blob: ccd153601a1935c9570eee1a0abcd9c76e69d7af [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>
danakj1fd259a02016-04-16 03:17:0912#include <memory>
rdsmith1d343be52016-10-21 20:37:5013#include <set>
[email protected]5285d972011-10-18 18:56:3414#include <string>
dchengc7eeda422015-12-26 03:56:4815#include <utility>
[email protected]95d88ffe2010-02-04 21:25:3316#include <vector>
[email protected]77848d12008-11-14 00:00:2217
[email protected]68bf9152008-09-25 19:47:3018#include "base/compiler_specific.h"
[email protected]57999812013-02-24 05:40:5219#include "base/files/file_path.h"
thestigd8df0332014-09-04 06:33:2920#include "base/files/file_util.h"
[email protected]f3da152d2012-06-02 01:00:5721#include "base/json/json_writer.h"
Adam Rice425cf122015-01-19 06:18:2422#include "base/logging.h"
Avi Drissman13fc8932015-12-20 04:40:4623#include "base/macros.h"
danakj1fd259a02016-04-16 03:17:0924#include "base/memory/ptr_util.h"
[email protected]bf828982013-08-14 18:01:4725#include "base/memory/weak_ptr.h"
fdoraya89e673c2017-01-31 21:44:2126#include "base/message_loop/message_loop.h"
[email protected]a34f61ee2014-03-18 20:59:4927#include "base/run_loop.h"
[email protected]125ef482013-06-11 18:32:4728#include "base/strings/string_util.h"
[email protected]750b2f3c2013-06-07 18:41:0529#include "base/strings/utf_string_conversions.h"
fdoraya89e673c2017-01-31 21:44:2130#include "base/test/scoped_task_scheduler.h"
[email protected]f36a8132011-09-02 18:36:3331#include "base/test/test_file_util.h"
gabf767595f2016-05-11 18:50:3532#include "base/threading/thread_task_runner_handle.h"
[email protected]277d5942010-08-11 21:02:3533#include "net/base/auth.h"
mmenkecbc2b712014-10-09 20:29:0734#include "net/base/chunked_upload_data_stream.h"
[email protected]bacff652009-03-31 17:50:3335#include "net/base/completion_callback.h"
mmenkecbc2b712014-10-09 20:29:0736#include "net/base/elements_upload_data_stream.h"
[email protected]58e32bb2013-01-21 18:23:2537#include "net/base/load_timing_info.h"
38#include "net/base/load_timing_info_test_util.h"
Adam Rice425cf122015-01-19 06:18:2439#include "net/base/net_errors.h"
rdsmith1d343be52016-10-21 20:37:5040#include "net/base/network_throttle_manager.h"
tbansal28e68f82016-02-04 02:56:1541#include "net/base/proxy_delegate.h"
[email protected]ac790b42009-12-02 04:31:3142#include "net/base/request_priority.h"
initial.commit586acc5fe2008-07-26 22:42:5243#include "net/base/test_completion_callback.h"
tbansal28e68f82016-02-04 02:56:1544#include "net/base/test_proxy_delegate.h"
[email protected]b2d26cfd2012-12-11 10:36:0645#include "net/base/upload_bytes_element_reader.h"
[email protected]d98961652012-09-11 20:27:2146#include "net/base/upload_file_element_reader.h"
[email protected]6e7845ae2013-03-29 21:48:1147#include "net/cert/mock_cert_verifier.h"
[email protected]bc71b8772013-04-10 20:55:1648#include "net/dns/host_cache.h"
[email protected]f2cb3cf2013-03-21 01:40:5349#include "net/dns/mock_host_resolver.h"
[email protected]df41d0d82014-03-13 00:43:2450#include "net/http/http_auth_challenge_tokenizer.h"
[email protected]3c32c5f2010-05-18 15:18:1251#include "net/http/http_auth_handler_digest.h"
[email protected]3fd9dae2010-06-21 11:39:0052#include "net/http/http_auth_handler_mock.h"
[email protected]385a4672009-03-11 22:21:2953#include "net/http/http_auth_handler_ntlm.h"
aberentbba302d2015-12-03 10:20:1954#include "net/http/http_auth_scheme.h"
Adam Rice425cf122015-01-19 06:18:2455#include "net/http/http_basic_state.h"
[email protected]0877e3d2009-10-17 22:29:5756#include "net/http/http_basic_stream.h"
initial.commit586acc5fe2008-07-26 22:42:5257#include "net/http/http_network_session.h"
[email protected]87bfa3f2010-09-30 14:54:5658#include "net/http/http_network_session_peer.h"
Adam Rice425cf122015-01-19 06:18:2459#include "net/http/http_request_headers.h"
mmenke5f94fda2016-06-02 20:54:1360#include "net/http/http_response_info.h"
[email protected]17291a022011-10-10 07:32:5361#include "net/http/http_server_properties_impl.h"
[email protected]0877e3d2009-10-17 22:29:5762#include "net/http/http_stream.h"
[email protected]8e6441ca2010-08-19 05:56:3863#include "net/http/http_stream_factory.h"
Adam Rice425cf122015-01-19 06:18:2464#include "net/http/http_stream_parser.h"
[email protected]c41737d2014-05-14 07:47:1965#include "net/http/http_transaction_test_util.h"
eroman87c53d62015-04-02 06:51:0766#include "net/log/net_log.h"
mikecirone8b85c432016-09-08 19:11:0067#include "net/log/net_log_event_type.h"
mikecironef22f9812016-10-04 03:40:1968#include "net/log/net_log_source.h"
vishal.b62985ca92015-04-17 08:45:5169#include "net/log/test_net_log.h"
mmenke43758e62015-05-04 21:09:4670#include "net/log/test_net_log_entry.h"
71#include "net/log/test_net_log_util.h"
sammc5dd160c2015-04-02 02:43:1372#include "net/proxy/mock_proxy_resolver.h"
[email protected]51fff29d2008-12-19 22:17:5373#include "net/proxy/proxy_config_service_fixed.h"
[email protected]e86839fd2013-08-14 18:29:0374#include "net/proxy/proxy_info.h"
[email protected]631f1322010-04-30 17:59:1175#include "net/proxy/proxy_resolver.h"
tbansal28e68f82016-02-04 02:56:1576#include "net/proxy/proxy_server.h"
[email protected]631f1322010-04-30 17:59:1177#include "net/proxy/proxy_service.h"
[email protected]f7984fc62009-06-22 23:26:4478#include "net/socket/client_socket_factory.h"
mmenked3641e12016-01-28 16:06:1579#include "net/socket/client_socket_pool.h"
[email protected]483fa202013-05-14 01:07:0380#include "net/socket/client_socket_pool_manager.h"
ttuttle1f2d7e92015-04-28 16:17:4781#include "net/socket/connection_attempts.h"
[email protected]a42dbd142011-11-17 16:42:0282#include "net/socket/mock_client_socket_pool_manager.h"
[email protected]bb88e1d32013-05-03 23:11:0783#include "net/socket/next_proto.h"
[email protected]f7984fc62009-06-22 23:26:4484#include "net/socket/socket_test_util.h"
85#include "net/socket/ssl_client_socket.h"
[email protected]2ff8b312010-04-26 22:20:5486#include "net/spdy/spdy_framer.h"
87#include "net/spdy/spdy_session.h"
88#include "net/spdy/spdy_session_pool.h"
[email protected]23e482282013-06-14 16:08:0289#include "net/spdy/spdy_test_util_common.h"
nharperb7441ef2016-01-25 23:54:1490#include "net/ssl/default_channel_id_store.h"
[email protected]536fd0b2013-03-14 17:41:5791#include "net/ssl/ssl_cert_request_info.h"
[email protected]e86839fd2013-08-14 18:29:0392#include "net/ssl/ssl_config_service.h"
[email protected]536fd0b2013-03-14 17:41:5793#include "net/ssl/ssl_config_service_defaults.h"
94#include "net/ssl/ssl_info.h"
svaldez7872fd02015-11-19 21:10:5495#include "net/ssl/ssl_private_key.h"
[email protected]6e7845ae2013-03-29 21:48:1196#include "net/test/cert_test_util.h"
robpercival214763f2016-07-01 23:27:0197#include "net/test/gtest_util.h"
rsleevia69c79a2016-06-22 03:28:4398#include "net/test/test_data_directory.h"
[email protected]831e4a32013-11-14 02:14:4499#include "net/websockets/websocket_handshake_stream_base.h"
bncf4588402015-11-24 13:33:18100#include "testing/gmock/include/gmock/gmock.h"
initial.commit586acc5fe2008-07-26 22:42:52101#include "testing/gtest/include/gtest/gtest.h"
[email protected]23887f04f2008-12-02 19:20:15102#include "testing/platform_test.h"
[email protected]795cbf82013-07-22 09:37:27103#include "url/gurl.h"
initial.commit586acc5fe2008-07-26 22:42:52104
robpercival214763f2016-07-01 23:27:01105using net::test::IsError;
106using net::test::IsOk;
107
[email protected]ad65a3e2013-12-25 18:18:01108using base::ASCIIToUTF16;
109
initial.commit586acc5fe2008-07-26 22:42:52110//-----------------------------------------------------------------------------
111
ttuttle859dc7a2015-04-23 19:42:29112namespace net {
113
[email protected]13c8a092010-07-29 06:15:44114namespace {
115
rdsmith1d343be52016-10-21 20:37:50116class TestNetworkStreamThrottler : public NetworkThrottleManager {
117 public:
118 TestNetworkStreamThrottler()
119 : throttle_new_requests_(false),
120 num_set_priority_calls_(0),
121 last_priority_set_(IDLE) {}
122
123 ~TestNetworkStreamThrottler() override {
124 EXPECT_TRUE(outstanding_throttles_.empty());
125 }
126
127 // NetworkThrottleManager
128 std::unique_ptr<Throttle> CreateThrottle(ThrottleDelegate* delegate,
129 RequestPriority priority,
130 bool ignore_limits) override {
131 std::unique_ptr<TestThrottle> test_throttle(
132 new TestThrottle(throttle_new_requests_, delegate, this));
133 outstanding_throttles_.insert(test_throttle.get());
134 return std::move(test_throttle);
135 }
136
137 void UnthrottleAllRequests() {
138 std::set<TestThrottle*> outstanding_throttles_copy(outstanding_throttles_);
139 for (auto& throttle : outstanding_throttles_copy) {
rdsmithbf8c3c12016-11-18 18:16:24140 if (throttle->IsBlocked())
rdsmith1d343be52016-10-21 20:37:50141 throttle->Unthrottle();
142 }
143 }
144
145 void set_throttle_new_requests(bool throttle_new_requests) {
146 throttle_new_requests_ = throttle_new_requests;
147 }
148
149 // Includes both throttled and unthrottled throttles.
150 size_t num_outstanding_requests() const {
151 return outstanding_throttles_.size();
152 }
153
154 int num_set_priority_calls() const { return num_set_priority_calls_; }
155 RequestPriority last_priority_set() const { return last_priority_set_; }
156 void set_priority_change_closure(
157 const base::Closure& priority_change_closure) {
158 priority_change_closure_ = priority_change_closure;
159 }
160
161 private:
162 class TestThrottle : public NetworkThrottleManager::Throttle {
163 public:
164 ~TestThrottle() override { throttler_->OnThrottleDestroyed(this); }
165
166 // Throttle
rdsmithbf8c3c12016-11-18 18:16:24167 bool IsBlocked() const override { return throttled_; }
168 RequestPriority Priority() const override {
169 NOTREACHED();
170 return IDLE;
171 }
rdsmith1d343be52016-10-21 20:37:50172 void SetPriority(RequestPriority priority) override {
173 throttler_->SetPriorityCalled(priority);
174 }
175
176 TestThrottle(bool throttled,
177 ThrottleDelegate* delegate,
178 TestNetworkStreamThrottler* throttler)
179 : throttled_(throttled), delegate_(delegate), throttler_(throttler) {}
180
181 void Unthrottle() {
182 EXPECT_TRUE(throttled_);
183
184 throttled_ = false;
rdsmithbf8c3c12016-11-18 18:16:24185 delegate_->OnThrottleUnblocked(this);
rdsmith1d343be52016-10-21 20:37:50186 }
187
188 bool throttled_;
189 ThrottleDelegate* delegate_;
190 TestNetworkStreamThrottler* throttler_;
191 };
192
193 void OnThrottleDestroyed(TestThrottle* throttle) {
194 EXPECT_NE(0u, outstanding_throttles_.count(throttle));
195 outstanding_throttles_.erase(throttle);
196 }
197
198 void SetPriorityCalled(RequestPriority priority) {
199 ++num_set_priority_calls_;
200 last_priority_set_ = priority;
201 if (!priority_change_closure_.is_null())
202 priority_change_closure_.Run();
203 }
204
205 // Includes both throttled and unthrottled throttles.
206 std::set<TestThrottle*> outstanding_throttles_;
207 bool throttle_new_requests_;
208 int num_set_priority_calls_;
209 RequestPriority last_priority_set_;
210 base::Closure priority_change_closure_;
211
212 DISALLOW_COPY_AND_ASSIGN(TestNetworkStreamThrottler);
213};
214
[email protected]42cba2fb2013-03-29 19:58:57215const base::string16 kBar(ASCIIToUTF16("bar"));
216const base::string16 kBar2(ASCIIToUTF16("bar2"));
217const base::string16 kBar3(ASCIIToUTF16("bar3"));
218const base::string16 kBaz(ASCIIToUTF16("baz"));
219const base::string16 kFirst(ASCIIToUTF16("first"));
220const base::string16 kFoo(ASCIIToUTF16("foo"));
221const base::string16 kFoo2(ASCIIToUTF16("foo2"));
222const base::string16 kFoo3(ASCIIToUTF16("foo3"));
223const base::string16 kFou(ASCIIToUTF16("fou"));
224const base::string16 kSecond(ASCIIToUTF16("second"));
225const base::string16 kTestingNTLM(ASCIIToUTF16("testing-ntlm"));
226const base::string16 kWrongPassword(ASCIIToUTF16("wrongpassword"));
[email protected]13c8a092010-07-29 06:15:44227
bnc2df4b522016-07-08 18:17:43228const char kAlternativeServiceHttpHeader[] =
229 "Alt-Svc: h2=\"mail.example.org:443\"\r\n";
230
ttuttle859dc7a2015-04-23 19:42:29231int GetIdleSocketCountInTransportSocketPool(HttpNetworkSession* session) {
232 return session->GetTransportSocketPool(HttpNetworkSession::NORMAL_SOCKET_POOL)
233 ->IdleSocketCount();
[email protected]e5c026642012-03-17 00:14:02234}
235
ttuttle859dc7a2015-04-23 19:42:29236int GetIdleSocketCountInSSLSocketPool(HttpNetworkSession* session) {
237 return session->GetSSLSocketPool(HttpNetworkSession::NORMAL_SOCKET_POOL)
238 ->IdleSocketCount();
[email protected]e5c026642012-03-17 00:14:02239}
240
ttuttle859dc7a2015-04-23 19:42:29241bool IsTransportSocketPoolStalled(HttpNetworkSession* session) {
242 return session->GetTransportSocketPool(HttpNetworkSession::NORMAL_SOCKET_POOL)
243 ->IsStalled();
[email protected]043b68c82013-08-22 23:41:52244}
245
[email protected]f3da152d2012-06-02 01:00:57246// Takes in a Value created from a NetLogHttpResponseParameter, and returns
247// a JSONified list of headers as a single string. Uses single quotes instead
248// of double quotes for easier comparison. Returns false on failure.
[email protected]ea5ef4c2013-06-13 22:50:27249bool GetHeaders(base::DictionaryValue* params, std::string* headers) {
[email protected]f3da152d2012-06-02 01:00:57250 if (!params)
251 return false;
[email protected]ea5ef4c2013-06-13 22:50:27252 base::ListValue* header_list;
[email protected]f3da152d2012-06-02 01:00:57253 if (!params->GetList("headers", &header_list))
254 return false;
255 std::string double_quote_headers;
estade8d046462015-05-16 01:02:34256 base::JSONWriter::Write(*header_list, &double_quote_headers);
[email protected]466c9862013-12-03 22:05:28257 base::ReplaceChars(double_quote_headers, "\"", "'", headers);
[email protected]f3da152d2012-06-02 01:00:57258 return true;
259}
260
[email protected]029c83b62013-01-24 05:28:20261// Tests LoadTimingInfo in the case a socket is reused and no PAC script is
262// used.
ttuttle859dc7a2015-04-23 19:42:29263void TestLoadTimingReused(const LoadTimingInfo& load_timing_info) {
[email protected]029c83b62013-01-24 05:28:20264 EXPECT_TRUE(load_timing_info.socket_reused);
mikecironef22f9812016-10-04 03:40:19265 EXPECT_NE(NetLogSource::kInvalidId, load_timing_info.socket_log_id);
[email protected]58e32bb2013-01-21 18:23:25266
[email protected]029c83b62013-01-24 05:28:20267 EXPECT_TRUE(load_timing_info.proxy_resolve_start.is_null());
268 EXPECT_TRUE(load_timing_info.proxy_resolve_end.is_null());
269
ttuttle859dc7a2015-04-23 19:42:29270 ExpectConnectTimingHasNoTimes(load_timing_info.connect_timing);
[email protected]029c83b62013-01-24 05:28:20271 EXPECT_FALSE(load_timing_info.send_start.is_null());
[email protected]58e32bb2013-01-21 18:23:25272
273 EXPECT_LE(load_timing_info.send_start, load_timing_info.send_end);
[email protected]58e32bb2013-01-21 18:23:25274
[email protected]3b23a222013-05-15 21:33:25275 // Set at a higher level.
[email protected]58e32bb2013-01-21 18:23:25276 EXPECT_TRUE(load_timing_info.request_start_time.is_null());
277 EXPECT_TRUE(load_timing_info.request_start.is_null());
[email protected]3b23a222013-05-15 21:33:25278 EXPECT_TRUE(load_timing_info.receive_headers_end.is_null());
[email protected]58e32bb2013-01-21 18:23:25279}
280
[email protected]029c83b62013-01-24 05:28:20281// Tests LoadTimingInfo in the case a new socket is used and no PAC script is
282// used.
ttuttle859dc7a2015-04-23 19:42:29283void TestLoadTimingNotReused(const LoadTimingInfo& load_timing_info,
[email protected]58e32bb2013-01-21 18:23:25284 int connect_timing_flags) {
[email protected]029c83b62013-01-24 05:28:20285 EXPECT_FALSE(load_timing_info.socket_reused);
mikecironef22f9812016-10-04 03:40:19286 EXPECT_NE(NetLogSource::kInvalidId, load_timing_info.socket_log_id);
[email protected]029c83b62013-01-24 05:28:20287
288 EXPECT_TRUE(load_timing_info.proxy_resolve_start.is_null());
289 EXPECT_TRUE(load_timing_info.proxy_resolve_end.is_null());
290
ttuttle859dc7a2015-04-23 19:42:29291 ExpectConnectTimingHasTimes(load_timing_info.connect_timing,
292 connect_timing_flags);
[email protected]029c83b62013-01-24 05:28:20293 EXPECT_LE(load_timing_info.connect_timing.connect_end,
294 load_timing_info.send_start);
295
296 EXPECT_LE(load_timing_info.send_start, load_timing_info.send_end);
[email protected]029c83b62013-01-24 05:28:20297
[email protected]3b23a222013-05-15 21:33:25298 // Set at a higher level.
[email protected]029c83b62013-01-24 05:28:20299 EXPECT_TRUE(load_timing_info.request_start_time.is_null());
300 EXPECT_TRUE(load_timing_info.request_start.is_null());
[email protected]3b23a222013-05-15 21:33:25301 EXPECT_TRUE(load_timing_info.receive_headers_end.is_null());
[email protected]029c83b62013-01-24 05:28:20302}
303
304// Tests LoadTimingInfo in the case a socket is reused and a PAC script is
305// used.
ttuttle859dc7a2015-04-23 19:42:29306void TestLoadTimingReusedWithPac(const LoadTimingInfo& load_timing_info) {
[email protected]029c83b62013-01-24 05:28:20307 EXPECT_TRUE(load_timing_info.socket_reused);
mikecironef22f9812016-10-04 03:40:19308 EXPECT_NE(NetLogSource::kInvalidId, load_timing_info.socket_log_id);
[email protected]029c83b62013-01-24 05:28:20309
ttuttle859dc7a2015-04-23 19:42:29310 ExpectConnectTimingHasNoTimes(load_timing_info.connect_timing);
[email protected]029c83b62013-01-24 05:28:20311
312 EXPECT_FALSE(load_timing_info.proxy_resolve_start.is_null());
313 EXPECT_LE(load_timing_info.proxy_resolve_start,
314 load_timing_info.proxy_resolve_end);
315 EXPECT_LE(load_timing_info.proxy_resolve_end,
316 load_timing_info.send_start);
317 EXPECT_LE(load_timing_info.send_start, load_timing_info.send_end);
[email protected]029c83b62013-01-24 05:28:20318
[email protected]3b23a222013-05-15 21:33:25319 // Set at a higher level.
[email protected]029c83b62013-01-24 05:28:20320 EXPECT_TRUE(load_timing_info.request_start_time.is_null());
321 EXPECT_TRUE(load_timing_info.request_start.is_null());
[email protected]3b23a222013-05-15 21:33:25322 EXPECT_TRUE(load_timing_info.receive_headers_end.is_null());
[email protected]029c83b62013-01-24 05:28:20323}
324
325// Tests LoadTimingInfo in the case a new socket is used and a PAC script is
326// used.
ttuttle859dc7a2015-04-23 19:42:29327void TestLoadTimingNotReusedWithPac(const LoadTimingInfo& load_timing_info,
[email protected]029c83b62013-01-24 05:28:20328 int connect_timing_flags) {
329 EXPECT_FALSE(load_timing_info.socket_reused);
mikecironef22f9812016-10-04 03:40:19330 EXPECT_NE(NetLogSource::kInvalidId, load_timing_info.socket_log_id);
[email protected]029c83b62013-01-24 05:28:20331
332 EXPECT_FALSE(load_timing_info.proxy_resolve_start.is_null());
333 EXPECT_LE(load_timing_info.proxy_resolve_start,
334 load_timing_info.proxy_resolve_end);
335 EXPECT_LE(load_timing_info.proxy_resolve_end,
336 load_timing_info.connect_timing.connect_start);
ttuttle859dc7a2015-04-23 19:42:29337 ExpectConnectTimingHasTimes(load_timing_info.connect_timing,
338 connect_timing_flags);
[email protected]029c83b62013-01-24 05:28:20339 EXPECT_LE(load_timing_info.connect_timing.connect_end,
340 load_timing_info.send_start);
341
342 EXPECT_LE(load_timing_info.send_start, load_timing_info.send_end);
[email protected]029c83b62013-01-24 05:28:20343
[email protected]3b23a222013-05-15 21:33:25344 // Set at a higher level.
[email protected]029c83b62013-01-24 05:28:20345 EXPECT_TRUE(load_timing_info.request_start_time.is_null());
346 EXPECT_TRUE(load_timing_info.request_start.is_null());
[email protected]3b23a222013-05-15 21:33:25347 EXPECT_TRUE(load_timing_info.receive_headers_end.is_null());
[email protected]58e32bb2013-01-21 18:23:25348}
349
ttuttle859dc7a2015-04-23 19:42:29350void AddWebSocketHeaders(HttpRequestHeaders* headers) {
Adam Rice425cf122015-01-19 06:18:24351 headers->SetHeader("Connection", "Upgrade");
352 headers->SetHeader("Upgrade", "websocket");
bncce36dca22015-04-21 22:11:23353 headers->SetHeader("Origin", "http://www.example.org");
Adam Rice425cf122015-01-19 06:18:24354 headers->SetHeader("Sec-WebSocket-Version", "13");
355 headers->SetHeader("Sec-WebSocket-Key", "dGhlIHNhbXBsZSBub25jZQ==");
356}
357
danakj1fd259a02016-04-16 03:17:09358std::unique_ptr<HttpNetworkSession> CreateSession(
mmenkee65e7af2015-10-13 17:16:42359 SpdySessionDependencies* session_deps) {
[email protected]c6bf8152012-12-02 07:43:34360 return SpdySessionDependencies::SpdyCreateSession(session_deps);
[email protected]e8d536192008-10-17 22:21:14361}
362
rdsmith1d343be52016-10-21 20:37:50363// Note that the pointer written into |*throttler| will only be valid
364// for the lifetime of the returned HttpNetworkSession.
365std::unique_ptr<HttpNetworkSession> CreateSessionWithThrottler(
366 SpdySessionDependencies* session_deps,
367 TestNetworkStreamThrottler** throttler) {
368 std::unique_ptr<HttpNetworkSession> session(
369 SpdySessionDependencies::SpdyCreateSession(session_deps));
370
371 std::unique_ptr<TestNetworkStreamThrottler> owned_throttler(
372 new TestNetworkStreamThrottler);
373 *throttler = owned_throttler.get();
374
375 HttpNetworkSessionPeer peer(session.get());
376 peer.SetNetworkStreamThrottler(std::move(owned_throttler));
377
378 return session;
379}
380
[email protected]448d4ca52012-03-04 04:12:23381} // namespace
382
bncd16676a2016-07-20 16:23:01383class HttpNetworkTransactionTest : public PlatformTest {
[email protected]483fa202013-05-14 01:07:03384 public:
bncd16676a2016-07-20 16:23:01385 ~HttpNetworkTransactionTest() override {
[email protected]483fa202013-05-14 01:07:03386 // Important to restore the per-pool limit first, since the pool limit must
387 // always be greater than group limit, and the tests reduce both limits.
388 ClientSocketPoolManager::set_max_sockets_per_pool(
389 HttpNetworkSession::NORMAL_SOCKET_POOL, old_max_pool_sockets_);
390 ClientSocketPoolManager::set_max_sockets_per_group(
391 HttpNetworkSession::NORMAL_SOCKET_POOL, old_max_group_sockets_);
392 }
393
[email protected]e3ceb682011-06-28 23:55:46394 protected:
[email protected]23e482282013-06-14 16:08:02395 HttpNetworkTransactionTest()
bnc032658ba2016-09-26 18:17:15396 : ssl_(ASYNC, OK),
397 old_max_group_sockets_(ClientSocketPoolManager::max_sockets_per_group(
[email protected]483fa202013-05-14 01:07:03398 HttpNetworkSession::NORMAL_SOCKET_POOL)),
399 old_max_pool_sockets_(ClientSocketPoolManager::max_sockets_per_pool(
400 HttpNetworkSession::NORMAL_SOCKET_POOL)) {
bncb26024382016-06-29 02:39:45401 session_deps_.enable_http2_alternative_service_with_different_host = true;
[email protected]483fa202013-05-14 01:07:03402 }
[email protected]bb88e1d32013-05-03 23:11:07403
[email protected]e3ceb682011-06-28 23:55:46404 struct SimpleGetHelperResult {
405 int rv;
406 std::string status_line;
407 std::string response_data;
sclittlefb249892015-09-10 21:33:22408 int64_t total_received_bytes;
409 int64_t total_sent_bytes;
[email protected]58e32bb2013-01-21 18:23:25410 LoadTimingInfo load_timing_info;
ttuttle1f2d7e92015-04-28 16:17:47411 ConnectionAttempts connection_attempts;
ttuttled9dbc652015-09-29 20:00:59412 IPEndPoint remote_endpoint_after_start;
[email protected]e3ceb682011-06-28 23:55:46413 };
414
dcheng67be2b1f2014-10-27 21:47:29415 void SetUp() override {
[email protected]0b0bf032010-09-21 18:08:50416 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
fdoray92e35a72016-06-10 15:54:55417 base::RunLoop().RunUntilIdle();
[email protected]2ff8b312010-04-26 22:20:54418 }
419
dcheng67be2b1f2014-10-27 21:47:29420 void TearDown() override {
[email protected]0b0bf032010-09-21 18:08:50421 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
fdoray92e35a72016-06-10 15:54:55422 base::RunLoop().RunUntilIdle();
[email protected]0e75a732008-10-16 20:36:09423 // Empty the current queue.
fdoray92e35a72016-06-10 15:54:55424 base::RunLoop().RunUntilIdle();
[email protected]0e75a732008-10-16 20:36:09425 PlatformTest::TearDown();
[email protected]0b0bf032010-09-21 18:08:50426 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
fdoray92e35a72016-06-10 15:54:55427 base::RunLoop().RunUntilIdle();
[email protected]0e75a732008-10-16 20:36:09428 }
429
[email protected]202965992011-12-07 23:04:51430 // Either |write_failure| specifies a write failure or |read_failure|
431 // specifies a read failure when using a reused socket. In either case, the
432 // failure should cause the network transaction to resend the request, and the
433 // other argument should be NULL.
434 void KeepAliveConnectionResendRequestTest(const MockWrite* write_failure,
435 const MockRead* read_failure);
initial.commit586acc5fe2008-07-26 22:42:52436
[email protected]a34f61ee2014-03-18 20:59:49437 // Either |write_failure| specifies a write failure or |read_failure|
438 // specifies a read failure when using a reused socket. In either case, the
439 // failure should cause the network transaction to resend the request, and the
440 // other argument should be NULL.
441 void PreconnectErrorResendRequestTest(const MockWrite* write_failure,
[email protected]09356c652014-03-25 15:36:10442 const MockRead* read_failure,
443 bool use_spdy);
[email protected]a34f61ee2014-03-18 20:59:49444
[email protected]5a60c8b2011-10-19 20:14:29445 SimpleGetHelperResult SimpleGetHelperForData(StaticSocketDataProvider* data[],
446 size_t data_count) {
[email protected]ff007e162009-05-23 09:13:15447 SimpleGetHelperResult out;
initial.commit586acc5fe2008-07-26 22:42:52448
[email protected]ff007e162009-05-23 09:13:15449 HttpRequestInfo request;
450 request.method = "GET";
bncce36dca22015-04-21 22:11:23451 request.url = GURL("http://www.example.org/");
initial.commit586acc5fe2008-07-26 22:42:52452
vishal.b62985ca92015-04-17 08:45:51453 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:07454 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:09455 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:16456 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:27457
[email protected]5a60c8b2011-10-19 20:14:29458 for (size_t i = 0; i < data_count; ++i) {
[email protected]bb88e1d32013-05-03 23:11:07459 session_deps_.socket_factory->AddSocketDataProvider(data[i]);
[email protected]5a60c8b2011-10-19 20:14:29460 }
initial.commit586acc5fe2008-07-26 22:42:52461
[email protected]49639fa2011-12-20 23:22:41462 TestCompletionCallback callback;
initial.commit586acc5fe2008-07-26 22:42:52463
eroman24bc6a12015-05-06 19:55:48464 EXPECT_TRUE(log.bound().IsCapturing());
bnc691fda62016-08-12 00:43:16465 int rv = trans.Start(&request, callback.callback(), log.bound());
robpercival214763f2016-07-01 23:27:01466 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
initial.commit586acc5fe2008-07-26 22:42:52467
[email protected]ff007e162009-05-23 09:13:15468 out.rv = callback.WaitForResult();
bnc691fda62016-08-12 00:43:16469 out.total_received_bytes = trans.GetTotalReceivedBytes();
470 out.total_sent_bytes = trans.GetTotalSentBytes();
[email protected]58e32bb2013-01-21 18:23:25471
472 // Even in the failure cases that use this function, connections are always
473 // successfully established before the error.
bnc691fda62016-08-12 00:43:16474 EXPECT_TRUE(trans.GetLoadTimingInfo(&out.load_timing_info));
[email protected]58e32bb2013-01-21 18:23:25475 TestLoadTimingNotReused(out.load_timing_info, CONNECT_TIMING_HAS_DNS_TIMES);
476
[email protected]ff007e162009-05-23 09:13:15477 if (out.rv != OK)
478 return out;
479
bnc691fda62016-08-12 00:43:16480 const HttpResponseInfo* response = trans.GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:50481 // Can't use ASSERT_* inside helper functions like this, so
482 // return an error.
wezca1070932016-05-26 20:30:52483 if (!response || !response->headers) {
[email protected]fe2255a2011-09-20 19:37:50484 out.rv = ERR_UNEXPECTED;
485 return out;
486 }
[email protected]ff007e162009-05-23 09:13:15487 out.status_line = response->headers->GetStatusLine();
488
[email protected]80a09a82012-11-16 17:40:06489 EXPECT_EQ("127.0.0.1", response->socket_address.host());
490 EXPECT_EQ(80, response->socket_address.port());
[email protected]6d81b482011-02-22 19:47:19491
ttuttled9dbc652015-09-29 20:00:59492 bool got_endpoint =
bnc691fda62016-08-12 00:43:16493 trans.GetRemoteEndpoint(&out.remote_endpoint_after_start);
ttuttled9dbc652015-09-29 20:00:59494 EXPECT_EQ(got_endpoint,
495 out.remote_endpoint_after_start.address().size() > 0);
496
bnc691fda62016-08-12 00:43:16497 rv = ReadTransaction(&trans, &out.response_data);
robpercival214763f2016-07-01 23:27:01498 EXPECT_THAT(rv, IsOk());
[email protected]b2fcd0e2010-12-01 15:19:40499
mmenke43758e62015-05-04 21:09:46500 TestNetLogEntry::List entries;
[email protected]b2fcd0e2010-12-01 15:19:40501 log.GetEntries(&entries);
[email protected]dbb83db2010-05-11 18:13:39502 size_t pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:00503 entries, 0, NetLogEventType::HTTP_TRANSACTION_SEND_REQUEST_HEADERS,
504 NetLogEventPhase::NONE);
[email protected]dbb83db2010-05-11 18:13:39505 ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:00506 entries, pos, NetLogEventType::HTTP_TRANSACTION_READ_RESPONSE_HEADERS,
507 NetLogEventPhase::NONE);
[email protected]ff007e162009-05-23 09:13:15508
[email protected]f3da152d2012-06-02 01:00:57509 std::string line;
510 EXPECT_TRUE(entries[pos].GetStringValue("line", &line));
511 EXPECT_EQ("GET / HTTP/1.1\r\n", line);
512
[email protected]79e1fd62013-06-20 06:50:04513 HttpRequestHeaders request_headers;
bnc691fda62016-08-12 00:43:16514 EXPECT_TRUE(trans.GetFullRequestHeaders(&request_headers));
[email protected]79e1fd62013-06-20 06:50:04515 std::string value;
516 EXPECT_TRUE(request_headers.GetHeader("Host", &value));
bncce36dca22015-04-21 22:11:23517 EXPECT_EQ("www.example.org", value);
[email protected]79e1fd62013-06-20 06:50:04518 EXPECT_TRUE(request_headers.GetHeader("Connection", &value));
519 EXPECT_EQ("keep-alive", value);
520
521 std::string response_headers;
522 EXPECT_TRUE(GetHeaders(entries[pos].params.get(), &response_headers));
bncce36dca22015-04-21 22:11:23523 EXPECT_EQ("['Host: www.example.org','Connection: keep-alive']",
[email protected]79e1fd62013-06-20 06:50:04524 response_headers);
[email protected]3deb9a52010-11-11 00:24:40525
bnc691fda62016-08-12 00:43:16526 out.total_received_bytes = trans.GetTotalReceivedBytes();
sclittlefb249892015-09-10 21:33:22527 // The total number of sent bytes should not have changed.
bnc691fda62016-08-12 00:43:16528 EXPECT_EQ(out.total_sent_bytes, trans.GetTotalSentBytes());
sclittlefb249892015-09-10 21:33:22529
bnc691fda62016-08-12 00:43:16530 trans.GetConnectionAttempts(&out.connection_attempts);
[email protected]aecfbf22008-10-16 02:02:47531 return out;
[email protected]ff007e162009-05-23 09:13:15532 }
initial.commit586acc5fe2008-07-26 22:42:52533
[email protected]5a60c8b2011-10-19 20:14:29534 SimpleGetHelperResult SimpleGetHelper(MockRead data_reads[],
535 size_t reads_count) {
sclittlefb249892015-09-10 21:33:22536 MockWrite data_writes[] = {
537 MockWrite("GET / HTTP/1.1\r\n"
538 "Host: www.example.org\r\n"
539 "Connection: keep-alive\r\n\r\n"),
540 };
[email protected]5a60c8b2011-10-19 20:14:29541
sclittlefb249892015-09-10 21:33:22542 StaticSocketDataProvider reads(data_reads, reads_count, data_writes,
543 arraysize(data_writes));
544 StaticSocketDataProvider* data[] = {&reads};
545 SimpleGetHelperResult out = SimpleGetHelperForData(data, 1);
546
547 EXPECT_EQ(CountWriteBytes(data_writes, arraysize(data_writes)),
548 out.total_sent_bytes);
549 return out;
[email protected]b8015c42013-12-24 15:18:19550 }
551
bnc032658ba2016-09-26 18:17:15552 void AddSSLSocketData() {
553 ssl_.next_proto = kProtoHTTP2;
554 ssl_.cert = ImportCertFromFile(GetTestCertsDirectory(), "spdy_pooling.pem");
555 ASSERT_TRUE(ssl_.cert);
556 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_);
557 }
558
[email protected]ff007e162009-05-23 09:13:15559 void ConnectStatusHelperWithExpectedStatus(const MockRead& status,
560 int expected_status);
initial.commit586acc5fe2008-07-26 22:42:52561
[email protected]ff007e162009-05-23 09:13:15562 void ConnectStatusHelper(const MockRead& status);
[email protected]bb88e1d32013-05-03 23:11:07563
564 void BypassHostCacheOnRefreshHelper(int load_flags);
565
566 void CheckErrorIsPassedBack(int error, IoMode mode);
567
[email protected]4bd46222013-05-14 19:32:23568 SpdyTestUtil spdy_util_;
[email protected]bb88e1d32013-05-03 23:11:07569 SpdySessionDependencies session_deps_;
bnc032658ba2016-09-26 18:17:15570 SSLSocketDataProvider ssl_;
[email protected]483fa202013-05-14 01:07:03571
572 // Original socket limits. Some tests set these. Safest to always restore
573 // them once each test has been run.
574 int old_max_group_sockets_;
575 int old_max_pool_sockets_;
[email protected]ff007e162009-05-23 09:13:15576};
[email protected]231d5a32008-09-13 00:45:27577
[email protected]448d4ca52012-03-04 04:12:23578namespace {
579
ryansturm49a8cb12016-06-15 16:51:09580class BeforeHeadersSentHandler {
[email protected]597a1ab2014-06-26 08:12:27581 public:
ryansturm49a8cb12016-06-15 16:51:09582 BeforeHeadersSentHandler()
583 : observed_before_headers_sent_with_proxy_(false),
584 observed_before_headers_sent_(false) {}
[email protected]597a1ab2014-06-26 08:12:27585
ryansturm49a8cb12016-06-15 16:51:09586 void OnBeforeHeadersSent(const ProxyInfo& proxy_info,
587 HttpRequestHeaders* request_headers) {
588 observed_before_headers_sent_ = true;
589 if (!proxy_info.is_http() && !proxy_info.is_https() &&
590 !proxy_info.is_quic()) {
591 return;
592 }
593 observed_before_headers_sent_with_proxy_ = true;
[email protected]597a1ab2014-06-26 08:12:27594 observed_proxy_server_uri_ = proxy_info.proxy_server().ToURI();
595 }
596
ryansturm49a8cb12016-06-15 16:51:09597 bool observed_before_headers_sent_with_proxy() const {
598 return observed_before_headers_sent_with_proxy_;
599 }
600
601 bool observed_before_headers_sent() const {
602 return observed_before_headers_sent_;
[email protected]597a1ab2014-06-26 08:12:27603 }
604
605 std::string observed_proxy_server_uri() const {
606 return observed_proxy_server_uri_;
607 }
608
609 private:
ryansturm49a8cb12016-06-15 16:51:09610 bool observed_before_headers_sent_with_proxy_;
611 bool observed_before_headers_sent_;
[email protected]597a1ab2014-06-26 08:12:27612 std::string observed_proxy_server_uri_;
613
ryansturm49a8cb12016-06-15 16:51:09614 DISALLOW_COPY_AND_ASSIGN(BeforeHeadersSentHandler);
[email protected]597a1ab2014-06-26 08:12:27615};
616
[email protected]15a5ccf82008-10-23 19:57:43617// Fill |str| with a long header list that consumes >= |size| bytes.
618void FillLargeHeadersString(std::string* str, int size) {
thestig9d3bb0c2015-01-24 00:49:51619 const char row[] =
[email protected]4ddaf2502008-10-23 18:26:19620 "SomeHeaderName: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx\r\n";
621 const int sizeof_row = strlen(row);
622 const int num_rows = static_cast<int>(
623 ceil(static_cast<float>(size) / sizeof_row));
624 const int sizeof_data = num_rows * sizeof_row;
625 DCHECK(sizeof_data >= size);
[email protected]15a5ccf82008-10-23 19:57:43626 str->reserve(sizeof_data);
[email protected]372d34a2008-11-05 21:30:51627
[email protected]4ddaf2502008-10-23 18:26:19628 for (int i = 0; i < num_rows; ++i)
[email protected]15a5ccf82008-10-23 19:57:43629 str->append(row, sizeof_row);
[email protected]4ddaf2502008-10-23 18:26:19630}
631
thakis84dff942015-07-28 20:47:38632#if defined(NTLM_PORTABLE)
[email protected]385a4672009-03-11 22:21:29633// Alternative functions that eliminate randomness and dependency on the local
634// host name so that the generated NTLM messages are reproducible.
avibf0746c2015-12-09 19:53:14635void MockGenerateRandom1(uint8_t* output, size_t n) {
636 static const uint8_t bytes[] = {0x55, 0x29, 0x66, 0x26,
637 0x6b, 0x9c, 0x73, 0x54};
[email protected]385a4672009-03-11 22:21:29638 static size_t current_byte = 0;
639 for (size_t i = 0; i < n; ++i) {
640 output[i] = bytes[current_byte++];
641 current_byte %= arraysize(bytes);
642 }
643}
644
avibf0746c2015-12-09 19:53:14645void MockGenerateRandom2(uint8_t* output, size_t n) {
646 static const uint8_t bytes[] = {0x96, 0x79, 0x85, 0xe7, 0x49, 0x93,
647 0x70, 0xa1, 0x4e, 0xe7, 0x87, 0x45,
648 0x31, 0x5b, 0xd3, 0x1f};
[email protected]385a4672009-03-11 22:21:29649 static size_t current_byte = 0;
650 for (size_t i = 0; i < n; ++i) {
651 output[i] = bytes[current_byte++];
652 current_byte %= arraysize(bytes);
653 }
654}
655
[email protected]fe2bc6a2009-03-23 16:52:20656std::string MockGetHostName() {
657 return "WTC-WIN7";
[email protected]385a4672009-03-11 22:21:29658}
thakis84dff942015-07-28 20:47:38659#endif // defined(NTLM_PORTABLE)
[email protected]385a4672009-03-11 22:21:29660
[email protected]e60e47a2010-07-14 03:37:18661template<typename ParentPool>
662class CaptureGroupNameSocketPool : public ParentPool {
[email protected]04e5be32009-06-26 20:00:31663 public:
[email protected]9e1bdd32011-02-03 21:48:34664 CaptureGroupNameSocketPool(HostResolver* host_resolver,
665 CertVerifier* cert_verifier);
[email protected]e60e47a2010-07-14 03:37:18666
[email protected]d80a4322009-08-14 07:07:49667 const std::string last_group_name_received() const {
668 return last_group_name_;
669 }
670
dmichaeld6e570d2014-12-18 22:30:57671 int RequestSocket(const std::string& group_name,
672 const void* socket_params,
673 RequestPriority priority,
mmenked3641e12016-01-28 16:06:15674 ClientSocketPool::RespectLimits respect_limits,
dmichaeld6e570d2014-12-18 22:30:57675 ClientSocketHandle* handle,
676 const CompletionCallback& callback,
tfarina42834112016-09-22 13:38:20677 const NetLogWithSource& net_log) override {
[email protected]04e5be32009-06-26 20:00:31678 last_group_name_ = group_name;
679 return ERR_IO_PENDING;
680 }
dmichaeld6e570d2014-12-18 22:30:57681 void CancelRequest(const std::string& group_name,
682 ClientSocketHandle* handle) override {}
683 void ReleaseSocket(const std::string& group_name,
danakj1fd259a02016-04-16 03:17:09684 std::unique_ptr<StreamSocket> socket,
dmichaeld6e570d2014-12-18 22:30:57685 int id) override {}
686 void CloseIdleSockets() override {}
687 int IdleSocketCount() const override { return 0; }
688 int IdleSocketCountInGroup(const std::string& group_name) const override {
[email protected]04e5be32009-06-26 20:00:31689 return 0;
690 }
dmichaeld6e570d2014-12-18 22:30:57691 LoadState GetLoadState(const std::string& group_name,
692 const ClientSocketHandle* handle) const override {
[email protected]04e5be32009-06-26 20:00:31693 return LOAD_STATE_IDLE;
694 }
dmichaeld6e570d2014-12-18 22:30:57695 base::TimeDelta ConnectionTimeout() const override {
[email protected]a796bcec2010-03-22 17:17:26696 return base::TimeDelta();
697 }
[email protected]d80a4322009-08-14 07:07:49698
699 private:
[email protected]04e5be32009-06-26 20:00:31700 std::string last_group_name_;
701};
702
[email protected]ab739042011-04-07 15:22:28703typedef CaptureGroupNameSocketPool<TransportClientSocketPool>
704CaptureGroupNameTransportSocketPool;
[email protected]e772db3f2010-07-12 18:11:13705typedef CaptureGroupNameSocketPool<HttpProxyClientSocketPool>
706CaptureGroupNameHttpProxySocketPool;
[email protected]2d731a32010-04-29 01:04:06707typedef CaptureGroupNameSocketPool<SOCKSClientSocketPool>
[email protected]2227c692010-05-04 15:36:11708CaptureGroupNameSOCKSSocketPool;
[email protected]e60e47a2010-07-14 03:37:18709typedef CaptureGroupNameSocketPool<SSLClientSocketPool>
710CaptureGroupNameSSLSocketPool;
711
rkaplowd90695c2015-03-25 22:12:41712template <typename ParentPool>
[email protected]e60e47a2010-07-14 03:37:18713CaptureGroupNameSocketPool<ParentPool>::CaptureGroupNameSocketPool(
[email protected]9e1bdd32011-02-03 21:48:34714 HostResolver* host_resolver,
715 CertVerifier* /* cert_verifier */)
tbansal7b403bcc2016-04-13 22:33:21716 : ParentPool(0, 0, host_resolver, NULL, NULL, NULL) {}
[email protected]e60e47a2010-07-14 03:37:18717
hashimoto0d3e4fb2015-01-09 05:02:50718template <>
[email protected]2df19bb2010-08-25 20:13:46719CaptureGroupNameHttpProxySocketPool::CaptureGroupNameSocketPool(
hashimotodae13b02015-01-15 04:28:21720 HostResolver* /* host_resolver */,
[email protected]9e1bdd32011-02-03 21:48:34721 CertVerifier* /* cert_verifier */)
rkaplowd90695c2015-03-25 22:12:41722 : HttpProxyClientSocketPool(0, 0, NULL, NULL, NULL) {
hashimoto0d3e4fb2015-01-09 05:02:50723}
[email protected]2df19bb2010-08-25 20:13:46724
[email protected]007b3f82013-04-09 08:46:45725template <>
[email protected]e60e47a2010-07-14 03:37:18726CaptureGroupNameSSLSocketPool::CaptureGroupNameSocketPool(
hashimotodae13b02015-01-15 04:28:21727 HostResolver* /* host_resolver */,
[email protected]9e1bdd32011-02-03 21:48:34728 CertVerifier* cert_verifier)
[email protected]007b3f82013-04-09 08:46:45729 : SSLClientSocketPool(0,
730 0,
[email protected]007b3f82013-04-09 08:46:45731 cert_verifier,
732 NULL,
733 NULL,
[email protected]284303b62013-11-28 15:11:54734 NULL,
eranm6571b2b2014-12-03 15:53:23735 NULL,
[email protected]007b3f82013-04-09 08:46:45736 std::string(),
737 NULL,
738 NULL,
739 NULL,
740 NULL,
741 NULL,
[email protected]8e458552014-08-05 00:02:15742 NULL) {
743}
[email protected]2227c692010-05-04 15:36:11744
[email protected]231d5a32008-09-13 00:45:27745//-----------------------------------------------------------------------------
746
[email protected]79cb5c12011-09-12 13:12:04747// Helper functions for validating that AuthChallengeInfo's are correctly
748// configured for common cases.
749bool CheckBasicServerAuth(const AuthChallengeInfo* auth_challenge) {
750 if (!auth_challenge)
751 return false;
752 EXPECT_FALSE(auth_challenge->is_proxy);
asanka098c0092016-06-16 20:18:43753 EXPECT_EQ("http://www.example.org", auth_challenge->challenger.Serialize());
[email protected]79cb5c12011-09-12 13:12:04754 EXPECT_EQ("MyRealm1", auth_challenge->realm);
aberentbba302d2015-12-03 10:20:19755 EXPECT_EQ(kBasicAuthScheme, auth_challenge->scheme);
[email protected]79cb5c12011-09-12 13:12:04756 return true;
757}
758
759bool CheckBasicProxyAuth(const AuthChallengeInfo* auth_challenge) {
760 if (!auth_challenge)
761 return false;
762 EXPECT_TRUE(auth_challenge->is_proxy);
asanka098c0092016-06-16 20:18:43763 EXPECT_EQ("http://myproxy:70", auth_challenge->challenger.Serialize());
764 EXPECT_EQ("MyRealm1", auth_challenge->realm);
765 EXPECT_EQ(kBasicAuthScheme, auth_challenge->scheme);
766 return true;
767}
768
769bool CheckBasicSecureProxyAuth(const AuthChallengeInfo* auth_challenge) {
770 if (!auth_challenge)
771 return false;
772 EXPECT_TRUE(auth_challenge->is_proxy);
773 EXPECT_EQ("https://myproxy:70", auth_challenge->challenger.Serialize());
[email protected]79cb5c12011-09-12 13:12:04774 EXPECT_EQ("MyRealm1", auth_challenge->realm);
aberentbba302d2015-12-03 10:20:19775 EXPECT_EQ(kBasicAuthScheme, auth_challenge->scheme);
[email protected]79cb5c12011-09-12 13:12:04776 return true;
777}
778
779bool CheckDigestServerAuth(const AuthChallengeInfo* auth_challenge) {
780 if (!auth_challenge)
781 return false;
782 EXPECT_FALSE(auth_challenge->is_proxy);
asanka098c0092016-06-16 20:18:43783 EXPECT_EQ("http://www.example.org", auth_challenge->challenger.Serialize());
[email protected]79cb5c12011-09-12 13:12:04784 EXPECT_EQ("digestive", auth_challenge->realm);
aberentbba302d2015-12-03 10:20:19785 EXPECT_EQ(kDigestAuthScheme, auth_challenge->scheme);
[email protected]79cb5c12011-09-12 13:12:04786 return true;
787}
788
thakis84dff942015-07-28 20:47:38789#if defined(NTLM_PORTABLE)
[email protected]79cb5c12011-09-12 13:12:04790bool CheckNTLMServerAuth(const AuthChallengeInfo* auth_challenge) {
791 if (!auth_challenge)
792 return false;
793 EXPECT_FALSE(auth_challenge->is_proxy);
asanka098c0092016-06-16 20:18:43794 EXPECT_EQ("http://172.22.68.17", auth_challenge->challenger.Serialize());
[email protected]79cb5c12011-09-12 13:12:04795 EXPECT_EQ(std::string(), auth_challenge->realm);
aberentbba302d2015-12-03 10:20:19796 EXPECT_EQ(kNtlmAuthScheme, auth_challenge->scheme);
[email protected]79cb5c12011-09-12 13:12:04797 return true;
798}
thakis84dff942015-07-28 20:47:38799#endif // defined(NTLM_PORTABLE)
[email protected]79cb5c12011-09-12 13:12:04800
[email protected]448d4ca52012-03-04 04:12:23801} // namespace
802
bncd16676a2016-07-20 16:23:01803TEST_F(HttpNetworkTransactionTest, Basic) {
danakj1fd259a02016-04-16 03:17:09804 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:16805 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]231d5a32008-09-13 00:45:27806}
807
bncd16676a2016-07-20 16:23:01808TEST_F(HttpNetworkTransactionTest, SimpleGET) {
[email protected]231d5a32008-09-13 00:45:27809 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:35810 MockRead("HTTP/1.0 200 OK\r\n\r\n"),
811 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:06812 MockRead(SYNCHRONOUS, OK),
[email protected]231d5a32008-09-13 00:45:27813 };
[email protected]31a2bfe2010-02-09 08:03:39814 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
815 arraysize(data_reads));
robpercival214763f2016-07-01 23:27:01816 EXPECT_THAT(out.rv, IsOk());
[email protected]231d5a32008-09-13 00:45:27817 EXPECT_EQ("HTTP/1.0 200 OK", out.status_line);
818 EXPECT_EQ("hello world", out.response_data);
sclittlefb249892015-09-10 21:33:22819 int64_t reads_size = CountReadBytes(data_reads, arraysize(data_reads));
820 EXPECT_EQ(reads_size, out.total_received_bytes);
ttuttle1f2d7e92015-04-28 16:17:47821 EXPECT_EQ(0u, out.connection_attempts.size());
ttuttled9dbc652015-09-29 20:00:59822
823 EXPECT_FALSE(out.remote_endpoint_after_start.address().empty());
[email protected]231d5a32008-09-13 00:45:27824}
825
826// Response with no status line.
bncd16676a2016-07-20 16:23:01827TEST_F(HttpNetworkTransactionTest, SimpleGETNoHeaders) {
[email protected]231d5a32008-09-13 00:45:27828 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:35829 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:06830 MockRead(SYNCHRONOUS, OK),
[email protected]231d5a32008-09-13 00:45:27831 };
[email protected]31a2bfe2010-02-09 08:03:39832 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
833 arraysize(data_reads));
mmenkea2dcd3bf2016-08-16 21:49:41834 EXPECT_THAT(out.rv, IsOk());
835 EXPECT_EQ("HTTP/0.9 200 OK", out.status_line);
836 EXPECT_EQ("hello world", out.response_data);
837 int64_t reads_size = CountReadBytes(data_reads, arraysize(data_reads));
838 EXPECT_EQ(reads_size, out.total_received_bytes);
[email protected]231d5a32008-09-13 00:45:27839}
840
mmenkea7da6da2016-09-01 21:56:52841// Response with no status line, and a weird port. Should fail by default.
842TEST_F(HttpNetworkTransactionTest, SimpleGETNoHeadersWeirdPort) {
843 MockRead data_reads[] = {
844 MockRead("hello world"), MockRead(SYNCHRONOUS, OK),
845 };
846
847 StaticSocketDataProvider data(data_reads, arraysize(data_reads), nullptr, 0);
848 session_deps_.socket_factory->AddSocketDataProvider(&data);
849
850 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
851
krasinc06a72a2016-12-21 03:42:46852 HttpRequestInfo request;
mmenkea7da6da2016-09-01 21:56:52853 std::unique_ptr<HttpTransaction> trans(
854 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
855
mmenkea7da6da2016-09-01 21:56:52856 request.method = "GET";
857 request.url = GURL("http://www.example.com:2000/");
858 TestCompletionCallback callback;
tfarina42834112016-09-22 13:38:20859 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
mmenkea7da6da2016-09-01 21:56:52860 EXPECT_THAT(callback.GetResult(rv), IsError(ERR_INVALID_HTTP_RESPONSE));
861}
862
863// Response with no status line, and a weird port. Option to allow weird ports
864// enabled.
865TEST_F(HttpNetworkTransactionTest, SimpleGETNoHeadersWeirdPortAllowed) {
866 MockRead data_reads[] = {
867 MockRead("hello world"), MockRead(SYNCHRONOUS, OK),
868 };
869
870 StaticSocketDataProvider data(data_reads, arraysize(data_reads), nullptr, 0);
871 session_deps_.socket_factory->AddSocketDataProvider(&data);
872 session_deps_.http_09_on_non_default_ports_enabled = true;
873 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
874
krasinc06a72a2016-12-21 03:42:46875 HttpRequestInfo request;
mmenkea7da6da2016-09-01 21:56:52876 std::unique_ptr<HttpTransaction> trans(
877 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
878
mmenkea7da6da2016-09-01 21:56:52879 request.method = "GET";
880 request.url = GURL("http://www.example.com:2000/");
881 TestCompletionCallback callback;
tfarina42834112016-09-22 13:38:20882 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
mmenkea7da6da2016-09-01 21:56:52883 EXPECT_THAT(callback.GetResult(rv), IsOk());
884
885 const HttpResponseInfo* info = trans->GetResponseInfo();
886 ASSERT_TRUE(info->headers);
887 EXPECT_EQ("HTTP/0.9 200 OK", info->headers->GetStatusLine());
888
889 // Don't bother to read the body - that's verified elsewhere, important thing
890 // is that the option to allow HTTP/0.9 on non-default ports is respected.
891}
892
[email protected]231d5a32008-09-13 00:45:27893// Allow up to 4 bytes of junk to precede status line.
bncd16676a2016-07-20 16:23:01894TEST_F(HttpNetworkTransactionTest, StatusLineJunk3Bytes) {
[email protected]231d5a32008-09-13 00:45:27895 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:35896 MockRead("xxxHTTP/1.0 404 Not Found\nServer: blah\n\nDATA"),
[email protected]8ddf8322012-02-23 18:08:06897 MockRead(SYNCHRONOUS, OK),
[email protected]231d5a32008-09-13 00:45:27898 };
[email protected]31a2bfe2010-02-09 08:03:39899 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
900 arraysize(data_reads));
robpercival214763f2016-07-01 23:27:01901 EXPECT_THAT(out.rv, IsOk());
[email protected]231d5a32008-09-13 00:45:27902 EXPECT_EQ("HTTP/1.0 404 Not Found", out.status_line);
903 EXPECT_EQ("DATA", out.response_data);
sclittlefb249892015-09-10 21:33:22904 int64_t reads_size = CountReadBytes(data_reads, arraysize(data_reads));
905 EXPECT_EQ(reads_size, out.total_received_bytes);
[email protected]231d5a32008-09-13 00:45:27906}
907
908// Allow up to 4 bytes of junk to precede status line.
bncd16676a2016-07-20 16:23:01909TEST_F(HttpNetworkTransactionTest, StatusLineJunk4Bytes) {
[email protected]231d5a32008-09-13 00:45:27910 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:35911 MockRead("\n\nQJHTTP/1.0 404 Not Found\nServer: blah\n\nDATA"),
[email protected]8ddf8322012-02-23 18:08:06912 MockRead(SYNCHRONOUS, OK),
[email protected]231d5a32008-09-13 00:45:27913 };
[email protected]31a2bfe2010-02-09 08:03:39914 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
915 arraysize(data_reads));
robpercival214763f2016-07-01 23:27:01916 EXPECT_THAT(out.rv, IsOk());
[email protected]231d5a32008-09-13 00:45:27917 EXPECT_EQ("HTTP/1.0 404 Not Found", out.status_line);
918 EXPECT_EQ("DATA", out.response_data);
sclittlefb249892015-09-10 21:33:22919 int64_t reads_size = CountReadBytes(data_reads, arraysize(data_reads));
920 EXPECT_EQ(reads_size, out.total_received_bytes);
[email protected]231d5a32008-09-13 00:45:27921}
922
923// Beyond 4 bytes of slop and it should fail to find a status line.
bncd16676a2016-07-20 16:23:01924TEST_F(HttpNetworkTransactionTest, StatusLineJunk5Bytes) {
[email protected]231d5a32008-09-13 00:45:27925 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:35926 MockRead("xxxxxHTTP/1.1 404 Not Found\nServer: blah"),
[email protected]8ddf8322012-02-23 18:08:06927 MockRead(SYNCHRONOUS, OK),
[email protected]231d5a32008-09-13 00:45:27928 };
[email protected]31a2bfe2010-02-09 08:03:39929 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
930 arraysize(data_reads));
mmenkea2dcd3bf2016-08-16 21:49:41931 EXPECT_THAT(out.rv, IsOk());
932 EXPECT_EQ("HTTP/0.9 200 OK", out.status_line);
933 EXPECT_EQ("xxxxxHTTP/1.1 404 Not Found\nServer: blah", out.response_data);
934 int64_t reads_size = CountReadBytes(data_reads, arraysize(data_reads));
935 EXPECT_EQ(reads_size, out.total_received_bytes);
[email protected]231d5a32008-09-13 00:45:27936}
937
938// Same as StatusLineJunk4Bytes, except the read chunks are smaller.
bncd16676a2016-07-20 16:23:01939TEST_F(HttpNetworkTransactionTest, StatusLineJunk4Bytes_Slow) {
[email protected]231d5a32008-09-13 00:45:27940 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:35941 MockRead("\n"),
942 MockRead("\n"),
943 MockRead("Q"),
944 MockRead("J"),
945 MockRead("HTTP/1.0 404 Not Found\nServer: blah\n\nDATA"),
[email protected]8ddf8322012-02-23 18:08:06946 MockRead(SYNCHRONOUS, OK),
[email protected]231d5a32008-09-13 00:45:27947 };
[email protected]31a2bfe2010-02-09 08:03:39948 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
949 arraysize(data_reads));
robpercival214763f2016-07-01 23:27:01950 EXPECT_THAT(out.rv, IsOk());
[email protected]231d5a32008-09-13 00:45:27951 EXPECT_EQ("HTTP/1.0 404 Not Found", out.status_line);
952 EXPECT_EQ("DATA", out.response_data);
sclittlefb249892015-09-10 21:33:22953 int64_t reads_size = CountReadBytes(data_reads, arraysize(data_reads));
954 EXPECT_EQ(reads_size, out.total_received_bytes);
[email protected]231d5a32008-09-13 00:45:27955}
956
957// Close the connection before enough bytes to have a status line.
bncd16676a2016-07-20 16:23:01958TEST_F(HttpNetworkTransactionTest, StatusLinePartial) {
[email protected]231d5a32008-09-13 00:45:27959 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:35960 MockRead("HTT"),
[email protected]8ddf8322012-02-23 18:08:06961 MockRead(SYNCHRONOUS, OK),
[email protected]231d5a32008-09-13 00:45:27962 };
[email protected]31a2bfe2010-02-09 08:03:39963 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
964 arraysize(data_reads));
mmenkea2dcd3bf2016-08-16 21:49:41965 EXPECT_THAT(out.rv, IsOk());
966 EXPECT_EQ("HTTP/0.9 200 OK", out.status_line);
967 EXPECT_EQ("HTT", out.response_data);
968 int64_t reads_size = CountReadBytes(data_reads, arraysize(data_reads));
969 EXPECT_EQ(reads_size, out.total_received_bytes);
initial.commit586acc5fe2008-07-26 22:42:52970}
971
[email protected]f9d44aa2008-09-23 23:57:17972// Simulate a 204 response, lacking a Content-Length header, sent over a
973// persistent connection. The response should still terminate since a 204
974// cannot have a response body.
bncd16676a2016-07-20 16:23:01975TEST_F(HttpNetworkTransactionTest, StopsReading204) {
[email protected]b8015c42013-12-24 15:18:19976 char junk[] = "junk";
[email protected]f9d44aa2008-09-23 23:57:17977 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:35978 MockRead("HTTP/1.1 204 No Content\r\n\r\n"),
[email protected]b8015c42013-12-24 15:18:19979 MockRead(junk), // Should not be read!!
[email protected]8ddf8322012-02-23 18:08:06980 MockRead(SYNCHRONOUS, OK),
[email protected]f9d44aa2008-09-23 23:57:17981 };
[email protected]31a2bfe2010-02-09 08:03:39982 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
983 arraysize(data_reads));
robpercival214763f2016-07-01 23:27:01984 EXPECT_THAT(out.rv, IsOk());
[email protected]f9d44aa2008-09-23 23:57:17985 EXPECT_EQ("HTTP/1.1 204 No Content", out.status_line);
986 EXPECT_EQ("", out.response_data);
sclittlefb249892015-09-10 21:33:22987 int64_t reads_size = CountReadBytes(data_reads, arraysize(data_reads));
988 int64_t response_size = reads_size - strlen(junk);
989 EXPECT_EQ(response_size, out.total_received_bytes);
[email protected]f9d44aa2008-09-23 23:57:17990}
991
[email protected]0877e3d2009-10-17 22:29:57992// A simple request using chunked encoding with some extra data after.
bncd16676a2016-07-20 16:23:01993TEST_F(HttpNetworkTransactionTest, ChunkedEncoding) {
[email protected]b8015c42013-12-24 15:18:19994 std::string final_chunk = "0\r\n\r\n";
995 std::string extra_data = "HTTP/1.1 200 OK\r\n";
996 std::string last_read = final_chunk + extra_data;
[email protected]0877e3d2009-10-17 22:29:57997 MockRead data_reads[] = {
998 MockRead("HTTP/1.1 200 OK\r\nTransfer-Encoding: chunked\r\n\r\n"),
999 MockRead("5\r\nHello\r\n"),
1000 MockRead("1\r\n"),
1001 MockRead(" \r\n"),
1002 MockRead("5\r\nworld\r\n"),
[email protected]b8015c42013-12-24 15:18:191003 MockRead(last_read.data()),
[email protected]8ddf8322012-02-23 18:08:061004 MockRead(SYNCHRONOUS, OK),
[email protected]0877e3d2009-10-17 22:29:571005 };
[email protected]31a2bfe2010-02-09 08:03:391006 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
1007 arraysize(data_reads));
robpercival214763f2016-07-01 23:27:011008 EXPECT_THAT(out.rv, IsOk());
[email protected]0877e3d2009-10-17 22:29:571009 EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
1010 EXPECT_EQ("Hello world", out.response_data);
sclittlefb249892015-09-10 21:33:221011 int64_t reads_size = CountReadBytes(data_reads, arraysize(data_reads));
1012 int64_t response_size = reads_size - extra_data.size();
1013 EXPECT_EQ(response_size, out.total_received_bytes);
[email protected]0877e3d2009-10-17 22:29:571014}
1015
[email protected]9fe44f52010-09-23 18:36:001016// Next tests deal with http://crbug.com/56344.
1017
bncd16676a2016-07-20 16:23:011018TEST_F(HttpNetworkTransactionTest,
[email protected]9fe44f52010-09-23 18:36:001019 MultipleContentLengthHeadersNoTransferEncoding) {
1020 MockRead data_reads[] = {
1021 MockRead("HTTP/1.1 200 OK\r\n"),
1022 MockRead("Content-Length: 10\r\n"),
1023 MockRead("Content-Length: 5\r\n\r\n"),
1024 };
1025 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
1026 arraysize(data_reads));
robpercival214763f2016-07-01 23:27:011027 EXPECT_THAT(out.rv, IsError(ERR_RESPONSE_HEADERS_MULTIPLE_CONTENT_LENGTH));
[email protected]9fe44f52010-09-23 18:36:001028}
1029
bncd16676a2016-07-20 16:23:011030TEST_F(HttpNetworkTransactionTest,
[email protected]44b52042010-10-29 22:48:041031 DuplicateContentLengthHeadersNoTransferEncoding) {
1032 MockRead data_reads[] = {
1033 MockRead("HTTP/1.1 200 OK\r\n"),
1034 MockRead("Content-Length: 5\r\n"),
1035 MockRead("Content-Length: 5\r\n\r\n"),
1036 MockRead("Hello"),
1037 };
1038 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
1039 arraysize(data_reads));
robpercival214763f2016-07-01 23:27:011040 EXPECT_THAT(out.rv, IsOk());
[email protected]44b52042010-10-29 22:48:041041 EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
1042 EXPECT_EQ("Hello", out.response_data);
1043}
1044
bncd16676a2016-07-20 16:23:011045TEST_F(HttpNetworkTransactionTest,
[email protected]44b52042010-10-29 22:48:041046 ComplexContentLengthHeadersNoTransferEncoding) {
1047 // More than 2 dupes.
1048 {
1049 MockRead data_reads[] = {
1050 MockRead("HTTP/1.1 200 OK\r\n"),
1051 MockRead("Content-Length: 5\r\n"),
1052 MockRead("Content-Length: 5\r\n"),
1053 MockRead("Content-Length: 5\r\n\r\n"),
1054 MockRead("Hello"),
1055 };
1056 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
1057 arraysize(data_reads));
robpercival214763f2016-07-01 23:27:011058 EXPECT_THAT(out.rv, IsOk());
[email protected]44b52042010-10-29 22:48:041059 EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
1060 EXPECT_EQ("Hello", out.response_data);
1061 }
1062 // HTTP/1.0
1063 {
1064 MockRead data_reads[] = {
1065 MockRead("HTTP/1.0 200 OK\r\n"),
1066 MockRead("Content-Length: 5\r\n"),
1067 MockRead("Content-Length: 5\r\n"),
1068 MockRead("Content-Length: 5\r\n\r\n"),
1069 MockRead("Hello"),
1070 };
1071 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
1072 arraysize(data_reads));
robpercival214763f2016-07-01 23:27:011073 EXPECT_THAT(out.rv, IsOk());
[email protected]44b52042010-10-29 22:48:041074 EXPECT_EQ("HTTP/1.0 200 OK", out.status_line);
1075 EXPECT_EQ("Hello", out.response_data);
1076 }
1077 // 2 dupes and one mismatched.
1078 {
1079 MockRead data_reads[] = {
1080 MockRead("HTTP/1.1 200 OK\r\n"),
1081 MockRead("Content-Length: 10\r\n"),
1082 MockRead("Content-Length: 10\r\n"),
1083 MockRead("Content-Length: 5\r\n\r\n"),
1084 };
1085 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
1086 arraysize(data_reads));
robpercival214763f2016-07-01 23:27:011087 EXPECT_THAT(out.rv, IsError(ERR_RESPONSE_HEADERS_MULTIPLE_CONTENT_LENGTH));
[email protected]44b52042010-10-29 22:48:041088 }
1089}
1090
bncd16676a2016-07-20 16:23:011091TEST_F(HttpNetworkTransactionTest,
[email protected]9fe44f52010-09-23 18:36:001092 MultipleContentLengthHeadersTransferEncoding) {
1093 MockRead data_reads[] = {
1094 MockRead("HTTP/1.1 200 OK\r\n"),
1095 MockRead("Content-Length: 666\r\n"),
1096 MockRead("Content-Length: 1337\r\n"),
1097 MockRead("Transfer-Encoding: chunked\r\n\r\n"),
1098 MockRead("5\r\nHello\r\n"),
1099 MockRead("1\r\n"),
1100 MockRead(" \r\n"),
1101 MockRead("5\r\nworld\r\n"),
1102 MockRead("0\r\n\r\nHTTP/1.1 200 OK\r\n"),
[email protected]8ddf8322012-02-23 18:08:061103 MockRead(SYNCHRONOUS, OK),
[email protected]9fe44f52010-09-23 18:36:001104 };
1105 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
1106 arraysize(data_reads));
robpercival214763f2016-07-01 23:27:011107 EXPECT_THAT(out.rv, IsOk());
[email protected]9fe44f52010-09-23 18:36:001108 EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
1109 EXPECT_EQ("Hello world", out.response_data);
1110}
1111
[email protected]1628fe92011-10-04 23:04:551112// Next tests deal with http://crbug.com/98895.
1113
1114// Checks that a single Content-Disposition header results in no error.
bncd16676a2016-07-20 16:23:011115TEST_F(HttpNetworkTransactionTest, SingleContentDispositionHeader) {
[email protected]1628fe92011-10-04 23:04:551116 MockRead data_reads[] = {
1117 MockRead("HTTP/1.1 200 OK\r\n"),
1118 MockRead("Content-Disposition: attachment;filename=\"salutations.txt\"r\n"),
1119 MockRead("Content-Length: 5\r\n\r\n"),
1120 MockRead("Hello"),
1121 };
1122 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
1123 arraysize(data_reads));
robpercival214763f2016-07-01 23:27:011124 EXPECT_THAT(out.rv, IsOk());
[email protected]1628fe92011-10-04 23:04:551125 EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
1126 EXPECT_EQ("Hello", out.response_data);
1127}
1128
[email protected]54a9c6e52012-03-21 20:10:591129// Checks that two identical Content-Disposition headers result in no error.
bncd16676a2016-07-20 16:23:011130TEST_F(HttpNetworkTransactionTest, TwoIdenticalContentDispositionHeaders) {
[email protected]1628fe92011-10-04 23:04:551131 MockRead data_reads[] = {
1132 MockRead("HTTP/1.1 200 OK\r\n"),
1133 MockRead("Content-Disposition: attachment;filename=\"greetings.txt\"r\n"),
1134 MockRead("Content-Disposition: attachment;filename=\"greetings.txt\"r\n"),
1135 MockRead("Content-Length: 5\r\n\r\n"),
1136 MockRead("Hello"),
1137 };
1138 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
1139 arraysize(data_reads));
robpercival214763f2016-07-01 23:27:011140 EXPECT_THAT(out.rv, IsOk());
[email protected]54a9c6e52012-03-21 20:10:591141 EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
1142 EXPECT_EQ("Hello", out.response_data);
[email protected]1628fe92011-10-04 23:04:551143}
1144
1145// Checks that two distinct Content-Disposition headers result in an error.
bncd16676a2016-07-20 16:23:011146TEST_F(HttpNetworkTransactionTest, TwoDistinctContentDispositionHeaders) {
[email protected]1628fe92011-10-04 23:04:551147 MockRead data_reads[] = {
1148 MockRead("HTTP/1.1 200 OK\r\n"),
1149 MockRead("Content-Disposition: attachment;filename=\"greetings.txt\"r\n"),
1150 MockRead("Content-Disposition: attachment;filename=\"hi.txt\"r\n"),
1151 MockRead("Content-Length: 5\r\n\r\n"),
1152 MockRead("Hello"),
1153 };
1154 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
1155 arraysize(data_reads));
robpercival214763f2016-07-01 23:27:011156 EXPECT_THAT(out.rv,
1157 IsError(ERR_RESPONSE_HEADERS_MULTIPLE_CONTENT_DISPOSITION));
[email protected]1628fe92011-10-04 23:04:551158}
1159
[email protected]54a9c6e52012-03-21 20:10:591160// Checks that two identical Location headers result in no error.
1161// Also tests Location header behavior.
bncd16676a2016-07-20 16:23:011162TEST_F(HttpNetworkTransactionTest, TwoIdenticalLocationHeaders) {
[email protected]1628fe92011-10-04 23:04:551163 MockRead data_reads[] = {
1164 MockRead("HTTP/1.1 302 Redirect\r\n"),
1165 MockRead("Location: http://good.com/\r\n"),
[email protected]54a9c6e52012-03-21 20:10:591166 MockRead("Location: http://good.com/\r\n"),
[email protected]1628fe92011-10-04 23:04:551167 MockRead("Content-Length: 0\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:061168 MockRead(SYNCHRONOUS, OK),
[email protected]1628fe92011-10-04 23:04:551169 };
1170
1171 HttpRequestInfo request;
1172 request.method = "GET";
1173 request.url = GURL("http://redirect.com/");
[email protected]1628fe92011-10-04 23:04:551174
danakj1fd259a02016-04-16 03:17:091175 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:161176 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]1628fe92011-10-04 23:04:551177
1178 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:071179 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1628fe92011-10-04 23:04:551180
[email protected]49639fa2011-12-20 23:22:411181 TestCompletionCallback callback;
[email protected]1628fe92011-10-04 23:04:551182
tfarina42834112016-09-22 13:38:201183 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:011184 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]1628fe92011-10-04 23:04:551185
robpercival214763f2016-07-01 23:27:011186 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]1628fe92011-10-04 23:04:551187
bnc691fda62016-08-12 00:43:161188 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:521189 ASSERT_TRUE(response);
1190 ASSERT_TRUE(response->headers);
[email protected]1628fe92011-10-04 23:04:551191 EXPECT_EQ("HTTP/1.1 302 Redirect", response->headers->GetStatusLine());
1192 std::string url;
1193 EXPECT_TRUE(response->headers->IsRedirect(&url));
1194 EXPECT_EQ("http://good.com/", url);
tbansal2ecbbc72016-10-06 17:15:471195 EXPECT_TRUE(response->proxy_server.is_direct());
[email protected]1628fe92011-10-04 23:04:551196}
1197
[email protected]1628fe92011-10-04 23:04:551198// Checks that two distinct Location headers result in an error.
bncd16676a2016-07-20 16:23:011199TEST_F(HttpNetworkTransactionTest, TwoDistinctLocationHeaders) {
[email protected]1628fe92011-10-04 23:04:551200 MockRead data_reads[] = {
1201 MockRead("HTTP/1.1 302 Redirect\r\n"),
1202 MockRead("Location: http://good.com/\r\n"),
1203 MockRead("Location: http://evil.com/\r\n"),
1204 MockRead("Content-Length: 0\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:061205 MockRead(SYNCHRONOUS, OK),
[email protected]1628fe92011-10-04 23:04:551206 };
1207 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
1208 arraysize(data_reads));
robpercival214763f2016-07-01 23:27:011209 EXPECT_THAT(out.rv, IsError(ERR_RESPONSE_HEADERS_MULTIPLE_LOCATION));
[email protected]1628fe92011-10-04 23:04:551210}
1211
[email protected]ef0faf2e72009-03-05 23:27:231212// Do a request using the HEAD method. Verify that we don't try to read the
1213// message body (since HEAD has none).
bncd16676a2016-07-20 16:23:011214TEST_F(HttpNetworkTransactionTest, Head) {
[email protected]1c773ea12009-04-28 19:58:421215 HttpRequestInfo request;
[email protected]ef0faf2e72009-03-05 23:27:231216 request.method = "HEAD";
bncce36dca22015-04-21 22:11:231217 request.url = GURL("http://www.example.org/");
[email protected]ef0faf2e72009-03-05 23:27:231218
danakj1fd259a02016-04-16 03:17:091219 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:161220 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
ryansturm49a8cb12016-06-15 16:51:091221 BeforeHeadersSentHandler headers_handler;
bnc691fda62016-08-12 00:43:161222 trans.SetBeforeHeadersSentCallback(
ryansturm49a8cb12016-06-15 16:51:091223 base::Bind(&BeforeHeadersSentHandler::OnBeforeHeadersSent,
1224 base::Unretained(&headers_handler)));
[email protected]cb9bf6ca2011-01-28 13:15:271225
[email protected]ef0faf2e72009-03-05 23:27:231226 MockWrite data_writes1[] = {
csharrisonf473dd192015-08-18 13:54:131227 MockWrite("HEAD / HTTP/1.1\r\n"
1228 "Host: www.example.org\r\n"
1229 "Connection: keep-alive\r\n\r\n"),
[email protected]ef0faf2e72009-03-05 23:27:231230 };
1231 MockRead data_reads1[] = {
mmenked39192ee2015-12-09 00:57:231232 MockRead("HTTP/1.1 404 Not Found\r\n"), MockRead("Server: Blah\r\n"),
1233 MockRead("Content-Length: 1234\r\n\r\n"),
[email protected]ef0faf2e72009-03-05 23:27:231234
mmenked39192ee2015-12-09 00:57:231235 // No response body because the test stops reading here.
1236 MockRead(SYNCHRONOUS, ERR_UNEXPECTED),
[email protected]ef0faf2e72009-03-05 23:27:231237 };
1238
[email protected]31a2bfe2010-02-09 08:03:391239 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
1240 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:071241 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]ef0faf2e72009-03-05 23:27:231242
[email protected]49639fa2011-12-20 23:22:411243 TestCompletionCallback callback1;
[email protected]ef0faf2e72009-03-05 23:27:231244
tfarina42834112016-09-22 13:38:201245 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:011246 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]ef0faf2e72009-03-05 23:27:231247
1248 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:011249 EXPECT_THAT(rv, IsOk());
[email protected]ef0faf2e72009-03-05 23:27:231250
bnc691fda62016-08-12 00:43:161251 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:521252 ASSERT_TRUE(response);
[email protected]ef0faf2e72009-03-05 23:27:231253
1254 // Check that the headers got parsed.
wezca1070932016-05-26 20:30:521255 EXPECT_TRUE(response->headers);
[email protected]ef0faf2e72009-03-05 23:27:231256 EXPECT_EQ(1234, response->headers->GetContentLength());
1257 EXPECT_EQ("HTTP/1.1 404 Not Found", response->headers->GetStatusLine());
tbansal2ecbbc72016-10-06 17:15:471258 EXPECT_TRUE(response->proxy_server.is_direct());
ryansturm49a8cb12016-06-15 16:51:091259 EXPECT_TRUE(headers_handler.observed_before_headers_sent());
1260 EXPECT_FALSE(headers_handler.observed_before_headers_sent_with_proxy());
[email protected]ef0faf2e72009-03-05 23:27:231261
1262 std::string server_header;
olli.raulaee489a52016-01-25 08:37:101263 size_t iter = 0;
[email protected]ef0faf2e72009-03-05 23:27:231264 bool has_server_header = response->headers->EnumerateHeader(
1265 &iter, "Server", &server_header);
1266 EXPECT_TRUE(has_server_header);
1267 EXPECT_EQ("Blah", server_header);
1268
1269 // Reading should give EOF right away, since there is no message body
1270 // (despite non-zero content-length).
1271 std::string response_data;
bnc691fda62016-08-12 00:43:161272 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:011273 EXPECT_THAT(rv, IsOk());
[email protected]ef0faf2e72009-03-05 23:27:231274 EXPECT_EQ("", response_data);
1275}
1276
bncd16676a2016-07-20 16:23:011277TEST_F(HttpNetworkTransactionTest, ReuseConnection) {
danakj1fd259a02016-04-16 03:17:091278 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
initial.commit586acc5fe2008-07-26 22:42:521279
1280 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:351281 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
1282 MockRead("hello"),
1283 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
1284 MockRead("world"),
[email protected]8ddf8322012-02-23 18:08:061285 MockRead(SYNCHRONOUS, OK),
initial.commit586acc5fe2008-07-26 22:42:521286 };
[email protected]31a2bfe2010-02-09 08:03:391287 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:071288 session_deps_.socket_factory->AddSocketDataProvider(&data);
initial.commit586acc5fe2008-07-26 22:42:521289
[email protected]0b0bf032010-09-21 18:08:501290 const char* const kExpectedResponseData[] = {
initial.commit586acc5fe2008-07-26 22:42:521291 "hello", "world"
1292 };
1293
1294 for (int i = 0; i < 2; ++i) {
[email protected]1c773ea12009-04-28 19:58:421295 HttpRequestInfo request;
initial.commit586acc5fe2008-07-26 22:42:521296 request.method = "GET";
bncce36dca22015-04-21 22:11:231297 request.url = GURL("http://www.example.org/");
initial.commit586acc5fe2008-07-26 22:42:521298
bnc691fda62016-08-12 00:43:161299 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:271300
[email protected]49639fa2011-12-20 23:22:411301 TestCompletionCallback callback;
initial.commit586acc5fe2008-07-26 22:42:521302
tfarina42834112016-09-22 13:38:201303 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:011304 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
initial.commit586acc5fe2008-07-26 22:42:521305
1306 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:011307 EXPECT_THAT(rv, IsOk());
initial.commit586acc5fe2008-07-26 22:42:521308
bnc691fda62016-08-12 00:43:161309 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:521310 ASSERT_TRUE(response);
initial.commit586acc5fe2008-07-26 22:42:521311
wezca1070932016-05-26 20:30:521312 EXPECT_TRUE(response->headers);
[email protected]3d2a59b2008-09-26 19:44:251313 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
tbansal2ecbbc72016-10-06 17:15:471314 EXPECT_TRUE(response->proxy_server.is_direct());
initial.commit586acc5fe2008-07-26 22:42:521315
1316 std::string response_data;
bnc691fda62016-08-12 00:43:161317 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:011318 EXPECT_THAT(rv, IsOk());
[email protected]3d2a59b2008-09-26 19:44:251319 EXPECT_EQ(kExpectedResponseData[i], response_data);
initial.commit586acc5fe2008-07-26 22:42:521320 }
1321}
1322
bncd16676a2016-07-20 16:23:011323TEST_F(HttpNetworkTransactionTest, Ignores100) {
danakj1fd259a02016-04-16 03:17:091324 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:221325 element_readers.push_back(
ricea2deef682016-09-09 08:04:071326 base::MakeUnique<UploadBytesElementReader>("foo", 3));
olli.raula6df48b2a2015-11-26 07:40:221327 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]329b68b2012-11-14 17:54:271328
[email protected]1c773ea12009-04-28 19:58:421329 HttpRequestInfo request;
initial.commit586acc5fe2008-07-26 22:42:521330 request.method = "POST";
1331 request.url = GURL("http://www.foo.com/");
[email protected]329b68b2012-11-14 17:54:271332 request.upload_data_stream = &upload_data_stream;
initial.commit586acc5fe2008-07-26 22:42:521333
shivanishab9a143952016-09-19 17:23:411334 // Check the upload progress returned before initialization is correct.
1335 UploadProgress progress = request.upload_data_stream->GetUploadProgress();
1336 EXPECT_EQ(0u, progress.size());
1337 EXPECT_EQ(0u, progress.position());
1338
danakj1fd259a02016-04-16 03:17:091339 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:161340 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:271341
initial.commit586acc5fe2008-07-26 22:42:521342 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:351343 MockRead("HTTP/1.0 100 Continue\r\n\r\n"),
1344 MockRead("HTTP/1.0 200 OK\r\n\r\n"),
1345 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:061346 MockRead(SYNCHRONOUS, OK),
initial.commit586acc5fe2008-07-26 22:42:521347 };
[email protected]31a2bfe2010-02-09 08:03:391348 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:071349 session_deps_.socket_factory->AddSocketDataProvider(&data);
initial.commit586acc5fe2008-07-26 22:42:521350
[email protected]49639fa2011-12-20 23:22:411351 TestCompletionCallback callback;
initial.commit586acc5fe2008-07-26 22:42:521352
tfarina42834112016-09-22 13:38:201353 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:011354 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
initial.commit586acc5fe2008-07-26 22:42:521355
1356 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:011357 EXPECT_THAT(rv, IsOk());
initial.commit586acc5fe2008-07-26 22:42:521358
bnc691fda62016-08-12 00:43:161359 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:521360 ASSERT_TRUE(response);
initial.commit586acc5fe2008-07-26 22:42:521361
wezca1070932016-05-26 20:30:521362 EXPECT_TRUE(response->headers);
[email protected]3d2a59b2008-09-26 19:44:251363 EXPECT_EQ("HTTP/1.0 200 OK", response->headers->GetStatusLine());
initial.commit586acc5fe2008-07-26 22:42:521364
1365 std::string response_data;
bnc691fda62016-08-12 00:43:161366 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:011367 EXPECT_THAT(rv, IsOk());
[email protected]3d2a59b2008-09-26 19:44:251368 EXPECT_EQ("hello world", response_data);
initial.commit586acc5fe2008-07-26 22:42:521369}
1370
[email protected]3a2d3662009-03-27 03:49:141371// This test is almost the same as Ignores100 above, but the response contains
1372// a 102 instead of a 100. Also, instead of HTTP/1.0 the response is
[email protected]0877e3d2009-10-17 22:29:571373// HTTP/1.1 and the two status headers are read in one read.
bncd16676a2016-07-20 16:23:011374TEST_F(HttpNetworkTransactionTest, Ignores1xx) {
[email protected]1c773ea12009-04-28 19:58:421375 HttpRequestInfo request;
[email protected]3a2d3662009-03-27 03:49:141376 request.method = "GET";
1377 request.url = GURL("http://www.foo.com/");
[email protected]3a2d3662009-03-27 03:49:141378
danakj1fd259a02016-04-16 03:17:091379 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:161380 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:271381
[email protected]3a2d3662009-03-27 03:49:141382 MockRead data_reads[] = {
[email protected]0877e3d2009-10-17 22:29:571383 MockRead("HTTP/1.1 102 Unspecified status code\r\n\r\n"
1384 "HTTP/1.1 200 OK\r\n\r\n"),
[email protected]3a2d3662009-03-27 03:49:141385 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:061386 MockRead(SYNCHRONOUS, OK),
[email protected]3a2d3662009-03-27 03:49:141387 };
[email protected]31a2bfe2010-02-09 08:03:391388 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:071389 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]3a2d3662009-03-27 03:49:141390
[email protected]49639fa2011-12-20 23:22:411391 TestCompletionCallback callback;
[email protected]3a2d3662009-03-27 03:49:141392
tfarina42834112016-09-22 13:38:201393 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:011394 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]3a2d3662009-03-27 03:49:141395
1396 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:011397 EXPECT_THAT(rv, IsOk());
[email protected]3a2d3662009-03-27 03:49:141398
bnc691fda62016-08-12 00:43:161399 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:521400 ASSERT_TRUE(response);
[email protected]3a2d3662009-03-27 03:49:141401
wezca1070932016-05-26 20:30:521402 EXPECT_TRUE(response->headers);
[email protected]3a2d3662009-03-27 03:49:141403 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
1404
1405 std::string response_data;
bnc691fda62016-08-12 00:43:161406 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:011407 EXPECT_THAT(rv, IsOk());
[email protected]3a2d3662009-03-27 03:49:141408 EXPECT_EQ("hello world", response_data);
1409}
1410
bncd16676a2016-07-20 16:23:011411TEST_F(HttpNetworkTransactionTest, Incomplete100ThenEOF) {
zmo9528c9f42015-08-04 22:12:081412 HttpRequestInfo request;
1413 request.method = "POST";
1414 request.url = GURL("http://www.foo.com/");
zmo9528c9f42015-08-04 22:12:081415
danakj1fd259a02016-04-16 03:17:091416 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:161417 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
zmo9528c9f42015-08-04 22:12:081418
1419 MockRead data_reads[] = {
1420 MockRead(SYNCHRONOUS, "HTTP/1.0 100 Continue\r\n"),
1421 MockRead(ASYNC, 0),
[email protected]ee9410e72010-01-07 01:42:381422 };
zmo9528c9f42015-08-04 22:12:081423 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
1424 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]ee9410e72010-01-07 01:42:381425
zmo9528c9f42015-08-04 22:12:081426 TestCompletionCallback callback;
[email protected]ee9410e72010-01-07 01:42:381427
tfarina42834112016-09-22 13:38:201428 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:011429 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]ee9410e72010-01-07 01:42:381430
zmo9528c9f42015-08-04 22:12:081431 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:011432 EXPECT_THAT(rv, IsOk());
[email protected]ee9410e72010-01-07 01:42:381433
zmo9528c9f42015-08-04 22:12:081434 std::string response_data;
bnc691fda62016-08-12 00:43:161435 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:011436 EXPECT_THAT(rv, IsOk());
zmo9528c9f42015-08-04 22:12:081437 EXPECT_EQ("", response_data);
[email protected]ee9410e72010-01-07 01:42:381438}
1439
bncd16676a2016-07-20 16:23:011440TEST_F(HttpNetworkTransactionTest, EmptyResponse) {
[email protected]ee9410e72010-01-07 01:42:381441 HttpRequestInfo request;
1442 request.method = "POST";
1443 request.url = GURL("http://www.foo.com/");
[email protected]ee9410e72010-01-07 01:42:381444
danakj1fd259a02016-04-16 03:17:091445 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:161446 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:271447
[email protected]ee9410e72010-01-07 01:42:381448 MockRead data_reads[] = {
[email protected]8ddf8322012-02-23 18:08:061449 MockRead(ASYNC, 0),
[email protected]ee9410e72010-01-07 01:42:381450 };
[email protected]31a2bfe2010-02-09 08:03:391451 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:071452 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]ee9410e72010-01-07 01:42:381453
[email protected]49639fa2011-12-20 23:22:411454 TestCompletionCallback callback;
[email protected]ee9410e72010-01-07 01:42:381455
tfarina42834112016-09-22 13:38:201456 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:011457 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]ee9410e72010-01-07 01:42:381458
1459 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:011460 EXPECT_THAT(rv, IsError(ERR_EMPTY_RESPONSE));
[email protected]ee9410e72010-01-07 01:42:381461}
1462
[email protected]23e482282013-06-14 16:08:021463void HttpNetworkTransactionTest::KeepAliveConnectionResendRequestTest(
[email protected]202965992011-12-07 23:04:511464 const MockWrite* write_failure,
1465 const MockRead* read_failure) {
[email protected]1c773ea12009-04-28 19:58:421466 HttpRequestInfo request;
initial.commit586acc5fe2008-07-26 22:42:521467 request.method = "GET";
1468 request.url = GURL("http://www.foo.com/");
initial.commit586acc5fe2008-07-26 22:42:521469
vishal.b62985ca92015-04-17 08:45:511470 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:071471 session_deps_.net_log = &net_log;
danakj1fd259a02016-04-16 03:17:091472 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:271473
[email protected]202965992011-12-07 23:04:511474 // Written data for successfully sending both requests.
1475 MockWrite data1_writes[] = {
1476 MockWrite("GET / HTTP/1.1\r\n"
1477 "Host: www.foo.com\r\n"
1478 "Connection: keep-alive\r\n\r\n"),
1479 MockWrite("GET / HTTP/1.1\r\n"
1480 "Host: www.foo.com\r\n"
1481 "Connection: keep-alive\r\n\r\n")
1482 };
1483
1484 // Read results for the first request.
initial.commit586acc5fe2008-07-26 22:42:521485 MockRead data1_reads[] = {
[email protected]217e6022008-09-29 18:18:351486 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
1487 MockRead("hello"),
[email protected]8ddf8322012-02-23 18:08:061488 MockRead(ASYNC, OK),
initial.commit586acc5fe2008-07-26 22:42:521489 };
[email protected]202965992011-12-07 23:04:511490
1491 if (write_failure) {
[email protected]a34f61ee2014-03-18 20:59:491492 ASSERT_FALSE(read_failure);
[email protected]202965992011-12-07 23:04:511493 data1_writes[1] = *write_failure;
1494 } else {
1495 ASSERT_TRUE(read_failure);
1496 data1_reads[2] = *read_failure;
1497 }
1498
1499 StaticSocketDataProvider data1(data1_reads, arraysize(data1_reads),
1500 data1_writes, arraysize(data1_writes));
[email protected]bb88e1d32013-05-03 23:11:071501 session_deps_.socket_factory->AddSocketDataProvider(&data1);
initial.commit586acc5fe2008-07-26 22:42:521502
1503 MockRead data2_reads[] = {
[email protected]217e6022008-09-29 18:18:351504 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
1505 MockRead("world"),
[email protected]8ddf8322012-02-23 18:08:061506 MockRead(ASYNC, OK),
initial.commit586acc5fe2008-07-26 22:42:521507 };
[email protected]31a2bfe2010-02-09 08:03:391508 StaticSocketDataProvider data2(data2_reads, arraysize(data2_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:071509 session_deps_.socket_factory->AddSocketDataProvider(&data2);
initial.commit586acc5fe2008-07-26 22:42:521510
thestig9d3bb0c2015-01-24 00:49:511511 const char* const kExpectedResponseData[] = {
initial.commit586acc5fe2008-07-26 22:42:521512 "hello", "world"
1513 };
1514
mikecironef22f9812016-10-04 03:40:191515 uint32_t first_socket_log_id = NetLogSource::kInvalidId;
initial.commit586acc5fe2008-07-26 22:42:521516 for (int i = 0; i < 2; ++i) {
[email protected]49639fa2011-12-20 23:22:411517 TestCompletionCallback callback;
initial.commit586acc5fe2008-07-26 22:42:521518
bnc691fda62016-08-12 00:43:161519 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
initial.commit586acc5fe2008-07-26 22:42:521520
tfarina42834112016-09-22 13:38:201521 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:011522 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
initial.commit586acc5fe2008-07-26 22:42:521523
1524 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:011525 EXPECT_THAT(rv, IsOk());
initial.commit586acc5fe2008-07-26 22:42:521526
[email protected]58e32bb2013-01-21 18:23:251527 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:161528 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]58e32bb2013-01-21 18:23:251529 TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_DNS_TIMES);
1530 if (i == 0) {
1531 first_socket_log_id = load_timing_info.socket_log_id;
1532 } else {
1533 // The second request should be using a new socket.
1534 EXPECT_NE(first_socket_log_id, load_timing_info.socket_log_id);
1535 }
1536
bnc691fda62016-08-12 00:43:161537 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:521538 ASSERT_TRUE(response);
initial.commit586acc5fe2008-07-26 22:42:521539
wezca1070932016-05-26 20:30:521540 EXPECT_TRUE(response->headers);
tbansal2ecbbc72016-10-06 17:15:471541 EXPECT_TRUE(response->proxy_server.is_direct());
[email protected]3d2a59b2008-09-26 19:44:251542 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
initial.commit586acc5fe2008-07-26 22:42:521543
1544 std::string response_data;
bnc691fda62016-08-12 00:43:161545 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:011546 EXPECT_THAT(rv, IsOk());
[email protected]3d2a59b2008-09-26 19:44:251547 EXPECT_EQ(kExpectedResponseData[i], response_data);
initial.commit586acc5fe2008-07-26 22:42:521548 }
1549}
[email protected]3d2a59b2008-09-26 19:44:251550
[email protected]a34f61ee2014-03-18 20:59:491551void HttpNetworkTransactionTest::PreconnectErrorResendRequestTest(
1552 const MockWrite* write_failure,
[email protected]09356c652014-03-25 15:36:101553 const MockRead* read_failure,
1554 bool use_spdy) {
[email protected]a34f61ee2014-03-18 20:59:491555 HttpRequestInfo request;
1556 request.method = "GET";
[email protected]09356c652014-03-25 15:36:101557 request.url = GURL("https://www.foo.com/");
[email protected]a34f61ee2014-03-18 20:59:491558
vishal.b62985ca92015-04-17 08:45:511559 TestNetLog net_log;
[email protected]a34f61ee2014-03-18 20:59:491560 session_deps_.net_log = &net_log;
danakj1fd259a02016-04-16 03:17:091561 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]a34f61ee2014-03-18 20:59:491562
[email protected]09356c652014-03-25 15:36:101563 SSLSocketDataProvider ssl1(ASYNC, OK);
1564 SSLSocketDataProvider ssl2(ASYNC, OK);
1565 if (use_spdy) {
bnc3cf2a592016-08-11 14:48:361566 ssl1.next_proto = kProtoHTTP2;
1567 ssl2.next_proto = kProtoHTTP2;
[email protected]09356c652014-03-25 15:36:101568 }
1569 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl1);
1570 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
[email protected]a34f61ee2014-03-18 20:59:491571
[email protected]09356c652014-03-25 15:36:101572 // SPDY versions of the request and response.
bncdf80d44fd2016-07-15 20:27:411573 SpdySerializedFrame spdy_request(spdy_util_.ConstructSpdyGet(
bnc38dcd392016-02-09 23:19:491574 request.url.spec().c_str(), 1, DEFAULT_PRIORITY));
bncdf80d44fd2016-07-15 20:27:411575 SpdySerializedFrame spdy_response(
bnc42331402016-07-25 13:36:151576 spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
bncdf80d44fd2016-07-15 20:27:411577 SpdySerializedFrame spdy_data(
1578 spdy_util_.ConstructSpdyDataFrame(1, "hello", 5, true));
[email protected]a34f61ee2014-03-18 20:59:491579
[email protected]09356c652014-03-25 15:36:101580 // HTTP/1.1 versions of the request and response.
1581 const char kHttpRequest[] = "GET / HTTP/1.1\r\n"
1582 "Host: www.foo.com\r\n"
1583 "Connection: keep-alive\r\n\r\n";
1584 const char kHttpResponse[] = "HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n";
1585 const char kHttpData[] = "hello";
1586
1587 std::vector<MockRead> data1_reads;
1588 std::vector<MockWrite> data1_writes;
[email protected]a34f61ee2014-03-18 20:59:491589 if (write_failure) {
1590 ASSERT_FALSE(read_failure);
[email protected]09356c652014-03-25 15:36:101591 data1_writes.push_back(*write_failure);
1592 data1_reads.push_back(MockRead(ASYNC, OK));
[email protected]a34f61ee2014-03-18 20:59:491593 } else {
1594 ASSERT_TRUE(read_failure);
[email protected]09356c652014-03-25 15:36:101595 if (use_spdy) {
bncdf80d44fd2016-07-15 20:27:411596 data1_writes.push_back(CreateMockWrite(spdy_request));
[email protected]09356c652014-03-25 15:36:101597 } else {
1598 data1_writes.push_back(MockWrite(kHttpRequest));
1599 }
1600 data1_reads.push_back(*read_failure);
[email protected]a34f61ee2014-03-18 20:59:491601 }
1602
[email protected]09356c652014-03-25 15:36:101603 StaticSocketDataProvider data1(&data1_reads[0], data1_reads.size(),
1604 &data1_writes[0], data1_writes.size());
[email protected]a34f61ee2014-03-18 20:59:491605 session_deps_.socket_factory->AddSocketDataProvider(&data1);
1606
[email protected]09356c652014-03-25 15:36:101607 std::vector<MockRead> data2_reads;
1608 std::vector<MockWrite> data2_writes;
1609
1610 if (use_spdy) {
bncdf80d44fd2016-07-15 20:27:411611 data2_writes.push_back(CreateMockWrite(spdy_request, 0, ASYNC));
[email protected]09356c652014-03-25 15:36:101612
bncdf80d44fd2016-07-15 20:27:411613 data2_reads.push_back(CreateMockRead(spdy_response, 1, ASYNC));
1614 data2_reads.push_back(CreateMockRead(spdy_data, 2, ASYNC));
[email protected]09356c652014-03-25 15:36:101615 data2_reads.push_back(MockRead(ASYNC, OK, 3));
1616 } else {
1617 data2_writes.push_back(
1618 MockWrite(ASYNC, kHttpRequest, strlen(kHttpRequest), 0));
1619
1620 data2_reads.push_back(
1621 MockRead(ASYNC, kHttpResponse, strlen(kHttpResponse), 1));
1622 data2_reads.push_back(MockRead(ASYNC, kHttpData, strlen(kHttpData), 2));
1623 data2_reads.push_back(MockRead(ASYNC, OK, 3));
1624 }
rch8e6c6c42015-05-01 14:05:131625 SequencedSocketData data2(&data2_reads[0], data2_reads.size(),
1626 &data2_writes[0], data2_writes.size());
[email protected]a34f61ee2014-03-18 20:59:491627 session_deps_.socket_factory->AddSocketDataProvider(&data2);
1628
1629 // Preconnect a socket.
nharper8cdb0fb2016-04-22 21:34:591630 session->http_stream_factory()->PreconnectStreams(1, request);
[email protected]a34f61ee2014-03-18 20:59:491631 // Wait for the preconnect to complete.
1632 // TODO(davidben): Some way to wait for an idle socket count might be handy.
1633 base::RunLoop().RunUntilIdle();
[email protected]09356c652014-03-25 15:36:101634 EXPECT_EQ(1, GetIdleSocketCountInSSLSocketPool(session.get()));
[email protected]a34f61ee2014-03-18 20:59:491635
1636 // Make the request.
1637 TestCompletionCallback callback;
1638
bnc691fda62016-08-12 00:43:161639 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]a34f61ee2014-03-18 20:59:491640
tfarina42834112016-09-22 13:38:201641 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:011642 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]a34f61ee2014-03-18 20:59:491643
1644 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:011645 EXPECT_THAT(rv, IsOk());
[email protected]a34f61ee2014-03-18 20:59:491646
1647 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:161648 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]09356c652014-03-25 15:36:101649 TestLoadTimingNotReused(
1650 load_timing_info,
1651 CONNECT_TIMING_HAS_DNS_TIMES|CONNECT_TIMING_HAS_SSL_TIMES);
[email protected]a34f61ee2014-03-18 20:59:491652
bnc691fda62016-08-12 00:43:161653 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:521654 ASSERT_TRUE(response);
[email protected]a34f61ee2014-03-18 20:59:491655
wezca1070932016-05-26 20:30:521656 EXPECT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:021657 if (response->was_fetched_via_spdy) {
1658 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
1659 } else {
1660 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
1661 }
[email protected]a34f61ee2014-03-18 20:59:491662
1663 std::string response_data;
bnc691fda62016-08-12 00:43:161664 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:011665 EXPECT_THAT(rv, IsOk());
[email protected]09356c652014-03-25 15:36:101666 EXPECT_EQ(kHttpData, response_data);
[email protected]a34f61ee2014-03-18 20:59:491667}
1668
bncd16676a2016-07-20 16:23:011669TEST_F(HttpNetworkTransactionTest, KeepAliveConnectionNotConnectedOnWrite) {
[email protected]8ddf8322012-02-23 18:08:061670 MockWrite write_failure(ASYNC, ERR_SOCKET_NOT_CONNECTED);
[email protected]202965992011-12-07 23:04:511671 KeepAliveConnectionResendRequestTest(&write_failure, NULL);
1672}
1673
bncd16676a2016-07-20 16:23:011674TEST_F(HttpNetworkTransactionTest, KeepAliveConnectionReset) {
[email protected]8ddf8322012-02-23 18:08:061675 MockRead read_failure(ASYNC, ERR_CONNECTION_RESET);
[email protected]202965992011-12-07 23:04:511676 KeepAliveConnectionResendRequestTest(NULL, &read_failure);
[email protected]3d2a59b2008-09-26 19:44:251677}
1678
bncd16676a2016-07-20 16:23:011679TEST_F(HttpNetworkTransactionTest, KeepAliveConnectionEOF) {
[email protected]8ddf8322012-02-23 18:08:061680 MockRead read_failure(SYNCHRONOUS, OK); // EOF
[email protected]202965992011-12-07 23:04:511681 KeepAliveConnectionResendRequestTest(NULL, &read_failure);
[email protected]3d2a59b2008-09-26 19:44:251682}
1683
[email protected]d58ceea82014-06-04 10:55:541684// Make sure that on a 408 response (Request Timeout), the request is retried,
1685// if the socket was a reused keep alive socket.
bncd16676a2016-07-20 16:23:011686TEST_F(HttpNetworkTransactionTest, KeepAlive408) {
[email protected]d58ceea82014-06-04 10:55:541687 MockRead read_failure(SYNCHRONOUS,
1688 "HTTP/1.1 408 Request Timeout\r\n"
1689 "Connection: Keep-Alive\r\n"
1690 "Content-Length: 6\r\n\r\n"
1691 "Pickle");
1692 KeepAliveConnectionResendRequestTest(NULL, &read_failure);
1693}
1694
bncd16676a2016-07-20 16:23:011695TEST_F(HttpNetworkTransactionTest, PreconnectErrorNotConnectedOnWrite) {
[email protected]a34f61ee2014-03-18 20:59:491696 MockWrite write_failure(ASYNC, ERR_SOCKET_NOT_CONNECTED);
[email protected]09356c652014-03-25 15:36:101697 PreconnectErrorResendRequestTest(&write_failure, NULL, false);
[email protected]a34f61ee2014-03-18 20:59:491698}
1699
bncd16676a2016-07-20 16:23:011700TEST_F(HttpNetworkTransactionTest, PreconnectErrorReset) {
[email protected]a34f61ee2014-03-18 20:59:491701 MockRead read_failure(ASYNC, ERR_CONNECTION_RESET);
[email protected]09356c652014-03-25 15:36:101702 PreconnectErrorResendRequestTest(NULL, &read_failure, false);
[email protected]a34f61ee2014-03-18 20:59:491703}
1704
bncd16676a2016-07-20 16:23:011705TEST_F(HttpNetworkTransactionTest, PreconnectErrorEOF) {
[email protected]a34f61ee2014-03-18 20:59:491706 MockRead read_failure(SYNCHRONOUS, OK); // EOF
[email protected]09356c652014-03-25 15:36:101707 PreconnectErrorResendRequestTest(NULL, &read_failure, false);
1708}
1709
bncd16676a2016-07-20 16:23:011710TEST_F(HttpNetworkTransactionTest, PreconnectErrorAsyncEOF) {
[email protected]09356c652014-03-25 15:36:101711 MockRead read_failure(ASYNC, OK); // EOF
1712 PreconnectErrorResendRequestTest(NULL, &read_failure, false);
1713}
1714
[email protected]d58ceea82014-06-04 10:55:541715// Make sure that on a 408 response (Request Timeout), the request is retried,
1716// if the socket was a preconnected (UNUSED_IDLE) socket.
bncd16676a2016-07-20 16:23:011717TEST_F(HttpNetworkTransactionTest, RetryOnIdle408) {
[email protected]d58ceea82014-06-04 10:55:541718 MockRead read_failure(SYNCHRONOUS,
1719 "HTTP/1.1 408 Request Timeout\r\n"
1720 "Connection: Keep-Alive\r\n"
1721 "Content-Length: 6\r\n\r\n"
1722 "Pickle");
1723 KeepAliveConnectionResendRequestTest(NULL, &read_failure);
1724 PreconnectErrorResendRequestTest(NULL, &read_failure, false);
1725}
1726
bncd16676a2016-07-20 16:23:011727TEST_F(HttpNetworkTransactionTest, SpdyPreconnectErrorNotConnectedOnWrite) {
[email protected]09356c652014-03-25 15:36:101728 MockWrite write_failure(ASYNC, ERR_SOCKET_NOT_CONNECTED);
1729 PreconnectErrorResendRequestTest(&write_failure, NULL, true);
1730}
1731
bncd16676a2016-07-20 16:23:011732TEST_F(HttpNetworkTransactionTest, SpdyPreconnectErrorReset) {
[email protected]09356c652014-03-25 15:36:101733 MockRead read_failure(ASYNC, ERR_CONNECTION_RESET);
1734 PreconnectErrorResendRequestTest(NULL, &read_failure, true);
1735}
1736
bncd16676a2016-07-20 16:23:011737TEST_F(HttpNetworkTransactionTest, SpdyPreconnectErrorEOF) {
[email protected]09356c652014-03-25 15:36:101738 MockRead read_failure(SYNCHRONOUS, OK); // EOF
1739 PreconnectErrorResendRequestTest(NULL, &read_failure, true);
1740}
1741
bncd16676a2016-07-20 16:23:011742TEST_F(HttpNetworkTransactionTest, SpdyPreconnectErrorAsyncEOF) {
[email protected]09356c652014-03-25 15:36:101743 MockRead read_failure(ASYNC, OK); // EOF
1744 PreconnectErrorResendRequestTest(NULL, &read_failure, true);
[email protected]a34f61ee2014-03-18 20:59:491745}
1746
bncd16676a2016-07-20 16:23:011747TEST_F(HttpNetworkTransactionTest, NonKeepAliveConnectionReset) {
[email protected]1c773ea12009-04-28 19:58:421748 HttpRequestInfo request;
[email protected]3d2a59b2008-09-26 19:44:251749 request.method = "GET";
bncce36dca22015-04-21 22:11:231750 request.url = GURL("http://www.example.org/");
[email protected]3d2a59b2008-09-26 19:44:251751
danakj1fd259a02016-04-16 03:17:091752 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:161753 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:271754
[email protected]3d2a59b2008-09-26 19:44:251755 MockRead data_reads[] = {
[email protected]8ddf8322012-02-23 18:08:061756 MockRead(ASYNC, ERR_CONNECTION_RESET),
[email protected]217e6022008-09-29 18:18:351757 MockRead("HTTP/1.0 200 OK\r\n\r\n"), // Should not be used
1758 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:061759 MockRead(SYNCHRONOUS, OK),
[email protected]3d2a59b2008-09-26 19:44:251760 };
[email protected]31a2bfe2010-02-09 08:03:391761 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:071762 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]3d2a59b2008-09-26 19:44:251763
[email protected]49639fa2011-12-20 23:22:411764 TestCompletionCallback callback;
[email protected]3d2a59b2008-09-26 19:44:251765
tfarina42834112016-09-22 13:38:201766 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:011767 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]3d2a59b2008-09-26 19:44:251768
1769 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:011770 EXPECT_THAT(rv, IsError(ERR_CONNECTION_RESET));
ttuttled9dbc652015-09-29 20:00:591771
1772 IPEndPoint endpoint;
bnc691fda62016-08-12 00:43:161773 EXPECT_TRUE(trans.GetRemoteEndpoint(&endpoint));
ttuttled9dbc652015-09-29 20:00:591774 EXPECT_LT(0u, endpoint.address().size());
[email protected]3d2a59b2008-09-26 19:44:251775}
1776
1777// What do various browsers do when the server closes a non-keepalive
1778// connection without sending any response header or body?
1779//
1780// IE7: error page
1781// Safari 3.1.2 (Windows): error page
1782// Firefox 3.0.1: blank page
1783// Opera 9.52: after five attempts, blank page
[email protected]1c773ea12009-04-28 19:58:421784// Us with WinHTTP: error page (ERR_INVALID_RESPONSE)
1785// Us: error page (EMPTY_RESPONSE)
bncd16676a2016-07-20 16:23:011786TEST_F(HttpNetworkTransactionTest, NonKeepAliveConnectionEOF) {
[email protected]3d2a59b2008-09-26 19:44:251787 MockRead data_reads[] = {
[email protected]8ddf8322012-02-23 18:08:061788 MockRead(SYNCHRONOUS, OK), // EOF
[email protected]217e6022008-09-29 18:18:351789 MockRead("HTTP/1.0 200 OK\r\n\r\n"), // Should not be used
1790 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:061791 MockRead(SYNCHRONOUS, OK),
[email protected]3d2a59b2008-09-26 19:44:251792 };
[email protected]31a2bfe2010-02-09 08:03:391793 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
1794 arraysize(data_reads));
robpercival214763f2016-07-01 23:27:011795 EXPECT_THAT(out.rv, IsError(ERR_EMPTY_RESPONSE));
[email protected]3d2a59b2008-09-26 19:44:251796}
[email protected]1826a402014-01-08 15:40:481797
[email protected]7a5378b2012-11-04 03:25:171798// Next 2 cases (KeepAliveEarlyClose and KeepAliveEarlyClose2) are regression
1799// tests. There was a bug causing HttpNetworkTransaction to hang in the
1800// destructor in such situations.
1801// See http://crbug.com/154712 and http://crbug.com/156609.
bncd16676a2016-07-20 16:23:011802TEST_F(HttpNetworkTransactionTest, KeepAliveEarlyClose) {
[email protected]7a5378b2012-11-04 03:25:171803 HttpRequestInfo request;
1804 request.method = "GET";
bncce36dca22015-04-21 22:11:231805 request.url = GURL("http://www.example.org/");
[email protected]7a5378b2012-11-04 03:25:171806
danakj1fd259a02016-04-16 03:17:091807 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:161808 std::unique_ptr<HttpNetworkTransaction> trans(
[email protected]90499482013-06-01 00:39:501809 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]7a5378b2012-11-04 03:25:171810
1811 MockRead data_reads[] = {
1812 MockRead("HTTP/1.0 200 OK\r\n"),
1813 MockRead("Connection: keep-alive\r\n"),
1814 MockRead("Content-Length: 100\r\n\r\n"),
1815 MockRead("hello"),
1816 MockRead(SYNCHRONOUS, 0),
1817 };
1818 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:071819 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]7a5378b2012-11-04 03:25:171820
1821 TestCompletionCallback callback;
1822
tfarina42834112016-09-22 13:38:201823 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:011824 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]7a5378b2012-11-04 03:25:171825
1826 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:011827 EXPECT_THAT(rv, IsOk());
[email protected]7a5378b2012-11-04 03:25:171828
1829 scoped_refptr<IOBufferWithSize> io_buf(new IOBufferWithSize(100));
[email protected]90499482013-06-01 00:39:501830 rv = trans->Read(io_buf.get(), io_buf->size(), callback.callback());
[email protected]7a5378b2012-11-04 03:25:171831 if (rv == ERR_IO_PENDING)
1832 rv = callback.WaitForResult();
1833 EXPECT_EQ(5, rv);
[email protected]90499482013-06-01 00:39:501834 rv = trans->Read(io_buf.get(), io_buf->size(), callback.callback());
robpercival214763f2016-07-01 23:27:011835 EXPECT_THAT(rv, IsError(ERR_CONTENT_LENGTH_MISMATCH));
[email protected]7a5378b2012-11-04 03:25:171836
1837 trans.reset();
fdoray92e35a72016-06-10 15:54:551838 base::RunLoop().RunUntilIdle();
[email protected]7a5378b2012-11-04 03:25:171839 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
1840}
1841
bncd16676a2016-07-20 16:23:011842TEST_F(HttpNetworkTransactionTest, KeepAliveEarlyClose2) {
[email protected]7a5378b2012-11-04 03:25:171843 HttpRequestInfo request;
1844 request.method = "GET";
bncce36dca22015-04-21 22:11:231845 request.url = GURL("http://www.example.org/");
[email protected]7a5378b2012-11-04 03:25:171846
danakj1fd259a02016-04-16 03:17:091847 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:161848 std::unique_ptr<HttpNetworkTransaction> trans(
[email protected]90499482013-06-01 00:39:501849 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]7a5378b2012-11-04 03:25:171850
1851 MockRead data_reads[] = {
1852 MockRead("HTTP/1.0 200 OK\r\n"),
1853 MockRead("Connection: keep-alive\r\n"),
1854 MockRead("Content-Length: 100\r\n\r\n"),
1855 MockRead(SYNCHRONOUS, 0),
1856 };
1857 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:071858 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]7a5378b2012-11-04 03:25:171859
1860 TestCompletionCallback callback;
1861
tfarina42834112016-09-22 13:38:201862 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:011863 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]7a5378b2012-11-04 03:25:171864
1865 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:011866 EXPECT_THAT(rv, IsOk());
[email protected]7a5378b2012-11-04 03:25:171867
1868 scoped_refptr<IOBufferWithSize> io_buf(new IOBufferWithSize(100));
[email protected]90499482013-06-01 00:39:501869 rv = trans->Read(io_buf.get(), io_buf->size(), callback.callback());
[email protected]7a5378b2012-11-04 03:25:171870 if (rv == ERR_IO_PENDING)
1871 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:011872 EXPECT_THAT(rv, IsError(ERR_CONTENT_LENGTH_MISMATCH));
[email protected]7a5378b2012-11-04 03:25:171873
1874 trans.reset();
fdoray92e35a72016-06-10 15:54:551875 base::RunLoop().RunUntilIdle();
[email protected]7a5378b2012-11-04 03:25:171876 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
1877}
1878
[email protected]0b0bf032010-09-21 18:08:501879// Test that we correctly reuse a keep-alive connection after not explicitly
1880// reading the body.
bncd16676a2016-07-20 16:23:011881TEST_F(HttpNetworkTransactionTest, KeepAliveAfterUnreadBody) {
[email protected]fc31d6a42010-06-24 18:05:131882 HttpRequestInfo request;
1883 request.method = "GET";
1884 request.url = GURL("http://www.foo.com/");
[email protected]fc31d6a42010-06-24 18:05:131885
vishal.b62985ca92015-04-17 08:45:511886 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:071887 session_deps_.net_log = &net_log;
danakj1fd259a02016-04-16 03:17:091888 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:271889
mmenkecc2298e2015-12-07 18:20:181890 const char* request_data =
1891 "GET / HTTP/1.1\r\n"
1892 "Host: www.foo.com\r\n"
1893 "Connection: keep-alive\r\n\r\n";
1894 MockWrite data_writes[] = {
1895 MockWrite(ASYNC, 0, request_data), MockWrite(ASYNC, 2, request_data),
1896 MockWrite(ASYNC, 4, request_data), MockWrite(ASYNC, 6, request_data),
1897 MockWrite(ASYNC, 8, request_data), MockWrite(ASYNC, 10, request_data),
1898 MockWrite(ASYNC, 12, request_data), MockWrite(ASYNC, 14, request_data),
1899 MockWrite(ASYNC, 17, request_data), MockWrite(ASYNC, 20, request_data),
1900 };
1901
[email protected]0b0bf032010-09-21 18:08:501902 // Note that because all these reads happen in the same
1903 // StaticSocketDataProvider, it shows that the same socket is being reused for
1904 // all transactions.
mmenkecc2298e2015-12-07 18:20:181905 MockRead data_reads[] = {
1906 MockRead(ASYNC, 1, "HTTP/1.1 204 No Content\r\n\r\n"),
1907 MockRead(ASYNC, 3, "HTTP/1.1 205 Reset Content\r\n\r\n"),
1908 MockRead(ASYNC, 5, "HTTP/1.1 304 Not Modified\r\n\r\n"),
1909 MockRead(ASYNC, 7,
1910 "HTTP/1.1 302 Found\r\n"
1911 "Content-Length: 0\r\n\r\n"),
1912 MockRead(ASYNC, 9,
1913 "HTTP/1.1 302 Found\r\n"
1914 "Content-Length: 5\r\n\r\n"
1915 "hello"),
1916 MockRead(ASYNC, 11,
1917 "HTTP/1.1 301 Moved Permanently\r\n"
1918 "Content-Length: 0\r\n\r\n"),
1919 MockRead(ASYNC, 13,
1920 "HTTP/1.1 301 Moved Permanently\r\n"
1921 "Content-Length: 5\r\n\r\n"
1922 "hello"),
[email protected]fc31d6a42010-06-24 18:05:131923
mmenkecc2298e2015-12-07 18:20:181924 // In the next two rounds, IsConnectedAndIdle returns false, due to
1925 // the set_busy_before_sync_reads(true) call, while the
1926 // HttpNetworkTransaction is being shut down, but the socket is still
1927 // reuseable. See http://crbug.com/544255.
1928 MockRead(ASYNC, 15,
1929 "HTTP/1.1 200 Hunky-Dory\r\n"
1930 "Content-Length: 5\r\n\r\n"),
1931 MockRead(SYNCHRONOUS, 16, "hello"),
[email protected]fc31d6a42010-06-24 18:05:131932
mmenkecc2298e2015-12-07 18:20:181933 MockRead(ASYNC, 18,
1934 "HTTP/1.1 200 Hunky-Dory\r\n"
1935 "Content-Length: 5\r\n\r\n"
1936 "he"),
1937 MockRead(SYNCHRONOUS, 19, "llo"),
1938
1939 // The body of the final request is actually read.
1940 MockRead(ASYNC, 21, "HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
1941 MockRead(ASYNC, 22, "hello"),
1942 };
1943 SequencedSocketData data(data_reads, arraysize(data_reads), data_writes,
1944 arraysize(data_writes));
1945 data.set_busy_before_sync_reads(true);
1946 session_deps_.socket_factory->AddSocketDataProvider(&data);
1947
1948 const int kNumUnreadBodies = arraysize(data_writes) - 1;
[email protected]0b0bf032010-09-21 18:08:501949 std::string response_lines[kNumUnreadBodies];
1950
mikecironef22f9812016-10-04 03:40:191951 uint32_t first_socket_log_id = NetLogSource::kInvalidId;
mmenkecc2298e2015-12-07 18:20:181952 for (size_t i = 0; i < kNumUnreadBodies; ++i) {
[email protected]49639fa2011-12-20 23:22:411953 TestCompletionCallback callback;
[email protected]fc31d6a42010-06-24 18:05:131954
bnc691fda62016-08-12 00:43:161955 std::unique_ptr<HttpNetworkTransaction> trans(
[email protected]90499482013-06-01 00:39:501956 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]fc31d6a42010-06-24 18:05:131957
tfarina42834112016-09-22 13:38:201958 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:011959 EXPECT_THAT(callback.GetResult(rv), IsOk());
[email protected]fc31d6a42010-06-24 18:05:131960
[email protected]58e32bb2013-01-21 18:23:251961 LoadTimingInfo load_timing_info;
1962 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
1963 if (i == 0) {
1964 TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_DNS_TIMES);
1965 first_socket_log_id = load_timing_info.socket_log_id;
1966 } else {
1967 TestLoadTimingReused(load_timing_info);
1968 EXPECT_EQ(first_socket_log_id, load_timing_info.socket_log_id);
1969 }
1970
[email protected]fc31d6a42010-06-24 18:05:131971 const HttpResponseInfo* response = trans->GetResponseInfo();
mmenkecc2298e2015-12-07 18:20:181972 ASSERT_TRUE(response);
[email protected]fc31d6a42010-06-24 18:05:131973
mmenkecc2298e2015-12-07 18:20:181974 ASSERT_TRUE(response->headers);
[email protected]0b0bf032010-09-21 18:08:501975 response_lines[i] = response->headers->GetStatusLine();
1976
mmenkecc2298e2015-12-07 18:20:181977 // Delete the transaction without reading the response bodies. Then spin
1978 // the message loop, so the response bodies are drained.
1979 trans.reset();
1980 base::RunLoop().RunUntilIdle();
[email protected]fc31d6a42010-06-24 18:05:131981 }
[email protected]0b0bf032010-09-21 18:08:501982
1983 const char* const kStatusLines[] = {
mmenkecc2298e2015-12-07 18:20:181984 "HTTP/1.1 204 No Content",
1985 "HTTP/1.1 205 Reset Content",
1986 "HTTP/1.1 304 Not Modified",
1987 "HTTP/1.1 302 Found",
1988 "HTTP/1.1 302 Found",
1989 "HTTP/1.1 301 Moved Permanently",
1990 "HTTP/1.1 301 Moved Permanently",
1991 "HTTP/1.1 200 Hunky-Dory",
1992 "HTTP/1.1 200 Hunky-Dory",
[email protected]0b0bf032010-09-21 18:08:501993 };
1994
mostynb91e0da982015-01-20 19:17:271995 static_assert(kNumUnreadBodies == arraysize(kStatusLines),
1996 "forgot to update kStatusLines");
[email protected]0b0bf032010-09-21 18:08:501997
1998 for (int i = 0; i < kNumUnreadBodies; ++i)
1999 EXPECT_EQ(kStatusLines[i], response_lines[i]);
2000
[email protected]49639fa2011-12-20 23:22:412001 TestCompletionCallback callback;
bnc691fda62016-08-12 00:43:162002 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:202003 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012004 EXPECT_THAT(callback.GetResult(rv), IsOk());
bnc691fda62016-08-12 00:43:162005 const HttpResponseInfo* response = trans.GetResponseInfo();
mmenkecc2298e2015-12-07 18:20:182006 ASSERT_TRUE(response);
2007 ASSERT_TRUE(response->headers);
[email protected]0b0bf032010-09-21 18:08:502008 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
2009 std::string response_data;
bnc691fda62016-08-12 00:43:162010 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:012011 EXPECT_THAT(rv, IsOk());
[email protected]0b0bf032010-09-21 18:08:502012 EXPECT_EQ("hello", response_data);
[email protected]fc31d6a42010-06-24 18:05:132013}
2014
mmenke5f94fda2016-06-02 20:54:132015// Sockets that receive extra data after a response is complete should not be
2016// reused.
bncd16676a2016-07-20 16:23:012017TEST_F(HttpNetworkTransactionTest, KeepAliveWithUnusedData1) {
mmenke5f94fda2016-06-02 20:54:132018 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
2019 MockWrite data_writes1[] = {
2020 MockWrite("HEAD / HTTP/1.1\r\n"
2021 "Host: www.borked.com\r\n"
2022 "Connection: keep-alive\r\n\r\n"),
2023 };
2024
2025 MockRead data_reads1[] = {
2026 MockRead("HTTP/1.1 200 OK\r\n"
2027 "Connection: keep-alive\r\n"
2028 "Content-Length: 22\r\n\r\n"
2029 "This server is borked."),
2030 };
2031
2032 MockWrite data_writes2[] = {
2033 MockWrite("GET /foo HTTP/1.1\r\n"
2034 "Host: www.borked.com\r\n"
2035 "Connection: keep-alive\r\n\r\n"),
2036 };
2037
2038 MockRead data_reads2[] = {
2039 MockRead("HTTP/1.1 200 OK\r\n"
2040 "Content-Length: 3\r\n\r\n"
2041 "foo"),
2042 };
2043 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
2044 data_writes1, arraysize(data_writes1));
2045 session_deps_.socket_factory->AddSocketDataProvider(&data1);
2046 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
2047 data_writes2, arraysize(data_writes2));
2048 session_deps_.socket_factory->AddSocketDataProvider(&data2);
2049
2050 TestCompletionCallback callback;
2051 HttpRequestInfo request1;
2052 request1.method = "HEAD";
2053 request1.url = GURL("http://www.borked.com/");
2054
bnc691fda62016-08-12 00:43:162055 std::unique_ptr<HttpNetworkTransaction> trans1(
mmenke5f94fda2016-06-02 20:54:132056 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
tfarina42834112016-09-22 13:38:202057 int rv = trans1->Start(&request1, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012058 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenke5f94fda2016-06-02 20:54:132059
2060 const HttpResponseInfo* response1 = trans1->GetResponseInfo();
2061 ASSERT_TRUE(response1);
2062 ASSERT_TRUE(response1->headers);
2063 EXPECT_EQ(200, response1->headers->response_code());
2064 EXPECT_TRUE(response1->headers->IsKeepAlive());
2065
2066 std::string response_data1;
robpercival214763f2016-07-01 23:27:012067 EXPECT_THAT(ReadTransaction(trans1.get(), &response_data1), IsOk());
mmenke5f94fda2016-06-02 20:54:132068 EXPECT_EQ("", response_data1);
2069 // Deleting the transaction attempts to release the socket back into the
2070 // socket pool.
2071 trans1.reset();
2072
2073 HttpRequestInfo request2;
2074 request2.method = "GET";
2075 request2.url = GURL("http://www.borked.com/foo");
2076
bnc691fda62016-08-12 00:43:162077 std::unique_ptr<HttpNetworkTransaction> trans2(
mmenke5f94fda2016-06-02 20:54:132078 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
tfarina42834112016-09-22 13:38:202079 rv = trans2->Start(&request2, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012080 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenke5f94fda2016-06-02 20:54:132081
2082 const HttpResponseInfo* response2 = trans2->GetResponseInfo();
2083 ASSERT_TRUE(response2);
2084 ASSERT_TRUE(response2->headers);
2085 EXPECT_EQ(200, response2->headers->response_code());
2086
2087 std::string response_data2;
robpercival214763f2016-07-01 23:27:012088 EXPECT_THAT(ReadTransaction(trans2.get(), &response_data2), IsOk());
mmenke5f94fda2016-06-02 20:54:132089 EXPECT_EQ("foo", response_data2);
2090}
2091
bncd16676a2016-07-20 16:23:012092TEST_F(HttpNetworkTransactionTest, KeepAliveWithUnusedData2) {
mmenke5f94fda2016-06-02 20:54:132093 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
2094 MockWrite data_writes1[] = {
2095 MockWrite("GET / HTTP/1.1\r\n"
2096 "Host: www.borked.com\r\n"
2097 "Connection: keep-alive\r\n\r\n"),
2098 };
2099
2100 MockRead data_reads1[] = {
2101 MockRead("HTTP/1.1 200 OK\r\n"
2102 "Connection: keep-alive\r\n"
2103 "Content-Length: 22\r\n\r\n"
2104 "This server is borked."
2105 "Bonus data!"),
2106 };
2107
2108 MockWrite data_writes2[] = {
2109 MockWrite("GET /foo HTTP/1.1\r\n"
2110 "Host: www.borked.com\r\n"
2111 "Connection: keep-alive\r\n\r\n"),
2112 };
2113
2114 MockRead data_reads2[] = {
2115 MockRead("HTTP/1.1 200 OK\r\n"
2116 "Content-Length: 3\r\n\r\n"
2117 "foo"),
2118 };
2119 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
2120 data_writes1, arraysize(data_writes1));
2121 session_deps_.socket_factory->AddSocketDataProvider(&data1);
2122 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
2123 data_writes2, arraysize(data_writes2));
2124 session_deps_.socket_factory->AddSocketDataProvider(&data2);
2125
2126 TestCompletionCallback callback;
2127 HttpRequestInfo request1;
2128 request1.method = "GET";
2129 request1.url = GURL("http://www.borked.com/");
2130
bnc691fda62016-08-12 00:43:162131 std::unique_ptr<HttpNetworkTransaction> trans1(
mmenke5f94fda2016-06-02 20:54:132132 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
tfarina42834112016-09-22 13:38:202133 int rv = trans1->Start(&request1, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012134 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenke5f94fda2016-06-02 20:54:132135
2136 const HttpResponseInfo* response1 = trans1->GetResponseInfo();
2137 ASSERT_TRUE(response1);
2138 ASSERT_TRUE(response1->headers);
2139 EXPECT_EQ(200, response1->headers->response_code());
2140 EXPECT_TRUE(response1->headers->IsKeepAlive());
2141
2142 std::string response_data1;
robpercival214763f2016-07-01 23:27:012143 EXPECT_THAT(ReadTransaction(trans1.get(), &response_data1), IsOk());
mmenke5f94fda2016-06-02 20:54:132144 EXPECT_EQ("This server is borked.", response_data1);
2145 // Deleting the transaction attempts to release the socket back into the
2146 // socket pool.
2147 trans1.reset();
2148
2149 HttpRequestInfo request2;
2150 request2.method = "GET";
2151 request2.url = GURL("http://www.borked.com/foo");
2152
bnc691fda62016-08-12 00:43:162153 std::unique_ptr<HttpNetworkTransaction> trans2(
mmenke5f94fda2016-06-02 20:54:132154 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
tfarina42834112016-09-22 13:38:202155 rv = trans2->Start(&request2, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012156 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenke5f94fda2016-06-02 20:54:132157
2158 const HttpResponseInfo* response2 = trans2->GetResponseInfo();
2159 ASSERT_TRUE(response2);
2160 ASSERT_TRUE(response2->headers);
2161 EXPECT_EQ(200, response2->headers->response_code());
2162
2163 std::string response_data2;
robpercival214763f2016-07-01 23:27:012164 EXPECT_THAT(ReadTransaction(trans2.get(), &response_data2), IsOk());
mmenke5f94fda2016-06-02 20:54:132165 EXPECT_EQ("foo", response_data2);
2166}
2167
bncd16676a2016-07-20 16:23:012168TEST_F(HttpNetworkTransactionTest, KeepAliveWithUnusedData3) {
mmenke5f94fda2016-06-02 20:54:132169 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
2170 MockWrite data_writes1[] = {
2171 MockWrite("GET / HTTP/1.1\r\n"
2172 "Host: www.borked.com\r\n"
2173 "Connection: keep-alive\r\n\r\n"),
2174 };
2175
2176 MockRead data_reads1[] = {
2177 MockRead("HTTP/1.1 200 OK\r\n"
2178 "Connection: keep-alive\r\n"
2179 "Transfer-Encoding: chunked\r\n\r\n"),
2180 MockRead("16\r\nThis server is borked.\r\n"),
2181 MockRead("0\r\n\r\nBonus data!"),
2182 };
2183
2184 MockWrite data_writes2[] = {
2185 MockWrite("GET /foo HTTP/1.1\r\n"
2186 "Host: www.borked.com\r\n"
2187 "Connection: keep-alive\r\n\r\n"),
2188 };
2189
2190 MockRead data_reads2[] = {
2191 MockRead("HTTP/1.1 200 OK\r\n"
2192 "Content-Length: 3\r\n\r\n"
2193 "foo"),
2194 };
2195 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
2196 data_writes1, arraysize(data_writes1));
2197 session_deps_.socket_factory->AddSocketDataProvider(&data1);
2198 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
2199 data_writes2, arraysize(data_writes2));
2200 session_deps_.socket_factory->AddSocketDataProvider(&data2);
2201
2202 TestCompletionCallback callback;
2203 HttpRequestInfo request1;
2204 request1.method = "GET";
2205 request1.url = GURL("http://www.borked.com/");
2206
bnc691fda62016-08-12 00:43:162207 std::unique_ptr<HttpNetworkTransaction> trans1(
mmenke5f94fda2016-06-02 20:54:132208 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
tfarina42834112016-09-22 13:38:202209 int rv = trans1->Start(&request1, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012210 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenke5f94fda2016-06-02 20:54:132211
2212 const HttpResponseInfo* response1 = trans1->GetResponseInfo();
2213 ASSERT_TRUE(response1);
2214 ASSERT_TRUE(response1->headers);
2215 EXPECT_EQ(200, response1->headers->response_code());
2216 EXPECT_TRUE(response1->headers->IsKeepAlive());
2217
2218 std::string response_data1;
robpercival214763f2016-07-01 23:27:012219 EXPECT_THAT(ReadTransaction(trans1.get(), &response_data1), IsOk());
mmenke5f94fda2016-06-02 20:54:132220 EXPECT_EQ("This server is borked.", response_data1);
2221 // Deleting the transaction attempts to release the socket back into the
2222 // socket pool.
2223 trans1.reset();
2224
2225 HttpRequestInfo request2;
2226 request2.method = "GET";
2227 request2.url = GURL("http://www.borked.com/foo");
2228
bnc691fda62016-08-12 00:43:162229 std::unique_ptr<HttpNetworkTransaction> trans2(
mmenke5f94fda2016-06-02 20:54:132230 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
tfarina42834112016-09-22 13:38:202231 rv = trans2->Start(&request2, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012232 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenke5f94fda2016-06-02 20:54:132233
2234 const HttpResponseInfo* response2 = trans2->GetResponseInfo();
2235 ASSERT_TRUE(response2);
2236 ASSERT_TRUE(response2->headers);
2237 EXPECT_EQ(200, response2->headers->response_code());
2238
2239 std::string response_data2;
robpercival214763f2016-07-01 23:27:012240 EXPECT_THAT(ReadTransaction(trans2.get(), &response_data2), IsOk());
mmenke5f94fda2016-06-02 20:54:132241 EXPECT_EQ("foo", response_data2);
2242}
2243
2244// This is a little different from the others - it tests the case that the
2245// HttpStreamParser doesn't know if there's extra data on a socket or not when
2246// the HttpNetworkTransaction is torn down, because the response body hasn't
2247// been read from yet, but the request goes through the HttpResponseBodyDrainer.
bncd16676a2016-07-20 16:23:012248TEST_F(HttpNetworkTransactionTest, KeepAliveWithUnusedData4) {
mmenke5f94fda2016-06-02 20:54:132249 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
2250 MockWrite data_writes1[] = {
2251 MockWrite("GET / HTTP/1.1\r\n"
2252 "Host: www.borked.com\r\n"
2253 "Connection: keep-alive\r\n\r\n"),
2254 };
2255
2256 MockRead data_reads1[] = {
2257 MockRead("HTTP/1.1 200 OK\r\n"
2258 "Connection: keep-alive\r\n"
2259 "Transfer-Encoding: chunked\r\n\r\n"),
2260 MockRead("16\r\nThis server is borked.\r\n"),
2261 MockRead("0\r\n\r\nBonus data!"),
2262 };
2263 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
2264 data_writes1, arraysize(data_writes1));
2265 session_deps_.socket_factory->AddSocketDataProvider(&data1);
2266
2267 TestCompletionCallback callback;
2268 HttpRequestInfo request1;
2269 request1.method = "GET";
2270 request1.url = GURL("http://www.borked.com/");
2271
bnc691fda62016-08-12 00:43:162272 std::unique_ptr<HttpNetworkTransaction> trans1(
mmenke5f94fda2016-06-02 20:54:132273 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
tfarina42834112016-09-22 13:38:202274 int rv = trans1->Start(&request1, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012275 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenke5f94fda2016-06-02 20:54:132276
2277 const HttpResponseInfo* response1 = trans1->GetResponseInfo();
2278 ASSERT_TRUE(response1);
2279 ASSERT_TRUE(response1->headers);
2280 EXPECT_EQ(200, response1->headers->response_code());
2281 EXPECT_TRUE(response1->headers->IsKeepAlive());
2282
2283 // Deleting the transaction creates an HttpResponseBodyDrainer to read the
2284 // response body.
2285 trans1.reset();
2286
2287 // Let the HttpResponseBodyDrainer drain the socket. It should determine the
2288 // socket can't be reused, rather than returning it to the socket pool.
2289 base::RunLoop().RunUntilIdle();
2290
2291 // There should be no idle sockets in the pool.
2292 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
2293}
2294
[email protected]038e9a32008-10-08 22:40:162295// Test the request-challenge-retry sequence for basic auth.
2296// (basic auth is the easiest to mock, because it has no randomness).
bncd16676a2016-07-20 16:23:012297TEST_F(HttpNetworkTransactionTest, BasicAuth) {
[email protected]1c773ea12009-04-28 19:58:422298 HttpRequestInfo request;
[email protected]038e9a32008-10-08 22:40:162299 request.method = "GET";
bncce36dca22015-04-21 22:11:232300 request.url = GURL("http://www.example.org/");
[email protected]038e9a32008-10-08 22:40:162301
vishal.b62985ca92015-04-17 08:45:512302 TestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:072303 session_deps_.net_log = &log;
danakj1fd259a02016-04-16 03:17:092304 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:162305 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:272306
[email protected]f9ee6b52008-11-08 06:46:232307 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:232308 MockWrite(
2309 "GET / HTTP/1.1\r\n"
2310 "Host: www.example.org\r\n"
2311 "Connection: keep-alive\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:232312 };
2313
[email protected]038e9a32008-10-08 22:40:162314 MockRead data_reads1[] = {
2315 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
2316 // Give a couple authenticate options (only the middle one is actually
2317 // supported).
[email protected]22927ad2009-09-21 19:56:192318 MockRead("WWW-Authenticate: Basic invalid\r\n"), // Malformed.
[email protected]038e9a32008-10-08 22:40:162319 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2320 MockRead("WWW-Authenticate: UNSUPPORTED realm=\"FOO\"\r\n"),
2321 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
2322 // Large content-length -- won't matter, as connection will be reset.
2323 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:062324 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]038e9a32008-10-08 22:40:162325 };
2326
2327 // After calling trans->RestartWithAuth(), this is the request we should
2328 // be issuing -- the final header line contains the credentials.
2329 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:232330 MockWrite(
2331 "GET / HTTP/1.1\r\n"
2332 "Host: www.example.org\r\n"
2333 "Connection: keep-alive\r\n"
2334 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]038e9a32008-10-08 22:40:162335 };
2336
2337 // Lastly, the server responds with the actual content.
2338 MockRead data_reads2[] = {
2339 MockRead("HTTP/1.0 200 OK\r\n"),
2340 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
2341 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:062342 MockRead(SYNCHRONOUS, OK),
[email protected]038e9a32008-10-08 22:40:162343 };
2344
[email protected]31a2bfe2010-02-09 08:03:392345 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
2346 data_writes1, arraysize(data_writes1));
2347 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
2348 data_writes2, arraysize(data_writes2));
[email protected]bb88e1d32013-05-03 23:11:072349 session_deps_.socket_factory->AddSocketDataProvider(&data1);
2350 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]038e9a32008-10-08 22:40:162351
[email protected]49639fa2011-12-20 23:22:412352 TestCompletionCallback callback1;
[email protected]038e9a32008-10-08 22:40:162353
tfarina42834112016-09-22 13:38:202354 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012355 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]038e9a32008-10-08 22:40:162356
2357 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:012358 EXPECT_THAT(rv, IsOk());
[email protected]038e9a32008-10-08 22:40:162359
[email protected]58e32bb2013-01-21 18:23:252360 LoadTimingInfo load_timing_info1;
bnc691fda62016-08-12 00:43:162361 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info1));
[email protected]58e32bb2013-01-21 18:23:252362 TestLoadTimingNotReused(load_timing_info1, CONNECT_TIMING_HAS_DNS_TIMES);
2363
sclittlefb249892015-09-10 21:33:222364 int64_t writes_size1 = CountWriteBytes(data_writes1, arraysize(data_writes1));
bnc691fda62016-08-12 00:43:162365 EXPECT_EQ(writes_size1, trans.GetTotalSentBytes());
sclittlefb249892015-09-10 21:33:222366 int64_t reads_size1 = CountReadBytes(data_reads1, arraysize(data_reads1));
bnc691fda62016-08-12 00:43:162367 EXPECT_EQ(reads_size1, trans.GetTotalReceivedBytes());
[email protected]b8015c42013-12-24 15:18:192368
bnc691fda62016-08-12 00:43:162369 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:522370 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:042371 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]038e9a32008-10-08 22:40:162372
[email protected]49639fa2011-12-20 23:22:412373 TestCompletionCallback callback2;
[email protected]038e9a32008-10-08 22:40:162374
bnc691fda62016-08-12 00:43:162375 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar), callback2.callback());
robpercival214763f2016-07-01 23:27:012376 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]038e9a32008-10-08 22:40:162377
2378 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:012379 EXPECT_THAT(rv, IsOk());
[email protected]038e9a32008-10-08 22:40:162380
[email protected]58e32bb2013-01-21 18:23:252381 LoadTimingInfo load_timing_info2;
bnc691fda62016-08-12 00:43:162382 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info2));
[email protected]58e32bb2013-01-21 18:23:252383 TestLoadTimingNotReused(load_timing_info2, CONNECT_TIMING_HAS_DNS_TIMES);
2384 // The load timing after restart should have a new socket ID, and times after
2385 // those of the first load timing.
2386 EXPECT_LE(load_timing_info1.receive_headers_end,
2387 load_timing_info2.connect_timing.connect_start);
2388 EXPECT_NE(load_timing_info1.socket_log_id, load_timing_info2.socket_log_id);
2389
sclittlefb249892015-09-10 21:33:222390 int64_t writes_size2 = CountWriteBytes(data_writes2, arraysize(data_writes2));
bnc691fda62016-08-12 00:43:162391 EXPECT_EQ(writes_size1 + writes_size2, trans.GetTotalSentBytes());
sclittlefb249892015-09-10 21:33:222392 int64_t reads_size2 = CountReadBytes(data_reads2, arraysize(data_reads2));
bnc691fda62016-08-12 00:43:162393 EXPECT_EQ(reads_size1 + reads_size2, trans.GetTotalReceivedBytes());
[email protected]b8015c42013-12-24 15:18:192394
bnc691fda62016-08-12 00:43:162395 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:522396 ASSERT_TRUE(response);
2397 EXPECT_FALSE(response->auth_challenge);
[email protected]038e9a32008-10-08 22:40:162398 EXPECT_EQ(100, response->headers->GetContentLength());
[email protected]038e9a32008-10-08 22:40:162399}
2400
ttuttled9dbc652015-09-29 20:00:592401// Test the request-challenge-retry sequence for basic auth.
2402// (basic auth is the easiest to mock, because it has no randomness).
bncd16676a2016-07-20 16:23:012403TEST_F(HttpNetworkTransactionTest, BasicAuthWithAddressChange) {
ttuttled9dbc652015-09-29 20:00:592404 HttpRequestInfo request;
2405 request.method = "GET";
2406 request.url = GURL("http://www.example.org/");
ttuttled9dbc652015-09-29 20:00:592407
2408 TestNetLog log;
2409 MockHostResolver* resolver = new MockHostResolver();
2410 session_deps_.net_log = &log;
2411 session_deps_.host_resolver.reset(resolver);
danakj1fd259a02016-04-16 03:17:092412 std::unique_ptr<HttpNetworkSession> session = CreateSession(&session_deps_);
bnc691fda62016-08-12 00:43:162413 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
ttuttled9dbc652015-09-29 20:00:592414
2415 resolver->rules()->ClearRules();
2416 resolver->rules()->AddRule("www.example.org", "127.0.0.1");
2417
2418 MockWrite data_writes1[] = {
2419 MockWrite("GET / HTTP/1.1\r\n"
2420 "Host: www.example.org\r\n"
2421 "Connection: keep-alive\r\n\r\n"),
2422 };
2423
2424 MockRead data_reads1[] = {
2425 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
2426 // Give a couple authenticate options (only the middle one is actually
2427 // supported).
2428 MockRead("WWW-Authenticate: Basic invalid\r\n"), // Malformed.
2429 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2430 MockRead("WWW-Authenticate: UNSUPPORTED realm=\"FOO\"\r\n"),
2431 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
2432 // Large content-length -- won't matter, as connection will be reset.
2433 MockRead("Content-Length: 10000\r\n\r\n"),
2434 MockRead(SYNCHRONOUS, ERR_FAILED),
2435 };
2436
2437 // After calling trans->RestartWithAuth(), this is the request we should
2438 // be issuing -- the final header line contains the credentials.
2439 MockWrite data_writes2[] = {
2440 MockWrite("GET / HTTP/1.1\r\n"
2441 "Host: www.example.org\r\n"
2442 "Connection: keep-alive\r\n"
2443 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
2444 };
2445
2446 // Lastly, the server responds with the actual content.
2447 MockRead data_reads2[] = {
2448 MockRead("HTTP/1.0 200 OK\r\n"),
2449 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
2450 MockRead("Content-Length: 100\r\n\r\n"), MockRead(SYNCHRONOUS, OK),
2451 };
2452
2453 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
2454 data_writes1, arraysize(data_writes1));
2455 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
2456 data_writes2, arraysize(data_writes2));
2457 session_deps_.socket_factory->AddSocketDataProvider(&data1);
2458 session_deps_.socket_factory->AddSocketDataProvider(&data2);
2459
2460 TestCompletionCallback callback1;
2461
bnc691fda62016-08-12 00:43:162462 EXPECT_EQ(OK, callback1.GetResult(trans.Start(&request, callback1.callback(),
tfarina42834112016-09-22 13:38:202463 NetLogWithSource())));
ttuttled9dbc652015-09-29 20:00:592464
2465 LoadTimingInfo load_timing_info1;
bnc691fda62016-08-12 00:43:162466 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info1));
ttuttled9dbc652015-09-29 20:00:592467 TestLoadTimingNotReused(load_timing_info1, CONNECT_TIMING_HAS_DNS_TIMES);
2468
2469 int64_t writes_size1 = CountWriteBytes(data_writes1, arraysize(data_writes1));
bnc691fda62016-08-12 00:43:162470 EXPECT_EQ(writes_size1, trans.GetTotalSentBytes());
ttuttled9dbc652015-09-29 20:00:592471 int64_t reads_size1 = CountReadBytes(data_reads1, arraysize(data_reads1));
bnc691fda62016-08-12 00:43:162472 EXPECT_EQ(reads_size1, trans.GetTotalReceivedBytes());
ttuttled9dbc652015-09-29 20:00:592473
bnc691fda62016-08-12 00:43:162474 const HttpResponseInfo* response = trans.GetResponseInfo();
ttuttled9dbc652015-09-29 20:00:592475 ASSERT_TRUE(response);
2476 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
2477
2478 IPEndPoint endpoint;
bnc691fda62016-08-12 00:43:162479 EXPECT_TRUE(trans.GetRemoteEndpoint(&endpoint));
ttuttled9dbc652015-09-29 20:00:592480 ASSERT_FALSE(endpoint.address().empty());
2481 EXPECT_EQ("127.0.0.1:80", endpoint.ToString());
2482
2483 resolver->rules()->ClearRules();
2484 resolver->rules()->AddRule("www.example.org", "127.0.0.2");
2485
2486 TestCompletionCallback callback2;
2487
bnc691fda62016-08-12 00:43:162488 EXPECT_EQ(OK, callback2.GetResult(trans.RestartWithAuth(
ttuttled9dbc652015-09-29 20:00:592489 AuthCredentials(kFoo, kBar), callback2.callback())));
2490
2491 LoadTimingInfo load_timing_info2;
bnc691fda62016-08-12 00:43:162492 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info2));
ttuttled9dbc652015-09-29 20:00:592493 TestLoadTimingNotReused(load_timing_info2, CONNECT_TIMING_HAS_DNS_TIMES);
2494 // The load timing after restart should have a new socket ID, and times after
2495 // those of the first load timing.
2496 EXPECT_LE(load_timing_info1.receive_headers_end,
2497 load_timing_info2.connect_timing.connect_start);
2498 EXPECT_NE(load_timing_info1.socket_log_id, load_timing_info2.socket_log_id);
2499
2500 int64_t writes_size2 = CountWriteBytes(data_writes2, arraysize(data_writes2));
bnc691fda62016-08-12 00:43:162501 EXPECT_EQ(writes_size1 + writes_size2, trans.GetTotalSentBytes());
ttuttled9dbc652015-09-29 20:00:592502 int64_t reads_size2 = CountReadBytes(data_reads2, arraysize(data_reads2));
bnc691fda62016-08-12 00:43:162503 EXPECT_EQ(reads_size1 + reads_size2, trans.GetTotalReceivedBytes());
ttuttled9dbc652015-09-29 20:00:592504
bnc691fda62016-08-12 00:43:162505 response = trans.GetResponseInfo();
ttuttled9dbc652015-09-29 20:00:592506 ASSERT_TRUE(response);
wezca1070932016-05-26 20:30:522507 EXPECT_FALSE(response->auth_challenge);
ttuttled9dbc652015-09-29 20:00:592508 EXPECT_EQ(100, response->headers->GetContentLength());
2509
bnc691fda62016-08-12 00:43:162510 EXPECT_TRUE(trans.GetRemoteEndpoint(&endpoint));
ttuttled9dbc652015-09-29 20:00:592511 ASSERT_FALSE(endpoint.address().empty());
2512 EXPECT_EQ("127.0.0.2:80", endpoint.ToString());
2513}
2514
bncd16676a2016-07-20 16:23:012515TEST_F(HttpNetworkTransactionTest, DoNotSendAuth) {
[email protected]861fcd52009-08-26 02:33:462516 HttpRequestInfo request;
2517 request.method = "GET";
bncce36dca22015-04-21 22:11:232518 request.url = GURL("http://www.example.org/");
ttuttle859dc7a2015-04-23 19:42:292519 request.load_flags = LOAD_DO_NOT_SEND_AUTH_DATA;
[email protected]861fcd52009-08-26 02:33:462520
danakj1fd259a02016-04-16 03:17:092521 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:162522 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:272523
[email protected]861fcd52009-08-26 02:33:462524 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:232525 MockWrite(
2526 "GET / HTTP/1.1\r\n"
2527 "Host: www.example.org\r\n"
2528 "Connection: keep-alive\r\n\r\n"),
[email protected]861fcd52009-08-26 02:33:462529 };
2530
2531 MockRead data_reads[] = {
2532 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
2533 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2534 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
2535 // Large content-length -- won't matter, as connection will be reset.
2536 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:062537 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]861fcd52009-08-26 02:33:462538 };
2539
[email protected]31a2bfe2010-02-09 08:03:392540 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
2541 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:072542 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]49639fa2011-12-20 23:22:412543 TestCompletionCallback callback;
[email protected]861fcd52009-08-26 02:33:462544
tfarina42834112016-09-22 13:38:202545 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012546 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]861fcd52009-08-26 02:33:462547
2548 rv = callback.WaitForResult();
2549 EXPECT_EQ(0, rv);
2550
sclittlefb249892015-09-10 21:33:222551 int64_t writes_size = CountWriteBytes(data_writes, arraysize(data_writes));
bnc691fda62016-08-12 00:43:162552 EXPECT_EQ(writes_size, trans.GetTotalSentBytes());
sclittlefb249892015-09-10 21:33:222553 int64_t reads_size = CountReadBytes(data_reads, arraysize(data_reads));
bnc691fda62016-08-12 00:43:162554 EXPECT_EQ(reads_size, trans.GetTotalReceivedBytes());
[email protected]b8015c42013-12-24 15:18:192555
bnc691fda62016-08-12 00:43:162556 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:522557 ASSERT_TRUE(response);
2558 EXPECT_FALSE(response->auth_challenge);
[email protected]861fcd52009-08-26 02:33:462559}
2560
[email protected]2d2697f92009-02-18 21:00:322561// Test the request-challenge-retry sequence for basic auth, over a keep-alive
2562// connection.
bncd16676a2016-07-20 16:23:012563TEST_F(HttpNetworkTransactionTest, BasicAuthKeepAlive) {
mmenkecc2298e2015-12-07 18:20:182564 // On the second pass, the body read of the auth challenge is synchronous, so
2565 // IsConnectedAndIdle returns false. The socket should still be drained and
2566 // reused. See http://crbug.com/544255.
2567 for (int i = 0; i < 2; ++i) {
2568 HttpRequestInfo request;
2569 request.method = "GET";
2570 request.url = GURL("http://www.example.org/");
[email protected]2d2697f92009-02-18 21:00:322571
mmenkecc2298e2015-12-07 18:20:182572 TestNetLog log;
2573 session_deps_.net_log = &log;
danakj1fd259a02016-04-16 03:17:092574 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:272575
mmenkecc2298e2015-12-07 18:20:182576 MockWrite data_writes[] = {
2577 MockWrite(ASYNC, 0,
2578 "GET / HTTP/1.1\r\n"
2579 "Host: www.example.org\r\n"
2580 "Connection: keep-alive\r\n\r\n"),
[email protected]2d2697f92009-02-18 21:00:322581
bnc691fda62016-08-12 00:43:162582 // After calling trans.RestartWithAuth(), this is the request we should
mmenkecc2298e2015-12-07 18:20:182583 // be issuing -- the final header line contains the credentials.
2584 MockWrite(ASYNC, 6,
2585 "GET / HTTP/1.1\r\n"
2586 "Host: www.example.org\r\n"
2587 "Connection: keep-alive\r\n"
2588 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
2589 };
[email protected]2d2697f92009-02-18 21:00:322590
mmenkecc2298e2015-12-07 18:20:182591 MockRead data_reads[] = {
2592 MockRead(ASYNC, 1, "HTTP/1.1 401 Unauthorized\r\n"),
2593 MockRead(ASYNC, 2, "WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2594 MockRead(ASYNC, 3, "Content-Type: text/html; charset=iso-8859-1\r\n"),
2595 MockRead(ASYNC, 4, "Content-Length: 14\r\n\r\n"),
2596 MockRead(i == 0 ? ASYNC : SYNCHRONOUS, 5, "Unauthorized\r\n"),
[email protected]2d2697f92009-02-18 21:00:322597
mmenkecc2298e2015-12-07 18:20:182598 // Lastly, the server responds with the actual content.
2599 MockRead(ASYNC, 7, "HTTP/1.1 200 OK\r\n"),
2600 MockRead(ASYNC, 8, "Content-Type: text/html; charset=iso-8859-1\r\n"),
2601 MockRead(ASYNC, 9, "Content-Length: 5\r\n\r\n"),
2602 MockRead(ASYNC, 10, "Hello"),
2603 };
[email protected]2d2697f92009-02-18 21:00:322604
mmenkecc2298e2015-12-07 18:20:182605 SequencedSocketData data(data_reads, arraysize(data_reads), data_writes,
2606 arraysize(data_writes));
2607 data.set_busy_before_sync_reads(true);
2608 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]2d0a4f92011-05-05 16:38:462609
mmenkecc2298e2015-12-07 18:20:182610 TestCompletionCallback callback1;
[email protected]2d2697f92009-02-18 21:00:322611
bnc691fda62016-08-12 00:43:162612 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:202613 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012614 ASSERT_THAT(callback1.GetResult(rv), IsOk());
[email protected]2d2697f92009-02-18 21:00:322615
mmenkecc2298e2015-12-07 18:20:182616 LoadTimingInfo load_timing_info1;
bnc691fda62016-08-12 00:43:162617 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info1));
mmenkecc2298e2015-12-07 18:20:182618 TestLoadTimingNotReused(load_timing_info1, CONNECT_TIMING_HAS_DNS_TIMES);
[email protected]2d2697f92009-02-18 21:00:322619
bnc691fda62016-08-12 00:43:162620 const HttpResponseInfo* response = trans.GetResponseInfo();
mmenkecc2298e2015-12-07 18:20:182621 ASSERT_TRUE(response);
2622 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]2d2697f92009-02-18 21:00:322623
mmenkecc2298e2015-12-07 18:20:182624 TestCompletionCallback callback2;
[email protected]58e32bb2013-01-21 18:23:252625
bnc691fda62016-08-12 00:43:162626 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar),
2627 callback2.callback());
robpercival214763f2016-07-01 23:27:012628 ASSERT_THAT(callback2.GetResult(rv), IsOk());
[email protected]2d2697f92009-02-18 21:00:322629
mmenkecc2298e2015-12-07 18:20:182630 LoadTimingInfo load_timing_info2;
bnc691fda62016-08-12 00:43:162631 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info2));
mmenkecc2298e2015-12-07 18:20:182632 TestLoadTimingReused(load_timing_info2);
2633 // The load timing after restart should have the same socket ID, and times
2634 // those of the first load timing.
2635 EXPECT_LE(load_timing_info1.receive_headers_end,
2636 load_timing_info2.send_start);
2637 EXPECT_EQ(load_timing_info1.socket_log_id, load_timing_info2.socket_log_id);
[email protected]2d2697f92009-02-18 21:00:322638
bnc691fda62016-08-12 00:43:162639 response = trans.GetResponseInfo();
mmenkecc2298e2015-12-07 18:20:182640 ASSERT_TRUE(response);
2641 EXPECT_FALSE(response->auth_challenge);
2642 EXPECT_EQ(5, response->headers->GetContentLength());
[email protected]2d2697f92009-02-18 21:00:322643
mmenkecc2298e2015-12-07 18:20:182644 std::string response_data;
bnc691fda62016-08-12 00:43:162645 EXPECT_THAT(ReadTransaction(&trans, &response_data), IsOk());
[email protected]2d2697f92009-02-18 21:00:322646
mmenkecc2298e2015-12-07 18:20:182647 int64_t writes_size = CountWriteBytes(data_writes, arraysize(data_writes));
bnc691fda62016-08-12 00:43:162648 EXPECT_EQ(writes_size, trans.GetTotalSentBytes());
mmenkecc2298e2015-12-07 18:20:182649 int64_t reads_size = CountReadBytes(data_reads, arraysize(data_reads));
bnc691fda62016-08-12 00:43:162650 EXPECT_EQ(reads_size, trans.GetTotalReceivedBytes());
mmenkecc2298e2015-12-07 18:20:182651 }
[email protected]2d2697f92009-02-18 21:00:322652}
2653
2654// Test the request-challenge-retry sequence for basic auth, over a keep-alive
2655// connection and with no response body to drain.
bncd16676a2016-07-20 16:23:012656TEST_F(HttpNetworkTransactionTest, BasicAuthKeepAliveNoBody) {
[email protected]1c773ea12009-04-28 19:58:422657 HttpRequestInfo request;
[email protected]2d2697f92009-02-18 21:00:322658 request.method = "GET";
bncce36dca22015-04-21 22:11:232659 request.url = GURL("http://www.example.org/");
[email protected]2d2697f92009-02-18 21:00:322660
danakj1fd259a02016-04-16 03:17:092661 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:272662
[email protected]2d2697f92009-02-18 21:00:322663 MockWrite data_writes1[] = {
bnc691fda62016-08-12 00:43:162664 MockWrite("GET / HTTP/1.1\r\n"
2665 "Host: www.example.org\r\n"
2666 "Connection: keep-alive\r\n\r\n"),
[email protected]2d2697f92009-02-18 21:00:322667
bnc691fda62016-08-12 00:43:162668 // After calling trans.RestartWithAuth(), this is the request we should
bncce36dca22015-04-21 22:11:232669 // be issuing -- the final header line contains the credentials.
bnc691fda62016-08-12 00:43:162670 MockWrite("GET / HTTP/1.1\r\n"
2671 "Host: www.example.org\r\n"
2672 "Connection: keep-alive\r\n"
2673 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]2d2697f92009-02-18 21:00:322674 };
2675
[email protected]2d2697f92009-02-18 21:00:322676 MockRead data_reads1[] = {
2677 MockRead("HTTP/1.1 401 Unauthorized\r\n"),
2678 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
[email protected]11203f012009-11-12 23:02:312679 MockRead("Content-Length: 0\r\n\r\n"), // No response body.
[email protected]2d2697f92009-02-18 21:00:322680
2681 // Lastly, the server responds with the actual content.
2682 MockRead("HTTP/1.1 200 OK\r\n"),
2683 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
[email protected]0b0bf032010-09-21 18:08:502684 MockRead("Content-Length: 5\r\n\r\n"),
2685 MockRead("hello"),
[email protected]2d2697f92009-02-18 21:00:322686 };
2687
[email protected]2d0a4f92011-05-05 16:38:462688 // An incorrect reconnect would cause this to be read.
2689 MockRead data_reads2[] = {
[email protected]8ddf8322012-02-23 18:08:062690 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]2d0a4f92011-05-05 16:38:462691 };
2692
[email protected]31a2bfe2010-02-09 08:03:392693 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
2694 data_writes1, arraysize(data_writes1));
[email protected]2d0a4f92011-05-05 16:38:462695 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
2696 NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:072697 session_deps_.socket_factory->AddSocketDataProvider(&data1);
2698 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]2d2697f92009-02-18 21:00:322699
[email protected]49639fa2011-12-20 23:22:412700 TestCompletionCallback callback1;
[email protected]2d2697f92009-02-18 21:00:322701
bnc691fda62016-08-12 00:43:162702 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:202703 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012704 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2d2697f92009-02-18 21:00:322705
2706 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:012707 EXPECT_THAT(rv, IsOk());
[email protected]2d2697f92009-02-18 21:00:322708
bnc691fda62016-08-12 00:43:162709 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:522710 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:042711 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]2d2697f92009-02-18 21:00:322712
[email protected]49639fa2011-12-20 23:22:412713 TestCompletionCallback callback2;
[email protected]2d2697f92009-02-18 21:00:322714
bnc691fda62016-08-12 00:43:162715 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar), callback2.callback());
robpercival214763f2016-07-01 23:27:012716 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2d2697f92009-02-18 21:00:322717
2718 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:012719 EXPECT_THAT(rv, IsOk());
[email protected]2d2697f92009-02-18 21:00:322720
bnc691fda62016-08-12 00:43:162721 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:522722 ASSERT_TRUE(response);
2723 EXPECT_FALSE(response->auth_challenge);
[email protected]0b0bf032010-09-21 18:08:502724 EXPECT_EQ(5, response->headers->GetContentLength());
[email protected]2d2697f92009-02-18 21:00:322725}
2726
2727// Test the request-challenge-retry sequence for basic auth, over a keep-alive
2728// connection and with a large response body to drain.
bncd16676a2016-07-20 16:23:012729TEST_F(HttpNetworkTransactionTest, BasicAuthKeepAliveLargeBody) {
[email protected]1c773ea12009-04-28 19:58:422730 HttpRequestInfo request;
[email protected]2d2697f92009-02-18 21:00:322731 request.method = "GET";
bncce36dca22015-04-21 22:11:232732 request.url = GURL("http://www.example.org/");
[email protected]2d2697f92009-02-18 21:00:322733
danakj1fd259a02016-04-16 03:17:092734 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:272735
[email protected]2d2697f92009-02-18 21:00:322736 MockWrite data_writes1[] = {
bnc691fda62016-08-12 00:43:162737 MockWrite("GET / HTTP/1.1\r\n"
2738 "Host: www.example.org\r\n"
2739 "Connection: keep-alive\r\n\r\n"),
[email protected]2d2697f92009-02-18 21:00:322740
bnc691fda62016-08-12 00:43:162741 // After calling trans.RestartWithAuth(), this is the request we should
bncce36dca22015-04-21 22:11:232742 // be issuing -- the final header line contains the credentials.
bnc691fda62016-08-12 00:43:162743 MockWrite("GET / HTTP/1.1\r\n"
2744 "Host: www.example.org\r\n"
2745 "Connection: keep-alive\r\n"
2746 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]2d2697f92009-02-18 21:00:322747 };
2748
2749 // Respond with 5 kb of response body.
2750 std::string large_body_string("Unauthorized");
2751 large_body_string.append(5 * 1024, ' ');
2752 large_body_string.append("\r\n");
2753
2754 MockRead data_reads1[] = {
2755 MockRead("HTTP/1.1 401 Unauthorized\r\n"),
2756 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2757 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
2758 // 5134 = 12 + 5 * 1024 + 2
2759 MockRead("Content-Length: 5134\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:062760 MockRead(ASYNC, large_body_string.data(), large_body_string.size()),
[email protected]2d2697f92009-02-18 21:00:322761
2762 // Lastly, the server responds with the actual content.
2763 MockRead("HTTP/1.1 200 OK\r\n"),
2764 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
[email protected]0b0bf032010-09-21 18:08:502765 MockRead("Content-Length: 5\r\n\r\n"),
2766 MockRead("hello"),
[email protected]2d2697f92009-02-18 21:00:322767 };
2768
[email protected]2d0a4f92011-05-05 16:38:462769 // An incorrect reconnect would cause this to be read.
2770 MockRead data_reads2[] = {
[email protected]8ddf8322012-02-23 18:08:062771 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]2d0a4f92011-05-05 16:38:462772 };
2773
[email protected]31a2bfe2010-02-09 08:03:392774 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
2775 data_writes1, arraysize(data_writes1));
[email protected]2d0a4f92011-05-05 16:38:462776 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
2777 NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:072778 session_deps_.socket_factory->AddSocketDataProvider(&data1);
2779 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]2d2697f92009-02-18 21:00:322780
[email protected]49639fa2011-12-20 23:22:412781 TestCompletionCallback callback1;
[email protected]2d2697f92009-02-18 21:00:322782
bnc691fda62016-08-12 00:43:162783 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:202784 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012785 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2d2697f92009-02-18 21:00:322786
2787 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:012788 EXPECT_THAT(rv, IsOk());
[email protected]2d2697f92009-02-18 21:00:322789
bnc691fda62016-08-12 00:43:162790 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:522791 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:042792 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]2d2697f92009-02-18 21:00:322793
[email protected]49639fa2011-12-20 23:22:412794 TestCompletionCallback callback2;
[email protected]2d2697f92009-02-18 21:00:322795
bnc691fda62016-08-12 00:43:162796 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar), callback2.callback());
robpercival214763f2016-07-01 23:27:012797 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2d2697f92009-02-18 21:00:322798
2799 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:012800 EXPECT_THAT(rv, IsOk());
[email protected]2d2697f92009-02-18 21:00:322801
bnc691fda62016-08-12 00:43:162802 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:522803 ASSERT_TRUE(response);
2804 EXPECT_FALSE(response->auth_challenge);
[email protected]0b0bf032010-09-21 18:08:502805 EXPECT_EQ(5, response->headers->GetContentLength());
[email protected]2d2697f92009-02-18 21:00:322806}
2807
2808// Test the request-challenge-retry sequence for basic auth, over a keep-alive
[email protected]11203f012009-11-12 23:02:312809// connection, but the server gets impatient and closes the connection.
bncd16676a2016-07-20 16:23:012810TEST_F(HttpNetworkTransactionTest, BasicAuthKeepAliveImpatientServer) {
[email protected]11203f012009-11-12 23:02:312811 HttpRequestInfo request;
2812 request.method = "GET";
bncce36dca22015-04-21 22:11:232813 request.url = GURL("http://www.example.org/");
[email protected]11203f012009-11-12 23:02:312814
danakj1fd259a02016-04-16 03:17:092815 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:272816
[email protected]11203f012009-11-12 23:02:312817 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:232818 MockWrite(
2819 "GET / HTTP/1.1\r\n"
2820 "Host: www.example.org\r\n"
2821 "Connection: keep-alive\r\n\r\n"),
2822 // This simulates the seemingly successful write to a closed connection
2823 // if the bug is not fixed.
2824 MockWrite(
2825 "GET / HTTP/1.1\r\n"
2826 "Host: www.example.org\r\n"
2827 "Connection: keep-alive\r\n"
2828 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]11203f012009-11-12 23:02:312829 };
2830
2831 MockRead data_reads1[] = {
2832 MockRead("HTTP/1.1 401 Unauthorized\r\n"),
2833 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2834 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
2835 MockRead("Content-Length: 14\r\n\r\n"),
2836 // Tell MockTCPClientSocket to simulate the server closing the connection.
[email protected]8ddf8322012-02-23 18:08:062837 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
[email protected]11203f012009-11-12 23:02:312838 MockRead("Unauthorized\r\n"),
[email protected]8ddf8322012-02-23 18:08:062839 MockRead(SYNCHRONOUS, OK), // The server closes the connection.
[email protected]11203f012009-11-12 23:02:312840 };
2841
bnc691fda62016-08-12 00:43:162842 // After calling trans.RestartWithAuth(), this is the request we should
[email protected]11203f012009-11-12 23:02:312843 // be issuing -- the final header line contains the credentials.
2844 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:232845 MockWrite(
2846 "GET / HTTP/1.1\r\n"
2847 "Host: www.example.org\r\n"
2848 "Connection: keep-alive\r\n"
2849 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]11203f012009-11-12 23:02:312850 };
2851
2852 // Lastly, the server responds with the actual content.
2853 MockRead data_reads2[] = {
2854 MockRead("HTTP/1.1 200 OK\r\n"),
2855 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
[email protected]0b0bf032010-09-21 18:08:502856 MockRead("Content-Length: 5\r\n\r\n"),
2857 MockRead("hello"),
[email protected]11203f012009-11-12 23:02:312858 };
2859
[email protected]31a2bfe2010-02-09 08:03:392860 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
2861 data_writes1, arraysize(data_writes1));
2862 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
2863 data_writes2, arraysize(data_writes2));
[email protected]bb88e1d32013-05-03 23:11:072864 session_deps_.socket_factory->AddSocketDataProvider(&data1);
2865 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]11203f012009-11-12 23:02:312866
[email protected]49639fa2011-12-20 23:22:412867 TestCompletionCallback callback1;
[email protected]11203f012009-11-12 23:02:312868
bnc691fda62016-08-12 00:43:162869 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:202870 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012871 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]11203f012009-11-12 23:02:312872
2873 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:012874 EXPECT_THAT(rv, IsOk());
[email protected]11203f012009-11-12 23:02:312875
bnc691fda62016-08-12 00:43:162876 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:522877 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:042878 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]11203f012009-11-12 23:02:312879
[email protected]49639fa2011-12-20 23:22:412880 TestCompletionCallback callback2;
[email protected]11203f012009-11-12 23:02:312881
bnc691fda62016-08-12 00:43:162882 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar), callback2.callback());
robpercival214763f2016-07-01 23:27:012883 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]11203f012009-11-12 23:02:312884
2885 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:012886 EXPECT_THAT(rv, IsOk());
[email protected]11203f012009-11-12 23:02:312887
bnc691fda62016-08-12 00:43:162888 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:522889 ASSERT_TRUE(response);
2890 EXPECT_FALSE(response->auth_challenge);
[email protected]0b0bf032010-09-21 18:08:502891 EXPECT_EQ(5, response->headers->GetContentLength());
[email protected]11203f012009-11-12 23:02:312892}
2893
[email protected]394816e92010-08-03 07:38:592894// Test the request-challenge-retry sequence for basic auth, over a connection
2895// that requires a restart when setting up an SSL tunnel.
bncd16676a2016-07-20 16:23:012896TEST_F(HttpNetworkTransactionTest, BasicAuthProxyNoKeepAliveHttp10) {
ttuttle34f63b52015-03-05 04:33:012897 HttpRequestInfo request;
2898 request.method = "GET";
bncce36dca22015-04-21 22:11:232899 request.url = GURL("https://www.example.org/");
ttuttle34f63b52015-03-05 04:33:012900 // when the no authentication data flag is set.
ttuttle859dc7a2015-04-23 19:42:292901 request.load_flags = LOAD_DO_NOT_SEND_AUTH_DATA;
ttuttle34f63b52015-03-05 04:33:012902
2903 // Configure against proxy server "myproxy:70".
rdsmith82957ad2015-09-16 19:42:032904 session_deps_.proxy_service =
2905 ProxyService::CreateFixedFromPacResult("PROXY myproxy:70");
vishal.b62985ca92015-04-17 08:45:512906 BoundTestNetLog log;
ttuttle34f63b52015-03-05 04:33:012907 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:092908 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
ttuttle34f63b52015-03-05 04:33:012909
2910 // Since we have proxy, should try to establish tunnel.
2911 MockWrite data_writes1[] = {
mmenkee71e15332015-10-07 16:39:542912 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:172913 "Host: www.example.org:443\r\n"
mmenkee71e15332015-10-07 16:39:542914 "Proxy-Connection: keep-alive\r\n\r\n"),
ttuttle34f63b52015-03-05 04:33:012915 };
2916
mmenkee71e15332015-10-07 16:39:542917 // The proxy responds to the connect with a 407, using a non-persistent
ttuttle34f63b52015-03-05 04:33:012918 // connection.
2919 MockRead data_reads1[] = {
2920 // No credentials.
2921 MockRead("HTTP/1.0 407 Proxy Authentication Required\r\n"),
2922 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n\r\n"),
mmenkee71e15332015-10-07 16:39:542923 };
ttuttle34f63b52015-03-05 04:33:012924
mmenkee71e15332015-10-07 16:39:542925 // Since the first connection couldn't be reused, need to establish another
2926 // once given credentials.
2927 MockWrite data_writes2[] = {
2928 // After calling trans->RestartWithAuth(), this is the request we should
2929 // be issuing -- the final header line contains the credentials.
2930 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:172931 "Host: www.example.org:443\r\n"
mmenkee71e15332015-10-07 16:39:542932 "Proxy-Connection: keep-alive\r\n"
2933 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
2934
2935 MockWrite("GET / HTTP/1.1\r\n"
2936 "Host: www.example.org\r\n"
2937 "Connection: keep-alive\r\n\r\n"),
2938 };
2939
2940 MockRead data_reads2[] = {
ttuttle34f63b52015-03-05 04:33:012941 MockRead("HTTP/1.0 200 Connection Established\r\n\r\n"),
2942
2943 MockRead("HTTP/1.1 200 OK\r\n"),
2944 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
2945 MockRead("Content-Length: 5\r\n\r\n"),
2946 MockRead(SYNCHRONOUS, "hello"),
2947 };
2948
2949 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
2950 data_writes1, arraysize(data_writes1));
2951 session_deps_.socket_factory->AddSocketDataProvider(&data1);
mmenkee71e15332015-10-07 16:39:542952 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
2953 data_writes2, arraysize(data_writes2));
2954 session_deps_.socket_factory->AddSocketDataProvider(&data2);
ttuttle34f63b52015-03-05 04:33:012955 SSLSocketDataProvider ssl(ASYNC, OK);
2956 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
2957
2958 TestCompletionCallback callback1;
2959
bnc691fda62016-08-12 00:43:162960 std::unique_ptr<HttpNetworkTransaction> trans(
ttuttle34f63b52015-03-05 04:33:012961 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
2962
2963 int rv = trans->Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:012964 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
ttuttle34f63b52015-03-05 04:33:012965
2966 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:012967 EXPECT_THAT(rv, IsOk());
mmenke43758e62015-05-04 21:09:462968 TestNetLogEntry::List entries;
ttuttle34f63b52015-03-05 04:33:012969 log.GetEntries(&entries);
2970 size_t pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:002971 entries, 0, NetLogEventType::HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
2972 NetLogEventPhase::NONE);
ttuttle34f63b52015-03-05 04:33:012973 ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:002974 entries, pos,
2975 NetLogEventType::HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
2976 NetLogEventPhase::NONE);
ttuttle34f63b52015-03-05 04:33:012977
2978 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:522979 ASSERT_TRUE(response);
ttuttle34f63b52015-03-05 04:33:012980 EXPECT_FALSE(response->headers->IsKeepAlive());
wezca1070932016-05-26 20:30:522981 ASSERT_TRUE(response->headers);
ttuttle34f63b52015-03-05 04:33:012982 EXPECT_EQ(407, response->headers->response_code());
2983 EXPECT_TRUE(HttpVersion(1, 0) == response->headers->GetHttpVersion());
2984 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
2985
2986 LoadTimingInfo load_timing_info;
2987 // CONNECT requests and responses are handled at the connect job level, so
2988 // the transaction does not yet have a connection.
2989 EXPECT_FALSE(trans->GetLoadTimingInfo(&load_timing_info));
2990
2991 TestCompletionCallback callback2;
2992
2993 rv =
2994 trans->RestartWithAuth(AuthCredentials(kFoo, kBar), callback2.callback());
robpercival214763f2016-07-01 23:27:012995 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
ttuttle34f63b52015-03-05 04:33:012996
2997 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:012998 EXPECT_THAT(rv, IsOk());
ttuttle34f63b52015-03-05 04:33:012999
3000 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:523001 ASSERT_TRUE(response);
ttuttle34f63b52015-03-05 04:33:013002
3003 EXPECT_TRUE(response->headers->IsKeepAlive());
3004 EXPECT_EQ(200, response->headers->response_code());
3005 EXPECT_EQ(5, response->headers->GetContentLength());
3006 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
3007
3008 // The password prompt info should not be set.
wezca1070932016-05-26 20:30:523009 EXPECT_FALSE(response->auth_challenge);
ttuttle34f63b52015-03-05 04:33:013010
3011 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
3012 TestLoadTimingNotReusedWithPac(load_timing_info,
3013 CONNECT_TIMING_HAS_SSL_TIMES);
3014
3015 trans.reset();
3016 session->CloseAllConnections();
3017}
3018
3019// Test the request-challenge-retry sequence for basic auth, over a connection
3020// that requires a restart when setting up an SSL tunnel.
bncd16676a2016-07-20 16:23:013021TEST_F(HttpNetworkTransactionTest, BasicAuthProxyNoKeepAliveHttp11) {
[email protected]394816e92010-08-03 07:38:593022 HttpRequestInfo request;
3023 request.method = "GET";
bncce36dca22015-04-21 22:11:233024 request.url = GURL("https://www.example.org/");
[email protected]394816e92010-08-03 07:38:593025 // when the no authentication data flag is set.
ttuttle859dc7a2015-04-23 19:42:293026 request.load_flags = LOAD_DO_NOT_SEND_AUTH_DATA;
[email protected]394816e92010-08-03 07:38:593027
[email protected]cb9bf6ca2011-01-28 13:15:273028 // Configure against proxy server "myproxy:70".
rdsmith82957ad2015-09-16 19:42:033029 session_deps_.proxy_service =
3030 ProxyService::CreateFixedFromPacResult("PROXY myproxy:70");
vishal.b62985ca92015-04-17 08:45:513031 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:073032 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:093033 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:273034
[email protected]394816e92010-08-03 07:38:593035 // Since we have proxy, should try to establish tunnel.
3036 MockWrite data_writes1[] = {
mmenkee71e15332015-10-07 16:39:543037 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:173038 "Host: www.example.org:443\r\n"
mmenkee71e15332015-10-07 16:39:543039 "Proxy-Connection: keep-alive\r\n\r\n"),
mmenkee0b5c882015-08-26 20:29:113040 };
3041
mmenkee71e15332015-10-07 16:39:543042 // The proxy responds to the connect with a 407, using a non-persistent
mmenke0fd148d2015-09-30 23:00:083043 // connection.
3044 MockRead data_reads1[] = {
mmenkee71e15332015-10-07 16:39:543045 // No credentials.
3046 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
3047 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
3048 MockRead("Proxy-Connection: close\r\n\r\n"),
3049 };
mmenkee0b5c882015-08-26 20:29:113050
mmenkee71e15332015-10-07 16:39:543051 MockWrite data_writes2[] = {
3052 // After calling trans->RestartWithAuth(), this is the request we should
3053 // be issuing -- the final header line contains the credentials.
3054 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:173055 "Host: www.example.org:443\r\n"
mmenkee71e15332015-10-07 16:39:543056 "Proxy-Connection: keep-alive\r\n"
3057 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
mmenke0fd148d2015-09-30 23:00:083058
mmenkee71e15332015-10-07 16:39:543059 MockWrite("GET / HTTP/1.1\r\n"
3060 "Host: www.example.org\r\n"
3061 "Connection: keep-alive\r\n\r\n"),
3062 };
3063
3064 MockRead data_reads2[] = {
3065 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
3066
3067 MockRead("HTTP/1.1 200 OK\r\n"),
3068 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
3069 MockRead("Content-Length: 5\r\n\r\n"),
3070 MockRead(SYNCHRONOUS, "hello"),
[email protected]394816e92010-08-03 07:38:593071 };
3072
3073 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
3074 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:073075 session_deps_.socket_factory->AddSocketDataProvider(&data1);
mmenkee71e15332015-10-07 16:39:543076 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
3077 data_writes2, arraysize(data_writes2));
3078 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]8ddf8322012-02-23 18:08:063079 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:073080 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]394816e92010-08-03 07:38:593081
[email protected]49639fa2011-12-20 23:22:413082 TestCompletionCallback callback1;
[email protected]394816e92010-08-03 07:38:593083
bnc691fda62016-08-12 00:43:163084 std::unique_ptr<HttpNetworkTransaction> trans(
[email protected]90499482013-06-01 00:39:503085 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]0b0bf032010-09-21 18:08:503086
[email protected]49639fa2011-12-20 23:22:413087 int rv = trans->Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:013088 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]394816e92010-08-03 07:38:593089
3090 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:013091 EXPECT_THAT(rv, IsOk());
mmenke43758e62015-05-04 21:09:463092 TestNetLogEntry::List entries;
[email protected]b2fcd0e2010-12-01 15:19:403093 log.GetEntries(&entries);
[email protected]394816e92010-08-03 07:38:593094 size_t pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:003095 entries, 0, NetLogEventType::HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
3096 NetLogEventPhase::NONE);
[email protected]394816e92010-08-03 07:38:593097 ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:403098 entries, pos,
mikecirone8b85c432016-09-08 19:11:003099 NetLogEventType::HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
3100 NetLogEventPhase::NONE);
[email protected]394816e92010-08-03 07:38:593101
3102 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:523103 ASSERT_TRUE(response);
ttuttle34f63b52015-03-05 04:33:013104 EXPECT_FALSE(response->headers->IsKeepAlive());
wezca1070932016-05-26 20:30:523105 ASSERT_TRUE(response->headers);
[email protected]394816e92010-08-03 07:38:593106 EXPECT_EQ(407, response->headers->response_code());
3107 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
[email protected]79cb5c12011-09-12 13:12:043108 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
[email protected]394816e92010-08-03 07:38:593109
[email protected]029c83b62013-01-24 05:28:203110 LoadTimingInfo load_timing_info;
3111 // CONNECT requests and responses are handled at the connect job level, so
3112 // the transaction does not yet have a connection.
3113 EXPECT_FALSE(trans->GetLoadTimingInfo(&load_timing_info));
3114
[email protected]49639fa2011-12-20 23:22:413115 TestCompletionCallback callback2;
[email protected]394816e92010-08-03 07:38:593116
[email protected]49639fa2011-12-20 23:22:413117 rv = trans->RestartWithAuth(
3118 AuthCredentials(kFoo, kBar), callback2.callback());
robpercival214763f2016-07-01 23:27:013119 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]394816e92010-08-03 07:38:593120
3121 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:013122 EXPECT_THAT(rv, IsOk());
[email protected]394816e92010-08-03 07:38:593123
3124 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:523125 ASSERT_TRUE(response);
[email protected]394816e92010-08-03 07:38:593126
3127 EXPECT_TRUE(response->headers->IsKeepAlive());
3128 EXPECT_EQ(200, response->headers->response_code());
[email protected]0b0bf032010-09-21 18:08:503129 EXPECT_EQ(5, response->headers->GetContentLength());
[email protected]394816e92010-08-03 07:38:593130 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
3131
3132 // The password prompt info should not be set.
wezca1070932016-05-26 20:30:523133 EXPECT_FALSE(response->auth_challenge);
[email protected]0b0bf032010-09-21 18:08:503134
[email protected]029c83b62013-01-24 05:28:203135 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
3136 TestLoadTimingNotReusedWithPac(load_timing_info,
3137 CONNECT_TIMING_HAS_SSL_TIMES);
3138
[email protected]0b0bf032010-09-21 18:08:503139 trans.reset();
[email protected]102e27c2011-02-23 01:01:313140 session->CloseAllConnections();
[email protected]394816e92010-08-03 07:38:593141}
3142
[email protected]11203f012009-11-12 23:02:313143// Test the request-challenge-retry sequence for basic auth, over a keep-alive
ttuttle34f63b52015-03-05 04:33:013144// proxy connection with HTTP/1.0 responses, when setting up an SSL tunnel.
bncd16676a2016-07-20 16:23:013145TEST_F(HttpNetworkTransactionTest, BasicAuthProxyKeepAliveHttp10) {
mmenked39192ee2015-12-09 00:57:233146 // On the second pass, the body read of the auth challenge is synchronous, so
3147 // IsConnectedAndIdle returns false. The socket should still be drained and
3148 // reused. See http://crbug.com/544255.
3149 for (int i = 0; i < 2; ++i) {
3150 HttpRequestInfo request;
3151 request.method = "GET";
3152 request.url = GURL("https://www.example.org/");
3153 // Ensure that proxy authentication is attempted even
3154 // when the no authentication data flag is set.
3155 request.load_flags = LOAD_DO_NOT_SEND_AUTH_DATA;
ttuttle34f63b52015-03-05 04:33:013156
mmenked39192ee2015-12-09 00:57:233157 // Configure against proxy server "myproxy:70".
3158 session_deps_.proxy_service = ProxyService::CreateFixed("myproxy:70");
3159 BoundTestNetLog log;
3160 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:093161 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
ttuttle34f63b52015-03-05 04:33:013162
bnc691fda62016-08-12 00:43:163163 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
ttuttle34f63b52015-03-05 04:33:013164
mmenked39192ee2015-12-09 00:57:233165 // Since we have proxy, should try to establish tunnel.
3166 MockWrite data_writes1[] = {
3167 MockWrite(ASYNC, 0,
3168 "CONNECT www.example.org:443 HTTP/1.1\r\n"
3169 "Host: www.example.org:443\r\n"
3170 "Proxy-Connection: keep-alive\r\n\r\n"),
ttuttle34f63b52015-03-05 04:33:013171
bnc691fda62016-08-12 00:43:163172 // After calling trans.RestartWithAuth(), this is the request we should
mmenked39192ee2015-12-09 00:57:233173 // be issuing -- the final header line contains the credentials.
3174 MockWrite(ASYNC, 3,
3175 "CONNECT www.example.org:443 HTTP/1.1\r\n"
3176 "Host: www.example.org:443\r\n"
3177 "Proxy-Connection: keep-alive\r\n"
3178 "Proxy-Authorization: Basic Zm9vOmJheg==\r\n\r\n"),
3179 };
ttuttle34f63b52015-03-05 04:33:013180
mmenked39192ee2015-12-09 00:57:233181 // The proxy responds to the connect with a 407, using a persistent
3182 // connection. (Since it's HTTP/1.0, keep-alive has to be explicit.)
3183 MockRead data_reads1[] = {
3184 // No credentials.
3185 MockRead(ASYNC, 1,
3186 "HTTP/1.0 407 Proxy Authentication Required\r\n"
3187 "Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"
3188 "Proxy-Connection: keep-alive\r\n"
3189 "Content-Length: 10\r\n\r\n"),
3190 MockRead(i == 0 ? ASYNC : SYNCHRONOUS, 2, "0123456789"),
ttuttle34f63b52015-03-05 04:33:013191
mmenked39192ee2015-12-09 00:57:233192 // Wrong credentials (wrong password).
3193 MockRead(ASYNC, 4,
3194 "HTTP/1.0 407 Proxy Authentication Required\r\n"
3195 "Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"
3196 "Proxy-Connection: keep-alive\r\n"
3197 "Content-Length: 10\r\n\r\n"),
3198 // No response body because the test stops reading here.
3199 MockRead(SYNCHRONOUS, ERR_UNEXPECTED, 5),
3200 };
ttuttle34f63b52015-03-05 04:33:013201
mmenked39192ee2015-12-09 00:57:233202 SequencedSocketData data1(data_reads1, arraysize(data_reads1), data_writes1,
3203 arraysize(data_writes1));
3204 data1.set_busy_before_sync_reads(true);
3205 session_deps_.socket_factory->AddSocketDataProvider(&data1);
ttuttle34f63b52015-03-05 04:33:013206
mmenked39192ee2015-12-09 00:57:233207 TestCompletionCallback callback1;
ttuttle34f63b52015-03-05 04:33:013208
bnc691fda62016-08-12 00:43:163209 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:013210 EXPECT_THAT(callback1.GetResult(rv), IsOk());
ttuttle34f63b52015-03-05 04:33:013211
mmenked39192ee2015-12-09 00:57:233212 TestNetLogEntry::List entries;
3213 log.GetEntries(&entries);
3214 size_t pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:003215 entries, 0, NetLogEventType::HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
3216 NetLogEventPhase::NONE);
mmenked39192ee2015-12-09 00:57:233217 ExpectLogContainsSomewhere(
3218 entries, pos,
mikecirone8b85c432016-09-08 19:11:003219 NetLogEventType::HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
3220 NetLogEventPhase::NONE);
ttuttle34f63b52015-03-05 04:33:013221
bnc691fda62016-08-12 00:43:163222 const HttpResponseInfo* response = trans.GetResponseInfo();
mmenked39192ee2015-12-09 00:57:233223 ASSERT_TRUE(response);
3224 ASSERT_TRUE(response->headers);
3225 EXPECT_TRUE(response->headers->IsKeepAlive());
3226 EXPECT_EQ(407, response->headers->response_code());
3227 EXPECT_EQ(10, response->headers->GetContentLength());
3228 EXPECT_TRUE(HttpVersion(1, 0) == response->headers->GetHttpVersion());
3229 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
ttuttle34f63b52015-03-05 04:33:013230
mmenked39192ee2015-12-09 00:57:233231 TestCompletionCallback callback2;
ttuttle34f63b52015-03-05 04:33:013232
mmenked39192ee2015-12-09 00:57:233233 // Wrong password (should be "bar").
bnc691fda62016-08-12 00:43:163234 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBaz),
3235 callback2.callback());
robpercival214763f2016-07-01 23:27:013236 EXPECT_THAT(callback2.GetResult(rv), IsOk());
ttuttle34f63b52015-03-05 04:33:013237
bnc691fda62016-08-12 00:43:163238 response = trans.GetResponseInfo();
mmenked39192ee2015-12-09 00:57:233239 ASSERT_TRUE(response);
3240 ASSERT_TRUE(response->headers);
3241 EXPECT_TRUE(response->headers->IsKeepAlive());
3242 EXPECT_EQ(407, response->headers->response_code());
3243 EXPECT_EQ(10, response->headers->GetContentLength());
3244 EXPECT_TRUE(HttpVersion(1, 0) == response->headers->GetHttpVersion());
3245 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
ttuttle34f63b52015-03-05 04:33:013246
mmenked39192ee2015-12-09 00:57:233247 // Flush the idle socket before the NetLog and HttpNetworkTransaction go
3248 // out of scope.
3249 session->CloseAllConnections();
3250 }
ttuttle34f63b52015-03-05 04:33:013251}
3252
3253// Test the request-challenge-retry sequence for basic auth, over a keep-alive
3254// proxy connection with HTTP/1.1 responses, when setting up an SSL tunnel.
bncd16676a2016-07-20 16:23:013255TEST_F(HttpNetworkTransactionTest, BasicAuthProxyKeepAliveHttp11) {
mmenked39192ee2015-12-09 00:57:233256 // On the second pass, the body read of the auth challenge is synchronous, so
3257 // IsConnectedAndIdle returns false. The socket should still be drained and
3258 // reused. See http://crbug.com/544255.
3259 for (int i = 0; i < 2; ++i) {
3260 HttpRequestInfo request;
3261 request.method = "GET";
3262 request.url = GURL("https://www.example.org/");
3263 // Ensure that proxy authentication is attempted even
3264 // when the no authentication data flag is set.
3265 request.load_flags = LOAD_DO_NOT_SEND_AUTH_DATA;
3266
3267 // Configure against proxy server "myproxy:70".
3268 session_deps_.proxy_service = ProxyService::CreateFixed("myproxy:70");
3269 BoundTestNetLog log;
3270 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:093271 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
mmenked39192ee2015-12-09 00:57:233272
bnc691fda62016-08-12 00:43:163273 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
mmenked39192ee2015-12-09 00:57:233274
3275 // Since we have proxy, should try to establish tunnel.
3276 MockWrite data_writes1[] = {
3277 MockWrite(ASYNC, 0,
3278 "CONNECT www.example.org:443 HTTP/1.1\r\n"
3279 "Host: www.example.org:443\r\n"
3280 "Proxy-Connection: keep-alive\r\n\r\n"),
3281
bnc691fda62016-08-12 00:43:163282 // After calling trans.RestartWithAuth(), this is the request we should
mmenked39192ee2015-12-09 00:57:233283 // be issuing -- the final header line contains the credentials.
3284 MockWrite(ASYNC, 3,
3285 "CONNECT www.example.org:443 HTTP/1.1\r\n"
3286 "Host: www.example.org:443\r\n"
3287 "Proxy-Connection: keep-alive\r\n"
3288 "Proxy-Authorization: Basic Zm9vOmJheg==\r\n\r\n"),
3289 };
3290
3291 // The proxy responds to the connect with a 407, using a persistent
3292 // connection. (Since it's HTTP/1.0, keep-alive has to be explicit.)
3293 MockRead data_reads1[] = {
3294 // No credentials.
3295 MockRead(ASYNC, 1,
3296 "HTTP/1.1 407 Proxy Authentication Required\r\n"
3297 "Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"
3298 "Content-Length: 10\r\n\r\n"),
3299 MockRead(i == 0 ? ASYNC : SYNCHRONOUS, 2, "0123456789"),
3300
3301 // Wrong credentials (wrong password).
3302 MockRead(ASYNC, 4,
3303 "HTTP/1.1 407 Proxy Authentication Required\r\n"
3304 "Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"
3305 "Content-Length: 10\r\n\r\n"),
3306 // No response body because the test stops reading here.
3307 MockRead(SYNCHRONOUS, ERR_UNEXPECTED, 5),
3308 };
3309
3310 SequencedSocketData data1(data_reads1, arraysize(data_reads1), data_writes1,
3311 arraysize(data_writes1));
3312 data1.set_busy_before_sync_reads(true);
3313 session_deps_.socket_factory->AddSocketDataProvider(&data1);
3314
3315 TestCompletionCallback callback1;
3316
bnc691fda62016-08-12 00:43:163317 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:013318 EXPECT_THAT(callback1.GetResult(rv), IsOk());
mmenked39192ee2015-12-09 00:57:233319
3320 TestNetLogEntry::List entries;
3321 log.GetEntries(&entries);
3322 size_t pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:003323 entries, 0, NetLogEventType::HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
3324 NetLogEventPhase::NONE);
mmenked39192ee2015-12-09 00:57:233325 ExpectLogContainsSomewhere(
3326 entries, pos,
mikecirone8b85c432016-09-08 19:11:003327 NetLogEventType::HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
3328 NetLogEventPhase::NONE);
mmenked39192ee2015-12-09 00:57:233329
bnc691fda62016-08-12 00:43:163330 const HttpResponseInfo* response = trans.GetResponseInfo();
mmenked39192ee2015-12-09 00:57:233331 ASSERT_TRUE(response);
3332 ASSERT_TRUE(response->headers);
3333 EXPECT_TRUE(response->headers->IsKeepAlive());
3334 EXPECT_EQ(407, response->headers->response_code());
3335 EXPECT_EQ(10, response->headers->GetContentLength());
3336 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
3337 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
3338
3339 TestCompletionCallback callback2;
3340
3341 // Wrong password (should be "bar").
bnc691fda62016-08-12 00:43:163342 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBaz),
3343 callback2.callback());
robpercival214763f2016-07-01 23:27:013344 EXPECT_THAT(callback2.GetResult(rv), IsOk());
mmenked39192ee2015-12-09 00:57:233345
bnc691fda62016-08-12 00:43:163346 response = trans.GetResponseInfo();
mmenked39192ee2015-12-09 00:57:233347 ASSERT_TRUE(response);
3348 ASSERT_TRUE(response->headers);
3349 EXPECT_TRUE(response->headers->IsKeepAlive());
3350 EXPECT_EQ(407, response->headers->response_code());
3351 EXPECT_EQ(10, response->headers->GetContentLength());
3352 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
3353 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
3354
3355 // Flush the idle socket before the NetLog and HttpNetworkTransaction go
3356 // out of scope.
3357 session->CloseAllConnections();
3358 }
3359}
3360
3361// Test the request-challenge-retry sequence for basic auth, over a keep-alive
3362// proxy connection with HTTP/1.1 responses, when setting up an SSL tunnel, in
3363// the case the server sends extra data on the original socket, so it can't be
3364// reused.
bncd16676a2016-07-20 16:23:013365TEST_F(HttpNetworkTransactionTest, BasicAuthProxyKeepAliveExtraData) {
[email protected]cb9bf6ca2011-01-28 13:15:273366 HttpRequestInfo request;
3367 request.method = "GET";
bncce36dca22015-04-21 22:11:233368 request.url = GURL("https://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:273369 // when the no authentication data flag is set.
ttuttle859dc7a2015-04-23 19:42:293370 request.load_flags = LOAD_DO_NOT_SEND_AUTH_DATA;
[email protected]cb9bf6ca2011-01-28 13:15:273371
[email protected]2d2697f92009-02-18 21:00:323372 // Configure against proxy server "myproxy:70".
mmenked39192ee2015-12-09 00:57:233373 session_deps_.proxy_service =
3374 ProxyService::CreateFixedFromPacResult("PROXY myproxy:70");
vishal.b62985ca92015-04-17 08:45:513375 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:073376 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:093377 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]2d2697f92009-02-18 21:00:323378
[email protected]2d2697f92009-02-18 21:00:323379 // Since we have proxy, should try to establish tunnel.
3380 MockWrite data_writes1[] = {
mmenked39192ee2015-12-09 00:57:233381 MockWrite(ASYNC, 0,
3382 "CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:173383 "Host: www.example.org:443\r\n"
3384 "Proxy-Connection: keep-alive\r\n\r\n"),
mmenked39192ee2015-12-09 00:57:233385 };
[email protected]2d2697f92009-02-18 21:00:323386
mmenked39192ee2015-12-09 00:57:233387 // The proxy responds to the connect with a 407, using a persistent, but sends
3388 // extra data, so the socket cannot be reused.
3389 MockRead data_reads1[] = {
3390 // No credentials.
3391 MockRead(ASYNC, 1,
3392 "HTTP/1.1 407 Proxy Authentication Required\r\n"
3393 "Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"
3394 "Content-Length: 10\r\n\r\n"),
3395 MockRead(SYNCHRONOUS, 2, "0123456789"),
3396 MockRead(SYNCHRONOUS, 3, "I'm broken!"),
3397 };
3398
3399 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:233400 // After calling trans->RestartWithAuth(), this is the request we should
3401 // be issuing -- the final header line contains the credentials.
mmenked39192ee2015-12-09 00:57:233402 MockWrite(ASYNC, 0,
3403 "CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:173404 "Host: www.example.org:443\r\n"
3405 "Proxy-Connection: keep-alive\r\n"
mmenked39192ee2015-12-09 00:57:233406 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
3407
3408 MockWrite(ASYNC, 2,
3409 "GET / HTTP/1.1\r\n"
3410 "Host: www.example.org\r\n"
3411 "Connection: keep-alive\r\n\r\n"),
[email protected]2d2697f92009-02-18 21:00:323412 };
3413
mmenked39192ee2015-12-09 00:57:233414 MockRead data_reads2[] = {
3415 MockRead(ASYNC, 1, "HTTP/1.1 200 Connection Established\r\n\r\n"),
[email protected]2d2697f92009-02-18 21:00:323416
mmenked39192ee2015-12-09 00:57:233417 MockRead(ASYNC, 3,
3418 "HTTP/1.1 200 OK\r\n"
3419 "Content-Type: text/html; charset=iso-8859-1\r\n"
3420 "Content-Length: 5\r\n\r\n"),
3421 // No response body because the test stops reading here.
3422 MockRead(SYNCHRONOUS, ERR_UNEXPECTED, 4),
[email protected]2d2697f92009-02-18 21:00:323423 };
3424
mmenked39192ee2015-12-09 00:57:233425 SequencedSocketData data1(data_reads1, arraysize(data_reads1), data_writes1,
3426 arraysize(data_writes1));
3427 data1.set_busy_before_sync_reads(true);
[email protected]bb88e1d32013-05-03 23:11:073428 session_deps_.socket_factory->AddSocketDataProvider(&data1);
mmenked39192ee2015-12-09 00:57:233429 SequencedSocketData data2(data_reads2, arraysize(data_reads2), data_writes2,
3430 arraysize(data_writes2));
3431 session_deps_.socket_factory->AddSocketDataProvider(&data2);
3432 SSLSocketDataProvider ssl(ASYNC, OK);
3433 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]2d2697f92009-02-18 21:00:323434
[email protected]49639fa2011-12-20 23:22:413435 TestCompletionCallback callback1;
[email protected]2d2697f92009-02-18 21:00:323436
bnc691fda62016-08-12 00:43:163437 std::unique_ptr<HttpNetworkTransaction> trans(
mmenked39192ee2015-12-09 00:57:233438 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]2d2697f92009-02-18 21:00:323439
mmenked39192ee2015-12-09 00:57:233440 int rv = trans->Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:013441 EXPECT_THAT(callback1.GetResult(rv), IsOk());
mmenked39192ee2015-12-09 00:57:233442
mmenke43758e62015-05-04 21:09:463443 TestNetLogEntry::List entries;
[email protected]b2fcd0e2010-12-01 15:19:403444 log.GetEntries(&entries);
[email protected]dbb83db2010-05-11 18:13:393445 size_t pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:003446 entries, 0, NetLogEventType::HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
3447 NetLogEventPhase::NONE);
[email protected]dbb83db2010-05-11 18:13:393448 ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:403449 entries, pos,
mikecirone8b85c432016-09-08 19:11:003450 NetLogEventType::HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
3451 NetLogEventPhase::NONE);
[email protected]2d2697f92009-02-18 21:00:323452
[email protected]1c773ea12009-04-28 19:58:423453 const HttpResponseInfo* response = trans->GetResponseInfo();
ttuttle7933c112015-01-06 00:55:243454 ASSERT_TRUE(response);
3455 ASSERT_TRUE(response->headers);
[email protected]2d2697f92009-02-18 21:00:323456 EXPECT_TRUE(response->headers->IsKeepAlive());
3457 EXPECT_EQ(407, response->headers->response_code());
[email protected]1c773ea12009-04-28 19:58:423458 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
[email protected]79cb5c12011-09-12 13:12:043459 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
[email protected]2d2697f92009-02-18 21:00:323460
mmenked39192ee2015-12-09 00:57:233461 LoadTimingInfo load_timing_info;
3462 // CONNECT requests and responses are handled at the connect job level, so
3463 // the transaction does not yet have a connection.
3464 EXPECT_FALSE(trans->GetLoadTimingInfo(&load_timing_info));
3465
[email protected]49639fa2011-12-20 23:22:413466 TestCompletionCallback callback2;
[email protected]2d2697f92009-02-18 21:00:323467
mmenked39192ee2015-12-09 00:57:233468 rv =
3469 trans->RestartWithAuth(AuthCredentials(kFoo, kBar), callback2.callback());
robpercival214763f2016-07-01 23:27:013470 EXPECT_THAT(callback2.GetResult(rv), IsOk());
[email protected]2d2697f92009-02-18 21:00:323471
[email protected]2d2697f92009-02-18 21:00:323472 EXPECT_TRUE(response->headers->IsKeepAlive());
mmenked39192ee2015-12-09 00:57:233473 EXPECT_EQ(200, response->headers->response_code());
3474 EXPECT_EQ(5, response->headers->GetContentLength());
[email protected]1c773ea12009-04-28 19:58:423475 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
[email protected]e772db3f2010-07-12 18:11:133476
mmenked39192ee2015-12-09 00:57:233477 // The password prompt info should not be set.
3478 EXPECT_FALSE(response->auth_challenge);
3479
3480 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
3481 TestLoadTimingNotReusedWithPac(load_timing_info,
3482 CONNECT_TIMING_HAS_SSL_TIMES);
3483
3484 trans.reset();
[email protected]102e27c2011-02-23 01:01:313485 session->CloseAllConnections();
[email protected]2d2697f92009-02-18 21:00:323486}
3487
mmenkee71e15332015-10-07 16:39:543488// Test the case a proxy closes a socket while the challenge body is being
3489// drained.
bncd16676a2016-07-20 16:23:013490TEST_F(HttpNetworkTransactionTest, BasicAuthProxyKeepAliveHangupDuringBody) {
mmenkee71e15332015-10-07 16:39:543491 HttpRequestInfo request;
3492 request.method = "GET";
3493 request.url = GURL("https://www.example.org/");
3494 // Ensure that proxy authentication is attempted even
3495 // when the no authentication data flag is set.
3496 request.load_flags = LOAD_DO_NOT_SEND_AUTH_DATA;
3497
3498 // Configure against proxy server "myproxy:70".
3499 session_deps_.proxy_service = ProxyService::CreateFixed("myproxy:70");
danakj1fd259a02016-04-16 03:17:093500 std::unique_ptr<HttpNetworkSession> session = CreateSession(&session_deps_);
mmenkee71e15332015-10-07 16:39:543501
bnc691fda62016-08-12 00:43:163502 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
mmenkee71e15332015-10-07 16:39:543503
3504 // Since we have proxy, should try to establish tunnel.
3505 MockWrite data_writes1[] = {
3506 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:173507 "Host: www.example.org:443\r\n"
mmenkee71e15332015-10-07 16:39:543508 "Proxy-Connection: keep-alive\r\n\r\n"),
3509 };
3510
3511 // The proxy responds to the connect with a 407, using a persistent
3512 // connection.
3513 MockRead data_reads1[] = {
3514 // No credentials.
3515 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
3516 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
3517 MockRead("Content-Length: 10\r\n\r\n"), MockRead("spam!"),
3518 // Server hands up in the middle of the body.
3519 MockRead(ASYNC, ERR_CONNECTION_CLOSED),
3520 };
3521
3522 MockWrite data_writes2[] = {
bnc691fda62016-08-12 00:43:163523 // After calling trans.RestartWithAuth(), this is the request we should
mmenkee71e15332015-10-07 16:39:543524 // be issuing -- the final header line contains the credentials.
3525 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:173526 "Host: www.example.org:443\r\n"
mmenkee71e15332015-10-07 16:39:543527 "Proxy-Connection: keep-alive\r\n"
3528 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
3529
3530 MockWrite("GET / HTTP/1.1\r\n"
3531 "Host: www.example.org\r\n"
3532 "Connection: keep-alive\r\n\r\n"),
3533 };
3534
3535 MockRead data_reads2[] = {
3536 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
3537
3538 MockRead("HTTP/1.1 200 OK\r\n"),
3539 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
3540 MockRead("Content-Length: 5\r\n\r\n"),
3541 MockRead(SYNCHRONOUS, "hello"),
3542 };
3543
3544 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
3545 data_writes1, arraysize(data_writes1));
3546 session_deps_.socket_factory->AddSocketDataProvider(&data1);
3547 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
3548 data_writes2, arraysize(data_writes2));
3549 session_deps_.socket_factory->AddSocketDataProvider(&data2);
3550 SSLSocketDataProvider ssl(ASYNC, OK);
3551 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
3552
3553 TestCompletionCallback callback;
3554
tfarina42834112016-09-22 13:38:203555 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:013556 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenkee71e15332015-10-07 16:39:543557
bnc691fda62016-08-12 00:43:163558 const HttpResponseInfo* response = trans.GetResponseInfo();
mmenkee71e15332015-10-07 16:39:543559 ASSERT_TRUE(response);
3560 ASSERT_TRUE(response->headers);
3561 EXPECT_TRUE(response->headers->IsKeepAlive());
3562 EXPECT_EQ(407, response->headers->response_code());
3563 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
3564
bnc691fda62016-08-12 00:43:163565 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar), callback.callback());
robpercival214763f2016-07-01 23:27:013566 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenkee71e15332015-10-07 16:39:543567
bnc691fda62016-08-12 00:43:163568 response = trans.GetResponseInfo();
mmenkee71e15332015-10-07 16:39:543569 ASSERT_TRUE(response);
3570 ASSERT_TRUE(response->headers);
3571 EXPECT_TRUE(response->headers->IsKeepAlive());
3572 EXPECT_EQ(200, response->headers->response_code());
3573 std::string body;
bnc691fda62016-08-12 00:43:163574 EXPECT_THAT(ReadTransaction(&trans, &body), IsOk());
mmenkee71e15332015-10-07 16:39:543575 EXPECT_EQ("hello", body);
3576}
3577
[email protected]a8e9b162009-03-12 00:06:443578// Test that we don't read the response body when we fail to establish a tunnel,
3579// even if the user cancels the proxy's auth attempt.
bncd16676a2016-07-20 16:23:013580TEST_F(HttpNetworkTransactionTest, BasicAuthProxyCancelTunnel) {
[email protected]cb9bf6ca2011-01-28 13:15:273581 HttpRequestInfo request;
3582 request.method = "GET";
bncce36dca22015-04-21 22:11:233583 request.url = GURL("https://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:273584
[email protected]a8e9b162009-03-12 00:06:443585 // Configure against proxy server "myproxy:70".
rdsmith82957ad2015-09-16 19:42:033586 session_deps_.proxy_service = ProxyService::CreateFixed("myproxy:70");
[email protected]a8e9b162009-03-12 00:06:443587
danakj1fd259a02016-04-16 03:17:093588 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]a8e9b162009-03-12 00:06:443589
bnc691fda62016-08-12 00:43:163590 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]a8e9b162009-03-12 00:06:443591
[email protected]a8e9b162009-03-12 00:06:443592 // Since we have proxy, should try to establish tunnel.
3593 MockWrite data_writes[] = {
rsleevidb16bb02015-11-12 23:47:173594 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
3595 "Host: www.example.org:443\r\n"
3596 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]a8e9b162009-03-12 00:06:443597 };
3598
3599 // The proxy responds to the connect with a 407.
3600 MockRead data_reads[] = {
ttuttle7933c112015-01-06 00:55:243601 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
3602 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
3603 MockRead("Content-Length: 10\r\n\r\n"),
mmenked39192ee2015-12-09 00:57:233604 MockRead("0123456789"),
ttuttle7933c112015-01-06 00:55:243605 MockRead(SYNCHRONOUS, ERR_UNEXPECTED),
[email protected]a8e9b162009-03-12 00:06:443606 };
3607
[email protected]31a2bfe2010-02-09 08:03:393608 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
3609 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:073610 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]a8e9b162009-03-12 00:06:443611
[email protected]49639fa2011-12-20 23:22:413612 TestCompletionCallback callback;
[email protected]a8e9b162009-03-12 00:06:443613
tfarina42834112016-09-22 13:38:203614 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:013615 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]a8e9b162009-03-12 00:06:443616
3617 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:013618 EXPECT_THAT(rv, IsOk());
[email protected]a8e9b162009-03-12 00:06:443619
bnc691fda62016-08-12 00:43:163620 const HttpResponseInfo* response = trans.GetResponseInfo();
ttuttle7933c112015-01-06 00:55:243621 ASSERT_TRUE(response);
3622 ASSERT_TRUE(response->headers);
[email protected]a8e9b162009-03-12 00:06:443623 EXPECT_TRUE(response->headers->IsKeepAlive());
3624 EXPECT_EQ(407, response->headers->response_code());
[email protected]1c773ea12009-04-28 19:58:423625 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
[email protected]a8e9b162009-03-12 00:06:443626
3627 std::string response_data;
bnc691fda62016-08-12 00:43:163628 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:013629 EXPECT_THAT(rv, IsError(ERR_TUNNEL_CONNECTION_FAILED));
[email protected]e60e47a2010-07-14 03:37:183630
3631 // Flush the idle socket before the HttpNetworkTransaction goes out of scope.
[email protected]102e27c2011-02-23 01:01:313632 session->CloseAllConnections();
[email protected]a8e9b162009-03-12 00:06:443633}
3634
ttuttle7933c112015-01-06 00:55:243635// Test that we don't pass extraneous headers from the proxy's response to the
3636// caller when the proxy responds to CONNECT with 407.
bncd16676a2016-07-20 16:23:013637TEST_F(HttpNetworkTransactionTest, SanitizeProxyAuthHeaders) {
ttuttle7933c112015-01-06 00:55:243638 HttpRequestInfo request;
3639 request.method = "GET";
bncce36dca22015-04-21 22:11:233640 request.url = GURL("https://www.example.org/");
ttuttle7933c112015-01-06 00:55:243641
3642 // Configure against proxy server "myproxy:70".
rdsmith82957ad2015-09-16 19:42:033643 session_deps_.proxy_service = ProxyService::CreateFixed("myproxy:70");
ttuttle7933c112015-01-06 00:55:243644
danakj1fd259a02016-04-16 03:17:093645 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
ttuttle7933c112015-01-06 00:55:243646
bnc691fda62016-08-12 00:43:163647 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
ttuttle7933c112015-01-06 00:55:243648
3649 // Since we have proxy, should try to establish tunnel.
3650 MockWrite data_writes[] = {
rsleevidb16bb02015-11-12 23:47:173651 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
3652 "Host: www.example.org:443\r\n"
3653 "Proxy-Connection: keep-alive\r\n\r\n"),
ttuttle7933c112015-01-06 00:55:243654 };
3655
3656 // The proxy responds to the connect with a 407.
3657 MockRead data_reads[] = {
3658 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
3659 MockRead("X-Foo: bar\r\n"),
3660 MockRead("Set-Cookie: foo=bar\r\n"),
3661 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
3662 MockRead("Content-Length: 10\r\n\r\n"),
mmenked39192ee2015-12-09 00:57:233663 MockRead(SYNCHRONOUS, ERR_UNEXPECTED),
ttuttle7933c112015-01-06 00:55:243664 };
3665
3666 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
3667 arraysize(data_writes));
3668 session_deps_.socket_factory->AddSocketDataProvider(&data);
3669
3670 TestCompletionCallback callback;
3671
tfarina42834112016-09-22 13:38:203672 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:013673 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
ttuttle7933c112015-01-06 00:55:243674
3675 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:013676 EXPECT_THAT(rv, IsOk());
ttuttle7933c112015-01-06 00:55:243677
bnc691fda62016-08-12 00:43:163678 const HttpResponseInfo* response = trans.GetResponseInfo();
ttuttle7933c112015-01-06 00:55:243679 ASSERT_TRUE(response);
3680 ASSERT_TRUE(response->headers);
3681 EXPECT_TRUE(response->headers->IsKeepAlive());
3682 EXPECT_EQ(407, response->headers->response_code());
3683 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
3684 EXPECT_FALSE(response->headers->HasHeader("X-Foo"));
3685 EXPECT_FALSE(response->headers->HasHeader("Set-Cookie"));
3686
3687 std::string response_data;
bnc691fda62016-08-12 00:43:163688 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:013689 EXPECT_THAT(rv, IsError(ERR_TUNNEL_CONNECTION_FAILED));
ttuttle7933c112015-01-06 00:55:243690
3691 // Flush the idle socket before the HttpNetworkTransaction goes out of scope.
3692 session->CloseAllConnections();
3693}
3694
[email protected]8fdbcd22010-05-05 02:54:523695// Test when a server (non-proxy) returns a 407 (proxy-authenticate).
3696// The request should fail with ERR_UNEXPECTED_PROXY_AUTH.
bncd16676a2016-07-20 16:23:013697TEST_F(HttpNetworkTransactionTest, UnexpectedProxyAuth) {
[email protected]8fdbcd22010-05-05 02:54:523698 HttpRequestInfo request;
3699 request.method = "GET";
bncce36dca22015-04-21 22:11:233700 request.url = GURL("http://www.example.org/");
[email protected]8fdbcd22010-05-05 02:54:523701
[email protected]cb9bf6ca2011-01-28 13:15:273702 // We are using a DIRECT connection (i.e. no proxy) for this session.
danakj1fd259a02016-04-16 03:17:093703 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:163704 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:273705
[email protected]8fdbcd22010-05-05 02:54:523706 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:233707 MockWrite(
3708 "GET / HTTP/1.1\r\n"
3709 "Host: www.example.org\r\n"
3710 "Connection: keep-alive\r\n\r\n"),
[email protected]8fdbcd22010-05-05 02:54:523711 };
3712
3713 MockRead data_reads1[] = {
3714 MockRead("HTTP/1.0 407 Proxy Auth required\r\n"),
3715 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
3716 // Large content-length -- won't matter, as connection will be reset.
3717 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:063718 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]8fdbcd22010-05-05 02:54:523719 };
3720
3721 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
3722 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:073723 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8fdbcd22010-05-05 02:54:523724
[email protected]49639fa2011-12-20 23:22:413725 TestCompletionCallback callback;
[email protected]8fdbcd22010-05-05 02:54:523726
tfarina42834112016-09-22 13:38:203727 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:013728 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]8fdbcd22010-05-05 02:54:523729
3730 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:013731 EXPECT_THAT(rv, IsError(ERR_UNEXPECTED_PROXY_AUTH));
[email protected]8fdbcd22010-05-05 02:54:523732}
3733
[email protected]7a67a8152010-11-05 18:31:103734// Tests when an HTTPS server (non-proxy) returns a 407 (proxy-authentication)
3735// through a non-authenticating proxy. The request should fail with
3736// ERR_UNEXPECTED_PROXY_AUTH.
3737// Note that it is impossible to detect if an HTTP server returns a 407 through
3738// a non-authenticating proxy - there is nothing to indicate whether the
3739// response came from the proxy or the server, so it is treated as if the proxy
3740// issued the challenge.
bncd16676a2016-07-20 16:23:013741TEST_F(HttpNetworkTransactionTest, HttpsServerRequestsProxyAuthThroughProxy) {
[email protected]cb9bf6ca2011-01-28 13:15:273742 HttpRequestInfo request;
3743 request.method = "GET";
bncce36dca22015-04-21 22:11:233744 request.url = GURL("https://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:273745
rdsmith82957ad2015-09-16 19:42:033746 session_deps_.proxy_service = ProxyService::CreateFixed("myproxy:70");
vishal.b62985ca92015-04-17 08:45:513747 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:073748 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:093749 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]7a67a8152010-11-05 18:31:103750
[email protected]7a67a8152010-11-05 18:31:103751 // Since we have proxy, should try to establish tunnel.
3752 MockWrite data_writes1[] = {
rsleevidb16bb02015-11-12 23:47:173753 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
3754 "Host: www.example.org:443\r\n"
3755 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]7a67a8152010-11-05 18:31:103756
rsleevidb16bb02015-11-12 23:47:173757 MockWrite("GET / HTTP/1.1\r\n"
3758 "Host: www.example.org\r\n"
3759 "Connection: keep-alive\r\n\r\n"),
[email protected]7a67a8152010-11-05 18:31:103760 };
3761
3762 MockRead data_reads1[] = {
3763 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
3764
3765 MockRead("HTTP/1.1 407 Unauthorized\r\n"),
3766 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
3767 MockRead("\r\n"),
[email protected]8ddf8322012-02-23 18:08:063768 MockRead(SYNCHRONOUS, OK),
[email protected]7a67a8152010-11-05 18:31:103769 };
3770
3771 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
3772 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:073773 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8ddf8322012-02-23 18:08:063774 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:073775 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]7a67a8152010-11-05 18:31:103776
[email protected]49639fa2011-12-20 23:22:413777 TestCompletionCallback callback1;
[email protected]7a67a8152010-11-05 18:31:103778
bnc691fda62016-08-12 00:43:163779 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]7a67a8152010-11-05 18:31:103780
bnc691fda62016-08-12 00:43:163781 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:013782 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]7a67a8152010-11-05 18:31:103783
3784 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:013785 EXPECT_THAT(rv, IsError(ERR_UNEXPECTED_PROXY_AUTH));
mmenke43758e62015-05-04 21:09:463786 TestNetLogEntry::List entries;
[email protected]b2fcd0e2010-12-01 15:19:403787 log.GetEntries(&entries);
[email protected]7a67a8152010-11-05 18:31:103788 size_t pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:003789 entries, 0, NetLogEventType::HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
3790 NetLogEventPhase::NONE);
[email protected]7a67a8152010-11-05 18:31:103791 ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:403792 entries, pos,
mikecirone8b85c432016-09-08 19:11:003793 NetLogEventType::HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
3794 NetLogEventPhase::NONE);
[email protected]7a67a8152010-11-05 18:31:103795}
[email protected]2df19bb2010-08-25 20:13:463796
mmenke2a1781d2015-10-07 19:25:333797// Test a proxy auth scheme that allows default credentials and a proxy server
3798// that uses non-persistent connections.
bncd16676a2016-07-20 16:23:013799TEST_F(HttpNetworkTransactionTest,
mmenke2a1781d2015-10-07 19:25:333800 AuthAllowsDefaultCredentialsTunnelConnectionClose) {
3801 HttpRequestInfo request;
3802 request.method = "GET";
3803 request.url = GURL("https://www.example.org/");
3804
3805 // Configure against proxy server "myproxy:70".
3806 session_deps_.proxy_service =
3807 ProxyService::CreateFixedFromPacResult("PROXY myproxy:70");
3808
danakj1fd259a02016-04-16 03:17:093809 std::unique_ptr<HttpAuthHandlerMock::Factory> auth_handler_factory(
mmenke2a1781d2015-10-07 19:25:333810 new HttpAuthHandlerMock::Factory());
3811 auth_handler_factory->set_do_init_from_challenge(true);
danakj1fd259a02016-04-16 03:17:093812 std::unique_ptr<HttpAuthHandlerMock> mock_handler(new HttpAuthHandlerMock());
mmenke2a1781d2015-10-07 19:25:333813 mock_handler->set_allows_default_credentials(true);
3814 auth_handler_factory->AddMockHandler(mock_handler.release(),
3815 HttpAuth::AUTH_PROXY);
dchengc7eeda422015-12-26 03:56:483816 session_deps_.http_auth_handler_factory = std::move(auth_handler_factory);
mmenke2a1781d2015-10-07 19:25:333817
3818 // Add NetLog just so can verify load timing information gets a NetLog ID.
3819 NetLog net_log;
3820 session_deps_.net_log = &net_log;
danakj1fd259a02016-04-16 03:17:093821 std::unique_ptr<HttpNetworkSession> session = CreateSession(&session_deps_);
mmenke2a1781d2015-10-07 19:25:333822
3823 // Since we have proxy, should try to establish tunnel.
3824 MockWrite data_writes1[] = {
3825 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:173826 "Host: www.example.org:443\r\n"
mmenke2a1781d2015-10-07 19:25:333827 "Proxy-Connection: keep-alive\r\n\r\n"),
3828 };
3829
3830 // The proxy responds to the connect with a 407, using a non-persistent
3831 // connection.
3832 MockRead data_reads1[] = {
3833 // No credentials.
3834 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
3835 MockRead("Proxy-Authenticate: Mock\r\n"),
3836 MockRead("Proxy-Connection: close\r\n\r\n"),
3837 };
3838
3839 // Since the first connection couldn't be reused, need to establish another
3840 // once given credentials.
3841 MockWrite data_writes2[] = {
3842 // After calling trans->RestartWithAuth(), this is the request we should
3843 // be issuing -- the final header line contains the credentials.
3844 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:173845 "Host: www.example.org:443\r\n"
mmenke2a1781d2015-10-07 19:25:333846 "Proxy-Connection: keep-alive\r\n"
3847 "Proxy-Authorization: auth_token\r\n\r\n"),
3848
3849 MockWrite("GET / HTTP/1.1\r\n"
3850 "Host: www.example.org\r\n"
3851 "Connection: keep-alive\r\n\r\n"),
3852 };
3853
3854 MockRead data_reads2[] = {
3855 MockRead("HTTP/1.0 200 Connection Established\r\n\r\n"),
3856
3857 MockRead("HTTP/1.1 200 OK\r\n"),
3858 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
3859 MockRead("Content-Length: 5\r\n\r\n"),
3860 MockRead(SYNCHRONOUS, "hello"),
3861 };
3862
3863 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
3864 data_writes1, arraysize(data_writes1));
3865 session_deps_.socket_factory->AddSocketDataProvider(&data1);
3866 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
3867 data_writes2, arraysize(data_writes2));
3868 session_deps_.socket_factory->AddSocketDataProvider(&data2);
3869 SSLSocketDataProvider ssl(ASYNC, OK);
3870 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
3871
bnc691fda62016-08-12 00:43:163872 std::unique_ptr<HttpNetworkTransaction> trans(
mmenke2a1781d2015-10-07 19:25:333873 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
3874
3875 TestCompletionCallback callback;
tfarina42834112016-09-22 13:38:203876 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:013877 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenke2a1781d2015-10-07 19:25:333878
3879 const HttpResponseInfo* response = trans->GetResponseInfo();
3880 ASSERT_TRUE(response);
3881 ASSERT_TRUE(response->headers);
3882 EXPECT_FALSE(response->headers->IsKeepAlive());
3883 EXPECT_EQ(407, response->headers->response_code());
3884 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
3885 EXPECT_TRUE(trans->IsReadyToRestartForAuth());
wezca1070932016-05-26 20:30:523886 EXPECT_FALSE(response->auth_challenge);
mmenke2a1781d2015-10-07 19:25:333887
3888 LoadTimingInfo load_timing_info;
3889 // CONNECT requests and responses are handled at the connect job level, so
3890 // the transaction does not yet have a connection.
3891 EXPECT_FALSE(trans->GetLoadTimingInfo(&load_timing_info));
3892
3893 rv = trans->RestartWithAuth(AuthCredentials(), callback.callback());
robpercival214763f2016-07-01 23:27:013894 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenke2a1781d2015-10-07 19:25:333895 response = trans->GetResponseInfo();
3896 ASSERT_TRUE(response);
3897 ASSERT_TRUE(response->headers);
3898 EXPECT_TRUE(response->headers->IsKeepAlive());
3899 EXPECT_EQ(200, response->headers->response_code());
3900 EXPECT_EQ(5, response->headers->GetContentLength());
3901 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
3902
3903 // The password prompt info should not be set.
3904 EXPECT_FALSE(response->auth_challenge);
3905
3906 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
3907 TestLoadTimingNotReusedWithPac(load_timing_info,
3908 CONNECT_TIMING_HAS_SSL_TIMES);
3909
3910 trans.reset();
3911 session->CloseAllConnections();
3912}
3913
3914// Test a proxy auth scheme that allows default credentials and a proxy server
3915// that hangs up when credentials are initially sent.
bncd16676a2016-07-20 16:23:013916TEST_F(HttpNetworkTransactionTest,
mmenke2a1781d2015-10-07 19:25:333917 AuthAllowsDefaultCredentialsTunnelServerClosesConnection) {
3918 HttpRequestInfo request;
3919 request.method = "GET";
3920 request.url = GURL("https://www.example.org/");
3921
3922 // Configure against proxy server "myproxy:70".
3923 session_deps_.proxy_service =
3924 ProxyService::CreateFixedFromPacResult("PROXY myproxy:70");
3925
danakj1fd259a02016-04-16 03:17:093926 std::unique_ptr<HttpAuthHandlerMock::Factory> auth_handler_factory(
mmenke2a1781d2015-10-07 19:25:333927 new HttpAuthHandlerMock::Factory());
3928 auth_handler_factory->set_do_init_from_challenge(true);
danakj1fd259a02016-04-16 03:17:093929 std::unique_ptr<HttpAuthHandlerMock> mock_handler(new HttpAuthHandlerMock());
mmenke2a1781d2015-10-07 19:25:333930 mock_handler->set_allows_default_credentials(true);
3931 auth_handler_factory->AddMockHandler(mock_handler.release(),
3932 HttpAuth::AUTH_PROXY);
dchengc7eeda422015-12-26 03:56:483933 session_deps_.http_auth_handler_factory = std::move(auth_handler_factory);
mmenke2a1781d2015-10-07 19:25:333934
3935 // Add NetLog just so can verify load timing information gets a NetLog ID.
3936 NetLog net_log;
3937 session_deps_.net_log = &net_log;
danakj1fd259a02016-04-16 03:17:093938 std::unique_ptr<HttpNetworkSession> session = CreateSession(&session_deps_);
mmenke2a1781d2015-10-07 19:25:333939
3940 // Should try to establish tunnel.
3941 MockWrite data_writes1[] = {
3942 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:173943 "Host: www.example.org:443\r\n"
mmenke2a1781d2015-10-07 19:25:333944 "Proxy-Connection: keep-alive\r\n\r\n"),
3945
3946 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:173947 "Host: www.example.org:443\r\n"
mmenke2a1781d2015-10-07 19:25:333948 "Proxy-Connection: keep-alive\r\n"
3949 "Proxy-Authorization: auth_token\r\n\r\n"),
3950 };
3951
3952 // The proxy responds to the connect with a 407, using a non-persistent
3953 // connection.
3954 MockRead data_reads1[] = {
3955 // No credentials.
3956 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
3957 MockRead("Proxy-Authenticate: Mock\r\n\r\n"),
3958 MockRead(SYNCHRONOUS, ERR_CONNECTION_CLOSED),
3959 };
3960
3961 // Since the first connection was closed, need to establish another once given
3962 // credentials.
3963 MockWrite data_writes2[] = {
3964 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:173965 "Host: www.example.org:443\r\n"
mmenke2a1781d2015-10-07 19:25:333966 "Proxy-Connection: keep-alive\r\n"
3967 "Proxy-Authorization: auth_token\r\n\r\n"),
3968
3969 MockWrite("GET / HTTP/1.1\r\n"
3970 "Host: www.example.org\r\n"
3971 "Connection: keep-alive\r\n\r\n"),
3972 };
3973
3974 MockRead data_reads2[] = {
3975 MockRead("HTTP/1.0 200 Connection Established\r\n\r\n"),
3976
3977 MockRead("HTTP/1.1 200 OK\r\n"),
3978 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
3979 MockRead("Content-Length: 5\r\n\r\n"),
3980 MockRead(SYNCHRONOUS, "hello"),
3981 };
3982
3983 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
3984 data_writes1, arraysize(data_writes1));
3985 session_deps_.socket_factory->AddSocketDataProvider(&data1);
3986 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
3987 data_writes2, arraysize(data_writes2));
3988 session_deps_.socket_factory->AddSocketDataProvider(&data2);
3989 SSLSocketDataProvider ssl(ASYNC, OK);
3990 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
3991
bnc691fda62016-08-12 00:43:163992 std::unique_ptr<HttpNetworkTransaction> trans(
mmenke2a1781d2015-10-07 19:25:333993 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
3994
3995 TestCompletionCallback callback;
tfarina42834112016-09-22 13:38:203996 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:013997 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenke2a1781d2015-10-07 19:25:333998
3999 const HttpResponseInfo* response = trans->GetResponseInfo();
4000 ASSERT_TRUE(response);
4001 ASSERT_TRUE(response->headers);
4002 EXPECT_TRUE(response->headers->IsKeepAlive());
4003 EXPECT_EQ(407, response->headers->response_code());
4004 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
4005 EXPECT_TRUE(trans->IsReadyToRestartForAuth());
4006 EXPECT_FALSE(response->auth_challenge);
4007
4008 LoadTimingInfo load_timing_info;
4009 // CONNECT requests and responses are handled at the connect job level, so
4010 // the transaction does not yet have a connection.
4011 EXPECT_FALSE(trans->GetLoadTimingInfo(&load_timing_info));
4012
4013 rv = trans->RestartWithAuth(AuthCredentials(), callback.callback());
robpercival214763f2016-07-01 23:27:014014 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenke2a1781d2015-10-07 19:25:334015
4016 response = trans->GetResponseInfo();
4017 ASSERT_TRUE(response);
4018 ASSERT_TRUE(response->headers);
4019 EXPECT_TRUE(response->headers->IsKeepAlive());
4020 EXPECT_EQ(200, response->headers->response_code());
4021 EXPECT_EQ(5, response->headers->GetContentLength());
4022 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
4023
4024 // The password prompt info should not be set.
wezca1070932016-05-26 20:30:524025 EXPECT_FALSE(response->auth_challenge);
mmenke2a1781d2015-10-07 19:25:334026
4027 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
4028 TestLoadTimingNotReusedWithPac(load_timing_info,
4029 CONNECT_TIMING_HAS_SSL_TIMES);
4030
4031 trans.reset();
4032 session->CloseAllConnections();
4033}
4034
4035// Test a proxy auth scheme that allows default credentials and a proxy server
4036// that hangs up when credentials are initially sent, and hangs up again when
4037// they are retried.
bncd16676a2016-07-20 16:23:014038TEST_F(HttpNetworkTransactionTest,
mmenke2a1781d2015-10-07 19:25:334039 AuthAllowsDefaultCredentialsTunnelServerClosesConnectionTwice) {
4040 HttpRequestInfo request;
4041 request.method = "GET";
4042 request.url = GURL("https://www.example.org/");
4043
4044 // Configure against proxy server "myproxy:70".
4045 session_deps_.proxy_service =
4046 ProxyService::CreateFixedFromPacResult("PROXY myproxy:70");
4047
danakj1fd259a02016-04-16 03:17:094048 std::unique_ptr<HttpAuthHandlerMock::Factory> auth_handler_factory(
mmenke2a1781d2015-10-07 19:25:334049 new HttpAuthHandlerMock::Factory());
4050 auth_handler_factory->set_do_init_from_challenge(true);
danakj1fd259a02016-04-16 03:17:094051 std::unique_ptr<HttpAuthHandlerMock> mock_handler(new HttpAuthHandlerMock());
mmenke2a1781d2015-10-07 19:25:334052 mock_handler->set_allows_default_credentials(true);
4053 auth_handler_factory->AddMockHandler(mock_handler.release(),
4054 HttpAuth::AUTH_PROXY);
dchengc7eeda422015-12-26 03:56:484055 session_deps_.http_auth_handler_factory = std::move(auth_handler_factory);
mmenke2a1781d2015-10-07 19:25:334056
4057 // Add NetLog just so can verify load timing information gets a NetLog ID.
4058 NetLog net_log;
4059 session_deps_.net_log = &net_log;
danakj1fd259a02016-04-16 03:17:094060 std::unique_ptr<HttpNetworkSession> session = CreateSession(&session_deps_);
mmenke2a1781d2015-10-07 19:25:334061
4062 // Should try to establish tunnel.
4063 MockWrite data_writes1[] = {
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\r\n"),
4067
4068 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:174069 "Host: www.example.org:443\r\n"
mmenke2a1781d2015-10-07 19:25:334070 "Proxy-Connection: keep-alive\r\n"
4071 "Proxy-Authorization: auth_token\r\n\r\n"),
4072 };
4073
4074 // The proxy responds to the connect with a 407, and then hangs up after the
4075 // second request is sent.
4076 MockRead data_reads1[] = {
4077 // No credentials.
4078 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
4079 MockRead("Content-Length: 0\r\n"),
4080 MockRead("Proxy-Connection: keep-alive\r\n"),
4081 MockRead("Proxy-Authenticate: Mock\r\n\r\n"),
4082 MockRead(SYNCHRONOUS, ERR_CONNECTION_CLOSED),
4083 };
4084
4085 // HttpNetworkTransaction sees a reused connection that was closed with
4086 // ERR_CONNECTION_CLOSED, realized it might have been a race, so retries the
4087 // request.
4088 MockWrite data_writes2[] = {
4089 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:174090 "Host: www.example.org:443\r\n"
mmenke2a1781d2015-10-07 19:25:334091 "Proxy-Connection: keep-alive\r\n\r\n"),
4092 };
4093
4094 // The proxy, having had more than enough of us, just hangs up.
4095 MockRead data_reads2[] = {
4096 // No credentials.
4097 MockRead(SYNCHRONOUS, ERR_CONNECTION_CLOSED),
4098 };
4099
4100 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
4101 data_writes1, arraysize(data_writes1));
4102 session_deps_.socket_factory->AddSocketDataProvider(&data1);
4103 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
4104 data_writes2, arraysize(data_writes2));
4105 session_deps_.socket_factory->AddSocketDataProvider(&data2);
4106
bnc691fda62016-08-12 00:43:164107 std::unique_ptr<HttpNetworkTransaction> trans(
mmenke2a1781d2015-10-07 19:25:334108 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
4109
4110 TestCompletionCallback callback;
tfarina42834112016-09-22 13:38:204111 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:014112 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenke2a1781d2015-10-07 19:25:334113
4114 const HttpResponseInfo* response = trans->GetResponseInfo();
4115 ASSERT_TRUE(response);
4116 ASSERT_TRUE(response->headers);
4117 EXPECT_TRUE(response->headers->IsKeepAlive());
4118 EXPECT_EQ(407, response->headers->response_code());
4119 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
4120 EXPECT_TRUE(trans->IsReadyToRestartForAuth());
4121 EXPECT_FALSE(response->auth_challenge);
4122
4123 LoadTimingInfo load_timing_info;
4124 EXPECT_FALSE(trans->GetLoadTimingInfo(&load_timing_info));
4125
4126 rv = trans->RestartWithAuth(AuthCredentials(), callback.callback());
robpercival214763f2016-07-01 23:27:014127 EXPECT_THAT(callback.GetResult(rv), IsError(ERR_EMPTY_RESPONSE));
mmenke2a1781d2015-10-07 19:25:334128
4129 trans.reset();
4130 session->CloseAllConnections();
4131}
4132
4133// Test a proxy auth scheme that allows default credentials and a proxy server
4134// that hangs up when credentials are initially sent, and sends a challenge
4135// again they are retried.
bncd16676a2016-07-20 16:23:014136TEST_F(HttpNetworkTransactionTest,
mmenke2a1781d2015-10-07 19:25:334137 AuthAllowsDefaultCredentialsTunnelServerChallengesTwice) {
4138 HttpRequestInfo request;
4139 request.method = "GET";
4140 request.url = GURL("https://www.example.org/");
4141
4142 // Configure against proxy server "myproxy:70".
4143 session_deps_.proxy_service =
4144 ProxyService::CreateFixedFromPacResult("PROXY myproxy:70");
4145
danakj1fd259a02016-04-16 03:17:094146 std::unique_ptr<HttpAuthHandlerMock::Factory> auth_handler_factory(
mmenke2a1781d2015-10-07 19:25:334147 new HttpAuthHandlerMock::Factory());
4148 auth_handler_factory->set_do_init_from_challenge(true);
danakj1fd259a02016-04-16 03:17:094149 std::unique_ptr<HttpAuthHandlerMock> mock_handler(new HttpAuthHandlerMock());
mmenke2a1781d2015-10-07 19:25:334150 mock_handler->set_allows_default_credentials(true);
4151 auth_handler_factory->AddMockHandler(mock_handler.release(),
4152 HttpAuth::AUTH_PROXY);
4153 // Add another handler for the second challenge. It supports default
4154 // credentials, but they shouldn't be used, since they were already tried.
4155 mock_handler.reset(new HttpAuthHandlerMock());
4156 mock_handler->set_allows_default_credentials(true);
4157 auth_handler_factory->AddMockHandler(mock_handler.release(),
4158 HttpAuth::AUTH_PROXY);
dchengc7eeda422015-12-26 03:56:484159 session_deps_.http_auth_handler_factory = std::move(auth_handler_factory);
mmenke2a1781d2015-10-07 19:25:334160
4161 // Add NetLog just so can verify load timing information gets a NetLog ID.
4162 NetLog net_log;
4163 session_deps_.net_log = &net_log;
danakj1fd259a02016-04-16 03:17:094164 std::unique_ptr<HttpNetworkSession> session = CreateSession(&session_deps_);
mmenke2a1781d2015-10-07 19:25:334165
4166 // Should try to establish tunnel.
4167 MockWrite data_writes1[] = {
4168 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:174169 "Host: www.example.org:443\r\n"
mmenke2a1781d2015-10-07 19:25:334170 "Proxy-Connection: keep-alive\r\n\r\n"),
4171 };
4172
4173 // The proxy responds to the connect with a 407, using a non-persistent
4174 // connection.
4175 MockRead data_reads1[] = {
4176 // No credentials.
4177 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
4178 MockRead("Proxy-Authenticate: Mock\r\n"),
4179 MockRead("Proxy-Connection: close\r\n\r\n"),
4180 };
4181
4182 // Since the first connection was closed, need to establish another once given
4183 // credentials.
4184 MockWrite data_writes2[] = {
4185 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:174186 "Host: www.example.org:443\r\n"
mmenke2a1781d2015-10-07 19:25:334187 "Proxy-Connection: keep-alive\r\n"
4188 "Proxy-Authorization: auth_token\r\n\r\n"),
4189 };
4190
4191 MockRead data_reads2[] = {
4192 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
4193 MockRead("Proxy-Authenticate: Mock\r\n"),
4194 MockRead("Proxy-Connection: close\r\n\r\n"),
4195 };
4196
4197 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
4198 data_writes1, arraysize(data_writes1));
4199 session_deps_.socket_factory->AddSocketDataProvider(&data1);
4200 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
4201 data_writes2, arraysize(data_writes2));
4202 session_deps_.socket_factory->AddSocketDataProvider(&data2);
4203 SSLSocketDataProvider ssl(ASYNC, OK);
4204 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
4205
bnc691fda62016-08-12 00:43:164206 std::unique_ptr<HttpNetworkTransaction> trans(
mmenke2a1781d2015-10-07 19:25:334207 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
4208
4209 TestCompletionCallback callback;
tfarina42834112016-09-22 13:38:204210 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:014211 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenke2a1781d2015-10-07 19:25:334212
4213 const HttpResponseInfo* response = trans->GetResponseInfo();
4214 ASSERT_TRUE(response);
4215 ASSERT_TRUE(response->headers);
4216 EXPECT_EQ(407, response->headers->response_code());
4217 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
4218 EXPECT_TRUE(trans->IsReadyToRestartForAuth());
4219 EXPECT_FALSE(response->auth_challenge);
4220
4221 LoadTimingInfo load_timing_info;
4222 EXPECT_FALSE(trans->GetLoadTimingInfo(&load_timing_info));
4223
4224 rv = trans->RestartWithAuth(AuthCredentials(), callback.callback());
robpercival214763f2016-07-01 23:27:014225 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenke2a1781d2015-10-07 19:25:334226 response = trans->GetResponseInfo();
4227 ASSERT_TRUE(response);
4228 ASSERT_TRUE(response->headers);
4229 EXPECT_EQ(407, response->headers->response_code());
4230 EXPECT_FALSE(trans->IsReadyToRestartForAuth());
4231 EXPECT_TRUE(response->auth_challenge);
4232
4233 trans.reset();
4234 session->CloseAllConnections();
4235}
4236
asankae2257db2016-10-11 22:03:164237// A more nuanced test than GenerateAuthToken test which asserts that
4238// ERR_INVALID_AUTH_CREDENTIALS does not cause the auth scheme to be
4239// unnecessarily invalidated, and that if the server co-operates, the
4240// authentication handshake can continue with the same scheme but with a
4241// different identity.
4242TEST_F(HttpNetworkTransactionTest, NonPermanentGenerateAuthTokenError) {
4243 HttpRequestInfo request;
4244 request.method = "GET";
4245 request.url = GURL("http://www.example.org/");
4246
4247 std::unique_ptr<HttpAuthHandlerMock::Factory> auth_handler_factory(
4248 new HttpAuthHandlerMock::Factory());
4249 auth_handler_factory->set_do_init_from_challenge(true);
4250
4251 // First handler. Uses default credentials, but barfs at generate auth token.
4252 std::unique_ptr<HttpAuthHandlerMock> mock_handler(new HttpAuthHandlerMock());
4253 mock_handler->set_allows_default_credentials(true);
4254 mock_handler->set_allows_explicit_credentials(true);
4255 mock_handler->set_connection_based(true);
4256 mock_handler->SetGenerateExpectation(true, ERR_INVALID_AUTH_CREDENTIALS);
4257 auth_handler_factory->AddMockHandler(mock_handler.release(),
4258 HttpAuth::AUTH_SERVER);
4259
4260 // Add another handler for the second challenge. It supports default
4261 // credentials, but they shouldn't be used, since they were already tried.
4262 mock_handler.reset(new HttpAuthHandlerMock());
4263 mock_handler->set_allows_default_credentials(true);
4264 mock_handler->set_allows_explicit_credentials(true);
4265 mock_handler->set_connection_based(true);
4266 auth_handler_factory->AddMockHandler(mock_handler.release(),
4267 HttpAuth::AUTH_SERVER);
4268 session_deps_.http_auth_handler_factory = std::move(auth_handler_factory);
4269
4270 std::unique_ptr<HttpNetworkSession> session = CreateSession(&session_deps_);
4271
4272 MockWrite data_writes1[] = {
4273 MockWrite("GET / HTTP/1.1\r\n"
4274 "Host: www.example.org\r\n"
4275 "Connection: keep-alive\r\n\r\n"),
4276 };
4277
4278 MockRead data_reads1[] = {
4279 MockRead("HTTP/1.1 401 Authentication Required\r\n"
4280 "WWW-Authenticate: Mock\r\n"
4281 "Connection: keep-alive\r\n\r\n"),
4282 };
4283
4284 // Identical to data_writes1[]. The AuthHandler encounters a
4285 // ERR_INVALID_AUTH_CREDENTIALS during the GenerateAuthToken stage, so the
4286 // transaction procceds without an authorization header.
4287 MockWrite data_writes2[] = {
4288 MockWrite("GET / HTTP/1.1\r\n"
4289 "Host: www.example.org\r\n"
4290 "Connection: keep-alive\r\n\r\n"),
4291 };
4292
4293 MockRead data_reads2[] = {
4294 MockRead("HTTP/1.1 401 Authentication Required\r\n"
4295 "WWW-Authenticate: Mock\r\n"
4296 "Connection: keep-alive\r\n\r\n"),
4297 };
4298
4299 MockWrite data_writes3[] = {
4300 MockWrite("GET / HTTP/1.1\r\n"
4301 "Host: www.example.org\r\n"
4302 "Connection: keep-alive\r\n"
4303 "Authorization: auth_token\r\n\r\n"),
4304 };
4305
4306 MockRead data_reads3[] = {
4307 MockRead("HTTP/1.1 200 OK\r\n"
4308 "Content-Length: 5\r\n"
4309 "Content-Type: text/plain\r\n"
4310 "Connection: keep-alive\r\n\r\n"
4311 "Hello"),
4312 };
4313
4314 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
4315 data_writes1, arraysize(data_writes1));
4316 session_deps_.socket_factory->AddSocketDataProvider(&data1);
4317
4318 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
4319 data_writes2, arraysize(data_writes2));
4320 session_deps_.socket_factory->AddSocketDataProvider(&data2);
4321
4322 StaticSocketDataProvider data3(data_reads3, arraysize(data_reads3),
4323 data_writes3, arraysize(data_writes3));
4324 session_deps_.socket_factory->AddSocketDataProvider(&data3);
4325
4326 std::unique_ptr<HttpNetworkTransaction> trans(
4327 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
4328
4329 TestCompletionCallback callback;
4330 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
4331 EXPECT_THAT(callback.GetResult(rv), IsOk());
4332
4333 const HttpResponseInfo* response = trans->GetResponseInfo();
4334 ASSERT_TRUE(response);
4335 ASSERT_TRUE(response->headers);
4336 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
4337
4338 // The following three tests assert that an authentication challenge was
4339 // received and that the stack is ready to respond to the challenge using
4340 // ambient credentials.
4341 EXPECT_EQ(401, response->headers->response_code());
4342 EXPECT_TRUE(trans->IsReadyToRestartForAuth());
4343 EXPECT_FALSE(response->auth_challenge);
4344
4345 rv = trans->RestartWithAuth(AuthCredentials(), callback.callback());
4346 EXPECT_THAT(callback.GetResult(rv), IsOk());
4347 response = trans->GetResponseInfo();
4348 ASSERT_TRUE(response);
4349 ASSERT_TRUE(response->headers);
4350
4351 // The following three tests assert that an authentication challenge was
4352 // received and that the stack needs explicit credentials before it is ready
4353 // to respond to the challenge.
4354 EXPECT_EQ(401, response->headers->response_code());
4355 EXPECT_FALSE(trans->IsReadyToRestartForAuth());
4356 EXPECT_TRUE(response->auth_challenge);
4357
4358 rv = trans->RestartWithAuth(AuthCredentials(), callback.callback());
4359 EXPECT_THAT(callback.GetResult(rv), IsOk());
4360 response = trans->GetResponseInfo();
4361 ASSERT_TRUE(response);
4362 ASSERT_TRUE(response->headers);
4363 EXPECT_EQ(200, response->headers->response_code());
4364
4365 trans.reset();
4366 session->CloseAllConnections();
4367}
4368
[email protected]029c83b62013-01-24 05:28:204369// Test the load timing for HTTPS requests with an HTTP proxy.
bncd16676a2016-07-20 16:23:014370TEST_F(HttpNetworkTransactionTest, HttpProxyLoadTimingNoPacTwoRequests) {
[email protected]029c83b62013-01-24 05:28:204371 HttpRequestInfo request1;
4372 request1.method = "GET";
bncce36dca22015-04-21 22:11:234373 request1.url = GURL("https://www.example.org/1");
[email protected]029c83b62013-01-24 05:28:204374
4375 HttpRequestInfo request2;
4376 request2.method = "GET";
bncce36dca22015-04-21 22:11:234377 request2.url = GURL("https://www.example.org/2");
[email protected]029c83b62013-01-24 05:28:204378
4379 // Configure against proxy server "myproxy:70".
brettwc1213d92016-11-12 03:41:134380 session_deps_.proxy_service = ProxyService::CreateFixed("myproxy:70");
vishal.b62985ca92015-04-17 08:45:514381 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:074382 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:094383 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]029c83b62013-01-24 05:28:204384
4385 // Since we have proxy, should try to establish tunnel.
4386 MockWrite data_writes1[] = {
rsleevidb16bb02015-11-12 23:47:174387 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
4388 "Host: www.example.org:443\r\n"
4389 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]029c83b62013-01-24 05:28:204390
rsleevidb16bb02015-11-12 23:47:174391 MockWrite("GET /1 HTTP/1.1\r\n"
4392 "Host: www.example.org\r\n"
4393 "Connection: keep-alive\r\n\r\n"),
[email protected]029c83b62013-01-24 05:28:204394
rsleevidb16bb02015-11-12 23:47:174395 MockWrite("GET /2 HTTP/1.1\r\n"
4396 "Host: www.example.org\r\n"
4397 "Connection: keep-alive\r\n\r\n"),
[email protected]029c83b62013-01-24 05:28:204398 };
4399
4400 // The proxy responds to the connect with a 407, using a persistent
4401 // connection.
4402 MockRead data_reads1[] = {
4403 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
4404
4405 MockRead("HTTP/1.1 200 OK\r\n"),
4406 MockRead("Content-Length: 1\r\n\r\n"),
4407 MockRead(SYNCHRONOUS, "1"),
4408
4409 MockRead("HTTP/1.1 200 OK\r\n"),
4410 MockRead("Content-Length: 2\r\n\r\n"),
4411 MockRead(SYNCHRONOUS, "22"),
4412 };
4413
4414 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
4415 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:074416 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]029c83b62013-01-24 05:28:204417 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:074418 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]029c83b62013-01-24 05:28:204419
4420 TestCompletionCallback callback1;
bnc691fda62016-08-12 00:43:164421 std::unique_ptr<HttpNetworkTransaction> trans1(
[email protected]90499482013-06-01 00:39:504422 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]029c83b62013-01-24 05:28:204423
4424 int rv = trans1->Start(&request1, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:014425 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]029c83b62013-01-24 05:28:204426
4427 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:014428 EXPECT_THAT(rv, IsOk());
[email protected]029c83b62013-01-24 05:28:204429
4430 const HttpResponseInfo* response1 = trans1->GetResponseInfo();
wezca1070932016-05-26 20:30:524431 ASSERT_TRUE(response1);
tbansal2ecbbc72016-10-06 17:15:474432 EXPECT_TRUE(response1->proxy_server.is_http());
wezca1070932016-05-26 20:30:524433 ASSERT_TRUE(response1->headers);
[email protected]029c83b62013-01-24 05:28:204434 EXPECT_EQ(1, response1->headers->GetContentLength());
4435
4436 LoadTimingInfo load_timing_info1;
4437 EXPECT_TRUE(trans1->GetLoadTimingInfo(&load_timing_info1));
4438 TestLoadTimingNotReused(load_timing_info1, CONNECT_TIMING_HAS_SSL_TIMES);
4439
4440 trans1.reset();
4441
4442 TestCompletionCallback callback2;
bnc691fda62016-08-12 00:43:164443 std::unique_ptr<HttpNetworkTransaction> trans2(
[email protected]90499482013-06-01 00:39:504444 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]029c83b62013-01-24 05:28:204445
4446 rv = trans2->Start(&request2, callback2.callback(), log.bound());
robpercival214763f2016-07-01 23:27:014447 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]029c83b62013-01-24 05:28:204448
4449 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:014450 EXPECT_THAT(rv, IsOk());
[email protected]029c83b62013-01-24 05:28:204451
4452 const HttpResponseInfo* response2 = trans2->GetResponseInfo();
wezca1070932016-05-26 20:30:524453 ASSERT_TRUE(response2);
tbansal2ecbbc72016-10-06 17:15:474454 EXPECT_TRUE(response2->proxy_server.is_http());
wezca1070932016-05-26 20:30:524455 ASSERT_TRUE(response2->headers);
[email protected]029c83b62013-01-24 05:28:204456 EXPECT_EQ(2, response2->headers->GetContentLength());
4457
4458 LoadTimingInfo load_timing_info2;
4459 EXPECT_TRUE(trans2->GetLoadTimingInfo(&load_timing_info2));
4460 TestLoadTimingReused(load_timing_info2);
4461
4462 EXPECT_EQ(load_timing_info1.socket_log_id, load_timing_info2.socket_log_id);
4463
4464 trans2.reset();
4465 session->CloseAllConnections();
4466}
4467
4468// Test the load timing for HTTPS requests with an HTTP proxy and a PAC script.
bncd16676a2016-07-20 16:23:014469TEST_F(HttpNetworkTransactionTest, HttpProxyLoadTimingWithPacTwoRequests) {
[email protected]029c83b62013-01-24 05:28:204470 HttpRequestInfo request1;
4471 request1.method = "GET";
bncce36dca22015-04-21 22:11:234472 request1.url = GURL("https://www.example.org/1");
[email protected]029c83b62013-01-24 05:28:204473
4474 HttpRequestInfo request2;
4475 request2.method = "GET";
bncce36dca22015-04-21 22:11:234476 request2.url = GURL("https://www.example.org/2");
[email protected]029c83b62013-01-24 05:28:204477
4478 // Configure against proxy server "myproxy:70".
rdsmith82957ad2015-09-16 19:42:034479 session_deps_.proxy_service =
4480 ProxyService::CreateFixedFromPacResult("PROXY myproxy:70");
vishal.b62985ca92015-04-17 08:45:514481 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:074482 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:094483 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]029c83b62013-01-24 05:28:204484
4485 // Since we have proxy, should try to establish tunnel.
4486 MockWrite data_writes1[] = {
rsleevidb16bb02015-11-12 23:47:174487 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
4488 "Host: www.example.org:443\r\n"
4489 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]029c83b62013-01-24 05:28:204490
rsleevidb16bb02015-11-12 23:47:174491 MockWrite("GET /1 HTTP/1.1\r\n"
4492 "Host: www.example.org\r\n"
4493 "Connection: keep-alive\r\n\r\n"),
[email protected]029c83b62013-01-24 05:28:204494
rsleevidb16bb02015-11-12 23:47:174495 MockWrite("GET /2 HTTP/1.1\r\n"
4496 "Host: www.example.org\r\n"
4497 "Connection: keep-alive\r\n\r\n"),
[email protected]029c83b62013-01-24 05:28:204498 };
4499
4500 // The proxy responds to the connect with a 407, using a persistent
4501 // connection.
4502 MockRead data_reads1[] = {
4503 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
4504
4505 MockRead("HTTP/1.1 200 OK\r\n"),
4506 MockRead("Content-Length: 1\r\n\r\n"),
4507 MockRead(SYNCHRONOUS, "1"),
4508
4509 MockRead("HTTP/1.1 200 OK\r\n"),
4510 MockRead("Content-Length: 2\r\n\r\n"),
4511 MockRead(SYNCHRONOUS, "22"),
4512 };
4513
4514 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
4515 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:074516 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]029c83b62013-01-24 05:28:204517 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:074518 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]029c83b62013-01-24 05:28:204519
4520 TestCompletionCallback callback1;
bnc691fda62016-08-12 00:43:164521 std::unique_ptr<HttpNetworkTransaction> trans1(
[email protected]90499482013-06-01 00:39:504522 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]029c83b62013-01-24 05:28:204523
4524 int rv = trans1->Start(&request1, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:014525 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]029c83b62013-01-24 05:28:204526
4527 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:014528 EXPECT_THAT(rv, IsOk());
[email protected]029c83b62013-01-24 05:28:204529
4530 const HttpResponseInfo* response1 = trans1->GetResponseInfo();
wezca1070932016-05-26 20:30:524531 ASSERT_TRUE(response1);
4532 ASSERT_TRUE(response1->headers);
[email protected]029c83b62013-01-24 05:28:204533 EXPECT_EQ(1, response1->headers->GetContentLength());
4534
4535 LoadTimingInfo load_timing_info1;
4536 EXPECT_TRUE(trans1->GetLoadTimingInfo(&load_timing_info1));
4537 TestLoadTimingNotReusedWithPac(load_timing_info1,
4538 CONNECT_TIMING_HAS_SSL_TIMES);
4539
4540 trans1.reset();
4541
4542 TestCompletionCallback callback2;
bnc691fda62016-08-12 00:43:164543 std::unique_ptr<HttpNetworkTransaction> trans2(
[email protected]90499482013-06-01 00:39:504544 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]029c83b62013-01-24 05:28:204545
4546 rv = trans2->Start(&request2, callback2.callback(), log.bound());
robpercival214763f2016-07-01 23:27:014547 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]029c83b62013-01-24 05:28:204548
4549 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:014550 EXPECT_THAT(rv, IsOk());
[email protected]029c83b62013-01-24 05:28:204551
4552 const HttpResponseInfo* response2 = trans2->GetResponseInfo();
wezca1070932016-05-26 20:30:524553 ASSERT_TRUE(response2);
4554 ASSERT_TRUE(response2->headers);
[email protected]029c83b62013-01-24 05:28:204555 EXPECT_EQ(2, response2->headers->GetContentLength());
4556
4557 LoadTimingInfo load_timing_info2;
4558 EXPECT_TRUE(trans2->GetLoadTimingInfo(&load_timing_info2));
4559 TestLoadTimingReusedWithPac(load_timing_info2);
4560
4561 EXPECT_EQ(load_timing_info1.socket_log_id, load_timing_info2.socket_log_id);
4562
4563 trans2.reset();
4564 session->CloseAllConnections();
4565}
4566
[email protected]2df19bb2010-08-25 20:13:464567// Test a simple get through an HTTPS Proxy.
bncd16676a2016-07-20 16:23:014568TEST_F(HttpNetworkTransactionTest, HttpsProxyGet) {
[email protected]cb9bf6ca2011-01-28 13:15:274569 HttpRequestInfo request;
4570 request.method = "GET";
bncce36dca22015-04-21 22:11:234571 request.url = GURL("http://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:274572
[email protected]2df19bb2010-08-25 20:13:464573 // Configure against https proxy server "proxy:70".
rdsmith82957ad2015-09-16 19:42:034574 session_deps_.proxy_service = ProxyService::CreateFixed("https://proxy:70");
vishal.b62985ca92015-04-17 08:45:514575 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:074576 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:094577 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]2df19bb2010-08-25 20:13:464578
[email protected]2df19bb2010-08-25 20:13:464579 // Since we have proxy, should use full url
4580 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:234581 MockWrite(
4582 "GET http://www.example.org/ HTTP/1.1\r\n"
4583 "Host: www.example.org\r\n"
4584 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]2df19bb2010-08-25 20:13:464585 };
4586
4587 MockRead data_reads1[] = {
4588 MockRead("HTTP/1.1 200 OK\r\n"),
4589 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
4590 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:064591 MockRead(SYNCHRONOUS, OK),
[email protected]2df19bb2010-08-25 20:13:464592 };
4593
4594 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
4595 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:074596 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8ddf8322012-02-23 18:08:064597 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:074598 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]2df19bb2010-08-25 20:13:464599
[email protected]49639fa2011-12-20 23:22:414600 TestCompletionCallback callback1;
[email protected]2df19bb2010-08-25 20:13:464601
bnc691fda62016-08-12 00:43:164602 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]0b0bf032010-09-21 18:08:504603
bnc691fda62016-08-12 00:43:164604 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:014605 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2df19bb2010-08-25 20:13:464606
4607 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:014608 EXPECT_THAT(rv, IsOk());
[email protected]2df19bb2010-08-25 20:13:464609
[email protected]58e32bb2013-01-21 18:23:254610 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:164611 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]58e32bb2013-01-21 18:23:254612 TestLoadTimingNotReused(load_timing_info,
4613 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
4614
bnc691fda62016-08-12 00:43:164615 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:524616 ASSERT_TRUE(response);
[email protected]2df19bb2010-08-25 20:13:464617
tbansal2ecbbc72016-10-06 17:15:474618 EXPECT_TRUE(response->proxy_server.is_https());
[email protected]2df19bb2010-08-25 20:13:464619 EXPECT_TRUE(response->headers->IsKeepAlive());
4620 EXPECT_EQ(200, response->headers->response_code());
4621 EXPECT_EQ(100, response->headers->GetContentLength());
4622 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
4623
4624 // The password prompt info should not be set.
wezca1070932016-05-26 20:30:524625 EXPECT_FALSE(response->auth_challenge);
[email protected]2df19bb2010-08-25 20:13:464626}
4627
[email protected]7642b5ae2010-09-01 20:55:174628// Test a SPDY get through an HTTPS Proxy.
bncd16676a2016-07-20 16:23:014629TEST_F(HttpNetworkTransactionTest, HttpsProxySpdyGet) {
[email protected]cb9bf6ca2011-01-28 13:15:274630 HttpRequestInfo request;
4631 request.method = "GET";
bncce36dca22015-04-21 22:11:234632 request.url = GURL("http://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:274633
[email protected]7642b5ae2010-09-01 20:55:174634 // Configure against https proxy server "proxy:70".
rdsmith82957ad2015-09-16 19:42:034635 session_deps_.proxy_service = ProxyService::CreateFixed("https://proxy:70");
vishal.b62985ca92015-04-17 08:45:514636 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:074637 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:094638 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]7642b5ae2010-09-01 20:55:174639
bncce36dca22015-04-21 22:11:234640 // fetch http://www.example.org/ via SPDY
bncdf80d44fd2016-07-15 20:27:414641 SpdySerializedFrame req(
bncb26024382016-06-29 02:39:454642 spdy_util_.ConstructSpdyGet("http://www.example.org/", 1, LOWEST));
bncdf80d44fd2016-07-15 20:27:414643 MockWrite spdy_writes[] = {CreateMockWrite(req, 0)};
[email protected]7642b5ae2010-09-01 20:55:174644
bnc42331402016-07-25 13:36:154645 SpdySerializedFrame resp(spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
bncdf80d44fd2016-07-15 20:27:414646 SpdySerializedFrame data(spdy_util_.ConstructSpdyDataFrame(1, true));
[email protected]7642b5ae2010-09-01 20:55:174647 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:414648 CreateMockRead(resp, 1), CreateMockRead(data, 2), MockRead(ASYNC, 0, 3),
[email protected]7642b5ae2010-09-01 20:55:174649 };
4650
rch8e6c6c42015-05-01 14:05:134651 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
4652 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:074653 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]7642b5ae2010-09-01 20:55:174654
[email protected]8ddf8322012-02-23 18:08:064655 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:364656 ssl.next_proto = kProtoHTTP2;
[email protected]bb88e1d32013-05-03 23:11:074657 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]7642b5ae2010-09-01 20:55:174658
[email protected]49639fa2011-12-20 23:22:414659 TestCompletionCallback callback1;
[email protected]7642b5ae2010-09-01 20:55:174660
bnc691fda62016-08-12 00:43:164661 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]0b0bf032010-09-21 18:08:504662
bnc691fda62016-08-12 00:43:164663 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:014664 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]7642b5ae2010-09-01 20:55:174665
4666 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:014667 EXPECT_THAT(rv, IsOk());
[email protected]7642b5ae2010-09-01 20:55:174668
[email protected]58e32bb2013-01-21 18:23:254669 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:164670 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]58e32bb2013-01-21 18:23:254671 TestLoadTimingNotReused(load_timing_info,
4672 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
4673
bnc691fda62016-08-12 00:43:164674 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:524675 ASSERT_TRUE(response);
tbansal2ecbbc72016-10-06 17:15:474676 EXPECT_TRUE(response->proxy_server.is_https());
wezca1070932016-05-26 20:30:524677 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:024678 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]7642b5ae2010-09-01 20:55:174679
4680 std::string response_data;
bnc691fda62016-08-12 00:43:164681 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
[email protected]448d4ca52012-03-04 04:12:234682 EXPECT_EQ(kUploadData, response_data);
[email protected]7642b5ae2010-09-01 20:55:174683}
4684
[email protected]1c173852014-06-19 12:51:504685// Verifies that a session which races and wins against the owning transaction
4686// (completing prior to host resolution), doesn't fail the transaction.
4687// Regression test for crbug.com/334413.
bncd16676a2016-07-20 16:23:014688TEST_F(HttpNetworkTransactionTest, HttpsProxySpdyGetWithSessionRace) {
[email protected]1c173852014-06-19 12:51:504689 HttpRequestInfo request;
4690 request.method = "GET";
bncce36dca22015-04-21 22:11:234691 request.url = GURL("http://www.example.org/");
[email protected]1c173852014-06-19 12:51:504692
4693 // Configure SPDY proxy server "proxy:70".
rdsmith82957ad2015-09-16 19:42:034694 session_deps_.proxy_service = ProxyService::CreateFixed("https://proxy:70");
vishal.b62985ca92015-04-17 08:45:514695 BoundTestNetLog log;
[email protected]1c173852014-06-19 12:51:504696 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:094697 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]1c173852014-06-19 12:51:504698
bncce36dca22015-04-21 22:11:234699 // Fetch http://www.example.org/ through the SPDY proxy.
bncdf80d44fd2016-07-15 20:27:414700 SpdySerializedFrame req(
bncb26024382016-06-29 02:39:454701 spdy_util_.ConstructSpdyGet("http://www.example.org/", 1, LOWEST));
bncdf80d44fd2016-07-15 20:27:414702 MockWrite spdy_writes[] = {CreateMockWrite(req, 0)};
[email protected]1c173852014-06-19 12:51:504703
bnc42331402016-07-25 13:36:154704 SpdySerializedFrame resp(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
bncdf80d44fd2016-07-15 20:27:414705 SpdySerializedFrame data(spdy_util_.ConstructSpdyDataFrame(1, true));
[email protected]1c173852014-06-19 12:51:504706 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:414707 CreateMockRead(resp, 1), CreateMockRead(data, 2), MockRead(ASYNC, 0, 3),
[email protected]1c173852014-06-19 12:51:504708 };
4709
rch8e6c6c42015-05-01 14:05:134710 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
4711 arraysize(spdy_writes));
[email protected]1c173852014-06-19 12:51:504712 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
4713
4714 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:364715 ssl.next_proto = kProtoHTTP2;
[email protected]1c173852014-06-19 12:51:504716 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
4717
4718 TestCompletionCallback callback1;
4719
bnc691fda62016-08-12 00:43:164720 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]1c173852014-06-19 12:51:504721
4722 // Stall the hostname resolution begun by the transaction.
4723 session_deps_.host_resolver->set_synchronous_mode(false);
4724 session_deps_.host_resolver->set_ondemand_mode(true);
4725
bnc691fda62016-08-12 00:43:164726 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:014727 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]1c173852014-06-19 12:51:504728
4729 // Race a session to the proxy, which completes first.
4730 session_deps_.host_resolver->set_ondemand_mode(false);
4731 SpdySessionKey key(
4732 HostPortPair("proxy", 70), ProxyServer::Direct(), PRIVACY_MODE_DISABLED);
4733 base::WeakPtr<SpdySession> spdy_session =
mmenkee65e7af2015-10-13 17:16:424734 CreateSecureSpdySession(session.get(), key, log.bound());
[email protected]1c173852014-06-19 12:51:504735
4736 // Unstall the resolution begun by the transaction.
4737 session_deps_.host_resolver->set_ondemand_mode(true);
4738 session_deps_.host_resolver->ResolveAllPending();
4739
4740 EXPECT_FALSE(callback1.have_result());
4741 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:014742 EXPECT_THAT(rv, IsOk());
[email protected]1c173852014-06-19 12:51:504743
bnc691fda62016-08-12 00:43:164744 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:524745 ASSERT_TRUE(response);
4746 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:024747 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]1c173852014-06-19 12:51:504748
4749 std::string response_data;
bnc691fda62016-08-12 00:43:164750 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
[email protected]1c173852014-06-19 12:51:504751 EXPECT_EQ(kUploadData, response_data);
4752}
4753
[email protected]dc7bd1c52010-11-12 00:01:134754// Test a SPDY get through an HTTPS Proxy.
bncd16676a2016-07-20 16:23:014755TEST_F(HttpNetworkTransactionTest, HttpsProxySpdyGetWithProxyAuth) {
[email protected]cb9bf6ca2011-01-28 13:15:274756 HttpRequestInfo request;
4757 request.method = "GET";
bncce36dca22015-04-21 22:11:234758 request.url = GURL("http://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:274759
[email protected]79cb5c12011-09-12 13:12:044760 // Configure against https proxy server "myproxy:70".
rdsmith82957ad2015-09-16 19:42:034761 session_deps_.proxy_service = ProxyService::CreateFixed("https://myproxy:70");
vishal.b62985ca92015-04-17 08:45:514762 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:074763 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:094764 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]dc7bd1c52010-11-12 00:01:134765
[email protected]dc7bd1c52010-11-12 00:01:134766 // The first request will be a bare GET, the second request will be a
4767 // GET with a Proxy-Authorization header.
bncb26024382016-06-29 02:39:454768 spdy_util_.set_default_url(request.url);
bncdf80d44fd2016-07-15 20:27:414769 SpdySerializedFrame req_get(
bnc38dcd392016-02-09 23:19:494770 spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST, false));
rdsmithebb50aa2015-11-12 03:44:384771 spdy_util_.UpdateWithStreamDestruction(1);
[email protected]dc7bd1c52010-11-12 00:01:134772 const char* const kExtraAuthorizationHeaders[] = {
[email protected]cdf8f7e72013-05-23 10:56:464773 "proxy-authorization", "Basic Zm9vOmJhcg=="
[email protected]dc7bd1c52010-11-12 00:01:134774 };
bncdf80d44fd2016-07-15 20:27:414775 SpdySerializedFrame req_get_authorization(spdy_util_.ConstructSpdyGet(
4776 kExtraAuthorizationHeaders, arraysize(kExtraAuthorizationHeaders) / 2, 3,
4777 LOWEST, false));
[email protected]dc7bd1c52010-11-12 00:01:134778 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:414779 CreateMockWrite(req_get, 0), CreateMockWrite(req_get_authorization, 3),
[email protected]dc7bd1c52010-11-12 00:01:134780 };
4781
4782 // The first response is a 407 proxy authentication challenge, and the second
4783 // response will be a 200 response since the second request includes a valid
4784 // Authorization header.
4785 const char* const kExtraAuthenticationHeaders[] = {
[email protected]cdf8f7e72013-05-23 10:56:464786 "proxy-authenticate", "Basic realm=\"MyRealm1\""
[email protected]dc7bd1c52010-11-12 00:01:134787 };
bnc42331402016-07-25 13:36:154788 SpdySerializedFrame resp_authentication(spdy_util_.ConstructSpdyReplyError(
bncc9f762a2016-12-06 20:38:234789 "407", kExtraAuthenticationHeaders,
bncdf80d44fd2016-07-15 20:27:414790 arraysize(kExtraAuthenticationHeaders) / 2, 1));
4791 SpdySerializedFrame body_authentication(
4792 spdy_util_.ConstructSpdyDataFrame(1, true));
bnc42331402016-07-25 13:36:154793 SpdySerializedFrame resp_data(spdy_util_.ConstructSpdyGetReply(NULL, 0, 3));
bncdf80d44fd2016-07-15 20:27:414794 SpdySerializedFrame body_data(spdy_util_.ConstructSpdyDataFrame(3, true));
[email protected]dc7bd1c52010-11-12 00:01:134795 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:414796 CreateMockRead(resp_authentication, 1),
bnceb9aa7112017-01-05 01:03:464797 CreateMockRead(body_authentication, 2, SYNCHRONOUS),
bncdf80d44fd2016-07-15 20:27:414798 CreateMockRead(resp_data, 4),
4799 CreateMockRead(body_data, 5),
rch8e6c6c42015-05-01 14:05:134800 MockRead(ASYNC, 0, 6),
[email protected]dc7bd1c52010-11-12 00:01:134801 };
4802
rch8e6c6c42015-05-01 14:05:134803 SequencedSocketData data(spdy_reads, arraysize(spdy_reads), spdy_writes,
4804 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:074805 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]dc7bd1c52010-11-12 00:01:134806
[email protected]8ddf8322012-02-23 18:08:064807 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:364808 ssl.next_proto = kProtoHTTP2;
[email protected]bb88e1d32013-05-03 23:11:074809 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]dc7bd1c52010-11-12 00:01:134810
[email protected]49639fa2011-12-20 23:22:414811 TestCompletionCallback callback1;
[email protected]dc7bd1c52010-11-12 00:01:134812
bnc691fda62016-08-12 00:43:164813 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]dc7bd1c52010-11-12 00:01:134814
bnc691fda62016-08-12 00:43:164815 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:014816 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]dc7bd1c52010-11-12 00:01:134817
4818 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:014819 EXPECT_THAT(rv, IsOk());
[email protected]dc7bd1c52010-11-12 00:01:134820
bnc691fda62016-08-12 00:43:164821 const HttpResponseInfo* const response = trans.GetResponseInfo();
[email protected]dc7bd1c52010-11-12 00:01:134822
wezca1070932016-05-26 20:30:524823 ASSERT_TRUE(response);
4824 ASSERT_TRUE(response->headers);
[email protected]dc7bd1c52010-11-12 00:01:134825 EXPECT_EQ(407, response->headers->response_code());
4826 EXPECT_TRUE(response->was_fetched_via_spdy);
asanka098c0092016-06-16 20:18:434827 EXPECT_TRUE(CheckBasicSecureProxyAuth(response->auth_challenge.get()));
[email protected]dc7bd1c52010-11-12 00:01:134828
[email protected]49639fa2011-12-20 23:22:414829 TestCompletionCallback callback2;
[email protected]dc7bd1c52010-11-12 00:01:134830
bnc691fda62016-08-12 00:43:164831 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar), callback2.callback());
robpercival214763f2016-07-01 23:27:014832 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]dc7bd1c52010-11-12 00:01:134833
4834 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:014835 EXPECT_THAT(rv, IsOk());
[email protected]dc7bd1c52010-11-12 00:01:134836
bnc691fda62016-08-12 00:43:164837 const HttpResponseInfo* const response_restart = trans.GetResponseInfo();
[email protected]dc7bd1c52010-11-12 00:01:134838
wezca1070932016-05-26 20:30:524839 ASSERT_TRUE(response_restart);
4840 ASSERT_TRUE(response_restart->headers);
[email protected]dc7bd1c52010-11-12 00:01:134841 EXPECT_EQ(200, response_restart->headers->response_code());
4842 // The password prompt info should not be set.
wezca1070932016-05-26 20:30:524843 EXPECT_FALSE(response_restart->auth_challenge);
[email protected]dc7bd1c52010-11-12 00:01:134844}
4845
[email protected]d9da5fe2010-10-13 22:37:164846// Test a SPDY CONNECT through an HTTPS Proxy to an HTTPS (non-SPDY) Server.
bncd16676a2016-07-20 16:23:014847TEST_F(HttpNetworkTransactionTest, HttpsProxySpdyConnectHttps) {
[email protected]cb9bf6ca2011-01-28 13:15:274848 HttpRequestInfo request;
4849 request.method = "GET";
bncce36dca22015-04-21 22:11:234850 request.url = GURL("https://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:274851
[email protected]d9da5fe2010-10-13 22:37:164852 // Configure against https proxy server "proxy:70".
rdsmith82957ad2015-09-16 19:42:034853 session_deps_.proxy_service = ProxyService::CreateFixed("https://proxy:70");
vishal.b62985ca92015-04-17 08:45:514854 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:074855 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:094856 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]d9da5fe2010-10-13 22:37:164857
bnc691fda62016-08-12 00:43:164858 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]d9da5fe2010-10-13 22:37:164859
bncce36dca22015-04-21 22:11:234860 // CONNECT to www.example.org:443 via SPDY
bncdf80d44fd2016-07-15 20:27:414861 SpdySerializedFrame connect(spdy_util_.ConstructSpdyConnect(
bncce36dca22015-04-21 22:11:234862 NULL, 0, 1, LOWEST, HostPortPair("www.example.org", 443)));
4863 // fetch https://www.example.org/ via HTTP
[email protected]d9da5fe2010-10-13 22:37:164864
bncce36dca22015-04-21 22:11:234865 const char get[] =
4866 "GET / HTTP/1.1\r\n"
4867 "Host: www.example.org\r\n"
4868 "Connection: keep-alive\r\n\r\n";
bncdf80d44fd2016-07-15 20:27:414869 SpdySerializedFrame wrapped_get(
4870 spdy_util_.ConstructSpdyDataFrame(1, get, strlen(get), false));
bnc42331402016-07-25 13:36:154871 SpdySerializedFrame conn_resp(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
[email protected]d9da5fe2010-10-13 22:37:164872 const char resp[] = "HTTP/1.1 200 OK\r\n"
4873 "Content-Length: 10\r\n\r\n";
bncdf80d44fd2016-07-15 20:27:414874 SpdySerializedFrame wrapped_get_resp(
4875 spdy_util_.ConstructSpdyDataFrame(1, resp, strlen(resp), false));
4876 SpdySerializedFrame wrapped_body(
4877 spdy_util_.ConstructSpdyDataFrame(1, "1234567890", 10, false));
4878 SpdySerializedFrame window_update(
4879 spdy_util_.ConstructSpdyWindowUpdate(1, wrapped_get_resp.size()));
[email protected]8d2f7012012-02-16 00:08:044880
4881 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:414882 CreateMockWrite(connect, 0), CreateMockWrite(wrapped_get, 2),
4883 CreateMockWrite(window_update, 6),
[email protected]8d2f7012012-02-16 00:08:044884 };
4885
[email protected]d9da5fe2010-10-13 22:37:164886 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:414887 CreateMockRead(conn_resp, 1, ASYNC),
4888 CreateMockRead(wrapped_get_resp, 3, ASYNC),
4889 CreateMockRead(wrapped_body, 4, ASYNC),
4890 CreateMockRead(wrapped_body, 5, ASYNC),
rch8e6c6c42015-05-01 14:05:134891 MockRead(ASYNC, 0, 7),
[email protected]d9da5fe2010-10-13 22:37:164892 };
4893
rch8e6c6c42015-05-01 14:05:134894 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
4895 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:074896 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]d9da5fe2010-10-13 22:37:164897
[email protected]8ddf8322012-02-23 18:08:064898 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:364899 ssl.next_proto = kProtoHTTP2;
[email protected]bb88e1d32013-05-03 23:11:074900 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]8ddf8322012-02-23 18:08:064901 SSLSocketDataProvider ssl2(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:074902 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
[email protected]d9da5fe2010-10-13 22:37:164903
[email protected]49639fa2011-12-20 23:22:414904 TestCompletionCallback callback1;
[email protected]d9da5fe2010-10-13 22:37:164905
bnc691fda62016-08-12 00:43:164906 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:014907 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]d9da5fe2010-10-13 22:37:164908
4909 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:014910 ASSERT_THAT(rv, IsOk());
[email protected]d9da5fe2010-10-13 22:37:164911
[email protected]58e32bb2013-01-21 18:23:254912 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:164913 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]58e32bb2013-01-21 18:23:254914 TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_SSL_TIMES);
4915
bnc691fda62016-08-12 00:43:164916 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:524917 ASSERT_TRUE(response);
4918 ASSERT_TRUE(response->headers);
[email protected]d9da5fe2010-10-13 22:37:164919 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
4920
4921 std::string response_data;
bnc691fda62016-08-12 00:43:164922 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
[email protected]d9da5fe2010-10-13 22:37:164923 EXPECT_EQ("1234567890", response_data);
4924}
4925
4926// Test a SPDY CONNECT through an HTTPS Proxy to a SPDY server.
bncd16676a2016-07-20 16:23:014927TEST_F(HttpNetworkTransactionTest, HttpsProxySpdyConnectSpdy) {
4928 SpdyTestUtil spdy_util_wrapped;
rdsmithebb50aa2015-11-12 03:44:384929
[email protected]cb9bf6ca2011-01-28 13:15:274930 HttpRequestInfo request;
4931 request.method = "GET";
bncce36dca22015-04-21 22:11:234932 request.url = GURL("https://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:274933
[email protected]d9da5fe2010-10-13 22:37:164934 // Configure against https proxy server "proxy:70".
rdsmith82957ad2015-09-16 19:42:034935 session_deps_.proxy_service = ProxyService::CreateFixed("https://proxy:70");
vishal.b62985ca92015-04-17 08:45:514936 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:074937 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:094938 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]d9da5fe2010-10-13 22:37:164939
bnc691fda62016-08-12 00:43:164940 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]d9da5fe2010-10-13 22:37:164941
bncce36dca22015-04-21 22:11:234942 // CONNECT to www.example.org:443 via SPDY
bncdf80d44fd2016-07-15 20:27:414943 SpdySerializedFrame connect(spdy_util_.ConstructSpdyConnect(
bncce36dca22015-04-21 22:11:234944 NULL, 0, 1, LOWEST, HostPortPair("www.example.org", 443)));
4945 // fetch https://www.example.org/ via SPDY
4946 const char kMyUrl[] = "https://www.example.org/";
bncdf80d44fd2016-07-15 20:27:414947 SpdySerializedFrame get(
bnc38dcd392016-02-09 23:19:494948 spdy_util_wrapped.ConstructSpdyGet(kMyUrl, 1, LOWEST));
bncdf80d44fd2016-07-15 20:27:414949 SpdySerializedFrame wrapped_get(spdy_util_.ConstructWrappedSpdyFrame(get, 1));
bnc42331402016-07-25 13:36:154950 SpdySerializedFrame conn_resp(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
bncdf80d44fd2016-07-15 20:27:414951 SpdySerializedFrame get_resp(
bnc42331402016-07-25 13:36:154952 spdy_util_wrapped.ConstructSpdyGetReply(NULL, 0, 1));
bncdf80d44fd2016-07-15 20:27:414953 SpdySerializedFrame wrapped_get_resp(
[email protected]23e482282013-06-14 16:08:024954 spdy_util_.ConstructWrappedSpdyFrame(get_resp, 1));
bncdf80d44fd2016-07-15 20:27:414955 SpdySerializedFrame body(spdy_util_wrapped.ConstructSpdyDataFrame(1, true));
4956 SpdySerializedFrame wrapped_body(
[email protected]23e482282013-06-14 16:08:024957 spdy_util_.ConstructWrappedSpdyFrame(body, 1));
bncdf80d44fd2016-07-15 20:27:414958 SpdySerializedFrame window_update_get_resp(
4959 spdy_util_.ConstructSpdyWindowUpdate(1, wrapped_get_resp.size()));
4960 SpdySerializedFrame window_update_body(
4961 spdy_util_.ConstructSpdyWindowUpdate(1, wrapped_body.size()));
[email protected]8d2f7012012-02-16 00:08:044962
4963 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:414964 CreateMockWrite(connect, 0), CreateMockWrite(wrapped_get, 2),
4965 CreateMockWrite(window_update_get_resp, 6),
4966 CreateMockWrite(window_update_body, 7),
[email protected]8d2f7012012-02-16 00:08:044967 };
4968
[email protected]d9da5fe2010-10-13 22:37:164969 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:414970 CreateMockRead(conn_resp, 1, ASYNC),
rch32320842015-05-16 15:57:094971 MockRead(ASYNC, ERR_IO_PENDING, 3),
bncdf80d44fd2016-07-15 20:27:414972 CreateMockRead(wrapped_get_resp, 4, ASYNC),
4973 CreateMockRead(wrapped_body, 5, ASYNC),
rch8e6c6c42015-05-01 14:05:134974 MockRead(ASYNC, 0, 8),
[email protected]d9da5fe2010-10-13 22:37:164975 };
4976
rch32320842015-05-16 15:57:094977 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
4978 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:074979 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]d9da5fe2010-10-13 22:37:164980
[email protected]8ddf8322012-02-23 18:08:064981 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:364982 ssl.next_proto = kProtoHTTP2;
[email protected]bb88e1d32013-05-03 23:11:074983 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]8ddf8322012-02-23 18:08:064984 SSLSocketDataProvider ssl2(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:364985 ssl2.next_proto = kProtoHTTP2;
[email protected]bb88e1d32013-05-03 23:11:074986 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
[email protected]d9da5fe2010-10-13 22:37:164987
[email protected]49639fa2011-12-20 23:22:414988 TestCompletionCallback callback1;
[email protected]d9da5fe2010-10-13 22:37:164989
bnc691fda62016-08-12 00:43:164990 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:014991 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]d9da5fe2010-10-13 22:37:164992
rch32320842015-05-16 15:57:094993 // Allow the SpdyProxyClientSocket's write callback to complete.
fdoray92e35a72016-06-10 15:54:554994 base::RunLoop().RunUntilIdle();
rch32320842015-05-16 15:57:094995 // Now allow the read of the response to complete.
mmenkee24011922015-12-17 22:12:594996 spdy_data.Resume();
[email protected]d9da5fe2010-10-13 22:37:164997 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:014998 EXPECT_THAT(rv, IsOk());
[email protected]d9da5fe2010-10-13 22:37:164999
[email protected]58e32bb2013-01-21 18:23:255000 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:165001 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]58e32bb2013-01-21 18:23:255002 TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_SSL_TIMES);
5003
bnc691fda62016-08-12 00:43:165004 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:525005 ASSERT_TRUE(response);
5006 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:025007 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]d9da5fe2010-10-13 22:37:165008
5009 std::string response_data;
bnc691fda62016-08-12 00:43:165010 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
[email protected]448d4ca52012-03-04 04:12:235011 EXPECT_EQ(kUploadData, response_data);
[email protected]d9da5fe2010-10-13 22:37:165012}
5013
5014// Test a SPDY CONNECT failure through an HTTPS Proxy.
bncd16676a2016-07-20 16:23:015015TEST_F(HttpNetworkTransactionTest, HttpsProxySpdyConnectFailure) {
[email protected]cb9bf6ca2011-01-28 13:15:275016 HttpRequestInfo request;
5017 request.method = "GET";
bncce36dca22015-04-21 22:11:235018 request.url = GURL("https://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:275019
[email protected]d9da5fe2010-10-13 22:37:165020 // Configure against https proxy server "proxy:70".
rdsmith82957ad2015-09-16 19:42:035021 session_deps_.proxy_service = ProxyService::CreateFixed("https://proxy:70");
vishal.b62985ca92015-04-17 08:45:515022 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:075023 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:095024 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]d9da5fe2010-10-13 22:37:165025
bnc691fda62016-08-12 00:43:165026 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]d9da5fe2010-10-13 22:37:165027
bncce36dca22015-04-21 22:11:235028 // CONNECT to www.example.org:443 via SPDY
bncdf80d44fd2016-07-15 20:27:415029 SpdySerializedFrame connect(spdy_util_.ConstructSpdyConnect(
bncce36dca22015-04-21 22:11:235030 NULL, 0, 1, LOWEST, HostPortPair("www.example.org", 443)));
bncdf80d44fd2016-07-15 20:27:415031 SpdySerializedFrame get(
diannahu9904e272017-02-03 14:40:085032 spdy_util_.ConstructSpdyRstStream(1, ERROR_CODE_CANCEL));
[email protected]d9da5fe2010-10-13 22:37:165033
5034 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:415035 CreateMockWrite(connect, 0), CreateMockWrite(get, 2),
[email protected]d9da5fe2010-10-13 22:37:165036 };
5037
bnc42331402016-07-25 13:36:155038 SpdySerializedFrame resp(spdy_util_.ConstructSpdyReplyError(1));
bncdf80d44fd2016-07-15 20:27:415039 SpdySerializedFrame data(spdy_util_.ConstructSpdyDataFrame(1, true));
[email protected]d9da5fe2010-10-13 22:37:165040 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:415041 CreateMockRead(resp, 1, ASYNC), MockRead(ASYNC, 0, 3),
[email protected]d9da5fe2010-10-13 22:37:165042 };
5043
rch8e6c6c42015-05-01 14:05:135044 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
5045 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:075046 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]d9da5fe2010-10-13 22:37:165047
[email protected]8ddf8322012-02-23 18:08:065048 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:365049 ssl.next_proto = kProtoHTTP2;
[email protected]bb88e1d32013-05-03 23:11:075050 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]8ddf8322012-02-23 18:08:065051 SSLSocketDataProvider ssl2(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:365052 ssl2.next_proto = kProtoHTTP2;
[email protected]bb88e1d32013-05-03 23:11:075053 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
[email protected]d9da5fe2010-10-13 22:37:165054
[email protected]49639fa2011-12-20 23:22:415055 TestCompletionCallback callback1;
[email protected]d9da5fe2010-10-13 22:37:165056
bnc691fda62016-08-12 00:43:165057 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:015058 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]d9da5fe2010-10-13 22:37:165059
5060 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:015061 EXPECT_THAT(rv, IsError(ERR_TUNNEL_CONNECTION_FAILED));
[email protected]d9da5fe2010-10-13 22:37:165062
ttuttle960fcbf2016-04-19 13:26:325063 // TODO(juliatuttle): Anything else to check here?
[email protected]d9da5fe2010-10-13 22:37:165064}
5065
[email protected]f6c63db52013-02-02 00:35:225066// Test load timing in the case of two HTTPS (non-SPDY) requests through a SPDY
5067// HTTPS Proxy to different servers.
bncd16676a2016-07-20 16:23:015068TEST_F(HttpNetworkTransactionTest,
[email protected]f6c63db52013-02-02 00:35:225069 HttpsProxySpdyConnectHttpsLoadTimingTwoRequestsTwoServers) {
5070 // Configure against https proxy server "proxy:70".
rdsmith82957ad2015-09-16 19:42:035071 session_deps_.proxy_service = ProxyService::CreateFixed("https://proxy:70");
vishal.b62985ca92015-04-17 08:45:515072 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:075073 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:095074 std::unique_ptr<HttpNetworkSession> session(
mmenke11eb5152015-06-09 14:50:505075 SpdySessionDependencies::SpdyCreateSession(&session_deps_));
[email protected]f6c63db52013-02-02 00:35:225076
5077 HttpRequestInfo request1;
5078 request1.method = "GET";
bncce36dca22015-04-21 22:11:235079 request1.url = GURL("https://www.example.org/");
[email protected]f6c63db52013-02-02 00:35:225080 request1.load_flags = 0;
5081
5082 HttpRequestInfo request2;
5083 request2.method = "GET";
bncce36dca22015-04-21 22:11:235084 request2.url = GURL("https://mail.example.org/");
[email protected]f6c63db52013-02-02 00:35:225085 request2.load_flags = 0;
5086
bncce36dca22015-04-21 22:11:235087 // CONNECT to www.example.org:443 via SPDY.
bncdf80d44fd2016-07-15 20:27:415088 SpdySerializedFrame connect1(spdy_util_.ConstructSpdyConnect(
bncce36dca22015-04-21 22:11:235089 NULL, 0, 1, LOWEST, HostPortPair("www.example.org", 443)));
bnc42331402016-07-25 13:36:155090 SpdySerializedFrame conn_resp1(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
[email protected]f6c63db52013-02-02 00:35:225091
bncce36dca22015-04-21 22:11:235092 // Fetch https://www.example.org/ via HTTP.
5093 const char get1[] =
5094 "GET / HTTP/1.1\r\n"
5095 "Host: www.example.org\r\n"
[email protected]f6c63db52013-02-02 00:35:225096 "Connection: keep-alive\r\n\r\n";
bncdf80d44fd2016-07-15 20:27:415097 SpdySerializedFrame wrapped_get1(
5098 spdy_util_.ConstructSpdyDataFrame(1, get1, strlen(get1), false));
[email protected]f6c63db52013-02-02 00:35:225099 const char resp1[] = "HTTP/1.1 200 OK\r\n"
5100 "Content-Length: 1\r\n\r\n";
bncdf80d44fd2016-07-15 20:27:415101 SpdySerializedFrame wrapped_get_resp1(
5102 spdy_util_.ConstructSpdyDataFrame(1, resp1, strlen(resp1), false));
5103 SpdySerializedFrame wrapped_body1(
5104 spdy_util_.ConstructSpdyDataFrame(1, "1", 1, false));
5105 SpdySerializedFrame window_update(
5106 spdy_util_.ConstructSpdyWindowUpdate(1, wrapped_get_resp1.size()));
[email protected]f6c63db52013-02-02 00:35:225107
bncce36dca22015-04-21 22:11:235108 // CONNECT to mail.example.org:443 via SPDY.
[email protected]745aa9c2014-06-27 02:21:295109 SpdyHeaderBlock connect2_block;
5110 connect2_block[spdy_util_.GetMethodKey()] = "CONNECT";
bnca9b9e222016-07-11 20:10:405111 connect2_block[spdy_util_.GetHostKey()] = "mail.example.org:443";
bnc42331402016-07-25 13:36:155112 SpdySerializedFrame connect2(spdy_util_.ConstructSpdyHeaders(
5113 3, std::move(connect2_block), LOWEST, false));
[email protected]601e03f12014-04-06 16:26:395114
bnc42331402016-07-25 13:36:155115 SpdySerializedFrame conn_resp2(spdy_util_.ConstructSpdyGetReply(NULL, 0, 3));
[email protected]f6c63db52013-02-02 00:35:225116
bncce36dca22015-04-21 22:11:235117 // Fetch https://mail.example.org/ via HTTP.
5118 const char get2[] =
5119 "GET / HTTP/1.1\r\n"
5120 "Host: mail.example.org\r\n"
[email protected]f6c63db52013-02-02 00:35:225121 "Connection: keep-alive\r\n\r\n";
bncdf80d44fd2016-07-15 20:27:415122 SpdySerializedFrame wrapped_get2(
5123 spdy_util_.ConstructSpdyDataFrame(3, get2, strlen(get2), false));
[email protected]f6c63db52013-02-02 00:35:225124 const char resp2[] = "HTTP/1.1 200 OK\r\n"
5125 "Content-Length: 2\r\n\r\n";
bncdf80d44fd2016-07-15 20:27:415126 SpdySerializedFrame wrapped_get_resp2(
5127 spdy_util_.ConstructSpdyDataFrame(3, resp2, strlen(resp2), false));
5128 SpdySerializedFrame wrapped_body2(
5129 spdy_util_.ConstructSpdyDataFrame(3, "22", 2, false));
[email protected]f6c63db52013-02-02 00:35:225130
5131 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:415132 CreateMockWrite(connect1, 0), CreateMockWrite(wrapped_get1, 2),
5133 CreateMockWrite(connect2, 5), CreateMockWrite(wrapped_get2, 7),
[email protected]f6c63db52013-02-02 00:35:225134 };
5135
5136 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:415137 CreateMockRead(conn_resp1, 1, ASYNC),
5138 CreateMockRead(wrapped_get_resp1, 3, ASYNC),
5139 CreateMockRead(wrapped_body1, 4, ASYNC),
5140 CreateMockRead(conn_resp2, 6, ASYNC),
5141 CreateMockRead(wrapped_get_resp2, 8, ASYNC),
5142 CreateMockRead(wrapped_body2, 9, ASYNC),
5143 MockRead(ASYNC, 0, 10),
[email protected]f6c63db52013-02-02 00:35:225144 };
5145
mmenke11eb5152015-06-09 14:50:505146 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
5147 arraysize(spdy_writes));
5148 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]f6c63db52013-02-02 00:35:225149
5150 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:365151 ssl.next_proto = kProtoHTTP2;
mmenke11eb5152015-06-09 14:50:505152 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]f6c63db52013-02-02 00:35:225153 SSLSocketDataProvider ssl2(ASYNC, OK);
mmenke11eb5152015-06-09 14:50:505154 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
[email protected]f6c63db52013-02-02 00:35:225155 SSLSocketDataProvider ssl3(ASYNC, OK);
mmenke11eb5152015-06-09 14:50:505156 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl3);
[email protected]f6c63db52013-02-02 00:35:225157
5158 TestCompletionCallback callback;
5159
bnc691fda62016-08-12 00:43:165160 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:205161 int rv = trans.Start(&request1, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:015162 EXPECT_THAT(callback.GetResult(rv), IsOk());
[email protected]f6c63db52013-02-02 00:35:225163
5164 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:165165 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]f6c63db52013-02-02 00:35:225166 TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_SSL_TIMES);
5167
bnc691fda62016-08-12 00:43:165168 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:525169 ASSERT_TRUE(response);
5170 ASSERT_TRUE(response->headers);
[email protected]f6c63db52013-02-02 00:35:225171 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
5172
5173 std::string response_data;
ttuttle859dc7a2015-04-23 19:42:295174 scoped_refptr<IOBuffer> buf(new IOBuffer(256));
bnc691fda62016-08-12 00:43:165175 rv = trans.Read(buf.get(), 256, callback.callback());
mmenke11eb5152015-06-09 14:50:505176 EXPECT_EQ(1, callback.GetResult(rv));
[email protected]f6c63db52013-02-02 00:35:225177
bnc691fda62016-08-12 00:43:165178 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:205179 rv = trans2.Start(&request2, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:015180 EXPECT_THAT(callback.GetResult(rv), IsOk());
[email protected]f6c63db52013-02-02 00:35:225181
5182 LoadTimingInfo load_timing_info2;
bnc691fda62016-08-12 00:43:165183 EXPECT_TRUE(trans2.GetLoadTimingInfo(&load_timing_info2));
[email protected]f6c63db52013-02-02 00:35:225184 // Even though the SPDY connection is reused, a new tunnelled connection has
5185 // to be created, so the socket's load timing looks like a fresh connection.
5186 TestLoadTimingNotReused(load_timing_info2, CONNECT_TIMING_HAS_SSL_TIMES);
5187
5188 // The requests should have different IDs, since they each are using their own
5189 // separate stream.
5190 EXPECT_NE(load_timing_info.socket_log_id, load_timing_info2.socket_log_id);
5191
bnc691fda62016-08-12 00:43:165192 rv = trans2.Read(buf.get(), 256, callback.callback());
mmenke11eb5152015-06-09 14:50:505193 EXPECT_EQ(2, callback.GetResult(rv));
[email protected]f6c63db52013-02-02 00:35:225194}
5195
5196// Test load timing in the case of two HTTPS (non-SPDY) requests through a SPDY
5197// HTTPS Proxy to the same server.
bncd16676a2016-07-20 16:23:015198TEST_F(HttpNetworkTransactionTest,
[email protected]f6c63db52013-02-02 00:35:225199 HttpsProxySpdyConnectHttpsLoadTimingTwoRequestsSameServer) {
5200 // Configure against https proxy server "proxy:70".
rdsmith82957ad2015-09-16 19:42:035201 session_deps_.proxy_service = ProxyService::CreateFixed("https://proxy:70");
vishal.b62985ca92015-04-17 08:45:515202 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:075203 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:095204 std::unique_ptr<HttpNetworkSession> session(
mmenke11eb5152015-06-09 14:50:505205 SpdySessionDependencies::SpdyCreateSession(&session_deps_));
[email protected]f6c63db52013-02-02 00:35:225206
5207 HttpRequestInfo request1;
5208 request1.method = "GET";
bncce36dca22015-04-21 22:11:235209 request1.url = GURL("https://www.example.org/");
[email protected]f6c63db52013-02-02 00:35:225210 request1.load_flags = 0;
5211
5212 HttpRequestInfo request2;
5213 request2.method = "GET";
bncce36dca22015-04-21 22:11:235214 request2.url = GURL("https://www.example.org/2");
[email protected]f6c63db52013-02-02 00:35:225215 request2.load_flags = 0;
5216
bncce36dca22015-04-21 22:11:235217 // CONNECT to www.example.org:443 via SPDY.
bncdf80d44fd2016-07-15 20:27:415218 SpdySerializedFrame connect1(spdy_util_.ConstructSpdyConnect(
bncce36dca22015-04-21 22:11:235219 NULL, 0, 1, LOWEST, HostPortPair("www.example.org", 443)));
bnc42331402016-07-25 13:36:155220 SpdySerializedFrame conn_resp1(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
[email protected]f6c63db52013-02-02 00:35:225221
bncce36dca22015-04-21 22:11:235222 // Fetch https://www.example.org/ via HTTP.
5223 const char get1[] =
5224 "GET / HTTP/1.1\r\n"
5225 "Host: www.example.org\r\n"
[email protected]f6c63db52013-02-02 00:35:225226 "Connection: keep-alive\r\n\r\n";
bncdf80d44fd2016-07-15 20:27:415227 SpdySerializedFrame wrapped_get1(
5228 spdy_util_.ConstructSpdyDataFrame(1, get1, strlen(get1), false));
[email protected]f6c63db52013-02-02 00:35:225229 const char resp1[] = "HTTP/1.1 200 OK\r\n"
5230 "Content-Length: 1\r\n\r\n";
bncdf80d44fd2016-07-15 20:27:415231 SpdySerializedFrame wrapped_get_resp1(
5232 spdy_util_.ConstructSpdyDataFrame(1, resp1, strlen(resp1), false));
5233 SpdySerializedFrame wrapped_body1(
5234 spdy_util_.ConstructSpdyDataFrame(1, "1", 1, false));
5235 SpdySerializedFrame window_update(
5236 spdy_util_.ConstructSpdyWindowUpdate(1, wrapped_get_resp1.size()));
[email protected]f6c63db52013-02-02 00:35:225237
bncce36dca22015-04-21 22:11:235238 // Fetch https://www.example.org/2 via HTTP.
5239 const char get2[] =
5240 "GET /2 HTTP/1.1\r\n"
5241 "Host: www.example.org\r\n"
[email protected]f6c63db52013-02-02 00:35:225242 "Connection: keep-alive\r\n\r\n";
bncdf80d44fd2016-07-15 20:27:415243 SpdySerializedFrame wrapped_get2(
5244 spdy_util_.ConstructSpdyDataFrame(1, get2, strlen(get2), false));
[email protected]f6c63db52013-02-02 00:35:225245 const char resp2[] = "HTTP/1.1 200 OK\r\n"
5246 "Content-Length: 2\r\n\r\n";
bncdf80d44fd2016-07-15 20:27:415247 SpdySerializedFrame wrapped_get_resp2(
5248 spdy_util_.ConstructSpdyDataFrame(1, resp2, strlen(resp2), false));
5249 SpdySerializedFrame wrapped_body2(
5250 spdy_util_.ConstructSpdyDataFrame(1, "22", 2, false));
[email protected]f6c63db52013-02-02 00:35:225251
5252 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:415253 CreateMockWrite(connect1, 0), CreateMockWrite(wrapped_get1, 2),
5254 CreateMockWrite(wrapped_get2, 5),
[email protected]f6c63db52013-02-02 00:35:225255 };
5256
5257 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:415258 CreateMockRead(conn_resp1, 1, ASYNC),
5259 CreateMockRead(wrapped_get_resp1, 3, ASYNC),
bnceb9aa7112017-01-05 01:03:465260 CreateMockRead(wrapped_body1, 4, SYNCHRONOUS),
bncdf80d44fd2016-07-15 20:27:415261 CreateMockRead(wrapped_get_resp2, 6, ASYNC),
bnceb9aa7112017-01-05 01:03:465262 CreateMockRead(wrapped_body2, 7, SYNCHRONOUS),
bncdf80d44fd2016-07-15 20:27:415263 MockRead(ASYNC, 0, 8),
[email protected]f6c63db52013-02-02 00:35:225264 };
5265
mmenke11eb5152015-06-09 14:50:505266 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
5267 arraysize(spdy_writes));
5268 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]f6c63db52013-02-02 00:35:225269
5270 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:365271 ssl.next_proto = kProtoHTTP2;
mmenke11eb5152015-06-09 14:50:505272 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]f6c63db52013-02-02 00:35:225273 SSLSocketDataProvider ssl2(ASYNC, OK);
mmenke11eb5152015-06-09 14:50:505274 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
[email protected]f6c63db52013-02-02 00:35:225275
5276 TestCompletionCallback callback;
5277
bnc691fda62016-08-12 00:43:165278 std::unique_ptr<HttpNetworkTransaction> trans(
[email protected]90499482013-06-01 00:39:505279 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
tfarina42834112016-09-22 13:38:205280 int rv = trans->Start(&request1, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:015281 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]f6c63db52013-02-02 00:35:225282
5283 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:015284 EXPECT_THAT(rv, IsOk());
[email protected]f6c63db52013-02-02 00:35:225285
5286 LoadTimingInfo load_timing_info;
5287 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
5288 TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_SSL_TIMES);
5289
5290 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:525291 ASSERT_TRUE(response);
5292 ASSERT_TRUE(response->headers);
[email protected]f6c63db52013-02-02 00:35:225293 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
5294
5295 std::string response_data;
ttuttle859dc7a2015-04-23 19:42:295296 scoped_refptr<IOBuffer> buf(new IOBuffer(256));
[email protected]90499482013-06-01 00:39:505297 EXPECT_EQ(1, trans->Read(buf.get(), 256, callback.callback()));
[email protected]f6c63db52013-02-02 00:35:225298 trans.reset();
5299
bnc691fda62016-08-12 00:43:165300 std::unique_ptr<HttpNetworkTransaction> trans2(
[email protected]90499482013-06-01 00:39:505301 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
tfarina42834112016-09-22 13:38:205302 rv = trans2->Start(&request2, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:015303 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]f6c63db52013-02-02 00:35:225304
[email protected]f6c63db52013-02-02 00:35:225305 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:015306 EXPECT_THAT(rv, IsOk());
[email protected]f6c63db52013-02-02 00:35:225307
5308 LoadTimingInfo load_timing_info2;
5309 EXPECT_TRUE(trans2->GetLoadTimingInfo(&load_timing_info2));
5310 TestLoadTimingReused(load_timing_info2);
5311
5312 // The requests should have the same ID.
5313 EXPECT_EQ(load_timing_info.socket_log_id, load_timing_info2.socket_log_id);
5314
[email protected]90499482013-06-01 00:39:505315 EXPECT_EQ(2, trans2->Read(buf.get(), 256, callback.callback()));
[email protected]f6c63db52013-02-02 00:35:225316}
5317
5318// Test load timing in the case of of two HTTP requests through a SPDY HTTPS
5319// Proxy to different servers.
bncd16676a2016-07-20 16:23:015320TEST_F(HttpNetworkTransactionTest, HttpsProxySpdyLoadTimingTwoHttpRequests) {
[email protected]f6c63db52013-02-02 00:35:225321 // Configure against https proxy server "proxy:70".
rdsmith82957ad2015-09-16 19:42:035322 session_deps_.proxy_service = ProxyService::CreateFixed("https://proxy:70");
vishal.b62985ca92015-04-17 08:45:515323 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:075324 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:095325 std::unique_ptr<HttpNetworkSession> session(
mmenke11eb5152015-06-09 14:50:505326 SpdySessionDependencies::SpdyCreateSession(&session_deps_));
[email protected]f6c63db52013-02-02 00:35:225327
5328 HttpRequestInfo request1;
5329 request1.method = "GET";
bncce36dca22015-04-21 22:11:235330 request1.url = GURL("http://www.example.org/");
[email protected]f6c63db52013-02-02 00:35:225331 request1.load_flags = 0;
5332
5333 HttpRequestInfo request2;
5334 request2.method = "GET";
bncce36dca22015-04-21 22:11:235335 request2.url = GURL("http://mail.example.org/");
[email protected]f6c63db52013-02-02 00:35:225336 request2.load_flags = 0;
5337
bncce36dca22015-04-21 22:11:235338 // http://www.example.org/
bnc086b39e12016-06-24 13:05:265339 SpdyHeaderBlock headers(
bncce36dca22015-04-21 22:11:235340 spdy_util_.ConstructGetHeaderBlockForProxy("http://www.example.org/"));
bncdf80d44fd2016-07-15 20:27:415341 SpdySerializedFrame get1(
bnc42331402016-07-25 13:36:155342 spdy_util_.ConstructSpdyHeaders(1, std::move(headers), LOWEST, true));
5343 SpdySerializedFrame get_resp1(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
bncdf80d44fd2016-07-15 20:27:415344 SpdySerializedFrame body1(spdy_util_.ConstructSpdyDataFrame(1, "1", 1, true));
rdsmithebb50aa2015-11-12 03:44:385345 spdy_util_.UpdateWithStreamDestruction(1);
[email protected]f6c63db52013-02-02 00:35:225346
bncce36dca22015-04-21 22:11:235347 // http://mail.example.org/
bnc086b39e12016-06-24 13:05:265348 SpdyHeaderBlock headers2(
bncce36dca22015-04-21 22:11:235349 spdy_util_.ConstructGetHeaderBlockForProxy("http://mail.example.org/"));
bncdf80d44fd2016-07-15 20:27:415350 SpdySerializedFrame get2(
bnc42331402016-07-25 13:36:155351 spdy_util_.ConstructSpdyHeaders(3, std::move(headers2), LOWEST, true));
5352 SpdySerializedFrame get_resp2(spdy_util_.ConstructSpdyGetReply(NULL, 0, 3));
bncdf80d44fd2016-07-15 20:27:415353 SpdySerializedFrame body2(
5354 spdy_util_.ConstructSpdyDataFrame(3, "22", 2, true));
[email protected]f6c63db52013-02-02 00:35:225355
5356 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:415357 CreateMockWrite(get1, 0), CreateMockWrite(get2, 3),
[email protected]f6c63db52013-02-02 00:35:225358 };
5359
5360 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:415361 CreateMockRead(get_resp1, 1, ASYNC),
5362 CreateMockRead(body1, 2, ASYNC),
5363 CreateMockRead(get_resp2, 4, ASYNC),
5364 CreateMockRead(body2, 5, ASYNC),
5365 MockRead(ASYNC, 0, 6),
[email protected]f6c63db52013-02-02 00:35:225366 };
5367
mmenke11eb5152015-06-09 14:50:505368 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
5369 arraysize(spdy_writes));
5370 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]f6c63db52013-02-02 00:35:225371
5372 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:365373 ssl.next_proto = kProtoHTTP2;
mmenke11eb5152015-06-09 14:50:505374 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]f6c63db52013-02-02 00:35:225375
5376 TestCompletionCallback callback;
5377
bnc691fda62016-08-12 00:43:165378 std::unique_ptr<HttpNetworkTransaction> trans(
[email protected]90499482013-06-01 00:39:505379 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
tfarina42834112016-09-22 13:38:205380 int rv = trans->Start(&request1, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:015381 EXPECT_THAT(callback.GetResult(rv), IsOk());
[email protected]f6c63db52013-02-02 00:35:225382
5383 LoadTimingInfo load_timing_info;
5384 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
5385 TestLoadTimingNotReused(load_timing_info,
5386 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
5387
5388 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:525389 ASSERT_TRUE(response);
5390 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:025391 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]f6c63db52013-02-02 00:35:225392
5393 std::string response_data;
ttuttle859dc7a2015-04-23 19:42:295394 scoped_refptr<IOBuffer> buf(new IOBuffer(256));
mmenke11eb5152015-06-09 14:50:505395 rv = trans->Read(buf.get(), 256, callback.callback());
5396 EXPECT_EQ(1, callback.GetResult(rv));
[email protected]f6c63db52013-02-02 00:35:225397 // Delete the first request, so the second one can reuse the socket.
5398 trans.reset();
5399
bnc691fda62016-08-12 00:43:165400 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:205401 rv = trans2.Start(&request2, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:015402 EXPECT_THAT(callback.GetResult(rv), IsOk());
[email protected]f6c63db52013-02-02 00:35:225403
5404 LoadTimingInfo load_timing_info2;
bnc691fda62016-08-12 00:43:165405 EXPECT_TRUE(trans2.GetLoadTimingInfo(&load_timing_info2));
[email protected]f6c63db52013-02-02 00:35:225406 TestLoadTimingReused(load_timing_info2);
5407
5408 // The requests should have the same ID.
5409 EXPECT_EQ(load_timing_info.socket_log_id, load_timing_info2.socket_log_id);
5410
bnc691fda62016-08-12 00:43:165411 rv = trans2.Read(buf.get(), 256, callback.callback());
mmenke11eb5152015-06-09 14:50:505412 EXPECT_EQ(2, callback.GetResult(rv));
[email protected]f6c63db52013-02-02 00:35:225413}
5414
[email protected]2df19bb2010-08-25 20:13:465415// Test the challenge-response-retry sequence through an HTTPS Proxy
bncd16676a2016-07-20 16:23:015416TEST_F(HttpNetworkTransactionTest, HttpsProxyAuthRetry) {
[email protected]2df19bb2010-08-25 20:13:465417 HttpRequestInfo request;
5418 request.method = "GET";
bncce36dca22015-04-21 22:11:235419 request.url = GURL("http://www.example.org/");
[email protected]2df19bb2010-08-25 20:13:465420 // when the no authentication data flag is set.
ttuttle859dc7a2015-04-23 19:42:295421 request.load_flags = LOAD_DO_NOT_SEND_AUTH_DATA;
[email protected]2df19bb2010-08-25 20:13:465422
[email protected]79cb5c12011-09-12 13:12:045423 // Configure against https proxy server "myproxy:70".
rdsmith82957ad2015-09-16 19:42:035424 session_deps_.proxy_service = ProxyService::CreateFixed("https://myproxy:70");
vishal.b62985ca92015-04-17 08:45:515425 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:075426 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:095427 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:275428
[email protected]2df19bb2010-08-25 20:13:465429 // Since we have proxy, should use full url
5430 MockWrite data_writes1[] = {
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\r\n"),
[email protected]2df19bb2010-08-25 20:13:465434
bnc691fda62016-08-12 00:43:165435 // After calling trans.RestartWithAuth(), this is the request we should
bncce36dca22015-04-21 22:11:235436 // be issuing -- the final header line contains the credentials.
bnc691fda62016-08-12 00:43:165437 MockWrite("GET http://www.example.org/ HTTP/1.1\r\n"
5438 "Host: www.example.org\r\n"
5439 "Proxy-Connection: keep-alive\r\n"
5440 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]2df19bb2010-08-25 20:13:465441 };
5442
5443 // The proxy responds to the GET with a 407, using a persistent
5444 // connection.
5445 MockRead data_reads1[] = {
5446 // No credentials.
5447 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
5448 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
5449 MockRead("Proxy-Connection: keep-alive\r\n"),
5450 MockRead("Content-Length: 0\r\n\r\n"),
5451
5452 MockRead("HTTP/1.1 200 OK\r\n"),
5453 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
5454 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:065455 MockRead(SYNCHRONOUS, OK),
[email protected]2df19bb2010-08-25 20:13:465456 };
5457
5458 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
5459 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:075460 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8ddf8322012-02-23 18:08:065461 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:075462 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]2df19bb2010-08-25 20:13:465463
[email protected]49639fa2011-12-20 23:22:415464 TestCompletionCallback callback1;
[email protected]2df19bb2010-08-25 20:13:465465
bnc691fda62016-08-12 00:43:165466 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]0b0bf032010-09-21 18:08:505467
bnc691fda62016-08-12 00:43:165468 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:015469 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2df19bb2010-08-25 20:13:465470
5471 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:015472 EXPECT_THAT(rv, IsOk());
[email protected]2df19bb2010-08-25 20:13:465473
[email protected]58e32bb2013-01-21 18:23:255474 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:165475 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]58e32bb2013-01-21 18:23:255476 TestLoadTimingNotReused(load_timing_info,
5477 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
5478
bnc691fda62016-08-12 00:43:165479 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:525480 ASSERT_TRUE(response);
5481 ASSERT_TRUE(response->headers);
[email protected]2df19bb2010-08-25 20:13:465482 EXPECT_EQ(407, response->headers->response_code());
5483 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
asanka098c0092016-06-16 20:18:435484 EXPECT_TRUE(CheckBasicSecureProxyAuth(response->auth_challenge.get()));
[email protected]2df19bb2010-08-25 20:13:465485
[email protected]49639fa2011-12-20 23:22:415486 TestCompletionCallback callback2;
[email protected]2df19bb2010-08-25 20:13:465487
bnc691fda62016-08-12 00:43:165488 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar), callback2.callback());
robpercival214763f2016-07-01 23:27:015489 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2df19bb2010-08-25 20:13:465490
5491 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:015492 EXPECT_THAT(rv, IsOk());
[email protected]2df19bb2010-08-25 20:13:465493
[email protected]58e32bb2013-01-21 18:23:255494 load_timing_info = LoadTimingInfo();
bnc691fda62016-08-12 00:43:165495 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]58e32bb2013-01-21 18:23:255496 // Retrying with HTTP AUTH is considered to be reusing a socket.
5497 TestLoadTimingReused(load_timing_info);
5498
bnc691fda62016-08-12 00:43:165499 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:525500 ASSERT_TRUE(response);
[email protected]2df19bb2010-08-25 20:13:465501
5502 EXPECT_TRUE(response->headers->IsKeepAlive());
5503 EXPECT_EQ(200, response->headers->response_code());
5504 EXPECT_EQ(100, response->headers->GetContentLength());
5505 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
5506
5507 // The password prompt info should not be set.
wezca1070932016-05-26 20:30:525508 EXPECT_FALSE(response->auth_challenge);
[email protected]2df19bb2010-08-25 20:13:465509}
5510
[email protected]23e482282013-06-14 16:08:025511void HttpNetworkTransactionTest::ConnectStatusHelperWithExpectedStatus(
[email protected]c744cf22009-02-27 07:28:085512 const MockRead& status, int expected_status) {
[email protected]1c773ea12009-04-28 19:58:425513 HttpRequestInfo request;
[email protected]c744cf22009-02-27 07:28:085514 request.method = "GET";
bncce36dca22015-04-21 22:11:235515 request.url = GURL("https://www.example.org/");
[email protected]c744cf22009-02-27 07:28:085516
[email protected]cb9bf6ca2011-01-28 13:15:275517 // Configure against proxy server "myproxy:70".
rdsmith82957ad2015-09-16 19:42:035518 session_deps_.proxy_service = ProxyService::CreateFixed("myproxy:70");
danakj1fd259a02016-04-16 03:17:095519 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:275520
[email protected]c744cf22009-02-27 07:28:085521 // Since we have proxy, should try to establish tunnel.
5522 MockWrite data_writes[] = {
rsleevidb16bb02015-11-12 23:47:175523 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
5524 "Host: www.example.org:443\r\n"
5525 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]c744cf22009-02-27 07:28:085526 };
5527
5528 MockRead data_reads[] = {
mmenked39192ee2015-12-09 00:57:235529 status, MockRead("Content-Length: 10\r\n\r\n"),
5530 // No response body because the test stops reading here.
5531 MockRead(SYNCHRONOUS, ERR_UNEXPECTED),
[email protected]c744cf22009-02-27 07:28:085532 };
5533
[email protected]31a2bfe2010-02-09 08:03:395534 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
5535 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:075536 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]c744cf22009-02-27 07:28:085537
[email protected]49639fa2011-12-20 23:22:415538 TestCompletionCallback callback;
[email protected]c744cf22009-02-27 07:28:085539
bnc691fda62016-08-12 00:43:165540 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]0b0bf032010-09-21 18:08:505541
tfarina42834112016-09-22 13:38:205542 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:015543 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]c744cf22009-02-27 07:28:085544
5545 rv = callback.WaitForResult();
5546 EXPECT_EQ(expected_status, rv);
5547}
5548
[email protected]23e482282013-06-14 16:08:025549void HttpNetworkTransactionTest::ConnectStatusHelper(
[email protected]448d4ca52012-03-04 04:12:235550 const MockRead& status) {
[email protected]c744cf22009-02-27 07:28:085551 ConnectStatusHelperWithExpectedStatus(
[email protected]1c773ea12009-04-28 19:58:425552 status, ERR_TUNNEL_CONNECTION_FAILED);
[email protected]c744cf22009-02-27 07:28:085553}
5554
bncd16676a2016-07-20 16:23:015555TEST_F(HttpNetworkTransactionTest, ConnectStatus100) {
[email protected]c744cf22009-02-27 07:28:085556 ConnectStatusHelper(MockRead("HTTP/1.1 100 Continue\r\n"));
5557}
5558
bncd16676a2016-07-20 16:23:015559TEST_F(HttpNetworkTransactionTest, ConnectStatus101) {
[email protected]c744cf22009-02-27 07:28:085560 ConnectStatusHelper(MockRead("HTTP/1.1 101 Switching Protocols\r\n"));
5561}
5562
bncd16676a2016-07-20 16:23:015563TEST_F(HttpNetworkTransactionTest, ConnectStatus201) {
[email protected]c744cf22009-02-27 07:28:085564 ConnectStatusHelper(MockRead("HTTP/1.1 201 Created\r\n"));
5565}
5566
bncd16676a2016-07-20 16:23:015567TEST_F(HttpNetworkTransactionTest, ConnectStatus202) {
[email protected]c744cf22009-02-27 07:28:085568 ConnectStatusHelper(MockRead("HTTP/1.1 202 Accepted\r\n"));
5569}
5570
bncd16676a2016-07-20 16:23:015571TEST_F(HttpNetworkTransactionTest, ConnectStatus203) {
[email protected]c744cf22009-02-27 07:28:085572 ConnectStatusHelper(
5573 MockRead("HTTP/1.1 203 Non-Authoritative Information\r\n"));
5574}
5575
bncd16676a2016-07-20 16:23:015576TEST_F(HttpNetworkTransactionTest, ConnectStatus204) {
[email protected]c744cf22009-02-27 07:28:085577 ConnectStatusHelper(MockRead("HTTP/1.1 204 No Content\r\n"));
5578}
5579
bncd16676a2016-07-20 16:23:015580TEST_F(HttpNetworkTransactionTest, ConnectStatus205) {
[email protected]c744cf22009-02-27 07:28:085581 ConnectStatusHelper(MockRead("HTTP/1.1 205 Reset Content\r\n"));
5582}
5583
bncd16676a2016-07-20 16:23:015584TEST_F(HttpNetworkTransactionTest, ConnectStatus206) {
[email protected]c744cf22009-02-27 07:28:085585 ConnectStatusHelper(MockRead("HTTP/1.1 206 Partial Content\r\n"));
5586}
5587
bncd16676a2016-07-20 16:23:015588TEST_F(HttpNetworkTransactionTest, ConnectStatus300) {
[email protected]c744cf22009-02-27 07:28:085589 ConnectStatusHelper(MockRead("HTTP/1.1 300 Multiple Choices\r\n"));
5590}
5591
bncd16676a2016-07-20 16:23:015592TEST_F(HttpNetworkTransactionTest, ConnectStatus301) {
[email protected]c744cf22009-02-27 07:28:085593 ConnectStatusHelper(MockRead("HTTP/1.1 301 Moved Permanently\r\n"));
5594}
5595
bncd16676a2016-07-20 16:23:015596TEST_F(HttpNetworkTransactionTest, ConnectStatus302) {
[email protected]c744cf22009-02-27 07:28:085597 ConnectStatusHelper(MockRead("HTTP/1.1 302 Found\r\n"));
5598}
5599
bncd16676a2016-07-20 16:23:015600TEST_F(HttpNetworkTransactionTest, ConnectStatus303) {
[email protected]c744cf22009-02-27 07:28:085601 ConnectStatusHelper(MockRead("HTTP/1.1 303 See Other\r\n"));
5602}
5603
bncd16676a2016-07-20 16:23:015604TEST_F(HttpNetworkTransactionTest, ConnectStatus304) {
[email protected]c744cf22009-02-27 07:28:085605 ConnectStatusHelper(MockRead("HTTP/1.1 304 Not Modified\r\n"));
5606}
5607
bncd16676a2016-07-20 16:23:015608TEST_F(HttpNetworkTransactionTest, ConnectStatus305) {
[email protected]c744cf22009-02-27 07:28:085609 ConnectStatusHelper(MockRead("HTTP/1.1 305 Use Proxy\r\n"));
5610}
5611
bncd16676a2016-07-20 16:23:015612TEST_F(HttpNetworkTransactionTest, ConnectStatus306) {
[email protected]c744cf22009-02-27 07:28:085613 ConnectStatusHelper(MockRead("HTTP/1.1 306\r\n"));
5614}
5615
bncd16676a2016-07-20 16:23:015616TEST_F(HttpNetworkTransactionTest, ConnectStatus307) {
[email protected]c744cf22009-02-27 07:28:085617 ConnectStatusHelper(MockRead("HTTP/1.1 307 Temporary Redirect\r\n"));
5618}
5619
bncd16676a2016-07-20 16:23:015620TEST_F(HttpNetworkTransactionTest, ConnectStatus308) {
[email protected]0a17aab32014-04-24 03:32:375621 ConnectStatusHelper(MockRead("HTTP/1.1 308 Permanent Redirect\r\n"));
5622}
5623
bncd16676a2016-07-20 16:23:015624TEST_F(HttpNetworkTransactionTest, ConnectStatus400) {
[email protected]c744cf22009-02-27 07:28:085625 ConnectStatusHelper(MockRead("HTTP/1.1 400 Bad Request\r\n"));
5626}
5627
bncd16676a2016-07-20 16:23:015628TEST_F(HttpNetworkTransactionTest, ConnectStatus401) {
[email protected]c744cf22009-02-27 07:28:085629 ConnectStatusHelper(MockRead("HTTP/1.1 401 Unauthorized\r\n"));
5630}
5631
bncd16676a2016-07-20 16:23:015632TEST_F(HttpNetworkTransactionTest, ConnectStatus402) {
[email protected]c744cf22009-02-27 07:28:085633 ConnectStatusHelper(MockRead("HTTP/1.1 402 Payment Required\r\n"));
5634}
5635
bncd16676a2016-07-20 16:23:015636TEST_F(HttpNetworkTransactionTest, ConnectStatus403) {
[email protected]c744cf22009-02-27 07:28:085637 ConnectStatusHelper(MockRead("HTTP/1.1 403 Forbidden\r\n"));
5638}
5639
bncd16676a2016-07-20 16:23:015640TEST_F(HttpNetworkTransactionTest, ConnectStatus404) {
[email protected]c744cf22009-02-27 07:28:085641 ConnectStatusHelper(MockRead("HTTP/1.1 404 Not Found\r\n"));
5642}
5643
bncd16676a2016-07-20 16:23:015644TEST_F(HttpNetworkTransactionTest, ConnectStatus405) {
[email protected]c744cf22009-02-27 07:28:085645 ConnectStatusHelper(MockRead("HTTP/1.1 405 Method Not Allowed\r\n"));
5646}
5647
bncd16676a2016-07-20 16:23:015648TEST_F(HttpNetworkTransactionTest, ConnectStatus406) {
[email protected]c744cf22009-02-27 07:28:085649 ConnectStatusHelper(MockRead("HTTP/1.1 406 Not Acceptable\r\n"));
5650}
5651
bncd16676a2016-07-20 16:23:015652TEST_F(HttpNetworkTransactionTest, ConnectStatus407) {
[email protected]c744cf22009-02-27 07:28:085653 ConnectStatusHelperWithExpectedStatus(
5654 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
[email protected]a7ea8832010-07-12 17:54:545655 ERR_PROXY_AUTH_UNSUPPORTED);
[email protected]c744cf22009-02-27 07:28:085656}
5657
bncd16676a2016-07-20 16:23:015658TEST_F(HttpNetworkTransactionTest, ConnectStatus408) {
[email protected]c744cf22009-02-27 07:28:085659 ConnectStatusHelper(MockRead("HTTP/1.1 408 Request Timeout\r\n"));
5660}
5661
bncd16676a2016-07-20 16:23:015662TEST_F(HttpNetworkTransactionTest, ConnectStatus409) {
[email protected]c744cf22009-02-27 07:28:085663 ConnectStatusHelper(MockRead("HTTP/1.1 409 Conflict\r\n"));
5664}
5665
bncd16676a2016-07-20 16:23:015666TEST_F(HttpNetworkTransactionTest, ConnectStatus410) {
[email protected]c744cf22009-02-27 07:28:085667 ConnectStatusHelper(MockRead("HTTP/1.1 410 Gone\r\n"));
5668}
5669
bncd16676a2016-07-20 16:23:015670TEST_F(HttpNetworkTransactionTest, ConnectStatus411) {
[email protected]c744cf22009-02-27 07:28:085671 ConnectStatusHelper(MockRead("HTTP/1.1 411 Length Required\r\n"));
5672}
5673
bncd16676a2016-07-20 16:23:015674TEST_F(HttpNetworkTransactionTest, ConnectStatus412) {
[email protected]c744cf22009-02-27 07:28:085675 ConnectStatusHelper(MockRead("HTTP/1.1 412 Precondition Failed\r\n"));
5676}
5677
bncd16676a2016-07-20 16:23:015678TEST_F(HttpNetworkTransactionTest, ConnectStatus413) {
[email protected]c744cf22009-02-27 07:28:085679 ConnectStatusHelper(MockRead("HTTP/1.1 413 Request Entity Too Large\r\n"));
5680}
5681
bncd16676a2016-07-20 16:23:015682TEST_F(HttpNetworkTransactionTest, ConnectStatus414) {
[email protected]c744cf22009-02-27 07:28:085683 ConnectStatusHelper(MockRead("HTTP/1.1 414 Request-URI Too Long\r\n"));
5684}
5685
bncd16676a2016-07-20 16:23:015686TEST_F(HttpNetworkTransactionTest, ConnectStatus415) {
[email protected]c744cf22009-02-27 07:28:085687 ConnectStatusHelper(MockRead("HTTP/1.1 415 Unsupported Media Type\r\n"));
5688}
5689
bncd16676a2016-07-20 16:23:015690TEST_F(HttpNetworkTransactionTest, ConnectStatus416) {
[email protected]c744cf22009-02-27 07:28:085691 ConnectStatusHelper(
5692 MockRead("HTTP/1.1 416 Requested Range Not Satisfiable\r\n"));
5693}
5694
bncd16676a2016-07-20 16:23:015695TEST_F(HttpNetworkTransactionTest, ConnectStatus417) {
[email protected]c744cf22009-02-27 07:28:085696 ConnectStatusHelper(MockRead("HTTP/1.1 417 Expectation Failed\r\n"));
5697}
5698
bncd16676a2016-07-20 16:23:015699TEST_F(HttpNetworkTransactionTest, ConnectStatus500) {
[email protected]c744cf22009-02-27 07:28:085700 ConnectStatusHelper(MockRead("HTTP/1.1 500 Internal Server Error\r\n"));
5701}
5702
bncd16676a2016-07-20 16:23:015703TEST_F(HttpNetworkTransactionTest, ConnectStatus501) {
[email protected]c744cf22009-02-27 07:28:085704 ConnectStatusHelper(MockRead("HTTP/1.1 501 Not Implemented\r\n"));
5705}
5706
bncd16676a2016-07-20 16:23:015707TEST_F(HttpNetworkTransactionTest, ConnectStatus502) {
[email protected]c744cf22009-02-27 07:28:085708 ConnectStatusHelper(MockRead("HTTP/1.1 502 Bad Gateway\r\n"));
5709}
5710
bncd16676a2016-07-20 16:23:015711TEST_F(HttpNetworkTransactionTest, ConnectStatus503) {
[email protected]c744cf22009-02-27 07:28:085712 ConnectStatusHelper(MockRead("HTTP/1.1 503 Service Unavailable\r\n"));
5713}
5714
bncd16676a2016-07-20 16:23:015715TEST_F(HttpNetworkTransactionTest, ConnectStatus504) {
[email protected]c744cf22009-02-27 07:28:085716 ConnectStatusHelper(MockRead("HTTP/1.1 504 Gateway Timeout\r\n"));
5717}
5718
bncd16676a2016-07-20 16:23:015719TEST_F(HttpNetworkTransactionTest, ConnectStatus505) {
[email protected]c744cf22009-02-27 07:28:085720 ConnectStatusHelper(MockRead("HTTP/1.1 505 HTTP Version Not Supported\r\n"));
5721}
5722
[email protected]038e9a32008-10-08 22:40:165723// Test the flow when both the proxy server AND origin server require
5724// authentication. Again, this uses basic auth for both since that is
5725// the simplest to mock.
bncd16676a2016-07-20 16:23:015726TEST_F(HttpNetworkTransactionTest, BasicAuthProxyThenServer) {
[email protected]cb9bf6ca2011-01-28 13:15:275727 HttpRequestInfo request;
5728 request.method = "GET";
bncce36dca22015-04-21 22:11:235729 request.url = GURL("http://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:275730
[email protected]038e9a32008-10-08 22:40:165731 // Configure against proxy server "myproxy:70".
rdsmith82957ad2015-09-16 19:42:035732 session_deps_.proxy_service = ProxyService::CreateFixed("myproxy:70");
danakj1fd259a02016-04-16 03:17:095733 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]3fe8d2f82013-10-17 08:56:075734
bnc691fda62016-08-12 00:43:165735 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]038e9a32008-10-08 22:40:165736
[email protected]f9ee6b52008-11-08 06:46:235737 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:235738 MockWrite(
5739 "GET http://www.example.org/ HTTP/1.1\r\n"
5740 "Host: www.example.org\r\n"
5741 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:235742 };
5743
[email protected]038e9a32008-10-08 22:40:165744 MockRead data_reads1[] = {
5745 MockRead("HTTP/1.0 407 Unauthorized\r\n"),
5746 // Give a couple authenticate options (only the middle one is actually
5747 // supported).
[email protected]22927ad2009-09-21 19:56:195748 MockRead("Proxy-Authenticate: Basic invalid\r\n"), // Malformed.
[email protected]038e9a32008-10-08 22:40:165749 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
5750 MockRead("Proxy-Authenticate: UNSUPPORTED realm=\"FOO\"\r\n"),
5751 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
5752 // Large content-length -- won't matter, as connection will be reset.
5753 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:065754 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]038e9a32008-10-08 22:40:165755 };
5756
bnc691fda62016-08-12 00:43:165757 // After calling trans.RestartWithAuth() the first time, this is the
[email protected]038e9a32008-10-08 22:40:165758 // request we should be issuing -- the final header line contains the
5759 // proxy's credentials.
5760 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:235761 MockWrite(
5762 "GET http://www.example.org/ HTTP/1.1\r\n"
5763 "Host: www.example.org\r\n"
5764 "Proxy-Connection: keep-alive\r\n"
5765 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]038e9a32008-10-08 22:40:165766 };
5767
5768 // Now the proxy server lets the request pass through to origin server.
5769 // The origin server responds with a 401.
5770 MockRead data_reads2[] = {
5771 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
5772 // Note: We are using the same realm-name as the proxy server. This is
5773 // completely valid, as realms are unique across hosts.
5774 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
5775 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
5776 MockRead("Content-Length: 2000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:065777 MockRead(SYNCHRONOUS, ERR_FAILED), // Won't be reached.
[email protected]038e9a32008-10-08 22:40:165778 };
5779
bnc691fda62016-08-12 00:43:165780 // After calling trans.RestartWithAuth() the second time, we should send
[email protected]038e9a32008-10-08 22:40:165781 // the credentials for both the proxy and origin server.
5782 MockWrite data_writes3[] = {
bncce36dca22015-04-21 22:11:235783 MockWrite(
5784 "GET http://www.example.org/ HTTP/1.1\r\n"
5785 "Host: www.example.org\r\n"
5786 "Proxy-Connection: keep-alive\r\n"
5787 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n"
5788 "Authorization: Basic Zm9vMjpiYXIy\r\n\r\n"),
[email protected]038e9a32008-10-08 22:40:165789 };
5790
5791 // Lastly we get the desired content.
5792 MockRead data_reads3[] = {
5793 MockRead("HTTP/1.0 200 OK\r\n"),
5794 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
5795 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:065796 MockRead(SYNCHRONOUS, OK),
[email protected]038e9a32008-10-08 22:40:165797 };
5798
[email protected]31a2bfe2010-02-09 08:03:395799 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
5800 data_writes1, arraysize(data_writes1));
5801 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
5802 data_writes2, arraysize(data_writes2));
5803 StaticSocketDataProvider data3(data_reads3, arraysize(data_reads3),
5804 data_writes3, arraysize(data_writes3));
[email protected]bb88e1d32013-05-03 23:11:075805 session_deps_.socket_factory->AddSocketDataProvider(&data1);
5806 session_deps_.socket_factory->AddSocketDataProvider(&data2);
5807 session_deps_.socket_factory->AddSocketDataProvider(&data3);
[email protected]038e9a32008-10-08 22:40:165808
[email protected]49639fa2011-12-20 23:22:415809 TestCompletionCallback callback1;
[email protected]038e9a32008-10-08 22:40:165810
tfarina42834112016-09-22 13:38:205811 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:015812 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]038e9a32008-10-08 22:40:165813
5814 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:015815 EXPECT_THAT(rv, IsOk());
[email protected]038e9a32008-10-08 22:40:165816
bnc691fda62016-08-12 00:43:165817 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:525818 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:045819 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
[email protected]038e9a32008-10-08 22:40:165820
[email protected]49639fa2011-12-20 23:22:415821 TestCompletionCallback callback2;
[email protected]038e9a32008-10-08 22:40:165822
bnc691fda62016-08-12 00:43:165823 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar), callback2.callback());
robpercival214763f2016-07-01 23:27:015824 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]038e9a32008-10-08 22:40:165825
5826 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:015827 EXPECT_THAT(rv, IsOk());
[email protected]038e9a32008-10-08 22:40:165828
bnc691fda62016-08-12 00:43:165829 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:525830 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:045831 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]038e9a32008-10-08 22:40:165832
[email protected]49639fa2011-12-20 23:22:415833 TestCompletionCallback callback3;
[email protected]038e9a32008-10-08 22:40:165834
bnc691fda62016-08-12 00:43:165835 rv = trans.RestartWithAuth(AuthCredentials(kFoo2, kBar2),
5836 callback3.callback());
robpercival214763f2016-07-01 23:27:015837 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]038e9a32008-10-08 22:40:165838
5839 rv = callback3.WaitForResult();
robpercival214763f2016-07-01 23:27:015840 EXPECT_THAT(rv, IsOk());
[email protected]038e9a32008-10-08 22:40:165841
bnc691fda62016-08-12 00:43:165842 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:525843 EXPECT_FALSE(response->auth_challenge);
[email protected]038e9a32008-10-08 22:40:165844 EXPECT_EQ(100, response->headers->GetContentLength());
[email protected]038e9a32008-10-08 22:40:165845}
[email protected]4ddaf2502008-10-23 18:26:195846
[email protected]ea9dc9a2009-09-05 00:43:325847// For the NTLM implementation using SSPI, we skip the NTLM tests since we
5848// can't hook into its internals to cause it to generate predictable NTLM
5849// authorization headers.
5850#if defined(NTLM_PORTABLE)
[email protected]385a4672009-03-11 22:21:295851// The NTLM authentication unit tests were generated by capturing the HTTP
5852// requests and responses using Fiddler 2 and inspecting the generated random
5853// bytes in the debugger.
5854
5855// Enter the correct password and authenticate successfully.
bncd16676a2016-07-20 16:23:015856TEST_F(HttpNetworkTransactionTest, NTLMAuth1) {
[email protected]1c773ea12009-04-28 19:58:425857 HttpRequestInfo request;
[email protected]3f918782009-02-28 01:29:245858 request.method = "GET";
5859 request.url = GURL("http://172.22.68.17/kids/login.aspx");
[email protected]2217aa22013-10-11 03:03:545860
5861 // Ensure load is not disrupted by flags which suppress behaviour specific
5862 // to other auth schemes.
5863 request.load_flags = LOAD_DO_NOT_USE_EMBEDDED_IDENTITY;
[email protected]3f918782009-02-28 01:29:245864
[email protected]cb9bf6ca2011-01-28 13:15:275865 HttpAuthHandlerNTLM::ScopedProcSetter proc_setter(MockGenerateRandom1,
5866 MockGetHostName);
danakj1fd259a02016-04-16 03:17:095867 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:275868
[email protected]3f918782009-02-28 01:29:245869 MockWrite data_writes1[] = {
5870 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
5871 "Host: 172.22.68.17\r\n"
5872 "Connection: keep-alive\r\n\r\n"),
5873 };
5874
5875 MockRead data_reads1[] = {
5876 MockRead("HTTP/1.1 401 Access Denied\r\n"),
[email protected]aef04272010-06-28 18:03:045877 // Negotiate and NTLM are often requested together. However, we only want
5878 // to test NTLM. Since Negotiate is preferred over NTLM, we have to skip
5879 // the header that requests Negotiate for this test.
[email protected]3f918782009-02-28 01:29:245880 MockRead("WWW-Authenticate: NTLM\r\n"),
5881 MockRead("Connection: close\r\n"),
5882 MockRead("Content-Length: 42\r\n"),
[email protected]076c85082009-04-10 23:21:365883 MockRead("Content-Type: text/html\r\n\r\n"),
[email protected]3f918782009-02-28 01:29:245884 // Missing content -- won't matter, as connection will be reset.
[email protected]8ddf8322012-02-23 18:08:065885 MockRead(SYNCHRONOUS, ERR_UNEXPECTED),
[email protected]3f918782009-02-28 01:29:245886 };
5887
5888 MockWrite data_writes2[] = {
bnc691fda62016-08-12 00:43:165889 // After restarting with a null identity, this is the
5890 // request we should be issuing -- the final header line contains a Type
5891 // 1 message.
5892 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
5893 "Host: 172.22.68.17\r\n"
5894 "Connection: keep-alive\r\n"
5895 "Authorization: NTLM "
5896 "TlRMTVNTUAABAAAAB4IIAAAAAAAAAAAAAAAAAAAAAAA=\r\n\r\n"),
[email protected]3f918782009-02-28 01:29:245897
bnc691fda62016-08-12 00:43:165898 // After calling trans.RestartWithAuth(), we should send a Type 3 message
5899 // (the credentials for the origin server). The second request continues
5900 // on the same connection.
5901 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
5902 "Host: 172.22.68.17\r\n"
5903 "Connection: keep-alive\r\n"
5904 "Authorization: NTLM TlRMTVNTUAADAAAAGAAYAGgAAAAYABgAgA"
5905 "AAAAAAAABAAAAAGAAYAEAAAAAQABAAWAAAAAAAAAAAAAAABYIIAHQA"
5906 "ZQBzAHQAaQBuAGcALQBuAHQAbABtAFcAVABDAC0AVwBJAE4ANwBVKW"
5907 "Yma5xzVAAAAAAAAAAAAAAAAAAAAACH+gWcm+YsP9Tqb9zCR3WAeZZX"
5908 "ahlhx5I=\r\n\r\n"),
[email protected]3f918782009-02-28 01:29:245909 };
5910
5911 MockRead data_reads2[] = {
5912 // The origin server responds with a Type 2 message.
5913 MockRead("HTTP/1.1 401 Access Denied\r\n"),
5914 MockRead("WWW-Authenticate: NTLM "
[email protected]385a4672009-03-11 22:21:295915 "TlRMTVNTUAACAAAADAAMADgAAAAFgokCjGpMpPGlYKkAAAAAAAAAALo"
[email protected]3f918782009-02-28 01:29:245916 "AugBEAAAABQEoCgAAAA9HAE8ATwBHAEwARQACAAwARwBPAE8ARwBMAE"
5917 "UAAQAaAEEASwBFAEUAUwBBAFIAQQAtAEMATwBSAFAABAAeAGMAbwByA"
5918 "HAALgBnAG8AbwBnAGwAZQAuAGMAbwBtAAMAQABhAGsAZQBlAHMAYQBy"
5919 "AGEALQBjAG8AcgBwAC4AYQBkAC4AYwBvAHIAcAAuAGcAbwBvAGcAbAB"
5920 "lAC4AYwBvAG0ABQAeAGMAbwByAHAALgBnAG8AbwBnAGwAZQAuAGMAbw"
5921 "BtAAAAAAA=\r\n"),
5922 MockRead("Content-Length: 42\r\n"),
[email protected]076c85082009-04-10 23:21:365923 MockRead("Content-Type: text/html\r\n\r\n"),
[email protected]3f918782009-02-28 01:29:245924 MockRead("You are not authorized to view this page\r\n"),
5925
5926 // Lastly we get the desired content.
5927 MockRead("HTTP/1.1 200 OK\r\n"),
5928 MockRead("Content-Type: text/html; charset=utf-8\r\n"),
5929 MockRead("Content-Length: 13\r\n\r\n"),
5930 MockRead("Please Login\r\n"),
[email protected]8ddf8322012-02-23 18:08:065931 MockRead(SYNCHRONOUS, OK),
[email protected]3f918782009-02-28 01:29:245932 };
5933
[email protected]31a2bfe2010-02-09 08:03:395934 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
5935 data_writes1, arraysize(data_writes1));
5936 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
5937 data_writes2, arraysize(data_writes2));
[email protected]bb88e1d32013-05-03 23:11:075938 session_deps_.socket_factory->AddSocketDataProvider(&data1);
5939 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]3f918782009-02-28 01:29:245940
[email protected]49639fa2011-12-20 23:22:415941 TestCompletionCallback callback1;
[email protected]3f918782009-02-28 01:29:245942
bnc691fda62016-08-12 00:43:165943 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]0b0bf032010-09-21 18:08:505944
tfarina42834112016-09-22 13:38:205945 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:015946 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]3f918782009-02-28 01:29:245947
5948 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:015949 EXPECT_THAT(rv, IsOk());
[email protected]3f918782009-02-28 01:29:245950
bnc691fda62016-08-12 00:43:165951 EXPECT_FALSE(trans.IsReadyToRestartForAuth());
[email protected]0757e7702009-03-27 04:00:225952
bnc691fda62016-08-12 00:43:165953 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:525954 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:045955 EXPECT_TRUE(CheckNTLMServerAuth(response->auth_challenge.get()));
[email protected]3f918782009-02-28 01:29:245956
[email protected]49639fa2011-12-20 23:22:415957 TestCompletionCallback callback2;
[email protected]10af5fe72011-01-31 16:17:255958
bnc691fda62016-08-12 00:43:165959 rv = trans.RestartWithAuth(AuthCredentials(kTestingNTLM, kTestingNTLM),
5960 callback2.callback());
robpercival214763f2016-07-01 23:27:015961 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]10af5fe72011-01-31 16:17:255962
5963 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:015964 EXPECT_THAT(rv, IsOk());
[email protected]10af5fe72011-01-31 16:17:255965
bnc691fda62016-08-12 00:43:165966 EXPECT_TRUE(trans.IsReadyToRestartForAuth());
[email protected]10af5fe72011-01-31 16:17:255967
bnc691fda62016-08-12 00:43:165968 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:525969 ASSERT_TRUE(response);
5970 EXPECT_FALSE(response->auth_challenge);
[email protected]10af5fe72011-01-31 16:17:255971
[email protected]49639fa2011-12-20 23:22:415972 TestCompletionCallback callback3;
[email protected]3f918782009-02-28 01:29:245973
bnc691fda62016-08-12 00:43:165974 rv = trans.RestartWithAuth(AuthCredentials(), callback3.callback());
robpercival214763f2016-07-01 23:27:015975 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]3f918782009-02-28 01:29:245976
[email protected]0757e7702009-03-27 04:00:225977 rv = callback3.WaitForResult();
robpercival214763f2016-07-01 23:27:015978 EXPECT_THAT(rv, IsOk());
[email protected]3f918782009-02-28 01:29:245979
bnc691fda62016-08-12 00:43:165980 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:525981 ASSERT_TRUE(response);
5982 EXPECT_FALSE(response->auth_challenge);
[email protected]3f918782009-02-28 01:29:245983 EXPECT_EQ(13, response->headers->GetContentLength());
5984}
5985
[email protected]385a4672009-03-11 22:21:295986// Enter a wrong password, and then the correct one.
bncd16676a2016-07-20 16:23:015987TEST_F(HttpNetworkTransactionTest, NTLMAuth2) {
[email protected]1c773ea12009-04-28 19:58:425988 HttpRequestInfo request;
[email protected]385a4672009-03-11 22:21:295989 request.method = "GET";
5990 request.url = GURL("http://172.22.68.17/kids/login.aspx");
[email protected]385a4672009-03-11 22:21:295991
[email protected]cb9bf6ca2011-01-28 13:15:275992 HttpAuthHandlerNTLM::ScopedProcSetter proc_setter(MockGenerateRandom2,
5993 MockGetHostName);
danakj1fd259a02016-04-16 03:17:095994 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:275995
[email protected]385a4672009-03-11 22:21:295996 MockWrite data_writes1[] = {
5997 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
5998 "Host: 172.22.68.17\r\n"
5999 "Connection: keep-alive\r\n\r\n"),
6000 };
6001
6002 MockRead data_reads1[] = {
6003 MockRead("HTTP/1.1 401 Access Denied\r\n"),
[email protected]aef04272010-06-28 18:03:046004 // Negotiate and NTLM are often requested together. However, we only want
6005 // to test NTLM. Since Negotiate is preferred over NTLM, we have to skip
6006 // the header that requests Negotiate for this test.
[email protected]385a4672009-03-11 22:21:296007 MockRead("WWW-Authenticate: NTLM\r\n"),
6008 MockRead("Connection: close\r\n"),
6009 MockRead("Content-Length: 42\r\n"),
[email protected]076c85082009-04-10 23:21:366010 MockRead("Content-Type: text/html\r\n\r\n"),
[email protected]385a4672009-03-11 22:21:296011 // Missing content -- won't matter, as connection will be reset.
[email protected]8ddf8322012-02-23 18:08:066012 MockRead(SYNCHRONOUS, ERR_UNEXPECTED),
[email protected]385a4672009-03-11 22:21:296013 };
6014
6015 MockWrite data_writes2[] = {
bnc691fda62016-08-12 00:43:166016 // After restarting with a null identity, this is the
6017 // request we should be issuing -- the final header line contains a Type
6018 // 1 message.
6019 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
6020 "Host: 172.22.68.17\r\n"
6021 "Connection: keep-alive\r\n"
6022 "Authorization: NTLM "
6023 "TlRMTVNTUAABAAAAB4IIAAAAAAAAAAAAAAAAAAAAAAA=\r\n\r\n"),
[email protected]385a4672009-03-11 22:21:296024
bnc691fda62016-08-12 00:43:166025 // After calling trans.RestartWithAuth(), we should send a Type 3 message
6026 // (the credentials for the origin server). The second request continues
6027 // on the same connection.
6028 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
6029 "Host: 172.22.68.17\r\n"
6030 "Connection: keep-alive\r\n"
6031 "Authorization: NTLM TlRMTVNTUAADAAAAGAAYAGgAAAAYABgAgA"
6032 "AAAAAAAABAAAAAGAAYAEAAAAAQABAAWAAAAAAAAAAAAAAABYIIAHQA"
6033 "ZQBzAHQAaQBuAGcALQBuAHQAbABtAFcAVABDAC0AVwBJAE4ANwCWeY"
6034 "XnSZNwoQAAAAAAAAAAAAAAAAAAAADLa34/phTTKzNTWdub+uyFleOj"
6035 "4Ww7b7E=\r\n\r\n"),
[email protected]385a4672009-03-11 22:21:296036 };
6037
6038 MockRead data_reads2[] = {
6039 // The origin server responds with a Type 2 message.
6040 MockRead("HTTP/1.1 401 Access Denied\r\n"),
6041 MockRead("WWW-Authenticate: NTLM "
6042 "TlRMTVNTUAACAAAADAAMADgAAAAFgokCbVWUZezVGpAAAAAAAAAAALo"
6043 "AugBEAAAABQEoCgAAAA9HAE8ATwBHAEwARQACAAwARwBPAE8ARwBMAE"
6044 "UAAQAaAEEASwBFAEUAUwBBAFIAQQAtAEMATwBSAFAABAAeAGMAbwByA"
6045 "HAALgBnAG8AbwBnAGwAZQAuAGMAbwBtAAMAQABhAGsAZQBlAHMAYQBy"
6046 "AGEALQBjAG8AcgBwAC4AYQBkAC4AYwBvAHIAcAAuAGcAbwBvAGcAbAB"
6047 "lAC4AYwBvAG0ABQAeAGMAbwByAHAALgBnAG8AbwBnAGwAZQAuAGMAbw"
6048 "BtAAAAAAA=\r\n"),
6049 MockRead("Content-Length: 42\r\n"),
[email protected]076c85082009-04-10 23:21:366050 MockRead("Content-Type: text/html\r\n\r\n"),
[email protected]385a4672009-03-11 22:21:296051 MockRead("You are not authorized to view this page\r\n"),
6052
6053 // Wrong password.
6054 MockRead("HTTP/1.1 401 Access Denied\r\n"),
[email protected]385a4672009-03-11 22:21:296055 MockRead("WWW-Authenticate: NTLM\r\n"),
6056 MockRead("Connection: close\r\n"),
6057 MockRead("Content-Length: 42\r\n"),
[email protected]076c85082009-04-10 23:21:366058 MockRead("Content-Type: text/html\r\n\r\n"),
[email protected]385a4672009-03-11 22:21:296059 // Missing content -- won't matter, as connection will be reset.
[email protected]8ddf8322012-02-23 18:08:066060 MockRead(SYNCHRONOUS, ERR_UNEXPECTED),
[email protected]385a4672009-03-11 22:21:296061 };
6062
6063 MockWrite data_writes3[] = {
bnc691fda62016-08-12 00:43:166064 // After restarting with a null identity, this is the
6065 // request we should be issuing -- the final header line contains a Type
6066 // 1 message.
6067 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
6068 "Host: 172.22.68.17\r\n"
6069 "Connection: keep-alive\r\n"
6070 "Authorization: NTLM "
6071 "TlRMTVNTUAABAAAAB4IIAAAAAAAAAAAAAAAAAAAAAAA=\r\n\r\n"),
[email protected]385a4672009-03-11 22:21:296072
bnc691fda62016-08-12 00:43:166073 // After calling trans.RestartWithAuth(), we should send a Type 3 message
6074 // (the credentials for the origin server). The second request continues
6075 // on the same connection.
6076 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
6077 "Host: 172.22.68.17\r\n"
6078 "Connection: keep-alive\r\n"
6079 "Authorization: NTLM TlRMTVNTUAADAAAAGAAYAGgAAAAYABgAgA"
6080 "AAAAAAAABAAAAAGAAYAEAAAAAQABAAWAAAAAAAAAAAAAAABYIIAHQA"
6081 "ZQBzAHQAaQBuAGcALQBuAHQAbABtAFcAVABDAC0AVwBJAE4ANwBO54"
6082 "dFMVvTHwAAAAAAAAAAAAAAAAAAAACS7sT6Uzw7L0L//WUqlIaVWpbI"
6083 "+4MUm7c=\r\n\r\n"),
[email protected]385a4672009-03-11 22:21:296084 };
6085
6086 MockRead data_reads3[] = {
6087 // The origin server responds with a Type 2 message.
6088 MockRead("HTTP/1.1 401 Access Denied\r\n"),
6089 MockRead("WWW-Authenticate: NTLM "
6090 "TlRMTVNTUAACAAAADAAMADgAAAAFgokCL24VN8dgOR8AAAAAAAAAALo"
6091 "AugBEAAAABQEoCgAAAA9HAE8ATwBHAEwARQACAAwARwBPAE8ARwBMAE"
6092 "UAAQAaAEEASwBFAEUAUwBBAFIAQQAtAEMATwBSAFAABAAeAGMAbwByA"
6093 "HAALgBnAG8AbwBnAGwAZQAuAGMAbwBtAAMAQABhAGsAZQBlAHMAYQBy"
6094 "AGEALQBjAG8AcgBwAC4AYQBkAC4AYwBvAHIAcAAuAGcAbwBvAGcAbAB"
6095 "lAC4AYwBvAG0ABQAeAGMAbwByAHAALgBnAG8AbwBnAGwAZQAuAGMAbw"
6096 "BtAAAAAAA=\r\n"),
6097 MockRead("Content-Length: 42\r\n"),
[email protected]076c85082009-04-10 23:21:366098 MockRead("Content-Type: text/html\r\n\r\n"),
[email protected]385a4672009-03-11 22:21:296099 MockRead("You are not authorized to view this page\r\n"),
6100
6101 // Lastly we get the desired content.
6102 MockRead("HTTP/1.1 200 OK\r\n"),
6103 MockRead("Content-Type: text/html; charset=utf-8\r\n"),
6104 MockRead("Content-Length: 13\r\n\r\n"),
6105 MockRead("Please Login\r\n"),
[email protected]8ddf8322012-02-23 18:08:066106 MockRead(SYNCHRONOUS, OK),
[email protected]385a4672009-03-11 22:21:296107 };
6108
[email protected]31a2bfe2010-02-09 08:03:396109 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
6110 data_writes1, arraysize(data_writes1));
6111 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
6112 data_writes2, arraysize(data_writes2));
6113 StaticSocketDataProvider data3(data_reads3, arraysize(data_reads3),
6114 data_writes3, arraysize(data_writes3));
[email protected]bb88e1d32013-05-03 23:11:076115 session_deps_.socket_factory->AddSocketDataProvider(&data1);
6116 session_deps_.socket_factory->AddSocketDataProvider(&data2);
6117 session_deps_.socket_factory->AddSocketDataProvider(&data3);
[email protected]385a4672009-03-11 22:21:296118
[email protected]49639fa2011-12-20 23:22:416119 TestCompletionCallback callback1;
[email protected]385a4672009-03-11 22:21:296120
bnc691fda62016-08-12 00:43:166121 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]0b0bf032010-09-21 18:08:506122
tfarina42834112016-09-22 13:38:206123 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:016124 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]385a4672009-03-11 22:21:296125
6126 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:016127 EXPECT_THAT(rv, IsOk());
[email protected]385a4672009-03-11 22:21:296128
bnc691fda62016-08-12 00:43:166129 EXPECT_FALSE(trans.IsReadyToRestartForAuth());
[email protected]385a4672009-03-11 22:21:296130
bnc691fda62016-08-12 00:43:166131 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:526132 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:046133 EXPECT_TRUE(CheckNTLMServerAuth(response->auth_challenge.get()));
[email protected]385a4672009-03-11 22:21:296134
[email protected]49639fa2011-12-20 23:22:416135 TestCompletionCallback callback2;
[email protected]385a4672009-03-11 22:21:296136
[email protected]0757e7702009-03-27 04:00:226137 // Enter the wrong password.
bnc691fda62016-08-12 00:43:166138 rv = trans.RestartWithAuth(AuthCredentials(kTestingNTLM, kWrongPassword),
6139 callback2.callback());
robpercival214763f2016-07-01 23:27:016140 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]385a4672009-03-11 22:21:296141
[email protected]10af5fe72011-01-31 16:17:256142 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:016143 EXPECT_THAT(rv, IsOk());
[email protected]385a4672009-03-11 22:21:296144
bnc691fda62016-08-12 00:43:166145 EXPECT_TRUE(trans.IsReadyToRestartForAuth());
[email protected]49639fa2011-12-20 23:22:416146 TestCompletionCallback callback3;
bnc691fda62016-08-12 00:43:166147 rv = trans.RestartWithAuth(AuthCredentials(), callback3.callback());
robpercival214763f2016-07-01 23:27:016148 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]10af5fe72011-01-31 16:17:256149 rv = callback3.WaitForResult();
robpercival214763f2016-07-01 23:27:016150 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:166151 EXPECT_FALSE(trans.IsReadyToRestartForAuth());
[email protected]0757e7702009-03-27 04:00:226152
bnc691fda62016-08-12 00:43:166153 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:526154 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:046155 EXPECT_TRUE(CheckNTLMServerAuth(response->auth_challenge.get()));
[email protected]0757e7702009-03-27 04:00:226156
[email protected]49639fa2011-12-20 23:22:416157 TestCompletionCallback callback4;
[email protected]0757e7702009-03-27 04:00:226158
6159 // Now enter the right password.
bnc691fda62016-08-12 00:43:166160 rv = trans.RestartWithAuth(AuthCredentials(kTestingNTLM, kTestingNTLM),
6161 callback4.callback());
robpercival214763f2016-07-01 23:27:016162 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]10af5fe72011-01-31 16:17:256163
6164 rv = callback4.WaitForResult();
robpercival214763f2016-07-01 23:27:016165 EXPECT_THAT(rv, IsOk());
[email protected]10af5fe72011-01-31 16:17:256166
bnc691fda62016-08-12 00:43:166167 EXPECT_TRUE(trans.IsReadyToRestartForAuth());
[email protected]10af5fe72011-01-31 16:17:256168
[email protected]49639fa2011-12-20 23:22:416169 TestCompletionCallback callback5;
[email protected]10af5fe72011-01-31 16:17:256170
6171 // One more roundtrip
bnc691fda62016-08-12 00:43:166172 rv = trans.RestartWithAuth(AuthCredentials(), callback5.callback());
robpercival214763f2016-07-01 23:27:016173 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]0757e7702009-03-27 04:00:226174
6175 rv = callback5.WaitForResult();
robpercival214763f2016-07-01 23:27:016176 EXPECT_THAT(rv, IsOk());
[email protected]0757e7702009-03-27 04:00:226177
bnc691fda62016-08-12 00:43:166178 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:526179 EXPECT_FALSE(response->auth_challenge);
[email protected]385a4672009-03-11 22:21:296180 EXPECT_EQ(13, response->headers->GetContentLength());
6181}
[email protected]ea9dc9a2009-09-05 00:43:326182#endif // NTLM_PORTABLE
[email protected]385a4672009-03-11 22:21:296183
[email protected]4ddaf2502008-10-23 18:26:196184// Test reading a server response which has only headers, and no body.
6185// After some maximum number of bytes is consumed, the transaction should
6186// fail with ERR_RESPONSE_HEADERS_TOO_BIG.
bncd16676a2016-07-20 16:23:016187TEST_F(HttpNetworkTransactionTest, LargeHeadersNoBody) {
[email protected]1c773ea12009-04-28 19:58:426188 HttpRequestInfo request;
[email protected]4ddaf2502008-10-23 18:26:196189 request.method = "GET";
bncce36dca22015-04-21 22:11:236190 request.url = GURL("http://www.example.org/");
[email protected]4ddaf2502008-10-23 18:26:196191
danakj1fd259a02016-04-16 03:17:096192 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:166193 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:276194
[email protected]b75b7b2f2009-10-06 00:54:536195 // Respond with 300 kb of headers (we should fail after 256 kb).
[email protected]15a5ccf82008-10-23 19:57:436196 std::string large_headers_string;
[email protected]b75b7b2f2009-10-06 00:54:536197 FillLargeHeadersString(&large_headers_string, 300 * 1024);
[email protected]4ddaf2502008-10-23 18:26:196198
6199 MockRead data_reads[] = {
6200 MockRead("HTTP/1.0 200 OK\r\n"),
[email protected]8ddf8322012-02-23 18:08:066201 MockRead(ASYNC, large_headers_string.data(), large_headers_string.size()),
[email protected]4ddaf2502008-10-23 18:26:196202 MockRead("\r\nBODY"),
[email protected]8ddf8322012-02-23 18:08:066203 MockRead(SYNCHRONOUS, OK),
[email protected]4ddaf2502008-10-23 18:26:196204 };
[email protected]31a2bfe2010-02-09 08:03:396205 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:076206 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]4ddaf2502008-10-23 18:26:196207
[email protected]49639fa2011-12-20 23:22:416208 TestCompletionCallback callback;
[email protected]4ddaf2502008-10-23 18:26:196209
tfarina42834112016-09-22 13:38:206210 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:016211 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]4ddaf2502008-10-23 18:26:196212
6213 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:016214 EXPECT_THAT(rv, IsError(ERR_RESPONSE_HEADERS_TOO_BIG));
[email protected]4ddaf2502008-10-23 18:26:196215}
[email protected]f4e426b2008-11-05 00:24:496216
6217// Make sure that we don't try to reuse a TCPClientSocket when failing to
6218// establish tunnel.
6219// http://code.google.com/p/chromium/issues/detail?id=3772
bncd16676a2016-07-20 16:23:016220TEST_F(HttpNetworkTransactionTest, DontRecycleTransportSocketForSSLTunnel) {
[email protected]cb9bf6ca2011-01-28 13:15:276221 HttpRequestInfo request;
6222 request.method = "GET";
bncce36dca22015-04-21 22:11:236223 request.url = GURL("https://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:276224
[email protected]f4e426b2008-11-05 00:24:496225 // Configure against proxy server "myproxy:70".
rdsmith82957ad2015-09-16 19:42:036226 session_deps_.proxy_service = ProxyService::CreateFixed("myproxy:70");
[email protected]db8f44c2008-12-13 04:52:016227
danakj1fd259a02016-04-16 03:17:096228 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]f4e426b2008-11-05 00:24:496229
bnc691fda62016-08-12 00:43:166230 std::unique_ptr<HttpNetworkTransaction> trans(
[email protected]90499482013-06-01 00:39:506231 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]f4e426b2008-11-05 00:24:496232
[email protected]f4e426b2008-11-05 00:24:496233 // Since we have proxy, should try to establish tunnel.
6234 MockWrite data_writes1[] = {
rsleevidb16bb02015-11-12 23:47:176235 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
6236 "Host: www.example.org:443\r\n"
6237 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]f4e426b2008-11-05 00:24:496238 };
6239
[email protected]77848d12008-11-14 00:00:226240 // The proxy responds to the connect with a 404, using a persistent
[email protected]f4e426b2008-11-05 00:24:496241 // connection. Usually a proxy would return 501 (not implemented),
6242 // or 200 (tunnel established).
6243 MockRead data_reads1[] = {
mmenked39192ee2015-12-09 00:57:236244 MockRead("HTTP/1.1 404 Not Found\r\n"),
6245 MockRead("Content-Length: 10\r\n\r\n"),
6246 MockRead(SYNCHRONOUS, ERR_UNEXPECTED),
[email protected]f4e426b2008-11-05 00:24:496247 };
6248
[email protected]31a2bfe2010-02-09 08:03:396249 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
6250 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:076251 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]f4e426b2008-11-05 00:24:496252
[email protected]49639fa2011-12-20 23:22:416253 TestCompletionCallback callback1;
[email protected]f4e426b2008-11-05 00:24:496254
tfarina42834112016-09-22 13:38:206255 int rv = trans->Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:016256 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]f4e426b2008-11-05 00:24:496257
6258 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:016259 EXPECT_THAT(rv, IsError(ERR_TUNNEL_CONNECTION_FAILED));
[email protected]f4e426b2008-11-05 00:24:496260
[email protected]b4404c02009-04-10 16:38:526261 // Empty the current queue. This is necessary because idle sockets are
6262 // added to the connection pool asynchronously with a PostTask.
fdoray92e35a72016-06-10 15:54:556263 base::RunLoop().RunUntilIdle();
[email protected]b4404c02009-04-10 16:38:526264
[email protected]f4e426b2008-11-05 00:24:496265 // We now check to make sure the TCPClientSocket was not added back to
6266 // the pool.
[email protected]90499482013-06-01 00:39:506267 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]f4e426b2008-11-05 00:24:496268 trans.reset();
fdoray92e35a72016-06-10 15:54:556269 base::RunLoop().RunUntilIdle();
[email protected]f4e426b2008-11-05 00:24:496270 // Make sure that the socket didn't get recycled after calling the destructor.
[email protected]90499482013-06-01 00:39:506271 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]f4e426b2008-11-05 00:24:496272}
[email protected]372d34a2008-11-05 21:30:516273
[email protected]1b157c02009-04-21 01:55:406274// Make sure that we recycle a socket after reading all of the response body.
bncd16676a2016-07-20 16:23:016275TEST_F(HttpNetworkTransactionTest, RecycleSocket) {
[email protected]1c773ea12009-04-28 19:58:426276 HttpRequestInfo request;
[email protected]1b157c02009-04-21 01:55:406277 request.method = "GET";
bncce36dca22015-04-21 22:11:236278 request.url = GURL("http://www.example.org/");
[email protected]1b157c02009-04-21 01:55:406279
danakj1fd259a02016-04-16 03:17:096280 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:276281
bnc691fda62016-08-12 00:43:166282 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:276283
[email protected]1b157c02009-04-21 01:55:406284 MockRead data_reads[] = {
6285 // A part of the response body is received with the response headers.
6286 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 11\r\n\r\nhel"),
6287 // The rest of the response body is received in two parts.
6288 MockRead("lo"),
6289 MockRead(" world"),
6290 MockRead("junk"), // Should not be read!!
[email protected]8ddf8322012-02-23 18:08:066291 MockRead(SYNCHRONOUS, OK),
[email protected]1b157c02009-04-21 01:55:406292 };
6293
[email protected]31a2bfe2010-02-09 08:03:396294 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:076295 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1b157c02009-04-21 01:55:406296
[email protected]49639fa2011-12-20 23:22:416297 TestCompletionCallback callback;
[email protected]1b157c02009-04-21 01:55:406298
tfarina42834112016-09-22 13:38:206299 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:016300 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]1b157c02009-04-21 01:55:406301
6302 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:016303 EXPECT_THAT(rv, IsOk());
[email protected]1b157c02009-04-21 01:55:406304
bnc691fda62016-08-12 00:43:166305 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:526306 ASSERT_TRUE(response);
[email protected]1b157c02009-04-21 01:55:406307
wezca1070932016-05-26 20:30:526308 EXPECT_TRUE(response->headers);
[email protected]1b157c02009-04-21 01:55:406309 std::string status_line = response->headers->GetStatusLine();
6310 EXPECT_EQ("HTTP/1.1 200 OK", status_line);
6311
[email protected]90499482013-06-01 00:39:506312 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]1b157c02009-04-21 01:55:406313
6314 std::string response_data;
bnc691fda62016-08-12 00:43:166315 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:016316 EXPECT_THAT(rv, IsOk());
[email protected]1b157c02009-04-21 01:55:406317 EXPECT_EQ("hello world", response_data);
6318
6319 // Empty the current queue. This is necessary because idle sockets are
6320 // added to the connection pool asynchronously with a PostTask.
fdoray92e35a72016-06-10 15:54:556321 base::RunLoop().RunUntilIdle();
[email protected]1b157c02009-04-21 01:55:406322
6323 // We now check to make sure the socket was added back to the pool.
[email protected]90499482013-06-01 00:39:506324 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]1b157c02009-04-21 01:55:406325}
6326
[email protected]76a505b2010-08-25 06:23:006327// Make sure that we recycle a SSL socket after reading all of the response
6328// body.
bncd16676a2016-07-20 16:23:016329TEST_F(HttpNetworkTransactionTest, RecycleSSLSocket) {
[email protected]76a505b2010-08-25 06:23:006330 HttpRequestInfo request;
6331 request.method = "GET";
bncce36dca22015-04-21 22:11:236332 request.url = GURL("https://www.example.org/");
[email protected]76a505b2010-08-25 06:23:006333
6334 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:236335 MockWrite(
6336 "GET / HTTP/1.1\r\n"
6337 "Host: www.example.org\r\n"
6338 "Connection: keep-alive\r\n\r\n"),
[email protected]76a505b2010-08-25 06:23:006339 };
6340
6341 MockRead data_reads[] = {
6342 MockRead("HTTP/1.1 200 OK\r\n"),
6343 MockRead("Content-Length: 11\r\n\r\n"),
6344 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:066345 MockRead(SYNCHRONOUS, OK),
[email protected]76a505b2010-08-25 06:23:006346 };
6347
[email protected]8ddf8322012-02-23 18:08:066348 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:076349 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]76a505b2010-08-25 06:23:006350
6351 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
6352 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:076353 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]76a505b2010-08-25 06:23:006354
[email protected]49639fa2011-12-20 23:22:416355 TestCompletionCallback callback;
[email protected]76a505b2010-08-25 06:23:006356
danakj1fd259a02016-04-16 03:17:096357 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:166358 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]76a505b2010-08-25 06:23:006359
tfarina42834112016-09-22 13:38:206360 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
[email protected]76a505b2010-08-25 06:23:006361
robpercival214763f2016-07-01 23:27:016362 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
6363 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]76a505b2010-08-25 06:23:006364
bnc691fda62016-08-12 00:43:166365 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:526366 ASSERT_TRUE(response);
6367 ASSERT_TRUE(response->headers);
[email protected]76a505b2010-08-25 06:23:006368 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
6369
[email protected]90499482013-06-01 00:39:506370 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]76a505b2010-08-25 06:23:006371
6372 std::string response_data;
bnc691fda62016-08-12 00:43:166373 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:016374 EXPECT_THAT(rv, IsOk());
[email protected]76a505b2010-08-25 06:23:006375 EXPECT_EQ("hello world", response_data);
6376
6377 // Empty the current queue. This is necessary because idle sockets are
6378 // added to the connection pool asynchronously with a PostTask.
fdoray92e35a72016-06-10 15:54:556379 base::RunLoop().RunUntilIdle();
[email protected]76a505b2010-08-25 06:23:006380
6381 // We now check to make sure the socket was added back to the pool.
[email protected]90499482013-06-01 00:39:506382 EXPECT_EQ(1, GetIdleSocketCountInSSLSocketPool(session.get()));
[email protected]76a505b2010-08-25 06:23:006383}
6384
6385// Grab a SSL socket, use it, and put it back into the pool. Then, reuse it
6386// from the pool and make sure that we recover okay.
bncd16676a2016-07-20 16:23:016387TEST_F(HttpNetworkTransactionTest, RecycleDeadSSLSocket) {
[email protected]76a505b2010-08-25 06:23:006388 HttpRequestInfo request;
6389 request.method = "GET";
bncce36dca22015-04-21 22:11:236390 request.url = GURL("https://www.example.org/");
[email protected]76a505b2010-08-25 06:23:006391
6392 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:236393 MockWrite(
6394 "GET / HTTP/1.1\r\n"
6395 "Host: www.example.org\r\n"
6396 "Connection: keep-alive\r\n\r\n"),
6397 MockWrite(
6398 "GET / HTTP/1.1\r\n"
6399 "Host: www.example.org\r\n"
6400 "Connection: keep-alive\r\n\r\n"),
[email protected]76a505b2010-08-25 06:23:006401 };
6402
6403 MockRead data_reads[] = {
mmenke911ee0222015-12-04 03:58:426404 MockRead("HTTP/1.1 200 OK\r\n"), MockRead("Content-Length: 11\r\n\r\n"),
6405 MockRead("hello world"), MockRead(ASYNC, ERR_CONNECTION_CLOSED)};
[email protected]76a505b2010-08-25 06:23:006406
[email protected]8ddf8322012-02-23 18:08:066407 SSLSocketDataProvider ssl(ASYNC, OK);
6408 SSLSocketDataProvider ssl2(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:076409 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
6410 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
[email protected]76a505b2010-08-25 06:23:006411
6412 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
6413 data_writes, arraysize(data_writes));
6414 StaticSocketDataProvider data2(data_reads, arraysize(data_reads),
6415 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:076416 session_deps_.socket_factory->AddSocketDataProvider(&data);
6417 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]76a505b2010-08-25 06:23:006418
[email protected]49639fa2011-12-20 23:22:416419 TestCompletionCallback callback;
[email protected]76a505b2010-08-25 06:23:006420
danakj1fd259a02016-04-16 03:17:096421 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:166422 std::unique_ptr<HttpNetworkTransaction> trans(
[email protected]90499482013-06-01 00:39:506423 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]76a505b2010-08-25 06:23:006424
tfarina42834112016-09-22 13:38:206425 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
[email protected]76a505b2010-08-25 06:23:006426
robpercival214763f2016-07-01 23:27:016427 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
6428 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]76a505b2010-08-25 06:23:006429
6430 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:526431 ASSERT_TRUE(response);
6432 ASSERT_TRUE(response->headers);
[email protected]76a505b2010-08-25 06:23:006433 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
6434
[email protected]90499482013-06-01 00:39:506435 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]76a505b2010-08-25 06:23:006436
6437 std::string response_data;
6438 rv = ReadTransaction(trans.get(), &response_data);
robpercival214763f2016-07-01 23:27:016439 EXPECT_THAT(rv, IsOk());
[email protected]76a505b2010-08-25 06:23:006440 EXPECT_EQ("hello world", response_data);
6441
6442 // Empty the current queue. This is necessary because idle sockets are
6443 // added to the connection pool asynchronously with a PostTask.
fdoray92e35a72016-06-10 15:54:556444 base::RunLoop().RunUntilIdle();
[email protected]76a505b2010-08-25 06:23:006445
6446 // We now check to make sure the socket was added back to the pool.
[email protected]90499482013-06-01 00:39:506447 EXPECT_EQ(1, GetIdleSocketCountInSSLSocketPool(session.get()));
[email protected]76a505b2010-08-25 06:23:006448
6449 // Now start the second transaction, which should reuse the previous socket.
6450
[email protected]90499482013-06-01 00:39:506451 trans.reset(new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]76a505b2010-08-25 06:23:006452
tfarina42834112016-09-22 13:38:206453 rv = trans->Start(&request, callback.callback(), NetLogWithSource());
[email protected]76a505b2010-08-25 06:23:006454
robpercival214763f2016-07-01 23:27:016455 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
6456 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]76a505b2010-08-25 06:23:006457
6458 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:526459 ASSERT_TRUE(response);
6460 ASSERT_TRUE(response->headers);
[email protected]76a505b2010-08-25 06:23:006461 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
6462
[email protected]90499482013-06-01 00:39:506463 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]76a505b2010-08-25 06:23:006464
6465 rv = ReadTransaction(trans.get(), &response_data);
robpercival214763f2016-07-01 23:27:016466 EXPECT_THAT(rv, IsOk());
[email protected]76a505b2010-08-25 06:23:006467 EXPECT_EQ("hello world", response_data);
6468
6469 // Empty the current queue. This is necessary because idle sockets are
6470 // added to the connection pool asynchronously with a PostTask.
fdoray92e35a72016-06-10 15:54:556471 base::RunLoop().RunUntilIdle();
[email protected]76a505b2010-08-25 06:23:006472
6473 // We now check to make sure the socket was added back to the pool.
[email protected]90499482013-06-01 00:39:506474 EXPECT_EQ(1, GetIdleSocketCountInSSLSocketPool(session.get()));
[email protected]76a505b2010-08-25 06:23:006475}
6476
maksim.sisov0adf8592016-07-15 06:25:566477// Grab a socket, use it, and put it back into the pool. Then, make
6478// low memory notification and ensure the socket pool is flushed.
bncd16676a2016-07-20 16:23:016479TEST_F(HttpNetworkTransactionTest, FlushSocketPoolOnLowMemoryNotifications) {
maksim.sisov0adf8592016-07-15 06:25:566480 HttpRequestInfo request;
6481 request.method = "GET";
6482 request.url = GURL("http://www.example.org/");
6483 request.load_flags = 0;
6484
6485 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
6486
bnc691fda62016-08-12 00:43:166487 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
maksim.sisov0adf8592016-07-15 06:25:566488
6489 MockRead data_reads[] = {
6490 // A part of the response body is received with the response headers.
6491 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 11\r\n\r\nhel"),
6492 // The rest of the response body is received in two parts.
6493 MockRead("lo"), MockRead(" world"),
6494 MockRead("junk"), // Should not be read!!
6495 MockRead(SYNCHRONOUS, OK),
6496 };
6497
6498 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
6499 session_deps_.socket_factory->AddSocketDataProvider(&data);
6500
6501 TestCompletionCallback callback;
6502
tfarina42834112016-09-22 13:38:206503 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
maksim.sisov0adf8592016-07-15 06:25:566504 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
6505
6506 EXPECT_THAT(callback.GetResult(rv), IsOk());
6507
bnc691fda62016-08-12 00:43:166508 const HttpResponseInfo* response = trans.GetResponseInfo();
maksim.sisov0adf8592016-07-15 06:25:566509 ASSERT_TRUE(response);
6510 EXPECT_TRUE(response->headers);
6511 std::string status_line = response->headers->GetStatusLine();
6512 EXPECT_EQ("HTTP/1.1 200 OK", status_line);
6513
6514 // Make memory critical notification and ensure the transaction still has been
6515 // operating right.
6516 base::MemoryPressureListener::NotifyMemoryPressure(
6517 base::MemoryPressureListener::MEMORY_PRESSURE_LEVEL_CRITICAL);
6518 base::RunLoop().RunUntilIdle();
6519
6520 // Socket should not be flushed as long as it is not idle.
6521 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
6522
6523 std::string response_data;
bnc691fda62016-08-12 00:43:166524 rv = ReadTransaction(&trans, &response_data);
maksim.sisov0adf8592016-07-15 06:25:566525 EXPECT_THAT(rv, IsOk());
6526 EXPECT_EQ("hello world", response_data);
6527
6528 // Empty the current queue. This is necessary because idle sockets are
6529 // added to the connection pool asynchronously with a PostTask.
6530 base::RunLoop().RunUntilIdle();
6531
6532 // We now check to make sure the socket was added back to the pool.
6533 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
6534
6535 // Idle sockets should be flushed now.
6536 base::MemoryPressureListener::NotifyMemoryPressure(
6537 base::MemoryPressureListener::MEMORY_PRESSURE_LEVEL_CRITICAL);
6538 base::RunLoop().RunUntilIdle();
6539
6540 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
6541}
6542
6543// Grab an SSL socket, use it, and put it back into the pool. Then, make
6544// low memory notification and ensure the socket pool is flushed.
bncd16676a2016-07-20 16:23:016545TEST_F(HttpNetworkTransactionTest, FlushSSLSocketPoolOnLowMemoryNotifications) {
maksim.sisov0adf8592016-07-15 06:25:566546 HttpRequestInfo request;
6547 request.method = "GET";
6548 request.url = GURL("https://www.example.org/");
6549 request.load_flags = 0;
6550
6551 MockWrite data_writes[] = {
6552 MockWrite("GET / HTTP/1.1\r\n"
6553 "Host: www.example.org\r\n"
6554 "Connection: keep-alive\r\n\r\n"),
6555 };
6556
6557 MockRead data_reads[] = {
6558 MockRead("HTTP/1.1 200 OK\r\n"), MockRead("Content-Length: 11\r\n\r\n"),
6559 MockRead("hello world"), MockRead(ASYNC, ERR_CONNECTION_CLOSED)};
6560
6561 SSLSocketDataProvider ssl(ASYNC, OK);
6562 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
6563
6564 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
6565 arraysize(data_writes));
6566 session_deps_.socket_factory->AddSocketDataProvider(&data);
6567
6568 TestCompletionCallback callback;
6569
6570 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:166571 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
maksim.sisov0adf8592016-07-15 06:25:566572
6573 EXPECT_EQ(0, GetIdleSocketCountInSSLSocketPool(session.get()));
tfarina42834112016-09-22 13:38:206574 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
maksim.sisov0adf8592016-07-15 06:25:566575
6576 EXPECT_THAT(callback.GetResult(rv), IsOk());
6577
bnc691fda62016-08-12 00:43:166578 const HttpResponseInfo* response = trans.GetResponseInfo();
maksim.sisov0adf8592016-07-15 06:25:566579 ASSERT_TRUE(response);
6580 ASSERT_TRUE(response->headers);
6581 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
6582
6583 // Make memory critical notification and ensure the transaction still has been
6584 // operating right.
6585 base::MemoryPressureListener::NotifyMemoryPressure(
6586 base::MemoryPressureListener::MEMORY_PRESSURE_LEVEL_CRITICAL);
6587 base::RunLoop().RunUntilIdle();
6588
6589 EXPECT_EQ(0, GetIdleSocketCountInSSLSocketPool(session.get()));
6590
6591 std::string response_data;
bnc691fda62016-08-12 00:43:166592 rv = ReadTransaction(&trans, &response_data);
maksim.sisov0adf8592016-07-15 06:25:566593 EXPECT_THAT(rv, IsOk());
6594 EXPECT_EQ("hello world", response_data);
6595
6596 // Empty the current queue. This is necessary because idle sockets are
6597 // added to the connection pool asynchronously with a PostTask.
6598 base::RunLoop().RunUntilIdle();
6599
6600 // We now check to make sure the socket was added back to the pool.
6601 EXPECT_EQ(1, GetIdleSocketCountInSSLSocketPool(session.get()));
6602
6603 // Make memory notification once again and ensure idle socket is closed.
6604 base::MemoryPressureListener::NotifyMemoryPressure(
6605 base::MemoryPressureListener::MEMORY_PRESSURE_LEVEL_CRITICAL);
6606 base::RunLoop().RunUntilIdle();
6607
6608 EXPECT_EQ(0, GetIdleSocketCountInSSLSocketPool(session.get()));
6609}
6610
[email protected]b4404c02009-04-10 16:38:526611// Make sure that we recycle a socket after a zero-length response.
6612// http://crbug.com/9880
bncd16676a2016-07-20 16:23:016613TEST_F(HttpNetworkTransactionTest, RecycleSocketAfterZeroContentLength) {
[email protected]1c773ea12009-04-28 19:58:426614 HttpRequestInfo request;
[email protected]b4404c02009-04-10 16:38:526615 request.method = "GET";
bncce36dca22015-04-21 22:11:236616 request.url = GURL(
6617 "http://www.example.org/csi?v=3&s=web&action=&"
6618 "tran=undefined&ei=mAXcSeegAo-SMurloeUN&"
6619 "e=17259,18167,19592,19773,19981,20133,20173,20233&"
6620 "rt=prt.2642,ol.2649,xjs.2951");
[email protected]b4404c02009-04-10 16:38:526621
danakj1fd259a02016-04-16 03:17:096622 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:276623
[email protected]b4404c02009-04-10 16:38:526624 MockRead data_reads[] = {
6625 MockRead("HTTP/1.1 204 No Content\r\n"
6626 "Content-Length: 0\r\n"
6627 "Content-Type: text/html\r\n\r\n"),
6628 MockRead("junk"), // Should not be read!!
[email protected]8ddf8322012-02-23 18:08:066629 MockRead(SYNCHRONOUS, OK),
[email protected]b4404c02009-04-10 16:38:526630 };
6631
[email protected]31a2bfe2010-02-09 08:03:396632 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:076633 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]b4404c02009-04-10 16:38:526634
mmenkecc2298e2015-12-07 18:20:186635 // Transaction must be created after the MockReads, so it's destroyed before
6636 // them.
bnc691fda62016-08-12 00:43:166637 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
mmenkecc2298e2015-12-07 18:20:186638
[email protected]49639fa2011-12-20 23:22:416639 TestCompletionCallback callback;
[email protected]b4404c02009-04-10 16:38:526640
tfarina42834112016-09-22 13:38:206641 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:016642 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]b4404c02009-04-10 16:38:526643
6644 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:016645 EXPECT_THAT(rv, IsOk());
[email protected]b4404c02009-04-10 16:38:526646
bnc691fda62016-08-12 00:43:166647 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:526648 ASSERT_TRUE(response);
[email protected]b4404c02009-04-10 16:38:526649
wezca1070932016-05-26 20:30:526650 EXPECT_TRUE(response->headers);
[email protected]b4404c02009-04-10 16:38:526651 std::string status_line = response->headers->GetStatusLine();
6652 EXPECT_EQ("HTTP/1.1 204 No Content", status_line);
6653
[email protected]90499482013-06-01 00:39:506654 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]b4404c02009-04-10 16:38:526655
6656 std::string response_data;
bnc691fda62016-08-12 00:43:166657 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:016658 EXPECT_THAT(rv, IsOk());
[email protected]b4404c02009-04-10 16:38:526659 EXPECT_EQ("", response_data);
6660
6661 // Empty the current queue. This is necessary because idle sockets are
6662 // added to the connection pool asynchronously with a PostTask.
fdoray92e35a72016-06-10 15:54:556663 base::RunLoop().RunUntilIdle();
[email protected]b4404c02009-04-10 16:38:526664
6665 // We now check to make sure the socket was added back to the pool.
[email protected]90499482013-06-01 00:39:506666 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]b4404c02009-04-10 16:38:526667}
6668
bncd16676a2016-07-20 16:23:016669TEST_F(HttpNetworkTransactionTest, ResendRequestOnWriteBodyError) {
danakj1fd259a02016-04-16 03:17:096670 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:226671 element_readers.push_back(
ricea2deef682016-09-09 08:04:076672 base::MakeUnique<UploadBytesElementReader>("foo", 3));
olli.raula6df48b2a2015-11-26 07:40:226673 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]329b68b2012-11-14 17:54:276674
[email protected]1c773ea12009-04-28 19:58:426675 HttpRequestInfo request[2];
[email protected]372d34a2008-11-05 21:30:516676 // Transaction 1: a GET request that succeeds. The socket is recycled
6677 // after use.
6678 request[0].method = "GET";
6679 request[0].url = GURL("http://www.google.com/");
6680 request[0].load_flags = 0;
6681 // Transaction 2: a POST request. Reuses the socket kept alive from
6682 // transaction 1. The first attempts fails when writing the POST data.
6683 // This causes the transaction to retry with a new socket. The second
6684 // attempt succeeds.
6685 request[1].method = "POST";
6686 request[1].url = GURL("http://www.google.com/login.cgi");
[email protected]329b68b2012-11-14 17:54:276687 request[1].upload_data_stream = &upload_data_stream;
[email protected]372d34a2008-11-05 21:30:516688 request[1].load_flags = 0;
6689
danakj1fd259a02016-04-16 03:17:096690 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]372d34a2008-11-05 21:30:516691
6692 // The first socket is used for transaction 1 and the first attempt of
6693 // transaction 2.
6694
6695 // The response of transaction 1.
6696 MockRead data_reads1[] = {
6697 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 11\r\n\r\n"),
6698 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:066699 MockRead(SYNCHRONOUS, OK),
[email protected]372d34a2008-11-05 21:30:516700 };
6701 // The mock write results of transaction 1 and the first attempt of
6702 // transaction 2.
6703 MockWrite data_writes1[] = {
[email protected]8ddf8322012-02-23 18:08:066704 MockWrite(SYNCHRONOUS, 64), // GET
6705 MockWrite(SYNCHRONOUS, 93), // POST
6706 MockWrite(SYNCHRONOUS, ERR_CONNECTION_ABORTED), // POST data
[email protected]372d34a2008-11-05 21:30:516707 };
[email protected]31a2bfe2010-02-09 08:03:396708 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
6709 data_writes1, arraysize(data_writes1));
[email protected]372d34a2008-11-05 21:30:516710
6711 // The second socket is used for the second attempt of transaction 2.
6712
6713 // The response of transaction 2.
6714 MockRead data_reads2[] = {
6715 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 7\r\n\r\n"),
6716 MockRead("welcome"),
[email protected]8ddf8322012-02-23 18:08:066717 MockRead(SYNCHRONOUS, OK),
[email protected]372d34a2008-11-05 21:30:516718 };
6719 // The mock write results of the second attempt of transaction 2.
6720 MockWrite data_writes2[] = {
[email protected]8ddf8322012-02-23 18:08:066721 MockWrite(SYNCHRONOUS, 93), // POST
6722 MockWrite(SYNCHRONOUS, 3), // POST data
[email protected]372d34a2008-11-05 21:30:516723 };
[email protected]31a2bfe2010-02-09 08:03:396724 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
6725 data_writes2, arraysize(data_writes2));
[email protected]372d34a2008-11-05 21:30:516726
[email protected]bb88e1d32013-05-03 23:11:076727 session_deps_.socket_factory->AddSocketDataProvider(&data1);
6728 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]372d34a2008-11-05 21:30:516729
thestig9d3bb0c2015-01-24 00:49:516730 const char* const kExpectedResponseData[] = {
[email protected]372d34a2008-11-05 21:30:516731 "hello world", "welcome"
6732 };
6733
6734 for (int i = 0; i < 2; ++i) {
bnc691fda62016-08-12 00:43:166735 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]372d34a2008-11-05 21:30:516736
[email protected]49639fa2011-12-20 23:22:416737 TestCompletionCallback callback;
[email protected]372d34a2008-11-05 21:30:516738
tfarina42834112016-09-22 13:38:206739 int rv = trans.Start(&request[i], callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:016740 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]372d34a2008-11-05 21:30:516741
6742 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:016743 EXPECT_THAT(rv, IsOk());
[email protected]372d34a2008-11-05 21:30:516744
bnc691fda62016-08-12 00:43:166745 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:526746 ASSERT_TRUE(response);
[email protected]372d34a2008-11-05 21:30:516747
wezca1070932016-05-26 20:30:526748 EXPECT_TRUE(response->headers);
[email protected]372d34a2008-11-05 21:30:516749 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
6750
6751 std::string response_data;
bnc691fda62016-08-12 00:43:166752 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:016753 EXPECT_THAT(rv, IsOk());
[email protected]372d34a2008-11-05 21:30:516754 EXPECT_EQ(kExpectedResponseData[i], response_data);
6755 }
6756}
[email protected]f9ee6b52008-11-08 06:46:236757
6758// Test the request-challenge-retry sequence for basic auth when there is
6759// an identity in the URL. The request should be sent as normal, but when
[email protected]2262e3a2012-05-22 16:08:166760// it fails the identity from the URL is used to answer the challenge.
bncd16676a2016-07-20 16:23:016761TEST_F(HttpNetworkTransactionTest, AuthIdentityInURL) {
[email protected]1c773ea12009-04-28 19:58:426762 HttpRequestInfo request;
[email protected]f9ee6b52008-11-08 06:46:236763 request.method = "GET";
bncce36dca22015-04-21 22:11:236764 request.url = GURL("http://foo:b@[email protected]/");
[email protected]7b08ba62012-02-10 20:19:416765 request.load_flags = LOAD_NORMAL;
[email protected]a97cca42009-08-14 01:00:296766
danakj1fd259a02016-04-16 03:17:096767 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:166768 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:276769
[email protected]a97cca42009-08-14 01:00:296770 // The password contains an escaped character -- for this test to pass it
6771 // will need to be unescaped by HttpNetworkTransaction.
6772 EXPECT_EQ("b%40r", request.url.password());
6773
[email protected]f9ee6b52008-11-08 06:46:236774 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:236775 MockWrite(
6776 "GET / HTTP/1.1\r\n"
6777 "Host: www.example.org\r\n"
6778 "Connection: keep-alive\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:236779 };
6780
6781 MockRead data_reads1[] = {
6782 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
6783 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
6784 MockRead("Content-Length: 10\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:066785 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]f9ee6b52008-11-08 06:46:236786 };
6787
[email protected]2262e3a2012-05-22 16:08:166788 // After the challenge above, the transaction will be restarted using the
6789 // identity from the url (foo, b@r) to answer the challenge.
6790 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:236791 MockWrite(
6792 "GET / HTTP/1.1\r\n"
6793 "Host: www.example.org\r\n"
6794 "Connection: keep-alive\r\n"
6795 "Authorization: Basic Zm9vOmJAcg==\r\n\r\n"),
[email protected]2262e3a2012-05-22 16:08:166796 };
6797
6798 MockRead data_reads2[] = {
6799 MockRead("HTTP/1.0 200 OK\r\n"),
6800 MockRead("Content-Length: 100\r\n\r\n"),
6801 MockRead(SYNCHRONOUS, OK),
6802 };
6803
[email protected]31a2bfe2010-02-09 08:03:396804 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
6805 data_writes1, arraysize(data_writes1));
[email protected]2262e3a2012-05-22 16:08:166806 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
6807 data_writes2, arraysize(data_writes2));
[email protected]bb88e1d32013-05-03 23:11:076808 session_deps_.socket_factory->AddSocketDataProvider(&data1);
6809 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]f9ee6b52008-11-08 06:46:236810
[email protected]49639fa2011-12-20 23:22:416811 TestCompletionCallback callback1;
tfarina42834112016-09-22 13:38:206812 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:016813 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]f9ee6b52008-11-08 06:46:236814 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:016815 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:166816 EXPECT_TRUE(trans.IsReadyToRestartForAuth());
[email protected]2262e3a2012-05-22 16:08:166817
6818 TestCompletionCallback callback2;
bnc691fda62016-08-12 00:43:166819 rv = trans.RestartWithAuth(AuthCredentials(), callback2.callback());
robpercival214763f2016-07-01 23:27:016820 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2262e3a2012-05-22 16:08:166821 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:016822 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:166823 EXPECT_FALSE(trans.IsReadyToRestartForAuth());
[email protected]0757e7702009-03-27 04:00:226824
bnc691fda62016-08-12 00:43:166825 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:526826 ASSERT_TRUE(response);
[email protected]2262e3a2012-05-22 16:08:166827
6828 // There is no challenge info, since the identity in URL worked.
wezca1070932016-05-26 20:30:526829 EXPECT_FALSE(response->auth_challenge);
[email protected]2262e3a2012-05-22 16:08:166830
6831 EXPECT_EQ(100, response->headers->GetContentLength());
6832
6833 // Empty the current queue.
fdoray92e35a72016-06-10 15:54:556834 base::RunLoop().RunUntilIdle();
[email protected]2262e3a2012-05-22 16:08:166835}
6836
6837// Test the request-challenge-retry sequence for basic auth when there is an
6838// incorrect identity in the URL. The identity from the URL should be used only
6839// once.
bncd16676a2016-07-20 16:23:016840TEST_F(HttpNetworkTransactionTest, WrongAuthIdentityInURL) {
[email protected]2262e3a2012-05-22 16:08:166841 HttpRequestInfo request;
6842 request.method = "GET";
6843 // Note: the URL has a username:password in it. The password "baz" is
6844 // wrong (should be "bar").
bncce36dca22015-04-21 22:11:236845 request.url = GURL("http://foo:[email protected]/");
[email protected]2262e3a2012-05-22 16:08:166846
6847 request.load_flags = LOAD_NORMAL;
6848
danakj1fd259a02016-04-16 03:17:096849 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:166850 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]2262e3a2012-05-22 16:08:166851
6852 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:236853 MockWrite(
6854 "GET / HTTP/1.1\r\n"
6855 "Host: www.example.org\r\n"
6856 "Connection: keep-alive\r\n\r\n"),
[email protected]2262e3a2012-05-22 16:08:166857 };
6858
6859 MockRead data_reads1[] = {
6860 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
6861 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
6862 MockRead("Content-Length: 10\r\n\r\n"),
6863 MockRead(SYNCHRONOUS, ERR_FAILED),
6864 };
6865
6866 // After the challenge above, the transaction will be restarted using the
6867 // identity from the url (foo, baz) to answer the challenge.
6868 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:236869 MockWrite(
6870 "GET / HTTP/1.1\r\n"
6871 "Host: www.example.org\r\n"
6872 "Connection: keep-alive\r\n"
6873 "Authorization: Basic Zm9vOmJheg==\r\n\r\n"),
[email protected]2262e3a2012-05-22 16:08:166874 };
6875
6876 MockRead data_reads2[] = {
6877 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
6878 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
6879 MockRead("Content-Length: 10\r\n\r\n"),
6880 MockRead(SYNCHRONOUS, ERR_FAILED),
6881 };
6882
6883 // After the challenge above, the transaction will be restarted using the
6884 // identity supplied by the user (foo, bar) to answer the challenge.
6885 MockWrite data_writes3[] = {
bncce36dca22015-04-21 22:11:236886 MockWrite(
6887 "GET / HTTP/1.1\r\n"
6888 "Host: www.example.org\r\n"
6889 "Connection: keep-alive\r\n"
6890 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]2262e3a2012-05-22 16:08:166891 };
6892
6893 MockRead data_reads3[] = {
6894 MockRead("HTTP/1.0 200 OK\r\n"),
6895 MockRead("Content-Length: 100\r\n\r\n"),
6896 MockRead(SYNCHRONOUS, OK),
6897 };
6898
6899 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
6900 data_writes1, arraysize(data_writes1));
6901 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
6902 data_writes2, arraysize(data_writes2));
6903 StaticSocketDataProvider data3(data_reads3, arraysize(data_reads3),
6904 data_writes3, arraysize(data_writes3));
[email protected]bb88e1d32013-05-03 23:11:076905 session_deps_.socket_factory->AddSocketDataProvider(&data1);
6906 session_deps_.socket_factory->AddSocketDataProvider(&data2);
6907 session_deps_.socket_factory->AddSocketDataProvider(&data3);
[email protected]2262e3a2012-05-22 16:08:166908
6909 TestCompletionCallback callback1;
6910
tfarina42834112016-09-22 13:38:206911 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:016912 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2262e3a2012-05-22 16:08:166913
6914 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:016915 EXPECT_THAT(rv, IsOk());
[email protected]2262e3a2012-05-22 16:08:166916
bnc691fda62016-08-12 00:43:166917 EXPECT_TRUE(trans.IsReadyToRestartForAuth());
[email protected]2262e3a2012-05-22 16:08:166918 TestCompletionCallback callback2;
bnc691fda62016-08-12 00:43:166919 rv = trans.RestartWithAuth(AuthCredentials(), callback2.callback());
robpercival214763f2016-07-01 23:27:016920 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2262e3a2012-05-22 16:08:166921 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:016922 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:166923 EXPECT_FALSE(trans.IsReadyToRestartForAuth());
[email protected]2262e3a2012-05-22 16:08:166924
bnc691fda62016-08-12 00:43:166925 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:526926 ASSERT_TRUE(response);
[email protected]2262e3a2012-05-22 16:08:166927 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
6928
6929 TestCompletionCallback callback3;
bnc691fda62016-08-12 00:43:166930 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar), callback3.callback());
robpercival214763f2016-07-01 23:27:016931 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2262e3a2012-05-22 16:08:166932 rv = callback3.WaitForResult();
robpercival214763f2016-07-01 23:27:016933 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:166934 EXPECT_FALSE(trans.IsReadyToRestartForAuth());
[email protected]2262e3a2012-05-22 16:08:166935
bnc691fda62016-08-12 00:43:166936 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:526937 ASSERT_TRUE(response);
[email protected]2262e3a2012-05-22 16:08:166938
6939 // There is no challenge info, since the identity worked.
wezca1070932016-05-26 20:30:526940 EXPECT_FALSE(response->auth_challenge);
[email protected]2262e3a2012-05-22 16:08:166941
6942 EXPECT_EQ(100, response->headers->GetContentLength());
6943
[email protected]ea9dc9a2009-09-05 00:43:326944 // Empty the current queue.
fdoray92e35a72016-06-10 15:54:556945 base::RunLoop().RunUntilIdle();
[email protected]ea9dc9a2009-09-05 00:43:326946}
6947
[email protected]2217aa22013-10-11 03:03:546948
6949// Test the request-challenge-retry sequence for basic auth when there is a
6950// correct identity in the URL, but its use is being suppressed. The identity
6951// from the URL should never be used.
bncd16676a2016-07-20 16:23:016952TEST_F(HttpNetworkTransactionTest, AuthIdentityInURLSuppressed) {
[email protected]2217aa22013-10-11 03:03:546953 HttpRequestInfo request;
6954 request.method = "GET";
bncce36dca22015-04-21 22:11:236955 request.url = GURL("http://foo:[email protected]/");
[email protected]2217aa22013-10-11 03:03:546956 request.load_flags = LOAD_DO_NOT_USE_EMBEDDED_IDENTITY;
6957
danakj1fd259a02016-04-16 03:17:096958 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:166959 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]2217aa22013-10-11 03:03:546960
6961 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:236962 MockWrite(
6963 "GET / HTTP/1.1\r\n"
6964 "Host: www.example.org\r\n"
6965 "Connection: keep-alive\r\n\r\n"),
[email protected]2217aa22013-10-11 03:03:546966 };
6967
6968 MockRead data_reads1[] = {
6969 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
6970 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
6971 MockRead("Content-Length: 10\r\n\r\n"),
6972 MockRead(SYNCHRONOUS, ERR_FAILED),
6973 };
6974
6975 // After the challenge above, the transaction will be restarted using the
6976 // identity supplied by the user, not the one in the URL, to answer the
6977 // challenge.
6978 MockWrite data_writes3[] = {
bncce36dca22015-04-21 22:11:236979 MockWrite(
6980 "GET / HTTP/1.1\r\n"
6981 "Host: www.example.org\r\n"
6982 "Connection: keep-alive\r\n"
6983 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]2217aa22013-10-11 03:03:546984 };
6985
6986 MockRead data_reads3[] = {
6987 MockRead("HTTP/1.0 200 OK\r\n"),
6988 MockRead("Content-Length: 100\r\n\r\n"),
6989 MockRead(SYNCHRONOUS, OK),
6990 };
6991
6992 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
6993 data_writes1, arraysize(data_writes1));
6994 StaticSocketDataProvider data3(data_reads3, arraysize(data_reads3),
6995 data_writes3, arraysize(data_writes3));
6996 session_deps_.socket_factory->AddSocketDataProvider(&data1);
6997 session_deps_.socket_factory->AddSocketDataProvider(&data3);
6998
6999 TestCompletionCallback callback1;
tfarina42834112016-09-22 13:38:207000 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:017001 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2217aa22013-10-11 03:03:547002 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:017003 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:167004 EXPECT_FALSE(trans.IsReadyToRestartForAuth());
[email protected]2217aa22013-10-11 03:03:547005
bnc691fda62016-08-12 00:43:167006 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:527007 ASSERT_TRUE(response);
[email protected]2217aa22013-10-11 03:03:547008 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
7009
7010 TestCompletionCallback callback3;
bnc691fda62016-08-12 00:43:167011 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar), callback3.callback());
robpercival214763f2016-07-01 23:27:017012 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2217aa22013-10-11 03:03:547013 rv = callback3.WaitForResult();
robpercival214763f2016-07-01 23:27:017014 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:167015 EXPECT_FALSE(trans.IsReadyToRestartForAuth());
[email protected]2217aa22013-10-11 03:03:547016
bnc691fda62016-08-12 00:43:167017 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:527018 ASSERT_TRUE(response);
[email protected]2217aa22013-10-11 03:03:547019
7020 // There is no challenge info, since the identity worked.
wezca1070932016-05-26 20:30:527021 EXPECT_FALSE(response->auth_challenge);
[email protected]2217aa22013-10-11 03:03:547022 EXPECT_EQ(100, response->headers->GetContentLength());
7023
7024 // Empty the current queue.
fdoray92e35a72016-06-10 15:54:557025 base::RunLoop().RunUntilIdle();
[email protected]2217aa22013-10-11 03:03:547026}
7027
[email protected]f9ee6b52008-11-08 06:46:237028// Test that previously tried username/passwords for a realm get re-used.
bncd16676a2016-07-20 16:23:017029TEST_F(HttpNetworkTransactionTest, BasicAuthCacheAndPreauth) {
danakj1fd259a02016-04-16 03:17:097030 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]f9ee6b52008-11-08 06:46:237031
7032 // Transaction 1: authenticate (foo, bar) on MyRealm1
7033 {
[email protected]1c773ea12009-04-28 19:58:427034 HttpRequestInfo request;
[email protected]f9ee6b52008-11-08 06:46:237035 request.method = "GET";
bncce36dca22015-04-21 22:11:237036 request.url = GURL("http://www.example.org/x/y/z");
[email protected]f9ee6b52008-11-08 06:46:237037
bnc691fda62016-08-12 00:43:167038 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:277039
[email protected]f9ee6b52008-11-08 06:46:237040 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:237041 MockWrite(
7042 "GET /x/y/z HTTP/1.1\r\n"
7043 "Host: www.example.org\r\n"
7044 "Connection: keep-alive\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:237045 };
7046
7047 MockRead data_reads1[] = {
7048 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
7049 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
7050 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067051 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]f9ee6b52008-11-08 06:46:237052 };
7053
7054 // Resend with authorization (username=foo, password=bar)
7055 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:237056 MockWrite(
7057 "GET /x/y/z HTTP/1.1\r\n"
7058 "Host: www.example.org\r\n"
7059 "Connection: keep-alive\r\n"
7060 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:237061 };
7062
7063 // Sever accepts the authorization.
7064 MockRead data_reads2[] = {
7065 MockRead("HTTP/1.0 200 OK\r\n"),
7066 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067067 MockRead(SYNCHRONOUS, OK),
[email protected]f9ee6b52008-11-08 06:46:237068 };
7069
[email protected]31a2bfe2010-02-09 08:03:397070 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
7071 data_writes1, arraysize(data_writes1));
7072 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
7073 data_writes2, arraysize(data_writes2));
[email protected]bb88e1d32013-05-03 23:11:077074 session_deps_.socket_factory->AddSocketDataProvider(&data1);
7075 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]f9ee6b52008-11-08 06:46:237076
[email protected]49639fa2011-12-20 23:22:417077 TestCompletionCallback callback1;
[email protected]f9ee6b52008-11-08 06:46:237078
tfarina42834112016-09-22 13:38:207079 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:017080 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]f9ee6b52008-11-08 06:46:237081
7082 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:017083 EXPECT_THAT(rv, IsOk());
[email protected]f9ee6b52008-11-08 06:46:237084
bnc691fda62016-08-12 00:43:167085 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:527086 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:047087 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]f9ee6b52008-11-08 06:46:237088
[email protected]49639fa2011-12-20 23:22:417089 TestCompletionCallback callback2;
[email protected]f9ee6b52008-11-08 06:46:237090
bnc691fda62016-08-12 00:43:167091 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar),
7092 callback2.callback());
robpercival214763f2016-07-01 23:27:017093 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]f9ee6b52008-11-08 06:46:237094
7095 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:017096 EXPECT_THAT(rv, IsOk());
[email protected]f9ee6b52008-11-08 06:46:237097
bnc691fda62016-08-12 00:43:167098 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:527099 ASSERT_TRUE(response);
7100 EXPECT_FALSE(response->auth_challenge);
[email protected]f9ee6b52008-11-08 06:46:237101 EXPECT_EQ(100, response->headers->GetContentLength());
7102 }
7103
7104 // ------------------------------------------------------------------------
7105
7106 // Transaction 2: authenticate (foo2, bar2) on MyRealm2
7107 {
[email protected]1c773ea12009-04-28 19:58:427108 HttpRequestInfo request;
[email protected]f9ee6b52008-11-08 06:46:237109 request.method = "GET";
7110 // Note that Transaction 1 was at /x/y/z, so this is in the same
7111 // protection space as MyRealm1.
bncce36dca22015-04-21 22:11:237112 request.url = GURL("http://www.example.org/x/y/a/b");
[email protected]f9ee6b52008-11-08 06:46:237113
bnc691fda62016-08-12 00:43:167114 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:277115
[email protected]f9ee6b52008-11-08 06:46:237116 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:237117 MockWrite(
7118 "GET /x/y/a/b HTTP/1.1\r\n"
7119 "Host: www.example.org\r\n"
7120 "Connection: keep-alive\r\n"
7121 // Send preemptive authorization for MyRealm1
7122 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:237123 };
7124
7125 // The server didn't like the preemptive authorization, and
7126 // challenges us for a different realm (MyRealm2).
7127 MockRead data_reads1[] = {
7128 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
7129 MockRead("WWW-Authenticate: Basic realm=\"MyRealm2\"\r\n"),
7130 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067131 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]f9ee6b52008-11-08 06:46:237132 };
7133
7134 // Resend with authorization for MyRealm2 (username=foo2, password=bar2)
7135 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:237136 MockWrite(
7137 "GET /x/y/a/b HTTP/1.1\r\n"
7138 "Host: www.example.org\r\n"
7139 "Connection: keep-alive\r\n"
7140 "Authorization: Basic Zm9vMjpiYXIy\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:237141 };
7142
7143 // Sever accepts the authorization.
7144 MockRead data_reads2[] = {
7145 MockRead("HTTP/1.0 200 OK\r\n"),
7146 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067147 MockRead(SYNCHRONOUS, OK),
[email protected]f9ee6b52008-11-08 06:46:237148 };
7149
[email protected]31a2bfe2010-02-09 08:03:397150 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
7151 data_writes1, arraysize(data_writes1));
7152 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
7153 data_writes2, arraysize(data_writes2));
[email protected]bb88e1d32013-05-03 23:11:077154 session_deps_.socket_factory->AddSocketDataProvider(&data1);
7155 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]f9ee6b52008-11-08 06:46:237156
[email protected]49639fa2011-12-20 23:22:417157 TestCompletionCallback callback1;
[email protected]f9ee6b52008-11-08 06:46:237158
tfarina42834112016-09-22 13:38:207159 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:017160 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]f9ee6b52008-11-08 06:46:237161
7162 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:017163 EXPECT_THAT(rv, IsOk());
[email protected]f9ee6b52008-11-08 06:46:237164
bnc691fda62016-08-12 00:43:167165 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:527166 ASSERT_TRUE(response);
7167 ASSERT_TRUE(response->auth_challenge);
[email protected]79cb5c12011-09-12 13:12:047168 EXPECT_FALSE(response->auth_challenge->is_proxy);
asanka098c0092016-06-16 20:18:437169 EXPECT_EQ("http://www.example.org",
7170 response->auth_challenge->challenger.Serialize());
[email protected]79cb5c12011-09-12 13:12:047171 EXPECT_EQ("MyRealm2", response->auth_challenge->realm);
aberentbba302d2015-12-03 10:20:197172 EXPECT_EQ(kBasicAuthScheme, response->auth_challenge->scheme);
[email protected]f9ee6b52008-11-08 06:46:237173
[email protected]49639fa2011-12-20 23:22:417174 TestCompletionCallback callback2;
[email protected]f9ee6b52008-11-08 06:46:237175
bnc691fda62016-08-12 00:43:167176 rv = trans.RestartWithAuth(AuthCredentials(kFoo2, kBar2),
7177 callback2.callback());
robpercival214763f2016-07-01 23:27:017178 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]f9ee6b52008-11-08 06:46:237179
7180 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:017181 EXPECT_THAT(rv, IsOk());
[email protected]f9ee6b52008-11-08 06:46:237182
bnc691fda62016-08-12 00:43:167183 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:527184 ASSERT_TRUE(response);
7185 EXPECT_FALSE(response->auth_challenge);
[email protected]f9ee6b52008-11-08 06:46:237186 EXPECT_EQ(100, response->headers->GetContentLength());
7187 }
7188
7189 // ------------------------------------------------------------------------
7190
7191 // Transaction 3: Resend a request in MyRealm's protection space --
7192 // succeed with preemptive authorization.
7193 {
[email protected]1c773ea12009-04-28 19:58:427194 HttpRequestInfo request;
[email protected]f9ee6b52008-11-08 06:46:237195 request.method = "GET";
bncce36dca22015-04-21 22:11:237196 request.url = GURL("http://www.example.org/x/y/z2");
[email protected]f9ee6b52008-11-08 06:46:237197
bnc691fda62016-08-12 00:43:167198 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:277199
[email protected]f9ee6b52008-11-08 06:46:237200 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:237201 MockWrite(
7202 "GET /x/y/z2 HTTP/1.1\r\n"
7203 "Host: www.example.org\r\n"
7204 "Connection: keep-alive\r\n"
7205 // The authorization for MyRealm1 gets sent preemptively
7206 // (since the url is in the same protection space)
7207 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:237208 };
7209
7210 // Sever accepts the preemptive authorization
7211 MockRead data_reads1[] = {
7212 MockRead("HTTP/1.0 200 OK\r\n"),
7213 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067214 MockRead(SYNCHRONOUS, OK),
[email protected]f9ee6b52008-11-08 06:46:237215 };
7216
[email protected]31a2bfe2010-02-09 08:03:397217 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
7218 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:077219 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]f9ee6b52008-11-08 06:46:237220
[email protected]49639fa2011-12-20 23:22:417221 TestCompletionCallback callback1;
[email protected]f9ee6b52008-11-08 06:46:237222
tfarina42834112016-09-22 13:38:207223 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:017224 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]f9ee6b52008-11-08 06:46:237225
7226 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:017227 EXPECT_THAT(rv, IsOk());
[email protected]f9ee6b52008-11-08 06:46:237228
bnc691fda62016-08-12 00:43:167229 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:527230 ASSERT_TRUE(response);
[email protected]f9ee6b52008-11-08 06:46:237231
wezca1070932016-05-26 20:30:527232 EXPECT_FALSE(response->auth_challenge);
[email protected]f9ee6b52008-11-08 06:46:237233 EXPECT_EQ(100, response->headers->GetContentLength());
7234 }
7235
7236 // ------------------------------------------------------------------------
7237
7238 // Transaction 4: request another URL in MyRealm (however the
7239 // url is not known to belong to the protection space, so no pre-auth).
7240 {
[email protected]1c773ea12009-04-28 19:58:427241 HttpRequestInfo request;
[email protected]f9ee6b52008-11-08 06:46:237242 request.method = "GET";
bncce36dca22015-04-21 22:11:237243 request.url = GURL("http://www.example.org/x/1");
[email protected]f9ee6b52008-11-08 06:46:237244
bnc691fda62016-08-12 00:43:167245 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:277246
[email protected]f9ee6b52008-11-08 06:46:237247 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:237248 MockWrite(
7249 "GET /x/1 HTTP/1.1\r\n"
7250 "Host: www.example.org\r\n"
7251 "Connection: keep-alive\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:237252 };
7253
7254 MockRead data_reads1[] = {
7255 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
7256 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
7257 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067258 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]f9ee6b52008-11-08 06:46:237259 };
7260
7261 // Resend with authorization from MyRealm's cache.
7262 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:237263 MockWrite(
7264 "GET /x/1 HTTP/1.1\r\n"
7265 "Host: www.example.org\r\n"
7266 "Connection: keep-alive\r\n"
7267 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:237268 };
7269
7270 // Sever accepts the authorization.
7271 MockRead data_reads2[] = {
7272 MockRead("HTTP/1.0 200 OK\r\n"),
7273 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067274 MockRead(SYNCHRONOUS, OK),
[email protected]f9ee6b52008-11-08 06:46:237275 };
7276
[email protected]31a2bfe2010-02-09 08:03:397277 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
7278 data_writes1, arraysize(data_writes1));
7279 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
7280 data_writes2, arraysize(data_writes2));
[email protected]bb88e1d32013-05-03 23:11:077281 session_deps_.socket_factory->AddSocketDataProvider(&data1);
7282 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]f9ee6b52008-11-08 06:46:237283
[email protected]49639fa2011-12-20 23:22:417284 TestCompletionCallback callback1;
[email protected]f9ee6b52008-11-08 06:46:237285
tfarina42834112016-09-22 13:38:207286 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:017287 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]f9ee6b52008-11-08 06:46:237288
7289 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:017290 EXPECT_THAT(rv, IsOk());
[email protected]f9ee6b52008-11-08 06:46:237291
bnc691fda62016-08-12 00:43:167292 EXPECT_TRUE(trans.IsReadyToRestartForAuth());
[email protected]49639fa2011-12-20 23:22:417293 TestCompletionCallback callback2;
bnc691fda62016-08-12 00:43:167294 rv = trans.RestartWithAuth(AuthCredentials(), callback2.callback());
robpercival214763f2016-07-01 23:27:017295 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]0757e7702009-03-27 04:00:227296 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:017297 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:167298 EXPECT_FALSE(trans.IsReadyToRestartForAuth());
[email protected]0757e7702009-03-27 04:00:227299
bnc691fda62016-08-12 00:43:167300 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:527301 ASSERT_TRUE(response);
7302 EXPECT_FALSE(response->auth_challenge);
[email protected]f9ee6b52008-11-08 06:46:237303 EXPECT_EQ(100, response->headers->GetContentLength());
7304 }
7305
7306 // ------------------------------------------------------------------------
7307
7308 // Transaction 5: request a URL in MyRealm, but the server rejects the
7309 // cached identity. Should invalidate and re-prompt.
7310 {
[email protected]1c773ea12009-04-28 19:58:427311 HttpRequestInfo request;
[email protected]f9ee6b52008-11-08 06:46:237312 request.method = "GET";
bncce36dca22015-04-21 22:11:237313 request.url = GURL("http://www.example.org/p/q/t");
[email protected]f9ee6b52008-11-08 06:46:237314
bnc691fda62016-08-12 00:43:167315 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:277316
[email protected]f9ee6b52008-11-08 06:46:237317 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:237318 MockWrite(
7319 "GET /p/q/t HTTP/1.1\r\n"
7320 "Host: www.example.org\r\n"
7321 "Connection: keep-alive\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:237322 };
7323
7324 MockRead data_reads1[] = {
7325 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
7326 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
7327 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067328 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]f9ee6b52008-11-08 06:46:237329 };
7330
7331 // Resend with authorization from cache for MyRealm.
7332 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:237333 MockWrite(
7334 "GET /p/q/t HTTP/1.1\r\n"
7335 "Host: www.example.org\r\n"
7336 "Connection: keep-alive\r\n"
7337 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:237338 };
7339
7340 // Sever rejects the authorization.
7341 MockRead data_reads2[] = {
7342 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
7343 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
7344 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067345 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]f9ee6b52008-11-08 06:46:237346 };
7347
7348 // At this point we should prompt for new credentials for MyRealm.
7349 // Restart with username=foo3, password=foo4.
7350 MockWrite data_writes3[] = {
bncce36dca22015-04-21 22:11:237351 MockWrite(
7352 "GET /p/q/t HTTP/1.1\r\n"
7353 "Host: www.example.org\r\n"
7354 "Connection: keep-alive\r\n"
7355 "Authorization: Basic Zm9vMzpiYXIz\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:237356 };
7357
7358 // Sever accepts the authorization.
7359 MockRead data_reads3[] = {
7360 MockRead("HTTP/1.0 200 OK\r\n"),
7361 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067362 MockRead(SYNCHRONOUS, OK),
[email protected]f9ee6b52008-11-08 06:46:237363 };
7364
[email protected]31a2bfe2010-02-09 08:03:397365 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
7366 data_writes1, arraysize(data_writes1));
7367 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
7368 data_writes2, arraysize(data_writes2));
7369 StaticSocketDataProvider data3(data_reads3, arraysize(data_reads3),
7370 data_writes3, arraysize(data_writes3));
[email protected]bb88e1d32013-05-03 23:11:077371 session_deps_.socket_factory->AddSocketDataProvider(&data1);
7372 session_deps_.socket_factory->AddSocketDataProvider(&data2);
7373 session_deps_.socket_factory->AddSocketDataProvider(&data3);
[email protected]f9ee6b52008-11-08 06:46:237374
[email protected]49639fa2011-12-20 23:22:417375 TestCompletionCallback callback1;
[email protected]f9ee6b52008-11-08 06:46:237376
tfarina42834112016-09-22 13:38:207377 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:017378 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]f9ee6b52008-11-08 06:46:237379
7380 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:017381 EXPECT_THAT(rv, IsOk());
[email protected]f9ee6b52008-11-08 06:46:237382
bnc691fda62016-08-12 00:43:167383 EXPECT_TRUE(trans.IsReadyToRestartForAuth());
[email protected]49639fa2011-12-20 23:22:417384 TestCompletionCallback callback2;
bnc691fda62016-08-12 00:43:167385 rv = trans.RestartWithAuth(AuthCredentials(), callback2.callback());
robpercival214763f2016-07-01 23:27:017386 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]0757e7702009-03-27 04:00:227387 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:017388 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:167389 EXPECT_FALSE(trans.IsReadyToRestartForAuth());
[email protected]0757e7702009-03-27 04:00:227390
bnc691fda62016-08-12 00:43:167391 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:527392 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:047393 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]f9ee6b52008-11-08 06:46:237394
[email protected]49639fa2011-12-20 23:22:417395 TestCompletionCallback callback3;
[email protected]f9ee6b52008-11-08 06:46:237396
bnc691fda62016-08-12 00:43:167397 rv = trans.RestartWithAuth(AuthCredentials(kFoo3, kBar3),
7398 callback3.callback());
robpercival214763f2016-07-01 23:27:017399 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]f9ee6b52008-11-08 06:46:237400
[email protected]0757e7702009-03-27 04:00:227401 rv = callback3.WaitForResult();
robpercival214763f2016-07-01 23:27:017402 EXPECT_THAT(rv, IsOk());
[email protected]f9ee6b52008-11-08 06:46:237403
bnc691fda62016-08-12 00:43:167404 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:527405 ASSERT_TRUE(response);
7406 EXPECT_FALSE(response->auth_challenge);
[email protected]f9ee6b52008-11-08 06:46:237407 EXPECT_EQ(100, response->headers->GetContentLength());
7408 }
7409}
[email protected]89ceba9a2009-03-21 03:46:067410
[email protected]3c32c5f2010-05-18 15:18:127411// Tests that nonce count increments when multiple auth attempts
7412// are started with the same nonce.
bncd16676a2016-07-20 16:23:017413TEST_F(HttpNetworkTransactionTest, DigestPreAuthNonceCount) {
[email protected]54fea2562010-11-17 14:40:447414 HttpAuthHandlerDigest::Factory* digest_factory =
7415 new HttpAuthHandlerDigest::Factory();
7416 HttpAuthHandlerDigest::FixedNonceGenerator* nonce_generator =
7417 new HttpAuthHandlerDigest::FixedNonceGenerator("0123456789abcdef");
7418 digest_factory->set_nonce_generator(nonce_generator);
[email protected]bb88e1d32013-05-03 23:11:077419 session_deps_.http_auth_handler_factory.reset(digest_factory);
danakj1fd259a02016-04-16 03:17:097420 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]3c32c5f2010-05-18 15:18:127421
7422 // Transaction 1: authenticate (foo, bar) on MyRealm1
7423 {
[email protected]3c32c5f2010-05-18 15:18:127424 HttpRequestInfo request;
7425 request.method = "GET";
bncce36dca22015-04-21 22:11:237426 request.url = GURL("http://www.example.org/x/y/z");
[email protected]3c32c5f2010-05-18 15:18:127427
bnc691fda62016-08-12 00:43:167428 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:277429
[email protected]3c32c5f2010-05-18 15:18:127430 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:237431 MockWrite(
7432 "GET /x/y/z HTTP/1.1\r\n"
7433 "Host: www.example.org\r\n"
7434 "Connection: keep-alive\r\n\r\n"),
[email protected]3c32c5f2010-05-18 15:18:127435 };
7436
7437 MockRead data_reads1[] = {
7438 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
7439 MockRead("WWW-Authenticate: Digest realm=\"digestive\", nonce=\"OU812\", "
7440 "algorithm=MD5, qop=\"auth\"\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067441 MockRead(SYNCHRONOUS, OK),
[email protected]3c32c5f2010-05-18 15:18:127442 };
7443
7444 // Resend with authorization (username=foo, password=bar)
7445 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:237446 MockWrite(
7447 "GET /x/y/z HTTP/1.1\r\n"
7448 "Host: www.example.org\r\n"
7449 "Connection: keep-alive\r\n"
7450 "Authorization: Digest username=\"foo\", realm=\"digestive\", "
7451 "nonce=\"OU812\", uri=\"/x/y/z\", algorithm=MD5, "
7452 "response=\"03ffbcd30add722589c1de345d7a927f\", qop=auth, "
7453 "nc=00000001, cnonce=\"0123456789abcdef\"\r\n\r\n"),
[email protected]3c32c5f2010-05-18 15:18:127454 };
7455
7456 // Sever accepts the authorization.
7457 MockRead data_reads2[] = {
zmo9528c9f42015-08-04 22:12:087458 MockRead("HTTP/1.0 200 OK\r\n"),
7459 MockRead(SYNCHRONOUS, OK),
[email protected]3c32c5f2010-05-18 15:18:127460 };
7461
7462 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
7463 data_writes1, arraysize(data_writes1));
7464 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
7465 data_writes2, arraysize(data_writes2));
[email protected]bb88e1d32013-05-03 23:11:077466 session_deps_.socket_factory->AddSocketDataProvider(&data1);
7467 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]3c32c5f2010-05-18 15:18:127468
[email protected]49639fa2011-12-20 23:22:417469 TestCompletionCallback callback1;
[email protected]3c32c5f2010-05-18 15:18:127470
tfarina42834112016-09-22 13:38:207471 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:017472 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]3c32c5f2010-05-18 15:18:127473
7474 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:017475 EXPECT_THAT(rv, IsOk());
[email protected]3c32c5f2010-05-18 15:18:127476
bnc691fda62016-08-12 00:43:167477 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:527478 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:047479 EXPECT_TRUE(CheckDigestServerAuth(response->auth_challenge.get()));
[email protected]3c32c5f2010-05-18 15:18:127480
[email protected]49639fa2011-12-20 23:22:417481 TestCompletionCallback callback2;
[email protected]3c32c5f2010-05-18 15:18:127482
bnc691fda62016-08-12 00:43:167483 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar),
7484 callback2.callback());
robpercival214763f2016-07-01 23:27:017485 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]3c32c5f2010-05-18 15:18:127486
7487 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:017488 EXPECT_THAT(rv, IsOk());
[email protected]3c32c5f2010-05-18 15:18:127489
bnc691fda62016-08-12 00:43:167490 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:527491 ASSERT_TRUE(response);
7492 EXPECT_FALSE(response->auth_challenge);
[email protected]3c32c5f2010-05-18 15:18:127493 }
7494
7495 // ------------------------------------------------------------------------
7496
7497 // Transaction 2: Request another resource in digestive's protection space.
7498 // This will preemptively add an Authorization header which should have an
7499 // "nc" value of 2 (as compared to 1 in the first use.
7500 {
[email protected]3c32c5f2010-05-18 15:18:127501 HttpRequestInfo request;
7502 request.method = "GET";
7503 // Note that Transaction 1 was at /x/y/z, so this is in the same
7504 // protection space as digest.
bncce36dca22015-04-21 22:11:237505 request.url = GURL("http://www.example.org/x/y/a/b");
[email protected]3c32c5f2010-05-18 15:18:127506
bnc691fda62016-08-12 00:43:167507 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:277508
[email protected]3c32c5f2010-05-18 15:18:127509 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:237510 MockWrite(
7511 "GET /x/y/a/b HTTP/1.1\r\n"
7512 "Host: www.example.org\r\n"
7513 "Connection: keep-alive\r\n"
7514 "Authorization: Digest username=\"foo\", realm=\"digestive\", "
7515 "nonce=\"OU812\", uri=\"/x/y/a/b\", algorithm=MD5, "
7516 "response=\"d6f9a2c07d1c5df7b89379dca1269b35\", qop=auth, "
7517 "nc=00000002, cnonce=\"0123456789abcdef\"\r\n\r\n"),
[email protected]3c32c5f2010-05-18 15:18:127518 };
7519
7520 // Sever accepts the authorization.
7521 MockRead data_reads1[] = {
7522 MockRead("HTTP/1.0 200 OK\r\n"),
7523 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067524 MockRead(SYNCHRONOUS, OK),
[email protected]3c32c5f2010-05-18 15:18:127525 };
7526
7527 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
7528 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:077529 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]3c32c5f2010-05-18 15:18:127530
[email protected]49639fa2011-12-20 23:22:417531 TestCompletionCallback callback1;
[email protected]3c32c5f2010-05-18 15:18:127532
tfarina42834112016-09-22 13:38:207533 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:017534 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]3c32c5f2010-05-18 15:18:127535
7536 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:017537 EXPECT_THAT(rv, IsOk());
[email protected]3c32c5f2010-05-18 15:18:127538
bnc691fda62016-08-12 00:43:167539 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:527540 ASSERT_TRUE(response);
7541 EXPECT_FALSE(response->auth_challenge);
[email protected]3c32c5f2010-05-18 15:18:127542 }
7543}
7544
[email protected]89ceba9a2009-03-21 03:46:067545// Test the ResetStateForRestart() private method.
bncd16676a2016-07-20 16:23:017546TEST_F(HttpNetworkTransactionTest, ResetStateForRestart) {
[email protected]89ceba9a2009-03-21 03:46:067547 // Create a transaction (the dependencies aren't important).
danakj1fd259a02016-04-16 03:17:097548 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:167549 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]89ceba9a2009-03-21 03:46:067550
7551 // Setup some state (which we expect ResetStateForRestart() will clear).
bnc691fda62016-08-12 00:43:167552 trans.read_buf_ = new IOBuffer(15);
7553 trans.read_buf_len_ = 15;
7554 trans.request_headers_.SetHeader("Authorization", "NTLM");
[email protected]89ceba9a2009-03-21 03:46:067555
7556 // Setup state in response_
bnc691fda62016-08-12 00:43:167557 HttpResponseInfo* response = &trans.response_;
[email protected]0877e3d2009-10-17 22:29:577558 response->auth_challenge = new AuthChallengeInfo();
[email protected]70d66502011-09-23 00:55:087559 response->ssl_info.cert_status = static_cast<CertStatus>(-1); // Nonsensical.
[email protected]0877e3d2009-10-17 22:29:577560 response->response_time = base::Time::Now();
7561 response->was_cached = true; // (Wouldn't ever actually be true...)
[email protected]89ceba9a2009-03-21 03:46:067562
7563 { // Setup state for response_.vary_data
7564 HttpRequestInfo request;
7565 std::string temp("HTTP/1.1 200 OK\nVary: foo, bar\n\n");
7566 std::replace(temp.begin(), temp.end(), '\n', '\0');
[email protected]ad8e04a2010-11-01 04:16:277567 scoped_refptr<HttpResponseHeaders> headers(new HttpResponseHeaders(temp));
[email protected]8c76ae22010-04-20 22:15:437568 request.extra_headers.SetHeader("Foo", "1");
7569 request.extra_headers.SetHeader("bar", "23");
[email protected]90499482013-06-01 00:39:507570 EXPECT_TRUE(response->vary_data.Init(request, *headers.get()));
[email protected]89ceba9a2009-03-21 03:46:067571 }
7572
7573 // Cause the above state to be reset.
bnc691fda62016-08-12 00:43:167574 trans.ResetStateForRestart();
[email protected]89ceba9a2009-03-21 03:46:067575
7576 // Verify that the state that needed to be reset, has been reset.
bnc691fda62016-08-12 00:43:167577 EXPECT_FALSE(trans.read_buf_);
7578 EXPECT_EQ(0, trans.read_buf_len_);
7579 EXPECT_TRUE(trans.request_headers_.IsEmpty());
wezca1070932016-05-26 20:30:527580 EXPECT_FALSE(response->auth_challenge);
7581 EXPECT_FALSE(response->headers);
[email protected]34f40942010-10-04 00:34:047582 EXPECT_FALSE(response->was_cached);
[email protected]70d66502011-09-23 00:55:087583 EXPECT_EQ(0U, response->ssl_info.cert_status);
[email protected]0877e3d2009-10-17 22:29:577584 EXPECT_FALSE(response->vary_data.is_valid());
[email protected]89ceba9a2009-03-21 03:46:067585}
7586
[email protected]bacff652009-03-31 17:50:337587// Test HTTPS connections to a site with a bad certificate
bncd16676a2016-07-20 16:23:017588TEST_F(HttpNetworkTransactionTest, HTTPSBadCertificate) {
[email protected]bacff652009-03-31 17:50:337589 HttpRequestInfo request;
7590 request.method = "GET";
bncce36dca22015-04-21 22:11:237591 request.url = GURL("https://www.example.org/");
[email protected]bacff652009-03-31 17:50:337592
danakj1fd259a02016-04-16 03:17:097593 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:167594 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:277595
[email protected]bacff652009-03-31 17:50:337596 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:237597 MockWrite(
7598 "GET / HTTP/1.1\r\n"
7599 "Host: www.example.org\r\n"
7600 "Connection: keep-alive\r\n\r\n"),
[email protected]bacff652009-03-31 17:50:337601 };
7602
7603 MockRead data_reads[] = {
7604 MockRead("HTTP/1.0 200 OK\r\n"),
7605 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
7606 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067607 MockRead(SYNCHRONOUS, OK),
[email protected]bacff652009-03-31 17:50:337608 };
7609
[email protected]5ecc992a42009-11-11 01:41:597610 StaticSocketDataProvider ssl_bad_certificate;
[email protected]31a2bfe2010-02-09 08:03:397611 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
7612 data_writes, arraysize(data_writes));
[email protected]8ddf8322012-02-23 18:08:067613 SSLSocketDataProvider ssl_bad(ASYNC, ERR_CERT_AUTHORITY_INVALID);
7614 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bacff652009-03-31 17:50:337615
[email protected]bb88e1d32013-05-03 23:11:077616 session_deps_.socket_factory->AddSocketDataProvider(&ssl_bad_certificate);
7617 session_deps_.socket_factory->AddSocketDataProvider(&data);
7618 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_bad);
7619 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]bacff652009-03-31 17:50:337620
[email protected]49639fa2011-12-20 23:22:417621 TestCompletionCallback callback;
[email protected]bacff652009-03-31 17:50:337622
tfarina42834112016-09-22 13:38:207623 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:017624 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]bacff652009-03-31 17:50:337625
7626 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:017627 EXPECT_THAT(rv, IsError(ERR_CERT_AUTHORITY_INVALID));
[email protected]bacff652009-03-31 17:50:337628
bnc691fda62016-08-12 00:43:167629 rv = trans.RestartIgnoringLastError(callback.callback());
robpercival214763f2016-07-01 23:27:017630 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]bacff652009-03-31 17:50:337631
7632 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:017633 EXPECT_THAT(rv, IsOk());
[email protected]bacff652009-03-31 17:50:337634
bnc691fda62016-08-12 00:43:167635 const HttpResponseInfo* response = trans.GetResponseInfo();
[email protected]bacff652009-03-31 17:50:337636
wezca1070932016-05-26 20:30:527637 ASSERT_TRUE(response);
[email protected]bacff652009-03-31 17:50:337638 EXPECT_EQ(100, response->headers->GetContentLength());
7639}
7640
7641// Test HTTPS connections to a site with a bad certificate, going through a
7642// proxy
bncd16676a2016-07-20 16:23:017643TEST_F(HttpNetworkTransactionTest, HTTPSBadCertificateViaProxy) {
rdsmith82957ad2015-09-16 19:42:037644 session_deps_.proxy_service = ProxyService::CreateFixed("myproxy:70");
[email protected]bacff652009-03-31 17:50:337645
7646 HttpRequestInfo request;
7647 request.method = "GET";
bncce36dca22015-04-21 22:11:237648 request.url = GURL("https://www.example.org/");
[email protected]bacff652009-03-31 17:50:337649
7650 MockWrite proxy_writes[] = {
rsleevidb16bb02015-11-12 23:47:177651 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
7652 "Host: www.example.org:443\r\n"
7653 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]bacff652009-03-31 17:50:337654 };
7655
7656 MockRead proxy_reads[] = {
7657 MockRead("HTTP/1.0 200 Connected\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067658 MockRead(SYNCHRONOUS, OK)
[email protected]bacff652009-03-31 17:50:337659 };
7660
7661 MockWrite data_writes[] = {
rsleevidb16bb02015-11-12 23:47:177662 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
7663 "Host: www.example.org:443\r\n"
7664 "Proxy-Connection: keep-alive\r\n\r\n"),
7665 MockWrite("GET / HTTP/1.1\r\n"
7666 "Host: www.example.org\r\n"
7667 "Connection: keep-alive\r\n\r\n"),
[email protected]bacff652009-03-31 17:50:337668 };
7669
7670 MockRead data_reads[] = {
7671 MockRead("HTTP/1.0 200 Connected\r\n\r\n"),
7672 MockRead("HTTP/1.0 200 OK\r\n"),
7673 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
7674 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067675 MockRead(SYNCHRONOUS, OK),
[email protected]bacff652009-03-31 17:50:337676 };
7677
[email protected]31a2bfe2010-02-09 08:03:397678 StaticSocketDataProvider ssl_bad_certificate(
7679 proxy_reads, arraysize(proxy_reads),
7680 proxy_writes, arraysize(proxy_writes));
7681 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
7682 data_writes, arraysize(data_writes));
[email protected]8ddf8322012-02-23 18:08:067683 SSLSocketDataProvider ssl_bad(ASYNC, ERR_CERT_AUTHORITY_INVALID);
7684 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bacff652009-03-31 17:50:337685
[email protected]bb88e1d32013-05-03 23:11:077686 session_deps_.socket_factory->AddSocketDataProvider(&ssl_bad_certificate);
7687 session_deps_.socket_factory->AddSocketDataProvider(&data);
7688 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_bad);
7689 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]bacff652009-03-31 17:50:337690
[email protected]49639fa2011-12-20 23:22:417691 TestCompletionCallback callback;
[email protected]bacff652009-03-31 17:50:337692
7693 for (int i = 0; i < 2; i++) {
[email protected]bb88e1d32013-05-03 23:11:077694 session_deps_.socket_factory->ResetNextMockIndexes();
[email protected]bacff652009-03-31 17:50:337695
danakj1fd259a02016-04-16 03:17:097696 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:167697 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]bacff652009-03-31 17:50:337698
tfarina42834112016-09-22 13:38:207699 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:017700 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]bacff652009-03-31 17:50:337701
7702 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:017703 EXPECT_THAT(rv, IsError(ERR_CERT_AUTHORITY_INVALID));
[email protected]bacff652009-03-31 17:50:337704
bnc691fda62016-08-12 00:43:167705 rv = trans.RestartIgnoringLastError(callback.callback());
robpercival214763f2016-07-01 23:27:017706 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]bacff652009-03-31 17:50:337707
7708 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:017709 EXPECT_THAT(rv, IsOk());
[email protected]bacff652009-03-31 17:50:337710
bnc691fda62016-08-12 00:43:167711 const HttpResponseInfo* response = trans.GetResponseInfo();
[email protected]bacff652009-03-31 17:50:337712
wezca1070932016-05-26 20:30:527713 ASSERT_TRUE(response);
[email protected]bacff652009-03-31 17:50:337714 EXPECT_EQ(100, response->headers->GetContentLength());
7715 }
7716}
7717
[email protected]2df19bb2010-08-25 20:13:467718
7719// Test HTTPS connections to a site, going through an HTTPS proxy
bncd16676a2016-07-20 16:23:017720TEST_F(HttpNetworkTransactionTest, HTTPSViaHttpsProxy) {
rdsmith82957ad2015-09-16 19:42:037721 session_deps_.proxy_service =
7722 ProxyService::CreateFixedFromPacResult("HTTPS proxy:70");
vishal.b62985ca92015-04-17 08:45:517723 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:077724 session_deps_.net_log = &net_log;
[email protected]2df19bb2010-08-25 20:13:467725
7726 HttpRequestInfo request;
7727 request.method = "GET";
bncce36dca22015-04-21 22:11:237728 request.url = GURL("https://www.example.org/");
[email protected]2df19bb2010-08-25 20:13:467729
7730 MockWrite data_writes[] = {
rsleevidb16bb02015-11-12 23:47:177731 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
7732 "Host: www.example.org:443\r\n"
7733 "Proxy-Connection: keep-alive\r\n\r\n"),
7734 MockWrite("GET / HTTP/1.1\r\n"
7735 "Host: www.example.org\r\n"
7736 "Connection: keep-alive\r\n\r\n"),
[email protected]2df19bb2010-08-25 20:13:467737 };
7738
7739 MockRead data_reads[] = {
7740 MockRead("HTTP/1.0 200 Connected\r\n\r\n"),
7741 MockRead("HTTP/1.1 200 OK\r\n"),
7742 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
7743 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067744 MockRead(SYNCHRONOUS, OK),
[email protected]2df19bb2010-08-25 20:13:467745 };
7746
7747 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
7748 data_writes, arraysize(data_writes));
[email protected]8ddf8322012-02-23 18:08:067749 SSLSocketDataProvider proxy_ssl(ASYNC, OK); // SSL to the proxy
7750 SSLSocketDataProvider tunnel_ssl(ASYNC, OK); // SSL through the tunnel
[email protected]2df19bb2010-08-25 20:13:467751
[email protected]bb88e1d32013-05-03 23:11:077752 session_deps_.socket_factory->AddSocketDataProvider(&data);
7753 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy_ssl);
7754 session_deps_.socket_factory->AddSSLSocketDataProvider(&tunnel_ssl);
[email protected]2df19bb2010-08-25 20:13:467755
[email protected]49639fa2011-12-20 23:22:417756 TestCompletionCallback callback;
[email protected]2df19bb2010-08-25 20:13:467757
danakj1fd259a02016-04-16 03:17:097758 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:167759 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]2df19bb2010-08-25 20:13:467760
tfarina42834112016-09-22 13:38:207761 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:017762 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2df19bb2010-08-25 20:13:467763
7764 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:017765 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:167766 const HttpResponseInfo* response = trans.GetResponseInfo();
[email protected]2df19bb2010-08-25 20:13:467767
wezca1070932016-05-26 20:30:527768 ASSERT_TRUE(response);
[email protected]2df19bb2010-08-25 20:13:467769
tbansal2ecbbc72016-10-06 17:15:477770 EXPECT_TRUE(response->proxy_server.is_https());
[email protected]2df19bb2010-08-25 20:13:467771 EXPECT_TRUE(response->headers->IsKeepAlive());
7772 EXPECT_EQ(200, response->headers->response_code());
7773 EXPECT_EQ(100, response->headers->GetContentLength());
7774 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
[email protected]029c83b62013-01-24 05:28:207775
7776 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:167777 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]029c83b62013-01-24 05:28:207778 TestLoadTimingNotReusedWithPac(load_timing_info,
7779 CONNECT_TIMING_HAS_SSL_TIMES);
[email protected]2df19bb2010-08-25 20:13:467780}
7781
[email protected]511f6f52010-12-17 03:58:297782// Test an HTTPS Proxy's ability to redirect a CONNECT request
bncd16676a2016-07-20 16:23:017783TEST_F(HttpNetworkTransactionTest, RedirectOfHttpsConnectViaHttpsProxy) {
rdsmith82957ad2015-09-16 19:42:037784 session_deps_.proxy_service =
7785 ProxyService::CreateFixedFromPacResult("HTTPS proxy:70");
vishal.b62985ca92015-04-17 08:45:517786 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:077787 session_deps_.net_log = &net_log;
[email protected]511f6f52010-12-17 03:58:297788
7789 HttpRequestInfo request;
7790 request.method = "GET";
bncce36dca22015-04-21 22:11:237791 request.url = GURL("https://www.example.org/");
[email protected]511f6f52010-12-17 03:58:297792
7793 MockWrite data_writes[] = {
rsleevidb16bb02015-11-12 23:47:177794 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
7795 "Host: www.example.org:443\r\n"
7796 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]511f6f52010-12-17 03:58:297797 };
7798
7799 MockRead data_reads[] = {
7800 MockRead("HTTP/1.1 302 Redirect\r\n"),
7801 MockRead("Location: http://login.example.com/\r\n"),
7802 MockRead("Content-Length: 0\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067803 MockRead(SYNCHRONOUS, OK),
[email protected]511f6f52010-12-17 03:58:297804 };
7805
7806 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
7807 data_writes, arraysize(data_writes));
[email protected]8ddf8322012-02-23 18:08:067808 SSLSocketDataProvider proxy_ssl(ASYNC, OK); // SSL to the proxy
[email protected]511f6f52010-12-17 03:58:297809
[email protected]bb88e1d32013-05-03 23:11:077810 session_deps_.socket_factory->AddSocketDataProvider(&data);
7811 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy_ssl);
[email protected]511f6f52010-12-17 03:58:297812
[email protected]49639fa2011-12-20 23:22:417813 TestCompletionCallback callback;
[email protected]511f6f52010-12-17 03:58:297814
danakj1fd259a02016-04-16 03:17:097815 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:167816 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]511f6f52010-12-17 03:58:297817
tfarina42834112016-09-22 13:38:207818 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:017819 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]511f6f52010-12-17 03:58:297820
7821 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:017822 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:167823 const HttpResponseInfo* response = trans.GetResponseInfo();
[email protected]511f6f52010-12-17 03:58:297824
wezca1070932016-05-26 20:30:527825 ASSERT_TRUE(response);
[email protected]511f6f52010-12-17 03:58:297826
7827 EXPECT_EQ(302, response->headers->response_code());
7828 std::string url;
7829 EXPECT_TRUE(response->headers->IsRedirect(&url));
7830 EXPECT_EQ("http://login.example.com/", url);
[email protected]029c83b62013-01-24 05:28:207831
7832 // In the case of redirects from proxies, HttpNetworkTransaction returns
7833 // timing for the proxy connection instead of the connection to the host,
7834 // and no send / receive times.
7835 // See HttpNetworkTransaction::OnHttpsProxyTunnelResponse.
7836 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:167837 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]029c83b62013-01-24 05:28:207838
7839 EXPECT_FALSE(load_timing_info.socket_reused);
mikecironef22f9812016-10-04 03:40:197840 EXPECT_NE(NetLogSource::kInvalidId, load_timing_info.socket_log_id);
[email protected]029c83b62013-01-24 05:28:207841
7842 EXPECT_FALSE(load_timing_info.proxy_resolve_start.is_null());
7843 EXPECT_LE(load_timing_info.proxy_resolve_start,
7844 load_timing_info.proxy_resolve_end);
7845 EXPECT_LE(load_timing_info.proxy_resolve_end,
7846 load_timing_info.connect_timing.connect_start);
7847 ExpectConnectTimingHasTimes(
7848 load_timing_info.connect_timing,
7849 CONNECT_TIMING_HAS_DNS_TIMES | CONNECT_TIMING_HAS_SSL_TIMES);
7850
7851 EXPECT_TRUE(load_timing_info.send_start.is_null());
7852 EXPECT_TRUE(load_timing_info.send_end.is_null());
7853 EXPECT_TRUE(load_timing_info.receive_headers_end.is_null());
[email protected]511f6f52010-12-17 03:58:297854}
7855
7856// Test an HTTPS (SPDY) Proxy's ability to redirect a CONNECT request
bncd16676a2016-07-20 16:23:017857TEST_F(HttpNetworkTransactionTest, RedirectOfHttpsConnectViaSpdyProxy) {
rdsmith82957ad2015-09-16 19:42:037858 session_deps_.proxy_service = ProxyService::CreateFixed("https://proxy:70");
[email protected]511f6f52010-12-17 03:58:297859
7860 HttpRequestInfo request;
7861 request.method = "GET";
bncce36dca22015-04-21 22:11:237862 request.url = GURL("https://www.example.org/");
[email protected]511f6f52010-12-17 03:58:297863
bncdf80d44fd2016-07-15 20:27:417864 SpdySerializedFrame conn(spdy_util_.ConstructSpdyConnect(
bncce36dca22015-04-21 22:11:237865 NULL, 0, 1, LOWEST, HostPortPair("www.example.org", 443)));
bncdf80d44fd2016-07-15 20:27:417866 SpdySerializedFrame goaway(
diannahu9904e272017-02-03 14:40:087867 spdy_util_.ConstructSpdyRstStream(1, ERROR_CODE_CANCEL));
[email protected]511f6f52010-12-17 03:58:297868 MockWrite data_writes[] = {
bncdf80d44fd2016-07-15 20:27:417869 CreateMockWrite(conn, 0, SYNCHRONOUS),
7870 CreateMockWrite(goaway, 2, SYNCHRONOUS),
[email protected]511f6f52010-12-17 03:58:297871 };
7872
7873 static const char* const kExtraHeaders[] = {
7874 "location",
7875 "http://login.example.com/",
7876 };
bnc42331402016-07-25 13:36:157877 SpdySerializedFrame resp(spdy_util_.ConstructSpdyReplyError(
bncc9f762a2016-12-06 20:38:237878 "302", kExtraHeaders, arraysize(kExtraHeaders) / 2, 1));
[email protected]511f6f52010-12-17 03:58:297879 MockRead data_reads[] = {
bncdf80d44fd2016-07-15 20:27:417880 CreateMockRead(resp, 1), MockRead(ASYNC, 0, 3), // EOF
[email protected]511f6f52010-12-17 03:58:297881 };
7882
rch8e6c6c42015-05-01 14:05:137883 SequencedSocketData data(data_reads, arraysize(data_reads), data_writes,
7884 arraysize(data_writes));
[email protected]8ddf8322012-02-23 18:08:067885 SSLSocketDataProvider proxy_ssl(ASYNC, OK); // SSL to the proxy
bnc3cf2a592016-08-11 14:48:367886 proxy_ssl.next_proto = kProtoHTTP2;
[email protected]511f6f52010-12-17 03:58:297887
[email protected]bb88e1d32013-05-03 23:11:077888 session_deps_.socket_factory->AddSocketDataProvider(&data);
7889 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy_ssl);
[email protected]511f6f52010-12-17 03:58:297890
[email protected]49639fa2011-12-20 23:22:417891 TestCompletionCallback callback;
[email protected]511f6f52010-12-17 03:58:297892
danakj1fd259a02016-04-16 03:17:097893 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:167894 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]511f6f52010-12-17 03:58:297895
tfarina42834112016-09-22 13:38:207896 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:017897 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]511f6f52010-12-17 03:58:297898
7899 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:017900 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:167901 const HttpResponseInfo* response = trans.GetResponseInfo();
[email protected]511f6f52010-12-17 03:58:297902
wezca1070932016-05-26 20:30:527903 ASSERT_TRUE(response);
[email protected]511f6f52010-12-17 03:58:297904
7905 EXPECT_EQ(302, response->headers->response_code());
7906 std::string url;
7907 EXPECT_TRUE(response->headers->IsRedirect(&url));
7908 EXPECT_EQ("http://login.example.com/", url);
7909}
7910
[email protected]4eddbc732012-08-09 05:40:177911// Test that an HTTPS proxy's response to a CONNECT request is filtered.
bncd16676a2016-07-20 16:23:017912TEST_F(HttpNetworkTransactionTest, ErrorResponseToHttpsConnectViaHttpsProxy) {
rdsmith82957ad2015-09-16 19:42:037913 session_deps_.proxy_service = ProxyService::CreateFixed("https://proxy:70");
[email protected]511f6f52010-12-17 03:58:297914
7915 HttpRequestInfo request;
7916 request.method = "GET";
bncce36dca22015-04-21 22:11:237917 request.url = GURL("https://www.example.org/");
[email protected]511f6f52010-12-17 03:58:297918
7919 MockWrite data_writes[] = {
rsleevidb16bb02015-11-12 23:47:177920 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
7921 "Host: www.example.org:443\r\n"
7922 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]511f6f52010-12-17 03:58:297923 };
7924
7925 MockRead data_reads[] = {
7926 MockRead("HTTP/1.1 404 Not Found\r\n"),
7927 MockRead("Content-Length: 23\r\n\r\n"),
7928 MockRead("The host does not exist"),
[email protected]8ddf8322012-02-23 18:08:067929 MockRead(SYNCHRONOUS, OK),
[email protected]511f6f52010-12-17 03:58:297930 };
7931
7932 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
7933 data_writes, arraysize(data_writes));
[email protected]8ddf8322012-02-23 18:08:067934 SSLSocketDataProvider proxy_ssl(ASYNC, OK); // SSL to the proxy
[email protected]511f6f52010-12-17 03:58:297935
[email protected]bb88e1d32013-05-03 23:11:077936 session_deps_.socket_factory->AddSocketDataProvider(&data);
7937 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy_ssl);
[email protected]511f6f52010-12-17 03:58:297938
[email protected]49639fa2011-12-20 23:22:417939 TestCompletionCallback callback;
[email protected]511f6f52010-12-17 03:58:297940
danakj1fd259a02016-04-16 03:17:097941 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:167942 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]511f6f52010-12-17 03:58:297943
tfarina42834112016-09-22 13:38:207944 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:017945 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]511f6f52010-12-17 03:58:297946
7947 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:017948 EXPECT_THAT(rv, IsError(ERR_TUNNEL_CONNECTION_FAILED));
[email protected]511f6f52010-12-17 03:58:297949
ttuttle960fcbf2016-04-19 13:26:327950 // TODO(juliatuttle): Anything else to check here?
[email protected]511f6f52010-12-17 03:58:297951}
7952
[email protected]4eddbc732012-08-09 05:40:177953// Test that a SPDY proxy's response to a CONNECT request is filtered.
bncd16676a2016-07-20 16:23:017954TEST_F(HttpNetworkTransactionTest, ErrorResponseToHttpsConnectViaSpdyProxy) {
rdsmith82957ad2015-09-16 19:42:037955 session_deps_.proxy_service = ProxyService::CreateFixed("https://proxy:70");
[email protected]511f6f52010-12-17 03:58:297956
7957 HttpRequestInfo request;
7958 request.method = "GET";
bncce36dca22015-04-21 22:11:237959 request.url = GURL("https://www.example.org/");
[email protected]511f6f52010-12-17 03:58:297960
bncdf80d44fd2016-07-15 20:27:417961 SpdySerializedFrame conn(spdy_util_.ConstructSpdyConnect(
bncce36dca22015-04-21 22:11:237962 NULL, 0, 1, LOWEST, HostPortPair("www.example.org", 443)));
bncdf80d44fd2016-07-15 20:27:417963 SpdySerializedFrame rst(
diannahu9904e272017-02-03 14:40:087964 spdy_util_.ConstructSpdyRstStream(1, ERROR_CODE_CANCEL));
[email protected]511f6f52010-12-17 03:58:297965 MockWrite data_writes[] = {
bncdf80d44fd2016-07-15 20:27:417966 CreateMockWrite(conn, 0), CreateMockWrite(rst, 3),
[email protected]511f6f52010-12-17 03:58:297967 };
7968
7969 static const char* const kExtraHeaders[] = {
7970 "location",
7971 "http://login.example.com/",
7972 };
bnc42331402016-07-25 13:36:157973 SpdySerializedFrame resp(spdy_util_.ConstructSpdyReplyError(
bncc9f762a2016-12-06 20:38:237974 "404", kExtraHeaders, arraysize(kExtraHeaders) / 2, 1));
bncdf80d44fd2016-07-15 20:27:417975 SpdySerializedFrame body(spdy_util_.ConstructSpdyDataFrame(
bncb03b1092016-04-06 11:19:557976 1, "The host does not exist", 23, true));
[email protected]511f6f52010-12-17 03:58:297977 MockRead data_reads[] = {
bncdf80d44fd2016-07-15 20:27:417978 CreateMockRead(resp, 1), CreateMockRead(body, 2),
rch8e6c6c42015-05-01 14:05:137979 MockRead(ASYNC, 0, 4), // EOF
[email protected]511f6f52010-12-17 03:58:297980 };
7981
rch8e6c6c42015-05-01 14:05:137982 SequencedSocketData data(data_reads, arraysize(data_reads), data_writes,
7983 arraysize(data_writes));
[email protected]8ddf8322012-02-23 18:08:067984 SSLSocketDataProvider proxy_ssl(ASYNC, OK); // SSL to the proxy
bnc3cf2a592016-08-11 14:48:367985 proxy_ssl.next_proto = kProtoHTTP2;
[email protected]511f6f52010-12-17 03:58:297986
[email protected]bb88e1d32013-05-03 23:11:077987 session_deps_.socket_factory->AddSocketDataProvider(&data);
7988 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy_ssl);
[email protected]511f6f52010-12-17 03:58:297989
[email protected]49639fa2011-12-20 23:22:417990 TestCompletionCallback callback;
[email protected]511f6f52010-12-17 03:58:297991
danakj1fd259a02016-04-16 03:17:097992 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:167993 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]511f6f52010-12-17 03:58:297994
tfarina42834112016-09-22 13:38:207995 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:017996 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]511f6f52010-12-17 03:58:297997
7998 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:017999 EXPECT_THAT(rv, IsError(ERR_TUNNEL_CONNECTION_FAILED));
[email protected]511f6f52010-12-17 03:58:298000
ttuttle960fcbf2016-04-19 13:26:328001 // TODO(juliatuttle): Anything else to check here?
[email protected]511f6f52010-12-17 03:58:298002}
8003
[email protected]0c5fb722012-02-28 11:50:358004// Test the request-challenge-retry sequence for basic auth, through
8005// a SPDY proxy over a single SPDY session.
bncd16676a2016-07-20 16:23:018006TEST_F(HttpNetworkTransactionTest, BasicAuthSpdyProxy) {
[email protected]0c5fb722012-02-28 11:50:358007 HttpRequestInfo request;
8008 request.method = "GET";
bncce36dca22015-04-21 22:11:238009 request.url = GURL("https://www.example.org/");
[email protected]0c5fb722012-02-28 11:50:358010 // when the no authentication data flag is set.
ttuttle859dc7a2015-04-23 19:42:298011 request.load_flags = LOAD_DO_NOT_SEND_AUTH_DATA;
[email protected]0c5fb722012-02-28 11:50:358012
8013 // Configure against https proxy server "myproxy:70".
rdsmith82957ad2015-09-16 19:42:038014 session_deps_.proxy_service =
8015 ProxyService::CreateFixedFromPacResult("HTTPS myproxy:70");
vishal.b62985ca92015-04-17 08:45:518016 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:078017 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:098018 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]0c5fb722012-02-28 11:50:358019
8020 // Since we have proxy, should try to establish tunnel.
bncdf80d44fd2016-07-15 20:27:418021 SpdySerializedFrame req(spdy_util_.ConstructSpdyConnect(
bncce36dca22015-04-21 22:11:238022 NULL, 0, 1, LOWEST, HostPortPair("www.example.org", 443)));
bncdf80d44fd2016-07-15 20:27:418023 SpdySerializedFrame rst(
diannahu9904e272017-02-03 14:40:088024 spdy_util_.ConstructSpdyRstStream(1, ERROR_CODE_CANCEL));
rdsmithebb50aa2015-11-12 03:44:388025 spdy_util_.UpdateWithStreamDestruction(1);
[email protected]0c5fb722012-02-28 11:50:358026
bnc691fda62016-08-12 00:43:168027 // After calling trans.RestartWithAuth(), this is the request we should
[email protected]0c5fb722012-02-28 11:50:358028 // be issuing -- the final header line contains the credentials.
8029 const char* const kAuthCredentials[] = {
8030 "proxy-authorization", "Basic Zm9vOmJhcg==",
8031 };
bncdf80d44fd2016-07-15 20:27:418032 SpdySerializedFrame connect2(spdy_util_.ConstructSpdyConnect(
lgarrona91df87f2014-12-05 00:51:348033 kAuthCredentials, arraysize(kAuthCredentials) / 2, 3, LOWEST,
bncce36dca22015-04-21 22:11:238034 HostPortPair("www.example.org", 443)));
8035 // fetch https://www.example.org/ via HTTP
8036 const char get[] =
8037 "GET / HTTP/1.1\r\n"
8038 "Host: www.example.org\r\n"
8039 "Connection: keep-alive\r\n\r\n";
bncdf80d44fd2016-07-15 20:27:418040 SpdySerializedFrame wrapped_get(
8041 spdy_util_.ConstructSpdyDataFrame(3, get, strlen(get), false));
[email protected]0c5fb722012-02-28 11:50:358042
8043 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:418044 CreateMockWrite(req, 0, ASYNC), CreateMockWrite(rst, 2, ASYNC),
8045 CreateMockWrite(connect2, 3), CreateMockWrite(wrapped_get, 5),
[email protected]0c5fb722012-02-28 11:50:358046 };
8047
8048 // The proxy responds to the connect with a 407, using a persistent
8049 // connection.
thestig9d3bb0c2015-01-24 00:49:518050 const char kAuthStatus[] = "407";
[email protected]0c5fb722012-02-28 11:50:358051 const char* const kAuthChallenge[] = {
[email protected]0c5fb722012-02-28 11:50:358052 "proxy-authenticate", "Basic realm=\"MyRealm1\"",
8053 };
bnc42331402016-07-25 13:36:158054 SpdySerializedFrame conn_auth_resp(spdy_util_.ConstructSpdyReplyError(
bncdf80d44fd2016-07-15 20:27:418055 kAuthStatus, kAuthChallenge, arraysize(kAuthChallenge) / 2, 1));
[email protected]0c5fb722012-02-28 11:50:358056
bnc42331402016-07-25 13:36:158057 SpdySerializedFrame conn_resp(spdy_util_.ConstructSpdyGetReply(NULL, 0, 3));
[email protected]0c5fb722012-02-28 11:50:358058 const char resp[] = "HTTP/1.1 200 OK\r\n"
8059 "Content-Length: 5\r\n\r\n";
8060
bncdf80d44fd2016-07-15 20:27:418061 SpdySerializedFrame wrapped_get_resp(
8062 spdy_util_.ConstructSpdyDataFrame(3, resp, strlen(resp), false));
8063 SpdySerializedFrame wrapped_body(
8064 spdy_util_.ConstructSpdyDataFrame(3, "hello", 5, false));
[email protected]0c5fb722012-02-28 11:50:358065 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:418066 CreateMockRead(conn_auth_resp, 1, ASYNC),
8067 CreateMockRead(conn_resp, 4, ASYNC),
8068 CreateMockRead(wrapped_get_resp, 6, ASYNC),
8069 CreateMockRead(wrapped_body, 7, ASYNC),
rch8e6c6c42015-05-01 14:05:138070 MockRead(ASYNC, OK, 8), // EOF. May or may not be read.
[email protected]0c5fb722012-02-28 11:50:358071 };
8072
rch8e6c6c42015-05-01 14:05:138073 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
8074 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:078075 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]0c5fb722012-02-28 11:50:358076 // Negotiate SPDY to the proxy
8077 SSLSocketDataProvider proxy(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:368078 proxy.next_proto = kProtoHTTP2;
[email protected]bb88e1d32013-05-03 23:11:078079 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy);
[email protected]0c5fb722012-02-28 11:50:358080 // Vanilla SSL to the server
8081 SSLSocketDataProvider server(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:078082 session_deps_.socket_factory->AddSSLSocketDataProvider(&server);
[email protected]0c5fb722012-02-28 11:50:358083
8084 TestCompletionCallback callback1;
8085
bnc691fda62016-08-12 00:43:168086 std::unique_ptr<HttpNetworkTransaction> trans(
[email protected]90499482013-06-01 00:39:508087 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]0c5fb722012-02-28 11:50:358088
8089 int rv = trans->Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:018090 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]0c5fb722012-02-28 11:50:358091
8092 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:018093 EXPECT_THAT(rv, IsOk());
mmenke43758e62015-05-04 21:09:468094 TestNetLogEntry::List entries;
[email protected]0c5fb722012-02-28 11:50:358095 log.GetEntries(&entries);
8096 size_t pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:008097 entries, 0, NetLogEventType::HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
8098 NetLogEventPhase::NONE);
[email protected]0c5fb722012-02-28 11:50:358099 ExpectLogContainsSomewhere(
8100 entries, pos,
mikecirone8b85c432016-09-08 19:11:008101 NetLogEventType::HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
8102 NetLogEventPhase::NONE);
[email protected]0c5fb722012-02-28 11:50:358103
8104 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:528105 ASSERT_TRUE(response);
8106 ASSERT_TRUE(response->headers);
[email protected]0c5fb722012-02-28 11:50:358107 EXPECT_EQ(407, response->headers->response_code());
8108 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
wezca1070932016-05-26 20:30:528109 EXPECT_TRUE(response->auth_challenge);
asanka098c0092016-06-16 20:18:438110 EXPECT_TRUE(CheckBasicSecureProxyAuth(response->auth_challenge.get()));
[email protected]0c5fb722012-02-28 11:50:358111
8112 TestCompletionCallback callback2;
8113
8114 rv = trans->RestartWithAuth(AuthCredentials(kFoo, kBar),
8115 callback2.callback());
robpercival214763f2016-07-01 23:27:018116 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]0c5fb722012-02-28 11:50:358117
8118 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:018119 EXPECT_THAT(rv, IsOk());
[email protected]0c5fb722012-02-28 11:50:358120
8121 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:528122 ASSERT_TRUE(response);
[email protected]0c5fb722012-02-28 11:50:358123
8124 EXPECT_TRUE(response->headers->IsKeepAlive());
8125 EXPECT_EQ(200, response->headers->response_code());
8126 EXPECT_EQ(5, response->headers->GetContentLength());
8127 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
8128
8129 // The password prompt info should not be set.
wezca1070932016-05-26 20:30:528130 EXPECT_FALSE(response->auth_challenge);
[email protected]0c5fb722012-02-28 11:50:358131
[email protected]029c83b62013-01-24 05:28:208132 LoadTimingInfo load_timing_info;
8133 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
8134 TestLoadTimingNotReusedWithPac(load_timing_info,
8135 CONNECT_TIMING_HAS_SSL_TIMES);
8136
[email protected]0c5fb722012-02-28 11:50:358137 trans.reset();
8138 session->CloseAllConnections();
8139}
8140
[email protected]7c6f7ba2012-04-03 04:09:298141// Test that an explicitly trusted SPDY proxy can push a resource from an
8142// origin that is different from that of its associated resource.
bncd16676a2016-07-20 16:23:018143TEST_F(HttpNetworkTransactionTest, CrossOriginSPDYProxyPush) {
tbansal28e68f82016-02-04 02:56:158144 // Configure the proxy delegate to allow cross-origin SPDY pushes.
danakj1fd259a02016-04-16 03:17:098145 std::unique_ptr<TestProxyDelegate> proxy_delegate(new TestProxyDelegate());
tbansal28e68f82016-02-04 02:56:158146 proxy_delegate->set_trusted_spdy_proxy(net::ProxyServer::FromURI(
8147 "https://myproxy:443", net::ProxyServer::SCHEME_HTTP));
[email protected]7c6f7ba2012-04-03 04:09:298148 HttpRequestInfo request;
8149 HttpRequestInfo push_request;
8150
[email protected]7c6f7ba2012-04-03 04:09:298151 request.method = "GET";
bncce36dca22015-04-21 22:11:238152 request.url = GURL("http://www.example.org/");
[email protected]7c6f7ba2012-04-03 04:09:298153 push_request.method = "GET";
8154 push_request.url = GURL("http://www.another-origin.com/foo.dat");
8155
tbansal28e68f82016-02-04 02:56:158156 // Configure against https proxy server "myproxy:443".
rdsmith82957ad2015-09-16 19:42:038157 session_deps_.proxy_service =
tbansal28e68f82016-02-04 02:56:158158 ProxyService::CreateFixedFromPacResult("HTTPS myproxy:443");
vishal.b62985ca92015-04-17 08:45:518159 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:078160 session_deps_.net_log = log.bound().net_log();
[email protected]61b4efc2012-04-27 18:12:508161
inlinechan894515af2016-12-09 02:40:108162 session_deps_.proxy_delegate = std::move(proxy_delegate);
[email protected]61b4efc2012-04-27 18:12:508163
danakj1fd259a02016-04-16 03:17:098164 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]7c6f7ba2012-04-03 04:09:298165
bncdf80d44fd2016-07-15 20:27:418166 SpdySerializedFrame stream1_syn(
bncb26024382016-06-29 02:39:458167 spdy_util_.ConstructSpdyGet("http://www.example.org/", 1, LOWEST));
tombergan5d22c182017-01-11 02:05:358168 SpdySerializedFrame stream2_priority(
8169 spdy_util_.ConstructSpdyPriority(2, 1, IDLE, true));
[email protected]7c6f7ba2012-04-03 04:09:298170
8171 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:418172 CreateMockWrite(stream1_syn, 0, ASYNC),
tombergan5d22c182017-01-11 02:05:358173 CreateMockWrite(stream2_priority, 3, ASYNC),
[email protected]7c6f7ba2012-04-03 04:09:298174 };
8175
bncdf80d44fd2016-07-15 20:27:418176 SpdySerializedFrame stream1_reply(
bnc42331402016-07-25 13:36:158177 spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
[email protected]7c6f7ba2012-04-03 04:09:298178
bncdf80d44fd2016-07-15 20:27:418179 SpdySerializedFrame stream1_body(spdy_util_.ConstructSpdyDataFrame(1, true));
[email protected]7c6f7ba2012-04-03 04:09:298180
bncdf80d44fd2016-07-15 20:27:418181 SpdySerializedFrame stream2_syn(spdy_util_.ConstructSpdyPush(
bncb03b1092016-04-06 11:19:558182 NULL, 0, 2, 1, "http://www.another-origin.com/foo.dat"));
[email protected]8a0fc822013-06-27 20:52:438183 const char kPushedData[] = "pushed";
bncdf80d44fd2016-07-15 20:27:418184 SpdySerializedFrame stream2_body(spdy_util_.ConstructSpdyDataFrame(
8185 2, kPushedData, strlen(kPushedData), true));
[email protected]7c6f7ba2012-04-03 04:09:298186
8187 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:418188 CreateMockRead(stream1_reply, 1, ASYNC),
8189 CreateMockRead(stream2_syn, 2, ASYNC),
tombergan5d22c182017-01-11 02:05:358190 CreateMockRead(stream1_body, 4, ASYNC),
8191 CreateMockRead(stream2_body, 5, ASYNC),
8192 MockRead(SYNCHRONOUS, ERR_IO_PENDING, 6), // Force a hang
[email protected]7c6f7ba2012-04-03 04:09:298193 };
8194
rch8e6c6c42015-05-01 14:05:138195 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
8196 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:078197 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]7c6f7ba2012-04-03 04:09:298198 // Negotiate SPDY to the proxy
8199 SSLSocketDataProvider proxy(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:368200 proxy.next_proto = kProtoHTTP2;
[email protected]bb88e1d32013-05-03 23:11:078201 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy);
[email protected]7c6f7ba2012-04-03 04:09:298202
bnc691fda62016-08-12 00:43:168203 std::unique_ptr<HttpNetworkTransaction> trans(
[email protected]90499482013-06-01 00:39:508204 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]7c6f7ba2012-04-03 04:09:298205 TestCompletionCallback callback;
8206 int rv = trans->Start(&request, callback.callback(), log.bound());
robpercival214763f2016-07-01 23:27:018207 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]7c6f7ba2012-04-03 04:09:298208
8209 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:018210 EXPECT_THAT(rv, IsOk());
[email protected]7c6f7ba2012-04-03 04:09:298211 const HttpResponseInfo* response = trans->GetResponseInfo();
8212
bnc691fda62016-08-12 00:43:168213 std::unique_ptr<HttpNetworkTransaction> push_trans(
[email protected]90499482013-06-01 00:39:508214 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
8215 rv = push_trans->Start(&push_request, callback.callback(), log.bound());
robpercival214763f2016-07-01 23:27:018216 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]7c6f7ba2012-04-03 04:09:298217
8218 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:018219 EXPECT_THAT(rv, IsOk());
[email protected]7c6f7ba2012-04-03 04:09:298220 const HttpResponseInfo* push_response = push_trans->GetResponseInfo();
8221
wezca1070932016-05-26 20:30:528222 ASSERT_TRUE(response);
[email protected]7c6f7ba2012-04-03 04:09:298223 EXPECT_TRUE(response->headers->IsKeepAlive());
8224
8225 EXPECT_EQ(200, response->headers->response_code());
8226 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
8227
8228 std::string response_data;
8229 rv = ReadTransaction(trans.get(), &response_data);
robpercival214763f2016-07-01 23:27:018230 EXPECT_THAT(rv, IsOk());
[email protected]7c6f7ba2012-04-03 04:09:298231 EXPECT_EQ("hello!", response_data);
8232
[email protected]029c83b62013-01-24 05:28:208233 LoadTimingInfo load_timing_info;
8234 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
8235 TestLoadTimingNotReusedWithPac(load_timing_info,
8236 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
8237
[email protected]7c6f7ba2012-04-03 04:09:298238 // Verify the pushed stream.
wezca1070932016-05-26 20:30:528239 EXPECT_TRUE(push_response->headers);
[email protected]7c6f7ba2012-04-03 04:09:298240 EXPECT_EQ(200, push_response->headers->response_code());
8241
8242 rv = ReadTransaction(push_trans.get(), &response_data);
robpercival214763f2016-07-01 23:27:018243 EXPECT_THAT(rv, IsOk());
[email protected]7c6f7ba2012-04-03 04:09:298244 EXPECT_EQ("pushed", response_data);
8245
[email protected]029c83b62013-01-24 05:28:208246 LoadTimingInfo push_load_timing_info;
8247 EXPECT_TRUE(push_trans->GetLoadTimingInfo(&push_load_timing_info));
8248 TestLoadTimingReusedWithPac(push_load_timing_info);
8249 // The transactions should share a socket ID, despite being for different
8250 // origins.
8251 EXPECT_EQ(load_timing_info.socket_log_id,
8252 push_load_timing_info.socket_log_id);
8253
[email protected]7c6f7ba2012-04-03 04:09:298254 trans.reset();
8255 push_trans.reset();
8256 session->CloseAllConnections();
8257}
8258
[email protected]8c843192012-04-05 07:15:008259// Test that an explicitly trusted SPDY proxy cannot push HTTPS content.
bncd16676a2016-07-20 16:23:018260TEST_F(HttpNetworkTransactionTest, CrossOriginProxyPushCorrectness) {
tbansal28e68f82016-02-04 02:56:158261 // Configure the proxy delegate to allow cross-origin SPDY pushes.
danakj1fd259a02016-04-16 03:17:098262 std::unique_ptr<TestProxyDelegate> proxy_delegate(new TestProxyDelegate());
tbansal28e68f82016-02-04 02:56:158263 proxy_delegate->set_trusted_spdy_proxy(net::ProxyServer::FromURI(
8264 "https://myproxy:443", net::ProxyServer::SCHEME_HTTP));
[email protected]8c843192012-04-05 07:15:008265 HttpRequestInfo request;
8266
8267 request.method = "GET";
bncce36dca22015-04-21 22:11:238268 request.url = GURL("http://www.example.org/");
[email protected]8c843192012-04-05 07:15:008269
tbansal28e68f82016-02-04 02:56:158270 session_deps_.proxy_service =
8271 ProxyService::CreateFixed("https://myproxy:443");
vishal.b62985ca92015-04-17 08:45:518272 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:078273 session_deps_.net_log = log.bound().net_log();
[email protected]61b4efc2012-04-27 18:12:508274
8275 // Enable cross-origin push.
inlinechan894515af2016-12-09 02:40:108276 session_deps_.proxy_delegate = std::move(proxy_delegate);
[email protected]61b4efc2012-04-27 18:12:508277
danakj1fd259a02016-04-16 03:17:098278 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]8c843192012-04-05 07:15:008279
bncdf80d44fd2016-07-15 20:27:418280 SpdySerializedFrame stream1_syn(
bncb26024382016-06-29 02:39:458281 spdy_util_.ConstructSpdyGet("http://www.example.org/", 1, LOWEST));
[email protected]8c843192012-04-05 07:15:008282
bncdf80d44fd2016-07-15 20:27:418283 SpdySerializedFrame push_rst(
diannahu9904e272017-02-03 14:40:088284 spdy_util_.ConstructSpdyRstStream(2, ERROR_CODE_REFUSED_STREAM));
[email protected]8c843192012-04-05 07:15:008285
8286 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:418287 CreateMockWrite(stream1_syn, 0, ASYNC), CreateMockWrite(push_rst, 3),
[email protected]8c843192012-04-05 07:15:008288 };
8289
bncdf80d44fd2016-07-15 20:27:418290 SpdySerializedFrame stream1_reply(
bnc42331402016-07-25 13:36:158291 spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
[email protected]8c843192012-04-05 07:15:008292
bncdf80d44fd2016-07-15 20:27:418293 SpdySerializedFrame stream1_body(spdy_util_.ConstructSpdyDataFrame(1, true));
[email protected]8c843192012-04-05 07:15:008294
bncdf80d44fd2016-07-15 20:27:418295 SpdySerializedFrame stream2_syn(spdy_util_.ConstructSpdyPush(
bncb03b1092016-04-06 11:19:558296 NULL, 0, 2, 1, "https://www.another-origin.com/foo.dat"));
[email protected]8c843192012-04-05 07:15:008297
8298 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:418299 CreateMockRead(stream1_reply, 1, ASYNC),
8300 CreateMockRead(stream2_syn, 2, ASYNC),
8301 CreateMockRead(stream1_body, 4, ASYNC),
mmenkee24011922015-12-17 22:12:598302 MockRead(SYNCHRONOUS, ERR_IO_PENDING, 5), // Force a hang
[email protected]8c843192012-04-05 07:15:008303 };
8304
rch8e6c6c42015-05-01 14:05:138305 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
8306 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:078307 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]8c843192012-04-05 07:15:008308 // Negotiate SPDY to the proxy
8309 SSLSocketDataProvider proxy(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:368310 proxy.next_proto = kProtoHTTP2;
[email protected]bb88e1d32013-05-03 23:11:078311 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy);
[email protected]8c843192012-04-05 07:15:008312
bnc691fda62016-08-12 00:43:168313 std::unique_ptr<HttpNetworkTransaction> trans(
[email protected]90499482013-06-01 00:39:508314 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]8c843192012-04-05 07:15:008315 TestCompletionCallback callback;
8316 int rv = trans->Start(&request, callback.callback(), log.bound());
robpercival214763f2016-07-01 23:27:018317 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]8c843192012-04-05 07:15:008318
8319 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:018320 EXPECT_THAT(rv, IsOk());
[email protected]8c843192012-04-05 07:15:008321 const HttpResponseInfo* response = trans->GetResponseInfo();
8322
wezca1070932016-05-26 20:30:528323 ASSERT_TRUE(response);
[email protected]8c843192012-04-05 07:15:008324 EXPECT_TRUE(response->headers->IsKeepAlive());
8325
8326 EXPECT_EQ(200, response->headers->response_code());
8327 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
8328
8329 std::string response_data;
8330 rv = ReadTransaction(trans.get(), &response_data);
robpercival214763f2016-07-01 23:27:018331 EXPECT_THAT(rv, IsOk());
[email protected]8c843192012-04-05 07:15:008332 EXPECT_EQ("hello!", response_data);
8333
8334 trans.reset();
8335 session->CloseAllConnections();
8336}
8337
tbansal8ef1d3e2016-02-03 04:05:428338// Test that an explicitly trusted SPDY proxy can push same-origin HTTPS
8339// resources.
bncd16676a2016-07-20 16:23:018340TEST_F(HttpNetworkTransactionTest, SameOriginProxyPushCorrectness) {
tbansal28e68f82016-02-04 02:56:158341 // Configure the proxy delegate to allow cross-origin SPDY pushes.
danakj1fd259a02016-04-16 03:17:098342 std::unique_ptr<TestProxyDelegate> proxy_delegate(new TestProxyDelegate());
tbansal28e68f82016-02-04 02:56:158343 proxy_delegate->set_trusted_spdy_proxy(
8344 net::ProxyServer::FromURI("myproxy:70", net::ProxyServer::SCHEME_HTTP));
8345
tbansal8ef1d3e2016-02-03 04:05:428346 HttpRequestInfo request;
8347
8348 request.method = "GET";
8349 request.url = GURL("http://www.example.org/");
8350
8351 // Configure against https proxy server "myproxy:70".
8352 session_deps_.proxy_service = ProxyService::CreateFixed("https://myproxy:70");
8353 BoundTestNetLog log;
8354 session_deps_.net_log = log.bound().net_log();
8355
8356 // Enable cross-origin push.
inlinechan894515af2016-12-09 02:40:108357 session_deps_.proxy_delegate = std::move(proxy_delegate);
tbansal8ef1d3e2016-02-03 04:05:428358
danakj1fd259a02016-04-16 03:17:098359 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
tbansal8ef1d3e2016-02-03 04:05:428360
bncdf80d44fd2016-07-15 20:27:418361 SpdySerializedFrame stream1_syn(
bncb26024382016-06-29 02:39:458362 spdy_util_.ConstructSpdyGet("http://www.example.org/", 1, LOWEST));
tombergan5d22c182017-01-11 02:05:358363 SpdySerializedFrame stream2_priority(
8364 spdy_util_.ConstructSpdyPriority(2, 1, IDLE, true));
tbansal8ef1d3e2016-02-03 04:05:428365
8366 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:418367 CreateMockWrite(stream1_syn, 0, ASYNC),
tombergan5d22c182017-01-11 02:05:358368 CreateMockWrite(stream2_priority, 3, ASYNC),
tbansal8ef1d3e2016-02-03 04:05:428369 };
8370
bncdf80d44fd2016-07-15 20:27:418371 SpdySerializedFrame stream1_reply(
bnc42331402016-07-25 13:36:158372 spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
tbansal8ef1d3e2016-02-03 04:05:428373
bncdf80d44fd2016-07-15 20:27:418374 SpdySerializedFrame stream2_syn(spdy_util_.ConstructSpdyPush(
bnc38dcd392016-02-09 23:19:498375 nullptr, 0, 2, 1, "https://myproxy:70/foo.dat"));
8376
bncdf80d44fd2016-07-15 20:27:418377 SpdySerializedFrame stream1_body(spdy_util_.ConstructSpdyDataFrame(1, true));
tbansal8ef1d3e2016-02-03 04:05:428378
bncdf80d44fd2016-07-15 20:27:418379 SpdySerializedFrame stream2_reply(
bnc42331402016-07-25 13:36:158380 spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
tbansal8ef1d3e2016-02-03 04:05:428381
bncdf80d44fd2016-07-15 20:27:418382 SpdySerializedFrame stream2_body(spdy_util_.ConstructSpdyDataFrame(1, true));
tbansal8ef1d3e2016-02-03 04:05:428383
8384 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:418385 CreateMockRead(stream1_reply, 1, ASYNC),
8386 CreateMockRead(stream2_syn, 2, ASYNC),
tombergan5d22c182017-01-11 02:05:358387 CreateMockRead(stream1_body, 4, ASYNC),
8388 CreateMockRead(stream2_body, 5, ASYNC),
8389 MockRead(SYNCHRONOUS, ERR_IO_PENDING, 6), // Force a hang
tbansal8ef1d3e2016-02-03 04:05:428390 };
8391
8392 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
8393 arraysize(spdy_writes));
8394 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
8395 // Negotiate SPDY to the proxy
8396 SSLSocketDataProvider proxy(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:368397 proxy.next_proto = kProtoHTTP2;
tbansal8ef1d3e2016-02-03 04:05:428398 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy);
8399
bnc691fda62016-08-12 00:43:168400 std::unique_ptr<HttpNetworkTransaction> trans(
tbansal8ef1d3e2016-02-03 04:05:428401 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
8402 TestCompletionCallback callback;
8403 int rv = trans->Start(&request, callback.callback(), log.bound());
robpercival214763f2016-07-01 23:27:018404 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
tbansal8ef1d3e2016-02-03 04:05:428405
8406 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:018407 EXPECT_THAT(rv, IsOk());
tbansal8ef1d3e2016-02-03 04:05:428408 const HttpResponseInfo* response = trans->GetResponseInfo();
8409
wezca1070932016-05-26 20:30:528410 ASSERT_TRUE(response);
tbansal8ef1d3e2016-02-03 04:05:428411 EXPECT_TRUE(response->headers->IsKeepAlive());
8412
8413 EXPECT_EQ(200, response->headers->response_code());
8414 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
8415
8416 std::string response_data;
8417 rv = ReadTransaction(trans.get(), &response_data);
robpercival214763f2016-07-01 23:27:018418 EXPECT_THAT(rv, IsOk());
tbansal8ef1d3e2016-02-03 04:05:428419 EXPECT_EQ("hello!", response_data);
8420
8421 trans.reset();
8422 session->CloseAllConnections();
8423}
8424
[email protected]2df19bb2010-08-25 20:13:468425// Test HTTPS connections to a site with a bad certificate, going through an
8426// HTTPS proxy
bncd16676a2016-07-20 16:23:018427TEST_F(HttpNetworkTransactionTest, HTTPSBadCertificateViaHttpsProxy) {
rdsmith82957ad2015-09-16 19:42:038428 session_deps_.proxy_service = ProxyService::CreateFixed("https://proxy:70");
[email protected]2df19bb2010-08-25 20:13:468429
8430 HttpRequestInfo request;
8431 request.method = "GET";
bncce36dca22015-04-21 22:11:238432 request.url = GURL("https://www.example.org/");
[email protected]2df19bb2010-08-25 20:13:468433
8434 // Attempt to fetch the URL from a server with a bad cert
8435 MockWrite bad_cert_writes[] = {
rsleevidb16bb02015-11-12 23:47:178436 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
8437 "Host: www.example.org:443\r\n"
8438 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]2df19bb2010-08-25 20:13:468439 };
8440
8441 MockRead bad_cert_reads[] = {
8442 MockRead("HTTP/1.0 200 Connected\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:068443 MockRead(SYNCHRONOUS, OK)
[email protected]2df19bb2010-08-25 20:13:468444 };
8445
8446 // Attempt to fetch the URL with a good cert
8447 MockWrite good_data_writes[] = {
rsleevidb16bb02015-11-12 23:47:178448 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
8449 "Host: www.example.org:443\r\n"
8450 "Proxy-Connection: keep-alive\r\n\r\n"),
8451 MockWrite("GET / HTTP/1.1\r\n"
8452 "Host: www.example.org\r\n"
8453 "Connection: keep-alive\r\n\r\n"),
[email protected]2df19bb2010-08-25 20:13:468454 };
8455
8456 MockRead good_cert_reads[] = {
8457 MockRead("HTTP/1.0 200 Connected\r\n\r\n"),
8458 MockRead("HTTP/1.0 200 OK\r\n"),
8459 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
8460 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:068461 MockRead(SYNCHRONOUS, OK),
[email protected]2df19bb2010-08-25 20:13:468462 };
8463
8464 StaticSocketDataProvider ssl_bad_certificate(
8465 bad_cert_reads, arraysize(bad_cert_reads),
8466 bad_cert_writes, arraysize(bad_cert_writes));
8467 StaticSocketDataProvider data(good_cert_reads, arraysize(good_cert_reads),
8468 good_data_writes, arraysize(good_data_writes));
[email protected]8ddf8322012-02-23 18:08:068469 SSLSocketDataProvider ssl_bad(ASYNC, ERR_CERT_AUTHORITY_INVALID);
8470 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]2df19bb2010-08-25 20:13:468471
8472 // SSL to the proxy, then CONNECT request, then SSL with bad certificate
[email protected]bb88e1d32013-05-03 23:11:078473 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
8474 session_deps_.socket_factory->AddSocketDataProvider(&ssl_bad_certificate);
8475 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_bad);
[email protected]2df19bb2010-08-25 20:13:468476
8477 // SSL to the proxy, then CONNECT request, then valid SSL certificate
[email protected]bb88e1d32013-05-03 23:11:078478 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
8479 session_deps_.socket_factory->AddSocketDataProvider(&data);
8480 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]2df19bb2010-08-25 20:13:468481
[email protected]49639fa2011-12-20 23:22:418482 TestCompletionCallback callback;
[email protected]2df19bb2010-08-25 20:13:468483
danakj1fd259a02016-04-16 03:17:098484 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:168485 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]2df19bb2010-08-25 20:13:468486
tfarina42834112016-09-22 13:38:208487 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:018488 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2df19bb2010-08-25 20:13:468489
8490 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:018491 EXPECT_THAT(rv, IsError(ERR_CERT_AUTHORITY_INVALID));
[email protected]2df19bb2010-08-25 20:13:468492
bnc691fda62016-08-12 00:43:168493 rv = trans.RestartIgnoringLastError(callback.callback());
robpercival214763f2016-07-01 23:27:018494 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2df19bb2010-08-25 20:13:468495
8496 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:018497 EXPECT_THAT(rv, IsOk());
[email protected]2df19bb2010-08-25 20:13:468498
bnc691fda62016-08-12 00:43:168499 const HttpResponseInfo* response = trans.GetResponseInfo();
[email protected]2df19bb2010-08-25 20:13:468500
wezca1070932016-05-26 20:30:528501 ASSERT_TRUE(response);
[email protected]2df19bb2010-08-25 20:13:468502 EXPECT_EQ(100, response->headers->GetContentLength());
8503}
8504
bncd16676a2016-07-20 16:23:018505TEST_F(HttpNetworkTransactionTest, BuildRequest_UserAgent) {
[email protected]1c773ea12009-04-28 19:58:428506 HttpRequestInfo request;
8507 request.method = "GET";
bncce36dca22015-04-21 22:11:238508 request.url = GURL("http://www.example.org/");
[email protected]8c76ae22010-04-20 22:15:438509 request.extra_headers.SetHeader(HttpRequestHeaders::kUserAgent,
8510 "Chromium Ultra Awesome X Edition");
[email protected]1c773ea12009-04-28 19:58:428511
danakj1fd259a02016-04-16 03:17:098512 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:168513 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:278514
[email protected]1c773ea12009-04-28 19:58:428515 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:238516 MockWrite(
8517 "GET / HTTP/1.1\r\n"
8518 "Host: www.example.org\r\n"
8519 "Connection: keep-alive\r\n"
8520 "User-Agent: Chromium Ultra Awesome X Edition\r\n\r\n"),
[email protected]1c773ea12009-04-28 19:58:428521 };
8522
8523 // Lastly, the server responds with the actual content.
8524 MockRead data_reads[] = {
8525 MockRead("HTTP/1.0 200 OK\r\n"),
8526 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
8527 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:068528 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:428529 };
8530
[email protected]31a2bfe2010-02-09 08:03:398531 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
8532 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:078533 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:428534
[email protected]49639fa2011-12-20 23:22:418535 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:428536
tfarina42834112016-09-22 13:38:208537 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:018538 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]1c773ea12009-04-28 19:58:428539
8540 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:018541 EXPECT_THAT(rv, IsOk());
[email protected]1c773ea12009-04-28 19:58:428542}
8543
bncd16676a2016-07-20 16:23:018544TEST_F(HttpNetworkTransactionTest, BuildRequest_UserAgentOverTunnel) {
[email protected]da81f132010-08-18 23:39:298545 HttpRequestInfo request;
8546 request.method = "GET";
bncce36dca22015-04-21 22:11:238547 request.url = GURL("https://www.example.org/");
[email protected]da81f132010-08-18 23:39:298548 request.extra_headers.SetHeader(HttpRequestHeaders::kUserAgent,
8549 "Chromium Ultra Awesome X Edition");
8550
rdsmith82957ad2015-09-16 19:42:038551 session_deps_.proxy_service = ProxyService::CreateFixed("myproxy:70");
danakj1fd259a02016-04-16 03:17:098552 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:168553 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:278554
[email protected]da81f132010-08-18 23:39:298555 MockWrite data_writes[] = {
rsleevidb16bb02015-11-12 23:47:178556 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
8557 "Host: www.example.org:443\r\n"
8558 "Proxy-Connection: keep-alive\r\n"
8559 "User-Agent: Chromium Ultra Awesome X Edition\r\n\r\n"),
[email protected]da81f132010-08-18 23:39:298560 };
8561 MockRead data_reads[] = {
8562 // Return an error, so the transaction stops here (this test isn't
8563 // interested in the rest).
8564 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
8565 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
8566 MockRead("Proxy-Connection: close\r\n\r\n"),
8567 };
8568
8569 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
8570 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:078571 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]da81f132010-08-18 23:39:298572
[email protected]49639fa2011-12-20 23:22:418573 TestCompletionCallback callback;
[email protected]da81f132010-08-18 23:39:298574
tfarina42834112016-09-22 13:38:208575 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:018576 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]da81f132010-08-18 23:39:298577
8578 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:018579 EXPECT_THAT(rv, IsOk());
[email protected]da81f132010-08-18 23:39:298580}
8581
bncd16676a2016-07-20 16:23:018582TEST_F(HttpNetworkTransactionTest, BuildRequest_Referer) {
[email protected]1c773ea12009-04-28 19:58:428583 HttpRequestInfo request;
8584 request.method = "GET";
bncce36dca22015-04-21 22:11:238585 request.url = GURL("http://www.example.org/");
[email protected]c10450102011-06-27 09:06:168586 request.extra_headers.SetHeader(HttpRequestHeaders::kReferer,
8587 "http://the.previous.site.com/");
[email protected]1c773ea12009-04-28 19:58:428588
danakj1fd259a02016-04-16 03:17:098589 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:168590 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:278591
[email protected]1c773ea12009-04-28 19:58:428592 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:238593 MockWrite(
8594 "GET / HTTP/1.1\r\n"
8595 "Host: www.example.org\r\n"
8596 "Connection: keep-alive\r\n"
8597 "Referer: http://the.previous.site.com/\r\n\r\n"),
[email protected]1c773ea12009-04-28 19:58:428598 };
8599
8600 // Lastly, the server responds with the actual content.
8601 MockRead data_reads[] = {
8602 MockRead("HTTP/1.0 200 OK\r\n"),
8603 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
8604 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:068605 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:428606 };
8607
[email protected]31a2bfe2010-02-09 08:03:398608 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
8609 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:078610 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:428611
[email protected]49639fa2011-12-20 23:22:418612 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:428613
tfarina42834112016-09-22 13:38:208614 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:018615 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]1c773ea12009-04-28 19:58:428616
8617 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:018618 EXPECT_THAT(rv, IsOk());
[email protected]1c773ea12009-04-28 19:58:428619}
8620
bncd16676a2016-07-20 16:23:018621TEST_F(HttpNetworkTransactionTest, BuildRequest_PostContentLengthZero) {
[email protected]1c773ea12009-04-28 19:58:428622 HttpRequestInfo request;
8623 request.method = "POST";
bncce36dca22015-04-21 22:11:238624 request.url = GURL("http://www.example.org/");
[email protected]1c773ea12009-04-28 19:58:428625
danakj1fd259a02016-04-16 03:17:098626 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:168627 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:278628
[email protected]1c773ea12009-04-28 19:58:428629 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:238630 MockWrite(
8631 "POST / HTTP/1.1\r\n"
8632 "Host: www.example.org\r\n"
8633 "Connection: keep-alive\r\n"
8634 "Content-Length: 0\r\n\r\n"),
[email protected]1c773ea12009-04-28 19:58:428635 };
8636
8637 // Lastly, the server responds with the actual content.
8638 MockRead data_reads[] = {
8639 MockRead("HTTP/1.0 200 OK\r\n"),
8640 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
8641 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:068642 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:428643 };
8644
[email protected]31a2bfe2010-02-09 08:03:398645 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
8646 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:078647 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:428648
[email protected]49639fa2011-12-20 23:22:418649 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:428650
tfarina42834112016-09-22 13:38:208651 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:018652 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]1c773ea12009-04-28 19:58:428653
8654 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:018655 EXPECT_THAT(rv, IsOk());
[email protected]1c773ea12009-04-28 19:58:428656}
8657
bncd16676a2016-07-20 16:23:018658TEST_F(HttpNetworkTransactionTest, BuildRequest_PutContentLengthZero) {
[email protected]1c773ea12009-04-28 19:58:428659 HttpRequestInfo request;
8660 request.method = "PUT";
bncce36dca22015-04-21 22:11:238661 request.url = GURL("http://www.example.org/");
[email protected]1c773ea12009-04-28 19:58:428662
danakj1fd259a02016-04-16 03:17:098663 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:168664 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:278665
[email protected]1c773ea12009-04-28 19:58:428666 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:238667 MockWrite(
8668 "PUT / HTTP/1.1\r\n"
8669 "Host: www.example.org\r\n"
8670 "Connection: keep-alive\r\n"
8671 "Content-Length: 0\r\n\r\n"),
[email protected]1c773ea12009-04-28 19:58:428672 };
8673
8674 // Lastly, the server responds with the actual content.
8675 MockRead data_reads[] = {
8676 MockRead("HTTP/1.0 200 OK\r\n"),
8677 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
8678 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:068679 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:428680 };
8681
[email protected]31a2bfe2010-02-09 08:03:398682 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
8683 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:078684 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:428685
[email protected]49639fa2011-12-20 23:22:418686 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:428687
tfarina42834112016-09-22 13:38:208688 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:018689 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]1c773ea12009-04-28 19:58:428690
8691 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:018692 EXPECT_THAT(rv, IsOk());
[email protected]1c773ea12009-04-28 19:58:428693}
8694
bncd16676a2016-07-20 16:23:018695TEST_F(HttpNetworkTransactionTest, BuildRequest_HeadContentLengthZero) {
[email protected]1c773ea12009-04-28 19:58:428696 HttpRequestInfo request;
8697 request.method = "HEAD";
bncce36dca22015-04-21 22:11:238698 request.url = GURL("http://www.example.org/");
[email protected]1c773ea12009-04-28 19:58:428699
danakj1fd259a02016-04-16 03:17:098700 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:168701 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:278702
[email protected]1c773ea12009-04-28 19:58:428703 MockWrite data_writes[] = {
csharrisonf473dd192015-08-18 13:54:138704 MockWrite("HEAD / HTTP/1.1\r\n"
8705 "Host: www.example.org\r\n"
8706 "Connection: keep-alive\r\n\r\n"),
[email protected]1c773ea12009-04-28 19:58:428707 };
8708
8709 // Lastly, the server responds with the actual content.
8710 MockRead data_reads[] = {
8711 MockRead("HTTP/1.0 200 OK\r\n"),
8712 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
8713 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:068714 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:428715 };
8716
[email protected]31a2bfe2010-02-09 08:03:398717 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
8718 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:078719 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:428720
[email protected]49639fa2011-12-20 23:22:418721 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:428722
tfarina42834112016-09-22 13:38:208723 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:018724 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]1c773ea12009-04-28 19:58:428725
8726 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:018727 EXPECT_THAT(rv, IsOk());
[email protected]1c773ea12009-04-28 19:58:428728}
8729
bncd16676a2016-07-20 16:23:018730TEST_F(HttpNetworkTransactionTest, BuildRequest_CacheControlNoCache) {
[email protected]1c773ea12009-04-28 19:58:428731 HttpRequestInfo request;
8732 request.method = "GET";
bncce36dca22015-04-21 22:11:238733 request.url = GURL("http://www.example.org/");
[email protected]1c773ea12009-04-28 19:58:428734 request.load_flags = LOAD_BYPASS_CACHE;
8735
danakj1fd259a02016-04-16 03:17:098736 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:168737 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:278738
[email protected]1c773ea12009-04-28 19:58:428739 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:238740 MockWrite(
8741 "GET / HTTP/1.1\r\n"
8742 "Host: www.example.org\r\n"
8743 "Connection: keep-alive\r\n"
8744 "Pragma: no-cache\r\n"
8745 "Cache-Control: no-cache\r\n\r\n"),
[email protected]1c773ea12009-04-28 19:58:428746 };
8747
8748 // Lastly, the server responds with the actual content.
8749 MockRead data_reads[] = {
8750 MockRead("HTTP/1.0 200 OK\r\n"),
8751 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
8752 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:068753 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:428754 };
8755
[email protected]31a2bfe2010-02-09 08:03:398756 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
8757 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:078758 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:428759
[email protected]49639fa2011-12-20 23:22:418760 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:428761
tfarina42834112016-09-22 13:38:208762 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:018763 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]1c773ea12009-04-28 19:58:428764
8765 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:018766 EXPECT_THAT(rv, IsOk());
[email protected]1c773ea12009-04-28 19:58:428767}
8768
bncd16676a2016-07-20 16:23:018769TEST_F(HttpNetworkTransactionTest, BuildRequest_CacheControlValidateCache) {
[email protected]1c773ea12009-04-28 19:58:428770 HttpRequestInfo request;
8771 request.method = "GET";
bncce36dca22015-04-21 22:11:238772 request.url = GURL("http://www.example.org/");
[email protected]1c773ea12009-04-28 19:58:428773 request.load_flags = LOAD_VALIDATE_CACHE;
8774
danakj1fd259a02016-04-16 03:17:098775 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:168776 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:278777
[email protected]1c773ea12009-04-28 19:58:428778 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:238779 MockWrite(
8780 "GET / HTTP/1.1\r\n"
8781 "Host: www.example.org\r\n"
8782 "Connection: keep-alive\r\n"
8783 "Cache-Control: max-age=0\r\n\r\n"),
[email protected]1c773ea12009-04-28 19:58:428784 };
8785
8786 // Lastly, the server responds with the actual content.
8787 MockRead data_reads[] = {
8788 MockRead("HTTP/1.0 200 OK\r\n"),
8789 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
8790 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:068791 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:428792 };
8793
[email protected]31a2bfe2010-02-09 08:03:398794 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
8795 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:078796 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:428797
[email protected]49639fa2011-12-20 23:22:418798 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:428799
tfarina42834112016-09-22 13:38:208800 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:018801 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]1c773ea12009-04-28 19:58:428802
8803 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:018804 EXPECT_THAT(rv, IsOk());
[email protected]1c773ea12009-04-28 19:58:428805}
8806
bncd16676a2016-07-20 16:23:018807TEST_F(HttpNetworkTransactionTest, BuildRequest_ExtraHeaders) {
[email protected]1c773ea12009-04-28 19:58:428808 HttpRequestInfo request;
8809 request.method = "GET";
bncce36dca22015-04-21 22:11:238810 request.url = GURL("http://www.example.org/");
[email protected]8c76ae22010-04-20 22:15:438811 request.extra_headers.SetHeader("FooHeader", "Bar");
[email protected]1c773ea12009-04-28 19:58:428812
danakj1fd259a02016-04-16 03:17:098813 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:168814 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:278815
[email protected]1c773ea12009-04-28 19:58:428816 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:238817 MockWrite(
8818 "GET / HTTP/1.1\r\n"
8819 "Host: www.example.org\r\n"
8820 "Connection: keep-alive\r\n"
8821 "FooHeader: Bar\r\n\r\n"),
[email protected]1c773ea12009-04-28 19:58:428822 };
8823
8824 // Lastly, the server responds with the actual content.
8825 MockRead data_reads[] = {
8826 MockRead("HTTP/1.0 200 OK\r\n"),
8827 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
8828 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:068829 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:428830 };
8831
[email protected]31a2bfe2010-02-09 08:03:398832 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
8833 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:078834 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:428835
[email protected]49639fa2011-12-20 23:22:418836 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:428837
tfarina42834112016-09-22 13:38:208838 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:018839 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]1c773ea12009-04-28 19:58:428840
8841 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:018842 EXPECT_THAT(rv, IsOk());
[email protected]1c773ea12009-04-28 19:58:428843}
8844
bncd16676a2016-07-20 16:23:018845TEST_F(HttpNetworkTransactionTest, BuildRequest_ExtraHeadersStripped) {
[email protected]270c6412010-03-29 22:02:478846 HttpRequestInfo request;
8847 request.method = "GET";
bncce36dca22015-04-21 22:11:238848 request.url = GURL("http://www.example.org/");
[email protected]8c76ae22010-04-20 22:15:438849 request.extra_headers.SetHeader("referer", "www.foo.com");
8850 request.extra_headers.SetHeader("hEllo", "Kitty");
8851 request.extra_headers.SetHeader("FoO", "bar");
[email protected]270c6412010-03-29 22:02:478852
danakj1fd259a02016-04-16 03:17:098853 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:168854 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:278855
[email protected]270c6412010-03-29 22:02:478856 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:238857 MockWrite(
8858 "GET / HTTP/1.1\r\n"
8859 "Host: www.example.org\r\n"
8860 "Connection: keep-alive\r\n"
8861 "referer: www.foo.com\r\n"
8862 "hEllo: Kitty\r\n"
8863 "FoO: bar\r\n\r\n"),
[email protected]270c6412010-03-29 22:02:478864 };
8865
8866 // Lastly, the server responds with the actual content.
8867 MockRead data_reads[] = {
8868 MockRead("HTTP/1.0 200 OK\r\n"),
8869 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
8870 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:068871 MockRead(SYNCHRONOUS, OK),
[email protected]270c6412010-03-29 22:02:478872 };
8873
8874 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
8875 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:078876 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]270c6412010-03-29 22:02:478877
[email protected]49639fa2011-12-20 23:22:418878 TestCompletionCallback callback;
[email protected]270c6412010-03-29 22:02:478879
tfarina42834112016-09-22 13:38:208880 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:018881 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]270c6412010-03-29 22:02:478882
8883 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:018884 EXPECT_THAT(rv, IsOk());
[email protected]270c6412010-03-29 22:02:478885}
8886
bncd16676a2016-07-20 16:23:018887TEST_F(HttpNetworkTransactionTest, SOCKS4_HTTP_GET) {
[email protected]cb9bf6ca2011-01-28 13:15:278888 HttpRequestInfo request;
8889 request.method = "GET";
bncce36dca22015-04-21 22:11:238890 request.url = GURL("http://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:278891
rdsmith82957ad2015-09-16 19:42:038892 session_deps_.proxy_service =
8893 ProxyService::CreateFixedFromPacResult("SOCKS myproxy:1080");
vishal.b62985ca92015-04-17 08:45:518894 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:078895 session_deps_.net_log = &net_log;
[email protected]3cd17242009-06-23 02:59:028896
danakj1fd259a02016-04-16 03:17:098897 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:168898 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]3cd17242009-06-23 02:59:028899
[email protected]3cd17242009-06-23 02:59:028900 char write_buffer[] = { 0x04, 0x01, 0x00, 0x50, 127, 0, 0, 1, 0 };
8901 char read_buffer[] = { 0x00, 0x5A, 0x00, 0x00, 0, 0, 0, 0 };
8902
8903 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:238904 MockWrite(ASYNC, write_buffer, arraysize(write_buffer)),
8905 MockWrite(
8906 "GET / HTTP/1.1\r\n"
8907 "Host: www.example.org\r\n"
8908 "Connection: keep-alive\r\n\r\n")};
[email protected]3cd17242009-06-23 02:59:028909
8910 MockRead data_reads[] = {
[email protected]8ddf8322012-02-23 18:08:068911 MockRead(ASYNC, read_buffer, arraysize(read_buffer)),
[email protected]3cd17242009-06-23 02:59:028912 MockRead("HTTP/1.0 200 OK\r\n"),
8913 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n\r\n"),
8914 MockRead("Payload"),
[email protected]8ddf8322012-02-23 18:08:068915 MockRead(SYNCHRONOUS, OK)
[email protected]3cd17242009-06-23 02:59:028916 };
8917
[email protected]31a2bfe2010-02-09 08:03:398918 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
8919 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:078920 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]3cd17242009-06-23 02:59:028921
[email protected]49639fa2011-12-20 23:22:418922 TestCompletionCallback callback;
[email protected]3cd17242009-06-23 02:59:028923
tfarina42834112016-09-22 13:38:208924 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:018925 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]3cd17242009-06-23 02:59:028926
8927 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:018928 EXPECT_THAT(rv, IsOk());
[email protected]3cd17242009-06-23 02:59:028929
bnc691fda62016-08-12 00:43:168930 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:528931 ASSERT_TRUE(response);
[email protected]3cd17242009-06-23 02:59:028932
tbansal2ecbbc72016-10-06 17:15:478933 EXPECT_EQ(ProxyServer::SCHEME_SOCKS4, response->proxy_server.scheme());
[email protected]029c83b62013-01-24 05:28:208934 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:168935 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]029c83b62013-01-24 05:28:208936 TestLoadTimingNotReusedWithPac(load_timing_info,
8937 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
8938
[email protected]3cd17242009-06-23 02:59:028939 std::string response_text;
bnc691fda62016-08-12 00:43:168940 rv = ReadTransaction(&trans, &response_text);
robpercival214763f2016-07-01 23:27:018941 EXPECT_THAT(rv, IsOk());
[email protected]3cd17242009-06-23 02:59:028942 EXPECT_EQ("Payload", response_text);
8943}
8944
bncd16676a2016-07-20 16:23:018945TEST_F(HttpNetworkTransactionTest, SOCKS4_SSL_GET) {
[email protected]cb9bf6ca2011-01-28 13:15:278946 HttpRequestInfo request;
8947 request.method = "GET";
bncce36dca22015-04-21 22:11:238948 request.url = GURL("https://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:278949
rdsmith82957ad2015-09-16 19:42:038950 session_deps_.proxy_service =
8951 ProxyService::CreateFixedFromPacResult("SOCKS myproxy:1080");
vishal.b62985ca92015-04-17 08:45:518952 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:078953 session_deps_.net_log = &net_log;
[email protected]3cd17242009-06-23 02:59:028954
danakj1fd259a02016-04-16 03:17:098955 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:168956 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]3cd17242009-06-23 02:59:028957
[email protected]3cd17242009-06-23 02:59:028958 unsigned char write_buffer[] = { 0x04, 0x01, 0x01, 0xBB, 127, 0, 0, 1, 0 };
8959 unsigned char read_buffer[] = { 0x00, 0x5A, 0x00, 0x00, 0, 0, 0, 0 };
8960
8961 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:238962 MockWrite(ASYNC, reinterpret_cast<char*>(write_buffer),
8963 arraysize(write_buffer)),
8964 MockWrite(
8965 "GET / HTTP/1.1\r\n"
8966 "Host: www.example.org\r\n"
8967 "Connection: keep-alive\r\n\r\n")};
[email protected]3cd17242009-06-23 02:59:028968
8969 MockRead data_reads[] = {
[email protected]f871ee152012-07-27 19:02:018970 MockRead(ASYNC, reinterpret_cast<char*>(read_buffer),
8971 arraysize(read_buffer)),
[email protected]e0c27be2009-07-15 13:09:358972 MockRead("HTTP/1.0 200 OK\r\n"),
8973 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n\r\n"),
8974 MockRead("Payload"),
[email protected]8ddf8322012-02-23 18:08:068975 MockRead(SYNCHRONOUS, OK)
[email protected]e0c27be2009-07-15 13:09:358976 };
8977
[email protected]31a2bfe2010-02-09 08:03:398978 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
8979 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:078980 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]e0c27be2009-07-15 13:09:358981
[email protected]8ddf8322012-02-23 18:08:068982 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:078983 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]e0c27be2009-07-15 13:09:358984
[email protected]49639fa2011-12-20 23:22:418985 TestCompletionCallback callback;
[email protected]e0c27be2009-07-15 13:09:358986
tfarina42834112016-09-22 13:38:208987 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:018988 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]e0c27be2009-07-15 13:09:358989
8990 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:018991 EXPECT_THAT(rv, IsOk());
[email protected]e0c27be2009-07-15 13:09:358992
[email protected]029c83b62013-01-24 05:28:208993 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:168994 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]029c83b62013-01-24 05:28:208995 TestLoadTimingNotReusedWithPac(load_timing_info,
8996 CONNECT_TIMING_HAS_SSL_TIMES);
8997
bnc691fda62016-08-12 00:43:168998 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:528999 ASSERT_TRUE(response);
tbansal2ecbbc72016-10-06 17:15:479000 EXPECT_EQ(ProxyServer::SCHEME_SOCKS4, response->proxy_server.scheme());
[email protected]e0c27be2009-07-15 13:09:359001
9002 std::string response_text;
bnc691fda62016-08-12 00:43:169003 rv = ReadTransaction(&trans, &response_text);
robpercival214763f2016-07-01 23:27:019004 EXPECT_THAT(rv, IsOk());
[email protected]e0c27be2009-07-15 13:09:359005 EXPECT_EQ("Payload", response_text);
9006}
9007
bncd16676a2016-07-20 16:23:019008TEST_F(HttpNetworkTransactionTest, SOCKS4_HTTP_GET_no_PAC) {
[email protected]029c83b62013-01-24 05:28:209009 HttpRequestInfo request;
9010 request.method = "GET";
bncce36dca22015-04-21 22:11:239011 request.url = GURL("http://www.example.org/");
[email protected]029c83b62013-01-24 05:28:209012
rdsmith82957ad2015-09-16 19:42:039013 session_deps_.proxy_service =
9014 ProxyService::CreateFixed("socks4://myproxy:1080");
vishal.b62985ca92015-04-17 08:45:519015 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:079016 session_deps_.net_log = &net_log;
[email protected]029c83b62013-01-24 05:28:209017
danakj1fd259a02016-04-16 03:17:099018 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:169019 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]029c83b62013-01-24 05:28:209020
9021 char write_buffer[] = { 0x04, 0x01, 0x00, 0x50, 127, 0, 0, 1, 0 };
9022 char read_buffer[] = { 0x00, 0x5A, 0x00, 0x00, 0, 0, 0, 0 };
9023
9024 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:239025 MockWrite(ASYNC, write_buffer, arraysize(write_buffer)),
9026 MockWrite(
9027 "GET / HTTP/1.1\r\n"
9028 "Host: www.example.org\r\n"
9029 "Connection: keep-alive\r\n\r\n")};
[email protected]029c83b62013-01-24 05:28:209030
9031 MockRead data_reads[] = {
9032 MockRead(ASYNC, read_buffer, arraysize(read_buffer)),
9033 MockRead("HTTP/1.0 200 OK\r\n"),
9034 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n\r\n"),
9035 MockRead("Payload"),
9036 MockRead(SYNCHRONOUS, OK)
9037 };
9038
9039 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
9040 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:079041 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]029c83b62013-01-24 05:28:209042
9043 TestCompletionCallback callback;
9044
tfarina42834112016-09-22 13:38:209045 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:019046 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]029c83b62013-01-24 05:28:209047
9048 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:019049 EXPECT_THAT(rv, IsOk());
[email protected]029c83b62013-01-24 05:28:209050
bnc691fda62016-08-12 00:43:169051 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:529052 ASSERT_TRUE(response);
[email protected]029c83b62013-01-24 05:28:209053
9054 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:169055 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]029c83b62013-01-24 05:28:209056 TestLoadTimingNotReused(load_timing_info,
9057 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
9058
9059 std::string response_text;
bnc691fda62016-08-12 00:43:169060 rv = ReadTransaction(&trans, &response_text);
robpercival214763f2016-07-01 23:27:019061 EXPECT_THAT(rv, IsOk());
[email protected]029c83b62013-01-24 05:28:209062 EXPECT_EQ("Payload", response_text);
9063}
9064
bncd16676a2016-07-20 16:23:019065TEST_F(HttpNetworkTransactionTest, SOCKS5_HTTP_GET) {
[email protected]cb9bf6ca2011-01-28 13:15:279066 HttpRequestInfo request;
9067 request.method = "GET";
bncce36dca22015-04-21 22:11:239068 request.url = GURL("http://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:279069
rdsmith82957ad2015-09-16 19:42:039070 session_deps_.proxy_service =
9071 ProxyService::CreateFixedFromPacResult("SOCKS5 myproxy:1080");
vishal.b62985ca92015-04-17 08:45:519072 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:079073 session_deps_.net_log = &net_log;
[email protected]e0c27be2009-07-15 13:09:359074
danakj1fd259a02016-04-16 03:17:099075 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:169076 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]e0c27be2009-07-15 13:09:359077
[email protected]e0c27be2009-07-15 13:09:359078 const char kSOCKS5GreetRequest[] = { 0x05, 0x01, 0x00 };
9079 const char kSOCKS5GreetResponse[] = { 0x05, 0x00 };
[email protected]f209dba2009-12-18 00:24:379080 const char kSOCKS5OkRequest[] = {
bncce36dca22015-04-21 22:11:239081 0x05, // Version
9082 0x01, // Command (CONNECT)
9083 0x00, // Reserved.
9084 0x03, // Address type (DOMAINNAME).
9085 0x0F, // Length of domain (15)
9086 'w', 'w', 'w', '.', 'e', 'x', 'a', 'm', 'p', 'l', 'e', // Domain string
9087 '.', 'o', 'r', 'g', 0x00, 0x50, // 16-bit port (80)
[email protected]f209dba2009-12-18 00:24:379088 };
[email protected]e0c27be2009-07-15 13:09:359089 const char kSOCKS5OkResponse[] =
9090 { 0x05, 0x00, 0x00, 0x01, 127, 0, 0, 1, 0x00, 0x50 };
9091
9092 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:239093 MockWrite(ASYNC, kSOCKS5GreetRequest, arraysize(kSOCKS5GreetRequest)),
9094 MockWrite(ASYNC, kSOCKS5OkRequest, arraysize(kSOCKS5OkRequest)),
9095 MockWrite(
9096 "GET / HTTP/1.1\r\n"
9097 "Host: www.example.org\r\n"
9098 "Connection: keep-alive\r\n\r\n")};
[email protected]e0c27be2009-07-15 13:09:359099
9100 MockRead data_reads[] = {
[email protected]f871ee152012-07-27 19:02:019101 MockRead(ASYNC, kSOCKS5GreetResponse, arraysize(kSOCKS5GreetResponse)),
9102 MockRead(ASYNC, kSOCKS5OkResponse, arraysize(kSOCKS5OkResponse)),
[email protected]e0c27be2009-07-15 13:09:359103 MockRead("HTTP/1.0 200 OK\r\n"),
9104 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n\r\n"),
9105 MockRead("Payload"),
[email protected]8ddf8322012-02-23 18:08:069106 MockRead(SYNCHRONOUS, OK)
[email protected]e0c27be2009-07-15 13:09:359107 };
9108
[email protected]31a2bfe2010-02-09 08:03:399109 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
9110 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:079111 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]e0c27be2009-07-15 13:09:359112
[email protected]49639fa2011-12-20 23:22:419113 TestCompletionCallback callback;
[email protected]e0c27be2009-07-15 13:09:359114
tfarina42834112016-09-22 13:38:209115 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:019116 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]e0c27be2009-07-15 13:09:359117
9118 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:019119 EXPECT_THAT(rv, IsOk());
[email protected]e0c27be2009-07-15 13:09:359120
bnc691fda62016-08-12 00:43:169121 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:529122 ASSERT_TRUE(response);
tbansal2ecbbc72016-10-06 17:15:479123 EXPECT_EQ(ProxyServer::SCHEME_SOCKS5, response->proxy_server.scheme());
[email protected]e0c27be2009-07-15 13:09:359124
[email protected]029c83b62013-01-24 05:28:209125 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:169126 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]029c83b62013-01-24 05:28:209127 TestLoadTimingNotReusedWithPac(load_timing_info,
9128 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
9129
[email protected]e0c27be2009-07-15 13:09:359130 std::string response_text;
bnc691fda62016-08-12 00:43:169131 rv = ReadTransaction(&trans, &response_text);
robpercival214763f2016-07-01 23:27:019132 EXPECT_THAT(rv, IsOk());
[email protected]e0c27be2009-07-15 13:09:359133 EXPECT_EQ("Payload", response_text);
9134}
9135
bncd16676a2016-07-20 16:23:019136TEST_F(HttpNetworkTransactionTest, SOCKS5_SSL_GET) {
[email protected]cb9bf6ca2011-01-28 13:15:279137 HttpRequestInfo request;
9138 request.method = "GET";
bncce36dca22015-04-21 22:11:239139 request.url = GURL("https://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:279140
rdsmith82957ad2015-09-16 19:42:039141 session_deps_.proxy_service =
9142 ProxyService::CreateFixedFromPacResult("SOCKS5 myproxy:1080");
vishal.b62985ca92015-04-17 08:45:519143 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:079144 session_deps_.net_log = &net_log;
[email protected]e0c27be2009-07-15 13:09:359145
danakj1fd259a02016-04-16 03:17:099146 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:169147 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]e0c27be2009-07-15 13:09:359148
[email protected]e0c27be2009-07-15 13:09:359149 const char kSOCKS5GreetRequest[] = { 0x05, 0x01, 0x00 };
9150 const char kSOCKS5GreetResponse[] = { 0x05, 0x00 };
[email protected]f209dba2009-12-18 00:24:379151 const unsigned char kSOCKS5OkRequest[] = {
bncce36dca22015-04-21 22:11:239152 0x05, // Version
9153 0x01, // Command (CONNECT)
9154 0x00, // Reserved.
9155 0x03, // Address type (DOMAINNAME).
9156 0x0F, // Length of domain (15)
9157 'w', 'w', 'w', '.', 'e', 'x', 'a', 'm', 'p', 'l', 'e', // Domain string
9158 '.', 'o', 'r', 'g', 0x01, 0xBB, // 16-bit port (443)
[email protected]f209dba2009-12-18 00:24:379159 };
9160
[email protected]e0c27be2009-07-15 13:09:359161 const char kSOCKS5OkResponse[] =
9162 { 0x05, 0x00, 0x00, 0x01, 0, 0, 0, 0, 0x00, 0x00 };
9163
9164 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:239165 MockWrite(ASYNC, kSOCKS5GreetRequest, arraysize(kSOCKS5GreetRequest)),
9166 MockWrite(ASYNC, reinterpret_cast<const char*>(kSOCKS5OkRequest),
9167 arraysize(kSOCKS5OkRequest)),
9168 MockWrite(
9169 "GET / HTTP/1.1\r\n"
9170 "Host: www.example.org\r\n"
9171 "Connection: keep-alive\r\n\r\n")};
[email protected]e0c27be2009-07-15 13:09:359172
9173 MockRead data_reads[] = {
[email protected]f871ee152012-07-27 19:02:019174 MockRead(ASYNC, kSOCKS5GreetResponse, arraysize(kSOCKS5GreetResponse)),
9175 MockRead(ASYNC, kSOCKS5OkResponse, arraysize(kSOCKS5OkResponse)),
[email protected]3cd17242009-06-23 02:59:029176 MockRead("HTTP/1.0 200 OK\r\n"),
9177 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n\r\n"),
9178 MockRead("Payload"),
[email protected]8ddf8322012-02-23 18:08:069179 MockRead(SYNCHRONOUS, OK)
[email protected]3cd17242009-06-23 02:59:029180 };
9181
[email protected]31a2bfe2010-02-09 08:03:399182 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
9183 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:079184 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]3cd17242009-06-23 02:59:029185
[email protected]8ddf8322012-02-23 18:08:069186 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:079187 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]3cd17242009-06-23 02:59:029188
[email protected]49639fa2011-12-20 23:22:419189 TestCompletionCallback callback;
[email protected]3cd17242009-06-23 02:59:029190
tfarina42834112016-09-22 13:38:209191 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:019192 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]3cd17242009-06-23 02:59:029193
9194 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:019195 EXPECT_THAT(rv, IsOk());
[email protected]3cd17242009-06-23 02:59:029196
bnc691fda62016-08-12 00:43:169197 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:529198 ASSERT_TRUE(response);
tbansal2ecbbc72016-10-06 17:15:479199 EXPECT_EQ(ProxyServer::SCHEME_SOCKS5, response->proxy_server.scheme());
[email protected]3cd17242009-06-23 02:59:029200
[email protected]029c83b62013-01-24 05:28:209201 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:169202 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]029c83b62013-01-24 05:28:209203 TestLoadTimingNotReusedWithPac(load_timing_info,
9204 CONNECT_TIMING_HAS_SSL_TIMES);
9205
[email protected]3cd17242009-06-23 02:59:029206 std::string response_text;
bnc691fda62016-08-12 00:43:169207 rv = ReadTransaction(&trans, &response_text);
robpercival214763f2016-07-01 23:27:019208 EXPECT_THAT(rv, IsOk());
[email protected]3cd17242009-06-23 02:59:029209 EXPECT_EQ("Payload", response_text);
9210}
9211
[email protected]448d4ca52012-03-04 04:12:239212namespace {
9213
[email protected]04e5be32009-06-26 20:00:319214// Tests that for connection endpoints the group names are correctly set.
[email protected]2d731a32010-04-29 01:04:069215
9216struct GroupNameTest {
9217 std::string proxy_server;
9218 std::string url;
9219 std::string expected_group_name;
[email protected]e60e47a2010-07-14 03:37:189220 bool ssl;
[email protected]2d731a32010-04-29 01:04:069221};
9222
danakj1fd259a02016-04-16 03:17:099223std::unique_ptr<HttpNetworkSession> SetupSessionForGroupNameTests(
[email protected]bb88e1d32013-05-03 23:11:079224 SpdySessionDependencies* session_deps_) {
danakj1fd259a02016-04-16 03:17:099225 std::unique_ptr<HttpNetworkSession> session(CreateSession(session_deps_));
[email protected]2d731a32010-04-29 01:04:069226
bnc525e175a2016-06-20 12:36:409227 HttpServerProperties* http_server_properties =
[email protected]17291a022011-10-10 07:32:539228 session->http_server_properties();
bnc3472afd2016-11-17 15:27:219229 AlternativeService alternative_service(kProtoHTTP2, "", 444);
bnc7dc7e1b42015-07-28 14:43:129230 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
bnccacc0992015-03-20 20:22:229231 http_server_properties->SetAlternativeService(
bncaa60ff402016-06-22 19:12:429232 url::SchemeHostPort("https", "host.with.alternate", 443),
zhongyi3d4a55e72016-04-22 20:36:469233 alternative_service, expiration);
[email protected]2d731a32010-04-29 01:04:069234
9235 return session;
9236}
9237
mmenkee65e7af2015-10-13 17:16:429238int GroupNameTransactionHelper(const std::string& url,
9239 HttpNetworkSession* session) {
[email protected]2d731a32010-04-29 01:04:069240 HttpRequestInfo request;
9241 request.method = "GET";
9242 request.url = GURL(url);
[email protected]2d731a32010-04-29 01:04:069243
bnc691fda62016-08-12 00:43:169244 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session);
[email protected]cb9bf6ca2011-01-28 13:15:279245
[email protected]49639fa2011-12-20 23:22:419246 TestCompletionCallback callback;
[email protected]2d731a32010-04-29 01:04:069247
9248 // We do not complete this request, the dtor will clean the transaction up.
tfarina42834112016-09-22 13:38:209249 return trans.Start(&request, callback.callback(), NetLogWithSource());
[email protected]2d731a32010-04-29 01:04:069250}
9251
[email protected]448d4ca52012-03-04 04:12:239252} // namespace
9253
bncd16676a2016-07-20 16:23:019254TEST_F(HttpNetworkTransactionTest, GroupNameForDirectConnections) {
[email protected]2d731a32010-04-29 01:04:069255 const GroupNameTest tests[] = {
bncce36dca22015-04-21 22:11:239256 {
9257 "", // unused
9258 "http://www.example.org/direct",
9259 "www.example.org:80",
9260 false,
9261 },
9262 {
9263 "", // unused
9264 "http://[2001:1418:13:1::25]/direct",
9265 "[2001:1418:13:1::25]:80",
9266 false,
9267 },
[email protected]04e5be32009-06-26 20:00:319268
bncce36dca22015-04-21 22:11:239269 // SSL Tests
9270 {
9271 "", // unused
9272 "https://www.example.org/direct_ssl",
9273 "ssl/www.example.org:443",
9274 true,
9275 },
9276 {
9277 "", // unused
9278 "https://[2001:1418:13:1::25]/direct",
9279 "ssl/[2001:1418:13:1::25]:443",
9280 true,
9281 },
9282 {
9283 "", // unused
bncaa60ff402016-06-22 19:12:429284 "https://host.with.alternate/direct",
bncce36dca22015-04-21 22:11:239285 "ssl/host.with.alternate:443",
9286 true,
9287 },
[email protected]2d731a32010-04-29 01:04:069288 };
[email protected]2ff8b312010-04-26 22:20:549289
viettrungluue4a8b882014-10-16 06:17:389290 for (size_t i = 0; i < arraysize(tests); ++i) {
rdsmith82957ad2015-09-16 19:42:039291 session_deps_.proxy_service =
9292 ProxyService::CreateFixed(tests[i].proxy_server);
danakj1fd259a02016-04-16 03:17:099293 std::unique_ptr<HttpNetworkSession> session(
bnca9b9e222016-07-11 20:10:409294 SetupSessionForGroupNameTests(&session_deps_));
[email protected]2d731a32010-04-29 01:04:069295
mmenkee65e7af2015-10-13 17:16:429296 HttpNetworkSessionPeer peer(session.get());
[email protected]ab739042011-04-07 15:22:289297 CaptureGroupNameTransportSocketPool* transport_conn_pool =
9298 new CaptureGroupNameTransportSocketPool(NULL, NULL);
[email protected]2431756e2010-09-29 20:26:139299 CaptureGroupNameSSLSocketPool* ssl_conn_pool =
[email protected]9e1bdd32011-02-03 21:48:349300 new CaptureGroupNameSSLSocketPool(NULL, NULL);
danakj1fd259a02016-04-16 03:17:099301 std::unique_ptr<MockClientSocketPoolManager> mock_pool_manager(
[email protected]831e4a32013-11-14 02:14:449302 new MockClientSocketPoolManager);
[email protected]a42dbd142011-11-17 16:42:029303 mock_pool_manager->SetTransportSocketPool(transport_conn_pool);
9304 mock_pool_manager->SetSSLSocketPool(ssl_conn_pool);
dchengc7eeda422015-12-26 03:56:489305 peer.SetClientSocketPoolManager(std::move(mock_pool_manager));
[email protected]2d731a32010-04-29 01:04:069306
9307 EXPECT_EQ(ERR_IO_PENDING,
mmenkee65e7af2015-10-13 17:16:429308 GroupNameTransactionHelper(tests[i].url, session.get()));
[email protected]e60e47a2010-07-14 03:37:189309 if (tests[i].ssl)
9310 EXPECT_EQ(tests[i].expected_group_name,
9311 ssl_conn_pool->last_group_name_received());
9312 else
9313 EXPECT_EQ(tests[i].expected_group_name,
[email protected]ab739042011-04-07 15:22:289314 transport_conn_pool->last_group_name_received());
[email protected]2d731a32010-04-29 01:04:069315 }
[email protected]2d731a32010-04-29 01:04:069316}
9317
bncd16676a2016-07-20 16:23:019318TEST_F(HttpNetworkTransactionTest, GroupNameForHTTPProxyConnections) {
[email protected]2d731a32010-04-29 01:04:069319 const GroupNameTest tests[] = {
bncce36dca22015-04-21 22:11:239320 {
9321 "http_proxy",
9322 "http://www.example.org/http_proxy_normal",
9323 "www.example.org:80",
9324 false,
9325 },
[email protected]2d731a32010-04-29 01:04:069326
bncce36dca22015-04-21 22:11:239327 // SSL Tests
9328 {
9329 "http_proxy",
9330 "https://www.example.org/http_connect_ssl",
9331 "ssl/www.example.org:443",
9332 true,
9333 },
[email protected]af3490e2010-10-16 21:02:299334
bncce36dca22015-04-21 22:11:239335 {
9336 "http_proxy",
bncaa60ff402016-06-22 19:12:429337 "https://host.with.alternate/direct",
bncce36dca22015-04-21 22:11:239338 "ssl/host.with.alternate:443",
9339 true,
9340 },
[email protected]45499252013-01-23 17:12:569341
bncce36dca22015-04-21 22:11:239342 {
9343 "http_proxy",
9344 "ftp://ftp.google.com/http_proxy_normal",
9345 "ftp/ftp.google.com:21",
9346 false,
9347 },
[email protected]2d731a32010-04-29 01:04:069348 };
9349
viettrungluue4a8b882014-10-16 06:17:389350 for (size_t i = 0; i < arraysize(tests); ++i) {
rdsmith82957ad2015-09-16 19:42:039351 session_deps_.proxy_service =
9352 ProxyService::CreateFixed(tests[i].proxy_server);
danakj1fd259a02016-04-16 03:17:099353 std::unique_ptr<HttpNetworkSession> session(
bnca9b9e222016-07-11 20:10:409354 SetupSessionForGroupNameTests(&session_deps_));
[email protected]2d731a32010-04-29 01:04:069355
mmenkee65e7af2015-10-13 17:16:429356 HttpNetworkSessionPeer peer(session.get());
[email protected]2d731a32010-04-29 01:04:069357
[email protected]e60e47a2010-07-14 03:37:189358 HostPortPair proxy_host("http_proxy", 80);
[email protected]2431756e2010-09-29 20:26:139359 CaptureGroupNameHttpProxySocketPool* http_proxy_pool =
[email protected]9e1bdd32011-02-03 21:48:349360 new CaptureGroupNameHttpProxySocketPool(NULL, NULL);
[email protected]2431756e2010-09-29 20:26:139361 CaptureGroupNameSSLSocketPool* ssl_conn_pool =
[email protected]9e1bdd32011-02-03 21:48:349362 new CaptureGroupNameSSLSocketPool(NULL, NULL);
[email protected]a42dbd142011-11-17 16:42:029363
danakj1fd259a02016-04-16 03:17:099364 std::unique_ptr<MockClientSocketPoolManager> mock_pool_manager(
[email protected]831e4a32013-11-14 02:14:449365 new MockClientSocketPoolManager);
aviadef3442016-10-03 18:50:399366 mock_pool_manager->SetSocketPoolForHTTPProxy(
9367 proxy_host, base::WrapUnique(http_proxy_pool));
9368 mock_pool_manager->SetSocketPoolForSSLWithProxy(
9369 proxy_host, base::WrapUnique(ssl_conn_pool));
dchengc7eeda422015-12-26 03:56:489370 peer.SetClientSocketPoolManager(std::move(mock_pool_manager));
[email protected]2d731a32010-04-29 01:04:069371
9372 EXPECT_EQ(ERR_IO_PENDING,
mmenkee65e7af2015-10-13 17:16:429373 GroupNameTransactionHelper(tests[i].url, session.get()));
[email protected]e60e47a2010-07-14 03:37:189374 if (tests[i].ssl)
9375 EXPECT_EQ(tests[i].expected_group_name,
9376 ssl_conn_pool->last_group_name_received());
9377 else
9378 EXPECT_EQ(tests[i].expected_group_name,
9379 http_proxy_pool->last_group_name_received());
[email protected]2d731a32010-04-29 01:04:069380 }
[email protected]2d731a32010-04-29 01:04:069381}
9382
bncd16676a2016-07-20 16:23:019383TEST_F(HttpNetworkTransactionTest, GroupNameForSOCKSConnections) {
[email protected]2d731a32010-04-29 01:04:069384 const GroupNameTest tests[] = {
bncce36dca22015-04-21 22:11:239385 {
9386 "socks4://socks_proxy:1080",
9387 "http://www.example.org/socks4_direct",
9388 "socks4/www.example.org:80",
9389 false,
9390 },
9391 {
9392 "socks5://socks_proxy:1080",
9393 "http://www.example.org/socks5_direct",
9394 "socks5/www.example.org:80",
9395 false,
9396 },
[email protected]2d731a32010-04-29 01:04:069397
bncce36dca22015-04-21 22:11:239398 // SSL Tests
9399 {
9400 "socks4://socks_proxy:1080",
9401 "https://www.example.org/socks4_ssl",
9402 "socks4/ssl/www.example.org:443",
9403 true,
9404 },
9405 {
9406 "socks5://socks_proxy:1080",
9407 "https://www.example.org/socks5_ssl",
9408 "socks5/ssl/www.example.org:443",
9409 true,
9410 },
[email protected]af3490e2010-10-16 21:02:299411
bncce36dca22015-04-21 22:11:239412 {
9413 "socks4://socks_proxy:1080",
bncaa60ff402016-06-22 19:12:429414 "https://host.with.alternate/direct",
bncce36dca22015-04-21 22:11:239415 "socks4/ssl/host.with.alternate:443",
9416 true,
9417 },
[email protected]04e5be32009-06-26 20:00:319418 };
9419
viettrungluue4a8b882014-10-16 06:17:389420 for (size_t i = 0; i < arraysize(tests); ++i) {
rdsmith82957ad2015-09-16 19:42:039421 session_deps_.proxy_service =
9422 ProxyService::CreateFixed(tests[i].proxy_server);
danakj1fd259a02016-04-16 03:17:099423 std::unique_ptr<HttpNetworkSession> session(
bnca9b9e222016-07-11 20:10:409424 SetupSessionForGroupNameTests(&session_deps_));
[email protected]8b114dd72011-03-25 05:33:029425
mmenkee65e7af2015-10-13 17:16:429426 HttpNetworkSessionPeer peer(session.get());
[email protected]04e5be32009-06-26 20:00:319427
[email protected]e60e47a2010-07-14 03:37:189428 HostPortPair proxy_host("socks_proxy", 1080);
[email protected]2431756e2010-09-29 20:26:139429 CaptureGroupNameSOCKSSocketPool* socks_conn_pool =
[email protected]9e1bdd32011-02-03 21:48:349430 new CaptureGroupNameSOCKSSocketPool(NULL, NULL);
[email protected]2431756e2010-09-29 20:26:139431 CaptureGroupNameSSLSocketPool* ssl_conn_pool =
[email protected]9e1bdd32011-02-03 21:48:349432 new CaptureGroupNameSSLSocketPool(NULL, NULL);
[email protected]a42dbd142011-11-17 16:42:029433
danakj1fd259a02016-04-16 03:17:099434 std::unique_ptr<MockClientSocketPoolManager> mock_pool_manager(
[email protected]831e4a32013-11-14 02:14:449435 new MockClientSocketPoolManager);
aviadef3442016-10-03 18:50:399436 mock_pool_manager->SetSocketPoolForSOCKSProxy(
9437 proxy_host, base::WrapUnique(socks_conn_pool));
9438 mock_pool_manager->SetSocketPoolForSSLWithProxy(
9439 proxy_host, base::WrapUnique(ssl_conn_pool));
dchengc7eeda422015-12-26 03:56:489440 peer.SetClientSocketPoolManager(std::move(mock_pool_manager));
[email protected]04e5be32009-06-26 20:00:319441
bnc691fda62016-08-12 00:43:169442 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]04e5be32009-06-26 20:00:319443
[email protected]2d731a32010-04-29 01:04:069444 EXPECT_EQ(ERR_IO_PENDING,
mmenkee65e7af2015-10-13 17:16:429445 GroupNameTransactionHelper(tests[i].url, session.get()));
[email protected]e60e47a2010-07-14 03:37:189446 if (tests[i].ssl)
9447 EXPECT_EQ(tests[i].expected_group_name,
9448 ssl_conn_pool->last_group_name_received());
9449 else
9450 EXPECT_EQ(tests[i].expected_group_name,
9451 socks_conn_pool->last_group_name_received());
[email protected]04e5be32009-06-26 20:00:319452 }
9453}
9454
bncd16676a2016-07-20 16:23:019455TEST_F(HttpNetworkTransactionTest, ReconsiderProxyAfterFailedConnection) {
[email protected]cb9bf6ca2011-01-28 13:15:279456 HttpRequestInfo request;
9457 request.method = "GET";
bncce36dca22015-04-21 22:11:239458 request.url = GURL("http://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:279459
rdsmith82957ad2015-09-16 19:42:039460 session_deps_.proxy_service =
9461 ProxyService::CreateFixed("myproxy:70;foobar:80");
[email protected]b59ff372009-07-15 22:04:329462
[email protected]69719062010-01-05 20:09:219463 // This simulates failure resolving all hostnames; that means we will fail
9464 // connecting to both proxies (myproxy:70 and foobar:80).
[email protected]bb88e1d32013-05-03 23:11:079465 session_deps_.host_resolver->rules()->AddSimulatedFailure("*");
[email protected]b59ff372009-07-15 22:04:329466
danakj1fd259a02016-04-16 03:17:099467 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:169468 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]9172a982009-06-06 00:30:259469
[email protected]49639fa2011-12-20 23:22:419470 TestCompletionCallback callback;
[email protected]9172a982009-06-06 00:30:259471
tfarina42834112016-09-22 13:38:209472 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:019473 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]9172a982009-06-06 00:30:259474
[email protected]9172a982009-06-06 00:30:259475 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:019476 EXPECT_THAT(rv, IsError(ERR_PROXY_CONNECTION_FAILED));
[email protected]9172a982009-06-06 00:30:259477}
9478
[email protected]685af592010-05-11 19:31:249479// Base test to make sure that when the load flags for a request specify to
9480// bypass the cache, the DNS cache is not used.
[email protected]23e482282013-06-14 16:08:029481void HttpNetworkTransactionTest::BypassHostCacheOnRefreshHelper(
[email protected]bb88e1d32013-05-03 23:11:079482 int load_flags) {
[email protected]cb9bf6ca2011-01-28 13:15:279483 // Issue a request, asking to bypass the cache(s).
maksim.sisov31452af2016-07-27 06:38:109484 HttpRequestInfo request_info;
9485 request_info.method = "GET";
9486 request_info.load_flags = load_flags;
9487 request_info.url = GURL("http://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:279488
[email protected]a2c2fb92009-07-18 07:31:049489 // Select a host resolver that does caching.
[email protected]bb88e1d32013-05-03 23:11:079490 session_deps_.host_resolver.reset(new MockCachingHostResolver);
[email protected]b59ff372009-07-15 22:04:329491
danakj1fd259a02016-04-16 03:17:099492 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:169493 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]3b9cca42009-06-16 01:08:289494
bncce36dca22015-04-21 22:11:239495 // Warm up the host cache so it has an entry for "www.example.org".
[email protected]3b9cca42009-06-16 01:08:289496 AddressList addrlist;
[email protected]aa22b242011-11-16 18:58:299497 TestCompletionCallback callback;
maksim.sisov31452af2016-07-27 06:38:109498 std::unique_ptr<HostResolver::Request> request1;
[email protected]bb88e1d32013-05-03 23:11:079499 int rv = session_deps_.host_resolver->Resolve(
bncce36dca22015-04-21 22:11:239500 HostResolver::RequestInfo(HostPortPair("www.example.org", 80)),
maksim.sisov31452af2016-07-27 06:38:109501 DEFAULT_PRIORITY, &addrlist, callback.callback(), &request1,
tfarina42834112016-09-22 13:38:209502 NetLogWithSource());
robpercival214763f2016-07-01 23:27:019503 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]6e78dfb2011-07-28 21:34:479504 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:019505 EXPECT_THAT(rv, IsOk());
[email protected]3b9cca42009-06-16 01:08:289506
9507 // Verify that it was added to host cache, by doing a subsequent async lookup
9508 // and confirming it completes synchronously.
maksim.sisov31452af2016-07-27 06:38:109509 std::unique_ptr<HostResolver::Request> request2;
[email protected]bb88e1d32013-05-03 23:11:079510 rv = session_deps_.host_resolver->Resolve(
bncce36dca22015-04-21 22:11:239511 HostResolver::RequestInfo(HostPortPair("www.example.org", 80)),
maksim.sisov31452af2016-07-27 06:38:109512 DEFAULT_PRIORITY, &addrlist, callback.callback(), &request2,
tfarina42834112016-09-22 13:38:209513 NetLogWithSource());
robpercival214763f2016-07-01 23:27:019514 ASSERT_THAT(rv, IsOk());
[email protected]3b9cca42009-06-16 01:08:289515
bncce36dca22015-04-21 22:11:239516 // Inject a failure the next time that "www.example.org" is resolved. This way
[email protected]3b9cca42009-06-16 01:08:289517 // we can tell if the next lookup hit the cache, or the "network".
9518 // (cache --> success, "network" --> failure).
bncce36dca22015-04-21 22:11:239519 session_deps_.host_resolver->rules()->AddSimulatedFailure("www.example.org");
[email protected]3b9cca42009-06-16 01:08:289520
9521 // Connect up a mock socket which will fail with ERR_UNEXPECTED during the
9522 // first read -- this won't be reached as the host resolution will fail first.
[email protected]8ddf8322012-02-23 18:08:069523 MockRead data_reads[] = { MockRead(SYNCHRONOUS, ERR_UNEXPECTED) };
[email protected]31a2bfe2010-02-09 08:03:399524 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:079525 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]3b9cca42009-06-16 01:08:289526
[email protected]3b9cca42009-06-16 01:08:289527 // Run the request.
tfarina42834112016-09-22 13:38:209528 rv = trans.Start(&request_info, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:019529 ASSERT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]49639fa2011-12-20 23:22:419530 rv = callback.WaitForResult();
[email protected]3b9cca42009-06-16 01:08:289531
9532 // If we bypassed the cache, we would have gotten a failure while resolving
bncce36dca22015-04-21 22:11:239533 // "www.example.org".
robpercival214763f2016-07-01 23:27:019534 EXPECT_THAT(rv, IsError(ERR_NAME_NOT_RESOLVED));
[email protected]3b9cca42009-06-16 01:08:289535}
9536
[email protected]685af592010-05-11 19:31:249537// There are multiple load flags that should trigger the host cache bypass.
9538// Test each in isolation:
bncd16676a2016-07-20 16:23:019539TEST_F(HttpNetworkTransactionTest, BypassHostCacheOnRefresh1) {
[email protected]685af592010-05-11 19:31:249540 BypassHostCacheOnRefreshHelper(LOAD_BYPASS_CACHE);
9541}
9542
bncd16676a2016-07-20 16:23:019543TEST_F(HttpNetworkTransactionTest, BypassHostCacheOnRefresh2) {
[email protected]685af592010-05-11 19:31:249544 BypassHostCacheOnRefreshHelper(LOAD_VALIDATE_CACHE);
9545}
9546
bncd16676a2016-07-20 16:23:019547TEST_F(HttpNetworkTransactionTest, BypassHostCacheOnRefresh3) {
[email protected]685af592010-05-11 19:31:249548 BypassHostCacheOnRefreshHelper(LOAD_DISABLE_CACHE);
9549}
9550
[email protected]0877e3d2009-10-17 22:29:579551// Make sure we can handle an error when writing the request.
bncd16676a2016-07-20 16:23:019552TEST_F(HttpNetworkTransactionTest, RequestWriteError) {
[email protected]0877e3d2009-10-17 22:29:579553 HttpRequestInfo request;
9554 request.method = "GET";
9555 request.url = GURL("http://www.foo.com/");
[email protected]0877e3d2009-10-17 22:29:579556
9557 MockWrite write_failure[] = {
[email protected]8ddf8322012-02-23 18:08:069558 MockWrite(ASYNC, ERR_CONNECTION_RESET),
[email protected]0877e3d2009-10-17 22:29:579559 };
[email protected]31a2bfe2010-02-09 08:03:399560 StaticSocketDataProvider data(NULL, 0,
9561 write_failure, arraysize(write_failure));
[email protected]bb88e1d32013-05-03 23:11:079562 session_deps_.socket_factory->AddSocketDataProvider(&data);
danakj1fd259a02016-04-16 03:17:099563 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]0877e3d2009-10-17 22:29:579564
[email protected]49639fa2011-12-20 23:22:419565 TestCompletionCallback callback;
[email protected]0877e3d2009-10-17 22:29:579566
bnc691fda62016-08-12 00:43:169567 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]0877e3d2009-10-17 22:29:579568
tfarina42834112016-09-22 13:38:209569 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:019570 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]0877e3d2009-10-17 22:29:579571
9572 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:019573 EXPECT_THAT(rv, IsError(ERR_CONNECTION_RESET));
ttuttled9dbc652015-09-29 20:00:599574
9575 IPEndPoint endpoint;
bnc691fda62016-08-12 00:43:169576 EXPECT_TRUE(trans.GetRemoteEndpoint(&endpoint));
ttuttled9dbc652015-09-29 20:00:599577 EXPECT_LT(0u, endpoint.address().size());
[email protected]0877e3d2009-10-17 22:29:579578}
9579
zmo9528c9f42015-08-04 22:12:089580// Check that a connection closed after the start of the headers finishes ok.
bncd16676a2016-07-20 16:23:019581TEST_F(HttpNetworkTransactionTest, ConnectionClosedAfterStartOfHeaders) {
[email protected]0877e3d2009-10-17 22:29:579582 HttpRequestInfo request;
9583 request.method = "GET";
9584 request.url = GURL("http://www.foo.com/");
[email protected]0877e3d2009-10-17 22:29:579585
9586 MockRead data_reads[] = {
9587 MockRead("HTTP/1."),
[email protected]8ddf8322012-02-23 18:08:069588 MockRead(SYNCHRONOUS, OK),
[email protected]0877e3d2009-10-17 22:29:579589 };
9590
[email protected]31a2bfe2010-02-09 08:03:399591 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:079592 session_deps_.socket_factory->AddSocketDataProvider(&data);
danakj1fd259a02016-04-16 03:17:099593 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]0877e3d2009-10-17 22:29:579594
[email protected]49639fa2011-12-20 23:22:419595 TestCompletionCallback callback;
[email protected]0877e3d2009-10-17 22:29:579596
bnc691fda62016-08-12 00:43:169597 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]0877e3d2009-10-17 22:29:579598
tfarina42834112016-09-22 13:38:209599 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:019600 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]0877e3d2009-10-17 22:29:579601
9602 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:019603 EXPECT_THAT(rv, IsOk());
zmo9528c9f42015-08-04 22:12:089604
bnc691fda62016-08-12 00:43:169605 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:529606 ASSERT_TRUE(response);
zmo9528c9f42015-08-04 22:12:089607
wezca1070932016-05-26 20:30:529608 EXPECT_TRUE(response->headers);
zmo9528c9f42015-08-04 22:12:089609 EXPECT_EQ("HTTP/1.0 200 OK", response->headers->GetStatusLine());
9610
9611 std::string response_data;
bnc691fda62016-08-12 00:43:169612 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:019613 EXPECT_THAT(rv, IsOk());
zmo9528c9f42015-08-04 22:12:089614 EXPECT_EQ("", response_data);
ttuttled9dbc652015-09-29 20:00:599615
9616 IPEndPoint endpoint;
bnc691fda62016-08-12 00:43:169617 EXPECT_TRUE(trans.GetRemoteEndpoint(&endpoint));
ttuttled9dbc652015-09-29 20:00:599618 EXPECT_LT(0u, endpoint.address().size());
[email protected]0877e3d2009-10-17 22:29:579619}
9620
9621// Make sure that a dropped connection while draining the body for auth
9622// restart does the right thing.
bncd16676a2016-07-20 16:23:019623TEST_F(HttpNetworkTransactionTest, DrainResetOK) {
[email protected]0877e3d2009-10-17 22:29:579624 HttpRequestInfo request;
9625 request.method = "GET";
bncce36dca22015-04-21 22:11:239626 request.url = GURL("http://www.example.org/");
[email protected]0877e3d2009-10-17 22:29:579627
9628 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:239629 MockWrite(
9630 "GET / HTTP/1.1\r\n"
9631 "Host: www.example.org\r\n"
9632 "Connection: keep-alive\r\n\r\n"),
[email protected]0877e3d2009-10-17 22:29:579633 };
9634
9635 MockRead data_reads1[] = {
9636 MockRead("HTTP/1.1 401 Unauthorized\r\n"),
9637 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
9638 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
9639 MockRead("Content-Length: 14\r\n\r\n"),
9640 MockRead("Unauth"),
[email protected]8ddf8322012-02-23 18:08:069641 MockRead(ASYNC, ERR_CONNECTION_RESET),
[email protected]0877e3d2009-10-17 22:29:579642 };
9643
[email protected]31a2bfe2010-02-09 08:03:399644 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
9645 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:079646 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]0877e3d2009-10-17 22:29:579647
bnc691fda62016-08-12 00:43:169648 // After calling trans.RestartWithAuth(), this is the request we should
[email protected]0877e3d2009-10-17 22:29:579649 // be issuing -- the final header line contains the credentials.
9650 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:239651 MockWrite(
9652 "GET / HTTP/1.1\r\n"
9653 "Host: www.example.org\r\n"
9654 "Connection: keep-alive\r\n"
9655 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]0877e3d2009-10-17 22:29:579656 };
9657
9658 // Lastly, the server responds with the actual content.
9659 MockRead data_reads2[] = {
9660 MockRead("HTTP/1.1 200 OK\r\n"),
9661 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
9662 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:069663 MockRead(SYNCHRONOUS, OK),
[email protected]0877e3d2009-10-17 22:29:579664 };
9665
[email protected]31a2bfe2010-02-09 08:03:399666 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
9667 data_writes2, arraysize(data_writes2));
[email protected]bb88e1d32013-05-03 23:11:079668 session_deps_.socket_factory->AddSocketDataProvider(&data2);
danakj1fd259a02016-04-16 03:17:099669 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]0877e3d2009-10-17 22:29:579670
[email protected]49639fa2011-12-20 23:22:419671 TestCompletionCallback callback1;
[email protected]0877e3d2009-10-17 22:29:579672
bnc691fda62016-08-12 00:43:169673 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]0b0bf032010-09-21 18:08:509674
tfarina42834112016-09-22 13:38:209675 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:019676 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]0877e3d2009-10-17 22:29:579677
9678 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:019679 EXPECT_THAT(rv, IsOk());
[email protected]0877e3d2009-10-17 22:29:579680
bnc691fda62016-08-12 00:43:169681 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:529682 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:049683 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]0877e3d2009-10-17 22:29:579684
[email protected]49639fa2011-12-20 23:22:419685 TestCompletionCallback callback2;
[email protected]0877e3d2009-10-17 22:29:579686
bnc691fda62016-08-12 00:43:169687 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar), callback2.callback());
robpercival214763f2016-07-01 23:27:019688 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]0877e3d2009-10-17 22:29:579689
9690 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:019691 EXPECT_THAT(rv, IsOk());
[email protected]0877e3d2009-10-17 22:29:579692
bnc691fda62016-08-12 00:43:169693 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:529694 ASSERT_TRUE(response);
9695 EXPECT_FALSE(response->auth_challenge);
[email protected]0877e3d2009-10-17 22:29:579696 EXPECT_EQ(100, response->headers->GetContentLength());
9697}
9698
9699// Test HTTPS connections going through a proxy that sends extra data.
bncd16676a2016-07-20 16:23:019700TEST_F(HttpNetworkTransactionTest, HTTPSViaProxyWithExtraData) {
rdsmith82957ad2015-09-16 19:42:039701 session_deps_.proxy_service = ProxyService::CreateFixed("myproxy:70");
[email protected]0877e3d2009-10-17 22:29:579702
9703 HttpRequestInfo request;
9704 request.method = "GET";
bncce36dca22015-04-21 22:11:239705 request.url = GURL("https://www.example.org/");
[email protected]0877e3d2009-10-17 22:29:579706
9707 MockRead proxy_reads[] = {
9708 MockRead("HTTP/1.0 200 Connected\r\n\r\nExtra data"),
[email protected]8ddf8322012-02-23 18:08:069709 MockRead(SYNCHRONOUS, OK)
[email protected]0877e3d2009-10-17 22:29:579710 };
9711
[email protected]31a2bfe2010-02-09 08:03:399712 StaticSocketDataProvider data(proxy_reads, arraysize(proxy_reads), NULL, 0);
[email protected]8ddf8322012-02-23 18:08:069713 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]0877e3d2009-10-17 22:29:579714
[email protected]bb88e1d32013-05-03 23:11:079715 session_deps_.socket_factory->AddSocketDataProvider(&data);
9716 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]0877e3d2009-10-17 22:29:579717
[email protected]49639fa2011-12-20 23:22:419718 TestCompletionCallback callback;
[email protected]0877e3d2009-10-17 22:29:579719
[email protected]bb88e1d32013-05-03 23:11:079720 session_deps_.socket_factory->ResetNextMockIndexes();
[email protected]0877e3d2009-10-17 22:29:579721
danakj1fd259a02016-04-16 03:17:099722 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:169723 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]0877e3d2009-10-17 22:29:579724
tfarina42834112016-09-22 13:38:209725 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:019726 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]0877e3d2009-10-17 22:29:579727
9728 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:019729 EXPECT_THAT(rv, IsError(ERR_TUNNEL_CONNECTION_FAILED));
[email protected]0877e3d2009-10-17 22:29:579730}
9731
bncd16676a2016-07-20 16:23:019732TEST_F(HttpNetworkTransactionTest, LargeContentLengthThenClose) {
[email protected]9492e4a2010-02-24 00:58:469733 HttpRequestInfo request;
9734 request.method = "GET";
bncce36dca22015-04-21 22:11:239735 request.url = GURL("http://www.example.org/");
[email protected]9492e4a2010-02-24 00:58:469736
danakj1fd259a02016-04-16 03:17:099737 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:169738 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:279739
[email protected]e22e1362009-11-23 21:31:129740 MockRead data_reads[] = {
9741 MockRead("HTTP/1.0 200 OK\r\nContent-Length:6719476739\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:069742 MockRead(SYNCHRONOUS, OK),
[email protected]e22e1362009-11-23 21:31:129743 };
[email protected]9492e4a2010-02-24 00:58:469744
9745 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:079746 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]9492e4a2010-02-24 00:58:469747
[email protected]49639fa2011-12-20 23:22:419748 TestCompletionCallback callback;
[email protected]9492e4a2010-02-24 00:58:469749
tfarina42834112016-09-22 13:38:209750 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:019751 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]9492e4a2010-02-24 00:58:469752
robpercival214763f2016-07-01 23:27:019753 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]9492e4a2010-02-24 00:58:469754
bnc691fda62016-08-12 00:43:169755 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:529756 ASSERT_TRUE(response);
[email protected]9492e4a2010-02-24 00:58:469757
wezca1070932016-05-26 20:30:529758 EXPECT_TRUE(response->headers);
[email protected]9492e4a2010-02-24 00:58:469759 EXPECT_EQ("HTTP/1.0 200 OK", response->headers->GetStatusLine());
9760
9761 std::string response_data;
bnc691fda62016-08-12 00:43:169762 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:019763 EXPECT_THAT(rv, IsError(ERR_CONTENT_LENGTH_MISMATCH));
[email protected]e22e1362009-11-23 21:31:129764}
9765
bncd16676a2016-07-20 16:23:019766TEST_F(HttpNetworkTransactionTest, UploadFileSmallerThanLength) {
[email protected]6cdfd7f2013-02-08 20:40:159767 base::FilePath temp_file_path;
[email protected]03d9afc02013-12-03 17:55:529768 ASSERT_TRUE(base::CreateTemporaryFile(&temp_file_path));
avibf0746c2015-12-09 19:53:149769 const uint64_t kFakeSize = 100000; // file is actually blank
[email protected]d98961652012-09-11 20:27:219770 UploadFileElementReader::ScopedOverridingContentLengthForTests
9771 overriding_content_length(kFakeSize);
[email protected]95d88ffe2010-02-04 21:25:339772
danakj1fd259a02016-04-16 03:17:099773 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
ricea2deef682016-09-09 08:04:079774 element_readers.push_back(base::MakeUnique<UploadFileElementReader>(
avibf0746c2015-12-09 19:53:149775 base::ThreadTaskRunnerHandle::Get().get(), temp_file_path, 0,
ricea2deef682016-09-09 08:04:079776 std::numeric_limits<uint64_t>::max(), base::Time()));
olli.raula6df48b2a2015-11-26 07:40:229777 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]329b68b2012-11-14 17:54:279778
9779 HttpRequestInfo request;
9780 request.method = "POST";
bncce36dca22015-04-21 22:11:239781 request.url = GURL("http://www.example.org/upload");
[email protected]329b68b2012-11-14 17:54:279782 request.upload_data_stream = &upload_data_stream;
[email protected]329b68b2012-11-14 17:54:279783
danakj1fd259a02016-04-16 03:17:099784 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:169785 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]95d88ffe2010-02-04 21:25:339786
9787 MockRead data_reads[] = {
9788 MockRead("HTTP/1.0 200 OK\r\n\r\n"),
9789 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:069790 MockRead(SYNCHRONOUS, OK),
[email protected]95d88ffe2010-02-04 21:25:339791 };
[email protected]31a2bfe2010-02-09 08:03:399792 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:079793 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]95d88ffe2010-02-04 21:25:339794
[email protected]49639fa2011-12-20 23:22:419795 TestCompletionCallback callback;
[email protected]95d88ffe2010-02-04 21:25:339796
tfarina42834112016-09-22 13:38:209797 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:019798 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]95d88ffe2010-02-04 21:25:339799
9800 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:019801 EXPECT_THAT(rv, IsError(ERR_UPLOAD_FILE_CHANGED));
[email protected]95d88ffe2010-02-04 21:25:339802
bnc691fda62016-08-12 00:43:169803 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:529804 ASSERT_TRUE(response);
[email protected]95d88ffe2010-02-04 21:25:339805
maksim.sisove869bf52016-06-23 17:11:529806 EXPECT_FALSE(response->headers);
[email protected]95d88ffe2010-02-04 21:25:339807
[email protected]dd3aa792013-07-16 19:10:239808 base::DeleteFile(temp_file_path, false);
[email protected]95d88ffe2010-02-04 21:25:339809}
9810
bncd16676a2016-07-20 16:23:019811TEST_F(HttpNetworkTransactionTest, UploadUnreadableFile) {
[email protected]6cdfd7f2013-02-08 20:40:159812 base::FilePath temp_file;
[email protected]03d9afc02013-12-03 17:55:529813 ASSERT_TRUE(base::CreateTemporaryFile(&temp_file));
[email protected]6624b4622010-03-29 19:58:369814 std::string temp_file_content("Unreadable file.");
[email protected]e5c2a22e2014-03-06 20:42:309815 ASSERT_TRUE(base::WriteFile(temp_file, temp_file_content.c_str(),
[email protected]6624b4622010-03-29 19:58:369816 temp_file_content.length()));
[email protected]92be8eb2014-08-07 22:57:119817 ASSERT_TRUE(base::MakeFileUnreadable(temp_file));
[email protected]6624b4622010-03-29 19:58:369818
danakj1fd259a02016-04-16 03:17:099819 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
ricea2deef682016-09-09 08:04:079820 element_readers.push_back(base::MakeUnique<UploadFileElementReader>(
avibf0746c2015-12-09 19:53:149821 base::ThreadTaskRunnerHandle::Get().get(), temp_file, 0,
ricea2deef682016-09-09 08:04:079822 std::numeric_limits<uint64_t>::max(), base::Time()));
olli.raula6df48b2a2015-11-26 07:40:229823 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]329b68b2012-11-14 17:54:279824
9825 HttpRequestInfo request;
9826 request.method = "POST";
bncce36dca22015-04-21 22:11:239827 request.url = GURL("http://www.example.org/upload");
[email protected]329b68b2012-11-14 17:54:279828 request.upload_data_stream = &upload_data_stream;
[email protected]329b68b2012-11-14 17:54:279829
[email protected]999dd8c2013-11-12 06:45:549830 // If we try to upload an unreadable file, the transaction should fail.
danakj1fd259a02016-04-16 03:17:099831 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:169832 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]6624b4622010-03-29 19:58:369833
[email protected]999dd8c2013-11-12 06:45:549834 StaticSocketDataProvider data(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:079835 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]6624b4622010-03-29 19:58:369836
[email protected]49639fa2011-12-20 23:22:419837 TestCompletionCallback callback;
[email protected]6624b4622010-03-29 19:58:369838
tfarina42834112016-09-22 13:38:209839 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:019840 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]6624b4622010-03-29 19:58:369841
9842 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:019843 EXPECT_THAT(rv, IsError(ERR_ACCESS_DENIED));
[email protected]6624b4622010-03-29 19:58:369844
[email protected]dd3aa792013-07-16 19:10:239845 base::DeleteFile(temp_file, false);
[email protected]6624b4622010-03-29 19:58:369846}
9847
bncd16676a2016-07-20 16:23:019848TEST_F(HttpNetworkTransactionTest, CancelDuringInitRequestBody) {
[email protected]02cad5d2013-10-02 08:14:039849 class FakeUploadElementReader : public UploadElementReader {
9850 public:
9851 FakeUploadElementReader() {}
dchengb03027d2014-10-21 12:00:209852 ~FakeUploadElementReader() override {}
[email protected]02cad5d2013-10-02 08:14:039853
9854 const CompletionCallback& callback() const { return callback_; }
9855
9856 // UploadElementReader overrides:
dchengb03027d2014-10-21 12:00:209857 int Init(const CompletionCallback& callback) override {
[email protected]02cad5d2013-10-02 08:14:039858 callback_ = callback;
9859 return ERR_IO_PENDING;
9860 }
avibf0746c2015-12-09 19:53:149861 uint64_t GetContentLength() const override { return 0; }
9862 uint64_t BytesRemaining() const override { return 0; }
dchengb03027d2014-10-21 12:00:209863 int Read(IOBuffer* buf,
9864 int buf_length,
9865 const CompletionCallback& callback) override {
[email protected]02cad5d2013-10-02 08:14:039866 return ERR_FAILED;
9867 }
9868
9869 private:
9870 CompletionCallback callback_;
9871 };
9872
9873 FakeUploadElementReader* fake_reader = new FakeUploadElementReader;
danakj1fd259a02016-04-16 03:17:099874 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
9875 element_readers.push_back(base::WrapUnique(fake_reader));
olli.raula6df48b2a2015-11-26 07:40:229876 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]02cad5d2013-10-02 08:14:039877
9878 HttpRequestInfo request;
9879 request.method = "POST";
bncce36dca22015-04-21 22:11:239880 request.url = GURL("http://www.example.org/upload");
[email protected]02cad5d2013-10-02 08:14:039881 request.upload_data_stream = &upload_data_stream;
[email protected]02cad5d2013-10-02 08:14:039882
danakj1fd259a02016-04-16 03:17:099883 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:169884 std::unique_ptr<HttpNetworkTransaction> trans(
dcheng48459ac22014-08-26 00:46:419885 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]02cad5d2013-10-02 08:14:039886
9887 StaticSocketDataProvider data;
9888 session_deps_.socket_factory->AddSocketDataProvider(&data);
9889
9890 TestCompletionCallback callback;
tfarina42834112016-09-22 13:38:209891 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:019892 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
fdoray92e35a72016-06-10 15:54:559893 base::RunLoop().RunUntilIdle();
[email protected]02cad5d2013-10-02 08:14:039894
9895 // Transaction is pending on request body initialization.
9896 ASSERT_FALSE(fake_reader->callback().is_null());
9897
9898 // Return Init()'s result after the transaction gets destroyed.
9899 trans.reset();
9900 fake_reader->callback().Run(OK); // Should not crash.
9901}
9902
[email protected]aeefc9e82010-02-19 16:18:279903// Tests that changes to Auth realms are treated like auth rejections.
bncd16676a2016-07-20 16:23:019904TEST_F(HttpNetworkTransactionTest, ChangeAuthRealms) {
[email protected]aeefc9e82010-02-19 16:18:279905 HttpRequestInfo request;
9906 request.method = "GET";
bncce36dca22015-04-21 22:11:239907 request.url = GURL("http://www.example.org/");
[email protected]aeefc9e82010-02-19 16:18:279908
9909 // First transaction will request a resource and receive a Basic challenge
9910 // with realm="first_realm".
9911 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:239912 MockWrite(
9913 "GET / HTTP/1.1\r\n"
9914 "Host: www.example.org\r\n"
9915 "Connection: keep-alive\r\n"
9916 "\r\n"),
[email protected]aeefc9e82010-02-19 16:18:279917 };
9918 MockRead data_reads1[] = {
9919 MockRead("HTTP/1.1 401 Unauthorized\r\n"
9920 "WWW-Authenticate: Basic realm=\"first_realm\"\r\n"
9921 "\r\n"),
9922 };
9923
bnc691fda62016-08-12 00:43:169924 // After calling trans.RestartWithAuth(), provide an Authentication header
[email protected]aeefc9e82010-02-19 16:18:279925 // for first_realm. The server will reject and provide a challenge with
9926 // second_realm.
9927 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:239928 MockWrite(
9929 "GET / HTTP/1.1\r\n"
9930 "Host: www.example.org\r\n"
9931 "Connection: keep-alive\r\n"
9932 "Authorization: Basic Zmlyc3Q6YmF6\r\n"
9933 "\r\n"),
[email protected]aeefc9e82010-02-19 16:18:279934 };
9935 MockRead data_reads2[] = {
9936 MockRead("HTTP/1.1 401 Unauthorized\r\n"
9937 "WWW-Authenticate: Basic realm=\"second_realm\"\r\n"
9938 "\r\n"),
9939 };
9940
9941 // This again fails, and goes back to first_realm. Make sure that the
9942 // entry is removed from cache.
9943 MockWrite data_writes3[] = {
bncce36dca22015-04-21 22:11:239944 MockWrite(
9945 "GET / HTTP/1.1\r\n"
9946 "Host: www.example.org\r\n"
9947 "Connection: keep-alive\r\n"
9948 "Authorization: Basic c2Vjb25kOmZvdQ==\r\n"
9949 "\r\n"),
[email protected]aeefc9e82010-02-19 16:18:279950 };
9951 MockRead data_reads3[] = {
9952 MockRead("HTTP/1.1 401 Unauthorized\r\n"
9953 "WWW-Authenticate: Basic realm=\"first_realm\"\r\n"
9954 "\r\n"),
9955 };
9956
9957 // Try one last time (with the correct password) and get the resource.
9958 MockWrite data_writes4[] = {
bncce36dca22015-04-21 22:11:239959 MockWrite(
9960 "GET / HTTP/1.1\r\n"
9961 "Host: www.example.org\r\n"
9962 "Connection: keep-alive\r\n"
9963 "Authorization: Basic Zmlyc3Q6YmFy\r\n"
9964 "\r\n"),
[email protected]aeefc9e82010-02-19 16:18:279965 };
9966 MockRead data_reads4[] = {
9967 MockRead("HTTP/1.1 200 OK\r\n"
9968 "Content-Type: text/html; charset=iso-8859-1\r\n"
[email protected]0b0bf032010-09-21 18:08:509969 "Content-Length: 5\r\n"
9970 "\r\n"
9971 "hello"),
[email protected]aeefc9e82010-02-19 16:18:279972 };
9973
9974 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
9975 data_writes1, arraysize(data_writes1));
9976 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
9977 data_writes2, arraysize(data_writes2));
9978 StaticSocketDataProvider data3(data_reads3, arraysize(data_reads3),
9979 data_writes3, arraysize(data_writes3));
9980 StaticSocketDataProvider data4(data_reads4, arraysize(data_reads4),
9981 data_writes4, arraysize(data_writes4));
[email protected]bb88e1d32013-05-03 23:11:079982 session_deps_.socket_factory->AddSocketDataProvider(&data1);
9983 session_deps_.socket_factory->AddSocketDataProvider(&data2);
9984 session_deps_.socket_factory->AddSocketDataProvider(&data3);
9985 session_deps_.socket_factory->AddSocketDataProvider(&data4);
[email protected]aeefc9e82010-02-19 16:18:279986
[email protected]49639fa2011-12-20 23:22:419987 TestCompletionCallback callback1;
[email protected]aeefc9e82010-02-19 16:18:279988
danakj1fd259a02016-04-16 03:17:099989 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:169990 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]0b0bf032010-09-21 18:08:509991
[email protected]aeefc9e82010-02-19 16:18:279992 // Issue the first request with Authorize headers. There should be a
9993 // password prompt for first_realm waiting to be filled in after the
9994 // transaction completes.
tfarina42834112016-09-22 13:38:209995 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:019996 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]aeefc9e82010-02-19 16:18:279997 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:019998 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:169999 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5210000 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:0410001 const AuthChallengeInfo* challenge = response->auth_challenge.get();
wezca1070932016-05-26 20:30:5210002 ASSERT_TRUE(challenge);
[email protected]79cb5c12011-09-12 13:12:0410003 EXPECT_FALSE(challenge->is_proxy);
asanka098c0092016-06-16 20:18:4310004 EXPECT_EQ("http://www.example.org", challenge->challenger.Serialize());
[email protected]79cb5c12011-09-12 13:12:0410005 EXPECT_EQ("first_realm", challenge->realm);
aberentbba302d2015-12-03 10:20:1910006 EXPECT_EQ(kBasicAuthScheme, challenge->scheme);
[email protected]aeefc9e82010-02-19 16:18:2710007
10008 // Issue the second request with an incorrect password. There should be a
10009 // password prompt for second_realm waiting to be filled in after the
10010 // transaction completes.
[email protected]49639fa2011-12-20 23:22:4110011 TestCompletionCallback callback2;
bnc691fda62016-08-12 00:43:1610012 rv = trans.RestartWithAuth(AuthCredentials(kFirst, kBaz),
10013 callback2.callback());
robpercival214763f2016-07-01 23:27:0110014 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]aeefc9e82010-02-19 16:18:2710015 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:0110016 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:1610017 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5210018 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:0410019 challenge = response->auth_challenge.get();
wezca1070932016-05-26 20:30:5210020 ASSERT_TRUE(challenge);
[email protected]79cb5c12011-09-12 13:12:0410021 EXPECT_FALSE(challenge->is_proxy);
asanka098c0092016-06-16 20:18:4310022 EXPECT_EQ("http://www.example.org", challenge->challenger.Serialize());
[email protected]79cb5c12011-09-12 13:12:0410023 EXPECT_EQ("second_realm", challenge->realm);
aberentbba302d2015-12-03 10:20:1910024 EXPECT_EQ(kBasicAuthScheme, challenge->scheme);
[email protected]aeefc9e82010-02-19 16:18:2710025
10026 // Issue the third request with another incorrect password. There should be
10027 // a password prompt for first_realm waiting to be filled in. If the password
10028 // prompt is not present, it indicates that the HttpAuthCacheEntry for
10029 // first_realm was not correctly removed.
[email protected]49639fa2011-12-20 23:22:4110030 TestCompletionCallback callback3;
bnc691fda62016-08-12 00:43:1610031 rv = trans.RestartWithAuth(AuthCredentials(kSecond, kFou),
10032 callback3.callback());
robpercival214763f2016-07-01 23:27:0110033 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]aeefc9e82010-02-19 16:18:2710034 rv = callback3.WaitForResult();
robpercival214763f2016-07-01 23:27:0110035 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:1610036 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5210037 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:0410038 challenge = response->auth_challenge.get();
wezca1070932016-05-26 20:30:5210039 ASSERT_TRUE(challenge);
[email protected]79cb5c12011-09-12 13:12:0410040 EXPECT_FALSE(challenge->is_proxy);
asanka098c0092016-06-16 20:18:4310041 EXPECT_EQ("http://www.example.org", challenge->challenger.Serialize());
[email protected]79cb5c12011-09-12 13:12:0410042 EXPECT_EQ("first_realm", challenge->realm);
aberentbba302d2015-12-03 10:20:1910043 EXPECT_EQ(kBasicAuthScheme, challenge->scheme);
[email protected]aeefc9e82010-02-19 16:18:2710044
10045 // Issue the fourth request with the correct password and username.
[email protected]49639fa2011-12-20 23:22:4110046 TestCompletionCallback callback4;
bnc691fda62016-08-12 00:43:1610047 rv = trans.RestartWithAuth(AuthCredentials(kFirst, kBar),
10048 callback4.callback());
robpercival214763f2016-07-01 23:27:0110049 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]aeefc9e82010-02-19 16:18:2710050 rv = callback4.WaitForResult();
robpercival214763f2016-07-01 23:27:0110051 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:1610052 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5210053 ASSERT_TRUE(response);
10054 EXPECT_FALSE(response->auth_challenge);
[email protected]aeefc9e82010-02-19 16:18:2710055}
10056
bncd16676a2016-07-20 16:23:0110057TEST_F(HttpNetworkTransactionTest, HonorAlternativeServiceHeader) {
bncc958faa2015-07-31 18:14:5210058 MockRead data_reads[] = {
10059 MockRead("HTTP/1.1 200 OK\r\n"),
bnc2df4b522016-07-08 18:17:4310060 MockRead(kAlternativeServiceHttpHeader),
bncc958faa2015-07-31 18:14:5210061 MockRead("\r\n"),
10062 MockRead("hello world"),
10063 MockRead(SYNCHRONOUS, OK),
10064 };
10065
10066 HttpRequestInfo request;
10067 request.method = "GET";
bncb26024382016-06-29 02:39:4510068 request.url = GURL("https://www.example.org/");
bncc958faa2015-07-31 18:14:5210069
10070 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
bncc958faa2015-07-31 18:14:5210071 session_deps_.socket_factory->AddSocketDataProvider(&data);
10072
bncb26024382016-06-29 02:39:4510073 SSLSocketDataProvider ssl(ASYNC, OK);
10074 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
10075
bncc958faa2015-07-31 18:14:5210076 TestCompletionCallback callback;
10077
danakj1fd259a02016-04-16 03:17:0910078 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1610079 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
bncc958faa2015-07-31 18:14:5210080
tfarina42834112016-09-22 13:38:2010081 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110082 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
bncc958faa2015-07-31 18:14:5210083
bncb26024382016-06-29 02:39:4510084 url::SchemeHostPort test_server(request.url);
bnc525e175a2016-06-20 12:36:4010085 HttpServerProperties* http_server_properties =
10086 session->http_server_properties();
bncc958faa2015-07-31 18:14:5210087 AlternativeServiceVector alternative_service_vector =
bnc525e175a2016-06-20 12:36:4010088 http_server_properties->GetAlternativeServices(test_server);
bncc958faa2015-07-31 18:14:5210089 EXPECT_TRUE(alternative_service_vector.empty());
10090
robpercival214763f2016-07-01 23:27:0110091 EXPECT_THAT(callback.WaitForResult(), IsOk());
bncc958faa2015-07-31 18:14:5210092
bnc691fda62016-08-12 00:43:1610093 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5210094 ASSERT_TRUE(response);
10095 ASSERT_TRUE(response->headers);
bncc958faa2015-07-31 18:14:5210096 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
10097 EXPECT_FALSE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5210098 EXPECT_FALSE(response->was_alpn_negotiated);
bncc958faa2015-07-31 18:14:5210099
10100 std::string response_data;
bnc691fda62016-08-12 00:43:1610101 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
bncc958faa2015-07-31 18:14:5210102 EXPECT_EQ("hello world", response_data);
10103
10104 alternative_service_vector =
bnc525e175a2016-06-20 12:36:4010105 http_server_properties->GetAlternativeServices(test_server);
bncc958faa2015-07-31 18:14:5210106 ASSERT_EQ(1u, alternative_service_vector.size());
bnc3472afd2016-11-17 15:27:2110107 EXPECT_EQ(kProtoHTTP2, alternative_service_vector[0].protocol);
bncb26024382016-06-29 02:39:4510108 EXPECT_EQ("mail.example.org", alternative_service_vector[0].host);
bncc958faa2015-07-31 18:14:5210109 EXPECT_EQ(443, alternative_service_vector[0].port);
10110}
10111
bnce3dd56f2016-06-01 10:37:1110112// Regression test for https://crbug.com/615497.
bncd16676a2016-07-20 16:23:0110113TEST_F(HttpNetworkTransactionTest,
bnce3dd56f2016-06-01 10:37:1110114 DoNotParseAlternativeServiceHeaderOnInsecureRequest) {
bnce3dd56f2016-06-01 10:37:1110115 MockRead data_reads[] = {
10116 MockRead("HTTP/1.1 200 OK\r\n"),
bnc2df4b522016-07-08 18:17:4310117 MockRead(kAlternativeServiceHttpHeader),
bnce3dd56f2016-06-01 10:37:1110118 MockRead("\r\n"),
10119 MockRead("hello world"),
10120 MockRead(SYNCHRONOUS, OK),
10121 };
10122
10123 HttpRequestInfo request;
10124 request.method = "GET";
10125 request.url = GURL("http://www.example.org/");
10126 request.load_flags = 0;
10127
10128 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
10129 session_deps_.socket_factory->AddSocketDataProvider(&data);
10130
10131 TestCompletionCallback callback;
10132
10133 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1610134 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
bnce3dd56f2016-06-01 10:37:1110135
10136 url::SchemeHostPort test_server(request.url);
bnc525e175a2016-06-20 12:36:4010137 HttpServerProperties* http_server_properties =
10138 session->http_server_properties();
bnce3dd56f2016-06-01 10:37:1110139 AlternativeServiceVector alternative_service_vector =
bnc525e175a2016-06-20 12:36:4010140 http_server_properties->GetAlternativeServices(test_server);
bnce3dd56f2016-06-01 10:37:1110141 EXPECT_TRUE(alternative_service_vector.empty());
10142
tfarina42834112016-09-22 13:38:2010143 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110144 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
10145 EXPECT_THAT(callback.WaitForResult(), IsOk());
bnce3dd56f2016-06-01 10:37:1110146
bnc691fda62016-08-12 00:43:1610147 const HttpResponseInfo* response = trans.GetResponseInfo();
bnce3dd56f2016-06-01 10:37:1110148 ASSERT_TRUE(response);
10149 ASSERT_TRUE(response->headers);
10150 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
10151 EXPECT_FALSE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5210152 EXPECT_FALSE(response->was_alpn_negotiated);
bnce3dd56f2016-06-01 10:37:1110153
10154 std::string response_data;
bnc691fda62016-08-12 00:43:1610155 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
bnce3dd56f2016-06-01 10:37:1110156 EXPECT_EQ("hello world", response_data);
10157
10158 alternative_service_vector =
bnc525e175a2016-06-20 12:36:4010159 http_server_properties->GetAlternativeServices(test_server);
bnce3dd56f2016-06-01 10:37:1110160 EXPECT_TRUE(alternative_service_vector.empty());
10161}
10162
bnc8bef8da22016-05-30 01:28:2510163// HTTP/2 Alternative Services should be disabled if alternative service
10164// hostname is different from that of origin.
10165// TODO(bnc): Remove when https://crbug.com/615413 is fixed.
bncd16676a2016-07-20 16:23:0110166TEST_F(HttpNetworkTransactionTest,
bnc8bef8da22016-05-30 01:28:2510167 DisableHTTP2AlternativeServicesWithDifferentHost) {
bncb26024382016-06-29 02:39:4510168 session_deps_.enable_http2_alternative_service_with_different_host = false;
10169
bnc8bef8da22016-05-30 01:28:2510170 HttpRequestInfo request;
10171 request.method = "GET";
bncb26024382016-06-29 02:39:4510172 request.url = GURL("https://www.example.org/");
bnc8bef8da22016-05-30 01:28:2510173 request.load_flags = 0;
10174
10175 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
10176 StaticSocketDataProvider first_data;
10177 first_data.set_connect_data(mock_connect);
10178 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
bncb26024382016-06-29 02:39:4510179 SSLSocketDataProvider ssl_http11(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3610180 ssl_http11.next_proto = kProtoHTTP11;
bncb26024382016-06-29 02:39:4510181 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_http11);
bnc8bef8da22016-05-30 01:28:2510182
10183 MockRead data_reads[] = {
10184 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello world"),
10185 MockRead(ASYNC, OK),
10186 };
10187 StaticSocketDataProvider second_data(data_reads, arraysize(data_reads), NULL,
10188 0);
10189 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
10190
10191 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
10192
bnc525e175a2016-06-20 12:36:4010193 HttpServerProperties* http_server_properties =
bnc8bef8da22016-05-30 01:28:2510194 session->http_server_properties();
bnc3472afd2016-11-17 15:27:2110195 AlternativeService alternative_service(kProtoHTTP2, "different.example.org",
10196 444);
bnc8bef8da22016-05-30 01:28:2510197 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
10198 http_server_properties->SetAlternativeService(
10199 url::SchemeHostPort(request.url), alternative_service, expiration);
10200
bnc691fda62016-08-12 00:43:1610201 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
bnc8bef8da22016-05-30 01:28:2510202 TestCompletionCallback callback;
10203
tfarina42834112016-09-22 13:38:2010204 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
bnc8bef8da22016-05-30 01:28:2510205 // Alternative service is not used, request fails.
robpercival214763f2016-07-01 23:27:0110206 EXPECT_THAT(callback.GetResult(rv), IsError(ERR_CONNECTION_REFUSED));
bnc8bef8da22016-05-30 01:28:2510207}
10208
bnce3dd56f2016-06-01 10:37:1110209// Regression test for https://crbug.com/615497:
10210// Alternative Services should be disabled for http origin.
bncd16676a2016-07-20 16:23:0110211TEST_F(HttpNetworkTransactionTest,
bnce3dd56f2016-06-01 10:37:1110212 DisableAlternativeServicesForInsecureOrigin) {
bnce3dd56f2016-06-01 10:37:1110213 HttpRequestInfo request;
10214 request.method = "GET";
10215 request.url = GURL("http://www.example.org/");
10216 request.load_flags = 0;
10217
10218 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
10219 StaticSocketDataProvider first_data;
10220 first_data.set_connect_data(mock_connect);
10221 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
10222
10223 MockRead data_reads[] = {
10224 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello world"),
10225 MockRead(ASYNC, OK),
10226 };
10227 StaticSocketDataProvider second_data(data_reads, arraysize(data_reads), NULL,
10228 0);
10229 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
10230
10231 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
10232
bnc525e175a2016-06-20 12:36:4010233 HttpServerProperties* http_server_properties =
bnce3dd56f2016-06-01 10:37:1110234 session->http_server_properties();
bnc3472afd2016-11-17 15:27:2110235 AlternativeService alternative_service(kProtoHTTP2, "", 444);
bnce3dd56f2016-06-01 10:37:1110236 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
10237 http_server_properties->SetAlternativeService(
10238 url::SchemeHostPort(request.url), alternative_service, expiration);
10239
bnc691fda62016-08-12 00:43:1610240 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
bnce3dd56f2016-06-01 10:37:1110241 TestCompletionCallback callback;
10242
tfarina42834112016-09-22 13:38:2010243 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
bnce3dd56f2016-06-01 10:37:1110244 // Alternative service is not used, request fails.
robpercival214763f2016-07-01 23:27:0110245 EXPECT_THAT(callback.GetResult(rv), IsError(ERR_CONNECTION_REFUSED));
bnce3dd56f2016-06-01 10:37:1110246}
10247
bncd16676a2016-07-20 16:23:0110248TEST_F(HttpNetworkTransactionTest, ClearAlternativeServices) {
bnc4f575852015-10-14 18:35:0810249 // Set an alternative service for origin.
danakj1fd259a02016-04-16 03:17:0910250 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc525e175a2016-06-20 12:36:4010251 HttpServerProperties* http_server_properties =
10252 session->http_server_properties();
bncb26024382016-06-29 02:39:4510253 url::SchemeHostPort test_server("https", "www.example.org", 443);
bnc3472afd2016-11-17 15:27:2110254 AlternativeService alternative_service(kProtoQUIC, "", 80);
bnc4f575852015-10-14 18:35:0810255 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
bnc525e175a2016-06-20 12:36:4010256 http_server_properties->SetAlternativeService(
10257 test_server, alternative_service, expiration);
bnc4f575852015-10-14 18:35:0810258 AlternativeServiceVector alternative_service_vector =
bnc525e175a2016-06-20 12:36:4010259 http_server_properties->GetAlternativeServices(test_server);
bnc4f575852015-10-14 18:35:0810260 EXPECT_EQ(1u, alternative_service_vector.size());
10261
10262 // Send a clear header.
10263 MockRead data_reads[] = {
10264 MockRead("HTTP/1.1 200 OK\r\n"),
10265 MockRead("Alt-Svc: clear\r\n"),
10266 MockRead("\r\n"),
10267 MockRead("hello world"),
10268 MockRead(SYNCHRONOUS, OK),
10269 };
10270 StaticSocketDataProvider data(data_reads, arraysize(data_reads), nullptr, 0);
10271 session_deps_.socket_factory->AddSocketDataProvider(&data);
10272
bncb26024382016-06-29 02:39:4510273 SSLSocketDataProvider ssl(ASYNC, OK);
10274 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
10275
bnc4f575852015-10-14 18:35:0810276 HttpRequestInfo request;
10277 request.method = "GET";
bncb26024382016-06-29 02:39:4510278 request.url = GURL("https://www.example.org/");
bnc4f575852015-10-14 18:35:0810279
10280 TestCompletionCallback callback;
10281
bnc691fda62016-08-12 00:43:1610282 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
bnc4f575852015-10-14 18:35:0810283
tfarina42834112016-09-22 13:38:2010284 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110285 EXPECT_THAT(callback.GetResult(rv), IsOk());
bnc4f575852015-10-14 18:35:0810286
bnc691fda62016-08-12 00:43:1610287 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5210288 ASSERT_TRUE(response);
10289 ASSERT_TRUE(response->headers);
bnc4f575852015-10-14 18:35:0810290 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
10291 EXPECT_FALSE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5210292 EXPECT_FALSE(response->was_alpn_negotiated);
bnc4f575852015-10-14 18:35:0810293
10294 std::string response_data;
bnc691fda62016-08-12 00:43:1610295 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
bnc4f575852015-10-14 18:35:0810296 EXPECT_EQ("hello world", response_data);
10297
10298 alternative_service_vector =
bnc525e175a2016-06-20 12:36:4010299 http_server_properties->GetAlternativeServices(test_server);
bnc4f575852015-10-14 18:35:0810300 EXPECT_TRUE(alternative_service_vector.empty());
10301}
10302
bncd16676a2016-07-20 16:23:0110303TEST_F(HttpNetworkTransactionTest, HonorMultipleAlternativeServiceHeaders) {
bncc958faa2015-07-31 18:14:5210304 MockRead data_reads[] = {
10305 MockRead("HTTP/1.1 200 OK\r\n"),
bnc2df4b522016-07-08 18:17:4310306 MockRead("Alt-Svc: h2=\"www.example.com:443\","),
10307 MockRead("h2=\":1234\"\r\n\r\n"),
bncc958faa2015-07-31 18:14:5210308 MockRead("hello world"),
10309 MockRead(SYNCHRONOUS, OK),
10310 };
10311
10312 HttpRequestInfo request;
10313 request.method = "GET";
bncb26024382016-06-29 02:39:4510314 request.url = GURL("https://www.example.org/");
bncc958faa2015-07-31 18:14:5210315
10316 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
bncc958faa2015-07-31 18:14:5210317 session_deps_.socket_factory->AddSocketDataProvider(&data);
10318
bncb26024382016-06-29 02:39:4510319 SSLSocketDataProvider ssl(ASYNC, OK);
10320 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
10321
bncc958faa2015-07-31 18:14:5210322 TestCompletionCallback callback;
10323
danakj1fd259a02016-04-16 03:17:0910324 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1610325 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
bncc958faa2015-07-31 18:14:5210326
tfarina42834112016-09-22 13:38:2010327 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110328 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
bncc958faa2015-07-31 18:14:5210329
bncb26024382016-06-29 02:39:4510330 url::SchemeHostPort test_server("https", "www.example.org", 443);
bnc525e175a2016-06-20 12:36:4010331 HttpServerProperties* http_server_properties =
10332 session->http_server_properties();
bncc958faa2015-07-31 18:14:5210333 AlternativeServiceVector alternative_service_vector =
bnc525e175a2016-06-20 12:36:4010334 http_server_properties->GetAlternativeServices(test_server);
bncc958faa2015-07-31 18:14:5210335 EXPECT_TRUE(alternative_service_vector.empty());
10336
robpercival214763f2016-07-01 23:27:0110337 EXPECT_THAT(callback.WaitForResult(), IsOk());
bncc958faa2015-07-31 18:14:5210338
bnc691fda62016-08-12 00:43:1610339 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5210340 ASSERT_TRUE(response);
10341 ASSERT_TRUE(response->headers);
bncc958faa2015-07-31 18:14:5210342 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
10343 EXPECT_FALSE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5210344 EXPECT_FALSE(response->was_alpn_negotiated);
bncc958faa2015-07-31 18:14:5210345
10346 std::string response_data;
bnc691fda62016-08-12 00:43:1610347 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
bncc958faa2015-07-31 18:14:5210348 EXPECT_EQ("hello world", response_data);
10349
10350 alternative_service_vector =
bnc525e175a2016-06-20 12:36:4010351 http_server_properties->GetAlternativeServices(test_server);
bncc958faa2015-07-31 18:14:5210352 ASSERT_EQ(2u, alternative_service_vector.size());
bnc3472afd2016-11-17 15:27:2110353 EXPECT_EQ(kProtoHTTP2, alternative_service_vector[0].protocol);
bncc958faa2015-07-31 18:14:5210354 EXPECT_EQ("www.example.com", alternative_service_vector[0].host);
10355 EXPECT_EQ(443, alternative_service_vector[0].port);
bnc3472afd2016-11-17 15:27:2110356 EXPECT_EQ(kProtoHTTP2, alternative_service_vector[1].protocol);
bncc958faa2015-07-31 18:14:5210357 EXPECT_EQ("www.example.org", alternative_service_vector[1].host);
10358 EXPECT_EQ(1234, alternative_service_vector[1].port);
10359}
10360
bncd16676a2016-07-20 16:23:0110361TEST_F(HttpNetworkTransactionTest, IdentifyQuicBroken) {
zhongyi3d4a55e72016-04-22 20:36:4610362 url::SchemeHostPort server("https", "origin.example.org", 443);
zhongyi48704c182015-12-07 07:52:0210363 HostPortPair alternative("alternative.example.org", 443);
10364 std::string origin_url = "https://origin.example.org:443";
10365 std::string alternative_url = "https://alternative.example.org:443";
10366
10367 // Negotiate HTTP/1.1 with alternative.example.org.
10368 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3610369 ssl.next_proto = kProtoHTTP11;
zhongyi48704c182015-12-07 07:52:0210370 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
10371
10372 // HTTP/1.1 data for request.
10373 MockWrite http_writes[] = {
10374 MockWrite("GET / HTTP/1.1\r\n"
10375 "Host: alternative.example.org\r\n"
10376 "Connection: keep-alive\r\n\r\n"),
10377 };
10378
10379 MockRead http_reads[] = {
10380 MockRead("HTTP/1.1 200 OK\r\n"
10381 "Content-Type: text/html; charset=iso-8859-1\r\n"
10382 "Content-Length: 40\r\n\r\n"
10383 "first HTTP/1.1 response from alternative"),
10384 };
10385 StaticSocketDataProvider http_data(http_reads, arraysize(http_reads),
10386 http_writes, arraysize(http_writes));
10387 session_deps_.socket_factory->AddSocketDataProvider(&http_data);
10388
10389 StaticSocketDataProvider data_refused;
10390 data_refused.set_connect_data(MockConnect(ASYNC, ERR_CONNECTION_REFUSED));
10391 session_deps_.socket_factory->AddSocketDataProvider(&data_refused);
10392
zhongyi3d4a55e72016-04-22 20:36:4610393 // Set up a QUIC alternative service for server.
danakj1fd259a02016-04-16 03:17:0910394 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc525e175a2016-06-20 12:36:4010395 HttpServerProperties* http_server_properties =
zhongyi48704c182015-12-07 07:52:0210396 session->http_server_properties();
bnc3472afd2016-11-17 15:27:2110397 AlternativeService alternative_service(kProtoQUIC, alternative);
zhongyi48704c182015-12-07 07:52:0210398 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyi3d4a55e72016-04-22 20:36:4610399 http_server_properties->SetAlternativeService(server, alternative_service,
rchdc7b9052016-03-17 20:51:5010400 expiration);
zhongyi48704c182015-12-07 07:52:0210401 // Mark the QUIC alternative service as broken.
10402 http_server_properties->MarkAlternativeServiceBroken(alternative_service);
10403
zhongyi48704c182015-12-07 07:52:0210404 HttpRequestInfo request;
krasinc06a72a2016-12-21 03:42:4610405 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
zhongyi48704c182015-12-07 07:52:0210406 request.method = "GET";
10407 request.url = GURL(origin_url);
zhongyi48704c182015-12-07 07:52:0210408 TestCompletionCallback callback;
10409 NetErrorDetails details;
10410 EXPECT_FALSE(details.quic_broken);
10411
tfarina42834112016-09-22 13:38:2010412 trans.Start(&request, callback.callback(), NetLogWithSource());
bnc691fda62016-08-12 00:43:1610413 trans.PopulateNetErrorDetails(&details);
zhongyi48704c182015-12-07 07:52:0210414 EXPECT_TRUE(details.quic_broken);
10415}
10416
bncd16676a2016-07-20 16:23:0110417TEST_F(HttpNetworkTransactionTest, IdentifyQuicNotBroken) {
zhongyi3d4a55e72016-04-22 20:36:4610418 url::SchemeHostPort server("https", "origin.example.org", 443);
zhongyi48704c182015-12-07 07:52:0210419 HostPortPair alternative1("alternative1.example.org", 443);
10420 HostPortPair alternative2("alternative2.example.org", 443);
10421 std::string origin_url = "https://origin.example.org:443";
10422 std::string alternative_url1 = "https://alternative1.example.org:443";
10423 std::string alternative_url2 = "https://alternative2.example.org:443";
10424
10425 // Negotiate HTTP/1.1 with alternative1.example.org.
10426 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3610427 ssl.next_proto = kProtoHTTP11;
zhongyi48704c182015-12-07 07:52:0210428 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
10429
10430 // HTTP/1.1 data for request.
10431 MockWrite http_writes[] = {
10432 MockWrite("GET / HTTP/1.1\r\n"
10433 "Host: alternative1.example.org\r\n"
10434 "Connection: keep-alive\r\n\r\n"),
10435 };
10436
10437 MockRead http_reads[] = {
10438 MockRead("HTTP/1.1 200 OK\r\n"
10439 "Content-Type: text/html; charset=iso-8859-1\r\n"
10440 "Content-Length: 40\r\n\r\n"
10441 "first HTTP/1.1 response from alternative1"),
10442 };
10443 StaticSocketDataProvider http_data(http_reads, arraysize(http_reads),
10444 http_writes, arraysize(http_writes));
10445 session_deps_.socket_factory->AddSocketDataProvider(&http_data);
10446
10447 StaticSocketDataProvider data_refused;
10448 data_refused.set_connect_data(MockConnect(ASYNC, ERR_CONNECTION_REFUSED));
10449 session_deps_.socket_factory->AddSocketDataProvider(&data_refused);
10450
danakj1fd259a02016-04-16 03:17:0910451 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc525e175a2016-06-20 12:36:4010452 HttpServerProperties* http_server_properties =
zhongyi48704c182015-12-07 07:52:0210453 session->http_server_properties();
10454
zhongyi3d4a55e72016-04-22 20:36:4610455 // Set up two QUIC alternative services for server.
zhongyi48704c182015-12-07 07:52:0210456 AlternativeServiceInfoVector alternative_service_info_vector;
10457 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
10458
bnc3472afd2016-11-17 15:27:2110459 AlternativeService alternative_service1(kProtoQUIC, alternative1);
rchdc7b9052016-03-17 20:51:5010460 AlternativeServiceInfo alternative_service_info1(alternative_service1,
zhongyi48704c182015-12-07 07:52:0210461 expiration);
10462 alternative_service_info_vector.push_back(alternative_service_info1);
bnc3472afd2016-11-17 15:27:2110463 AlternativeService alternative_service2(kProtoQUIC, alternative2);
rchdc7b9052016-03-17 20:51:5010464 AlternativeServiceInfo alternative_service_info2(alternative_service2,
zhongyi48704c182015-12-07 07:52:0210465 expiration);
10466 alternative_service_info_vector.push_back(alternative_service_info2);
10467
10468 http_server_properties->SetAlternativeServices(
zhongyi3d4a55e72016-04-22 20:36:4610469 server, alternative_service_info_vector);
zhongyi48704c182015-12-07 07:52:0210470
10471 // Mark one of the QUIC alternative service as broken.
10472 http_server_properties->MarkAlternativeServiceBroken(alternative_service1);
10473
10474 const AlternativeServiceVector alternative_service_vector =
zhongyi3d4a55e72016-04-22 20:36:4610475 http_server_properties->GetAlternativeServices(server);
zhongyi48704c182015-12-07 07:52:0210476
zhongyi48704c182015-12-07 07:52:0210477 HttpRequestInfo request;
krasinc06a72a2016-12-21 03:42:4610478 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
zhongyi48704c182015-12-07 07:52:0210479 request.method = "GET";
10480 request.url = GURL(origin_url);
zhongyi48704c182015-12-07 07:52:0210481 TestCompletionCallback callback;
10482 NetErrorDetails details;
10483 EXPECT_FALSE(details.quic_broken);
10484
tfarina42834112016-09-22 13:38:2010485 trans.Start(&request, callback.callback(), NetLogWithSource());
bnc691fda62016-08-12 00:43:1610486 trans.PopulateNetErrorDetails(&details);
zhongyi48704c182015-12-07 07:52:0210487 EXPECT_FALSE(details.quic_broken);
10488}
10489
bncd16676a2016-07-20 16:23:0110490TEST_F(HttpNetworkTransactionTest, MarkBrokenAlternateProtocolAndFallback) {
[email protected]564b4912010-03-09 16:30:4210491 HttpRequestInfo request;
10492 request.method = "GET";
bncb26024382016-06-29 02:39:4510493 request.url = GURL("https://www.example.org/");
[email protected]564b4912010-03-09 16:30:4210494
[email protected]d973e99a2012-02-17 21:02:3610495 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
[email protected]564b4912010-03-09 16:30:4210496 StaticSocketDataProvider first_data;
10497 first_data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:0710498 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
bncb26024382016-06-29 02:39:4510499 SSLSocketDataProvider ssl_http11(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3610500 ssl_http11.next_proto = kProtoHTTP11;
bncb26024382016-06-29 02:39:4510501 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_http11);
[email protected]564b4912010-03-09 16:30:4210502
10503 MockRead data_reads[] = {
10504 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
10505 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:0610506 MockRead(ASYNC, OK),
[email protected]564b4912010-03-09 16:30:4210507 };
10508 StaticSocketDataProvider second_data(
10509 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0710510 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
[email protected]564b4912010-03-09 16:30:4210511
danakj1fd259a02016-04-16 03:17:0910512 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]564b4912010-03-09 16:30:4210513
bnc525e175a2016-06-20 12:36:4010514 HttpServerProperties* http_server_properties =
[email protected]17291a022011-10-10 07:32:5310515 session->http_server_properties();
zhongyi3d4a55e72016-04-22 20:36:4610516 const url::SchemeHostPort server(request.url);
[email protected]3912662a32011-10-04 00:51:1110517 // Port must be < 1024, or the header will be ignored (since initial port was
10518 // port 80 (another restricted port).
bncd9b132e2015-07-08 05:16:1010519 const AlternativeService alternative_service(
bnc3472afd2016-11-17 15:27:2110520 kProtoHTTP2, "www.example.org",
bncd9b132e2015-07-08 05:16:1010521 666); // Port is ignored by MockConnect anyway.
bnc7dc7e1b42015-07-28 14:43:1210522 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyi3d4a55e72016-04-22 20:36:4610523 http_server_properties->SetAlternativeService(server, alternative_service,
10524 expiration);
[email protected]564b4912010-03-09 16:30:4210525
bnc691fda62016-08-12 00:43:1610526 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]49639fa2011-12-20 23:22:4110527 TestCompletionCallback callback;
[email protected]564b4912010-03-09 16:30:4210528
tfarina42834112016-09-22 13:38:2010529 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110530 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
10531 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]564b4912010-03-09 16:30:4210532
bnc691fda62016-08-12 00:43:1610533 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5210534 ASSERT_TRUE(response);
10535 ASSERT_TRUE(response->headers);
[email protected]564b4912010-03-09 16:30:4210536 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
10537
10538 std::string response_data;
bnc691fda62016-08-12 00:43:1610539 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
[email protected]564b4912010-03-09 16:30:4210540 EXPECT_EQ("hello world", response_data);
10541
bncd9b132e2015-07-08 05:16:1010542 const AlternativeServiceVector alternative_service_vector =
zhongyi3d4a55e72016-04-22 20:36:4610543 http_server_properties->GetAlternativeServices(server);
bncd9b132e2015-07-08 05:16:1010544 ASSERT_EQ(1u, alternative_service_vector.size());
10545 EXPECT_EQ(alternative_service, alternative_service_vector[0]);
10546 EXPECT_TRUE(http_server_properties->IsAlternativeServiceBroken(
10547 alternative_service_vector[0]));
[email protected]564b4912010-03-09 16:30:4210548}
10549
bnc55ff9da2015-08-19 18:42:3510550// Ensure that we are not allowed to redirect traffic via an alternate protocol
10551// to an unrestricted (port >= 1024) when the original traffic was on a
10552// restricted port (port < 1024). Ensure that we can redirect in all other
10553// cases.
bncd16676a2016-07-20 16:23:0110554TEST_F(HttpNetworkTransactionTest, AlternateProtocolPortRestrictedBlocked) {
[email protected]3912662a32011-10-04 00:51:1110555 HttpRequestInfo restricted_port_request;
10556 restricted_port_request.method = "GET";
bncb26024382016-06-29 02:39:4510557 restricted_port_request.url = GURL("https://www.example.org:1023/");
[email protected]3912662a32011-10-04 00:51:1110558 restricted_port_request.load_flags = 0;
10559
[email protected]d973e99a2012-02-17 21:02:3610560 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
[email protected]3912662a32011-10-04 00:51:1110561 StaticSocketDataProvider first_data;
10562 first_data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:0710563 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
[email protected]3912662a32011-10-04 00:51:1110564
10565 MockRead data_reads[] = {
10566 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
10567 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:0610568 MockRead(ASYNC, OK),
[email protected]3912662a32011-10-04 00:51:1110569 };
10570 StaticSocketDataProvider second_data(
10571 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0710572 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
bncb26024382016-06-29 02:39:4510573 SSLSocketDataProvider ssl_http11(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3610574 ssl_http11.next_proto = kProtoHTTP11;
bncb26024382016-06-29 02:39:4510575 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_http11);
[email protected]3912662a32011-10-04 00:51:1110576
danakj1fd259a02016-04-16 03:17:0910577 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]3912662a32011-10-04 00:51:1110578
bnc525e175a2016-06-20 12:36:4010579 HttpServerProperties* http_server_properties =
[email protected]17291a022011-10-10 07:32:5310580 session->http_server_properties();
[email protected]3912662a32011-10-04 00:51:1110581 const int kUnrestrictedAlternatePort = 1024;
bnc3472afd2016-11-17 15:27:2110582 AlternativeService alternative_service(kProtoHTTP2, "www.example.org",
10583 kUnrestrictedAlternatePort);
bnc7dc7e1b42015-07-28 14:43:1210584 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
bnccacc0992015-03-20 20:22:2210585 http_server_properties->SetAlternativeService(
zhongyi3d4a55e72016-04-22 20:36:4610586 url::SchemeHostPort(restricted_port_request.url), alternative_service,
rchdc7b9052016-03-17 20:51:5010587 expiration);
[email protected]3912662a32011-10-04 00:51:1110588
bnc691fda62016-08-12 00:43:1610589 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]49639fa2011-12-20 23:22:4110590 TestCompletionCallback callback;
[email protected]3912662a32011-10-04 00:51:1110591
tfarina42834112016-09-22 13:38:2010592 int rv = trans.Start(&restricted_port_request, callback.callback(),
10593 NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110594 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]3912662a32011-10-04 00:51:1110595 // Invalid change to unrestricted port should fail.
robpercival214763f2016-07-01 23:27:0110596 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_CONNECTION_REFUSED));
[email protected]c54c6962013-02-01 04:53:1910597}
[email protected]3912662a32011-10-04 00:51:1110598
bnc55ff9da2015-08-19 18:42:3510599// Ensure that we are allowed to redirect traffic via an alternate protocol to
10600// an unrestricted (port >= 1024) when the original traffic was on a restricted
10601// port (port < 1024) if we set |enable_user_alternate_protocol_ports|.
bncd16676a2016-07-20 16:23:0110602TEST_F(HttpNetworkTransactionTest, AlternateProtocolPortRestrictedPermitted) {
[email protected]bb88e1d32013-05-03 23:11:0710603 session_deps_.enable_user_alternate_protocol_ports = true;
[email protected]c54c6962013-02-01 04:53:1910604
10605 HttpRequestInfo restricted_port_request;
10606 restricted_port_request.method = "GET";
bncb26024382016-06-29 02:39:4510607 restricted_port_request.url = GURL("https://www.example.org:1023/");
[email protected]c54c6962013-02-01 04:53:1910608 restricted_port_request.load_flags = 0;
10609
10610 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
10611 StaticSocketDataProvider first_data;
10612 first_data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:0710613 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
[email protected]c54c6962013-02-01 04:53:1910614
10615 MockRead data_reads[] = {
10616 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
10617 MockRead("hello world"),
10618 MockRead(ASYNC, OK),
10619 };
10620 StaticSocketDataProvider second_data(
10621 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0710622 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
bncb26024382016-06-29 02:39:4510623 SSLSocketDataProvider ssl_http11(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3610624 ssl_http11.next_proto = kProtoHTTP11;
bncb26024382016-06-29 02:39:4510625 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_http11);
[email protected]c54c6962013-02-01 04:53:1910626
danakj1fd259a02016-04-16 03:17:0910627 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]c54c6962013-02-01 04:53:1910628
bnc525e175a2016-06-20 12:36:4010629 HttpServerProperties* http_server_properties =
[email protected]c54c6962013-02-01 04:53:1910630 session->http_server_properties();
10631 const int kUnrestrictedAlternatePort = 1024;
bnc3472afd2016-11-17 15:27:2110632 AlternativeService alternative_service(kProtoHTTP2, "www.example.org",
10633 kUnrestrictedAlternatePort);
bnc7dc7e1b42015-07-28 14:43:1210634 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
bnccacc0992015-03-20 20:22:2210635 http_server_properties->SetAlternativeService(
zhongyi3d4a55e72016-04-22 20:36:4610636 url::SchemeHostPort(restricted_port_request.url), alternative_service,
rchdc7b9052016-03-17 20:51:5010637 expiration);
[email protected]c54c6962013-02-01 04:53:1910638
bnc691fda62016-08-12 00:43:1610639 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]c54c6962013-02-01 04:53:1910640 TestCompletionCallback callback;
10641
tfarina42834112016-09-22 13:38:2010642 EXPECT_EQ(ERR_IO_PENDING,
10643 trans.Start(&restricted_port_request, callback.callback(),
10644 NetLogWithSource()));
[email protected]c54c6962013-02-01 04:53:1910645 // Change to unrestricted port should succeed.
robpercival214763f2016-07-01 23:27:0110646 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]3912662a32011-10-04 00:51:1110647}
10648
bnc55ff9da2015-08-19 18:42:3510649// Ensure that we are not allowed to redirect traffic via an alternate protocol
10650// to an unrestricted (port >= 1024) when the original traffic was on a
10651// restricted port (port < 1024). Ensure that we can redirect in all other
10652// cases.
bncd16676a2016-07-20 16:23:0110653TEST_F(HttpNetworkTransactionTest, AlternateProtocolPortRestrictedAllowed) {
[email protected]3912662a32011-10-04 00:51:1110654 HttpRequestInfo restricted_port_request;
10655 restricted_port_request.method = "GET";
bncb26024382016-06-29 02:39:4510656 restricted_port_request.url = GURL("https://www.example.org:1023/");
[email protected]3912662a32011-10-04 00:51:1110657 restricted_port_request.load_flags = 0;
10658
[email protected]d973e99a2012-02-17 21:02:3610659 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
[email protected]3912662a32011-10-04 00:51:1110660 StaticSocketDataProvider first_data;
10661 first_data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:0710662 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
[email protected]3912662a32011-10-04 00:51:1110663
10664 MockRead data_reads[] = {
10665 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
10666 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:0610667 MockRead(ASYNC, OK),
[email protected]3912662a32011-10-04 00:51:1110668 };
10669 StaticSocketDataProvider second_data(
10670 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0710671 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
[email protected]3912662a32011-10-04 00:51:1110672
bncb26024382016-06-29 02:39:4510673 SSLSocketDataProvider ssl(ASYNC, OK);
10674 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
10675
danakj1fd259a02016-04-16 03:17:0910676 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]3912662a32011-10-04 00:51:1110677
bnc525e175a2016-06-20 12:36:4010678 HttpServerProperties* http_server_properties =
[email protected]17291a022011-10-10 07:32:5310679 session->http_server_properties();
[email protected]3912662a32011-10-04 00:51:1110680 const int kRestrictedAlternatePort = 80;
bnc3472afd2016-11-17 15:27:2110681 AlternativeService alternative_service(kProtoHTTP2, "www.example.org",
10682 kRestrictedAlternatePort);
bnc7dc7e1b42015-07-28 14:43:1210683 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
bnccacc0992015-03-20 20:22:2210684 http_server_properties->SetAlternativeService(
zhongyi3d4a55e72016-04-22 20:36:4610685 url::SchemeHostPort(restricted_port_request.url), alternative_service,
rchdc7b9052016-03-17 20:51:5010686 expiration);
[email protected]3912662a32011-10-04 00:51:1110687
bnc691fda62016-08-12 00:43:1610688 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]49639fa2011-12-20 23:22:4110689 TestCompletionCallback callback;
[email protected]3912662a32011-10-04 00:51:1110690
tfarina42834112016-09-22 13:38:2010691 int rv = trans.Start(&restricted_port_request, callback.callback(),
10692 NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110693 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]3912662a32011-10-04 00:51:1110694 // Valid change to restricted port should pass.
robpercival214763f2016-07-01 23:27:0110695 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]3912662a32011-10-04 00:51:1110696}
10697
bnc55ff9da2015-08-19 18:42:3510698// Ensure that we are not allowed to redirect traffic via an alternate protocol
10699// to an unrestricted (port >= 1024) when the original traffic was on a
10700// restricted port (port < 1024). Ensure that we can redirect in all other
10701// cases.
bncd16676a2016-07-20 16:23:0110702TEST_F(HttpNetworkTransactionTest, AlternateProtocolPortUnrestrictedAllowed1) {
[email protected]3912662a32011-10-04 00:51:1110703 HttpRequestInfo unrestricted_port_request;
10704 unrestricted_port_request.method = "GET";
bncb26024382016-06-29 02:39:4510705 unrestricted_port_request.url = GURL("https://www.example.org:1024/");
[email protected]3912662a32011-10-04 00:51:1110706 unrestricted_port_request.load_flags = 0;
10707
[email protected]d973e99a2012-02-17 21:02:3610708 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
[email protected]3912662a32011-10-04 00:51:1110709 StaticSocketDataProvider first_data;
10710 first_data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:0710711 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
[email protected]3912662a32011-10-04 00:51:1110712
10713 MockRead data_reads[] = {
10714 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
10715 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:0610716 MockRead(ASYNC, OK),
[email protected]3912662a32011-10-04 00:51:1110717 };
10718 StaticSocketDataProvider second_data(
10719 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0710720 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
bncb26024382016-06-29 02:39:4510721 SSLSocketDataProvider ssl_http11(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3610722 ssl_http11.next_proto = kProtoHTTP11;
bncb26024382016-06-29 02:39:4510723 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_http11);
[email protected]3912662a32011-10-04 00:51:1110724
danakj1fd259a02016-04-16 03:17:0910725 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]3912662a32011-10-04 00:51:1110726
bnc525e175a2016-06-20 12:36:4010727 HttpServerProperties* http_server_properties =
[email protected]17291a022011-10-10 07:32:5310728 session->http_server_properties();
[email protected]3912662a32011-10-04 00:51:1110729 const int kRestrictedAlternatePort = 80;
bnc3472afd2016-11-17 15:27:2110730 AlternativeService alternative_service(kProtoHTTP2, "www.example.org",
10731 kRestrictedAlternatePort);
bnc7dc7e1b42015-07-28 14:43:1210732 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
bnccacc0992015-03-20 20:22:2210733 http_server_properties->SetAlternativeService(
zhongyi3d4a55e72016-04-22 20:36:4610734 url::SchemeHostPort(unrestricted_port_request.url), alternative_service,
rchdc7b9052016-03-17 20:51:5010735 expiration);
[email protected]3912662a32011-10-04 00:51:1110736
bnc691fda62016-08-12 00:43:1610737 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]49639fa2011-12-20 23:22:4110738 TestCompletionCallback callback;
[email protected]3912662a32011-10-04 00:51:1110739
bnc691fda62016-08-12 00:43:1610740 int rv = trans.Start(&unrestricted_port_request, callback.callback(),
tfarina42834112016-09-22 13:38:2010741 NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110742 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]3912662a32011-10-04 00:51:1110743 // Valid change to restricted port should pass.
robpercival214763f2016-07-01 23:27:0110744 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]3912662a32011-10-04 00:51:1110745}
10746
bnc55ff9da2015-08-19 18:42:3510747// Ensure that we are not allowed to redirect traffic via an alternate protocol
10748// to an unrestricted (port >= 1024) when the original traffic was on a
10749// restricted port (port < 1024). Ensure that we can redirect in all other
10750// cases.
bncd16676a2016-07-20 16:23:0110751TEST_F(HttpNetworkTransactionTest, AlternateProtocolPortUnrestrictedAllowed2) {
[email protected]3912662a32011-10-04 00:51:1110752 HttpRequestInfo unrestricted_port_request;
10753 unrestricted_port_request.method = "GET";
bncb26024382016-06-29 02:39:4510754 unrestricted_port_request.url = GURL("https://www.example.org:1024/");
[email protected]3912662a32011-10-04 00:51:1110755 unrestricted_port_request.load_flags = 0;
10756
[email protected]d973e99a2012-02-17 21:02:3610757 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
[email protected]3912662a32011-10-04 00:51:1110758 StaticSocketDataProvider first_data;
10759 first_data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:0710760 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
[email protected]3912662a32011-10-04 00:51:1110761
10762 MockRead data_reads[] = {
10763 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
10764 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:0610765 MockRead(ASYNC, OK),
[email protected]3912662a32011-10-04 00:51:1110766 };
10767 StaticSocketDataProvider second_data(
10768 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0710769 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
[email protected]3912662a32011-10-04 00:51:1110770
bncb26024382016-06-29 02:39:4510771 SSLSocketDataProvider ssl(ASYNC, OK);
10772 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
10773
danakj1fd259a02016-04-16 03:17:0910774 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]3912662a32011-10-04 00:51:1110775
bnc525e175a2016-06-20 12:36:4010776 HttpServerProperties* http_server_properties =
[email protected]17291a022011-10-10 07:32:5310777 session->http_server_properties();
bnc0bbb02622015-07-23 10:06:2210778 const int kUnrestrictedAlternatePort = 1025;
bnc3472afd2016-11-17 15:27:2110779 AlternativeService alternative_service(kProtoHTTP2, "www.example.org",
10780 kUnrestrictedAlternatePort);
bnc7dc7e1b42015-07-28 14:43:1210781 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
bnccacc0992015-03-20 20:22:2210782 http_server_properties->SetAlternativeService(
zhongyi3d4a55e72016-04-22 20:36:4610783 url::SchemeHostPort(unrestricted_port_request.url), alternative_service,
rchdc7b9052016-03-17 20:51:5010784 expiration);
[email protected]3912662a32011-10-04 00:51:1110785
bnc691fda62016-08-12 00:43:1610786 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]49639fa2011-12-20 23:22:4110787 TestCompletionCallback callback;
[email protected]3912662a32011-10-04 00:51:1110788
bnc691fda62016-08-12 00:43:1610789 int rv = trans.Start(&unrestricted_port_request, callback.callback(),
tfarina42834112016-09-22 13:38:2010790 NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110791 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]3912662a32011-10-04 00:51:1110792 // Valid change to an unrestricted port should pass.
robpercival214763f2016-07-01 23:27:0110793 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]3912662a32011-10-04 00:51:1110794}
10795
bnc55ff9da2015-08-19 18:42:3510796// Ensure that we are not allowed to redirect traffic via an alternate protocol
10797// to an unsafe port, and that we resume the second HttpStreamFactoryImpl::Job
10798// once the alternate protocol request fails.
bncd16676a2016-07-20 16:23:0110799TEST_F(HttpNetworkTransactionTest, AlternateProtocolUnsafeBlocked) {
[email protected]eb6234e2012-01-19 01:50:0210800 HttpRequestInfo request;
10801 request.method = "GET";
bncce36dca22015-04-21 22:11:2310802 request.url = GURL("http://www.example.org/");
[email protected]eb6234e2012-01-19 01:50:0210803
10804 // The alternate protocol request will error out before we attempt to connect,
10805 // so only the standard HTTP request will try to connect.
10806 MockRead data_reads[] = {
10807 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
10808 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:0610809 MockRead(ASYNC, OK),
[email protected]eb6234e2012-01-19 01:50:0210810 };
10811 StaticSocketDataProvider data(
10812 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0710813 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]eb6234e2012-01-19 01:50:0210814
danakj1fd259a02016-04-16 03:17:0910815 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]eb6234e2012-01-19 01:50:0210816
bnc525e175a2016-06-20 12:36:4010817 HttpServerProperties* http_server_properties =
[email protected]eb6234e2012-01-19 01:50:0210818 session->http_server_properties();
10819 const int kUnsafePort = 7;
bnc3472afd2016-11-17 15:27:2110820 AlternativeService alternative_service(kProtoHTTP2, "www.example.org",
10821 kUnsafePort);
bnc7dc7e1b42015-07-28 14:43:1210822 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
bnccacc0992015-03-20 20:22:2210823 http_server_properties->SetAlternativeService(
zhongyi3d4a55e72016-04-22 20:36:4610824 url::SchemeHostPort(request.url), alternative_service, expiration);
[email protected]eb6234e2012-01-19 01:50:0210825
bnc691fda62016-08-12 00:43:1610826 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]eb6234e2012-01-19 01:50:0210827 TestCompletionCallback callback;
10828
tfarina42834112016-09-22 13:38:2010829 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110830 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]eb6234e2012-01-19 01:50:0210831 // The HTTP request should succeed.
robpercival214763f2016-07-01 23:27:0110832 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]eb6234e2012-01-19 01:50:0210833
bnc691fda62016-08-12 00:43:1610834 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5210835 ASSERT_TRUE(response);
10836 ASSERT_TRUE(response->headers);
[email protected]eb6234e2012-01-19 01:50:0210837 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
10838
10839 std::string response_data;
bnc691fda62016-08-12 00:43:1610840 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
[email protected]eb6234e2012-01-19 01:50:0210841 EXPECT_EQ("hello world", response_data);
10842}
10843
bncd16676a2016-07-20 16:23:0110844TEST_F(HttpNetworkTransactionTest, UseAlternateProtocolForNpnSpdy) {
[email protected]2ff8b312010-04-26 22:20:5410845 HttpRequestInfo request;
10846 request.method = "GET";
bncb26024382016-06-29 02:39:4510847 request.url = GURL("https://www.example.org/");
[email protected]2ff8b312010-04-26 22:20:5410848
10849 MockRead data_reads[] = {
bncc958faa2015-07-31 18:14:5210850 MockRead("HTTP/1.1 200 OK\r\n"),
bnc2df4b522016-07-08 18:17:4310851 MockRead(kAlternativeServiceHttpHeader),
bncc958faa2015-07-31 18:14:5210852 MockRead("\r\n"),
10853 MockRead("hello world"),
10854 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
10855 MockRead(ASYNC, OK)};
[email protected]2ff8b312010-04-26 22:20:5410856
10857 StaticSocketDataProvider first_transaction(
10858 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0710859 session_deps_.socket_factory->AddSocketDataProvider(&first_transaction);
bncb26024382016-06-29 02:39:4510860 SSLSocketDataProvider ssl_http11(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3610861 ssl_http11.next_proto = kProtoHTTP11;
bncb26024382016-06-29 02:39:4510862 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_http11);
[email protected]2ff8b312010-04-26 22:20:5410863
bnc032658ba2016-09-26 18:17:1510864 AddSSLSocketData();
[email protected]2ff8b312010-04-26 22:20:5410865
bncdf80d44fd2016-07-15 20:27:4110866 SpdySerializedFrame req(
bncb26024382016-06-29 02:39:4510867 spdy_util_.ConstructSpdyGet("https://www.example.org/", 1, LOWEST));
bncdf80d44fd2016-07-15 20:27:4110868 MockWrite spdy_writes[] = {CreateMockWrite(req, 0)};
[email protected]2ff8b312010-04-26 22:20:5410869
bnc42331402016-07-25 13:36:1510870 SpdySerializedFrame resp(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
bncdf80d44fd2016-07-15 20:27:4110871 SpdySerializedFrame data(spdy_util_.ConstructSpdyDataFrame(1, true));
[email protected]2ff8b312010-04-26 22:20:5410872 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:4110873 CreateMockRead(resp, 1), CreateMockRead(data, 2), MockRead(ASYNC, 0, 3),
[email protected]2ff8b312010-04-26 22:20:5410874 };
10875
rch8e6c6c42015-05-01 14:05:1310876 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
10877 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:0710878 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]2ff8b312010-04-26 22:20:5410879
[email protected]d973e99a2012-02-17 21:02:3610880 MockConnect never_finishing_connect(SYNCHRONOUS, ERR_IO_PENDING);
[email protected]2d6728692011-03-12 01:39:5510881 StaticSocketDataProvider hanging_non_alternate_protocol_socket(
10882 NULL, 0, NULL, 0);
10883 hanging_non_alternate_protocol_socket.set_connect_data(
10884 never_finishing_connect);
[email protected]bb88e1d32013-05-03 23:11:0710885 session_deps_.socket_factory->AddSocketDataProvider(
[email protected]2d6728692011-03-12 01:39:5510886 &hanging_non_alternate_protocol_socket);
10887
[email protected]49639fa2011-12-20 23:22:4110888 TestCompletionCallback callback;
[email protected]2ff8b312010-04-26 22:20:5410889
danakj1fd259a02016-04-16 03:17:0910890 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1610891 std::unique_ptr<HttpNetworkTransaction> trans(
[email protected]90499482013-06-01 00:39:5010892 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]2ff8b312010-04-26 22:20:5410893
tfarina42834112016-09-22 13:38:2010894 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110895 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
10896 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]2ff8b312010-04-26 22:20:5410897
10898 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5210899 ASSERT_TRUE(response);
10900 ASSERT_TRUE(response->headers);
[email protected]2ff8b312010-04-26 22:20:5410901 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
10902
10903 std::string response_data;
robpercival214763f2016-07-01 23:27:0110904 ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
[email protected]2ff8b312010-04-26 22:20:5410905 EXPECT_EQ("hello world", response_data);
10906
[email protected]90499482013-06-01 00:39:5010907 trans.reset(new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]2ff8b312010-04-26 22:20:5410908
tfarina42834112016-09-22 13:38:2010909 rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110910 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
10911 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]2ff8b312010-04-26 22:20:5410912
10913 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5210914 ASSERT_TRUE(response);
10915 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0210916 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]65041fa2010-05-21 06:56:5310917 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5210918 EXPECT_TRUE(response->was_alpn_negotiated);
[email protected]2ff8b312010-04-26 22:20:5410919
robpercival214763f2016-07-01 23:27:0110920 ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
[email protected]2ff8b312010-04-26 22:20:5410921 EXPECT_EQ("hello!", response_data);
[email protected]2ff8b312010-04-26 22:20:5410922}
10923
bncd16676a2016-07-20 16:23:0110924TEST_F(HttpNetworkTransactionTest, AlternateProtocolWithSpdyLateBinding) {
[email protected]2d6728692011-03-12 01:39:5510925 HttpRequestInfo request;
10926 request.method = "GET";
bncb26024382016-06-29 02:39:4510927 request.url = GURL("https://www.example.org/");
[email protected]2d6728692011-03-12 01:39:5510928
bncb26024382016-06-29 02:39:4510929 // First transaction receives Alt-Svc header over HTTP/1.1.
[email protected]2d6728692011-03-12 01:39:5510930 MockRead data_reads[] = {
bncc958faa2015-07-31 18:14:5210931 MockRead("HTTP/1.1 200 OK\r\n"),
bnc2df4b522016-07-08 18:17:4310932 MockRead(kAlternativeServiceHttpHeader),
bncc958faa2015-07-31 18:14:5210933 MockRead("\r\n"),
10934 MockRead("hello world"),
10935 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
10936 MockRead(ASYNC, OK),
[email protected]2d6728692011-03-12 01:39:5510937 };
10938
bncb26024382016-06-29 02:39:4510939 StaticSocketDataProvider http11_data(data_reads, arraysize(data_reads), NULL,
10940 0);
10941 session_deps_.socket_factory->AddSocketDataProvider(&http11_data);
[email protected]2d6728692011-03-12 01:39:5510942
bncb26024382016-06-29 02:39:4510943 SSLSocketDataProvider ssl_http11(ASYNC, OK);
10944 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_http11);
10945
10946 // Second transaction starts an alternative and a non-alternative Job.
10947 // Both sockets hang.
[email protected]d973e99a2012-02-17 21:02:3610948 MockConnect never_finishing_connect(SYNCHRONOUS, ERR_IO_PENDING);
mmenkecc2298e2015-12-07 18:20:1810949 StaticSocketDataProvider hanging_socket1(NULL, 0, NULL, 0);
10950 hanging_socket1.set_connect_data(never_finishing_connect);
mmenkecc2298e2015-12-07 18:20:1810951 session_deps_.socket_factory->AddSocketDataProvider(&hanging_socket1);
10952
10953 StaticSocketDataProvider hanging_socket2(NULL, 0, NULL, 0);
10954 hanging_socket2.set_connect_data(never_finishing_connect);
10955 session_deps_.socket_factory->AddSocketDataProvider(&hanging_socket2);
[email protected]2d6728692011-03-12 01:39:5510956
bncb26024382016-06-29 02:39:4510957 // Third transaction starts an alternative and a non-alternative job.
10958 // The non-alternative job hangs, but the alternative one succeeds.
10959 // The second transaction, still pending, binds to this socket.
bncdf80d44fd2016-07-15 20:27:4110960 SpdySerializedFrame req1(
bncb26024382016-06-29 02:39:4510961 spdy_util_.ConstructSpdyGet("https://www.example.org/", 1, LOWEST));
bncdf80d44fd2016-07-15 20:27:4110962 SpdySerializedFrame req2(
bncb26024382016-06-29 02:39:4510963 spdy_util_.ConstructSpdyGet("https://www.example.org/", 3, LOWEST));
[email protected]2d6728692011-03-12 01:39:5510964 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:4110965 CreateMockWrite(req1, 0), CreateMockWrite(req2, 1),
[email protected]2d6728692011-03-12 01:39:5510966 };
bnc42331402016-07-25 13:36:1510967 SpdySerializedFrame resp1(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
bncdf80d44fd2016-07-15 20:27:4110968 SpdySerializedFrame data1(spdy_util_.ConstructSpdyDataFrame(1, true));
bnc42331402016-07-25 13:36:1510969 SpdySerializedFrame resp2(spdy_util_.ConstructSpdyGetReply(NULL, 0, 3));
bncdf80d44fd2016-07-15 20:27:4110970 SpdySerializedFrame data2(spdy_util_.ConstructSpdyDataFrame(3, true));
[email protected]2d6728692011-03-12 01:39:5510971 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:4110972 CreateMockRead(resp1, 2), CreateMockRead(data1, 3),
10973 CreateMockRead(resp2, 4), CreateMockRead(data2, 5),
rch8e6c6c42015-05-01 14:05:1310974 MockRead(ASYNC, 0, 6),
[email protected]2d6728692011-03-12 01:39:5510975 };
10976
rch8e6c6c42015-05-01 14:05:1310977 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
10978 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:0710979 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]2d6728692011-03-12 01:39:5510980
bnc032658ba2016-09-26 18:17:1510981 AddSSLSocketData();
bncb26024382016-06-29 02:39:4510982
mmenkecc2298e2015-12-07 18:20:1810983 StaticSocketDataProvider hanging_socket3(NULL, 0, NULL, 0);
10984 hanging_socket3.set_connect_data(never_finishing_connect);
10985 session_deps_.socket_factory->AddSocketDataProvider(&hanging_socket3);
[email protected]2d6728692011-03-12 01:39:5510986
danakj1fd259a02016-04-16 03:17:0910987 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]49639fa2011-12-20 23:22:4110988 TestCompletionCallback callback1;
[email protected]90499482013-06-01 00:39:5010989 HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
[email protected]2d6728692011-03-12 01:39:5510990
tfarina42834112016-09-22 13:38:2010991 int rv = trans1.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110992 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
10993 EXPECT_THAT(callback1.WaitForResult(), IsOk());
[email protected]2d6728692011-03-12 01:39:5510994
10995 const HttpResponseInfo* response = trans1.GetResponseInfo();
wezca1070932016-05-26 20:30:5210996 ASSERT_TRUE(response);
10997 ASSERT_TRUE(response->headers);
[email protected]2d6728692011-03-12 01:39:5510998 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
10999
11000 std::string response_data;
robpercival214763f2016-07-01 23:27:0111001 ASSERT_THAT(ReadTransaction(&trans1, &response_data), IsOk());
[email protected]2d6728692011-03-12 01:39:5511002 EXPECT_EQ("hello world", response_data);
11003
[email protected]49639fa2011-12-20 23:22:4111004 TestCompletionCallback callback2;
[email protected]90499482013-06-01 00:39:5011005 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:2011006 rv = trans2.Start(&request, callback2.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0111007 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2d6728692011-03-12 01:39:5511008
[email protected]49639fa2011-12-20 23:22:4111009 TestCompletionCallback callback3;
[email protected]90499482013-06-01 00:39:5011010 HttpNetworkTransaction trans3(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:2011011 rv = trans3.Start(&request, callback3.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0111012 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2d6728692011-03-12 01:39:5511013
robpercival214763f2016-07-01 23:27:0111014 EXPECT_THAT(callback2.WaitForResult(), IsOk());
11015 EXPECT_THAT(callback3.WaitForResult(), IsOk());
[email protected]2d6728692011-03-12 01:39:5511016
11017 response = trans2.GetResponseInfo();
wezca1070932016-05-26 20:30:5211018 ASSERT_TRUE(response);
11019 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0211020 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]2d6728692011-03-12 01:39:5511021 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5211022 EXPECT_TRUE(response->was_alpn_negotiated);
robpercival214763f2016-07-01 23:27:0111023 ASSERT_THAT(ReadTransaction(&trans2, &response_data), IsOk());
[email protected]2d6728692011-03-12 01:39:5511024 EXPECT_EQ("hello!", response_data);
11025
11026 response = trans3.GetResponseInfo();
wezca1070932016-05-26 20:30:5211027 ASSERT_TRUE(response);
11028 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0211029 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]2d6728692011-03-12 01:39:5511030 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5211031 EXPECT_TRUE(response->was_alpn_negotiated);
robpercival214763f2016-07-01 23:27:0111032 ASSERT_THAT(ReadTransaction(&trans3, &response_data), IsOk());
[email protected]2d6728692011-03-12 01:39:5511033 EXPECT_EQ("hello!", response_data);
[email protected]2d6728692011-03-12 01:39:5511034}
11035
bncd16676a2016-07-20 16:23:0111036TEST_F(HttpNetworkTransactionTest, StallAlternativeServiceForNpnSpdy) {
[email protected]2d6728692011-03-12 01:39:5511037 HttpRequestInfo request;
11038 request.method = "GET";
bncb26024382016-06-29 02:39:4511039 request.url = GURL("https://www.example.org/");
[email protected]2d6728692011-03-12 01:39:5511040
11041 MockRead data_reads[] = {
bncc958faa2015-07-31 18:14:5211042 MockRead("HTTP/1.1 200 OK\r\n"),
bnc2df4b522016-07-08 18:17:4311043 MockRead(kAlternativeServiceHttpHeader),
bncc958faa2015-07-31 18:14:5211044 MockRead("\r\n"),
11045 MockRead("hello world"),
11046 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
11047 MockRead(ASYNC, OK),
[email protected]2d6728692011-03-12 01:39:5511048 };
11049
11050 StaticSocketDataProvider first_transaction(
11051 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0711052 session_deps_.socket_factory->AddSocketDataProvider(&first_transaction);
[email protected]2d6728692011-03-12 01:39:5511053
[email protected]8ddf8322012-02-23 18:08:0611054 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:0711055 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]2d6728692011-03-12 01:39:5511056
[email protected]d973e99a2012-02-17 21:02:3611057 MockConnect never_finishing_connect(SYNCHRONOUS, ERR_IO_PENDING);
[email protected]2d6728692011-03-12 01:39:5511058 StaticSocketDataProvider hanging_alternate_protocol_socket(
11059 NULL, 0, NULL, 0);
11060 hanging_alternate_protocol_socket.set_connect_data(
11061 never_finishing_connect);
[email protected]bb88e1d32013-05-03 23:11:0711062 session_deps_.socket_factory->AddSocketDataProvider(
[email protected]2d6728692011-03-12 01:39:5511063 &hanging_alternate_protocol_socket);
11064
bncb26024382016-06-29 02:39:4511065 // 2nd request is just a copy of the first one, over HTTP/1.1 again.
mmenkecc2298e2015-12-07 18:20:1811066 StaticSocketDataProvider second_transaction(data_reads, arraysize(data_reads),
11067 NULL, 0);
11068 session_deps_.socket_factory->AddSocketDataProvider(&second_transaction);
bncb26024382016-06-29 02:39:4511069 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]2d6728692011-03-12 01:39:5511070
[email protected]49639fa2011-12-20 23:22:4111071 TestCompletionCallback callback;
[email protected]2d6728692011-03-12 01:39:5511072
danakj1fd259a02016-04-16 03:17:0911073 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1611074 std::unique_ptr<HttpNetworkTransaction> trans(
[email protected]90499482013-06-01 00:39:5011075 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]2d6728692011-03-12 01:39:5511076
tfarina42834112016-09-22 13:38:2011077 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0111078 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
11079 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]2d6728692011-03-12 01:39:5511080
11081 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5211082 ASSERT_TRUE(response);
11083 ASSERT_TRUE(response->headers);
[email protected]2d6728692011-03-12 01:39:5511084 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
11085
11086 std::string response_data;
robpercival214763f2016-07-01 23:27:0111087 ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
[email protected]2d6728692011-03-12 01:39:5511088 EXPECT_EQ("hello world", response_data);
11089
[email protected]90499482013-06-01 00:39:5011090 trans.reset(new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]2d6728692011-03-12 01:39:5511091
tfarina42834112016-09-22 13:38:2011092 rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0111093 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
11094 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]2d6728692011-03-12 01:39:5511095
11096 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5211097 ASSERT_TRUE(response);
11098 ASSERT_TRUE(response->headers);
[email protected]2d6728692011-03-12 01:39:5511099 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
11100 EXPECT_FALSE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5211101 EXPECT_FALSE(response->was_alpn_negotiated);
[email protected]2d6728692011-03-12 01:39:5511102
robpercival214763f2016-07-01 23:27:0111103 ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
[email protected]2d6728692011-03-12 01:39:5511104 EXPECT_EQ("hello world", response_data);
[email protected]2d6728692011-03-12 01:39:5511105}
11106
[email protected]631f1322010-04-30 17:59:1111107class CapturingProxyResolver : public ProxyResolver {
11108 public:
sammce90c9212015-05-27 23:43:3511109 CapturingProxyResolver() {}
dchengb03027d2014-10-21 12:00:2011110 ~CapturingProxyResolver() override {}
[email protected]631f1322010-04-30 17:59:1111111
dchengb03027d2014-10-21 12:00:2011112 int GetProxyForURL(const GURL& url,
11113 ProxyInfo* results,
11114 const CompletionCallback& callback,
maksim.sisov7e157262016-10-20 11:19:5511115 std::unique_ptr<Request>* request,
tfarina42834112016-09-22 13:38:2011116 const NetLogWithSource& net_log) override {
[email protected]fae7669f2010-08-02 21:49:4011117 ProxyServer proxy_server(ProxyServer::SCHEME_HTTP,
11118 HostPortPair("myproxy", 80));
[email protected]d911f1b2010-05-05 22:39:4211119 results->UseProxyServer(proxy_server);
[email protected]631f1322010-04-30 17:59:1111120 resolved_.push_back(url);
[email protected]d911f1b2010-05-05 22:39:4211121 return OK;
[email protected]631f1322010-04-30 17:59:1111122 }
11123
[email protected]24476402010-07-20 20:55:1711124 const std::vector<GURL>& resolved() const { return resolved_; }
11125
11126 private:
[email protected]631f1322010-04-30 17:59:1111127 std::vector<GURL> resolved_;
11128
11129 DISALLOW_COPY_AND_ASSIGN(CapturingProxyResolver);
11130};
11131
sammce64b2362015-04-29 03:50:2311132class CapturingProxyResolverFactory : public ProxyResolverFactory {
11133 public:
11134 explicit CapturingProxyResolverFactory(CapturingProxyResolver* resolver)
11135 : ProxyResolverFactory(false), resolver_(resolver) {}
11136
11137 int CreateProxyResolver(
11138 const scoped_refptr<ProxyResolverScriptData>& pac_script,
danakj1fd259a02016-04-16 03:17:0911139 std::unique_ptr<ProxyResolver>* resolver,
sammce64b2362015-04-29 03:50:2311140 const net::CompletionCallback& callback,
danakj1fd259a02016-04-16 03:17:0911141 std::unique_ptr<Request>* request) override {
sammce64b2362015-04-29 03:50:2311142 resolver->reset(new ForwardingProxyResolver(resolver_));
11143 return OK;
11144 }
11145
11146 private:
11147 ProxyResolver* resolver_;
11148};
11149
bnc2e884782016-08-11 19:45:1911150// Test that proxy is resolved using the origin url,
11151// regardless of the alternative server.
11152TEST_F(HttpNetworkTransactionTest, UseOriginNotAlternativeForProxy) {
11153 // Configure proxy to bypass www.example.org, which is the origin URL.
11154 ProxyConfig proxy_config;
11155 proxy_config.proxy_rules().ParseFromString("myproxy:70");
11156 proxy_config.proxy_rules().bypass_rules.AddRuleFromString("www.example.org");
11157 auto proxy_config_service =
11158 base::MakeUnique<ProxyConfigServiceFixed>(proxy_config);
11159
11160 CapturingProxyResolver capturing_proxy_resolver;
11161 auto proxy_resolver_factory = base::MakeUnique<CapturingProxyResolverFactory>(
11162 &capturing_proxy_resolver);
11163
11164 TestNetLog net_log;
11165
11166 session_deps_.proxy_service = base::MakeUnique<ProxyService>(
11167 std::move(proxy_config_service), std::move(proxy_resolver_factory),
11168 &net_log);
11169
11170 session_deps_.net_log = &net_log;
11171
11172 // Configure alternative service with a hostname that is not bypassed by the
11173 // proxy.
11174 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
11175 HttpServerProperties* http_server_properties =
11176 session->http_server_properties();
11177 url::SchemeHostPort server("https", "www.example.org", 443);
11178 HostPortPair alternative("www.example.com", 443);
bnc3472afd2016-11-17 15:27:2111179 AlternativeService alternative_service(kProtoHTTP2, alternative);
bnc2e884782016-08-11 19:45:1911180 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
11181 http_server_properties->SetAlternativeService(server, alternative_service,
11182 expiration);
11183
11184 // Non-alternative job should hang.
11185 MockConnect never_finishing_connect(SYNCHRONOUS, ERR_IO_PENDING);
11186 StaticSocketDataProvider hanging_alternate_protocol_socket(nullptr, 0,
11187 nullptr, 0);
11188 hanging_alternate_protocol_socket.set_connect_data(never_finishing_connect);
11189 session_deps_.socket_factory->AddSocketDataProvider(
11190 &hanging_alternate_protocol_socket);
11191
bnc032658ba2016-09-26 18:17:1511192 AddSSLSocketData();
bnc2e884782016-08-11 19:45:1911193
11194 HttpRequestInfo request;
11195 request.method = "GET";
11196 request.url = GURL("https://www.example.org/");
11197 request.load_flags = 0;
11198
11199 SpdySerializedFrame req(
11200 spdy_util_.ConstructSpdyGet("https://www.example.org/", 1, LOWEST));
11201
11202 MockWrite spdy_writes[] = {CreateMockWrite(req, 0)};
11203
11204 SpdySerializedFrame resp(spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
11205 SpdySerializedFrame data(spdy_util_.ConstructSpdyDataFrame(1, true));
11206 MockRead spdy_reads[] = {
11207 CreateMockRead(resp, 1), CreateMockRead(data, 2), MockRead(ASYNC, 0, 3),
11208 };
11209
11210 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
11211 arraysize(spdy_writes));
11212 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
11213
11214 TestCompletionCallback callback;
11215
11216 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
11217
tfarina42834112016-09-22 13:38:2011218 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
bnc2e884782016-08-11 19:45:1911219 EXPECT_THAT(callback.GetResult(rv), IsOk());
11220
11221 const HttpResponseInfo* response = trans.GetResponseInfo();
11222 ASSERT_TRUE(response);
11223 ASSERT_TRUE(response->headers);
11224 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
11225 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5211226 EXPECT_TRUE(response->was_alpn_negotiated);
bnc2e884782016-08-11 19:45:1911227
11228 std::string response_data;
11229 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
11230 EXPECT_EQ("hello!", response_data);
11231
11232 // Origin host bypasses proxy, no resolution should have happened.
11233 ASSERT_TRUE(capturing_proxy_resolver.resolved().empty());
11234}
11235
bncd16676a2016-07-20 16:23:0111236TEST_F(HttpNetworkTransactionTest, UseAlternativeServiceForTunneledNpnSpdy) {
[email protected]631f1322010-04-30 17:59:1111237 ProxyConfig proxy_config;
[email protected]d911f1b2010-05-05 22:39:4211238 proxy_config.set_auto_detect(true);
11239 proxy_config.set_pac_url(GURL("http://fooproxyurl"));
[email protected]2227c692010-05-04 15:36:1111240
sammc5dd160c2015-04-02 02:43:1311241 CapturingProxyResolver capturing_proxy_resolver;
ricea2deef682016-09-09 08:04:0711242 session_deps_.proxy_service.reset(
11243 new ProxyService(base::MakeUnique<ProxyConfigServiceFixed>(proxy_config),
11244 base::MakeUnique<CapturingProxyResolverFactory>(
11245 &capturing_proxy_resolver),
11246 NULL));
vishal.b62985ca92015-04-17 08:45:5111247 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:0711248 session_deps_.net_log = &net_log;
[email protected]631f1322010-04-30 17:59:1111249
11250 HttpRequestInfo request;
11251 request.method = "GET";
bncb26024382016-06-29 02:39:4511252 request.url = GURL("https://www.example.org/");
[email protected]631f1322010-04-30 17:59:1111253
11254 MockRead data_reads[] = {
bncc958faa2015-07-31 18:14:5211255 MockRead("HTTP/1.1 200 OK\r\n"),
bnc2df4b522016-07-08 18:17:4311256 MockRead(kAlternativeServiceHttpHeader),
bncc958faa2015-07-31 18:14:5211257 MockRead("\r\n"),
11258 MockRead("hello world"),
11259 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
11260 MockRead(ASYNC, OK),
[email protected]631f1322010-04-30 17:59:1111261 };
11262
11263 StaticSocketDataProvider first_transaction(
11264 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0711265 session_deps_.socket_factory->AddSocketDataProvider(&first_transaction);
bncb26024382016-06-29 02:39:4511266 SSLSocketDataProvider ssl_http11(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3611267 ssl_http11.next_proto = kProtoHTTP11;
bncb26024382016-06-29 02:39:4511268 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_http11);
[email protected]631f1322010-04-30 17:59:1111269
bnc032658ba2016-09-26 18:17:1511270 AddSSLSocketData();
[email protected]631f1322010-04-30 17:59:1111271
bncdf80d44fd2016-07-15 20:27:4111272 SpdySerializedFrame req(
bncb26024382016-06-29 02:39:4511273 spdy_util_.ConstructSpdyGet("https://www.example.org/", 1, LOWEST));
[email protected]631f1322010-04-30 17:59:1111274 MockWrite spdy_writes[] = {
rch8e6c6c42015-05-01 14:05:1311275 MockWrite(ASYNC, 0,
bnc8bef8da22016-05-30 01:28:2511276 "CONNECT www.example.org:443 HTTP/1.1\r\n"
11277 "Host: www.example.org:443\r\n"
rch8e6c6c42015-05-01 14:05:1311278 "Proxy-Connection: keep-alive\r\n\r\n"),
bncdf80d44fd2016-07-15 20:27:4111279 CreateMockWrite(req, 2),
[email protected]631f1322010-04-30 17:59:1111280 };
11281
[email protected]d911f1b2010-05-05 22:39:4211282 const char kCONNECTResponse[] = "HTTP/1.1 200 Connected\r\n\r\n";
11283
bnc42331402016-07-25 13:36:1511284 SpdySerializedFrame resp(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
bncdf80d44fd2016-07-15 20:27:4111285 SpdySerializedFrame data(spdy_util_.ConstructSpdyDataFrame(1, true));
[email protected]631f1322010-04-30 17:59:1111286 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:4111287 MockRead(ASYNC, 1, kCONNECTResponse), CreateMockRead(resp, 3),
11288 CreateMockRead(data, 4), MockRead(SYNCHRONOUS, ERR_IO_PENDING, 5),
[email protected]631f1322010-04-30 17:59:1111289 };
11290
rch8e6c6c42015-05-01 14:05:1311291 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
11292 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:0711293 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]631f1322010-04-30 17:59:1111294
[email protected]d973e99a2012-02-17 21:02:3611295 MockConnect never_finishing_connect(SYNCHRONOUS, ERR_IO_PENDING);
[email protected]2d6728692011-03-12 01:39:5511296 StaticSocketDataProvider hanging_non_alternate_protocol_socket(
11297 NULL, 0, NULL, 0);
11298 hanging_non_alternate_protocol_socket.set_connect_data(
11299 never_finishing_connect);
[email protected]bb88e1d32013-05-03 23:11:0711300 session_deps_.socket_factory->AddSocketDataProvider(
[email protected]2d6728692011-03-12 01:39:5511301 &hanging_non_alternate_protocol_socket);
11302
[email protected]49639fa2011-12-20 23:22:4111303 TestCompletionCallback callback;
[email protected]631f1322010-04-30 17:59:1111304
danakj1fd259a02016-04-16 03:17:0911305 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1611306 std::unique_ptr<HttpNetworkTransaction> trans(
[email protected]90499482013-06-01 00:39:5011307 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]631f1322010-04-30 17:59:1111308
tfarina42834112016-09-22 13:38:2011309 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
mmenkea2dcd3bf2016-08-16 21:49:4111310 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
11311 EXPECT_THAT(callback.WaitForResult(), IsOk());
11312
11313 const HttpResponseInfo* response = trans->GetResponseInfo();
11314 ASSERT_TRUE(response);
11315 ASSERT_TRUE(response->headers);
11316 EXPECT_EQ("HTTP/0.9 200 OK", response->headers->GetStatusLine());
11317 EXPECT_FALSE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5211318 EXPECT_TRUE(response->was_alpn_negotiated);
mmenkea2dcd3bf2016-08-16 21:49:4111319
11320 std::string response_data;
11321 ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
11322 EXPECT_EQ("hello world", response_data);
[email protected]631f1322010-04-30 17:59:1111323
[email protected]90499482013-06-01 00:39:5011324 trans.reset(new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]631f1322010-04-30 17:59:1111325
tfarina42834112016-09-22 13:38:2011326 rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0111327 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
11328 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]631f1322010-04-30 17:59:1111329
mmenkea2dcd3bf2016-08-16 21:49:4111330 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5211331 ASSERT_TRUE(response);
11332 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0211333 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]65041fa2010-05-21 06:56:5311334 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5211335 EXPECT_TRUE(response->was_alpn_negotiated);
[email protected]631f1322010-04-30 17:59:1111336
robpercival214763f2016-07-01 23:27:0111337 ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
[email protected]631f1322010-04-30 17:59:1111338 EXPECT_EQ("hello!", response_data);
bncb26024382016-06-29 02:39:4511339 ASSERT_EQ(2u, capturing_proxy_resolver.resolved().size());
11340 EXPECT_EQ("https://www.example.org/",
sammc5dd160c2015-04-02 02:43:1311341 capturing_proxy_resolver.resolved()[0].spec());
bncce36dca22015-04-21 22:11:2311342 EXPECT_EQ("https://www.example.org/",
sammc5dd160c2015-04-02 02:43:1311343 capturing_proxy_resolver.resolved()[1].spec());
[email protected]631f1322010-04-30 17:59:1111344
[email protected]029c83b62013-01-24 05:28:2011345 LoadTimingInfo load_timing_info;
11346 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
11347 TestLoadTimingNotReusedWithPac(load_timing_info,
11348 CONNECT_TIMING_HAS_SSL_TIMES);
[email protected]631f1322010-04-30 17:59:1111349}
[email protected]631f1322010-04-30 17:59:1111350
bncd16676a2016-07-20 16:23:0111351TEST_F(HttpNetworkTransactionTest,
bnc1c196c6e2016-05-28 13:51:4811352 UseAlternativeServiceForNpnSpdyWithExistingSpdySession) {
[email protected]2ff8b312010-04-26 22:20:5411353 HttpRequestInfo request;
11354 request.method = "GET";
bncb26024382016-06-29 02:39:4511355 request.url = GURL("https://www.example.org/");
[email protected]2ff8b312010-04-26 22:20:5411356
11357 MockRead data_reads[] = {
bncc958faa2015-07-31 18:14:5211358 MockRead("HTTP/1.1 200 OK\r\n"),
bnc2df4b522016-07-08 18:17:4311359 MockRead(kAlternativeServiceHttpHeader),
bncc958faa2015-07-31 18:14:5211360 MockRead("\r\n"),
11361 MockRead("hello world"),
11362 MockRead(ASYNC, OK),
[email protected]2ff8b312010-04-26 22:20:5411363 };
11364
11365 StaticSocketDataProvider first_transaction(
11366 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0711367 session_deps_.socket_factory->AddSocketDataProvider(&first_transaction);
bncb26024382016-06-29 02:39:4511368 SSLSocketDataProvider ssl_http11(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3611369 ssl_http11.next_proto = kProtoHTTP11;
bncb26024382016-06-29 02:39:4511370 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_http11);
[email protected]2ff8b312010-04-26 22:20:5411371
bnc032658ba2016-09-26 18:17:1511372 AddSSLSocketData();
[email protected]2ff8b312010-04-26 22:20:5411373
bncdf80d44fd2016-07-15 20:27:4111374 SpdySerializedFrame req(
bncb26024382016-06-29 02:39:4511375 spdy_util_.ConstructSpdyGet("https://www.example.org/", 1, LOWEST));
bncdf80d44fd2016-07-15 20:27:4111376 MockWrite spdy_writes[] = {CreateMockWrite(req, 0)};
[email protected]2ff8b312010-04-26 22:20:5411377
bnc42331402016-07-25 13:36:1511378 SpdySerializedFrame resp(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
bncdf80d44fd2016-07-15 20:27:4111379 SpdySerializedFrame data(spdy_util_.ConstructSpdyDataFrame(1, true));
[email protected]2ff8b312010-04-26 22:20:5411380 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:4111381 CreateMockRead(resp, 1), CreateMockRead(data, 2), MockRead(ASYNC, 0, 3),
[email protected]2ff8b312010-04-26 22:20:5411382 };
11383
rch8e6c6c42015-05-01 14:05:1311384 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
11385 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:0711386 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]2ff8b312010-04-26 22:20:5411387
[email protected]83039bb2011-12-09 18:43:5511388 TestCompletionCallback callback;
[email protected]2ff8b312010-04-26 22:20:5411389
danakj1fd259a02016-04-16 03:17:0911390 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]2ff8b312010-04-26 22:20:5411391
bnc691fda62016-08-12 00:43:1611392 std::unique_ptr<HttpNetworkTransaction> trans(
[email protected]90499482013-06-01 00:39:5011393 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]2ff8b312010-04-26 22:20:5411394
tfarina42834112016-09-22 13:38:2011395 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0111396 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
11397 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]2ff8b312010-04-26 22:20:5411398
11399 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5211400 ASSERT_TRUE(response);
11401 ASSERT_TRUE(response->headers);
[email protected]2ff8b312010-04-26 22:20:5411402 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
11403
11404 std::string response_data;
robpercival214763f2016-07-01 23:27:0111405 ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
[email protected]2ff8b312010-04-26 22:20:5411406 EXPECT_EQ("hello world", response_data);
11407
11408 // Set up an initial SpdySession in the pool to reuse.
bnc8bef8da22016-05-30 01:28:2511409 HostPortPair host_port_pair("www.example.org", 443);
[email protected]e6d017652013-05-17 18:01:4011410 SpdySessionKey key(host_port_pair, ProxyServer::Direct(),
[email protected]314b03992014-04-01 01:28:5311411 PRIVACY_MODE_DISABLED);
[email protected]795cbf82013-07-22 09:37:2711412 base::WeakPtr<SpdySession> spdy_session =
tfarina42834112016-09-22 13:38:2011413 CreateSecureSpdySession(session.get(), key, NetLogWithSource());
[email protected]02b0c342010-09-25 21:09:3811414
[email protected]90499482013-06-01 00:39:5011415 trans.reset(new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]2ff8b312010-04-26 22:20:5411416
tfarina42834112016-09-22 13:38:2011417 rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0111418 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
11419 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]2ff8b312010-04-26 22:20:5411420
11421 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5211422 ASSERT_TRUE(response);
11423 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0211424 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]65041fa2010-05-21 06:56:5311425 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5211426 EXPECT_TRUE(response->was_alpn_negotiated);
[email protected]2ff8b312010-04-26 22:20:5411427
robpercival214763f2016-07-01 23:27:0111428 ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
[email protected]2ff8b312010-04-26 22:20:5411429 EXPECT_EQ("hello!", response_data);
[email protected]564b4912010-03-09 16:30:4211430}
11431
[email protected]044de0642010-06-17 10:42:1511432// GenerateAuthToken is a mighty big test.
11433// It tests all permutation of GenerateAuthToken behavior:
11434// - Synchronous and Asynchronous completion.
11435// - OK or error on completion.
11436// - Direct connection, non-authenticating proxy, and authenticating proxy.
11437// - HTTP or HTTPS backend (to include proxy tunneling).
11438// - Non-authenticating and authenticating backend.
11439//
[email protected]fe3b7dc2012-02-03 19:52:0911440// In all, there are 44 reasonable permuations (for example, if there are
[email protected]044de0642010-06-17 10:42:1511441// problems generating an auth token for an authenticating proxy, we don't
11442// need to test all permutations of the backend server).
11443//
11444// The test proceeds by going over each of the configuration cases, and
11445// potentially running up to three rounds in each of the tests. The TestConfig
11446// specifies both the configuration for the test as well as the expectations
11447// for the results.
bncd16676a2016-07-20 16:23:0111448TEST_F(HttpNetworkTransactionTest, GenerateAuthToken) {
[email protected]0b0bf032010-09-21 18:08:5011449 static const char kServer[] = "http://www.example.com";
11450 static const char kSecureServer[] = "https://www.example.com";
11451 static const char kProxy[] = "myproxy:70";
[email protected]044de0642010-06-17 10:42:1511452
11453 enum AuthTiming {
11454 AUTH_NONE,
11455 AUTH_SYNC,
11456 AUTH_ASYNC,
11457 };
11458
11459 const MockWrite kGet(
11460 "GET / HTTP/1.1\r\n"
11461 "Host: www.example.com\r\n"
11462 "Connection: keep-alive\r\n\r\n");
11463 const MockWrite kGetProxy(
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\r\n");
11467 const MockWrite kGetAuth(
11468 "GET / HTTP/1.1\r\n"
11469 "Host: www.example.com\r\n"
11470 "Connection: keep-alive\r\n"
11471 "Authorization: auth_token\r\n\r\n");
11472 const MockWrite kGetProxyAuth(
11473 "GET http://www.example.com/ HTTP/1.1\r\n"
11474 "Host: www.example.com\r\n"
11475 "Proxy-Connection: keep-alive\r\n"
11476 "Proxy-Authorization: auth_token\r\n\r\n");
11477 const MockWrite kGetAuthThroughProxy(
11478 "GET http://www.example.com/ HTTP/1.1\r\n"
11479 "Host: www.example.com\r\n"
11480 "Proxy-Connection: keep-alive\r\n"
11481 "Authorization: auth_token\r\n\r\n");
11482 const MockWrite kGetAuthWithProxyAuth(
11483 "GET http://www.example.com/ HTTP/1.1\r\n"
11484 "Host: www.example.com\r\n"
11485 "Proxy-Connection: keep-alive\r\n"
11486 "Proxy-Authorization: auth_token\r\n"
11487 "Authorization: auth_token\r\n\r\n");
11488 const MockWrite kConnect(
11489 "CONNECT www.example.com:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:1711490 "Host: www.example.com:443\r\n"
[email protected]044de0642010-06-17 10:42:1511491 "Proxy-Connection: keep-alive\r\n\r\n");
11492 const MockWrite kConnectProxyAuth(
11493 "CONNECT www.example.com:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:1711494 "Host: www.example.com:443\r\n"
[email protected]044de0642010-06-17 10:42:1511495 "Proxy-Connection: keep-alive\r\n"
11496 "Proxy-Authorization: auth_token\r\n\r\n");
11497
11498 const MockRead kSuccess(
11499 "HTTP/1.1 200 OK\r\n"
11500 "Content-Type: text/html; charset=iso-8859-1\r\n"
11501 "Content-Length: 3\r\n\r\n"
11502 "Yes");
11503 const MockRead kFailure(
11504 "Should not be called.");
11505 const MockRead kServerChallenge(
11506 "HTTP/1.1 401 Unauthorized\r\n"
11507 "WWW-Authenticate: Mock realm=server\r\n"
11508 "Content-Type: text/html; charset=iso-8859-1\r\n"
11509 "Content-Length: 14\r\n\r\n"
11510 "Unauthorized\r\n");
11511 const MockRead kProxyChallenge(
11512 "HTTP/1.1 407 Unauthorized\r\n"
11513 "Proxy-Authenticate: Mock realm=proxy\r\n"
11514 "Proxy-Connection: close\r\n"
11515 "Content-Type: text/html; charset=iso-8859-1\r\n"
11516 "Content-Length: 14\r\n\r\n"
11517 "Unauthorized\r\n");
11518 const MockRead kProxyConnected(
11519 "HTTP/1.1 200 Connection Established\r\n\r\n");
11520
11521 // NOTE(cbentzel): I wanted TestReadWriteRound to be a simple struct with
11522 // no constructors, but the C++ compiler on Windows warns about
11523 // unspecified data in compound literals. So, moved to using constructors,
11524 // and TestRound's created with the default constructor should not be used.
11525 struct TestRound {
11526 TestRound()
11527 : expected_rv(ERR_UNEXPECTED),
11528 extra_write(NULL),
11529 extra_read(NULL) {
11530 }
11531 TestRound(const MockWrite& write_arg, const MockRead& read_arg,
11532 int expected_rv_arg)
11533 : write(write_arg),
11534 read(read_arg),
11535 expected_rv(expected_rv_arg),
11536 extra_write(NULL),
11537 extra_read(NULL) {
11538 }
11539 TestRound(const MockWrite& write_arg, const MockRead& read_arg,
11540 int expected_rv_arg, const MockWrite* extra_write_arg,
[email protected]f871ee152012-07-27 19:02:0111541 const MockRead* extra_read_arg)
[email protected]044de0642010-06-17 10:42:1511542 : write(write_arg),
11543 read(read_arg),
11544 expected_rv(expected_rv_arg),
11545 extra_write(extra_write_arg),
11546 extra_read(extra_read_arg) {
11547 }
11548 MockWrite write;
11549 MockRead read;
11550 int expected_rv;
11551 const MockWrite* extra_write;
11552 const MockRead* extra_read;
11553 };
11554
11555 static const int kNoSSL = 500;
11556
11557 struct TestConfig {
asanka463ca4262016-11-16 02:34:3111558 int line_number;
thestig9d3bb0c2015-01-24 00:49:5111559 const char* const proxy_url;
[email protected]044de0642010-06-17 10:42:1511560 AuthTiming proxy_auth_timing;
asanka463ca4262016-11-16 02:34:3111561 int first_generate_proxy_token_rv;
thestig9d3bb0c2015-01-24 00:49:5111562 const char* const server_url;
[email protected]044de0642010-06-17 10:42:1511563 AuthTiming server_auth_timing;
asanka463ca4262016-11-16 02:34:3111564 int first_generate_server_token_rv;
[email protected]044de0642010-06-17 10:42:1511565 int num_auth_rounds;
11566 int first_ssl_round;
asankae2257db2016-10-11 22:03:1611567 TestRound rounds[4];
[email protected]044de0642010-06-17 10:42:1511568 } test_configs[] = {
asankac93076192016-10-03 15:46:0211569 // Non-authenticating HTTP server with a direct connection.
asanka463ca4262016-11-16 02:34:3111570 {__LINE__,
11571 nullptr,
asankac93076192016-10-03 15:46:0211572 AUTH_NONE,
11573 OK,
11574 kServer,
11575 AUTH_NONE,
11576 OK,
11577 1,
11578 kNoSSL,
11579 {TestRound(kGet, kSuccess, OK)}},
11580 // Authenticating HTTP server with a direct connection.
asanka463ca4262016-11-16 02:34:3111581 {__LINE__,
11582 nullptr,
asankac93076192016-10-03 15:46:0211583 AUTH_NONE,
11584 OK,
11585 kServer,
11586 AUTH_SYNC,
11587 OK,
11588 2,
11589 kNoSSL,
11590 {TestRound(kGet, kServerChallenge, OK),
[email protected]044de0642010-06-17 10:42:1511591 TestRound(kGetAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3111592 {__LINE__,
11593 nullptr,
asankac93076192016-10-03 15:46:0211594 AUTH_NONE,
11595 OK,
11596 kServer,
11597 AUTH_SYNC,
11598 ERR_INVALID_AUTH_CREDENTIALS,
asankae2257db2016-10-11 22:03:1611599 3,
11600 kNoSSL,
11601 {TestRound(kGet, kServerChallenge, OK),
11602 TestRound(kGet, kServerChallenge, OK),
11603 TestRound(kGetAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3111604 {__LINE__,
11605 nullptr,
asankae2257db2016-10-11 22:03:1611606 AUTH_NONE,
11607 OK,
11608 kServer,
11609 AUTH_SYNC,
11610 ERR_UNSUPPORTED_AUTH_SCHEME,
11611 2,
11612 kNoSSL,
11613 {TestRound(kGet, kServerChallenge, OK), TestRound(kGet, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3111614 {__LINE__,
11615 nullptr,
asankae2257db2016-10-11 22:03:1611616 AUTH_NONE,
11617 OK,
11618 kServer,
11619 AUTH_SYNC,
11620 ERR_UNDOCUMENTED_SECURITY_LIBRARY_STATUS,
11621 2,
11622 kNoSSL,
11623 {TestRound(kGet, kServerChallenge, OK), TestRound(kGet, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3111624 {__LINE__,
11625 kProxy,
asankae2257db2016-10-11 22:03:1611626 AUTH_SYNC,
11627 ERR_FAILED,
11628 kServer,
11629 AUTH_NONE,
11630 OK,
11631 2,
11632 kNoSSL,
11633 {TestRound(kGetProxy, kProxyChallenge, OK),
11634 TestRound(kGetProxy, kFailure, ERR_FAILED)}},
asanka463ca4262016-11-16 02:34:3111635 {__LINE__,
11636 kProxy,
asankae2257db2016-10-11 22:03:1611637 AUTH_ASYNC,
11638 ERR_FAILED,
11639 kServer,
11640 AUTH_NONE,
11641 OK,
11642 2,
11643 kNoSSL,
11644 {TestRound(kGetProxy, kProxyChallenge, OK),
11645 TestRound(kGetProxy, kFailure, ERR_FAILED)}},
asanka463ca4262016-11-16 02:34:3111646 {__LINE__,
11647 nullptr,
asankae2257db2016-10-11 22:03:1611648 AUTH_NONE,
11649 OK,
11650 kServer,
11651 AUTH_SYNC,
11652 ERR_FAILED,
asankac93076192016-10-03 15:46:0211653 2,
11654 kNoSSL,
11655 {TestRound(kGet, kServerChallenge, OK),
asankae2257db2016-10-11 22:03:1611656 TestRound(kGet, kFailure, ERR_FAILED)}},
asanka463ca4262016-11-16 02:34:3111657 {__LINE__,
11658 nullptr,
asankae2257db2016-10-11 22:03:1611659 AUTH_NONE,
11660 OK,
11661 kServer,
11662 AUTH_ASYNC,
11663 ERR_FAILED,
11664 2,
11665 kNoSSL,
11666 {TestRound(kGet, kServerChallenge, OK),
11667 TestRound(kGet, kFailure, ERR_FAILED)}},
asanka463ca4262016-11-16 02:34:3111668 {__LINE__,
11669 nullptr,
asankac93076192016-10-03 15:46:0211670 AUTH_NONE,
11671 OK,
11672 kServer,
11673 AUTH_ASYNC,
11674 OK,
11675 2,
11676 kNoSSL,
11677 {TestRound(kGet, kServerChallenge, OK),
[email protected]044de0642010-06-17 10:42:1511678 TestRound(kGetAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3111679 {__LINE__,
11680 nullptr,
asankac93076192016-10-03 15:46:0211681 AUTH_NONE,
11682 OK,
11683 kServer,
11684 AUTH_ASYNC,
11685 ERR_INVALID_AUTH_CREDENTIALS,
asankae2257db2016-10-11 22:03:1611686 3,
asankac93076192016-10-03 15:46:0211687 kNoSSL,
11688 {TestRound(kGet, kServerChallenge, OK),
asankae2257db2016-10-11 22:03:1611689 // The second round uses a HttpAuthHandlerMock that always succeeds.
11690 TestRound(kGet, kServerChallenge, OK),
11691 TestRound(kGetAuth, kSuccess, OK)}},
asankac93076192016-10-03 15:46:0211692 // Non-authenticating HTTP server through a non-authenticating proxy.
asanka463ca4262016-11-16 02:34:3111693 {__LINE__,
11694 kProxy,
asankac93076192016-10-03 15:46:0211695 AUTH_NONE,
11696 OK,
11697 kServer,
11698 AUTH_NONE,
11699 OK,
11700 1,
11701 kNoSSL,
11702 {TestRound(kGetProxy, kSuccess, OK)}},
11703 // Authenticating HTTP server through a non-authenticating proxy.
asanka463ca4262016-11-16 02:34:3111704 {__LINE__,
11705 kProxy,
asankac93076192016-10-03 15:46:0211706 AUTH_NONE,
11707 OK,
11708 kServer,
11709 AUTH_SYNC,
11710 OK,
11711 2,
11712 kNoSSL,
11713 {TestRound(kGetProxy, kServerChallenge, OK),
[email protected]044de0642010-06-17 10:42:1511714 TestRound(kGetAuthThroughProxy, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3111715 {__LINE__,
11716 kProxy,
asankac93076192016-10-03 15:46:0211717 AUTH_NONE,
11718 OK,
11719 kServer,
11720 AUTH_SYNC,
11721 ERR_INVALID_AUTH_CREDENTIALS,
asankae2257db2016-10-11 22:03:1611722 3,
asankac93076192016-10-03 15:46:0211723 kNoSSL,
11724 {TestRound(kGetProxy, kServerChallenge, OK),
asankae2257db2016-10-11 22:03:1611725 TestRound(kGetProxy, kServerChallenge, OK),
11726 TestRound(kGetAuthThroughProxy, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3111727 {__LINE__,
11728 kProxy,
asankac93076192016-10-03 15:46:0211729 AUTH_NONE,
11730 OK,
11731 kServer,
11732 AUTH_ASYNC,
11733 OK,
11734 2,
11735 kNoSSL,
11736 {TestRound(kGetProxy, kServerChallenge, OK),
[email protected]044de0642010-06-17 10:42:1511737 TestRound(kGetAuthThroughProxy, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3111738 {__LINE__,
11739 kProxy,
asankac93076192016-10-03 15:46:0211740 AUTH_NONE,
11741 OK,
11742 kServer,
11743 AUTH_ASYNC,
11744 ERR_INVALID_AUTH_CREDENTIALS,
11745 2,
11746 kNoSSL,
11747 {TestRound(kGetProxy, kServerChallenge, OK),
asankae2257db2016-10-11 22:03:1611748 TestRound(kGetProxy, kSuccess, OK)}},
asankac93076192016-10-03 15:46:0211749 // Non-authenticating HTTP server through an authenticating proxy.
asanka463ca4262016-11-16 02:34:3111750 {__LINE__,
11751 kProxy,
asankac93076192016-10-03 15:46:0211752 AUTH_SYNC,
11753 OK,
11754 kServer,
11755 AUTH_NONE,
11756 OK,
11757 2,
11758 kNoSSL,
11759 {TestRound(kGetProxy, kProxyChallenge, OK),
[email protected]044de0642010-06-17 10:42:1511760 TestRound(kGetProxyAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3111761 {__LINE__,
11762 kProxy,
asankac93076192016-10-03 15:46:0211763 AUTH_SYNC,
11764 ERR_INVALID_AUTH_CREDENTIALS,
11765 kServer,
11766 AUTH_NONE,
11767 OK,
11768 2,
11769 kNoSSL,
11770 {TestRound(kGetProxy, kProxyChallenge, OK),
asankae2257db2016-10-11 22:03:1611771 TestRound(kGetProxy, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3111772 {__LINE__,
11773 kProxy,
asankac93076192016-10-03 15:46:0211774 AUTH_ASYNC,
11775 OK,
11776 kServer,
11777 AUTH_NONE,
11778 OK,
11779 2,
11780 kNoSSL,
11781 {TestRound(kGetProxy, kProxyChallenge, OK),
[email protected]044de0642010-06-17 10:42:1511782 TestRound(kGetProxyAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3111783 {__LINE__,
11784 kProxy,
asankac93076192016-10-03 15:46:0211785 AUTH_ASYNC,
11786 ERR_INVALID_AUTH_CREDENTIALS,
11787 kServer,
11788 AUTH_NONE,
11789 OK,
11790 2,
11791 kNoSSL,
11792 {TestRound(kGetProxy, kProxyChallenge, OK),
asankae2257db2016-10-11 22:03:1611793 TestRound(kGetProxy, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3111794 {__LINE__,
11795 kProxy,
11796 AUTH_ASYNC,
11797 ERR_INVALID_AUTH_CREDENTIALS,
11798 kServer,
11799 AUTH_NONE,
11800 OK,
11801 3,
11802 kNoSSL,
11803 {TestRound(kGetProxy, kProxyChallenge, OK),
11804 TestRound(kGetProxy, kProxyChallenge, OK),
11805 TestRound(kGetProxyAuth, kSuccess, OK)}},
asankac93076192016-10-03 15:46:0211806 // Authenticating HTTP server through an authenticating proxy.
asanka463ca4262016-11-16 02:34:3111807 {__LINE__,
11808 kProxy,
asankac93076192016-10-03 15:46:0211809 AUTH_SYNC,
11810 OK,
11811 kServer,
11812 AUTH_SYNC,
11813 OK,
11814 3,
11815 kNoSSL,
11816 {TestRound(kGetProxy, kProxyChallenge, OK),
[email protected]044de0642010-06-17 10:42:1511817 TestRound(kGetProxyAuth, kServerChallenge, OK),
11818 TestRound(kGetAuthWithProxyAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3111819 {__LINE__,
11820 kProxy,
asankac93076192016-10-03 15:46:0211821 AUTH_SYNC,
11822 OK,
11823 kServer,
11824 AUTH_SYNC,
11825 ERR_INVALID_AUTH_CREDENTIALS,
11826 3,
11827 kNoSSL,
11828 {TestRound(kGetProxy, kProxyChallenge, OK),
[email protected]044de0642010-06-17 10:42:1511829 TestRound(kGetProxyAuth, kServerChallenge, OK),
asankae2257db2016-10-11 22:03:1611830 TestRound(kGetProxyAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3111831 {__LINE__,
11832 kProxy,
asankac93076192016-10-03 15:46:0211833 AUTH_ASYNC,
11834 OK,
11835 kServer,
11836 AUTH_SYNC,
11837 OK,
11838 3,
11839 kNoSSL,
11840 {TestRound(kGetProxy, kProxyChallenge, OK),
[email protected]044de0642010-06-17 10:42:1511841 TestRound(kGetProxyAuth, kServerChallenge, OK),
11842 TestRound(kGetAuthWithProxyAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3111843 {__LINE__,
11844 kProxy,
asankac93076192016-10-03 15:46:0211845 AUTH_ASYNC,
11846 OK,
11847 kServer,
11848 AUTH_SYNC,
11849 ERR_INVALID_AUTH_CREDENTIALS,
11850 3,
11851 kNoSSL,
11852 {TestRound(kGetProxy, kProxyChallenge, OK),
[email protected]044de0642010-06-17 10:42:1511853 TestRound(kGetProxyAuth, kServerChallenge, OK),
asankae2257db2016-10-11 22:03:1611854 TestRound(kGetProxyAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3111855 {__LINE__,
11856 kProxy,
asankac93076192016-10-03 15:46:0211857 AUTH_SYNC,
11858 OK,
11859 kServer,
11860 AUTH_ASYNC,
11861 OK,
11862 3,
11863 kNoSSL,
11864 {TestRound(kGetProxy, kProxyChallenge, OK),
[email protected]044de0642010-06-17 10:42:1511865 TestRound(kGetProxyAuth, kServerChallenge, OK),
11866 TestRound(kGetAuthWithProxyAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3111867 {__LINE__,
11868 kProxy,
11869 AUTH_SYNC,
11870 ERR_INVALID_AUTH_CREDENTIALS,
11871 kServer,
11872 AUTH_ASYNC,
11873 OK,
11874 4,
11875 kNoSSL,
11876 {TestRound(kGetProxy, kProxyChallenge, OK),
11877 TestRound(kGetProxy, kProxyChallenge, OK),
11878 TestRound(kGetProxyAuth, kServerChallenge, OK),
11879 TestRound(kGetAuthWithProxyAuth, kSuccess, OK)}},
11880 {__LINE__,
11881 kProxy,
asankac93076192016-10-03 15:46:0211882 AUTH_SYNC,
11883 OK,
11884 kServer,
11885 AUTH_ASYNC,
11886 ERR_INVALID_AUTH_CREDENTIALS,
11887 3,
11888 kNoSSL,
11889 {TestRound(kGetProxy, kProxyChallenge, OK),
[email protected]044de0642010-06-17 10:42:1511890 TestRound(kGetProxyAuth, kServerChallenge, OK),
asankae2257db2016-10-11 22:03:1611891 TestRound(kGetProxyAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3111892 {__LINE__,
11893 kProxy,
asankac93076192016-10-03 15:46:0211894 AUTH_ASYNC,
11895 OK,
11896 kServer,
11897 AUTH_ASYNC,
11898 OK,
11899 3,
11900 kNoSSL,
11901 {TestRound(kGetProxy, kProxyChallenge, OK),
[email protected]044de0642010-06-17 10:42:1511902 TestRound(kGetProxyAuth, kServerChallenge, OK),
11903 TestRound(kGetAuthWithProxyAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3111904 {__LINE__,
11905 kProxy,
asankac93076192016-10-03 15:46:0211906 AUTH_ASYNC,
11907 OK,
11908 kServer,
11909 AUTH_ASYNC,
11910 ERR_INVALID_AUTH_CREDENTIALS,
11911 3,
11912 kNoSSL,
11913 {TestRound(kGetProxy, kProxyChallenge, OK),
[email protected]044de0642010-06-17 10:42:1511914 TestRound(kGetProxyAuth, kServerChallenge, OK),
asankae2257db2016-10-11 22:03:1611915 TestRound(kGetProxyAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3111916 {__LINE__,
11917 kProxy,
11918 AUTH_ASYNC,
11919 ERR_INVALID_AUTH_CREDENTIALS,
11920 kServer,
11921 AUTH_ASYNC,
11922 ERR_INVALID_AUTH_CREDENTIALS,
11923 4,
11924 kNoSSL,
11925 {TestRound(kGetProxy, kProxyChallenge, OK),
11926 TestRound(kGetProxy, kProxyChallenge, OK),
11927 TestRound(kGetProxyAuth, kServerChallenge, OK),
11928 TestRound(kGetProxyAuth, kSuccess, OK)}},
asankac93076192016-10-03 15:46:0211929 // Non-authenticating HTTPS server with a direct connection.
asanka463ca4262016-11-16 02:34:3111930 {__LINE__,
11931 nullptr,
asankac93076192016-10-03 15:46:0211932 AUTH_NONE,
11933 OK,
11934 kSecureServer,
11935 AUTH_NONE,
11936 OK,
11937 1,
11938 0,
11939 {TestRound(kGet, kSuccess, OK)}},
11940 // Authenticating HTTPS server with a direct connection.
asanka463ca4262016-11-16 02:34:3111941 {__LINE__,
11942 nullptr,
asankac93076192016-10-03 15:46:0211943 AUTH_NONE,
11944 OK,
11945 kSecureServer,
11946 AUTH_SYNC,
11947 OK,
11948 2,
11949 0,
11950 {TestRound(kGet, kServerChallenge, OK),
[email protected]044de0642010-06-17 10:42:1511951 TestRound(kGetAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3111952 {__LINE__,
11953 nullptr,
asankac93076192016-10-03 15:46:0211954 AUTH_NONE,
11955 OK,
11956 kSecureServer,
11957 AUTH_SYNC,
11958 ERR_INVALID_AUTH_CREDENTIALS,
11959 2,
11960 0,
asankae2257db2016-10-11 22:03:1611961 {TestRound(kGet, kServerChallenge, OK), TestRound(kGet, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3111962 {__LINE__,
11963 nullptr,
asankac93076192016-10-03 15:46:0211964 AUTH_NONE,
11965 OK,
11966 kSecureServer,
11967 AUTH_ASYNC,
11968 OK,
11969 2,
11970 0,
11971 {TestRound(kGet, kServerChallenge, OK),
[email protected]044de0642010-06-17 10:42:1511972 TestRound(kGetAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3111973 {__LINE__,
11974 nullptr,
asankac93076192016-10-03 15:46:0211975 AUTH_NONE,
11976 OK,
11977 kSecureServer,
11978 AUTH_ASYNC,
11979 ERR_INVALID_AUTH_CREDENTIALS,
11980 2,
11981 0,
asankae2257db2016-10-11 22:03:1611982 {TestRound(kGet, kServerChallenge, OK), TestRound(kGet, kSuccess, OK)}},
asankac93076192016-10-03 15:46:0211983 // Non-authenticating HTTPS server with a non-authenticating proxy.
asanka463ca4262016-11-16 02:34:3111984 {__LINE__,
11985 kProxy,
asankac93076192016-10-03 15:46:0211986 AUTH_NONE,
11987 OK,
11988 kSecureServer,
11989 AUTH_NONE,
11990 OK,
11991 1,
11992 0,
11993 {TestRound(kConnect, kProxyConnected, OK, &kGet, &kSuccess)}},
11994 // Authenticating HTTPS server through a non-authenticating proxy.
asanka463ca4262016-11-16 02:34:3111995 {__LINE__,
11996 kProxy,
asankac93076192016-10-03 15:46:0211997 AUTH_NONE,
11998 OK,
11999 kSecureServer,
12000 AUTH_SYNC,
12001 OK,
12002 2,
12003 0,
12004 {TestRound(kConnect, kProxyConnected, OK, &kGet, &kServerChallenge),
[email protected]044de0642010-06-17 10:42:1512005 TestRound(kGetAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112006 {__LINE__,
12007 kProxy,
asankac93076192016-10-03 15:46:0212008 AUTH_NONE,
12009 OK,
12010 kSecureServer,
12011 AUTH_SYNC,
12012 ERR_INVALID_AUTH_CREDENTIALS,
12013 2,
12014 0,
12015 {TestRound(kConnect, kProxyConnected, OK, &kGet, &kServerChallenge),
asankae2257db2016-10-11 22:03:1612016 TestRound(kGet, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112017 {__LINE__,
12018 kProxy,
asankac93076192016-10-03 15:46:0212019 AUTH_NONE,
12020 OK,
12021 kSecureServer,
12022 AUTH_ASYNC,
12023 OK,
12024 2,
12025 0,
12026 {TestRound(kConnect, kProxyConnected, OK, &kGet, &kServerChallenge),
[email protected]044de0642010-06-17 10:42:1512027 TestRound(kGetAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112028 {__LINE__,
12029 kProxy,
asankac93076192016-10-03 15:46:0212030 AUTH_NONE,
12031 OK,
12032 kSecureServer,
12033 AUTH_ASYNC,
12034 ERR_INVALID_AUTH_CREDENTIALS,
12035 2,
12036 0,
12037 {TestRound(kConnect, kProxyConnected, OK, &kGet, &kServerChallenge),
asankae2257db2016-10-11 22:03:1612038 TestRound(kGet, kSuccess, OK)}},
asankac93076192016-10-03 15:46:0212039 // Non-Authenticating HTTPS server through an authenticating proxy.
asanka463ca4262016-11-16 02:34:3112040 {__LINE__,
12041 kProxy,
asankac93076192016-10-03 15:46:0212042 AUTH_SYNC,
12043 OK,
12044 kSecureServer,
12045 AUTH_NONE,
12046 OK,
12047 2,
12048 1,
12049 {TestRound(kConnect, kProxyChallenge, OK),
[email protected]044de0642010-06-17 10:42:1512050 TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet, &kSuccess)}},
asanka463ca4262016-11-16 02:34:3112051 {__LINE__,
12052 kProxy,
asankac93076192016-10-03 15:46:0212053 AUTH_SYNC,
12054 ERR_INVALID_AUTH_CREDENTIALS,
12055 kSecureServer,
12056 AUTH_NONE,
12057 OK,
12058 2,
12059 kNoSSL,
12060 {TestRound(kConnect, kProxyChallenge, OK),
asankae2257db2016-10-11 22:03:1612061 TestRound(kConnect, kProxyConnected, OK, &kGet, &kSuccess)}},
asanka463ca4262016-11-16 02:34:3112062 {__LINE__,
12063 kProxy,
asankae2257db2016-10-11 22:03:1612064 AUTH_SYNC,
12065 ERR_UNSUPPORTED_AUTH_SCHEME,
12066 kSecureServer,
12067 AUTH_NONE,
12068 OK,
12069 2,
12070 kNoSSL,
12071 {TestRound(kConnect, kProxyChallenge, OK),
12072 TestRound(kConnect, kProxyConnected, OK, &kGet, &kSuccess)}},
asanka463ca4262016-11-16 02:34:3112073 {__LINE__,
12074 kProxy,
asankae2257db2016-10-11 22:03:1612075 AUTH_SYNC,
12076 ERR_UNEXPECTED,
12077 kSecureServer,
12078 AUTH_NONE,
12079 OK,
12080 2,
12081 kNoSSL,
12082 {TestRound(kConnect, kProxyChallenge, OK),
12083 TestRound(kConnect, kProxyConnected, ERR_UNEXPECTED)}},
asanka463ca4262016-11-16 02:34:3112084 {__LINE__,
12085 kProxy,
asankac93076192016-10-03 15:46:0212086 AUTH_ASYNC,
12087 OK,
12088 kSecureServer,
12089 AUTH_NONE,
12090 OK,
12091 2,
12092 1,
12093 {TestRound(kConnect, kProxyChallenge, OK),
[email protected]044de0642010-06-17 10:42:1512094 TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet, &kSuccess)}},
asanka463ca4262016-11-16 02:34:3112095 {__LINE__,
12096 kProxy,
asankac93076192016-10-03 15:46:0212097 AUTH_ASYNC,
12098 ERR_INVALID_AUTH_CREDENTIALS,
12099 kSecureServer,
12100 AUTH_NONE,
12101 OK,
12102 2,
12103 kNoSSL,
12104 {TestRound(kConnect, kProxyChallenge, OK),
asankae2257db2016-10-11 22:03:1612105 TestRound(kConnect, kProxyConnected, OK, &kGet, &kSuccess)}},
asankac93076192016-10-03 15:46:0212106 // Authenticating HTTPS server through an authenticating proxy.
asanka463ca4262016-11-16 02:34:3112107 {__LINE__,
12108 kProxy,
asankac93076192016-10-03 15:46:0212109 AUTH_SYNC,
12110 OK,
12111 kSecureServer,
12112 AUTH_SYNC,
12113 OK,
12114 3,
12115 1,
12116 {TestRound(kConnect, kProxyChallenge, OK),
12117 TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet,
12118 &kServerChallenge),
[email protected]044de0642010-06-17 10:42:1512119 TestRound(kGetAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112120 {__LINE__,
12121 kProxy,
asankac93076192016-10-03 15:46:0212122 AUTH_SYNC,
12123 OK,
12124 kSecureServer,
12125 AUTH_SYNC,
12126 ERR_INVALID_AUTH_CREDENTIALS,
12127 3,
12128 1,
12129 {TestRound(kConnect, kProxyChallenge, OK),
12130 TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet,
12131 &kServerChallenge),
asankae2257db2016-10-11 22:03:1612132 TestRound(kGet, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112133 {__LINE__,
12134 kProxy,
asankac93076192016-10-03 15:46:0212135 AUTH_ASYNC,
12136 OK,
12137 kSecureServer,
12138 AUTH_SYNC,
12139 OK,
12140 3,
12141 1,
12142 {TestRound(kConnect, kProxyChallenge, OK),
12143 TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet,
12144 &kServerChallenge),
[email protected]044de0642010-06-17 10:42:1512145 TestRound(kGetAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112146 {__LINE__,
12147 kProxy,
asankac93076192016-10-03 15:46:0212148 AUTH_ASYNC,
12149 OK,
12150 kSecureServer,
12151 AUTH_SYNC,
12152 ERR_INVALID_AUTH_CREDENTIALS,
12153 3,
12154 1,
12155 {TestRound(kConnect, kProxyChallenge, OK),
12156 TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet,
12157 &kServerChallenge),
asankae2257db2016-10-11 22:03:1612158 TestRound(kGet, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112159 {__LINE__,
12160 kProxy,
asankac93076192016-10-03 15:46:0212161 AUTH_SYNC,
12162 OK,
12163 kSecureServer,
12164 AUTH_ASYNC,
12165 OK,
12166 3,
12167 1,
12168 {TestRound(kConnect, kProxyChallenge, OK),
12169 TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet,
12170 &kServerChallenge),
[email protected]044de0642010-06-17 10:42:1512171 TestRound(kGetAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112172 {__LINE__,
12173 kProxy,
asankac93076192016-10-03 15:46:0212174 AUTH_SYNC,
12175 OK,
12176 kSecureServer,
12177 AUTH_ASYNC,
12178 ERR_INVALID_AUTH_CREDENTIALS,
12179 3,
12180 1,
12181 {TestRound(kConnect, kProxyChallenge, OK),
12182 TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet,
12183 &kServerChallenge),
asankae2257db2016-10-11 22:03:1612184 TestRound(kGet, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112185 {__LINE__,
12186 kProxy,
asankac93076192016-10-03 15:46:0212187 AUTH_ASYNC,
12188 OK,
12189 kSecureServer,
12190 AUTH_ASYNC,
12191 OK,
12192 3,
12193 1,
12194 {TestRound(kConnect, kProxyChallenge, OK),
12195 TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet,
12196 &kServerChallenge),
[email protected]044de0642010-06-17 10:42:1512197 TestRound(kGetAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112198 {__LINE__,
12199 kProxy,
asankac93076192016-10-03 15:46:0212200 AUTH_ASYNC,
12201 OK,
12202 kSecureServer,
12203 AUTH_ASYNC,
12204 ERR_INVALID_AUTH_CREDENTIALS,
12205 3,
12206 1,
12207 {TestRound(kConnect, kProxyChallenge, OK),
12208 TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet,
12209 &kServerChallenge),
asankae2257db2016-10-11 22:03:1612210 TestRound(kGet, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112211 {__LINE__,
12212 kProxy,
12213 AUTH_ASYNC,
12214 ERR_INVALID_AUTH_CREDENTIALS,
12215 kSecureServer,
12216 AUTH_ASYNC,
12217 ERR_INVALID_AUTH_CREDENTIALS,
12218 4,
12219 2,
12220 {TestRound(kConnect, kProxyChallenge, OK),
12221 TestRound(kConnect, kProxyChallenge, OK),
12222 TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet,
12223 &kServerChallenge),
12224 TestRound(kGet, kSuccess, OK)}},
[email protected]044de0642010-06-17 10:42:1512225 };
12226
asanka463ca4262016-11-16 02:34:3112227 for (const auto& test_config : test_configs) {
12228 SCOPED_TRACE(::testing::Message() << "Test config at "
12229 << test_config.line_number);
[email protected]2d01c262011-08-11 23:07:0812230 HttpAuthHandlerMock::Factory* auth_factory(
12231 new HttpAuthHandlerMock::Factory());
[email protected]bb88e1d32013-05-03 23:11:0712232 session_deps_.http_auth_handler_factory.reset(auth_factory);
asanka5ffd5d72016-03-23 16:20:4912233 SSLInfo empty_ssl_info;
[email protected]65d34382010-07-01 18:12:2612234
12235 // Set up authentication handlers as necessary.
[email protected]044de0642010-06-17 10:42:1512236 if (test_config.proxy_auth_timing != AUTH_NONE) {
asanka463ca4262016-11-16 02:34:3112237 for (int n = 0; n < 3; n++) {
[email protected]2d01c262011-08-11 23:07:0812238 HttpAuthHandlerMock* auth_handler(new HttpAuthHandlerMock());
12239 std::string auth_challenge = "Mock realm=proxy";
12240 GURL origin(test_config.proxy_url);
[email protected]df41d0d82014-03-13 00:43:2412241 HttpAuthChallengeTokenizer tokenizer(auth_challenge.begin(),
12242 auth_challenge.end());
[email protected]2d01c262011-08-11 23:07:0812243 auth_handler->InitFromChallenge(&tokenizer, HttpAuth::AUTH_PROXY,
tfarina42834112016-09-22 13:38:2012244 empty_ssl_info, origin,
12245 NetLogWithSource());
[email protected]2d01c262011-08-11 23:07:0812246 auth_handler->SetGenerateExpectation(
12247 test_config.proxy_auth_timing == AUTH_ASYNC,
asanka463ca4262016-11-16 02:34:3112248 n == 0 ? test_config.first_generate_proxy_token_rv : OK);
[email protected]2d01c262011-08-11 23:07:0812249 auth_factory->AddMockHandler(auth_handler, HttpAuth::AUTH_PROXY);
12250 }
[email protected]044de0642010-06-17 10:42:1512251 }
12252 if (test_config.server_auth_timing != AUTH_NONE) {
[email protected]3fd9dae2010-06-21 11:39:0012253 HttpAuthHandlerMock* auth_handler(new HttpAuthHandlerMock());
[email protected]044de0642010-06-17 10:42:1512254 std::string auth_challenge = "Mock realm=server";
12255 GURL origin(test_config.server_url);
[email protected]df41d0d82014-03-13 00:43:2412256 HttpAuthChallengeTokenizer tokenizer(auth_challenge.begin(),
12257 auth_challenge.end());
[email protected]044de0642010-06-17 10:42:1512258 auth_handler->InitFromChallenge(&tokenizer, HttpAuth::AUTH_SERVER,
tfarina42834112016-09-22 13:38:2012259 empty_ssl_info, origin,
12260 NetLogWithSource());
[email protected]044de0642010-06-17 10:42:1512261 auth_handler->SetGenerateExpectation(
12262 test_config.server_auth_timing == AUTH_ASYNC,
asanka463ca4262016-11-16 02:34:3112263 test_config.first_generate_server_token_rv);
[email protected]2d01c262011-08-11 23:07:0812264 auth_factory->AddMockHandler(auth_handler, HttpAuth::AUTH_SERVER);
asankae2257db2016-10-11 22:03:1612265
12266 // The second handler always succeeds. It should only be used where there
12267 // are multiple auth sessions for server auth in the same network
12268 // transaction using the same auth scheme.
12269 std::unique_ptr<HttpAuthHandlerMock> second_handler =
12270 base::MakeUnique<HttpAuthHandlerMock>();
12271 second_handler->InitFromChallenge(&tokenizer, HttpAuth::AUTH_SERVER,
12272 empty_ssl_info, origin,
12273 NetLogWithSource());
12274 second_handler->SetGenerateExpectation(true, OK);
12275 auth_factory->AddMockHandler(second_handler.release(),
12276 HttpAuth::AUTH_SERVER);
[email protected]044de0642010-06-17 10:42:1512277 }
12278 if (test_config.proxy_url) {
rdsmith82957ad2015-09-16 19:42:0312279 session_deps_.proxy_service =
12280 ProxyService::CreateFixed(test_config.proxy_url);
[email protected]044de0642010-06-17 10:42:1512281 } else {
rdsmith82957ad2015-09-16 19:42:0312282 session_deps_.proxy_service = ProxyService::CreateDirect();
[email protected]044de0642010-06-17 10:42:1512283 }
12284
12285 HttpRequestInfo request;
12286 request.method = "GET";
12287 request.url = GURL(test_config.server_url);
[email protected]044de0642010-06-17 10:42:1512288
danakj1fd259a02016-04-16 03:17:0912289 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]044de0642010-06-17 10:42:1512290
rchcb68dc62015-05-21 04:45:3612291 SSLSocketDataProvider ssl_socket_data_provider(SYNCHRONOUS, OK);
12292
12293 std::vector<std::vector<MockRead>> mock_reads(1);
12294 std::vector<std::vector<MockWrite>> mock_writes(1);
[email protected]044de0642010-06-17 10:42:1512295 for (int round = 0; round < test_config.num_auth_rounds; ++round) {
12296 const TestRound& read_write_round = test_config.rounds[round];
12297
12298 // Set up expected reads and writes.
rchcb68dc62015-05-21 04:45:3612299 mock_reads.back().push_back(read_write_round.read);
12300 mock_writes.back().push_back(read_write_round.write);
12301
12302 // kProxyChallenge uses Proxy-Connection: close which means that the
12303 // socket is closed and a new one will be created for the next request.
mmenkee71e15332015-10-07 16:39:5412304 if (read_write_round.read.data == kProxyChallenge.data) {
rchcb68dc62015-05-21 04:45:3612305 mock_reads.push_back(std::vector<MockRead>());
12306 mock_writes.push_back(std::vector<MockWrite>());
[email protected]044de0642010-06-17 10:42:1512307 }
12308
rchcb68dc62015-05-21 04:45:3612309 if (read_write_round.extra_read) {
12310 mock_reads.back().push_back(*read_write_round.extra_read);
[email protected]044de0642010-06-17 10:42:1512311 }
rchcb68dc62015-05-21 04:45:3612312 if (read_write_round.extra_write) {
12313 mock_writes.back().push_back(*read_write_round.extra_write);
12314 }
[email protected]044de0642010-06-17 10:42:1512315
12316 // Add an SSL sequence if necessary.
[email protected]044de0642010-06-17 10:42:1512317 if (round >= test_config.first_ssl_round)
[email protected]bb88e1d32013-05-03 23:11:0712318 session_deps_.socket_factory->AddSSLSocketDataProvider(
[email protected]044de0642010-06-17 10:42:1512319 &ssl_socket_data_provider);
rchcb68dc62015-05-21 04:45:3612320 }
[email protected]044de0642010-06-17 10:42:1512321
danakj1fd259a02016-04-16 03:17:0912322 std::vector<std::unique_ptr<StaticSocketDataProvider>> data_providers;
rchcb68dc62015-05-21 04:45:3612323 for (size_t i = 0; i < mock_reads.size(); ++i) {
danakj1fd259a02016-04-16 03:17:0912324 data_providers.push_back(base::WrapUnique(new StaticSocketDataProvider(
davidben5f8b6bc2015-11-25 03:19:5412325 mock_reads[i].data(), mock_reads[i].size(), mock_writes[i].data(),
olli.raula525048c2015-12-10 07:38:3212326 mock_writes[i].size())));
rchcb68dc62015-05-21 04:45:3612327 session_deps_.socket_factory->AddSocketDataProvider(
olli.raula525048c2015-12-10 07:38:3212328 data_providers.back().get());
rchcb68dc62015-05-21 04:45:3612329 }
12330
mmenkecc2298e2015-12-07 18:20:1812331 // Transaction must be created after DataProviders, so it's destroyed before
12332 // they are as well.
12333 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
12334
rchcb68dc62015-05-21 04:45:3612335 for (int round = 0; round < test_config.num_auth_rounds; ++round) {
12336 const TestRound& read_write_round = test_config.rounds[round];
[email protected]044de0642010-06-17 10:42:1512337 // Start or restart the transaction.
[email protected]49639fa2011-12-20 23:22:4112338 TestCompletionCallback callback;
[email protected]044de0642010-06-17 10:42:1512339 int rv;
12340 if (round == 0) {
tfarina42834112016-09-22 13:38:2012341 rv = trans.Start(&request, callback.callback(), NetLogWithSource());
[email protected]044de0642010-06-17 10:42:1512342 } else {
[email protected]49639fa2011-12-20 23:22:4112343 rv = trans.RestartWithAuth(
12344 AuthCredentials(kFoo, kBar), callback.callback());
[email protected]044de0642010-06-17 10:42:1512345 }
12346 if (rv == ERR_IO_PENDING)
12347 rv = callback.WaitForResult();
12348
12349 // Compare results with expected data.
asankae2257db2016-10-11 22:03:1612350 EXPECT_THAT(rv, IsError(read_write_round.expected_rv));
[email protected]0b0bf032010-09-21 18:08:5012351 const HttpResponseInfo* response = trans.GetResponseInfo();
ttuttlec0c828492015-05-15 01:25:5512352 if (read_write_round.expected_rv != OK) {
[email protected]044de0642010-06-17 10:42:1512353 EXPECT_EQ(round + 1, test_config.num_auth_rounds);
12354 continue;
12355 }
12356 if (round + 1 < test_config.num_auth_rounds) {
wezca1070932016-05-26 20:30:5212357 EXPECT_TRUE(response->auth_challenge);
[email protected]044de0642010-06-17 10:42:1512358 } else {
wezca1070932016-05-26 20:30:5212359 EXPECT_FALSE(response->auth_challenge);
asankae2257db2016-10-11 22:03:1612360 EXPECT_FALSE(trans.IsReadyToRestartForAuth());
[email protected]044de0642010-06-17 10:42:1512361 }
12362 }
[email protected]e5ae96a2010-04-14 20:12:4512363 }
12364}
12365
bncd16676a2016-07-20 16:23:0112366TEST_F(HttpNetworkTransactionTest, MultiRoundAuth) {
[email protected]c871bce92010-07-15 21:51:1412367 // Do multi-round authentication and make sure it works correctly.
[email protected]c871bce92010-07-15 21:51:1412368 HttpAuthHandlerMock::Factory* auth_factory(
12369 new HttpAuthHandlerMock::Factory());
[email protected]bb88e1d32013-05-03 23:11:0712370 session_deps_.http_auth_handler_factory.reset(auth_factory);
rdsmith82957ad2015-09-16 19:42:0312371 session_deps_.proxy_service = ProxyService::CreateDirect();
[email protected]bb88e1d32013-05-03 23:11:0712372 session_deps_.host_resolver->rules()->AddRule("www.example.com", "10.0.0.1");
12373 session_deps_.host_resolver->set_synchronous_mode(true);
[email protected]c871bce92010-07-15 21:51:1412374
12375 HttpAuthHandlerMock* auth_handler(new HttpAuthHandlerMock());
12376 auth_handler->set_connection_based(true);
12377 std::string auth_challenge = "Mock realm=server";
12378 GURL origin("http://www.example.com");
[email protected]df41d0d82014-03-13 00:43:2412379 HttpAuthChallengeTokenizer tokenizer(auth_challenge.begin(),
12380 auth_challenge.end());
asanka5ffd5d72016-03-23 16:20:4912381 SSLInfo empty_ssl_info;
[email protected]c871bce92010-07-15 21:51:1412382 auth_handler->InitFromChallenge(&tokenizer, HttpAuth::AUTH_SERVER,
tfarina42834112016-09-22 13:38:2012383 empty_ssl_info, origin, NetLogWithSource());
[email protected]2d01c262011-08-11 23:07:0812384 auth_factory->AddMockHandler(auth_handler, HttpAuth::AUTH_SERVER);
[email protected]c871bce92010-07-15 21:51:1412385
[email protected]c871bce92010-07-15 21:51:1412386 int rv = OK;
12387 const HttpResponseInfo* response = NULL;
12388 HttpRequestInfo request;
12389 request.method = "GET";
12390 request.url = origin;
[email protected]cb9bf6ca2011-01-28 13:15:2712391
danakj1fd259a02016-04-16 03:17:0912392 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]7ef4cbbb2011-02-06 11:19:1012393
12394 // Use a TCP Socket Pool with only one connection per group. This is used
12395 // to validate that the TCP socket is not released to the pool between
12396 // each round of multi-round authentication.
mmenkee65e7af2015-10-13 17:16:4212397 HttpNetworkSessionPeer session_peer(session.get());
[email protected]ab739042011-04-07 15:22:2812398 TransportClientSocketPool* transport_pool = new TransportClientSocketPool(
[email protected]7ef4cbbb2011-02-06 11:19:1012399 50, // Max sockets for pool
12400 1, // Max sockets per group
tbansal7b403bcc2016-04-13 22:33:2112401 session_deps_.host_resolver.get(), session_deps_.socket_factory.get(),
12402 NULL, session_deps_.net_log);
danakj1fd259a02016-04-16 03:17:0912403 std::unique_ptr<MockClientSocketPoolManager> mock_pool_manager(
[email protected]831e4a32013-11-14 02:14:4412404 new MockClientSocketPoolManager);
[email protected]a42dbd142011-11-17 16:42:0212405 mock_pool_manager->SetTransportSocketPool(transport_pool);
dchengc7eeda422015-12-26 03:56:4812406 session_peer.SetClientSocketPoolManager(std::move(mock_pool_manager));
[email protected]7ef4cbbb2011-02-06 11:19:1012407
bnc691fda62016-08-12 00:43:1612408 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]49639fa2011-12-20 23:22:4112409 TestCompletionCallback callback;
[email protected]c871bce92010-07-15 21:51:1412410
12411 const MockWrite kGet(
12412 "GET / HTTP/1.1\r\n"
12413 "Host: www.example.com\r\n"
12414 "Connection: keep-alive\r\n\r\n");
12415 const MockWrite kGetAuth(
12416 "GET / HTTP/1.1\r\n"
12417 "Host: www.example.com\r\n"
12418 "Connection: keep-alive\r\n"
12419 "Authorization: auth_token\r\n\r\n");
12420
12421 const MockRead kServerChallenge(
12422 "HTTP/1.1 401 Unauthorized\r\n"
12423 "WWW-Authenticate: Mock realm=server\r\n"
12424 "Content-Type: text/html; charset=iso-8859-1\r\n"
12425 "Content-Length: 14\r\n\r\n"
12426 "Unauthorized\r\n");
12427 const MockRead kSuccess(
12428 "HTTP/1.1 200 OK\r\n"
12429 "Content-Type: text/html; charset=iso-8859-1\r\n"
12430 "Content-Length: 3\r\n\r\n"
12431 "Yes");
12432
12433 MockWrite writes[] = {
12434 // First round
12435 kGet,
12436 // Second round
12437 kGetAuth,
12438 // Third round
12439 kGetAuth,
[email protected]eca50e122010-09-11 14:03:3012440 // Fourth round
[email protected]7ef4cbbb2011-02-06 11:19:1012441 kGetAuth,
12442 // Competing request
12443 kGet,
[email protected]c871bce92010-07-15 21:51:1412444 };
12445 MockRead reads[] = {
12446 // First round
12447 kServerChallenge,
12448 // Second round
12449 kServerChallenge,
12450 // Third round
[email protected]eca50e122010-09-11 14:03:3012451 kServerChallenge,
12452 // Fourth round
[email protected]c871bce92010-07-15 21:51:1412453 kSuccess,
[email protected]7ef4cbbb2011-02-06 11:19:1012454 // Competing response
12455 kSuccess,
[email protected]c871bce92010-07-15 21:51:1412456 };
12457 StaticSocketDataProvider data_provider(reads, arraysize(reads),
12458 writes, arraysize(writes));
[email protected]bb88e1d32013-05-03 23:11:0712459 session_deps_.socket_factory->AddSocketDataProvider(&data_provider);
[email protected]c871bce92010-07-15 21:51:1412460
thestig9d3bb0c2015-01-24 00:49:5112461 const char kSocketGroup[] = "www.example.com:80";
[email protected]7ef4cbbb2011-02-06 11:19:1012462
12463 // First round of authentication.
[email protected]c871bce92010-07-15 21:51:1412464 auth_handler->SetGenerateExpectation(false, OK);
tfarina42834112016-09-22 13:38:2012465 rv = trans.Start(&request, callback.callback(), NetLogWithSource());
[email protected]c871bce92010-07-15 21:51:1412466 if (rv == ERR_IO_PENDING)
12467 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0112468 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:1612469 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5212470 ASSERT_TRUE(response);
12471 EXPECT_TRUE(response->auth_challenge);
[email protected]ab739042011-04-07 15:22:2812472 EXPECT_EQ(0, transport_pool->IdleSocketCountInGroup(kSocketGroup));
asanka463ca4262016-11-16 02:34:3112473 EXPECT_EQ(HttpAuthHandlerMock::State::WAIT_FOR_GENERATE_AUTH_TOKEN,
12474 auth_handler->state());
[email protected]c871bce92010-07-15 21:51:1412475
[email protected]7ef4cbbb2011-02-06 11:19:1012476 // In between rounds, another request comes in for the same domain.
12477 // It should not be able to grab the TCP socket that trans has already
12478 // claimed.
bnc691fda62016-08-12 00:43:1612479 HttpNetworkTransaction trans_compete(DEFAULT_PRIORITY, session.get());
[email protected]49639fa2011-12-20 23:22:4112480 TestCompletionCallback callback_compete;
tfarina42834112016-09-22 13:38:2012481 rv = trans_compete.Start(&request, callback_compete.callback(),
12482 NetLogWithSource());
robpercival214763f2016-07-01 23:27:0112483 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]7ef4cbbb2011-02-06 11:19:1012484 // callback_compete.WaitForResult at this point would stall forever,
12485 // since the HttpNetworkTransaction does not release the request back to
12486 // the pool until after authentication completes.
12487
12488 // Second round of authentication.
[email protected]c871bce92010-07-15 21:51:1412489 auth_handler->SetGenerateExpectation(false, OK);
bnc691fda62016-08-12 00:43:1612490 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar), callback.callback());
[email protected]c871bce92010-07-15 21:51:1412491 if (rv == ERR_IO_PENDING)
12492 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0112493 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:1612494 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5212495 ASSERT_TRUE(response);
12496 EXPECT_FALSE(response->auth_challenge);
[email protected]ab739042011-04-07 15:22:2812497 EXPECT_EQ(0, transport_pool->IdleSocketCountInGroup(kSocketGroup));
asanka463ca4262016-11-16 02:34:3112498 EXPECT_EQ(HttpAuthHandlerMock::State::WAIT_FOR_GENERATE_AUTH_TOKEN,
12499 auth_handler->state());
[email protected]c871bce92010-07-15 21:51:1412500
[email protected]7ef4cbbb2011-02-06 11:19:1012501 // Third round of authentication.
[email protected]c871bce92010-07-15 21:51:1412502 auth_handler->SetGenerateExpectation(false, OK);
bnc691fda62016-08-12 00:43:1612503 rv = trans.RestartWithAuth(AuthCredentials(), callback.callback());
[email protected]c871bce92010-07-15 21:51:1412504 if (rv == ERR_IO_PENDING)
12505 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0112506 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:1612507 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5212508 ASSERT_TRUE(response);
12509 EXPECT_FALSE(response->auth_challenge);
[email protected]ab739042011-04-07 15:22:2812510 EXPECT_EQ(0, transport_pool->IdleSocketCountInGroup(kSocketGroup));
asanka463ca4262016-11-16 02:34:3112511 EXPECT_EQ(HttpAuthHandlerMock::State::WAIT_FOR_GENERATE_AUTH_TOKEN,
12512 auth_handler->state());
[email protected]eca50e122010-09-11 14:03:3012513
[email protected]7ef4cbbb2011-02-06 11:19:1012514 // Fourth round of authentication, which completes successfully.
[email protected]eca50e122010-09-11 14:03:3012515 auth_handler->SetGenerateExpectation(false, OK);
bnc691fda62016-08-12 00:43:1612516 rv = trans.RestartWithAuth(AuthCredentials(), callback.callback());
[email protected]eca50e122010-09-11 14:03:3012517 if (rv == ERR_IO_PENDING)
12518 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0112519 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:1612520 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5212521 ASSERT_TRUE(response);
12522 EXPECT_FALSE(response->auth_challenge);
[email protected]ab739042011-04-07 15:22:2812523 EXPECT_EQ(0, transport_pool->IdleSocketCountInGroup(kSocketGroup));
[email protected]7ef4cbbb2011-02-06 11:19:1012524
asanka463ca4262016-11-16 02:34:3112525 // In WAIT_FOR_CHALLENGE, although in reality the auth handler is done. A real
12526 // auth handler should transition to a DONE state in concert with the remote
12527 // server. But that's not something we can test here with a mock handler.
12528 EXPECT_EQ(HttpAuthHandlerMock::State::WAIT_FOR_CHALLENGE,
12529 auth_handler->state());
12530
[email protected]7ef4cbbb2011-02-06 11:19:1012531 // Read the body since the fourth round was successful. This will also
12532 // release the socket back to the pool.
12533 scoped_refptr<IOBufferWithSize> io_buf(new IOBufferWithSize(50));
bnc691fda62016-08-12 00:43:1612534 rv = trans.Read(io_buf.get(), io_buf->size(), callback.callback());
[email protected]7ef4cbbb2011-02-06 11:19:1012535 if (rv == ERR_IO_PENDING)
12536 rv = callback.WaitForResult();
12537 EXPECT_EQ(3, rv);
bnc691fda62016-08-12 00:43:1612538 rv = trans.Read(io_buf.get(), io_buf->size(), callback.callback());
[email protected]7ef4cbbb2011-02-06 11:19:1012539 EXPECT_EQ(0, rv);
12540 // There are still 0 idle sockets, since the trans_compete transaction
12541 // will be handed it immediately after trans releases it to the group.
[email protected]ab739042011-04-07 15:22:2812542 EXPECT_EQ(0, transport_pool->IdleSocketCountInGroup(kSocketGroup));
[email protected]7ef4cbbb2011-02-06 11:19:1012543
12544 // The competing request can now finish. Wait for the headers and then
12545 // read the body.
12546 rv = callback_compete.WaitForResult();
robpercival214763f2016-07-01 23:27:0112547 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:1612548 rv = trans_compete.Read(io_buf.get(), io_buf->size(), callback.callback());
[email protected]7ef4cbbb2011-02-06 11:19:1012549 if (rv == ERR_IO_PENDING)
12550 rv = callback.WaitForResult();
12551 EXPECT_EQ(3, rv);
bnc691fda62016-08-12 00:43:1612552 rv = trans_compete.Read(io_buf.get(), io_buf->size(), callback.callback());
[email protected]7ef4cbbb2011-02-06 11:19:1012553 EXPECT_EQ(0, rv);
12554
12555 // Finally, the socket is released to the group.
[email protected]ab739042011-04-07 15:22:2812556 EXPECT_EQ(1, transport_pool->IdleSocketCountInGroup(kSocketGroup));
[email protected]c871bce92010-07-15 21:51:1412557}
12558
[email protected]65041fa2010-05-21 06:56:5312559// This tests the case that a request is issued via http instead of spdy after
12560// npn is negotiated.
bncd16676a2016-07-20 16:23:0112561TEST_F(HttpNetworkTransactionTest, NpnWithHttpOverSSL) {
[email protected]65041fa2010-05-21 06:56:5312562 HttpRequestInfo request;
12563 request.method = "GET";
bncce36dca22015-04-21 22:11:2312564 request.url = GURL("https://www.example.org/");
[email protected]65041fa2010-05-21 06:56:5312565
12566 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:2312567 MockWrite(
12568 "GET / HTTP/1.1\r\n"
12569 "Host: www.example.org\r\n"
12570 "Connection: keep-alive\r\n\r\n"),
[email protected]65041fa2010-05-21 06:56:5312571 };
12572
12573 MockRead data_reads[] = {
bncc958faa2015-07-31 18:14:5212574 MockRead("HTTP/1.1 200 OK\r\n"),
bnc2df4b522016-07-08 18:17:4312575 MockRead(kAlternativeServiceHttpHeader),
bncc958faa2015-07-31 18:14:5212576 MockRead("\r\n"),
12577 MockRead("hello world"),
12578 MockRead(SYNCHRONOUS, OK),
[email protected]65041fa2010-05-21 06:56:5312579 };
12580
[email protected]8ddf8322012-02-23 18:08:0612581 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3612582 ssl.next_proto = kProtoHTTP11;
[email protected]65041fa2010-05-21 06:56:5312583
[email protected]bb88e1d32013-05-03 23:11:0712584 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]65041fa2010-05-21 06:56:5312585
12586 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
12587 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:0712588 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]65041fa2010-05-21 06:56:5312589
[email protected]49639fa2011-12-20 23:22:4112590 TestCompletionCallback callback;
[email protected]65041fa2010-05-21 06:56:5312591
danakj1fd259a02016-04-16 03:17:0912592 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1612593 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]65041fa2010-05-21 06:56:5312594
tfarina42834112016-09-22 13:38:2012595 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
[email protected]65041fa2010-05-21 06:56:5312596
robpercival214763f2016-07-01 23:27:0112597 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
12598 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]65041fa2010-05-21 06:56:5312599
bnc691fda62016-08-12 00:43:1612600 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5212601 ASSERT_TRUE(response);
12602 ASSERT_TRUE(response->headers);
[email protected]65041fa2010-05-21 06:56:5312603 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
12604
12605 std::string response_data;
bnc691fda62016-08-12 00:43:1612606 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
[email protected]65041fa2010-05-21 06:56:5312607 EXPECT_EQ("hello world", response_data);
12608
12609 EXPECT_FALSE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5212610 EXPECT_TRUE(response->was_alpn_negotiated);
[email protected]65041fa2010-05-21 06:56:5312611}
[email protected]26ef6582010-06-24 02:30:4712612
bnc55ff9da2015-08-19 18:42:3512613// Simulate the SSL handshake completing with an NPN negotiation followed by an
12614// immediate server closing of the socket.
12615// Regression test for https://crbug.com/46369.
bncd16676a2016-07-20 16:23:0112616TEST_F(HttpNetworkTransactionTest, SpdyPostNPNServerHangup) {
[email protected]26ef6582010-06-24 02:30:4712617 HttpRequestInfo request;
12618 request.method = "GET";
bncce36dca22015-04-21 22:11:2312619 request.url = GURL("https://www.example.org/");
[email protected]26ef6582010-06-24 02:30:4712620
[email protected]8ddf8322012-02-23 18:08:0612621 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3612622 ssl.next_proto = kProtoHTTP2;
[email protected]bb88e1d32013-05-03 23:11:0712623 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]26ef6582010-06-24 02:30:4712624
bncdf80d44fd2016-07-15 20:27:4112625 SpdySerializedFrame req(
bnc38dcd392016-02-09 23:19:4912626 spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST, true));
bncdf80d44fd2016-07-15 20:27:4112627 MockWrite spdy_writes[] = {CreateMockWrite(req, 1)};
[email protected]26ef6582010-06-24 02:30:4712628
12629 MockRead spdy_reads[] = {
[email protected]8ddf8322012-02-23 18:08:0612630 MockRead(SYNCHRONOUS, 0, 0) // Not async - return 0 immediately.
[email protected]26ef6582010-06-24 02:30:4712631 };
12632
rch8e6c6c42015-05-01 14:05:1312633 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
12634 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:0712635 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]26ef6582010-06-24 02:30:4712636
[email protected]49639fa2011-12-20 23:22:4112637 TestCompletionCallback callback;
[email protected]26ef6582010-06-24 02:30:4712638
danakj1fd259a02016-04-16 03:17:0912639 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1612640 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]26ef6582010-06-24 02:30:4712641
tfarina42834112016-09-22 13:38:2012642 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0112643 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
12644 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_CONNECTION_CLOSED));
[email protected]26ef6582010-06-24 02:30:4712645}
[email protected]65d34382010-07-01 18:12:2612646
[email protected]795cbf82013-07-22 09:37:2712647// A subclass of HttpAuthHandlerMock that records the request URL when
12648// it gets it. This is needed since the auth handler may get destroyed
12649// before we get a chance to query it.
12650class UrlRecordingHttpAuthHandlerMock : public HttpAuthHandlerMock {
12651 public:
12652 explicit UrlRecordingHttpAuthHandlerMock(GURL* url) : url_(url) {}
12653
dchengb03027d2014-10-21 12:00:2012654 ~UrlRecordingHttpAuthHandlerMock() override {}
[email protected]795cbf82013-07-22 09:37:2712655
12656 protected:
dchengb03027d2014-10-21 12:00:2012657 int GenerateAuthTokenImpl(const AuthCredentials* credentials,
12658 const HttpRequestInfo* request,
12659 const CompletionCallback& callback,
12660 std::string* auth_token) override {
[email protected]795cbf82013-07-22 09:37:2712661 *url_ = request->url;
12662 return HttpAuthHandlerMock::GenerateAuthTokenImpl(
12663 credentials, request, callback, auth_token);
12664 }
12665
12666 private:
12667 GURL* url_;
12668};
12669
[email protected]8e6441ca2010-08-19 05:56:3812670// Test that if we cancel the transaction as the connection is completing, that
12671// everything tears down correctly.
bncd16676a2016-07-20 16:23:0112672TEST_F(HttpNetworkTransactionTest, SimpleCancel) {
[email protected]8e6441ca2010-08-19 05:56:3812673 // Setup everything about the connection to complete synchronously, so that
12674 // after calling HttpNetworkTransaction::Start, the only thing we're waiting
12675 // for is the callback from the HttpStreamRequest.
12676 // Then cancel the transaction.
12677 // Verify that we don't crash.
[email protected]d973e99a2012-02-17 21:02:3612678 MockConnect mock_connect(SYNCHRONOUS, OK);
[email protected]8e6441ca2010-08-19 05:56:3812679 MockRead data_reads[] = {
[email protected]8ddf8322012-02-23 18:08:0612680 MockRead(SYNCHRONOUS, "HTTP/1.0 200 OK\r\n\r\n"),
12681 MockRead(SYNCHRONOUS, "hello world"),
12682 MockRead(SYNCHRONOUS, OK),
[email protected]8e6441ca2010-08-19 05:56:3812683 };
12684
[email protected]8e6441ca2010-08-19 05:56:3812685 HttpRequestInfo request;
12686 request.method = "GET";
bncce36dca22015-04-21 22:11:2312687 request.url = GURL("http://www.example.org/");
[email protected]8e6441ca2010-08-19 05:56:3812688
[email protected]bb88e1d32013-05-03 23:11:0712689 session_deps_.host_resolver->set_synchronous_mode(true);
danakj1fd259a02016-04-16 03:17:0912690 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1612691 std::unique_ptr<HttpNetworkTransaction> trans(
dcheng48459ac22014-08-26 00:46:4112692 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:2712693
[email protected]8e6441ca2010-08-19 05:56:3812694 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
12695 data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:0712696 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]8e6441ca2010-08-19 05:56:3812697
[email protected]49639fa2011-12-20 23:22:4112698 TestCompletionCallback callback;
[email protected]8e6441ca2010-08-19 05:56:3812699
vishal.b62985ca92015-04-17 08:45:5112700 BoundTestNetLog log;
[email protected]49639fa2011-12-20 23:22:4112701 int rv = trans->Start(&request, callback.callback(), log.bound());
robpercival214763f2016-07-01 23:27:0112702 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]8e6441ca2010-08-19 05:56:3812703 trans.reset(); // Cancel the transaction here.
12704
fdoray92e35a72016-06-10 15:54:5512705 base::RunLoop().RunUntilIdle();
[email protected]f45c1ee2010-08-03 00:54:3012706}
12707
[email protected]ecab6e052014-05-16 14:58:1212708// Test that if a transaction is cancelled after receiving the headers, the
12709// stream is drained properly and added back to the socket pool. The main
12710// purpose of this test is to make sure that an HttpStreamParser can be read
12711// from after the HttpNetworkTransaction and the objects it owns have been
12712// deleted.
12713// See http://crbug.com/368418
bncd16676a2016-07-20 16:23:0112714TEST_F(HttpNetworkTransactionTest, CancelAfterHeaders) {
[email protected]ecab6e052014-05-16 14:58:1212715 MockRead data_reads[] = {
12716 MockRead(ASYNC, "HTTP/1.1 200 OK\r\n"),
12717 MockRead(ASYNC, "Content-Length: 2\r\n"),
12718 MockRead(ASYNC, "Connection: Keep-Alive\r\n\r\n"),
12719 MockRead(ASYNC, "1"),
12720 // 2 async reads are necessary to trigger a ReadResponseBody call after the
12721 // HttpNetworkTransaction has been deleted.
12722 MockRead(ASYNC, "2"),
12723 MockRead(SYNCHRONOUS, ERR_IO_PENDING), // Should never read this.
12724 };
12725 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
12726 session_deps_.socket_factory->AddSocketDataProvider(&data);
12727
danakj1fd259a02016-04-16 03:17:0912728 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]ecab6e052014-05-16 14:58:1212729
12730 {
12731 HttpRequestInfo request;
12732 request.method = "GET";
bncce36dca22015-04-21 22:11:2312733 request.url = GURL("http://www.example.org/");
[email protected]ecab6e052014-05-16 14:58:1212734
dcheng48459ac22014-08-26 00:46:4112735 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]ecab6e052014-05-16 14:58:1212736 TestCompletionCallback callback;
12737
tfarina42834112016-09-22 13:38:2012738 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0112739 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]ecab6e052014-05-16 14:58:1212740 callback.WaitForResult();
12741
12742 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5212743 ASSERT_TRUE(response);
12744 EXPECT_TRUE(response->headers);
[email protected]ecab6e052014-05-16 14:58:1212745 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
12746
12747 // The transaction and HttpRequestInfo are deleted.
12748 }
12749
12750 // Let the HttpResponseBodyDrainer drain the socket.
fdoray92e35a72016-06-10 15:54:5512751 base::RunLoop().RunUntilIdle();
[email protected]ecab6e052014-05-16 14:58:1212752
12753 // Socket should now be idle, waiting to be reused.
dcheng48459ac22014-08-26 00:46:4112754 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]ecab6e052014-05-16 14:58:1212755}
12756
[email protected]76a505b2010-08-25 06:23:0012757// Test a basic GET request through a proxy.
bncd16676a2016-07-20 16:23:0112758TEST_F(HttpNetworkTransactionTest, ProxyGet) {
rdsmith82957ad2015-09-16 19:42:0312759 session_deps_.proxy_service =
12760 ProxyService::CreateFixedFromPacResult("PROXY myproxy:70");
vishal.b62985ca92015-04-17 08:45:5112761 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:0712762 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:0912763 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]76a505b2010-08-25 06:23:0012764
[email protected]76a505b2010-08-25 06:23:0012765 HttpRequestInfo request;
12766 request.method = "GET";
bncce36dca22015-04-21 22:11:2312767 request.url = GURL("http://www.example.org/");
[email protected]76a505b2010-08-25 06:23:0012768
12769 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:2312770 MockWrite(
12771 "GET http://www.example.org/ HTTP/1.1\r\n"
12772 "Host: www.example.org\r\n"
12773 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]76a505b2010-08-25 06:23:0012774 };
12775
12776 MockRead data_reads1[] = {
12777 MockRead("HTTP/1.1 200 OK\r\n"),
12778 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
12779 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:0612780 MockRead(SYNCHRONOUS, OK),
[email protected]76a505b2010-08-25 06:23:0012781 };
12782
12783 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
12784 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:0712785 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]76a505b2010-08-25 06:23:0012786
[email protected]49639fa2011-12-20 23:22:4112787 TestCompletionCallback callback1;
[email protected]76a505b2010-08-25 06:23:0012788
bnc691fda62016-08-12 00:43:1612789 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
ryansturm49a8cb12016-06-15 16:51:0912790 BeforeHeadersSentHandler headers_handler;
bnc691fda62016-08-12 00:43:1612791 trans.SetBeforeHeadersSentCallback(
ryansturm49a8cb12016-06-15 16:51:0912792 base::Bind(&BeforeHeadersSentHandler::OnBeforeHeadersSent,
12793 base::Unretained(&headers_handler)));
[email protected]0b0bf032010-09-21 18:08:5012794
bnc691fda62016-08-12 00:43:1612795 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:0112796 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]76a505b2010-08-25 06:23:0012797
12798 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:0112799 EXPECT_THAT(rv, IsOk());
[email protected]76a505b2010-08-25 06:23:0012800
bnc691fda62016-08-12 00:43:1612801 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5212802 ASSERT_TRUE(response);
[email protected]76a505b2010-08-25 06:23:0012803
12804 EXPECT_TRUE(response->headers->IsKeepAlive());
12805 EXPECT_EQ(200, response->headers->response_code());
12806 EXPECT_EQ(100, response->headers->GetContentLength());
12807 EXPECT_TRUE(response->was_fetched_via_proxy);
tbansal2ecbbc72016-10-06 17:15:4712808 EXPECT_EQ(ProxyServer(ProxyServer::SCHEME_HTTP,
12809 HostPortPair::FromString("myproxy:70")),
12810 response->proxy_server);
ryansturm49a8cb12016-06-15 16:51:0912811 EXPECT_TRUE(headers_handler.observed_before_headers_sent());
12812 EXPECT_TRUE(headers_handler.observed_before_headers_sent_with_proxy());
12813 EXPECT_EQ("myproxy:70", headers_handler.observed_proxy_server_uri());
[email protected]76a505b2010-08-25 06:23:0012814 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
[email protected]029c83b62013-01-24 05:28:2012815
12816 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:1612817 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]029c83b62013-01-24 05:28:2012818 TestLoadTimingNotReusedWithPac(load_timing_info,
12819 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
[email protected]76a505b2010-08-25 06:23:0012820}
12821
12822// Test a basic HTTPS GET request through a proxy.
bncd16676a2016-07-20 16:23:0112823TEST_F(HttpNetworkTransactionTest, ProxyTunnelGet) {
rdsmith82957ad2015-09-16 19:42:0312824 session_deps_.proxy_service =
12825 ProxyService::CreateFixedFromPacResult("PROXY myproxy:70");
vishal.b62985ca92015-04-17 08:45:5112826 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:0712827 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:0912828 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]76a505b2010-08-25 06:23:0012829
[email protected]76a505b2010-08-25 06:23:0012830 HttpRequestInfo request;
12831 request.method = "GET";
bncce36dca22015-04-21 22:11:2312832 request.url = GURL("https://www.example.org/");
[email protected]76a505b2010-08-25 06:23:0012833
12834 // Since we have proxy, should try to establish tunnel.
12835 MockWrite data_writes1[] = {
rsleevidb16bb02015-11-12 23:47:1712836 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
12837 "Host: www.example.org:443\r\n"
12838 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]76a505b2010-08-25 06:23:0012839
rsleevidb16bb02015-11-12 23:47:1712840 MockWrite("GET / HTTP/1.1\r\n"
12841 "Host: www.example.org\r\n"
12842 "Connection: keep-alive\r\n\r\n"),
[email protected]76a505b2010-08-25 06:23:0012843 };
12844
12845 MockRead data_reads1[] = {
12846 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
12847
12848 MockRead("HTTP/1.1 200 OK\r\n"),
12849 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
12850 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:0612851 MockRead(SYNCHRONOUS, OK),
[email protected]76a505b2010-08-25 06:23:0012852 };
12853
12854 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
12855 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:0712856 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8ddf8322012-02-23 18:08:0612857 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:0712858 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]76a505b2010-08-25 06:23:0012859
[email protected]49639fa2011-12-20 23:22:4112860 TestCompletionCallback callback1;
[email protected]76a505b2010-08-25 06:23:0012861
bnc691fda62016-08-12 00:43:1612862 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
ryansturm49a8cb12016-06-15 16:51:0912863 BeforeHeadersSentHandler headers_handler;
bnc691fda62016-08-12 00:43:1612864 trans.SetBeforeHeadersSentCallback(
ryansturm49a8cb12016-06-15 16:51:0912865 base::Bind(&BeforeHeadersSentHandler::OnBeforeHeadersSent,
12866 base::Unretained(&headers_handler)));
[email protected]0b0bf032010-09-21 18:08:5012867
bnc691fda62016-08-12 00:43:1612868 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:0112869 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]76a505b2010-08-25 06:23:0012870
12871 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:0112872 EXPECT_THAT(rv, IsOk());
mmenke43758e62015-05-04 21:09:4612873 TestNetLogEntry::List entries;
[email protected]b2fcd0e2010-12-01 15:19:4012874 log.GetEntries(&entries);
[email protected]76a505b2010-08-25 06:23:0012875 size_t pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:0012876 entries, 0, NetLogEventType::HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
12877 NetLogEventPhase::NONE);
[email protected]76a505b2010-08-25 06:23:0012878 ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:4012879 entries, pos,
mikecirone8b85c432016-09-08 19:11:0012880 NetLogEventType::HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
12881 NetLogEventPhase::NONE);
[email protected]76a505b2010-08-25 06:23:0012882
bnc691fda62016-08-12 00:43:1612883 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5212884 ASSERT_TRUE(response);
[email protected]76a505b2010-08-25 06:23:0012885
12886 EXPECT_TRUE(response->headers->IsKeepAlive());
12887 EXPECT_EQ(200, response->headers->response_code());
12888 EXPECT_EQ(100, response->headers->GetContentLength());
12889 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
12890 EXPECT_TRUE(response->was_fetched_via_proxy);
tbansal2ecbbc72016-10-06 17:15:4712891 EXPECT_EQ(ProxyServer(ProxyServer::SCHEME_HTTP,
12892 HostPortPair::FromString("myproxy:70")),
12893 response->proxy_server);
ryansturm49a8cb12016-06-15 16:51:0912894 EXPECT_TRUE(headers_handler.observed_before_headers_sent());
12895 EXPECT_TRUE(headers_handler.observed_before_headers_sent_with_proxy());
12896 EXPECT_EQ("myproxy:70", headers_handler.observed_proxy_server_uri());
[email protected]029c83b62013-01-24 05:28:2012897
12898 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:1612899 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]029c83b62013-01-24 05:28:2012900 TestLoadTimingNotReusedWithPac(load_timing_info,
12901 CONNECT_TIMING_HAS_SSL_TIMES);
[email protected]76a505b2010-08-25 06:23:0012902}
12903
rsleevidb16bb02015-11-12 23:47:1712904// Test a basic HTTPS GET request through a proxy, connecting to an IPv6
12905// literal host.
bncd16676a2016-07-20 16:23:0112906TEST_F(HttpNetworkTransactionTest, ProxyTunnelGetIPv6) {
rsleevidb16bb02015-11-12 23:47:1712907 session_deps_.proxy_service =
12908 ProxyService::CreateFixedFromPacResult("PROXY myproxy:70");
12909 BoundTestNetLog log;
12910 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:0912911 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
rsleevidb16bb02015-11-12 23:47:1712912
12913 HttpRequestInfo request;
12914 request.method = "GET";
12915 request.url = GURL("https://[::1]:443/");
12916
12917 // Since we have proxy, should try to establish tunnel.
12918 MockWrite data_writes1[] = {
12919 MockWrite("CONNECT [::1]:443 HTTP/1.1\r\n"
12920 "Host: [::1]:443\r\n"
12921 "Proxy-Connection: keep-alive\r\n\r\n"),
12922
12923 MockWrite("GET / HTTP/1.1\r\n"
12924 "Host: [::1]\r\n"
12925 "Connection: keep-alive\r\n\r\n"),
12926 };
12927
12928 MockRead data_reads1[] = {
12929 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
12930
12931 MockRead("HTTP/1.1 200 OK\r\n"),
12932 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
12933 MockRead("Content-Length: 100\r\n\r\n"),
12934 MockRead(SYNCHRONOUS, OK),
12935 };
12936
12937 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
12938 data_writes1, arraysize(data_writes1));
12939 session_deps_.socket_factory->AddSocketDataProvider(&data1);
12940 SSLSocketDataProvider ssl(ASYNC, OK);
12941 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
12942
12943 TestCompletionCallback callback1;
12944
bnc691fda62016-08-12 00:43:1612945 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
rsleevidb16bb02015-11-12 23:47:1712946
bnc691fda62016-08-12 00:43:1612947 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:0112948 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
rsleevidb16bb02015-11-12 23:47:1712949
12950 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:0112951 EXPECT_THAT(rv, IsOk());
rsleevidb16bb02015-11-12 23:47:1712952 TestNetLogEntry::List entries;
12953 log.GetEntries(&entries);
12954 size_t pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:0012955 entries, 0, NetLogEventType::HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
12956 NetLogEventPhase::NONE);
rsleevidb16bb02015-11-12 23:47:1712957 ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:0012958 entries, pos,
12959 NetLogEventType::HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
12960 NetLogEventPhase::NONE);
rsleevidb16bb02015-11-12 23:47:1712961
bnc691fda62016-08-12 00:43:1612962 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5212963 ASSERT_TRUE(response);
rsleevidb16bb02015-11-12 23:47:1712964
12965 EXPECT_TRUE(response->headers->IsKeepAlive());
12966 EXPECT_EQ(200, response->headers->response_code());
12967 EXPECT_EQ(100, response->headers->GetContentLength());
12968 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
12969 EXPECT_TRUE(response->was_fetched_via_proxy);
tbansal2ecbbc72016-10-06 17:15:4712970 EXPECT_EQ(ProxyServer(ProxyServer::SCHEME_HTTP,
12971 HostPortPair::FromString("myproxy:70")),
12972 response->proxy_server);
rsleevidb16bb02015-11-12 23:47:1712973
12974 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:1612975 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
rsleevidb16bb02015-11-12 23:47:1712976 TestLoadTimingNotReusedWithPac(load_timing_info,
12977 CONNECT_TIMING_HAS_SSL_TIMES);
12978}
12979
[email protected]76a505b2010-08-25 06:23:0012980// Test a basic HTTPS GET request through a proxy, but the server hangs up
12981// while establishing the tunnel.
bncd16676a2016-07-20 16:23:0112982TEST_F(HttpNetworkTransactionTest, ProxyTunnelGetHangup) {
rdsmith82957ad2015-09-16 19:42:0312983 session_deps_.proxy_service = ProxyService::CreateFixed("myproxy:70");
vishal.b62985ca92015-04-17 08:45:5112984 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:0712985 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:0912986 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]76a505b2010-08-25 06:23:0012987
[email protected]76a505b2010-08-25 06:23:0012988 HttpRequestInfo request;
12989 request.method = "GET";
bncce36dca22015-04-21 22:11:2312990 request.url = GURL("https://www.example.org/");
[email protected]76a505b2010-08-25 06:23:0012991
12992 // Since we have proxy, should try to establish tunnel.
12993 MockWrite data_writes1[] = {
rsleevidb16bb02015-11-12 23:47:1712994 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
12995 "Host: www.example.org:443\r\n"
12996 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]76a505b2010-08-25 06:23:0012997
rsleevidb16bb02015-11-12 23:47:1712998 MockWrite("GET / HTTP/1.1\r\n"
12999 "Host: www.example.org\r\n"
13000 "Connection: keep-alive\r\n\r\n"),
[email protected]76a505b2010-08-25 06:23:0013001 };
13002
13003 MockRead data_reads1[] = {
[email protected]8ddf8322012-02-23 18:08:0613004 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
[email protected]76a505b2010-08-25 06:23:0013005 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:0613006 MockRead(ASYNC, 0, 0), // EOF
[email protected]76a505b2010-08-25 06:23:0013007 };
13008
13009 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
13010 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:0713011 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8ddf8322012-02-23 18:08:0613012 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:0713013 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]76a505b2010-08-25 06:23:0013014
[email protected]49639fa2011-12-20 23:22:4113015 TestCompletionCallback callback1;
[email protected]76a505b2010-08-25 06:23:0013016
bnc691fda62016-08-12 00:43:1613017 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]0b0bf032010-09-21 18:08:5013018
bnc691fda62016-08-12 00:43:1613019 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:0113020 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]76a505b2010-08-25 06:23:0013021
13022 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:0113023 EXPECT_THAT(rv, IsError(ERR_EMPTY_RESPONSE));
mmenke43758e62015-05-04 21:09:4613024 TestNetLogEntry::List entries;
[email protected]b2fcd0e2010-12-01 15:19:4013025 log.GetEntries(&entries);
[email protected]76a505b2010-08-25 06:23:0013026 size_t pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:0013027 entries, 0, NetLogEventType::HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
13028 NetLogEventPhase::NONE);
[email protected]76a505b2010-08-25 06:23:0013029 ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:4013030 entries, pos,
mikecirone8b85c432016-09-08 19:11:0013031 NetLogEventType::HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
13032 NetLogEventPhase::NONE);
[email protected]76a505b2010-08-25 06:23:0013033}
13034
[email protected]749eefa82010-09-13 22:14:0313035// Test for crbug.com/55424.
bncd16676a2016-07-20 16:23:0113036TEST_F(HttpNetworkTransactionTest, PreconnectWithExistingSpdySession) {
bncdf80d44fd2016-07-15 20:27:4113037 SpdySerializedFrame req(
bnc38dcd392016-02-09 23:19:4913038 spdy_util_.ConstructSpdyGet("https://www.example.org", 1, LOWEST));
bncdf80d44fd2016-07-15 20:27:4113039 MockWrite spdy_writes[] = {CreateMockWrite(req, 0)};
[email protected]749eefa82010-09-13 22:14:0313040
bnc42331402016-07-25 13:36:1513041 SpdySerializedFrame resp(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
bncdf80d44fd2016-07-15 20:27:4113042 SpdySerializedFrame data(spdy_util_.ConstructSpdyDataFrame(1, true));
[email protected]749eefa82010-09-13 22:14:0313043 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:4113044 CreateMockRead(resp, 1), CreateMockRead(data, 2), MockRead(ASYNC, 0, 3),
[email protected]749eefa82010-09-13 22:14:0313045 };
13046
rch8e6c6c42015-05-01 14:05:1313047 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
13048 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:0713049 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]749eefa82010-09-13 22:14:0313050
[email protected]8ddf8322012-02-23 18:08:0613051 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3613052 ssl.next_proto = kProtoHTTP2;
[email protected]bb88e1d32013-05-03 23:11:0713053 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]749eefa82010-09-13 22:14:0313054
danakj1fd259a02016-04-16 03:17:0913055 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]749eefa82010-09-13 22:14:0313056
13057 // Set up an initial SpdySession in the pool to reuse.
bncce36dca22015-04-21 22:11:2313058 HostPortPair host_port_pair("www.example.org", 443);
[email protected]e6d017652013-05-17 18:01:4013059 SpdySessionKey key(host_port_pair, ProxyServer::Direct(),
[email protected]314b03992014-04-01 01:28:5313060 PRIVACY_MODE_DISABLED);
[email protected]795cbf82013-07-22 09:37:2713061 base::WeakPtr<SpdySession> spdy_session =
bnc032658ba2016-09-26 18:17:1513062 CreateSecureSpdySession(session.get(), key, NetLogWithSource());
[email protected]749eefa82010-09-13 22:14:0313063
13064 HttpRequestInfo request;
13065 request.method = "GET";
bncce36dca22015-04-21 22:11:2313066 request.url = GURL("https://www.example.org/");
[email protected]749eefa82010-09-13 22:14:0313067
13068 // This is the important line that marks this as a preconnect.
13069 request.motivation = HttpRequestInfo::PRECONNECT_MOTIVATED;
13070
bnc691fda62016-08-12 00:43:1613071 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]749eefa82010-09-13 22:14:0313072
[email protected]41d64e82013-07-03 22:44:2613073 TestCompletionCallback callback;
tfarina42834112016-09-22 13:38:2013074 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0113075 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
13076 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]749eefa82010-09-13 22:14:0313077}
13078
[email protected]73b8dd222010-11-11 19:55:2413079// Given a net error, cause that error to be returned from the first Write()
bnc691fda62016-08-12 00:43:1613080// call and verify that the HttpNetworkTransaction fails with that error.
[email protected]23e482282013-06-14 16:08:0213081void HttpNetworkTransactionTest::CheckErrorIsPassedBack(
[email protected]bb88e1d32013-05-03 23:11:0713082 int error, IoMode mode) {
ttuttle859dc7a2015-04-23 19:42:2913083 HttpRequestInfo request_info;
[email protected]cb9bf6ca2011-01-28 13:15:2713084 request_info.url = GURL("https://www.example.com/");
13085 request_info.method = "GET";
ttuttle859dc7a2015-04-23 19:42:2913086 request_info.load_flags = LOAD_NORMAL;
[email protected]cb9bf6ca2011-01-28 13:15:2713087
[email protected]8ddf8322012-02-23 18:08:0613088 SSLSocketDataProvider ssl_data(mode, OK);
ttuttle859dc7a2015-04-23 19:42:2913089 MockWrite data_writes[] = {
13090 MockWrite(mode, error),
[email protected]73b8dd222010-11-11 19:55:2413091 };
ttuttle859dc7a2015-04-23 19:42:2913092 StaticSocketDataProvider data(NULL, 0, data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:0713093 session_deps_.socket_factory->AddSocketDataProvider(&data);
13094 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data);
[email protected]73b8dd222010-11-11 19:55:2413095
danakj1fd259a02016-04-16 03:17:0913096 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1613097 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]73b8dd222010-11-11 19:55:2413098
[email protected]49639fa2011-12-20 23:22:4113099 TestCompletionCallback callback;
tfarina42834112016-09-22 13:38:2013100 int rv = trans.Start(&request_info, callback.callback(), NetLogWithSource());
ttuttle859dc7a2015-04-23 19:42:2913101 if (rv == ERR_IO_PENDING)
[email protected]73b8dd222010-11-11 19:55:2413102 rv = callback.WaitForResult();
13103 ASSERT_EQ(error, rv);
13104}
13105
bncd16676a2016-07-20 16:23:0113106TEST_F(HttpNetworkTransactionTest, SSLWriteCertError) {
[email protected]73b8dd222010-11-11 19:55:2413107 // Just check a grab bag of cert errors.
13108 static const int kErrors[] = {
13109 ERR_CERT_COMMON_NAME_INVALID,
13110 ERR_CERT_AUTHORITY_INVALID,
13111 ERR_CERT_DATE_INVALID,
13112 };
13113 for (size_t i = 0; i < arraysize(kErrors); i++) {
[email protected]8ddf8322012-02-23 18:08:0613114 CheckErrorIsPassedBack(kErrors[i], ASYNC);
13115 CheckErrorIsPassedBack(kErrors[i], SYNCHRONOUS);
[email protected]73b8dd222010-11-11 19:55:2413116 }
13117}
13118
[email protected]bd0b6772011-01-11 19:59:3013119// Ensure that a client certificate is removed from the SSL client auth
13120// cache when:
13121// 1) No proxy is involved.
13122// 2) TLS False Start is disabled.
13123// 3) The initial TLS handshake requests a client certificate.
13124// 4) The client supplies an invalid/unacceptable certificate.
bncd16676a2016-07-20 16:23:0113125TEST_F(HttpNetworkTransactionTest, ClientAuthCertCache_Direct_NoFalseStart) {
ttuttle859dc7a2015-04-23 19:42:2913126 HttpRequestInfo request_info;
[email protected]cb9bf6ca2011-01-28 13:15:2713127 request_info.url = GURL("https://www.example.com/");
13128 request_info.method = "GET";
ttuttle859dc7a2015-04-23 19:42:2913129 request_info.load_flags = LOAD_NORMAL;
[email protected]cb9bf6ca2011-01-28 13:15:2713130
[email protected]bd0b6772011-01-11 19:59:3013131 scoped_refptr<SSLCertRequestInfo> cert_request(new SSLCertRequestInfo());
[email protected]791879c2013-12-17 07:22:4113132 cert_request->host_and_port = HostPortPair("www.example.com", 443);
[email protected]bd0b6772011-01-11 19:59:3013133
13134 // [ssl_]data1 contains the data for the first SSL handshake. When a
13135 // CertificateRequest is received for the first time, the handshake will
13136 // be aborted to allow the caller to provide a certificate.
ttuttle859dc7a2015-04-23 19:42:2913137 SSLSocketDataProvider ssl_data1(ASYNC, ERR_SSL_CLIENT_AUTH_CERT_NEEDED);
[email protected]bd0b6772011-01-11 19:59:3013138 ssl_data1.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0713139 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data1);
ttuttle859dc7a2015-04-23 19:42:2913140 StaticSocketDataProvider data1(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0713141 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]bd0b6772011-01-11 19:59:3013142
13143 // [ssl_]data2 contains the data for the second SSL handshake. When TLS
13144 // False Start is not being used, the result of the SSL handshake will be
13145 // returned as part of the SSLClientSocket::Connect() call. This test
13146 // matches the result of a server sending a handshake_failure alert,
13147 // rather than a Finished message, because it requires a client
13148 // certificate and none was supplied.
ttuttle859dc7a2015-04-23 19:42:2913149 SSLSocketDataProvider ssl_data2(ASYNC, ERR_SSL_PROTOCOL_ERROR);
[email protected]bd0b6772011-01-11 19:59:3013150 ssl_data2.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0713151 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data2);
ttuttle859dc7a2015-04-23 19:42:2913152 StaticSocketDataProvider data2(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0713153 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]bd0b6772011-01-11 19:59:3013154
13155 // [ssl_]data3 contains the data for the third SSL handshake. When a
13156 // connection to a server fails during an SSL handshake,
davidbenb937d6c2015-05-14 04:53:4213157 // HttpNetworkTransaction will attempt to fallback to TLSv1.1 if the previous
13158 // connection was attempted with TLSv1.2. This is transparent to the caller
[email protected]bd0b6772011-01-11 19:59:3013159 // of the HttpNetworkTransaction. Because this test failure is due to
13160 // requiring a client certificate, this fallback handshake should also
13161 // fail.
ttuttle859dc7a2015-04-23 19:42:2913162 SSLSocketDataProvider ssl_data3(ASYNC, ERR_SSL_PROTOCOL_ERROR);
[email protected]bd0b6772011-01-11 19:59:3013163 ssl_data3.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0713164 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data3);
ttuttle859dc7a2015-04-23 19:42:2913165 StaticSocketDataProvider data3(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0713166 session_deps_.socket_factory->AddSocketDataProvider(&data3);
[email protected]bd0b6772011-01-11 19:59:3013167
[email protected]80c75f682012-05-26 16:22:1713168 // [ssl_]data4 contains the data for the fourth SSL handshake. When a
13169 // connection to a server fails during an SSL handshake,
davidbenb937d6c2015-05-14 04:53:4213170 // HttpNetworkTransaction will attempt to fallback to TLSv1 if the previous
13171 // connection was attempted with TLSv1.1. This is transparent to the caller
[email protected]80c75f682012-05-26 16:22:1713172 // of the HttpNetworkTransaction. Because this test failure is due to
13173 // requiring a client certificate, this fallback handshake should also
13174 // fail.
ttuttle859dc7a2015-04-23 19:42:2913175 SSLSocketDataProvider ssl_data4(ASYNC, ERR_SSL_PROTOCOL_ERROR);
[email protected]80c75f682012-05-26 16:22:1713176 ssl_data4.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0713177 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data4);
ttuttle859dc7a2015-04-23 19:42:2913178 StaticSocketDataProvider data4(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0713179 session_deps_.socket_factory->AddSocketDataProvider(&data4);
[email protected]80c75f682012-05-26 16:22:1713180
danakj1fd259a02016-04-16 03:17:0913181 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1613182 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]bd0b6772011-01-11 19:59:3013183
[email protected]bd0b6772011-01-11 19:59:3013184 // Begin the SSL handshake with the peer. This consumes ssl_data1.
[email protected]49639fa2011-12-20 23:22:4113185 TestCompletionCallback callback;
tfarina42834112016-09-22 13:38:2013186 int rv = trans.Start(&request_info, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0113187 ASSERT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]bd0b6772011-01-11 19:59:3013188
13189 // Complete the SSL handshake, which should abort due to requiring a
13190 // client certificate.
13191 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0113192 ASSERT_THAT(rv, IsError(ERR_SSL_CLIENT_AUTH_CERT_NEEDED));
[email protected]bd0b6772011-01-11 19:59:3013193
13194 // Indicate that no certificate should be supplied. From the perspective
13195 // of SSLClientCertCache, NULL is just as meaningful as a real
13196 // certificate, so this is the same as supply a
13197 // legitimate-but-unacceptable certificate.
bnc691fda62016-08-12 00:43:1613198 rv = trans.RestartWithCertificate(NULL, NULL, callback.callback());
robpercival214763f2016-07-01 23:27:0113199 ASSERT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]bd0b6772011-01-11 19:59:3013200
13201 // Ensure the certificate was added to the client auth cache before
13202 // allowing the connection to continue restarting.
13203 scoped_refptr<X509Certificate> client_cert;
svaldez7872fd02015-11-19 21:10:5413204 scoped_refptr<SSLPrivateKey> client_private_key;
[email protected]791879c2013-12-17 07:22:4113205 ASSERT_TRUE(session->ssl_client_auth_cache()->Lookup(
svaldez7872fd02015-11-19 21:10:5413206 HostPortPair("www.example.com", 443), &client_cert, &client_private_key));
wezca1070932016-05-26 20:30:5213207 ASSERT_FALSE(client_cert);
[email protected]bd0b6772011-01-11 19:59:3013208
13209 // Restart the handshake. This will consume ssl_data2, which fails, and
[email protected]80c75f682012-05-26 16:22:1713210 // then consume ssl_data3 and ssl_data4, both of which should also fail.
13211 // The result code is checked against what ssl_data4 should return.
[email protected]bd0b6772011-01-11 19:59:3013212 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0113213 ASSERT_THAT(rv, IsError(ERR_SSL_PROTOCOL_ERROR));
[email protected]bd0b6772011-01-11 19:59:3013214
13215 // Ensure that the client certificate is removed from the cache on a
13216 // handshake failure.
[email protected]791879c2013-12-17 07:22:4113217 ASSERT_FALSE(session->ssl_client_auth_cache()->Lookup(
svaldez7872fd02015-11-19 21:10:5413218 HostPortPair("www.example.com", 443), &client_cert, &client_private_key));
[email protected]bd0b6772011-01-11 19:59:3013219}
13220
13221// Ensure that a client certificate is removed from the SSL client auth
13222// cache when:
13223// 1) No proxy is involved.
13224// 2) TLS False Start is enabled.
13225// 3) The initial TLS handshake requests a client certificate.
13226// 4) The client supplies an invalid/unacceptable certificate.
bncd16676a2016-07-20 16:23:0113227TEST_F(HttpNetworkTransactionTest, ClientAuthCertCache_Direct_FalseStart) {
ttuttle859dc7a2015-04-23 19:42:2913228 HttpRequestInfo request_info;
[email protected]cb9bf6ca2011-01-28 13:15:2713229 request_info.url = GURL("https://www.example.com/");
13230 request_info.method = "GET";
ttuttle859dc7a2015-04-23 19:42:2913231 request_info.load_flags = LOAD_NORMAL;
[email protected]cb9bf6ca2011-01-28 13:15:2713232
[email protected]bd0b6772011-01-11 19:59:3013233 scoped_refptr<SSLCertRequestInfo> cert_request(new SSLCertRequestInfo());
[email protected]791879c2013-12-17 07:22:4113234 cert_request->host_and_port = HostPortPair("www.example.com", 443);
[email protected]bd0b6772011-01-11 19:59:3013235
13236 // When TLS False Start is used, SSLClientSocket::Connect() calls will
13237 // return successfully after reading up to the peer's Certificate message.
13238 // This is to allow the caller to call SSLClientSocket::Write(), which can
13239 // enqueue application data to be sent in the same packet as the
13240 // ChangeCipherSpec and Finished messages.
13241 // The actual handshake will be finished when SSLClientSocket::Read() is
13242 // called, which expects to process the peer's ChangeCipherSpec and
13243 // Finished messages. If there was an error negotiating with the peer,
13244 // such as due to the peer requiring a client certificate when none was
13245 // supplied, the alert sent by the peer won't be processed until Read() is
13246 // called.
13247
13248 // Like the non-False Start case, when a client certificate is requested by
13249 // the peer, the handshake is aborted during the Connect() call.
13250 // [ssl_]data1 represents the initial SSL handshake with the peer.
ttuttle859dc7a2015-04-23 19:42:2913251 SSLSocketDataProvider ssl_data1(ASYNC, ERR_SSL_CLIENT_AUTH_CERT_NEEDED);
[email protected]bd0b6772011-01-11 19:59:3013252 ssl_data1.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0713253 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data1);
ttuttle859dc7a2015-04-23 19:42:2913254 StaticSocketDataProvider data1(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0713255 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]bd0b6772011-01-11 19:59:3013256
13257 // When a client certificate is supplied, Connect() will not be aborted
13258 // when the peer requests the certificate. Instead, the handshake will
13259 // artificially succeed, allowing the caller to write the HTTP request to
13260 // the socket. The handshake messages are not processed until Read() is
13261 // called, which then detects that the handshake was aborted, due to the
13262 // peer sending a handshake_failure because it requires a client
13263 // certificate.
ttuttle859dc7a2015-04-23 19:42:2913264 SSLSocketDataProvider ssl_data2(ASYNC, OK);
[email protected]bd0b6772011-01-11 19:59:3013265 ssl_data2.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0713266 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data2);
ttuttle859dc7a2015-04-23 19:42:2913267 MockRead data2_reads[] = {
13268 MockRead(ASYNC /* async */, ERR_SSL_PROTOCOL_ERROR),
[email protected]bd0b6772011-01-11 19:59:3013269 };
ttuttle859dc7a2015-04-23 19:42:2913270 StaticSocketDataProvider data2(data2_reads, arraysize(data2_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0713271 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]bd0b6772011-01-11 19:59:3013272
13273 // As described in ClientAuthCertCache_Direct_NoFalseStart, [ssl_]data3 is
[email protected]80c75f682012-05-26 16:22:1713274 // the data for the SSL handshake once the TLSv1.1 connection falls back to
13275 // TLSv1. It has the same behaviour as [ssl_]data2.
ttuttle859dc7a2015-04-23 19:42:2913276 SSLSocketDataProvider ssl_data3(ASYNC, OK);
[email protected]bd0b6772011-01-11 19:59:3013277 ssl_data3.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0713278 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data3);
ttuttle859dc7a2015-04-23 19:42:2913279 StaticSocketDataProvider data3(data2_reads, arraysize(data2_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0713280 session_deps_.socket_factory->AddSocketDataProvider(&data3);
[email protected]bd0b6772011-01-11 19:59:3013281
[email protected]80c75f682012-05-26 16:22:1713282 // [ssl_]data4 is the data for the SSL handshake once the TLSv1 connection
13283 // falls back to SSLv3. It has the same behaviour as [ssl_]data2.
ttuttle859dc7a2015-04-23 19:42:2913284 SSLSocketDataProvider ssl_data4(ASYNC, OK);
[email protected]80c75f682012-05-26 16:22:1713285 ssl_data4.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0713286 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data4);
ttuttle859dc7a2015-04-23 19:42:2913287 StaticSocketDataProvider data4(data2_reads, arraysize(data2_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0713288 session_deps_.socket_factory->AddSocketDataProvider(&data4);
[email protected]80c75f682012-05-26 16:22:1713289
[email protected]7799de12013-05-30 05:52:5113290 // Need one more if TLSv1.2 is enabled.
ttuttle859dc7a2015-04-23 19:42:2913291 SSLSocketDataProvider ssl_data5(ASYNC, OK);
[email protected]7799de12013-05-30 05:52:5113292 ssl_data5.cert_request_info = cert_request.get();
13293 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data5);
ttuttle859dc7a2015-04-23 19:42:2913294 StaticSocketDataProvider data5(data2_reads, arraysize(data2_reads), NULL, 0);
[email protected]7799de12013-05-30 05:52:5113295 session_deps_.socket_factory->AddSocketDataProvider(&data5);
13296
danakj1fd259a02016-04-16 03:17:0913297 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1613298 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]bd0b6772011-01-11 19:59:3013299
[email protected]bd0b6772011-01-11 19:59:3013300 // Begin the initial SSL handshake.
[email protected]49639fa2011-12-20 23:22:4113301 TestCompletionCallback callback;
tfarina42834112016-09-22 13:38:2013302 int rv = trans.Start(&request_info, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0113303 ASSERT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]bd0b6772011-01-11 19:59:3013304
13305 // Complete the SSL handshake, which should abort due to requiring a
13306 // client certificate.
13307 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0113308 ASSERT_THAT(rv, IsError(ERR_SSL_CLIENT_AUTH_CERT_NEEDED));
[email protected]bd0b6772011-01-11 19:59:3013309
13310 // Indicate that no certificate should be supplied. From the perspective
13311 // of SSLClientCertCache, NULL is just as meaningful as a real
13312 // certificate, so this is the same as supply a
13313 // legitimate-but-unacceptable certificate.
bnc691fda62016-08-12 00:43:1613314 rv = trans.RestartWithCertificate(NULL, NULL, callback.callback());
robpercival214763f2016-07-01 23:27:0113315 ASSERT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]bd0b6772011-01-11 19:59:3013316
13317 // Ensure the certificate was added to the client auth cache before
13318 // allowing the connection to continue restarting.
13319 scoped_refptr<X509Certificate> client_cert;
svaldez7872fd02015-11-19 21:10:5413320 scoped_refptr<SSLPrivateKey> client_private_key;
[email protected]791879c2013-12-17 07:22:4113321 ASSERT_TRUE(session->ssl_client_auth_cache()->Lookup(
svaldez7872fd02015-11-19 21:10:5413322 HostPortPair("www.example.com", 443), &client_cert, &client_private_key));
wezca1070932016-05-26 20:30:5213323 ASSERT_FALSE(client_cert);
[email protected]bd0b6772011-01-11 19:59:3013324
[email protected]bd0b6772011-01-11 19:59:3013325 // Restart the handshake. This will consume ssl_data2, which fails, and
[email protected]80c75f682012-05-26 16:22:1713326 // then consume ssl_data3 and ssl_data4, both of which should also fail.
13327 // The result code is checked against what ssl_data4 should return.
[email protected]bd0b6772011-01-11 19:59:3013328 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0113329 ASSERT_THAT(rv, IsError(ERR_SSL_PROTOCOL_ERROR));
[email protected]bd0b6772011-01-11 19:59:3013330
13331 // Ensure that the client certificate is removed from the cache on a
13332 // handshake failure.
[email protected]791879c2013-12-17 07:22:4113333 ASSERT_FALSE(session->ssl_client_auth_cache()->Lookup(
svaldez7872fd02015-11-19 21:10:5413334 HostPortPair("www.example.com", 443), &client_cert, &client_private_key));
[email protected]bd0b6772011-01-11 19:59:3013335}
13336
[email protected]8c405132011-01-11 22:03:1813337// Ensure that a client certificate is removed from the SSL client auth
13338// cache when:
13339// 1) An HTTPS proxy is involved.
13340// 3) The HTTPS proxy requests a client certificate.
13341// 4) The client supplies an invalid/unacceptable certificate for the
13342// proxy.
13343// The test is repeated twice, first for connecting to an HTTPS endpoint,
13344// then for connecting to an HTTP endpoint.
bncd16676a2016-07-20 16:23:0113345TEST_F(HttpNetworkTransactionTest, ClientAuthCertCache_Proxy_Fail) {
rdsmith82957ad2015-09-16 19:42:0313346 session_deps_.proxy_service = ProxyService::CreateFixed("https://proxy:70");
vishal.b62985ca92015-04-17 08:45:5113347 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:0713348 session_deps_.net_log = log.bound().net_log();
[email protected]8c405132011-01-11 22:03:1813349
13350 scoped_refptr<SSLCertRequestInfo> cert_request(new SSLCertRequestInfo());
[email protected]791879c2013-12-17 07:22:4113351 cert_request->host_and_port = HostPortPair("proxy", 70);
[email protected]8c405132011-01-11 22:03:1813352
13353 // See ClientAuthCertCache_Direct_NoFalseStart for the explanation of
13354 // [ssl_]data[1-3]. Rather than represending the endpoint
13355 // (www.example.com:443), they represent failures with the HTTPS proxy
13356 // (proxy:70).
ttuttle859dc7a2015-04-23 19:42:2913357 SSLSocketDataProvider ssl_data1(ASYNC, ERR_SSL_CLIENT_AUTH_CERT_NEEDED);
[email protected]8c405132011-01-11 22:03:1813358 ssl_data1.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0713359 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data1);
ttuttle859dc7a2015-04-23 19:42:2913360 StaticSocketDataProvider data1(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0713361 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8c405132011-01-11 22:03:1813362
ttuttle859dc7a2015-04-23 19:42:2913363 SSLSocketDataProvider ssl_data2(ASYNC, ERR_SSL_PROTOCOL_ERROR);
[email protected]8c405132011-01-11 22:03:1813364 ssl_data2.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0713365 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data2);
ttuttle859dc7a2015-04-23 19:42:2913366 StaticSocketDataProvider data2(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0713367 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]8c405132011-01-11 22:03:1813368
[email protected]80c75f682012-05-26 16:22:1713369 // TODO(wtc): find out why this unit test doesn't need [ssl_]data3.
13370#if 0
ttuttle859dc7a2015-04-23 19:42:2913371 SSLSocketDataProvider ssl_data3(ASYNC, ERR_SSL_PROTOCOL_ERROR);
[email protected]8c405132011-01-11 22:03:1813372 ssl_data3.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0713373 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data3);
ttuttle859dc7a2015-04-23 19:42:2913374 StaticSocketDataProvider data3(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0713375 session_deps_.socket_factory->AddSocketDataProvider(&data3);
[email protected]80c75f682012-05-26 16:22:1713376#endif
[email protected]8c405132011-01-11 22:03:1813377
ttuttle859dc7a2015-04-23 19:42:2913378 HttpRequestInfo requests[2];
[email protected]8c405132011-01-11 22:03:1813379 requests[0].url = GURL("https://www.example.com/");
13380 requests[0].method = "GET";
ttuttle859dc7a2015-04-23 19:42:2913381 requests[0].load_flags = LOAD_NORMAL;
[email protected]8c405132011-01-11 22:03:1813382
13383 requests[1].url = GURL("http://www.example.com/");
13384 requests[1].method = "GET";
ttuttle859dc7a2015-04-23 19:42:2913385 requests[1].load_flags = LOAD_NORMAL;
[email protected]8c405132011-01-11 22:03:1813386
13387 for (size_t i = 0; i < arraysize(requests); ++i) {
[email protected]bb88e1d32013-05-03 23:11:0713388 session_deps_.socket_factory->ResetNextMockIndexes();
danakj1fd259a02016-04-16 03:17:0913389 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1613390 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]8c405132011-01-11 22:03:1813391
13392 // Begin the SSL handshake with the proxy.
[email protected]49639fa2011-12-20 23:22:4113393 TestCompletionCallback callback;
tfarina42834112016-09-22 13:38:2013394 int rv = trans.Start(&requests[i], callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0113395 ASSERT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]8c405132011-01-11 22:03:1813396
13397 // Complete the SSL handshake, which should abort due to requiring a
13398 // client certificate.
13399 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0113400 ASSERT_THAT(rv, IsError(ERR_SSL_CLIENT_AUTH_CERT_NEEDED));
[email protected]8c405132011-01-11 22:03:1813401
13402 // Indicate that no certificate should be supplied. From the perspective
13403 // of SSLClientCertCache, NULL is just as meaningful as a real
13404 // certificate, so this is the same as supply a
13405 // legitimate-but-unacceptable certificate.
bnc691fda62016-08-12 00:43:1613406 rv = trans.RestartWithCertificate(NULL, NULL, callback.callback());
robpercival214763f2016-07-01 23:27:0113407 ASSERT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]8c405132011-01-11 22:03:1813408
13409 // Ensure the certificate was added to the client auth cache before
13410 // allowing the connection to continue restarting.
13411 scoped_refptr<X509Certificate> client_cert;
svaldez7872fd02015-11-19 21:10:5413412 scoped_refptr<SSLPrivateKey> client_private_key;
[email protected]791879c2013-12-17 07:22:4113413 ASSERT_TRUE(session->ssl_client_auth_cache()->Lookup(
svaldez7872fd02015-11-19 21:10:5413414 HostPortPair("proxy", 70), &client_cert, &client_private_key));
wezca1070932016-05-26 20:30:5213415 ASSERT_FALSE(client_cert);
[email protected]8c405132011-01-11 22:03:1813416 // Ensure the certificate was NOT cached for the endpoint. This only
13417 // applies to HTTPS requests, but is fine to check for HTTP requests.
[email protected]791879c2013-12-17 07:22:4113418 ASSERT_FALSE(session->ssl_client_auth_cache()->Lookup(
svaldez7872fd02015-11-19 21:10:5413419 HostPortPair("www.example.com", 443), &client_cert,
13420 &client_private_key));
[email protected]8c405132011-01-11 22:03:1813421
13422 // Restart the handshake. This will consume ssl_data2, which fails, and
13423 // then consume ssl_data3, which should also fail. The result code is
13424 // checked against what ssl_data3 should return.
13425 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0113426 ASSERT_THAT(rv, IsError(ERR_PROXY_CONNECTION_FAILED));
[email protected]8c405132011-01-11 22:03:1813427
13428 // Now that the new handshake has failed, ensure that the client
13429 // certificate was removed from the client auth cache.
[email protected]791879c2013-12-17 07:22:4113430 ASSERT_FALSE(session->ssl_client_auth_cache()->Lookup(
svaldez7872fd02015-11-19 21:10:5413431 HostPortPair("proxy", 70), &client_cert, &client_private_key));
[email protected]791879c2013-12-17 07:22:4113432 ASSERT_FALSE(session->ssl_client_auth_cache()->Lookup(
svaldez7872fd02015-11-19 21:10:5413433 HostPortPair("www.example.com", 443), &client_cert,
13434 &client_private_key));
[email protected]8c405132011-01-11 22:03:1813435 }
13436}
13437
bncd16676a2016-07-20 16:23:0113438TEST_F(HttpNetworkTransactionTest, UseIPConnectionPooling) {
[email protected]e3ceb682011-06-28 23:55:4613439 // Set up a special HttpNetworkSession with a MockCachingHostResolver.
[email protected]bb88e1d32013-05-03 23:11:0713440 session_deps_.host_resolver.reset(new MockCachingHostResolver());
danakj1fd259a02016-04-16 03:17:0913441 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]e3ceb682011-06-28 23:55:4613442
bnc032658ba2016-09-26 18:17:1513443 AddSSLSocketData();
[email protected]e3ceb682011-06-28 23:55:4613444
bncdf80d44fd2016-07-15 20:27:4113445 SpdySerializedFrame host1_req(
bnc38dcd392016-02-09 23:19:4913446 spdy_util_.ConstructSpdyGet("https://www.example.org", 1, LOWEST));
rdsmithebb50aa2015-11-12 03:44:3813447 spdy_util_.UpdateWithStreamDestruction(1);
bncdf80d44fd2016-07-15 20:27:4113448 SpdySerializedFrame host2_req(
bnca4d611d2016-09-22 19:55:3713449 spdy_util_.ConstructSpdyGet("https://mail.example.com", 3, LOWEST));
[email protected]e3ceb682011-06-28 23:55:4613450 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:4113451 CreateMockWrite(host1_req, 0), CreateMockWrite(host2_req, 3),
[email protected]e3ceb682011-06-28 23:55:4613452 };
bnc42331402016-07-25 13:36:1513453 SpdySerializedFrame host1_resp(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
bncdf80d44fd2016-07-15 20:27:4113454 SpdySerializedFrame host1_resp_body(
13455 spdy_util_.ConstructSpdyDataFrame(1, true));
bnc42331402016-07-25 13:36:1513456 SpdySerializedFrame host2_resp(spdy_util_.ConstructSpdyGetReply(NULL, 0, 3));
bncdf80d44fd2016-07-15 20:27:4113457 SpdySerializedFrame host2_resp_body(
13458 spdy_util_.ConstructSpdyDataFrame(3, true));
[email protected]e3ceb682011-06-28 23:55:4613459 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:4113460 CreateMockRead(host1_resp, 1), CreateMockRead(host1_resp_body, 2),
13461 CreateMockRead(host2_resp, 4), CreateMockRead(host2_resp_body, 5),
rch8e6c6c42015-05-01 14:05:1313462 MockRead(ASYNC, 0, 6),
[email protected]e3ceb682011-06-28 23:55:4613463 };
13464
eroman36d84e54432016-03-17 03:23:0213465 IPEndPoint peer_addr(IPAddress::IPv4Localhost(), 443);
[email protected]d2b5f092012-06-08 23:55:0213466 MockConnect connect(ASYNC, OK, peer_addr);
rch8e6c6c42015-05-01 14:05:1313467 SequencedSocketData spdy_data(connect, spdy_reads, arraysize(spdy_reads),
13468 spdy_writes, arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:0713469 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]e3ceb682011-06-28 23:55:4613470
[email protected]aa22b242011-11-16 18:58:2913471 TestCompletionCallback callback;
[email protected]e3ceb682011-06-28 23:55:4613472 HttpRequestInfo request1;
13473 request1.method = "GET";
bncce36dca22015-04-21 22:11:2313474 request1.url = GURL("https://www.example.org/");
[email protected]e3ceb682011-06-28 23:55:4613475 request1.load_flags = 0;
[email protected]90499482013-06-01 00:39:5013476 HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
[email protected]e3ceb682011-06-28 23:55:4613477
tfarina42834112016-09-22 13:38:2013478 int rv = trans1.Start(&request1, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0113479 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
13480 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]e3ceb682011-06-28 23:55:4613481
13482 const HttpResponseInfo* response = trans1.GetResponseInfo();
wezca1070932016-05-26 20:30:5213483 ASSERT_TRUE(response);
13484 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0213485 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]e3ceb682011-06-28 23:55:4613486
13487 std::string response_data;
robpercival214763f2016-07-01 23:27:0113488 ASSERT_THAT(ReadTransaction(&trans1, &response_data), IsOk());
[email protected]e3ceb682011-06-28 23:55:4613489 EXPECT_EQ("hello!", response_data);
13490
bnca4d611d2016-09-22 19:55:3713491 // Preload mail.example.com into HostCache.
13492 HostPortPair host_port("mail.example.com", 443);
[email protected]5109c1952013-08-20 18:44:1013493 HostResolver::RequestInfo resolve_info(host_port);
[email protected]e3ceb682011-06-28 23:55:4613494 AddressList ignored;
maksim.sisov31452af2016-07-27 06:38:1013495 std::unique_ptr<HostResolver::Request> request;
13496 rv = session_deps_.host_resolver->Resolve(resolve_info, DEFAULT_PRIORITY,
13497 &ignored, callback.callback(),
tfarina42834112016-09-22 13:38:2013498 &request, NetLogWithSource());
robpercival214763f2016-07-01 23:27:0113499 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]6e78dfb2011-07-28 21:34:4713500 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0113501 EXPECT_THAT(rv, IsOk());
[email protected]e3ceb682011-06-28 23:55:4613502
13503 HttpRequestInfo request2;
13504 request2.method = "GET";
bnca4d611d2016-09-22 19:55:3713505 request2.url = GURL("https://mail.example.com/");
[email protected]e3ceb682011-06-28 23:55:4613506 request2.load_flags = 0;
[email protected]90499482013-06-01 00:39:5013507 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
[email protected]e3ceb682011-06-28 23:55:4613508
tfarina42834112016-09-22 13:38:2013509 rv = trans2.Start(&request2, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0113510 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
13511 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]e3ceb682011-06-28 23:55:4613512
13513 response = trans2.GetResponseInfo();
wezca1070932016-05-26 20:30:5213514 ASSERT_TRUE(response);
13515 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0213516 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]e3ceb682011-06-28 23:55:4613517 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5213518 EXPECT_TRUE(response->was_alpn_negotiated);
robpercival214763f2016-07-01 23:27:0113519 ASSERT_THAT(ReadTransaction(&trans2, &response_data), IsOk());
[email protected]e3ceb682011-06-28 23:55:4613520 EXPECT_EQ("hello!", response_data);
[email protected]e3ceb682011-06-28 23:55:4613521}
13522
bncd16676a2016-07-20 16:23:0113523TEST_F(HttpNetworkTransactionTest, UseIPConnectionPoolingAfterResolution) {
[email protected]d2b5f092012-06-08 23:55:0213524 // Set up a special HttpNetworkSession with a MockCachingHostResolver.
[email protected]bb88e1d32013-05-03 23:11:0713525 session_deps_.host_resolver.reset(new MockCachingHostResolver());
danakj1fd259a02016-04-16 03:17:0913526 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]d2b5f092012-06-08 23:55:0213527
bnc032658ba2016-09-26 18:17:1513528 AddSSLSocketData();
[email protected]d2b5f092012-06-08 23:55:0213529
bncdf80d44fd2016-07-15 20:27:4113530 SpdySerializedFrame host1_req(
bnc38dcd392016-02-09 23:19:4913531 spdy_util_.ConstructSpdyGet("https://www.example.org", 1, LOWEST));
rdsmithebb50aa2015-11-12 03:44:3813532 spdy_util_.UpdateWithStreamDestruction(1);
bncdf80d44fd2016-07-15 20:27:4113533 SpdySerializedFrame host2_req(
bnca4d611d2016-09-22 19:55:3713534 spdy_util_.ConstructSpdyGet("https://mail.example.com", 3, LOWEST));
[email protected]d2b5f092012-06-08 23:55:0213535 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:4113536 CreateMockWrite(host1_req, 0), CreateMockWrite(host2_req, 3),
[email protected]d2b5f092012-06-08 23:55:0213537 };
bnc42331402016-07-25 13:36:1513538 SpdySerializedFrame host1_resp(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
bncdf80d44fd2016-07-15 20:27:4113539 SpdySerializedFrame host1_resp_body(
13540 spdy_util_.ConstructSpdyDataFrame(1, true));
bnc42331402016-07-25 13:36:1513541 SpdySerializedFrame host2_resp(spdy_util_.ConstructSpdyGetReply(NULL, 0, 3));
bncdf80d44fd2016-07-15 20:27:4113542 SpdySerializedFrame host2_resp_body(
13543 spdy_util_.ConstructSpdyDataFrame(3, true));
[email protected]d2b5f092012-06-08 23:55:0213544 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:4113545 CreateMockRead(host1_resp, 1), CreateMockRead(host1_resp_body, 2),
13546 CreateMockRead(host2_resp, 4), CreateMockRead(host2_resp_body, 5),
rch8e6c6c42015-05-01 14:05:1313547 MockRead(ASYNC, 0, 6),
[email protected]d2b5f092012-06-08 23:55:0213548 };
13549
eroman36d84e54432016-03-17 03:23:0213550 IPEndPoint peer_addr(IPAddress::IPv4Localhost(), 443);
[email protected]d2b5f092012-06-08 23:55:0213551 MockConnect connect(ASYNC, OK, peer_addr);
rch8e6c6c42015-05-01 14:05:1313552 SequencedSocketData spdy_data(connect, spdy_reads, arraysize(spdy_reads),
13553 spdy_writes, arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:0713554 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]d2b5f092012-06-08 23:55:0213555
13556 TestCompletionCallback callback;
13557 HttpRequestInfo request1;
13558 request1.method = "GET";
bncce36dca22015-04-21 22:11:2313559 request1.url = GURL("https://www.example.org/");
[email protected]d2b5f092012-06-08 23:55:0213560 request1.load_flags = 0;
[email protected]90499482013-06-01 00:39:5013561 HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
[email protected]d2b5f092012-06-08 23:55:0213562
tfarina42834112016-09-22 13:38:2013563 int rv = trans1.Start(&request1, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0113564 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
13565 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]d2b5f092012-06-08 23:55:0213566
13567 const HttpResponseInfo* response = trans1.GetResponseInfo();
wezca1070932016-05-26 20:30:5213568 ASSERT_TRUE(response);
13569 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0213570 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]d2b5f092012-06-08 23:55:0213571
13572 std::string response_data;
robpercival214763f2016-07-01 23:27:0113573 ASSERT_THAT(ReadTransaction(&trans1, &response_data), IsOk());
[email protected]d2b5f092012-06-08 23:55:0213574 EXPECT_EQ("hello!", response_data);
13575
13576 HttpRequestInfo request2;
13577 request2.method = "GET";
bnca4d611d2016-09-22 19:55:3713578 request2.url = GURL("https://mail.example.com/");
[email protected]d2b5f092012-06-08 23:55:0213579 request2.load_flags = 0;
[email protected]90499482013-06-01 00:39:5013580 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
[email protected]d2b5f092012-06-08 23:55:0213581
tfarina42834112016-09-22 13:38:2013582 rv = trans2.Start(&request2, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0113583 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
13584 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]d2b5f092012-06-08 23:55:0213585
13586 response = trans2.GetResponseInfo();
wezca1070932016-05-26 20:30:5213587 ASSERT_TRUE(response);
13588 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0213589 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]d2b5f092012-06-08 23:55:0213590 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5213591 EXPECT_TRUE(response->was_alpn_negotiated);
robpercival214763f2016-07-01 23:27:0113592 ASSERT_THAT(ReadTransaction(&trans2, &response_data), IsOk());
[email protected]d2b5f092012-06-08 23:55:0213593 EXPECT_EQ("hello!", response_data);
[email protected]d2b5f092012-06-08 23:55:0213594}
13595
ttuttle859dc7a2015-04-23 19:42:2913596class OneTimeCachingHostResolver : public HostResolver {
[email protected]e3ceb682011-06-28 23:55:4613597 public:
13598 explicit OneTimeCachingHostResolver(const HostPortPair& host_port)
13599 : host_port_(host_port) {}
dchengb03027d2014-10-21 12:00:2013600 ~OneTimeCachingHostResolver() override {}
[email protected]e3ceb682011-06-28 23:55:4613601
13602 RuleBasedHostResolverProc* rules() { return host_resolver_.rules(); }
13603
13604 // HostResolver methods:
dchengb03027d2014-10-21 12:00:2013605 int Resolve(const RequestInfo& info,
13606 RequestPriority priority,
13607 AddressList* addresses,
13608 const CompletionCallback& callback,
maksim.sisov31452af2016-07-27 06:38:1013609 std::unique_ptr<Request>* out_req,
tfarina42834112016-09-22 13:38:2013610 const NetLogWithSource& net_log) override {
[email protected]95a214c2011-08-04 21:50:4013611 return host_resolver_.Resolve(
[email protected]5109c1952013-08-20 18:44:1013612 info, priority, addresses, callback, out_req, net_log);
[email protected]95a214c2011-08-04 21:50:4013613 }
13614
dchengb03027d2014-10-21 12:00:2013615 int ResolveFromCache(const RequestInfo& info,
13616 AddressList* addresses,
tfarina42834112016-09-22 13:38:2013617 const NetLogWithSource& net_log) override {
[email protected]95a214c2011-08-04 21:50:4013618 int rv = host_resolver_.ResolveFromCache(info, addresses, net_log);
13619 if (rv == OK && info.host_port_pair().Equals(host_port_))
[email protected]98e1cd012011-11-08 15:33:0913620 host_resolver_.GetHostCache()->clear();
[email protected]e3ceb682011-06-28 23:55:4613621 return rv;
13622 }
13623
[email protected]46da33be2011-07-19 21:58:0413624 MockCachingHostResolver* GetMockHostResolver() {
13625 return &host_resolver_;
13626 }
13627
[email protected]e3ceb682011-06-28 23:55:4613628 private:
13629 MockCachingHostResolver host_resolver_;
13630 const HostPortPair host_port_;
13631};
13632
bncd16676a2016-07-20 16:23:0113633TEST_F(HttpNetworkTransactionTest,
mmenke5c642132015-06-02 16:05:1313634 UseIPConnectionPoolingWithHostCacheExpiration) {
[email protected]e3ceb682011-06-28 23:55:4613635 // Set up a special HttpNetworkSession with a OneTimeCachingHostResolver.
bnca4d611d2016-09-22 19:55:3713636 OneTimeCachingHostResolver host_resolver(
13637 HostPortPair("mail.example.com", 443));
[email protected]c6bf8152012-12-02 07:43:3413638 HttpNetworkSession::Params params =
[email protected]bb88e1d32013-05-03 23:11:0713639 SpdySessionDependencies::CreateSessionParams(&session_deps_);
[email protected]e3ceb682011-06-28 23:55:4613640 params.host_resolver = &host_resolver;
danakj1fd259a02016-04-16 03:17:0913641 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]e3ceb682011-06-28 23:55:4613642
bnc032658ba2016-09-26 18:17:1513643 AddSSLSocketData();
[email protected]e3ceb682011-06-28 23:55:4613644
bncdf80d44fd2016-07-15 20:27:4113645 SpdySerializedFrame host1_req(
bnc38dcd392016-02-09 23:19:4913646 spdy_util_.ConstructSpdyGet("https://www.example.org", 1, LOWEST));
rdsmithebb50aa2015-11-12 03:44:3813647 spdy_util_.UpdateWithStreamDestruction(1);
bncdf80d44fd2016-07-15 20:27:4113648 SpdySerializedFrame host2_req(
bnca4d611d2016-09-22 19:55:3713649 spdy_util_.ConstructSpdyGet("https://mail.example.com", 3, LOWEST));
[email protected]e3ceb682011-06-28 23:55:4613650 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:4113651 CreateMockWrite(host1_req, 0), CreateMockWrite(host2_req, 3),
[email protected]e3ceb682011-06-28 23:55:4613652 };
bnc42331402016-07-25 13:36:1513653 SpdySerializedFrame host1_resp(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
bncdf80d44fd2016-07-15 20:27:4113654 SpdySerializedFrame host1_resp_body(
13655 spdy_util_.ConstructSpdyDataFrame(1, true));
bnc42331402016-07-25 13:36:1513656 SpdySerializedFrame host2_resp(spdy_util_.ConstructSpdyGetReply(NULL, 0, 3));
bncdf80d44fd2016-07-15 20:27:4113657 SpdySerializedFrame host2_resp_body(
13658 spdy_util_.ConstructSpdyDataFrame(3, true));
[email protected]e3ceb682011-06-28 23:55:4613659 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:4113660 CreateMockRead(host1_resp, 1), CreateMockRead(host1_resp_body, 2),
13661 CreateMockRead(host2_resp, 4), CreateMockRead(host2_resp_body, 5),
rch8e6c6c42015-05-01 14:05:1313662 MockRead(ASYNC, 0, 6),
[email protected]e3ceb682011-06-28 23:55:4613663 };
13664
eroman36d84e54432016-03-17 03:23:0213665 IPEndPoint peer_addr(IPAddress::IPv4Localhost(), 443);
[email protected]d2b5f092012-06-08 23:55:0213666 MockConnect connect(ASYNC, OK, peer_addr);
rch8e6c6c42015-05-01 14:05:1313667 SequencedSocketData spdy_data(connect, spdy_reads, arraysize(spdy_reads),
13668 spdy_writes, arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:0713669 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]e3ceb682011-06-28 23:55:4613670
[email protected]aa22b242011-11-16 18:58:2913671 TestCompletionCallback callback;
[email protected]e3ceb682011-06-28 23:55:4613672 HttpRequestInfo request1;
13673 request1.method = "GET";
bncce36dca22015-04-21 22:11:2313674 request1.url = GURL("https://www.example.org/");
[email protected]e3ceb682011-06-28 23:55:4613675 request1.load_flags = 0;
[email protected]90499482013-06-01 00:39:5013676 HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
[email protected]e3ceb682011-06-28 23:55:4613677
tfarina42834112016-09-22 13:38:2013678 int rv = trans1.Start(&request1, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0113679 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
13680 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]e3ceb682011-06-28 23:55:4613681
13682 const HttpResponseInfo* response = trans1.GetResponseInfo();
wezca1070932016-05-26 20:30:5213683 ASSERT_TRUE(response);
13684 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0213685 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]e3ceb682011-06-28 23:55:4613686
13687 std::string response_data;
robpercival214763f2016-07-01 23:27:0113688 ASSERT_THAT(ReadTransaction(&trans1, &response_data), IsOk());
[email protected]e3ceb682011-06-28 23:55:4613689 EXPECT_EQ("hello!", response_data);
13690
13691 // Preload cache entries into HostCache.
bnca4d611d2016-09-22 19:55:3713692 HostResolver::RequestInfo resolve_info(HostPortPair("mail.example.com", 443));
[email protected]e3ceb682011-06-28 23:55:4613693 AddressList ignored;
maksim.sisov31452af2016-07-27 06:38:1013694 std::unique_ptr<HostResolver::Request> request;
13695 rv = host_resolver.Resolve(resolve_info, DEFAULT_PRIORITY, &ignored,
tfarina42834112016-09-22 13:38:2013696 callback.callback(), &request, NetLogWithSource());
robpercival214763f2016-07-01 23:27:0113697 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]6e78dfb2011-07-28 21:34:4713698 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0113699 EXPECT_THAT(rv, IsOk());
[email protected]e3ceb682011-06-28 23:55:4613700
13701 HttpRequestInfo request2;
13702 request2.method = "GET";
bnca4d611d2016-09-22 19:55:3713703 request2.url = GURL("https://mail.example.com/");
[email protected]e3ceb682011-06-28 23:55:4613704 request2.load_flags = 0;
[email protected]90499482013-06-01 00:39:5013705 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
[email protected]e3ceb682011-06-28 23:55:4613706
tfarina42834112016-09-22 13:38:2013707 rv = trans2.Start(&request2, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0113708 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
13709 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]e3ceb682011-06-28 23:55:4613710
13711 response = trans2.GetResponseInfo();
wezca1070932016-05-26 20:30:5213712 ASSERT_TRUE(response);
13713 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0213714 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]e3ceb682011-06-28 23:55:4613715 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5213716 EXPECT_TRUE(response->was_alpn_negotiated);
robpercival214763f2016-07-01 23:27:0113717 ASSERT_THAT(ReadTransaction(&trans2, &response_data), IsOk());
[email protected]e3ceb682011-06-28 23:55:4613718 EXPECT_EQ("hello!", response_data);
[email protected]e3ceb682011-06-28 23:55:4613719}
13720
bncd16676a2016-07-20 16:23:0113721TEST_F(HttpNetworkTransactionTest, DoNotUseSpdySessionForHttp) {
bncce36dca22015-04-21 22:11:2313722 const std::string https_url = "https://www.example.org:8080/";
13723 const std::string http_url = "http://www.example.org:8080/";
[email protected]8450d722012-07-02 19:14:0413724
13725 // SPDY GET for HTTPS URL
bncdf80d44fd2016-07-15 20:27:4113726 SpdySerializedFrame req1(
bnc38dcd392016-02-09 23:19:4913727 spdy_util_.ConstructSpdyGet(https_url.c_str(), 1, LOWEST));
[email protected]8450d722012-07-02 19:14:0413728
13729 MockWrite writes1[] = {
bncdf80d44fd2016-07-15 20:27:4113730 CreateMockWrite(req1, 0),
[email protected]8450d722012-07-02 19:14:0413731 };
13732
bnc42331402016-07-25 13:36:1513733 SpdySerializedFrame resp1(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
bncdf80d44fd2016-07-15 20:27:4113734 SpdySerializedFrame body1(spdy_util_.ConstructSpdyDataFrame(1, true));
13735 MockRead reads1[] = {CreateMockRead(resp1, 1), CreateMockRead(body1, 2),
mmenkee24011922015-12-17 22:12:5913736 MockRead(SYNCHRONOUS, ERR_IO_PENDING, 3)};
[email protected]8450d722012-07-02 19:14:0413737
rch8e6c6c42015-05-01 14:05:1313738 SequencedSocketData data1(reads1, arraysize(reads1), writes1,
13739 arraysize(writes1));
[email protected]8450d722012-07-02 19:14:0413740 MockConnect connect_data1(ASYNC, OK);
[email protected]dd54bd82012-07-19 23:44:5713741 data1.set_connect_data(connect_data1);
[email protected]8450d722012-07-02 19:14:0413742
13743 // HTTP GET for the HTTP URL
13744 MockWrite writes2[] = {
rch8e6c6c42015-05-01 14:05:1313745 MockWrite(ASYNC, 0,
lgarrona91df87f2014-12-05 00:51:3413746 "GET / HTTP/1.1\r\n"
bncce36dca22015-04-21 22:11:2313747 "Host: www.example.org:8080\r\n"
lgarrona91df87f2014-12-05 00:51:3413748 "Connection: keep-alive\r\n\r\n"),
[email protected]8450d722012-07-02 19:14:0413749 };
13750
13751 MockRead reads2[] = {
rch8e6c6c42015-05-01 14:05:1313752 MockRead(ASYNC, 1, "HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
13753 MockRead(ASYNC, 2, "hello"),
13754 MockRead(ASYNC, OK, 3),
[email protected]8450d722012-07-02 19:14:0413755 };
13756
rch8e6c6c42015-05-01 14:05:1313757 SequencedSocketData data2(reads2, arraysize(reads2), writes2,
13758 arraysize(writes2));
[email protected]8450d722012-07-02 19:14:0413759
[email protected]8450d722012-07-02 19:14:0413760 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3613761 ssl.next_proto = kProtoHTTP2;
[email protected]bb88e1d32013-05-03 23:11:0713762 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
13763 session_deps_.socket_factory->AddSocketDataProvider(&data1);
13764 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]8450d722012-07-02 19:14:0413765
danakj1fd259a02016-04-16 03:17:0913766 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]8450d722012-07-02 19:14:0413767
13768 // Start the first transaction to set up the SpdySession
13769 HttpRequestInfo request1;
13770 request1.method = "GET";
13771 request1.url = GURL(https_url);
[email protected]8450d722012-07-02 19:14:0413772 request1.load_flags = 0;
[email protected]90499482013-06-01 00:39:5013773 HttpNetworkTransaction trans1(LOWEST, session.get());
[email protected]8450d722012-07-02 19:14:0413774 TestCompletionCallback callback1;
13775 EXPECT_EQ(ERR_IO_PENDING,
tfarina42834112016-09-22 13:38:2013776 trans1.Start(&request1, callback1.callback(), NetLogWithSource()));
fdoray92e35a72016-06-10 15:54:5513777 base::RunLoop().RunUntilIdle();
[email protected]8450d722012-07-02 19:14:0413778
robpercival214763f2016-07-01 23:27:0113779 EXPECT_THAT(callback1.WaitForResult(), IsOk());
[email protected]8450d722012-07-02 19:14:0413780 EXPECT_TRUE(trans1.GetResponseInfo()->was_fetched_via_spdy);
13781
13782 // Now, start the HTTP request
13783 HttpRequestInfo request2;
13784 request2.method = "GET";
13785 request2.url = GURL(http_url);
[email protected]8450d722012-07-02 19:14:0413786 request2.load_flags = 0;
[email protected]90499482013-06-01 00:39:5013787 HttpNetworkTransaction trans2(MEDIUM, session.get());
[email protected]8450d722012-07-02 19:14:0413788 TestCompletionCallback callback2;
13789 EXPECT_EQ(ERR_IO_PENDING,
tfarina42834112016-09-22 13:38:2013790 trans2.Start(&request2, callback2.callback(), NetLogWithSource()));
fdoray92e35a72016-06-10 15:54:5513791 base::RunLoop().RunUntilIdle();
[email protected]8450d722012-07-02 19:14:0413792
robpercival214763f2016-07-01 23:27:0113793 EXPECT_THAT(callback2.WaitForResult(), IsOk());
[email protected]8450d722012-07-02 19:14:0413794 EXPECT_FALSE(trans2.GetResponseInfo()->was_fetched_via_spdy);
13795}
13796
bnc5452e2a2015-05-08 16:27:4213797// Alternative service requires HTTP/2 (or SPDY), but HTTP/1.1 is negotiated
13798// with the alternative server. That connection should not be used.
bncd16676a2016-07-20 16:23:0113799TEST_F(HttpNetworkTransactionTest, AlternativeServiceNotOnHttp11) {
bnc8bef8da22016-05-30 01:28:2513800 url::SchemeHostPort server("https", "www.example.org", 443);
13801 HostPortPair alternative("www.example.org", 444);
bnc5452e2a2015-05-08 16:27:4213802
bnc8bef8da22016-05-30 01:28:2513803 // Negotiate HTTP/1.1 with alternative.
bnc5452e2a2015-05-08 16:27:4213804 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3613805 ssl.next_proto = kProtoHTTP11;
bnc5452e2a2015-05-08 16:27:4213806 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
13807
13808 // No data should be read from the alternative, because HTTP/1.1 is
13809 // negotiated.
13810 StaticSocketDataProvider data;
13811 session_deps_.socket_factory->AddSocketDataProvider(&data);
13812
13813 // This test documents that an alternate Job should not be used if HTTP/1.1 is
zhongyi3d4a55e72016-04-22 20:36:4613814 // negotiated. In order to test this, a failed connection to the server is
bnc5452e2a2015-05-08 16:27:4213815 // mocked. This way the request relies on the alternate Job.
13816 StaticSocketDataProvider data_refused;
13817 data_refused.set_connect_data(MockConnect(ASYNC, ERR_CONNECTION_REFUSED));
13818 session_deps_.socket_factory->AddSocketDataProvider(&data_refused);
13819
zhongyi3d4a55e72016-04-22 20:36:4613820 // Set up alternative service for server.
danakj1fd259a02016-04-16 03:17:0913821 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc525e175a2016-06-20 12:36:4013822 HttpServerProperties* http_server_properties =
bnc5452e2a2015-05-08 16:27:4213823 session->http_server_properties();
bnc3472afd2016-11-17 15:27:2113824 AlternativeService alternative_service(kProtoHTTP2, alternative);
bnc7dc7e1b42015-07-28 14:43:1213825 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyi3d4a55e72016-04-22 20:36:4613826 http_server_properties->SetAlternativeService(server, alternative_service,
rchdc7b9052016-03-17 20:51:5013827 expiration);
bnc5452e2a2015-05-08 16:27:4213828
bnc5452e2a2015-05-08 16:27:4213829 HttpRequestInfo request;
krasinc06a72a2016-12-21 03:42:4613830 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
bnc5452e2a2015-05-08 16:27:4213831 request.method = "GET";
bnc8bef8da22016-05-30 01:28:2513832 request.url = GURL("https://www.example.org:443");
bnc5452e2a2015-05-08 16:27:4213833 TestCompletionCallback callback;
13834
13835 // HTTP/2 (or SPDY) is required for alternative service, if HTTP/1.1 is
bnc94c92842016-09-21 15:22:5213836 // negotiated, the alternate Job should fail with ERR_ALPN_NEGOTIATION_FAILED.
tfarina42834112016-09-22 13:38:2013837 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
bnc94c92842016-09-21 15:22:5213838 EXPECT_THAT(callback.GetResult(rv), IsError(ERR_ALPN_NEGOTIATION_FAILED));
bnc5452e2a2015-05-08 16:27:4213839}
13840
bnc40448a532015-05-11 19:13:1413841// A request to a server with an alternative service fires two Jobs: one to the
zhongyi3d4a55e72016-04-22 20:36:4613842// server, and an alternate one to the alternative server. If the former
bnc40448a532015-05-11 19:13:1413843// succeeds, the request should succeed, even if the latter fails because
13844// HTTP/1.1 is negotiated which is insufficient for alternative service.
bncd16676a2016-07-20 16:23:0113845TEST_F(HttpNetworkTransactionTest, FailedAlternativeServiceIsNotUserVisible) {
bnc8bef8da22016-05-30 01:28:2513846 url::SchemeHostPort server("https", "www.example.org", 443);
13847 HostPortPair alternative("www.example.org", 444);
bnc40448a532015-05-11 19:13:1413848
13849 // Negotiate HTTP/1.1 with alternative.
13850 SSLSocketDataProvider alternative_ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3613851 alternative_ssl.next_proto = kProtoHTTP11;
bnc40448a532015-05-11 19:13:1413852 session_deps_.socket_factory->AddSSLSocketDataProvider(&alternative_ssl);
13853
13854 // No data should be read from the alternative, because HTTP/1.1 is
13855 // negotiated.
13856 StaticSocketDataProvider data;
13857 session_deps_.socket_factory->AddSocketDataProvider(&data);
13858
zhongyi3d4a55e72016-04-22 20:36:4613859 // Negotiate HTTP/1.1 with server.
bnc40448a532015-05-11 19:13:1413860 SSLSocketDataProvider origin_ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3613861 origin_ssl.next_proto = kProtoHTTP11;
bnc40448a532015-05-11 19:13:1413862 session_deps_.socket_factory->AddSSLSocketDataProvider(&origin_ssl);
13863
13864 MockWrite http_writes[] = {
bnc8bef8da22016-05-30 01:28:2513865 MockWrite("GET / HTTP/1.1\r\n"
13866 "Host: www.example.org\r\n"
13867 "Connection: keep-alive\r\n\r\n"),
13868 MockWrite("GET /second HTTP/1.1\r\n"
13869 "Host: www.example.org\r\n"
13870 "Connection: keep-alive\r\n\r\n"),
bnc40448a532015-05-11 19:13:1413871 };
13872
13873 MockRead http_reads[] = {
13874 MockRead("HTTP/1.1 200 OK\r\n"),
13875 MockRead("Content-Type: text/html\r\n"),
13876 MockRead("Content-Length: 6\r\n\r\n"),
13877 MockRead("foobar"),
13878 MockRead("HTTP/1.1 200 OK\r\n"),
13879 MockRead("Content-Type: text/html\r\n"),
13880 MockRead("Content-Length: 7\r\n\r\n"),
13881 MockRead("another"),
13882 };
13883 StaticSocketDataProvider http_data(http_reads, arraysize(http_reads),
13884 http_writes, arraysize(http_writes));
13885 session_deps_.socket_factory->AddSocketDataProvider(&http_data);
13886
zhongyi3d4a55e72016-04-22 20:36:4613887 // Set up alternative service for server.
danakj1fd259a02016-04-16 03:17:0913888 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc525e175a2016-06-20 12:36:4013889 HttpServerProperties* http_server_properties =
bnc40448a532015-05-11 19:13:1413890 session->http_server_properties();
bnc3472afd2016-11-17 15:27:2113891 AlternativeService alternative_service(kProtoHTTP2, alternative);
bnc7dc7e1b42015-07-28 14:43:1213892 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyi3d4a55e72016-04-22 20:36:4613893 http_server_properties->SetAlternativeService(server, alternative_service,
rchdc7b9052016-03-17 20:51:5013894 expiration);
bnc40448a532015-05-11 19:13:1413895
13896 HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
13897 HttpRequestInfo request1;
13898 request1.method = "GET";
bnc8bef8da22016-05-30 01:28:2513899 request1.url = GURL("https://www.example.org:443");
bnc40448a532015-05-11 19:13:1413900 request1.load_flags = 0;
13901 TestCompletionCallback callback1;
13902
tfarina42834112016-09-22 13:38:2013903 int rv = trans1.Start(&request1, callback1.callback(), NetLogWithSource());
bnc40448a532015-05-11 19:13:1413904 rv = callback1.GetResult(rv);
robpercival214763f2016-07-01 23:27:0113905 EXPECT_THAT(rv, IsOk());
bnc40448a532015-05-11 19:13:1413906
13907 const HttpResponseInfo* response1 = trans1.GetResponseInfo();
wezca1070932016-05-26 20:30:5213908 ASSERT_TRUE(response1);
13909 ASSERT_TRUE(response1->headers);
bnc40448a532015-05-11 19:13:1413910 EXPECT_EQ("HTTP/1.1 200 OK", response1->headers->GetStatusLine());
13911
13912 std::string response_data1;
robpercival214763f2016-07-01 23:27:0113913 ASSERT_THAT(ReadTransaction(&trans1, &response_data1), IsOk());
bnc40448a532015-05-11 19:13:1413914 EXPECT_EQ("foobar", response_data1);
13915
13916 // Alternative should be marked as broken, because HTTP/1.1 is not sufficient
13917 // for alternative service.
13918 EXPECT_TRUE(
13919 http_server_properties->IsAlternativeServiceBroken(alternative_service));
13920
zhongyi3d4a55e72016-04-22 20:36:4613921 // Since |alternative_service| is broken, a second transaction to server
bnc40448a532015-05-11 19:13:1413922 // should not start an alternate Job. It should pool to existing connection
zhongyi3d4a55e72016-04-22 20:36:4613923 // to server.
bnc40448a532015-05-11 19:13:1413924 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
13925 HttpRequestInfo request2;
13926 request2.method = "GET";
bnc8bef8da22016-05-30 01:28:2513927 request2.url = GURL("https://www.example.org:443/second");
bnc40448a532015-05-11 19:13:1413928 request2.load_flags = 0;
13929 TestCompletionCallback callback2;
13930
tfarina42834112016-09-22 13:38:2013931 rv = trans2.Start(&request2, callback2.callback(), NetLogWithSource());
bnc40448a532015-05-11 19:13:1413932 rv = callback2.GetResult(rv);
robpercival214763f2016-07-01 23:27:0113933 EXPECT_THAT(rv, IsOk());
bnc40448a532015-05-11 19:13:1413934
13935 const HttpResponseInfo* response2 = trans2.GetResponseInfo();
wezca1070932016-05-26 20:30:5213936 ASSERT_TRUE(response2);
13937 ASSERT_TRUE(response2->headers);
bnc40448a532015-05-11 19:13:1413938 EXPECT_EQ("HTTP/1.1 200 OK", response2->headers->GetStatusLine());
13939
13940 std::string response_data2;
robpercival214763f2016-07-01 23:27:0113941 ASSERT_THAT(ReadTransaction(&trans2, &response_data2), IsOk());
bnc40448a532015-05-11 19:13:1413942 EXPECT_EQ("another", response_data2);
13943}
13944
bnc5452e2a2015-05-08 16:27:4213945// Alternative service requires HTTP/2 (or SPDY), but there is already a
13946// HTTP/1.1 socket open to the alternative server. That socket should not be
13947// used.
bncd16676a2016-07-20 16:23:0113948TEST_F(HttpNetworkTransactionTest, AlternativeServiceShouldNotPoolToHttp11) {
zhongyi3d4a55e72016-04-22 20:36:4613949 url::SchemeHostPort server("https", "origin.example.org", 443);
bnc5452e2a2015-05-08 16:27:4213950 HostPortPair alternative("alternative.example.org", 443);
13951 std::string origin_url = "https://origin.example.org:443";
13952 std::string alternative_url = "https://alternative.example.org:443";
13953
13954 // Negotiate HTTP/1.1 with alternative.example.org.
13955 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3613956 ssl.next_proto = kProtoHTTP11;
bnc5452e2a2015-05-08 16:27:4213957 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
13958
13959 // HTTP/1.1 data for |request1| and |request2|.
13960 MockWrite http_writes[] = {
13961 MockWrite(
13962 "GET / HTTP/1.1\r\n"
13963 "Host: alternative.example.org\r\n"
13964 "Connection: keep-alive\r\n\r\n"),
13965 MockWrite(
13966 "GET / HTTP/1.1\r\n"
13967 "Host: alternative.example.org\r\n"
13968 "Connection: keep-alive\r\n\r\n"),
13969 };
13970
13971 MockRead http_reads[] = {
13972 MockRead(
13973 "HTTP/1.1 200 OK\r\n"
13974 "Content-Type: text/html; charset=iso-8859-1\r\n"
13975 "Content-Length: 40\r\n\r\n"
13976 "first HTTP/1.1 response from alternative"),
13977 MockRead(
13978 "HTTP/1.1 200 OK\r\n"
13979 "Content-Type: text/html; charset=iso-8859-1\r\n"
13980 "Content-Length: 41\r\n\r\n"
13981 "second HTTP/1.1 response from alternative"),
13982 };
13983 StaticSocketDataProvider http_data(http_reads, arraysize(http_reads),
13984 http_writes, arraysize(http_writes));
13985 session_deps_.socket_factory->AddSocketDataProvider(&http_data);
13986
13987 // This test documents that an alternate Job should not pool to an already
13988 // existing HTTP/1.1 connection. In order to test this, a failed connection
zhongyi3d4a55e72016-04-22 20:36:4613989 // to the server is mocked. This way |request2| relies on the alternate Job.
bnc5452e2a2015-05-08 16:27:4213990 StaticSocketDataProvider data_refused;
13991 data_refused.set_connect_data(MockConnect(ASYNC, ERR_CONNECTION_REFUSED));
13992 session_deps_.socket_factory->AddSocketDataProvider(&data_refused);
13993
zhongyi3d4a55e72016-04-22 20:36:4613994 // Set up alternative service for server.
danakj1fd259a02016-04-16 03:17:0913995 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc525e175a2016-06-20 12:36:4013996 HttpServerProperties* http_server_properties =
bnc5452e2a2015-05-08 16:27:4213997 session->http_server_properties();
bnc3472afd2016-11-17 15:27:2113998 AlternativeService alternative_service(kProtoHTTP2, alternative);
bnc7dc7e1b42015-07-28 14:43:1213999 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyi3d4a55e72016-04-22 20:36:4614000 http_server_properties->SetAlternativeService(server, alternative_service,
rchdc7b9052016-03-17 20:51:5014001 expiration);
bnc5452e2a2015-05-08 16:27:4214002
14003 // First transaction to alternative to open an HTTP/1.1 socket.
bnc5452e2a2015-05-08 16:27:4214004 HttpRequestInfo request1;
krasinc06a72a2016-12-21 03:42:4614005 HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
bnc5452e2a2015-05-08 16:27:4214006 request1.method = "GET";
14007 request1.url = GURL(alternative_url);
14008 request1.load_flags = 0;
14009 TestCompletionCallback callback1;
14010
tfarina42834112016-09-22 13:38:2014011 int rv = trans1.Start(&request1, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0114012 EXPECT_THAT(callback1.GetResult(rv), IsOk());
bnc691fda62016-08-12 00:43:1614013 const HttpResponseInfo* response1 = trans1.GetResponseInfo();
bnc5452e2a2015-05-08 16:27:4214014 ASSERT_TRUE(response1);
wezca1070932016-05-26 20:30:5214015 ASSERT_TRUE(response1->headers);
bnc5452e2a2015-05-08 16:27:4214016 EXPECT_EQ("HTTP/1.1 200 OK", response1->headers->GetStatusLine());
bnc94c92842016-09-21 15:22:5214017 EXPECT_TRUE(response1->was_alpn_negotiated);
bnc5452e2a2015-05-08 16:27:4214018 EXPECT_FALSE(response1->was_fetched_via_spdy);
14019 std::string response_data1;
bnc691fda62016-08-12 00:43:1614020 ASSERT_THAT(ReadTransaction(&trans1, &response_data1), IsOk());
bnc5452e2a2015-05-08 16:27:4214021 EXPECT_EQ("first HTTP/1.1 response from alternative", response_data1);
14022
14023 // Request for origin.example.org, which has an alternative service. This
14024 // will start two Jobs: the alternative looks for connections to pool to,
14025 // finds one which is HTTP/1.1, and should ignore it, and should not try to
zhongyi3d4a55e72016-04-22 20:36:4614026 // open other connections to alternative server. The Job to server fails, so
bnc5452e2a2015-05-08 16:27:4214027 // this request fails.
bnc5452e2a2015-05-08 16:27:4214028 HttpRequestInfo request2;
krasinc06a72a2016-12-21 03:42:4614029 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
bnc5452e2a2015-05-08 16:27:4214030 request2.method = "GET";
14031 request2.url = GURL(origin_url);
14032 request2.load_flags = 0;
14033 TestCompletionCallback callback2;
14034
tfarina42834112016-09-22 13:38:2014035 rv = trans2.Start(&request2, callback2.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0114036 EXPECT_THAT(callback2.GetResult(rv), IsError(ERR_CONNECTION_REFUSED));
bnc5452e2a2015-05-08 16:27:4214037
14038 // Another transaction to alternative. This is to test that the HTTP/1.1
14039 // socket is still open and in the pool.
bnc5452e2a2015-05-08 16:27:4214040 HttpRequestInfo request3;
krasinc06a72a2016-12-21 03:42:4614041 HttpNetworkTransaction trans3(DEFAULT_PRIORITY, session.get());
bnc5452e2a2015-05-08 16:27:4214042 request3.method = "GET";
14043 request3.url = GURL(alternative_url);
14044 request3.load_flags = 0;
14045 TestCompletionCallback callback3;
14046
tfarina42834112016-09-22 13:38:2014047 rv = trans3.Start(&request3, callback3.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0114048 EXPECT_THAT(callback3.GetResult(rv), IsOk());
bnc691fda62016-08-12 00:43:1614049 const HttpResponseInfo* response3 = trans3.GetResponseInfo();
bnc5452e2a2015-05-08 16:27:4214050 ASSERT_TRUE(response3);
wezca1070932016-05-26 20:30:5214051 ASSERT_TRUE(response3->headers);
bnc5452e2a2015-05-08 16:27:4214052 EXPECT_EQ("HTTP/1.1 200 OK", response3->headers->GetStatusLine());
bnc94c92842016-09-21 15:22:5214053 EXPECT_TRUE(response3->was_alpn_negotiated);
bnc5452e2a2015-05-08 16:27:4214054 EXPECT_FALSE(response3->was_fetched_via_spdy);
14055 std::string response_data3;
bnc691fda62016-08-12 00:43:1614056 ASSERT_THAT(ReadTransaction(&trans3, &response_data3), IsOk());
bnc5452e2a2015-05-08 16:27:4214057 EXPECT_EQ("second HTTP/1.1 response from alternative", response_data3);
14058}
14059
bncd16676a2016-07-20 16:23:0114060TEST_F(HttpNetworkTransactionTest, DoNotUseSpdySessionForHttpOverTunnel) {
bncce36dca22015-04-21 22:11:2314061 const std::string https_url = "https://www.example.org:8080/";
14062 const std::string http_url = "http://www.example.org:8080/";
[email protected]8450d722012-07-02 19:14:0414063
rdsmithebb50aa2015-11-12 03:44:3814064 // Separate SPDY util instance for naked and wrapped requests.
bncd16676a2016-07-20 16:23:0114065 SpdyTestUtil spdy_util_wrapped;
rdsmithebb50aa2015-11-12 03:44:3814066
[email protected]8450d722012-07-02 19:14:0414067 // SPDY GET for HTTPS URL (through CONNECT tunnel)
bncce36dca22015-04-21 22:11:2314068 const HostPortPair host_port_pair("www.example.org", 8080);
bncdf80d44fd2016-07-15 20:27:4114069 SpdySerializedFrame connect(
lgarrona91df87f2014-12-05 00:51:3414070 spdy_util_.ConstructSpdyConnect(NULL, 0, 1, LOWEST, host_port_pair));
bncdf80d44fd2016-07-15 20:27:4114071 SpdySerializedFrame req1(
bnc38dcd392016-02-09 23:19:4914072 spdy_util_wrapped.ConstructSpdyGet(https_url.c_str(), 1, LOWEST));
bncdf80d44fd2016-07-15 20:27:4114073 SpdySerializedFrame wrapped_req1(
[email protected]23e482282013-06-14 16:08:0214074 spdy_util_.ConstructWrappedSpdyFrame(req1, 1));
[email protected]601e03f12014-04-06 16:26:3914075
14076 // SPDY GET for HTTP URL (through the proxy, but not the tunnel).
[email protected]745aa9c2014-06-27 02:21:2914077 SpdyHeaderBlock req2_block;
14078 req2_block[spdy_util_.GetMethodKey()] = "GET";
bncce36dca22015-04-21 22:11:2314079 req2_block[spdy_util_.GetHostKey()] = "www.example.org:8080";
[email protected]745aa9c2014-06-27 02:21:2914080 req2_block[spdy_util_.GetSchemeKey()] = "http";
bnc7ecc1122015-09-28 13:22:4914081 req2_block[spdy_util_.GetPathKey()] = "/";
bncdf80d44fd2016-07-15 20:27:4114082 SpdySerializedFrame req2(
bnc42331402016-07-25 13:36:1514083 spdy_util_.ConstructSpdyHeaders(3, std::move(req2_block), MEDIUM, true));
[email protected]8450d722012-07-02 19:14:0414084
14085 MockWrite writes1[] = {
bncdf80d44fd2016-07-15 20:27:4114086 CreateMockWrite(connect, 0), CreateMockWrite(wrapped_req1, 2),
14087 CreateMockWrite(req2, 6),
[email protected]8450d722012-07-02 19:14:0414088 };
14089
bncdf80d44fd2016-07-15 20:27:4114090 SpdySerializedFrame conn_resp(
bnc42331402016-07-25 13:36:1514091 spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
bncdf80d44fd2016-07-15 20:27:4114092 SpdySerializedFrame resp1(
bnc42331402016-07-25 13:36:1514093 spdy_util_wrapped.ConstructSpdyGetReply(nullptr, 0, 1));
bncdf80d44fd2016-07-15 20:27:4114094 SpdySerializedFrame body1(spdy_util_wrapped.ConstructSpdyDataFrame(1, true));
14095 SpdySerializedFrame wrapped_resp1(
rdsmithebb50aa2015-11-12 03:44:3814096 spdy_util_wrapped.ConstructWrappedSpdyFrame(resp1, 1));
bncdf80d44fd2016-07-15 20:27:4114097 SpdySerializedFrame wrapped_body1(
rdsmithebb50aa2015-11-12 03:44:3814098 spdy_util_wrapped.ConstructWrappedSpdyFrame(body1, 1));
bnc42331402016-07-25 13:36:1514099 SpdySerializedFrame resp2(spdy_util_.ConstructSpdyGetReply(NULL, 0, 3));
bncdf80d44fd2016-07-15 20:27:4114100 SpdySerializedFrame body2(spdy_util_.ConstructSpdyDataFrame(3, true));
mmenke666a6fea2015-12-19 04:16:3314101 MockRead reads1[] = {
bncdf80d44fd2016-07-15 20:27:4114102 CreateMockRead(conn_resp, 1),
mmenke666a6fea2015-12-19 04:16:3314103 MockRead(ASYNC, ERR_IO_PENDING, 3),
bncdf80d44fd2016-07-15 20:27:4114104 CreateMockRead(wrapped_resp1, 4),
14105 CreateMockRead(wrapped_body1, 5),
mmenke666a6fea2015-12-19 04:16:3314106 MockRead(ASYNC, ERR_IO_PENDING, 7),
bncdf80d44fd2016-07-15 20:27:4114107 CreateMockRead(resp2, 8),
14108 CreateMockRead(body2, 9),
mmenke666a6fea2015-12-19 04:16:3314109 MockRead(SYNCHRONOUS, ERR_IO_PENDING, 10),
14110 };
[email protected]8450d722012-07-02 19:14:0414111
mmenke666a6fea2015-12-19 04:16:3314112 SequencedSocketData data1(reads1, arraysize(reads1), writes1,
14113 arraysize(writes1));
[email protected]8450d722012-07-02 19:14:0414114 MockConnect connect_data1(ASYNC, OK);
[email protected]dd54bd82012-07-19 23:44:5714115 data1.set_connect_data(connect_data1);
[email protected]8450d722012-07-02 19:14:0414116
rdsmith82957ad2015-09-16 19:42:0314117 session_deps_.proxy_service =
14118 ProxyService::CreateFixedFromPacResult("HTTPS proxy:70");
vishal.b62985ca92015-04-17 08:45:5114119 TestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:0714120 session_deps_.net_log = &log;
[email protected]8450d722012-07-02 19:14:0414121 SSLSocketDataProvider ssl1(ASYNC, OK); // to the proxy
bnc3cf2a592016-08-11 14:48:3614122 ssl1.next_proto = kProtoHTTP2;
mmenke666a6fea2015-12-19 04:16:3314123 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl1);
[email protected]8450d722012-07-02 19:14:0414124 SSLSocketDataProvider ssl2(ASYNC, OK); // to the server
bnc3cf2a592016-08-11 14:48:3614125 ssl2.next_proto = kProtoHTTP2;
mmenke666a6fea2015-12-19 04:16:3314126 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
14127 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8450d722012-07-02 19:14:0414128
danakj1fd259a02016-04-16 03:17:0914129 std::unique_ptr<HttpNetworkSession> session = CreateSession(&session_deps_);
[email protected]8450d722012-07-02 19:14:0414130
14131 // Start the first transaction to set up the SpdySession
14132 HttpRequestInfo request1;
14133 request1.method = "GET";
14134 request1.url = GURL(https_url);
[email protected]8450d722012-07-02 19:14:0414135 request1.load_flags = 0;
[email protected]90499482013-06-01 00:39:5014136 HttpNetworkTransaction trans1(LOWEST, session.get());
[email protected]8450d722012-07-02 19:14:0414137 TestCompletionCallback callback1;
tfarina42834112016-09-22 13:38:2014138 int rv = trans1.Start(&request1, callback1.callback(), NetLogWithSource());
[email protected]8450d722012-07-02 19:14:0414139
mmenke666a6fea2015-12-19 04:16:3314140 // This pause is a hack to avoid running into https://crbug.com/497228.
14141 data1.RunUntilPaused();
14142 base::RunLoop().RunUntilIdle();
14143 data1.Resume();
robpercival214763f2016-07-01 23:27:0114144 EXPECT_THAT(callback1.GetResult(rv), IsOk());
[email protected]8450d722012-07-02 19:14:0414145 EXPECT_TRUE(trans1.GetResponseInfo()->was_fetched_via_spdy);
14146
[email protected]f6c63db52013-02-02 00:35:2214147 LoadTimingInfo load_timing_info1;
14148 EXPECT_TRUE(trans1.GetLoadTimingInfo(&load_timing_info1));
14149 TestLoadTimingNotReusedWithPac(load_timing_info1,
14150 CONNECT_TIMING_HAS_SSL_TIMES);
14151
mmenke666a6fea2015-12-19 04:16:3314152 // Now, start the HTTP request.
[email protected]8450d722012-07-02 19:14:0414153 HttpRequestInfo request2;
14154 request2.method = "GET";
14155 request2.url = GURL(http_url);
[email protected]8450d722012-07-02 19:14:0414156 request2.load_flags = 0;
[email protected]90499482013-06-01 00:39:5014157 HttpNetworkTransaction trans2(MEDIUM, session.get());
[email protected]8450d722012-07-02 19:14:0414158 TestCompletionCallback callback2;
tfarina42834112016-09-22 13:38:2014159 rv = trans2.Start(&request2, callback2.callback(), NetLogWithSource());
[email protected]8450d722012-07-02 19:14:0414160
mmenke666a6fea2015-12-19 04:16:3314161 // This pause is a hack to avoid running into https://crbug.com/497228.
14162 data1.RunUntilPaused();
14163 base::RunLoop().RunUntilIdle();
14164 data1.Resume();
robpercival214763f2016-07-01 23:27:0114165 EXPECT_THAT(callback2.GetResult(rv), IsOk());
mmenke666a6fea2015-12-19 04:16:3314166
[email protected]8450d722012-07-02 19:14:0414167 EXPECT_TRUE(trans2.GetResponseInfo()->was_fetched_via_spdy);
[email protected]f6c63db52013-02-02 00:35:2214168
14169 LoadTimingInfo load_timing_info2;
14170 EXPECT_TRUE(trans2.GetLoadTimingInfo(&load_timing_info2));
14171 // The established SPDY sessions is considered reused by the HTTP request.
14172 TestLoadTimingReusedWithPac(load_timing_info2);
14173 // HTTP requests over a SPDY session should have a different connection
14174 // socket_log_id than requests over a tunnel.
14175 EXPECT_NE(load_timing_info1.socket_log_id, load_timing_info2.socket_log_id);
[email protected]8450d722012-07-02 19:14:0414176}
14177
[email protected]2d88e7d2012-07-19 17:55:1714178// Test that in the case where we have a SPDY session to a SPDY proxy
14179// that we do not pool other origins that resolve to the same IP when
14180// the certificate does not match the new origin.
14181// http://crbug.com/134690
bncd16676a2016-07-20 16:23:0114182TEST_F(HttpNetworkTransactionTest, DoNotUseSpdySessionIfCertDoesNotMatch) {
bncce36dca22015-04-21 22:11:2314183 const std::string url1 = "http://www.example.org/";
14184 const std::string url2 = "https://news.example.org/";
[email protected]2d88e7d2012-07-19 17:55:1714185 const std::string ip_addr = "1.2.3.4";
14186
rdsmithebb50aa2015-11-12 03:44:3814187 // Second SpdyTestUtil instance for the second socket.
bncd16676a2016-07-20 16:23:0114188 SpdyTestUtil spdy_util_secure;
rdsmithebb50aa2015-11-12 03:44:3814189
[email protected]2d88e7d2012-07-19 17:55:1714190 // SPDY GET for HTTP URL (through SPDY proxy)
bnc086b39e12016-06-24 13:05:2614191 SpdyHeaderBlock headers(
bncce36dca22015-04-21 22:11:2314192 spdy_util_.ConstructGetHeaderBlockForProxy("http://www.example.org/"));
bncdf80d44fd2016-07-15 20:27:4114193 SpdySerializedFrame req1(
bnc42331402016-07-25 13:36:1514194 spdy_util_.ConstructSpdyHeaders(1, std::move(headers), LOWEST, true));
[email protected]2d88e7d2012-07-19 17:55:1714195
14196 MockWrite writes1[] = {
bncdf80d44fd2016-07-15 20:27:4114197 CreateMockWrite(req1, 0),
[email protected]2d88e7d2012-07-19 17:55:1714198 };
14199
bnc42331402016-07-25 13:36:1514200 SpdySerializedFrame resp1(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
bncdf80d44fd2016-07-15 20:27:4114201 SpdySerializedFrame body1(spdy_util_.ConstructSpdyDataFrame(1, true));
[email protected]2d88e7d2012-07-19 17:55:1714202 MockRead reads1[] = {
bncdf80d44fd2016-07-15 20:27:4114203 MockRead(ASYNC, ERR_IO_PENDING, 1), CreateMockRead(resp1, 2),
14204 CreateMockRead(body1, 3), MockRead(ASYNC, OK, 4), // EOF
[email protected]2d88e7d2012-07-19 17:55:1714205 };
14206
mmenke666a6fea2015-12-19 04:16:3314207 SequencedSocketData data1(reads1, arraysize(reads1), writes1,
14208 arraysize(writes1));
martijnfe9636e2016-02-06 14:33:3214209 IPAddress ip;
martijn654c8c42016-02-10 22:10:5914210 ASSERT_TRUE(ip.AssignFromIPLiteral(ip_addr));
[email protected]2d88e7d2012-07-19 17:55:1714211 IPEndPoint peer_addr = IPEndPoint(ip, 443);
14212 MockConnect connect_data1(ASYNC, OK, peer_addr);
mmenke666a6fea2015-12-19 04:16:3314213 data1.set_connect_data(connect_data1);
[email protected]2d88e7d2012-07-19 17:55:1714214
14215 // SPDY GET for HTTPS URL (direct)
bncdf80d44fd2016-07-15 20:27:4114216 SpdySerializedFrame req2(
bnc38dcd392016-02-09 23:19:4914217 spdy_util_secure.ConstructSpdyGet(url2.c_str(), 1, MEDIUM));
[email protected]2d88e7d2012-07-19 17:55:1714218
14219 MockWrite writes2[] = {
bncdf80d44fd2016-07-15 20:27:4114220 CreateMockWrite(req2, 0),
[email protected]2d88e7d2012-07-19 17:55:1714221 };
14222
bnc42331402016-07-25 13:36:1514223 SpdySerializedFrame resp2(spdy_util_secure.ConstructSpdyGetReply(NULL, 0, 1));
bncdf80d44fd2016-07-15 20:27:4114224 SpdySerializedFrame body2(spdy_util_secure.ConstructSpdyDataFrame(1, true));
14225 MockRead reads2[] = {CreateMockRead(resp2, 1), CreateMockRead(body2, 2),
mmenke666a6fea2015-12-19 04:16:3314226 MockRead(ASYNC, OK, 3)};
[email protected]2d88e7d2012-07-19 17:55:1714227
mmenke666a6fea2015-12-19 04:16:3314228 SequencedSocketData data2(reads2, arraysize(reads2), writes2,
14229 arraysize(writes2));
[email protected]2d88e7d2012-07-19 17:55:1714230 MockConnect connect_data2(ASYNC, OK);
mmenke666a6fea2015-12-19 04:16:3314231 data2.set_connect_data(connect_data2);
[email protected]2d88e7d2012-07-19 17:55:1714232
14233 // Set up a proxy config that sends HTTP requests to a proxy, and
14234 // all others direct.
14235 ProxyConfig proxy_config;
14236 proxy_config.proxy_rules().ParseFromString("http=https://proxy:443");
[email protected]bb88e1d32013-05-03 23:11:0714237 session_deps_.proxy_service.reset(new ProxyService(
danakj1fd259a02016-04-16 03:17:0914238 base::WrapUnique(new ProxyConfigServiceFixed(proxy_config)), nullptr,
csharrisonb7e3a082015-09-22 19:13:0414239 NULL));
[email protected]2d88e7d2012-07-19 17:55:1714240
bncce36dca22015-04-21 22:11:2314241 SSLSocketDataProvider ssl1(ASYNC, OK); // to the proxy
bnc3cf2a592016-08-11 14:48:3614242 ssl1.next_proto = kProtoHTTP2;
[email protected]2d88e7d2012-07-19 17:55:1714243 // Load a valid cert. Note, that this does not need to
14244 // be valid for proxy because the MockSSLClientSocket does
14245 // not actually verify it. But SpdySession will use this
14246 // to see if it is valid for the new origin
bncce36dca22015-04-21 22:11:2314247 ssl1.cert = ImportCertFromFile(GetTestCertsDirectory(), "ok_cert.pem");
wezca1070932016-05-26 20:30:5214248 ASSERT_TRUE(ssl1.cert);
mmenke666a6fea2015-12-19 04:16:3314249 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl1);
14250 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]2d88e7d2012-07-19 17:55:1714251
14252 SSLSocketDataProvider ssl2(ASYNC, OK); // to the server
bnc3cf2a592016-08-11 14:48:3614253 ssl2.next_proto = kProtoHTTP2;
mmenke666a6fea2015-12-19 04:16:3314254 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
14255 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]2d88e7d2012-07-19 17:55:1714256
[email protected]bb88e1d32013-05-03 23:11:0714257 session_deps_.host_resolver.reset(new MockCachingHostResolver());
bncce36dca22015-04-21 22:11:2314258 session_deps_.host_resolver->rules()->AddRule("news.example.org", ip_addr);
[email protected]bb88e1d32013-05-03 23:11:0714259 session_deps_.host_resolver->rules()->AddRule("proxy", ip_addr);
[email protected]2d88e7d2012-07-19 17:55:1714260
danakj1fd259a02016-04-16 03:17:0914261 std::unique_ptr<HttpNetworkSession> session = CreateSession(&session_deps_);
[email protected]2d88e7d2012-07-19 17:55:1714262
14263 // Start the first transaction to set up the SpdySession
14264 HttpRequestInfo request1;
14265 request1.method = "GET";
14266 request1.url = GURL(url1);
[email protected]2d88e7d2012-07-19 17:55:1714267 request1.load_flags = 0;
[email protected]90499482013-06-01 00:39:5014268 HttpNetworkTransaction trans1(LOWEST, session.get());
[email protected]2d88e7d2012-07-19 17:55:1714269 TestCompletionCallback callback1;
14270 ASSERT_EQ(ERR_IO_PENDING,
tfarina42834112016-09-22 13:38:2014271 trans1.Start(&request1, callback1.callback(), NetLogWithSource()));
mmenke666a6fea2015-12-19 04:16:3314272 // This pause is a hack to avoid running into https://crbug.com/497228.
14273 data1.RunUntilPaused();
14274 base::RunLoop().RunUntilIdle();
14275 data1.Resume();
[email protected]2d88e7d2012-07-19 17:55:1714276
robpercival214763f2016-07-01 23:27:0114277 EXPECT_THAT(callback1.WaitForResult(), IsOk());
[email protected]2d88e7d2012-07-19 17:55:1714278 EXPECT_TRUE(trans1.GetResponseInfo()->was_fetched_via_spdy);
14279
14280 // Now, start the HTTP request
14281 HttpRequestInfo request2;
14282 request2.method = "GET";
14283 request2.url = GURL(url2);
[email protected]2d88e7d2012-07-19 17:55:1714284 request2.load_flags = 0;
[email protected]90499482013-06-01 00:39:5014285 HttpNetworkTransaction trans2(MEDIUM, session.get());
[email protected]2d88e7d2012-07-19 17:55:1714286 TestCompletionCallback callback2;
14287 EXPECT_EQ(ERR_IO_PENDING,
tfarina42834112016-09-22 13:38:2014288 trans2.Start(&request2, callback2.callback(), NetLogWithSource()));
fdoray92e35a72016-06-10 15:54:5514289 base::RunLoop().RunUntilIdle();
[email protected]2d88e7d2012-07-19 17:55:1714290
14291 ASSERT_TRUE(callback2.have_result());
robpercival214763f2016-07-01 23:27:0114292 EXPECT_THAT(callback2.WaitForResult(), IsOk());
[email protected]2d88e7d2012-07-19 17:55:1714293 EXPECT_TRUE(trans2.GetResponseInfo()->was_fetched_via_spdy);
14294}
14295
[email protected]85f97342013-04-17 06:12:2414296// Test to verify that a failed socket read (due to an ERR_CONNECTION_CLOSED
14297// error) in SPDY session, removes the socket from pool and closes the SPDY
14298// session. Verify that new url's from the same HttpNetworkSession (and a new
14299// SpdySession) do work. http://crbug.com/224701
bncd16676a2016-07-20 16:23:0114300TEST_F(HttpNetworkTransactionTest, ErrorSocketNotConnected) {
bncce36dca22015-04-21 22:11:2314301 const std::string https_url = "https://www.example.org/";
[email protected]85f97342013-04-17 06:12:2414302
14303 MockRead reads1[] = {
14304 MockRead(SYNCHRONOUS, ERR_CONNECTION_CLOSED, 0)
14305 };
14306
mmenke11eb5152015-06-09 14:50:5014307 SequencedSocketData data1(reads1, arraysize(reads1), NULL, 0);
[email protected]85f97342013-04-17 06:12:2414308
bncdf80d44fd2016-07-15 20:27:4114309 SpdySerializedFrame req2(
bnc38dcd392016-02-09 23:19:4914310 spdy_util_.ConstructSpdyGet(https_url.c_str(), 1, MEDIUM));
[email protected]85f97342013-04-17 06:12:2414311 MockWrite writes2[] = {
bncdf80d44fd2016-07-15 20:27:4114312 CreateMockWrite(req2, 0),
[email protected]85f97342013-04-17 06:12:2414313 };
14314
bnc42331402016-07-25 13:36:1514315 SpdySerializedFrame resp2(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
bncdf80d44fd2016-07-15 20:27:4114316 SpdySerializedFrame body2(spdy_util_.ConstructSpdyDataFrame(1, true));
[email protected]85f97342013-04-17 06:12:2414317 MockRead reads2[] = {
bncdf80d44fd2016-07-15 20:27:4114318 CreateMockRead(resp2, 1), CreateMockRead(body2, 2),
14319 MockRead(ASYNC, OK, 3) // EOF
[email protected]85f97342013-04-17 06:12:2414320 };
14321
mmenke11eb5152015-06-09 14:50:5014322 SequencedSocketData data2(reads2, arraysize(reads2), writes2,
14323 arraysize(writes2));
[email protected]85f97342013-04-17 06:12:2414324
[email protected]85f97342013-04-17 06:12:2414325 SSLSocketDataProvider ssl1(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3614326 ssl1.next_proto = kProtoHTTP2;
mmenke11eb5152015-06-09 14:50:5014327 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl1);
14328 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]85f97342013-04-17 06:12:2414329
14330 SSLSocketDataProvider ssl2(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3614331 ssl2.next_proto = kProtoHTTP2;
mmenke11eb5152015-06-09 14:50:5014332 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
14333 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]85f97342013-04-17 06:12:2414334
danakj1fd259a02016-04-16 03:17:0914335 std::unique_ptr<HttpNetworkSession> session(
mmenke11eb5152015-06-09 14:50:5014336 SpdySessionDependencies::SpdyCreateSession(&session_deps_));
[email protected]85f97342013-04-17 06:12:2414337
14338 // Start the first transaction to set up the SpdySession and verify that
14339 // connection was closed.
14340 HttpRequestInfo request1;
14341 request1.method = "GET";
14342 request1.url = GURL(https_url);
14343 request1.load_flags = 0;
[email protected]90499482013-06-01 00:39:5014344 HttpNetworkTransaction trans1(MEDIUM, session.get());
[email protected]85f97342013-04-17 06:12:2414345 TestCompletionCallback callback1;
14346 EXPECT_EQ(ERR_IO_PENDING,
tfarina42834112016-09-22 13:38:2014347 trans1.Start(&request1, callback1.callback(), NetLogWithSource()));
robpercival214763f2016-07-01 23:27:0114348 EXPECT_THAT(callback1.WaitForResult(), IsError(ERR_CONNECTION_CLOSED));
[email protected]85f97342013-04-17 06:12:2414349
14350 // Now, start the second request and make sure it succeeds.
14351 HttpRequestInfo request2;
14352 request2.method = "GET";
14353 request2.url = GURL(https_url);
14354 request2.load_flags = 0;
[email protected]90499482013-06-01 00:39:5014355 HttpNetworkTransaction trans2(MEDIUM, session.get());
[email protected]85f97342013-04-17 06:12:2414356 TestCompletionCallback callback2;
14357 EXPECT_EQ(ERR_IO_PENDING,
tfarina42834112016-09-22 13:38:2014358 trans2.Start(&request2, callback2.callback(), NetLogWithSource()));
[email protected]85f97342013-04-17 06:12:2414359
robpercival214763f2016-07-01 23:27:0114360 ASSERT_THAT(callback2.WaitForResult(), IsOk());
[email protected]85f97342013-04-17 06:12:2414361 EXPECT_TRUE(trans2.GetResponseInfo()->was_fetched_via_spdy);
14362}
14363
bncd16676a2016-07-20 16:23:0114364TEST_F(HttpNetworkTransactionTest, CloseIdleSpdySessionToOpenNewOne) {
[email protected]483fa202013-05-14 01:07:0314365 ClientSocketPoolManager::set_max_sockets_per_group(
14366 HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
14367 ClientSocketPoolManager::set_max_sockets_per_pool(
14368 HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
14369
14370 // Use two different hosts with different IPs so they don't get pooled.
14371 session_deps_.host_resolver->rules()->AddRule("www.a.com", "10.0.0.1");
14372 session_deps_.host_resolver->rules()->AddRule("www.b.com", "10.0.0.2");
danakj1fd259a02016-04-16 03:17:0914373 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]483fa202013-05-14 01:07:0314374
14375 SSLSocketDataProvider ssl1(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3614376 ssl1.next_proto = kProtoHTTP2;
[email protected]483fa202013-05-14 01:07:0314377 SSLSocketDataProvider ssl2(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3614378 ssl2.next_proto = kProtoHTTP2;
[email protected]483fa202013-05-14 01:07:0314379 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl1);
14380 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
14381
bncdf80d44fd2016-07-15 20:27:4114382 SpdySerializedFrame host1_req(
bnc38dcd392016-02-09 23:19:4914383 spdy_util_.ConstructSpdyGet("https://www.a.com", 1, DEFAULT_PRIORITY));
[email protected]483fa202013-05-14 01:07:0314384 MockWrite spdy1_writes[] = {
bncdf80d44fd2016-07-15 20:27:4114385 CreateMockWrite(host1_req, 0),
[email protected]483fa202013-05-14 01:07:0314386 };
bnc42331402016-07-25 13:36:1514387 SpdySerializedFrame host1_resp(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
bncdf80d44fd2016-07-15 20:27:4114388 SpdySerializedFrame host1_resp_body(
14389 spdy_util_.ConstructSpdyDataFrame(1, true));
[email protected]483fa202013-05-14 01:07:0314390 MockRead spdy1_reads[] = {
bncdf80d44fd2016-07-15 20:27:4114391 CreateMockRead(host1_resp, 1), CreateMockRead(host1_resp_body, 2),
mmenkee24011922015-12-17 22:12:5914392 MockRead(SYNCHRONOUS, ERR_IO_PENDING, 3),
[email protected]483fa202013-05-14 01:07:0314393 };
14394
rdsmithebb50aa2015-11-12 03:44:3814395 // Use a separate test instance for the separate SpdySession that will be
14396 // created.
bncd16676a2016-07-20 16:23:0114397 SpdyTestUtil spdy_util_2;
danakj1fd259a02016-04-16 03:17:0914398 std::unique_ptr<SequencedSocketData> spdy1_data(
rch8e6c6c42015-05-01 14:05:1314399 new SequencedSocketData(spdy1_reads, arraysize(spdy1_reads), spdy1_writes,
14400 arraysize(spdy1_writes)));
[email protected]483fa202013-05-14 01:07:0314401 session_deps_.socket_factory->AddSocketDataProvider(spdy1_data.get());
14402
bncdf80d44fd2016-07-15 20:27:4114403 SpdySerializedFrame host2_req(
bnc38dcd392016-02-09 23:19:4914404 spdy_util_2.ConstructSpdyGet("https://www.b.com", 1, DEFAULT_PRIORITY));
[email protected]483fa202013-05-14 01:07:0314405 MockWrite spdy2_writes[] = {
bncdf80d44fd2016-07-15 20:27:4114406 CreateMockWrite(host2_req, 0),
[email protected]483fa202013-05-14 01:07:0314407 };
bnc42331402016-07-25 13:36:1514408 SpdySerializedFrame host2_resp(spdy_util_2.ConstructSpdyGetReply(NULL, 0, 1));
bncdf80d44fd2016-07-15 20:27:4114409 SpdySerializedFrame host2_resp_body(
14410 spdy_util_2.ConstructSpdyDataFrame(1, true));
[email protected]483fa202013-05-14 01:07:0314411 MockRead spdy2_reads[] = {
bncdf80d44fd2016-07-15 20:27:4114412 CreateMockRead(host2_resp, 1), CreateMockRead(host2_resp_body, 2),
mmenkee24011922015-12-17 22:12:5914413 MockRead(SYNCHRONOUS, ERR_IO_PENDING, 3),
[email protected]483fa202013-05-14 01:07:0314414 };
14415
danakj1fd259a02016-04-16 03:17:0914416 std::unique_ptr<SequencedSocketData> spdy2_data(
rch8e6c6c42015-05-01 14:05:1314417 new SequencedSocketData(spdy2_reads, arraysize(spdy2_reads), spdy2_writes,
14418 arraysize(spdy2_writes)));
[email protected]483fa202013-05-14 01:07:0314419 session_deps_.socket_factory->AddSocketDataProvider(spdy2_data.get());
14420
14421 MockWrite http_write[] = {
14422 MockWrite("GET / HTTP/1.1\r\n"
14423 "Host: www.a.com\r\n"
14424 "Connection: keep-alive\r\n\r\n"),
14425 };
14426
14427 MockRead http_read[] = {
14428 MockRead("HTTP/1.1 200 OK\r\n"),
14429 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
14430 MockRead("Content-Length: 6\r\n\r\n"),
14431 MockRead("hello!"),
14432 };
14433 StaticSocketDataProvider http_data(http_read, arraysize(http_read),
14434 http_write, arraysize(http_write));
14435 session_deps_.socket_factory->AddSocketDataProvider(&http_data);
14436
14437 HostPortPair host_port_pair_a("www.a.com", 443);
[email protected]e6d017652013-05-17 18:01:4014438 SpdySessionKey spdy_session_key_a(
[email protected]314b03992014-04-01 01:28:5314439 host_port_pair_a, ProxyServer::Direct(), PRIVACY_MODE_DISABLED);
[email protected]483fa202013-05-14 01:07:0314440 EXPECT_FALSE(
[email protected]41d64e82013-07-03 22:44:2614441 HasSpdySession(session->spdy_session_pool(), spdy_session_key_a));
[email protected]483fa202013-05-14 01:07:0314442
14443 TestCompletionCallback callback;
14444 HttpRequestInfo request1;
14445 request1.method = "GET";
14446 request1.url = GURL("https://www.a.com/");
14447 request1.load_flags = 0;
danakj1fd259a02016-04-16 03:17:0914448 std::unique_ptr<HttpNetworkTransaction> trans(
[email protected]90499482013-06-01 00:39:5014449 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]483fa202013-05-14 01:07:0314450
tfarina42834112016-09-22 13:38:2014451 int rv = trans->Start(&request1, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0114452 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
14453 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]483fa202013-05-14 01:07:0314454
14455 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5214456 ASSERT_TRUE(response);
14457 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0214458 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]483fa202013-05-14 01:07:0314459 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5214460 EXPECT_TRUE(response->was_alpn_negotiated);
[email protected]483fa202013-05-14 01:07:0314461
14462 std::string response_data;
robpercival214763f2016-07-01 23:27:0114463 ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
[email protected]483fa202013-05-14 01:07:0314464 EXPECT_EQ("hello!", response_data);
14465 trans.reset();
14466 EXPECT_TRUE(
[email protected]41d64e82013-07-03 22:44:2614467 HasSpdySession(session->spdy_session_pool(), spdy_session_key_a));
[email protected]483fa202013-05-14 01:07:0314468
14469 HostPortPair host_port_pair_b("www.b.com", 443);
[email protected]e6d017652013-05-17 18:01:4014470 SpdySessionKey spdy_session_key_b(
[email protected]314b03992014-04-01 01:28:5314471 host_port_pair_b, ProxyServer::Direct(), PRIVACY_MODE_DISABLED);
[email protected]483fa202013-05-14 01:07:0314472 EXPECT_FALSE(
[email protected]41d64e82013-07-03 22:44:2614473 HasSpdySession(session->spdy_session_pool(), spdy_session_key_b));
[email protected]483fa202013-05-14 01:07:0314474 HttpRequestInfo request2;
14475 request2.method = "GET";
14476 request2.url = GURL("https://www.b.com/");
14477 request2.load_flags = 0;
[email protected]90499482013-06-01 00:39:5014478 trans.reset(new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]483fa202013-05-14 01:07:0314479
tfarina42834112016-09-22 13:38:2014480 rv = trans->Start(&request2, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0114481 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
14482 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]483fa202013-05-14 01:07:0314483
14484 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5214485 ASSERT_TRUE(response);
14486 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0214487 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]483fa202013-05-14 01:07:0314488 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5214489 EXPECT_TRUE(response->was_alpn_negotiated);
robpercival214763f2016-07-01 23:27:0114490 ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
[email protected]483fa202013-05-14 01:07:0314491 EXPECT_EQ("hello!", response_data);
14492 EXPECT_FALSE(
[email protected]41d64e82013-07-03 22:44:2614493 HasSpdySession(session->spdy_session_pool(), spdy_session_key_a));
[email protected]483fa202013-05-14 01:07:0314494 EXPECT_TRUE(
[email protected]41d64e82013-07-03 22:44:2614495 HasSpdySession(session->spdy_session_pool(), spdy_session_key_b));
[email protected]483fa202013-05-14 01:07:0314496
14497 HostPortPair host_port_pair_a1("www.a.com", 80);
[email protected]e6d017652013-05-17 18:01:4014498 SpdySessionKey spdy_session_key_a1(
[email protected]314b03992014-04-01 01:28:5314499 host_port_pair_a1, ProxyServer::Direct(), PRIVACY_MODE_DISABLED);
[email protected]483fa202013-05-14 01:07:0314500 EXPECT_FALSE(
[email protected]41d64e82013-07-03 22:44:2614501 HasSpdySession(session->spdy_session_pool(), spdy_session_key_a1));
[email protected]483fa202013-05-14 01:07:0314502 HttpRequestInfo request3;
14503 request3.method = "GET";
14504 request3.url = GURL("http://www.a.com/");
14505 request3.load_flags = 0;
[email protected]90499482013-06-01 00:39:5014506 trans.reset(new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]483fa202013-05-14 01:07:0314507
tfarina42834112016-09-22 13:38:2014508 rv = trans->Start(&request3, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0114509 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
14510 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]483fa202013-05-14 01:07:0314511
14512 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5214513 ASSERT_TRUE(response);
14514 ASSERT_TRUE(response->headers);
[email protected]483fa202013-05-14 01:07:0314515 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
14516 EXPECT_FALSE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5214517 EXPECT_FALSE(response->was_alpn_negotiated);
robpercival214763f2016-07-01 23:27:0114518 ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
[email protected]483fa202013-05-14 01:07:0314519 EXPECT_EQ("hello!", response_data);
14520 EXPECT_FALSE(
[email protected]41d64e82013-07-03 22:44:2614521 HasSpdySession(session->spdy_session_pool(), spdy_session_key_a));
[email protected]483fa202013-05-14 01:07:0314522 EXPECT_FALSE(
[email protected]41d64e82013-07-03 22:44:2614523 HasSpdySession(session->spdy_session_pool(), spdy_session_key_b));
[email protected]483fa202013-05-14 01:07:0314524}
14525
bncd16676a2016-07-20 16:23:0114526TEST_F(HttpNetworkTransactionTest, HttpSyncConnectError) {
[email protected]79e1fd62013-06-20 06:50:0414527 HttpRequestInfo request;
14528 request.method = "GET";
bncce36dca22015-04-21 22:11:2314529 request.url = GURL("http://www.example.org/");
[email protected]79e1fd62013-06-20 06:50:0414530
danakj1fd259a02016-04-16 03:17:0914531 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1614532 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]79e1fd62013-06-20 06:50:0414533
ttuttled9dbc652015-09-29 20:00:5914534 MockConnect mock_connect(SYNCHRONOUS, ERR_NAME_NOT_RESOLVED);
[email protected]79e1fd62013-06-20 06:50:0414535 StaticSocketDataProvider data;
14536 data.set_connect_data(mock_connect);
14537 session_deps_.socket_factory->AddSocketDataProvider(&data);
14538
14539 TestCompletionCallback callback;
14540
tfarina42834112016-09-22 13:38:2014541 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0114542 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]79e1fd62013-06-20 06:50:0414543
14544 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0114545 EXPECT_THAT(rv, IsError(ERR_NAME_NOT_RESOLVED));
[email protected]79e1fd62013-06-20 06:50:0414546
[email protected]79e1fd62013-06-20 06:50:0414547 // We don't care whether this succeeds or fails, but it shouldn't crash.
14548 HttpRequestHeaders request_headers;
bnc691fda62016-08-12 00:43:1614549 trans.GetFullRequestHeaders(&request_headers);
ttuttle1f2d7e92015-04-28 16:17:4714550
14551 ConnectionAttempts attempts;
bnc691fda62016-08-12 00:43:1614552 trans.GetConnectionAttempts(&attempts);
ttuttle1f2d7e92015-04-28 16:17:4714553 ASSERT_EQ(1u, attempts.size());
robpercival214763f2016-07-01 23:27:0114554 EXPECT_THAT(attempts[0].result, IsError(ERR_NAME_NOT_RESOLVED));
ttuttled9dbc652015-09-29 20:00:5914555
14556 IPEndPoint endpoint;
bnc691fda62016-08-12 00:43:1614557 EXPECT_FALSE(trans.GetRemoteEndpoint(&endpoint));
ttuttled9dbc652015-09-29 20:00:5914558 EXPECT_TRUE(endpoint.address().empty());
[email protected]79e1fd62013-06-20 06:50:0414559}
14560
bncd16676a2016-07-20 16:23:0114561TEST_F(HttpNetworkTransactionTest, HttpAsyncConnectError) {
[email protected]79e1fd62013-06-20 06:50:0414562 HttpRequestInfo request;
14563 request.method = "GET";
bncce36dca22015-04-21 22:11:2314564 request.url = GURL("http://www.example.org/");
[email protected]79e1fd62013-06-20 06:50:0414565
danakj1fd259a02016-04-16 03:17:0914566 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1614567 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]79e1fd62013-06-20 06:50:0414568
ttuttled9dbc652015-09-29 20:00:5914569 MockConnect mock_connect(ASYNC, ERR_NAME_NOT_RESOLVED);
[email protected]79e1fd62013-06-20 06:50:0414570 StaticSocketDataProvider data;
14571 data.set_connect_data(mock_connect);
14572 session_deps_.socket_factory->AddSocketDataProvider(&data);
14573
14574 TestCompletionCallback callback;
14575
tfarina42834112016-09-22 13:38:2014576 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0114577 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]79e1fd62013-06-20 06:50:0414578
14579 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0114580 EXPECT_THAT(rv, IsError(ERR_NAME_NOT_RESOLVED));
[email protected]79e1fd62013-06-20 06:50:0414581
[email protected]79e1fd62013-06-20 06:50:0414582 // We don't care whether this succeeds or fails, but it shouldn't crash.
14583 HttpRequestHeaders request_headers;
bnc691fda62016-08-12 00:43:1614584 trans.GetFullRequestHeaders(&request_headers);
ttuttle1f2d7e92015-04-28 16:17:4714585
14586 ConnectionAttempts attempts;
bnc691fda62016-08-12 00:43:1614587 trans.GetConnectionAttempts(&attempts);
ttuttle1f2d7e92015-04-28 16:17:4714588 ASSERT_EQ(1u, attempts.size());
robpercival214763f2016-07-01 23:27:0114589 EXPECT_THAT(attempts[0].result, IsError(ERR_NAME_NOT_RESOLVED));
ttuttled9dbc652015-09-29 20:00:5914590
14591 IPEndPoint endpoint;
bnc691fda62016-08-12 00:43:1614592 EXPECT_FALSE(trans.GetRemoteEndpoint(&endpoint));
ttuttled9dbc652015-09-29 20:00:5914593 EXPECT_TRUE(endpoint.address().empty());
[email protected]79e1fd62013-06-20 06:50:0414594}
14595
bncd16676a2016-07-20 16:23:0114596TEST_F(HttpNetworkTransactionTest, HttpSyncWriteError) {
[email protected]79e1fd62013-06-20 06:50:0414597 HttpRequestInfo request;
14598 request.method = "GET";
bncce36dca22015-04-21 22:11:2314599 request.url = GURL("http://www.example.org/");
[email protected]79e1fd62013-06-20 06:50:0414600
danakj1fd259a02016-04-16 03:17:0914601 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1614602 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]79e1fd62013-06-20 06:50:0414603
14604 MockWrite data_writes[] = {
14605 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
14606 };
14607 MockRead data_reads[] = {
14608 MockRead(SYNCHRONOUS, ERR_UNEXPECTED), // Should not be reached.
14609 };
14610
14611 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
14612 data_writes, arraysize(data_writes));
14613 session_deps_.socket_factory->AddSocketDataProvider(&data);
14614
14615 TestCompletionCallback callback;
14616
tfarina42834112016-09-22 13:38:2014617 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0114618 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]79e1fd62013-06-20 06:50:0414619
14620 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0114621 EXPECT_THAT(rv, IsError(ERR_CONNECTION_RESET));
[email protected]79e1fd62013-06-20 06:50:0414622
[email protected]79e1fd62013-06-20 06:50:0414623 HttpRequestHeaders request_headers;
bnc691fda62016-08-12 00:43:1614624 EXPECT_TRUE(trans.GetFullRequestHeaders(&request_headers));
[email protected]79e1fd62013-06-20 06:50:0414625 EXPECT_TRUE(request_headers.HasHeader("Host"));
14626}
14627
bncd16676a2016-07-20 16:23:0114628TEST_F(HttpNetworkTransactionTest, HttpAsyncWriteError) {
[email protected]79e1fd62013-06-20 06:50:0414629 HttpRequestInfo request;
14630 request.method = "GET";
bncce36dca22015-04-21 22:11:2314631 request.url = GURL("http://www.example.org/");
[email protected]79e1fd62013-06-20 06:50:0414632
danakj1fd259a02016-04-16 03:17:0914633 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1614634 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]79e1fd62013-06-20 06:50:0414635
14636 MockWrite data_writes[] = {
14637 MockWrite(ASYNC, ERR_CONNECTION_RESET),
14638 };
14639 MockRead data_reads[] = {
14640 MockRead(SYNCHRONOUS, ERR_UNEXPECTED), // Should not be reached.
14641 };
14642
14643 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
14644 data_writes, arraysize(data_writes));
14645 session_deps_.socket_factory->AddSocketDataProvider(&data);
14646
14647 TestCompletionCallback callback;
14648
tfarina42834112016-09-22 13:38:2014649 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0114650 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]79e1fd62013-06-20 06:50:0414651
14652 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0114653 EXPECT_THAT(rv, IsError(ERR_CONNECTION_RESET));
[email protected]79e1fd62013-06-20 06:50:0414654
[email protected]79e1fd62013-06-20 06:50:0414655 HttpRequestHeaders request_headers;
bnc691fda62016-08-12 00:43:1614656 EXPECT_TRUE(trans.GetFullRequestHeaders(&request_headers));
[email protected]79e1fd62013-06-20 06:50:0414657 EXPECT_TRUE(request_headers.HasHeader("Host"));
14658}
14659
bncd16676a2016-07-20 16:23:0114660TEST_F(HttpNetworkTransactionTest, HttpSyncReadError) {
[email protected]79e1fd62013-06-20 06:50:0414661 HttpRequestInfo request;
14662 request.method = "GET";
bncce36dca22015-04-21 22:11:2314663 request.url = GURL("http://www.example.org/");
[email protected]79e1fd62013-06-20 06:50:0414664
danakj1fd259a02016-04-16 03:17:0914665 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1614666 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]79e1fd62013-06-20 06:50:0414667
14668 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:2314669 MockWrite(
14670 "GET / HTTP/1.1\r\n"
14671 "Host: www.example.org\r\n"
14672 "Connection: keep-alive\r\n\r\n"),
[email protected]79e1fd62013-06-20 06:50:0414673 };
14674 MockRead data_reads[] = {
14675 MockRead(SYNCHRONOUS, ERR_CONNECTION_RESET),
14676 };
14677
14678 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
14679 data_writes, arraysize(data_writes));
14680 session_deps_.socket_factory->AddSocketDataProvider(&data);
14681
14682 TestCompletionCallback callback;
14683
tfarina42834112016-09-22 13:38:2014684 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0114685 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]79e1fd62013-06-20 06:50:0414686
14687 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0114688 EXPECT_THAT(rv, IsError(ERR_CONNECTION_RESET));
[email protected]79e1fd62013-06-20 06:50:0414689
[email protected]79e1fd62013-06-20 06:50:0414690 HttpRequestHeaders request_headers;
bnc691fda62016-08-12 00:43:1614691 EXPECT_TRUE(trans.GetFullRequestHeaders(&request_headers));
[email protected]79e1fd62013-06-20 06:50:0414692 EXPECT_TRUE(request_headers.HasHeader("Host"));
14693}
14694
bncd16676a2016-07-20 16:23:0114695TEST_F(HttpNetworkTransactionTest, HttpAsyncReadError) {
[email protected]79e1fd62013-06-20 06:50:0414696 HttpRequestInfo request;
14697 request.method = "GET";
bncce36dca22015-04-21 22:11:2314698 request.url = GURL("http://www.example.org/");
[email protected]79e1fd62013-06-20 06:50:0414699
danakj1fd259a02016-04-16 03:17:0914700 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1614701 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]79e1fd62013-06-20 06:50:0414702
14703 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:2314704 MockWrite(
14705 "GET / HTTP/1.1\r\n"
14706 "Host: www.example.org\r\n"
14707 "Connection: keep-alive\r\n\r\n"),
[email protected]79e1fd62013-06-20 06:50:0414708 };
14709 MockRead data_reads[] = {
14710 MockRead(ASYNC, ERR_CONNECTION_RESET),
14711 };
14712
14713 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
14714 data_writes, arraysize(data_writes));
14715 session_deps_.socket_factory->AddSocketDataProvider(&data);
14716
14717 TestCompletionCallback callback;
14718
tfarina42834112016-09-22 13:38:2014719 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0114720 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]79e1fd62013-06-20 06:50:0414721
14722 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0114723 EXPECT_THAT(rv, IsError(ERR_CONNECTION_RESET));
[email protected]79e1fd62013-06-20 06:50:0414724
[email protected]79e1fd62013-06-20 06:50:0414725 HttpRequestHeaders request_headers;
bnc691fda62016-08-12 00:43:1614726 EXPECT_TRUE(trans.GetFullRequestHeaders(&request_headers));
[email protected]79e1fd62013-06-20 06:50:0414727 EXPECT_TRUE(request_headers.HasHeader("Host"));
14728}
14729
bncd16676a2016-07-20 16:23:0114730TEST_F(HttpNetworkTransactionTest, GetFullRequestHeadersIncludesExtraHeader) {
[email protected]79e1fd62013-06-20 06:50:0414731 HttpRequestInfo request;
14732 request.method = "GET";
bncce36dca22015-04-21 22:11:2314733 request.url = GURL("http://www.example.org/");
[email protected]79e1fd62013-06-20 06:50:0414734 request.extra_headers.SetHeader("X-Foo", "bar");
14735
danakj1fd259a02016-04-16 03:17:0914736 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1614737 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]79e1fd62013-06-20 06:50:0414738
14739 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:2314740 MockWrite(
14741 "GET / HTTP/1.1\r\n"
14742 "Host: www.example.org\r\n"
14743 "Connection: keep-alive\r\n"
14744 "X-Foo: bar\r\n\r\n"),
[email protected]79e1fd62013-06-20 06:50:0414745 };
14746 MockRead data_reads[] = {
14747 MockRead("HTTP/1.1 200 OK\r\n"
14748 "Content-Length: 5\r\n\r\n"
14749 "hello"),
14750 MockRead(ASYNC, ERR_UNEXPECTED),
14751 };
14752
14753 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
14754 data_writes, arraysize(data_writes));
14755 session_deps_.socket_factory->AddSocketDataProvider(&data);
14756
14757 TestCompletionCallback callback;
14758
tfarina42834112016-09-22 13:38:2014759 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0114760 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]79e1fd62013-06-20 06:50:0414761
14762 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0114763 EXPECT_THAT(rv, IsOk());
[email protected]79e1fd62013-06-20 06:50:0414764
14765 HttpRequestHeaders request_headers;
bnc691fda62016-08-12 00:43:1614766 EXPECT_TRUE(trans.GetFullRequestHeaders(&request_headers));
[email protected]79e1fd62013-06-20 06:50:0414767 std::string foo;
14768 EXPECT_TRUE(request_headers.GetHeader("X-Foo", &foo));
14769 EXPECT_EQ("bar", foo);
14770}
14771
[email protected]bf828982013-08-14 18:01:4714772namespace {
14773
yhiranoa7e05bb2014-11-06 05:40:3914774// Fake HttpStream that simply records calls to SetPriority().
14775class FakeStream : public HttpStream,
[email protected]e86839fd2013-08-14 18:29:0314776 public base::SupportsWeakPtr<FakeStream> {
14777 public:
14778 explicit FakeStream(RequestPriority priority) : priority_(priority) {}
dchengb03027d2014-10-21 12:00:2014779 ~FakeStream() override {}
[email protected]e86839fd2013-08-14 18:29:0314780
14781 RequestPriority priority() const { return priority_; }
14782
dchengb03027d2014-10-21 12:00:2014783 int InitializeStream(const HttpRequestInfo* request_info,
14784 RequestPriority priority,
tfarina42834112016-09-22 13:38:2014785 const NetLogWithSource& net_log,
dchengb03027d2014-10-21 12:00:2014786 const CompletionCallback& callback) override {
[email protected]e86839fd2013-08-14 18:29:0314787 return ERR_IO_PENDING;
14788 }
14789
dchengb03027d2014-10-21 12:00:2014790 int SendRequest(const HttpRequestHeaders& request_headers,
14791 HttpResponseInfo* response,
14792 const CompletionCallback& callback) override {
[email protected]e86839fd2013-08-14 18:29:0314793 ADD_FAILURE();
14794 return ERR_UNEXPECTED;
14795 }
14796
dchengb03027d2014-10-21 12:00:2014797 int ReadResponseHeaders(const CompletionCallback& callback) override {
[email protected]e86839fd2013-08-14 18:29:0314798 ADD_FAILURE();
14799 return ERR_UNEXPECTED;
14800 }
14801
dchengb03027d2014-10-21 12:00:2014802 int ReadResponseBody(IOBuffer* buf,
14803 int buf_len,
14804 const CompletionCallback& callback) override {
[email protected]e86839fd2013-08-14 18:29:0314805 ADD_FAILURE();
14806 return ERR_UNEXPECTED;
14807 }
14808
dchengb03027d2014-10-21 12:00:2014809 void Close(bool not_reusable) override {}
[email protected]e86839fd2013-08-14 18:29:0314810
dchengb03027d2014-10-21 12:00:2014811 bool IsResponseBodyComplete() const override {
[email protected]e86839fd2013-08-14 18:29:0314812 ADD_FAILURE();
14813 return false;
14814 }
14815
dchengb03027d2014-10-21 12:00:2014816 bool IsConnectionReused() const override {
[email protected]e86839fd2013-08-14 18:29:0314817 ADD_FAILURE();
14818 return false;
14819 }
14820
dchengb03027d2014-10-21 12:00:2014821 void SetConnectionReused() override { ADD_FAILURE(); }
[email protected]e86839fd2013-08-14 18:29:0314822
mmenkebd84c392015-09-02 14:12:3414823 bool CanReuseConnection() const override { return false; }
[email protected]e86839fd2013-08-14 18:29:0314824
sclittle4de1bab92015-09-22 21:28:2414825 int64_t GetTotalReceivedBytes() const override {
[email protected]bc92bc972013-12-13 08:32:5914826 ADD_FAILURE();
14827 return 0;
14828 }
14829
sclittlebe1ccf62015-09-02 19:40:3614830 int64_t GetTotalSentBytes() const override {
14831 ADD_FAILURE();
14832 return 0;
14833 }
14834
dchengb03027d2014-10-21 12:00:2014835 bool GetLoadTimingInfo(LoadTimingInfo* load_timing_info) const override {
[email protected]e86839fd2013-08-14 18:29:0314836 ADD_FAILURE();
14837 return false;
14838 }
14839
dchengb03027d2014-10-21 12:00:2014840 void GetSSLInfo(SSLInfo* ssl_info) override { ADD_FAILURE(); }
14841
14842 void GetSSLCertRequestInfo(SSLCertRequestInfo* cert_request_info) override {
[email protected]e86839fd2013-08-14 18:29:0314843 ADD_FAILURE();
14844 }
14845
ttuttled9dbc652015-09-29 20:00:5914846 bool GetRemoteEndpoint(IPEndPoint* endpoint) override { return false; }
14847
nharper78e6d2b2016-09-21 05:42:3514848 Error GetTokenBindingSignature(crypto::ECPrivateKey* key,
14849 TokenBindingType tb_type,
14850 std::vector<uint8_t>* out) override {
nharperb7441ef2016-01-25 23:54:1414851 ADD_FAILURE();
14852 return ERR_NOT_IMPLEMENTED;
14853 }
14854
dchengb03027d2014-10-21 12:00:2014855 void Drain(HttpNetworkSession* session) override { ADD_FAILURE(); }
[email protected]e86839fd2013-08-14 18:29:0314856
zhongyica364fbb2015-12-12 03:39:1214857 void PopulateNetErrorDetails(NetErrorDetails* details) override { return; }
14858
dchengb03027d2014-10-21 12:00:2014859 void SetPriority(RequestPriority priority) override { priority_ = priority; }
[email protected]e86839fd2013-08-14 18:29:0314860
yhiranoa7e05bb2014-11-06 05:40:3914861 HttpStream* RenewStreamForAuth() override { return NULL; }
14862
[email protected]e86839fd2013-08-14 18:29:0314863 private:
14864 RequestPriority priority_;
14865
14866 DISALLOW_COPY_AND_ASSIGN(FakeStream);
14867};
14868
14869// Fake HttpStreamRequest that simply records calls to SetPriority()
14870// and vends FakeStreams with its current priority.
[email protected]bf828982013-08-14 18:01:4714871class FakeStreamRequest : public HttpStreamRequest,
14872 public base::SupportsWeakPtr<FakeStreamRequest> {
14873 public:
[email protected]e86839fd2013-08-14 18:29:0314874 FakeStreamRequest(RequestPriority priority,
14875 HttpStreamRequest::Delegate* delegate)
14876 : priority_(priority),
[email protected]831e4a32013-11-14 02:14:4414877 delegate_(delegate),
14878 websocket_stream_create_helper_(NULL) {}
14879
14880 FakeStreamRequest(RequestPriority priority,
14881 HttpStreamRequest::Delegate* delegate,
14882 WebSocketHandshakeStreamBase::CreateHelper* create_helper)
14883 : priority_(priority),
14884 delegate_(delegate),
14885 websocket_stream_create_helper_(create_helper) {}
[email protected]e86839fd2013-08-14 18:29:0314886
dchengb03027d2014-10-21 12:00:2014887 ~FakeStreamRequest() override {}
[email protected]bf828982013-08-14 18:01:4714888
14889 RequestPriority priority() const { return priority_; }
14890
[email protected]831e4a32013-11-14 02:14:4414891 const WebSocketHandshakeStreamBase::CreateHelper*
14892 websocket_stream_create_helper() const {
14893 return websocket_stream_create_helper_;
14894 }
14895
[email protected]e86839fd2013-08-14 18:29:0314896 // Create a new FakeStream and pass it to the request's
14897 // delegate. Returns a weak pointer to the FakeStream.
14898 base::WeakPtr<FakeStream> FinishStreamRequest() {
14899 FakeStream* fake_stream = new FakeStream(priority_);
14900 // Do this before calling OnStreamReady() as OnStreamReady() may
14901 // immediately delete |fake_stream|.
14902 base::WeakPtr<FakeStream> weak_stream = fake_stream->AsWeakPtr();
14903 delegate_->OnStreamReady(SSLConfig(), ProxyInfo(), fake_stream);
14904 return weak_stream;
14905 }
14906
dchengb03027d2014-10-21 12:00:2014907 int RestartTunnelWithProxyAuth(const AuthCredentials& credentials) override {
[email protected]bf828982013-08-14 18:01:4714908 ADD_FAILURE();
14909 return ERR_UNEXPECTED;
14910 }
14911
dchengb03027d2014-10-21 12:00:2014912 LoadState GetLoadState() const override {
[email protected]bf828982013-08-14 18:01:4714913 ADD_FAILURE();
14914 return LoadState();
14915 }
14916
dchengb03027d2014-10-21 12:00:2014917 void SetPriority(RequestPriority priority) override { priority_ = priority; }
[email protected]bf828982013-08-14 18:01:4714918
bnc94c92842016-09-21 15:22:5214919 bool was_alpn_negotiated() const override { return false; }
[email protected]bf828982013-08-14 18:01:4714920
bnc6227b26e2016-08-12 02:00:4314921 NextProto negotiated_protocol() const override { return kProtoUnknown; }
[email protected]bf828982013-08-14 18:01:4714922
dchengb03027d2014-10-21 12:00:2014923 bool using_spdy() const override { return false; }
[email protected]bf828982013-08-14 18:01:4714924
ttuttle1f2d7e92015-04-28 16:17:4714925 const ConnectionAttempts& connection_attempts() const override {
14926 static ConnectionAttempts no_attempts;
14927 return no_attempts;
14928 }
14929
[email protected]bf828982013-08-14 18:01:4714930 private:
14931 RequestPriority priority_;
[email protected]e86839fd2013-08-14 18:29:0314932 HttpStreamRequest::Delegate* const delegate_;
[email protected]831e4a32013-11-14 02:14:4414933 WebSocketHandshakeStreamBase::CreateHelper* websocket_stream_create_helper_;
[email protected]bf828982013-08-14 18:01:4714934
14935 DISALLOW_COPY_AND_ASSIGN(FakeStreamRequest);
14936};
14937
14938// Fake HttpStreamFactory that vends FakeStreamRequests.
14939class FakeStreamFactory : public HttpStreamFactory {
14940 public:
14941 FakeStreamFactory() {}
dchengb03027d2014-10-21 12:00:2014942 ~FakeStreamFactory() override {}
[email protected]bf828982013-08-14 18:01:4714943
14944 // Returns a WeakPtr<> to the last HttpStreamRequest returned by
14945 // RequestStream() (which may be NULL if it was destroyed already).
14946 base::WeakPtr<FakeStreamRequest> last_stream_request() {
14947 return last_stream_request_;
14948 }
14949
dchengb03027d2014-10-21 12:00:2014950 HttpStreamRequest* RequestStream(const HttpRequestInfo& info,
14951 RequestPriority priority,
14952 const SSLConfig& server_ssl_config,
14953 const SSLConfig& proxy_ssl_config,
14954 HttpStreamRequest::Delegate* delegate,
tfarina42834112016-09-22 13:38:2014955 const NetLogWithSource& net_log) override {
[email protected]e86839fd2013-08-14 18:29:0314956 FakeStreamRequest* fake_request = new FakeStreamRequest(priority, delegate);
[email protected]bf828982013-08-14 18:01:4714957 last_stream_request_ = fake_request->AsWeakPtr();
14958 return fake_request;
14959 }
14960
xunjieli5749218c2016-03-22 16:43:0614961 HttpStreamRequest* RequestBidirectionalStreamImpl(
xunjieli11834f02015-12-22 04:27:0814962 const HttpRequestInfo& info,
14963 RequestPriority priority,
14964 const SSLConfig& server_ssl_config,
14965 const SSLConfig& proxy_ssl_config,
14966 HttpStreamRequest::Delegate* delegate,
tfarina42834112016-09-22 13:38:2014967 const NetLogWithSource& net_log) override {
xunjieli11834f02015-12-22 04:27:0814968 NOTREACHED();
14969 return nullptr;
14970 }
14971
dchengb03027d2014-10-21 12:00:2014972 HttpStreamRequest* RequestWebSocketHandshakeStream(
[email protected]bf828982013-08-14 18:01:4714973 const HttpRequestInfo& info,
14974 RequestPriority priority,
14975 const SSLConfig& server_ssl_config,
14976 const SSLConfig& proxy_ssl_config,
14977 HttpStreamRequest::Delegate* delegate,
[email protected]467086b2013-11-12 08:19:4614978 WebSocketHandshakeStreamBase::CreateHelper* create_helper,
tfarina42834112016-09-22 13:38:2014979 const NetLogWithSource& net_log) override {
[email protected]831e4a32013-11-14 02:14:4414980 FakeStreamRequest* fake_request =
14981 new FakeStreamRequest(priority, delegate, create_helper);
14982 last_stream_request_ = fake_request->AsWeakPtr();
14983 return fake_request;
[email protected]bf828982013-08-14 18:01:4714984 }
14985
dchengb03027d2014-10-21 12:00:2014986 void PreconnectStreams(int num_streams,
nharper8cdb0fb2016-04-22 21:34:5914987 const HttpRequestInfo& info) override {
[email protected]bf828982013-08-14 18:01:4714988 ADD_FAILURE();
14989 }
14990
dchengb03027d2014-10-21 12:00:2014991 const HostMappingRules* GetHostMappingRules() const override {
[email protected]bf828982013-08-14 18:01:4714992 ADD_FAILURE();
14993 return NULL;
14994 }
14995
xunjielif5267de2017-01-20 21:18:5714996 void DumpMemoryStats(base::trace_event::ProcessMemoryDump* pmd,
14997 const std::string& parent_absolute_name) const override {
14998 ADD_FAILURE();
14999 }
15000
[email protected]bf828982013-08-14 18:01:4715001 private:
15002 base::WeakPtr<FakeStreamRequest> last_stream_request_;
15003
15004 DISALLOW_COPY_AND_ASSIGN(FakeStreamFactory);
15005};
15006
Adam Rice425cf122015-01-19 06:18:2415007// TODO(ricea): Maybe unify this with the one in
15008// url_request_http_job_unittest.cc ?
15009class FakeWebSocketBasicHandshakeStream : public WebSocketHandshakeStreamBase {
15010 public:
danakj1fd259a02016-04-16 03:17:0915011 FakeWebSocketBasicHandshakeStream(
15012 std::unique_ptr<ClientSocketHandle> connection,
15013 bool using_proxy)
mmenkea7da6da2016-09-01 21:56:5215014 : state_(std::move(connection), using_proxy, false) {}
Adam Rice425cf122015-01-19 06:18:2415015
15016 // Fake implementation of HttpStreamBase methods.
15017 // This ends up being quite "real" because this object has to really send data
15018 // on the mock socket. It might be easier to use the real implementation, but
15019 // the fact that the WebSocket code is not compiled on iOS makes that
15020 // difficult.
15021 int InitializeStream(const HttpRequestInfo* request_info,
15022 RequestPriority priority,
tfarina42834112016-09-22 13:38:2015023 const NetLogWithSource& net_log,
Adam Rice425cf122015-01-19 06:18:2415024 const CompletionCallback& callback) override {
15025 state_.Initialize(request_info, priority, net_log, callback);
15026 return OK;
15027 }
15028
15029 int SendRequest(const HttpRequestHeaders& request_headers,
15030 HttpResponseInfo* response,
15031 const CompletionCallback& callback) override {
15032 return parser()->SendRequest(state_.GenerateRequestLine(), request_headers,
15033 response, callback);
15034 }
15035
15036 int ReadResponseHeaders(const CompletionCallback& callback) override {
15037 return parser()->ReadResponseHeaders(callback);
15038 }
15039
15040 int ReadResponseBody(IOBuffer* buf,
15041 int buf_len,
15042 const CompletionCallback& callback) override {
15043 NOTREACHED();
15044 return ERR_IO_PENDING;
15045 }
15046
15047 void Close(bool not_reusable) override {
15048 if (parser())
15049 parser()->Close(true);
15050 }
15051
15052 bool IsResponseBodyComplete() const override {
15053 NOTREACHED();
15054 return false;
15055 }
15056
Adam Rice425cf122015-01-19 06:18:2415057 bool IsConnectionReused() const override {
15058 NOTREACHED();
15059 return false;
15060 }
15061 void SetConnectionReused() override { NOTREACHED(); }
15062
mmenkebd84c392015-09-02 14:12:3415063 bool CanReuseConnection() const override { return false; }
Adam Rice425cf122015-01-19 06:18:2415064
sclittle4de1bab92015-09-22 21:28:2415065 int64_t GetTotalReceivedBytes() const override {
Adam Rice425cf122015-01-19 06:18:2415066 NOTREACHED();
15067 return 0;
15068 }
15069
sclittlebe1ccf62015-09-02 19:40:3615070 int64_t GetTotalSentBytes() const override {
15071 NOTREACHED();
15072 return 0;
15073 }
15074
Adam Rice425cf122015-01-19 06:18:2415075 bool GetLoadTimingInfo(LoadTimingInfo* load_timing_info) const override {
15076 NOTREACHED();
15077 return false;
15078 }
15079
Adam Ricecb76ac62015-02-20 05:33:2515080 void GetSSLInfo(SSLInfo* ssl_info) override {}
Adam Rice425cf122015-01-19 06:18:2415081
15082 void GetSSLCertRequestInfo(SSLCertRequestInfo* cert_request_info) override {
15083 NOTREACHED();
15084 }
15085
ttuttled9dbc652015-09-29 20:00:5915086 bool GetRemoteEndpoint(IPEndPoint* endpoint) override { return false; }
15087
nharper78e6d2b2016-09-21 05:42:3515088 Error GetTokenBindingSignature(crypto::ECPrivateKey* key,
15089 TokenBindingType tb_type,
15090 std::vector<uint8_t>* out) override {
nharperb7441ef2016-01-25 23:54:1415091 ADD_FAILURE();
15092 return ERR_NOT_IMPLEMENTED;
15093 }
15094
Adam Rice425cf122015-01-19 06:18:2415095 void Drain(HttpNetworkSession* session) override { NOTREACHED(); }
15096
zhongyica364fbb2015-12-12 03:39:1215097 void PopulateNetErrorDetails(NetErrorDetails* details) override { return; }
15098
Adam Rice425cf122015-01-19 06:18:2415099 void SetPriority(RequestPriority priority) override { NOTREACHED(); }
15100
Adam Rice425cf122015-01-19 06:18:2415101 HttpStream* RenewStreamForAuth() override {
15102 NOTREACHED();
15103 return nullptr;
15104 }
15105
15106 // Fake implementation of WebSocketHandshakeStreamBase method(s)
danakj1fd259a02016-04-16 03:17:0915107 std::unique_ptr<WebSocketStream> Upgrade() override {
Adam Rice425cf122015-01-19 06:18:2415108 NOTREACHED();
danakj1fd259a02016-04-16 03:17:0915109 return std::unique_ptr<WebSocketStream>();
Adam Rice425cf122015-01-19 06:18:2415110 }
15111
15112 private:
15113 HttpStreamParser* parser() const { return state_.parser(); }
15114 HttpBasicState state_;
15115
15116 DISALLOW_COPY_AND_ASSIGN(FakeWebSocketBasicHandshakeStream);
15117};
15118
[email protected]831e4a32013-11-14 02:14:4415119// TODO(yhirano): Split this class out into a net/websockets file, if it is
15120// worth doing.
15121class FakeWebSocketStreamCreateHelper :
15122 public WebSocketHandshakeStreamBase::CreateHelper {
15123 public:
dchengb03027d2014-10-21 12:00:2015124 WebSocketHandshakeStreamBase* CreateBasicStream(
danakj1fd259a02016-04-16 03:17:0915125 std::unique_ptr<ClientSocketHandle> connection,
mostynbba063d6032014-10-09 11:01:1315126 bool using_proxy) override {
dchengc7eeda422015-12-26 03:56:4815127 return new FakeWebSocketBasicHandshakeStream(std::move(connection),
Adam Rice425cf122015-01-19 06:18:2415128 using_proxy);
[email protected]831e4a32013-11-14 02:14:4415129 }
15130
dchengb03027d2014-10-21 12:00:2015131 WebSocketHandshakeStreamBase* CreateSpdyStream(
[email protected]831e4a32013-11-14 02:14:4415132 const base::WeakPtr<SpdySession>& session,
mostynbba063d6032014-10-09 11:01:1315133 bool use_relative_url) override {
[email protected]831e4a32013-11-14 02:14:4415134 NOTREACHED();
15135 return NULL;
15136 };
15137
dchengb03027d2014-10-21 12:00:2015138 ~FakeWebSocketStreamCreateHelper() override {}
[email protected]831e4a32013-11-14 02:14:4415139
danakj1fd259a02016-04-16 03:17:0915140 virtual std::unique_ptr<WebSocketStream> Upgrade() {
[email protected]831e4a32013-11-14 02:14:4415141 NOTREACHED();
danakj1fd259a02016-04-16 03:17:0915142 return std::unique_ptr<WebSocketStream>();
[email protected]831e4a32013-11-14 02:14:4415143 }
15144};
15145
[email protected]bf828982013-08-14 18:01:4715146} // namespace
15147
15148// Make sure that HttpNetworkTransaction passes on its priority to its
15149// stream request on start.
bncd16676a2016-07-20 16:23:0115150TEST_F(HttpNetworkTransactionTest, SetStreamRequestPriorityOnStart) {
danakj1fd259a02016-04-16 03:17:0915151 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
mmenkee65e7af2015-10-13 17:16:4215152 HttpNetworkSessionPeer peer(session.get());
[email protected]bf828982013-08-14 18:01:4715153 FakeStreamFactory* fake_factory = new FakeStreamFactory();
danakj1fd259a02016-04-16 03:17:0915154 peer.SetHttpStreamFactory(std::unique_ptr<HttpStreamFactory>(fake_factory));
[email protected]bf828982013-08-14 18:01:4715155
krasinc06a72a2016-12-21 03:42:4615156 HttpRequestInfo request;
dcheng48459ac22014-08-26 00:46:4115157 HttpNetworkTransaction trans(LOW, session.get());
[email protected]bf828982013-08-14 18:01:4715158
wezca1070932016-05-26 20:30:5215159 ASSERT_FALSE(fake_factory->last_stream_request());
[email protected]bf828982013-08-14 18:01:4715160
[email protected]bf828982013-08-14 18:01:4715161 TestCompletionCallback callback;
15162 EXPECT_EQ(ERR_IO_PENDING,
tfarina42834112016-09-22 13:38:2015163 trans.Start(&request, callback.callback(), NetLogWithSource()));
[email protected]bf828982013-08-14 18:01:4715164
15165 base::WeakPtr<FakeStreamRequest> fake_request =
15166 fake_factory->last_stream_request();
wezca1070932016-05-26 20:30:5215167 ASSERT_TRUE(fake_request);
[email protected]bf828982013-08-14 18:01:4715168 EXPECT_EQ(LOW, fake_request->priority());
15169}
15170
15171// Make sure that HttpNetworkTransaction passes on its priority
15172// updates to its stream request.
bncd16676a2016-07-20 16:23:0115173TEST_F(HttpNetworkTransactionTest, SetStreamRequestPriority) {
danakj1fd259a02016-04-16 03:17:0915174 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
mmenkee65e7af2015-10-13 17:16:4215175 HttpNetworkSessionPeer peer(session.get());
[email protected]bf828982013-08-14 18:01:4715176 FakeStreamFactory* fake_factory = new FakeStreamFactory();
danakj1fd259a02016-04-16 03:17:0915177 peer.SetHttpStreamFactory(std::unique_ptr<HttpStreamFactory>(fake_factory));
[email protected]bf828982013-08-14 18:01:4715178
krasinc06a72a2016-12-21 03:42:4615179 HttpRequestInfo request;
dcheng48459ac22014-08-26 00:46:4115180 HttpNetworkTransaction trans(LOW, session.get());
[email protected]bf828982013-08-14 18:01:4715181
[email protected]bf828982013-08-14 18:01:4715182 TestCompletionCallback callback;
15183 EXPECT_EQ(ERR_IO_PENDING,
tfarina42834112016-09-22 13:38:2015184 trans.Start(&request, callback.callback(), NetLogWithSource()));
[email protected]bf828982013-08-14 18:01:4715185
15186 base::WeakPtr<FakeStreamRequest> fake_request =
15187 fake_factory->last_stream_request();
wezca1070932016-05-26 20:30:5215188 ASSERT_TRUE(fake_request);
[email protected]bf828982013-08-14 18:01:4715189 EXPECT_EQ(LOW, fake_request->priority());
15190
15191 trans.SetPriority(LOWEST);
wezca1070932016-05-26 20:30:5215192 ASSERT_TRUE(fake_request);
[email protected]bf828982013-08-14 18:01:4715193 EXPECT_EQ(LOWEST, fake_request->priority());
15194}
15195
[email protected]e86839fd2013-08-14 18:29:0315196// Make sure that HttpNetworkTransaction passes on its priority
15197// updates to its stream.
bncd16676a2016-07-20 16:23:0115198TEST_F(HttpNetworkTransactionTest, SetStreamPriority) {
danakj1fd259a02016-04-16 03:17:0915199 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
mmenkee65e7af2015-10-13 17:16:4215200 HttpNetworkSessionPeer peer(session.get());
[email protected]e86839fd2013-08-14 18:29:0315201 FakeStreamFactory* fake_factory = new FakeStreamFactory();
danakj1fd259a02016-04-16 03:17:0915202 peer.SetHttpStreamFactory(std::unique_ptr<HttpStreamFactory>(fake_factory));
[email protected]e86839fd2013-08-14 18:29:0315203
krasinc06a72a2016-12-21 03:42:4615204 HttpRequestInfo request;
dcheng48459ac22014-08-26 00:46:4115205 HttpNetworkTransaction trans(LOW, session.get());
[email protected]e86839fd2013-08-14 18:29:0315206
[email protected]e86839fd2013-08-14 18:29:0315207 TestCompletionCallback callback;
15208 EXPECT_EQ(ERR_IO_PENDING,
tfarina42834112016-09-22 13:38:2015209 trans.Start(&request, callback.callback(), NetLogWithSource()));
[email protected]e86839fd2013-08-14 18:29:0315210
15211 base::WeakPtr<FakeStreamRequest> fake_request =
15212 fake_factory->last_stream_request();
wezca1070932016-05-26 20:30:5215213 ASSERT_TRUE(fake_request);
[email protected]e86839fd2013-08-14 18:29:0315214 base::WeakPtr<FakeStream> fake_stream = fake_request->FinishStreamRequest();
wezca1070932016-05-26 20:30:5215215 ASSERT_TRUE(fake_stream);
[email protected]e86839fd2013-08-14 18:29:0315216 EXPECT_EQ(LOW, fake_stream->priority());
15217
15218 trans.SetPriority(LOWEST);
15219 EXPECT_EQ(LOWEST, fake_stream->priority());
15220}
15221
bncd16676a2016-07-20 16:23:0115222TEST_F(HttpNetworkTransactionTest, CreateWebSocketHandshakeStream) {
[email protected]831e4a32013-11-14 02:14:4415223 // The same logic needs to be tested for both ws: and wss: schemes, but this
15224 // test is already parameterised on NextProto, so it uses a loop to verify
15225 // that the different schemes work.
bncce36dca22015-04-21 22:11:2315226 std::string test_cases[] = {"ws://www.example.org/",
15227 "wss://www.example.org/"};
[email protected]831e4a32013-11-14 02:14:4415228 for (size_t i = 0; i < arraysize(test_cases); ++i) {
danakj1fd259a02016-04-16 03:17:0915229 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
mmenkee65e7af2015-10-13 17:16:4215230 HttpNetworkSessionPeer peer(session.get());
[email protected]831e4a32013-11-14 02:14:4415231 FakeStreamFactory* fake_factory = new FakeStreamFactory();
15232 FakeWebSocketStreamCreateHelper websocket_stream_create_helper;
[email protected]0191b51c2013-11-18 10:55:2315233 peer.SetHttpStreamFactoryForWebSocket(
danakj1fd259a02016-04-16 03:17:0915234 std::unique_ptr<HttpStreamFactory>(fake_factory));
[email protected]831e4a32013-11-14 02:14:4415235
krasinc06a72a2016-12-21 03:42:4615236 HttpRequestInfo request;
dcheng48459ac22014-08-26 00:46:4115237 HttpNetworkTransaction trans(LOW, session.get());
[email protected]831e4a32013-11-14 02:14:4415238 trans.SetWebSocketHandshakeStreamCreateHelper(
15239 &websocket_stream_create_helper);
15240
[email protected]831e4a32013-11-14 02:14:4415241 TestCompletionCallback callback;
15242 request.method = "GET";
15243 request.url = GURL(test_cases[i]);
15244
15245 EXPECT_EQ(ERR_IO_PENDING,
tfarina42834112016-09-22 13:38:2015246 trans.Start(&request, callback.callback(), NetLogWithSource()));
[email protected]831e4a32013-11-14 02:14:4415247
15248 base::WeakPtr<FakeStreamRequest> fake_request =
15249 fake_factory->last_stream_request();
wezca1070932016-05-26 20:30:5215250 ASSERT_TRUE(fake_request);
[email protected]831e4a32013-11-14 02:14:4415251 EXPECT_EQ(&websocket_stream_create_helper,
15252 fake_request->websocket_stream_create_helper());
15253 }
15254}
15255
[email protected]043b68c82013-08-22 23:41:5215256// Tests that when a used socket is returned to the SSL socket pool, it's closed
15257// if the transport socket pool is stalled on the global socket limit.
bncd16676a2016-07-20 16:23:0115258TEST_F(HttpNetworkTransactionTest, CloseSSLSocketOnIdleForHttpRequest) {
[email protected]043b68c82013-08-22 23:41:5215259 ClientSocketPoolManager::set_max_sockets_per_group(
15260 HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
15261 ClientSocketPoolManager::set_max_sockets_per_pool(
15262 HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
15263
15264 // Set up SSL request.
15265
15266 HttpRequestInfo ssl_request;
15267 ssl_request.method = "GET";
bncce36dca22015-04-21 22:11:2315268 ssl_request.url = GURL("https://www.example.org/");
[email protected]043b68c82013-08-22 23:41:5215269
15270 MockWrite ssl_writes[] = {
bncce36dca22015-04-21 22:11:2315271 MockWrite(
15272 "GET / HTTP/1.1\r\n"
15273 "Host: www.example.org\r\n"
15274 "Connection: keep-alive\r\n\r\n"),
[email protected]043b68c82013-08-22 23:41:5215275 };
15276 MockRead ssl_reads[] = {
15277 MockRead("HTTP/1.1 200 OK\r\n"),
15278 MockRead("Content-Length: 11\r\n\r\n"),
15279 MockRead("hello world"),
15280 MockRead(SYNCHRONOUS, OK),
15281 };
15282 StaticSocketDataProvider ssl_data(ssl_reads, arraysize(ssl_reads),
15283 ssl_writes, arraysize(ssl_writes));
15284 session_deps_.socket_factory->AddSocketDataProvider(&ssl_data);
15285
15286 SSLSocketDataProvider ssl(ASYNC, OK);
15287 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
15288
15289 // Set up HTTP request.
15290
15291 HttpRequestInfo http_request;
15292 http_request.method = "GET";
bncce36dca22015-04-21 22:11:2315293 http_request.url = GURL("http://www.example.org/");
[email protected]043b68c82013-08-22 23:41:5215294
15295 MockWrite http_writes[] = {
bncce36dca22015-04-21 22:11:2315296 MockWrite(
15297 "GET / HTTP/1.1\r\n"
15298 "Host: www.example.org\r\n"
15299 "Connection: keep-alive\r\n\r\n"),
[email protected]043b68c82013-08-22 23:41:5215300 };
15301 MockRead http_reads[] = {
15302 MockRead("HTTP/1.1 200 OK\r\n"),
15303 MockRead("Content-Length: 7\r\n\r\n"),
15304 MockRead("falafel"),
15305 MockRead(SYNCHRONOUS, OK),
15306 };
15307 StaticSocketDataProvider http_data(http_reads, arraysize(http_reads),
15308 http_writes, arraysize(http_writes));
15309 session_deps_.socket_factory->AddSocketDataProvider(&http_data);
15310
danakj1fd259a02016-04-16 03:17:0915311 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]043b68c82013-08-22 23:41:5215312
15313 // Start the SSL request.
15314 TestCompletionCallback ssl_callback;
bnc691fda62016-08-12 00:43:1615315 HttpNetworkTransaction ssl_trans(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:2015316 ASSERT_EQ(ERR_IO_PENDING,
15317 ssl_trans.Start(&ssl_request, ssl_callback.callback(),
15318 NetLogWithSource()));
[email protected]043b68c82013-08-22 23:41:5215319
15320 // Start the HTTP request. Pool should stall.
15321 TestCompletionCallback http_callback;
bnc691fda62016-08-12 00:43:1615322 HttpNetworkTransaction http_trans(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:2015323 ASSERT_EQ(ERR_IO_PENDING,
15324 http_trans.Start(&http_request, http_callback.callback(),
15325 NetLogWithSource()));
dcheng48459ac22014-08-26 00:46:4115326 EXPECT_TRUE(IsTransportSocketPoolStalled(session.get()));
[email protected]043b68c82013-08-22 23:41:5215327
15328 // Wait for response from SSL request.
robpercival214763f2016-07-01 23:27:0115329 ASSERT_THAT(ssl_callback.WaitForResult(), IsOk());
[email protected]043b68c82013-08-22 23:41:5215330 std::string response_data;
bnc691fda62016-08-12 00:43:1615331 ASSERT_THAT(ReadTransaction(&ssl_trans, &response_data), IsOk());
[email protected]043b68c82013-08-22 23:41:5215332 EXPECT_EQ("hello world", response_data);
15333
15334 // The SSL socket should automatically be closed, so the HTTP request can
15335 // start.
dcheng48459ac22014-08-26 00:46:4115336 EXPECT_EQ(0, GetIdleSocketCountInSSLSocketPool(session.get()));
15337 ASSERT_FALSE(IsTransportSocketPoolStalled(session.get()));
[email protected]043b68c82013-08-22 23:41:5215338
15339 // The HTTP request can now complete.
robpercival214763f2016-07-01 23:27:0115340 ASSERT_THAT(http_callback.WaitForResult(), IsOk());
bnc691fda62016-08-12 00:43:1615341 ASSERT_THAT(ReadTransaction(&http_trans, &response_data), IsOk());
[email protected]043b68c82013-08-22 23:41:5215342 EXPECT_EQ("falafel", response_data);
15343
dcheng48459ac22014-08-26 00:46:4115344 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]043b68c82013-08-22 23:41:5215345}
15346
15347// Tests that when a SSL connection is established but there's no corresponding
15348// request that needs it, the new socket is closed if the transport socket pool
15349// is stalled on the global socket limit.
bncd16676a2016-07-20 16:23:0115350TEST_F(HttpNetworkTransactionTest, CloseSSLSocketOnIdleForHttpRequest2) {
[email protected]043b68c82013-08-22 23:41:5215351 ClientSocketPoolManager::set_max_sockets_per_group(
15352 HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
15353 ClientSocketPoolManager::set_max_sockets_per_pool(
15354 HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
15355
15356 // Set up an ssl request.
15357
15358 HttpRequestInfo ssl_request;
15359 ssl_request.method = "GET";
15360 ssl_request.url = GURL("https://www.foopy.com/");
15361
15362 // No data will be sent on the SSL socket.
15363 StaticSocketDataProvider ssl_data;
15364 session_deps_.socket_factory->AddSocketDataProvider(&ssl_data);
15365
15366 SSLSocketDataProvider ssl(ASYNC, OK);
15367 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
15368
15369 // Set up HTTP request.
15370
15371 HttpRequestInfo http_request;
15372 http_request.method = "GET";
bncce36dca22015-04-21 22:11:2315373 http_request.url = GURL("http://www.example.org/");
[email protected]043b68c82013-08-22 23:41:5215374
15375 MockWrite http_writes[] = {
bncce36dca22015-04-21 22:11:2315376 MockWrite(
15377 "GET / HTTP/1.1\r\n"
15378 "Host: www.example.org\r\n"
15379 "Connection: keep-alive\r\n\r\n"),
[email protected]043b68c82013-08-22 23:41:5215380 };
15381 MockRead http_reads[] = {
15382 MockRead("HTTP/1.1 200 OK\r\n"),
15383 MockRead("Content-Length: 7\r\n\r\n"),
15384 MockRead("falafel"),
15385 MockRead(SYNCHRONOUS, OK),
15386 };
15387 StaticSocketDataProvider http_data(http_reads, arraysize(http_reads),
15388 http_writes, arraysize(http_writes));
15389 session_deps_.socket_factory->AddSocketDataProvider(&http_data);
15390
danakj1fd259a02016-04-16 03:17:0915391 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]043b68c82013-08-22 23:41:5215392
15393 // Preconnect an SSL socket. A preconnect is needed because connect jobs are
15394 // cancelled when a normal transaction is cancelled.
ttuttle859dc7a2015-04-23 19:42:2915395 HttpStreamFactory* http_stream_factory = session->http_stream_factory();
nharper8cdb0fb2016-04-22 21:34:5915396 http_stream_factory->PreconnectStreams(1, ssl_request);
dcheng48459ac22014-08-26 00:46:4115397 EXPECT_EQ(0, GetIdleSocketCountInSSLSocketPool(session.get()));
[email protected]043b68c82013-08-22 23:41:5215398
15399 // Start the HTTP request. Pool should stall.
15400 TestCompletionCallback http_callback;
bnc691fda62016-08-12 00:43:1615401 HttpNetworkTransaction http_trans(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:2015402 ASSERT_EQ(ERR_IO_PENDING,
15403 http_trans.Start(&http_request, http_callback.callback(),
15404 NetLogWithSource()));
dcheng48459ac22014-08-26 00:46:4115405 EXPECT_TRUE(IsTransportSocketPoolStalled(session.get()));
[email protected]043b68c82013-08-22 23:41:5215406
15407 // The SSL connection will automatically be closed once the connection is
15408 // established, to let the HTTP request start.
robpercival214763f2016-07-01 23:27:0115409 ASSERT_THAT(http_callback.WaitForResult(), IsOk());
[email protected]043b68c82013-08-22 23:41:5215410 std::string response_data;
bnc691fda62016-08-12 00:43:1615411 ASSERT_THAT(ReadTransaction(&http_trans, &response_data), IsOk());
[email protected]043b68c82013-08-22 23:41:5215412 EXPECT_EQ("falafel", response_data);
15413
dcheng48459ac22014-08-26 00:46:4115414 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]043b68c82013-08-22 23:41:5215415}
15416
bncd16676a2016-07-20 16:23:0115417TEST_F(HttpNetworkTransactionTest, PostReadsErrorResponseAfterReset) {
danakj1fd259a02016-04-16 03:17:0915418 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:2215419 element_readers.push_back(
ricea2deef682016-09-09 08:04:0715420 base::MakeUnique<UploadBytesElementReader>("foo", 3));
olli.raula6df48b2a2015-11-26 07:40:2215421 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]02d74a02014-04-23 18:10:5415422
15423 HttpRequestInfo request;
15424 request.method = "POST";
15425 request.url = GURL("http://www.foo.com/");
15426 request.upload_data_stream = &upload_data_stream;
[email protected]02d74a02014-04-23 18:10:5415427
danakj1fd259a02016-04-16 03:17:0915428 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1615429 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]02d74a02014-04-23 18:10:5415430 // Send headers successfully, but get an error while sending the body.
15431 MockWrite data_writes[] = {
15432 MockWrite("POST / HTTP/1.1\r\n"
15433 "Host: www.foo.com\r\n"
15434 "Connection: keep-alive\r\n"
15435 "Content-Length: 3\r\n\r\n"),
15436 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
15437 };
15438
15439 MockRead data_reads[] = {
15440 MockRead("HTTP/1.0 400 Not OK\r\n\r\n"),
15441 MockRead("hello world"),
15442 MockRead(SYNCHRONOUS, OK),
15443 };
15444 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
15445 arraysize(data_writes));
15446 session_deps_.socket_factory->AddSocketDataProvider(&data);
15447
15448 TestCompletionCallback callback;
15449
tfarina42834112016-09-22 13:38:2015450 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0115451 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]02d74a02014-04-23 18:10:5415452
15453 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0115454 EXPECT_THAT(rv, IsOk());
[email protected]02d74a02014-04-23 18:10:5415455
bnc691fda62016-08-12 00:43:1615456 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5215457 ASSERT_TRUE(response);
[email protected]02d74a02014-04-23 18:10:5415458
wezca1070932016-05-26 20:30:5215459 EXPECT_TRUE(response->headers);
[email protected]02d74a02014-04-23 18:10:5415460 EXPECT_EQ("HTTP/1.0 400 Not OK", response->headers->GetStatusLine());
15461
15462 std::string response_data;
bnc691fda62016-08-12 00:43:1615463 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:0115464 EXPECT_THAT(rv, IsOk());
[email protected]02d74a02014-04-23 18:10:5415465 EXPECT_EQ("hello world", response_data);
15466}
15467
15468// This test makes sure the retry logic doesn't trigger when reading an error
15469// response from a server that rejected a POST with a CONNECTION_RESET.
bncd16676a2016-07-20 16:23:0115470TEST_F(HttpNetworkTransactionTest,
[email protected]02d74a02014-04-23 18:10:5415471 PostReadsErrorResponseAfterResetOnReusedSocket) {
danakj1fd259a02016-04-16 03:17:0915472 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]02d74a02014-04-23 18:10:5415473 MockWrite data_writes[] = {
15474 MockWrite("GET / HTTP/1.1\r\n"
15475 "Host: www.foo.com\r\n"
15476 "Connection: keep-alive\r\n\r\n"),
15477 MockWrite("POST / HTTP/1.1\r\n"
15478 "Host: www.foo.com\r\n"
15479 "Connection: keep-alive\r\n"
15480 "Content-Length: 3\r\n\r\n"),
15481 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
15482 };
15483
15484 MockRead data_reads[] = {
15485 MockRead("HTTP/1.1 200 Peachy\r\n"
15486 "Content-Length: 14\r\n\r\n"),
15487 MockRead("first response"),
15488 MockRead("HTTP/1.1 400 Not OK\r\n"
15489 "Content-Length: 15\r\n\r\n"),
15490 MockRead("second response"),
15491 MockRead(SYNCHRONOUS, OK),
15492 };
15493 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
15494 arraysize(data_writes));
15495 session_deps_.socket_factory->AddSocketDataProvider(&data);
15496
15497 TestCompletionCallback callback;
15498 HttpRequestInfo request1;
15499 request1.method = "GET";
15500 request1.url = GURL("http://www.foo.com/");
15501 request1.load_flags = 0;
15502
bnc691fda62016-08-12 00:43:1615503 std::unique_ptr<HttpNetworkTransaction> trans1(
dcheng48459ac22014-08-26 00:46:4115504 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
tfarina42834112016-09-22 13:38:2015505 int rv = trans1->Start(&request1, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0115506 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]02d74a02014-04-23 18:10:5415507
15508 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0115509 EXPECT_THAT(rv, IsOk());
[email protected]02d74a02014-04-23 18:10:5415510
15511 const HttpResponseInfo* response1 = trans1->GetResponseInfo();
wezca1070932016-05-26 20:30:5215512 ASSERT_TRUE(response1);
[email protected]02d74a02014-04-23 18:10:5415513
wezca1070932016-05-26 20:30:5215514 EXPECT_TRUE(response1->headers);
[email protected]02d74a02014-04-23 18:10:5415515 EXPECT_EQ("HTTP/1.1 200 Peachy", response1->headers->GetStatusLine());
15516
15517 std::string response_data1;
15518 rv = ReadTransaction(trans1.get(), &response_data1);
robpercival214763f2016-07-01 23:27:0115519 EXPECT_THAT(rv, IsOk());
[email protected]02d74a02014-04-23 18:10:5415520 EXPECT_EQ("first response", response_data1);
15521 // Delete the transaction to release the socket back into the socket pool.
15522 trans1.reset();
15523
danakj1fd259a02016-04-16 03:17:0915524 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:2215525 element_readers.push_back(
danakj1fd259a02016-04-16 03:17:0915526 base::WrapUnique(new UploadBytesElementReader("foo", 3)));
olli.raula6df48b2a2015-11-26 07:40:2215527 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]02d74a02014-04-23 18:10:5415528
15529 HttpRequestInfo request2;
15530 request2.method = "POST";
15531 request2.url = GURL("http://www.foo.com/");
15532 request2.upload_data_stream = &upload_data_stream;
15533 request2.load_flags = 0;
15534
bnc691fda62016-08-12 00:43:1615535 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:2015536 rv = trans2.Start(&request2, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0115537 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]02d74a02014-04-23 18:10:5415538
15539 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0115540 EXPECT_THAT(rv, IsOk());
[email protected]02d74a02014-04-23 18:10:5415541
bnc691fda62016-08-12 00:43:1615542 const HttpResponseInfo* response2 = trans2.GetResponseInfo();
wezca1070932016-05-26 20:30:5215543 ASSERT_TRUE(response2);
[email protected]02d74a02014-04-23 18:10:5415544
wezca1070932016-05-26 20:30:5215545 EXPECT_TRUE(response2->headers);
[email protected]02d74a02014-04-23 18:10:5415546 EXPECT_EQ("HTTP/1.1 400 Not OK", response2->headers->GetStatusLine());
15547
15548 std::string response_data2;
bnc691fda62016-08-12 00:43:1615549 rv = ReadTransaction(&trans2, &response_data2);
robpercival214763f2016-07-01 23:27:0115550 EXPECT_THAT(rv, IsOk());
[email protected]02d74a02014-04-23 18:10:5415551 EXPECT_EQ("second response", response_data2);
15552}
15553
bncd16676a2016-07-20 16:23:0115554TEST_F(HttpNetworkTransactionTest,
[email protected]02d74a02014-04-23 18:10:5415555 PostReadsErrorResponseAfterResetPartialBodySent) {
danakj1fd259a02016-04-16 03:17:0915556 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:2215557 element_readers.push_back(
ricea2deef682016-09-09 08:04:0715558 base::MakeUnique<UploadBytesElementReader>("foo", 3));
olli.raula6df48b2a2015-11-26 07:40:2215559 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]02d74a02014-04-23 18:10:5415560
15561 HttpRequestInfo request;
15562 request.method = "POST";
15563 request.url = GURL("http://www.foo.com/");
15564 request.upload_data_stream = &upload_data_stream;
[email protected]02d74a02014-04-23 18:10:5415565
danakj1fd259a02016-04-16 03:17:0915566 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1615567 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]02d74a02014-04-23 18:10:5415568 // Send headers successfully, but get an error while sending the body.
15569 MockWrite data_writes[] = {
15570 MockWrite("POST / HTTP/1.1\r\n"
15571 "Host: www.foo.com\r\n"
15572 "Connection: keep-alive\r\n"
15573 "Content-Length: 3\r\n\r\n"
15574 "fo"),
15575 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
15576 };
15577
15578 MockRead data_reads[] = {
15579 MockRead("HTTP/1.0 400 Not OK\r\n\r\n"),
15580 MockRead("hello world"),
15581 MockRead(SYNCHRONOUS, OK),
15582 };
15583 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
15584 arraysize(data_writes));
15585 session_deps_.socket_factory->AddSocketDataProvider(&data);
15586
15587 TestCompletionCallback callback;
15588
tfarina42834112016-09-22 13:38:2015589 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0115590 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]02d74a02014-04-23 18:10:5415591
15592 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0115593 EXPECT_THAT(rv, IsOk());
[email protected]02d74a02014-04-23 18:10:5415594
bnc691fda62016-08-12 00:43:1615595 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5215596 ASSERT_TRUE(response);
[email protected]02d74a02014-04-23 18:10:5415597
wezca1070932016-05-26 20:30:5215598 EXPECT_TRUE(response->headers);
[email protected]02d74a02014-04-23 18:10:5415599 EXPECT_EQ("HTTP/1.0 400 Not OK", response->headers->GetStatusLine());
15600
15601 std::string response_data;
bnc691fda62016-08-12 00:43:1615602 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:0115603 EXPECT_THAT(rv, IsOk());
[email protected]02d74a02014-04-23 18:10:5415604 EXPECT_EQ("hello world", response_data);
15605}
15606
15607// This tests the more common case than the previous test, where headers and
15608// body are not merged into a single request.
bncd16676a2016-07-20 16:23:0115609TEST_F(HttpNetworkTransactionTest, ChunkedPostReadsErrorResponseAfterReset) {
mmenkecbc2b712014-10-09 20:29:0715610 ChunkedUploadDataStream upload_data_stream(0);
[email protected]02d74a02014-04-23 18:10:5415611
15612 HttpRequestInfo request;
15613 request.method = "POST";
15614 request.url = GURL("http://www.foo.com/");
15615 request.upload_data_stream = &upload_data_stream;
[email protected]02d74a02014-04-23 18:10:5415616
danakj1fd259a02016-04-16 03:17:0915617 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1615618 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]02d74a02014-04-23 18:10:5415619 // Send headers successfully, but get an error while sending the body.
15620 MockWrite data_writes[] = {
15621 MockWrite("POST / HTTP/1.1\r\n"
15622 "Host: www.foo.com\r\n"
15623 "Connection: keep-alive\r\n"
15624 "Transfer-Encoding: chunked\r\n\r\n"),
15625 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
15626 };
15627
15628 MockRead data_reads[] = {
15629 MockRead("HTTP/1.0 400 Not OK\r\n\r\n"),
15630 MockRead("hello world"),
15631 MockRead(SYNCHRONOUS, OK),
15632 };
15633 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
15634 arraysize(data_writes));
15635 session_deps_.socket_factory->AddSocketDataProvider(&data);
15636
15637 TestCompletionCallback callback;
15638
tfarina42834112016-09-22 13:38:2015639 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0115640 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]02d74a02014-04-23 18:10:5415641 // Make sure the headers are sent before adding a chunk. This ensures that
15642 // they can't be merged with the body in a single send. Not currently
15643 // necessary since a chunked body is never merged with headers, but this makes
15644 // the test more future proof.
15645 base::RunLoop().RunUntilIdle();
15646
mmenkecbc2b712014-10-09 20:29:0715647 upload_data_stream.AppendData("last chunk", 10, true);
[email protected]02d74a02014-04-23 18:10:5415648
15649 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0115650 EXPECT_THAT(rv, IsOk());
[email protected]02d74a02014-04-23 18:10:5415651
bnc691fda62016-08-12 00:43:1615652 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5215653 ASSERT_TRUE(response);
[email protected]02d74a02014-04-23 18:10:5415654
wezca1070932016-05-26 20:30:5215655 EXPECT_TRUE(response->headers);
[email protected]02d74a02014-04-23 18:10:5415656 EXPECT_EQ("HTTP/1.0 400 Not OK", response->headers->GetStatusLine());
15657
15658 std::string response_data;
bnc691fda62016-08-12 00:43:1615659 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:0115660 EXPECT_THAT(rv, IsOk());
[email protected]02d74a02014-04-23 18:10:5415661 EXPECT_EQ("hello world", response_data);
15662}
15663
bncd16676a2016-07-20 16:23:0115664TEST_F(HttpNetworkTransactionTest, PostReadsErrorResponseAfterResetAnd100) {
danakj1fd259a02016-04-16 03:17:0915665 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:2215666 element_readers.push_back(
ricea2deef682016-09-09 08:04:0715667 base::MakeUnique<UploadBytesElementReader>("foo", 3));
olli.raula6df48b2a2015-11-26 07:40:2215668 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]02d74a02014-04-23 18:10:5415669
15670 HttpRequestInfo request;
15671 request.method = "POST";
15672 request.url = GURL("http://www.foo.com/");
15673 request.upload_data_stream = &upload_data_stream;
[email protected]02d74a02014-04-23 18:10:5415674
danakj1fd259a02016-04-16 03:17:0915675 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1615676 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]02d74a02014-04-23 18:10:5415677
15678 MockWrite data_writes[] = {
15679 MockWrite("POST / HTTP/1.1\r\n"
15680 "Host: www.foo.com\r\n"
15681 "Connection: keep-alive\r\n"
15682 "Content-Length: 3\r\n\r\n"),
15683 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
15684 };
15685
15686 MockRead data_reads[] = {
15687 MockRead("HTTP/1.0 100 Continue\r\n\r\n"),
15688 MockRead("HTTP/1.0 400 Not OK\r\n\r\n"),
15689 MockRead("hello world"),
15690 MockRead(SYNCHRONOUS, OK),
15691 };
15692 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
15693 arraysize(data_writes));
15694 session_deps_.socket_factory->AddSocketDataProvider(&data);
15695
15696 TestCompletionCallback callback;
15697
tfarina42834112016-09-22 13:38:2015698 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0115699 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]02d74a02014-04-23 18:10:5415700
15701 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0115702 EXPECT_THAT(rv, IsOk());
[email protected]02d74a02014-04-23 18:10:5415703
bnc691fda62016-08-12 00:43:1615704 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5215705 ASSERT_TRUE(response);
[email protected]02d74a02014-04-23 18:10:5415706
wezca1070932016-05-26 20:30:5215707 EXPECT_TRUE(response->headers);
[email protected]02d74a02014-04-23 18:10:5415708 EXPECT_EQ("HTTP/1.0 400 Not OK", response->headers->GetStatusLine());
15709
15710 std::string response_data;
bnc691fda62016-08-12 00:43:1615711 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:0115712 EXPECT_THAT(rv, IsOk());
[email protected]02d74a02014-04-23 18:10:5415713 EXPECT_EQ("hello world", response_data);
15714}
15715
bncd16676a2016-07-20 16:23:0115716TEST_F(HttpNetworkTransactionTest, PostIgnoresNonErrorResponseAfterReset) {
danakj1fd259a02016-04-16 03:17:0915717 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:2215718 element_readers.push_back(
ricea2deef682016-09-09 08:04:0715719 base::MakeUnique<UploadBytesElementReader>("foo", 3));
olli.raula6df48b2a2015-11-26 07:40:2215720 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]02d74a02014-04-23 18:10:5415721
15722 HttpRequestInfo request;
15723 request.method = "POST";
15724 request.url = GURL("http://www.foo.com/");
15725 request.upload_data_stream = &upload_data_stream;
[email protected]02d74a02014-04-23 18:10:5415726
danakj1fd259a02016-04-16 03:17:0915727 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1615728 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]02d74a02014-04-23 18:10:5415729 // Send headers successfully, but get an error while sending the body.
15730 MockWrite data_writes[] = {
15731 MockWrite("POST / HTTP/1.1\r\n"
15732 "Host: www.foo.com\r\n"
15733 "Connection: keep-alive\r\n"
15734 "Content-Length: 3\r\n\r\n"),
15735 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
15736 };
15737
15738 MockRead data_reads[] = {
15739 MockRead("HTTP/1.0 200 Just Dandy\r\n\r\n"),
15740 MockRead("hello world"),
15741 MockRead(SYNCHRONOUS, OK),
15742 };
15743 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
15744 arraysize(data_writes));
15745 session_deps_.socket_factory->AddSocketDataProvider(&data);
15746
15747 TestCompletionCallback callback;
15748
tfarina42834112016-09-22 13:38:2015749 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0115750 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]02d74a02014-04-23 18:10:5415751
15752 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0115753 EXPECT_THAT(rv, IsError(ERR_CONNECTION_RESET));
[email protected]02d74a02014-04-23 18:10:5415754}
15755
bncd16676a2016-07-20 16:23:0115756TEST_F(HttpNetworkTransactionTest,
[email protected]02d74a02014-04-23 18:10:5415757 PostIgnoresNonErrorResponseAfterResetAnd100) {
danakj1fd259a02016-04-16 03:17:0915758 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:2215759 element_readers.push_back(
ricea2deef682016-09-09 08:04:0715760 base::MakeUnique<UploadBytesElementReader>("foo", 3));
olli.raula6df48b2a2015-11-26 07:40:2215761 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]02d74a02014-04-23 18:10:5415762
15763 HttpRequestInfo request;
15764 request.method = "POST";
15765 request.url = GURL("http://www.foo.com/");
15766 request.upload_data_stream = &upload_data_stream;
[email protected]02d74a02014-04-23 18:10:5415767
danakj1fd259a02016-04-16 03:17:0915768 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1615769 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]02d74a02014-04-23 18:10:5415770 // Send headers successfully, but get an error while sending the body.
15771 MockWrite data_writes[] = {
15772 MockWrite("POST / HTTP/1.1\r\n"
15773 "Host: www.foo.com\r\n"
15774 "Connection: keep-alive\r\n"
15775 "Content-Length: 3\r\n\r\n"),
15776 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
15777 };
15778
15779 MockRead data_reads[] = {
15780 MockRead("HTTP/1.0 100 Continue\r\n\r\n"),
15781 MockRead("HTTP/1.0 302 Redirect\r\n"),
15782 MockRead("Location: http://somewhere-else.com/\r\n"),
15783 MockRead("Content-Length: 0\r\n\r\n"),
15784 MockRead(SYNCHRONOUS, OK),
15785 };
15786 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
15787 arraysize(data_writes));
15788 session_deps_.socket_factory->AddSocketDataProvider(&data);
15789
15790 TestCompletionCallback callback;
15791
tfarina42834112016-09-22 13:38:2015792 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0115793 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]02d74a02014-04-23 18:10:5415794
15795 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0115796 EXPECT_THAT(rv, IsError(ERR_CONNECTION_RESET));
[email protected]02d74a02014-04-23 18:10:5415797}
15798
bncd16676a2016-07-20 16:23:0115799TEST_F(HttpNetworkTransactionTest, PostIgnoresHttp09ResponseAfterReset) {
danakj1fd259a02016-04-16 03:17:0915800 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:2215801 element_readers.push_back(
ricea2deef682016-09-09 08:04:0715802 base::MakeUnique<UploadBytesElementReader>("foo", 3));
olli.raula6df48b2a2015-11-26 07:40:2215803 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]02d74a02014-04-23 18:10:5415804
15805 HttpRequestInfo request;
15806 request.method = "POST";
15807 request.url = GURL("http://www.foo.com/");
15808 request.upload_data_stream = &upload_data_stream;
[email protected]02d74a02014-04-23 18:10:5415809
danakj1fd259a02016-04-16 03:17:0915810 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1615811 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]02d74a02014-04-23 18:10:5415812 // Send headers successfully, but get an error while sending the body.
15813 MockWrite data_writes[] = {
15814 MockWrite("POST / HTTP/1.1\r\n"
15815 "Host: www.foo.com\r\n"
15816 "Connection: keep-alive\r\n"
15817 "Content-Length: 3\r\n\r\n"),
15818 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
15819 };
15820
15821 MockRead data_reads[] = {
15822 MockRead("HTTP 0.9 rocks!"),
15823 MockRead(SYNCHRONOUS, OK),
15824 };
15825 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
15826 arraysize(data_writes));
15827 session_deps_.socket_factory->AddSocketDataProvider(&data);
15828
15829 TestCompletionCallback callback;
15830
tfarina42834112016-09-22 13:38:2015831 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0115832 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]02d74a02014-04-23 18:10:5415833
15834 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0115835 EXPECT_THAT(rv, IsError(ERR_CONNECTION_RESET));
[email protected]02d74a02014-04-23 18:10:5415836}
15837
bncd16676a2016-07-20 16:23:0115838TEST_F(HttpNetworkTransactionTest, PostIgnoresPartial400HeadersAfterReset) {
danakj1fd259a02016-04-16 03:17:0915839 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:2215840 element_readers.push_back(
ricea2deef682016-09-09 08:04:0715841 base::MakeUnique<UploadBytesElementReader>("foo", 3));
olli.raula6df48b2a2015-11-26 07:40:2215842 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]02d74a02014-04-23 18:10:5415843
15844 HttpRequestInfo request;
15845 request.method = "POST";
15846 request.url = GURL("http://www.foo.com/");
15847 request.upload_data_stream = &upload_data_stream;
[email protected]02d74a02014-04-23 18:10:5415848
danakj1fd259a02016-04-16 03:17:0915849 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1615850 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]02d74a02014-04-23 18:10:5415851 // Send headers successfully, but get an error while sending the body.
15852 MockWrite data_writes[] = {
15853 MockWrite("POST / HTTP/1.1\r\n"
15854 "Host: www.foo.com\r\n"
15855 "Connection: keep-alive\r\n"
15856 "Content-Length: 3\r\n\r\n"),
15857 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
15858 };
15859
15860 MockRead data_reads[] = {
15861 MockRead("HTTP/1.0 400 Not a Full Response\r\n"),
15862 MockRead(SYNCHRONOUS, OK),
15863 };
15864 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
15865 arraysize(data_writes));
15866 session_deps_.socket_factory->AddSocketDataProvider(&data);
15867
15868 TestCompletionCallback callback;
15869
tfarina42834112016-09-22 13:38:2015870 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0115871 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]02d74a02014-04-23 18:10:5415872
15873 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0115874 EXPECT_THAT(rv, IsError(ERR_CONNECTION_RESET));
[email protected]02d74a02014-04-23 18:10:5415875}
15876
Adam Rice425cf122015-01-19 06:18:2415877// Verify that proxy headers are not sent to the destination server when
15878// establishing a tunnel for a secure WebSocket connection.
bncd16676a2016-07-20 16:23:0115879TEST_F(HttpNetworkTransactionTest, ProxyHeadersNotSentOverWssTunnel) {
Adam Rice425cf122015-01-19 06:18:2415880 HttpRequestInfo request;
15881 request.method = "GET";
bncce36dca22015-04-21 22:11:2315882 request.url = GURL("wss://www.example.org/");
Adam Rice425cf122015-01-19 06:18:2415883 AddWebSocketHeaders(&request.extra_headers);
15884
15885 // Configure against proxy server "myproxy:70".
rdsmith82957ad2015-09-16 19:42:0315886 session_deps_.proxy_service =
15887 ProxyService::CreateFixedFromPacResult("PROXY myproxy:70");
Adam Rice425cf122015-01-19 06:18:2415888
danakj1fd259a02016-04-16 03:17:0915889 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
Adam Rice425cf122015-01-19 06:18:2415890
15891 // Since a proxy is configured, try to establish a tunnel.
15892 MockWrite data_writes[] = {
rsleevidb16bb02015-11-12 23:47:1715893 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
15894 "Host: www.example.org:443\r\n"
15895 "Proxy-Connection: keep-alive\r\n\r\n"),
Adam Rice425cf122015-01-19 06:18:2415896
15897 // After calling trans->RestartWithAuth(), this is the request we should
15898 // be issuing -- the final header line contains the credentials.
rsleevidb16bb02015-11-12 23:47:1715899 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
15900 "Host: www.example.org:443\r\n"
15901 "Proxy-Connection: keep-alive\r\n"
15902 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
Adam Rice425cf122015-01-19 06:18:2415903
rsleevidb16bb02015-11-12 23:47:1715904 MockWrite("GET / HTTP/1.1\r\n"
15905 "Host: www.example.org\r\n"
15906 "Connection: Upgrade\r\n"
15907 "Upgrade: websocket\r\n"
15908 "Origin: http://www.example.org\r\n"
15909 "Sec-WebSocket-Version: 13\r\n"
15910 "Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==\r\n\r\n"),
Adam Rice425cf122015-01-19 06:18:2415911 };
15912
15913 // The proxy responds to the connect with a 407, using a persistent
15914 // connection.
15915 MockRead data_reads[] = {
15916 // No credentials.
15917 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
15918 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
mmenkee71e15332015-10-07 16:39:5415919 MockRead("Content-Length: 0\r\n"),
15920 MockRead("Proxy-Connection: keep-alive\r\n\r\n"),
Adam Rice425cf122015-01-19 06:18:2415921
15922 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
15923
15924 MockRead("HTTP/1.1 101 Switching Protocols\r\n"),
15925 MockRead("Upgrade: websocket\r\n"),
15926 MockRead("Connection: Upgrade\r\n"),
15927 MockRead("Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=\r\n\r\n"),
15928 };
15929
15930 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
15931 arraysize(data_writes));
15932 session_deps_.socket_factory->AddSocketDataProvider(&data);
15933 SSLSocketDataProvider ssl(ASYNC, OK);
15934 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
15935
bnc691fda62016-08-12 00:43:1615936 std::unique_ptr<HttpNetworkTransaction> trans(
Adam Rice425cf122015-01-19 06:18:2415937 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
15938 FakeWebSocketStreamCreateHelper websocket_stream_create_helper;
15939 trans->SetWebSocketHandshakeStreamCreateHelper(
15940 &websocket_stream_create_helper);
15941
15942 {
15943 TestCompletionCallback callback;
15944
tfarina42834112016-09-22 13:38:2015945 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0115946 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
Adam Rice425cf122015-01-19 06:18:2415947
15948 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0115949 EXPECT_THAT(rv, IsOk());
Adam Rice425cf122015-01-19 06:18:2415950 }
15951
15952 const HttpResponseInfo* response = trans->GetResponseInfo();
15953 ASSERT_TRUE(response);
wezca1070932016-05-26 20:30:5215954 ASSERT_TRUE(response->headers);
Adam Rice425cf122015-01-19 06:18:2415955 EXPECT_EQ(407, response->headers->response_code());
15956
15957 {
15958 TestCompletionCallback callback;
15959
15960 int rv = trans->RestartWithAuth(AuthCredentials(kFoo, kBar),
15961 callback.callback());
robpercival214763f2016-07-01 23:27:0115962 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
Adam Rice425cf122015-01-19 06:18:2415963
15964 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0115965 EXPECT_THAT(rv, IsOk());
Adam Rice425cf122015-01-19 06:18:2415966 }
15967
15968 response = trans->GetResponseInfo();
15969 ASSERT_TRUE(response);
wezca1070932016-05-26 20:30:5215970 ASSERT_TRUE(response->headers);
Adam Rice425cf122015-01-19 06:18:2415971
15972 EXPECT_EQ(101, response->headers->response_code());
15973
15974 trans.reset();
15975 session->CloseAllConnections();
15976}
15977
15978// Verify that proxy headers are not sent to the destination server when
15979// establishing a tunnel for an insecure WebSocket connection.
15980// This requires the authentication info to be injected into the auth cache
15981// due to crbug.com/395064
15982// TODO(ricea): Change to use a 407 response once issue 395064 is fixed.
bncd16676a2016-07-20 16:23:0115983TEST_F(HttpNetworkTransactionTest, ProxyHeadersNotSentOverWsTunnel) {
Adam Rice425cf122015-01-19 06:18:2415984 HttpRequestInfo request;
15985 request.method = "GET";
bncce36dca22015-04-21 22:11:2315986 request.url = GURL("ws://www.example.org/");
Adam Rice425cf122015-01-19 06:18:2415987 AddWebSocketHeaders(&request.extra_headers);
15988
15989 // Configure against proxy server "myproxy:70".
rdsmith82957ad2015-09-16 19:42:0315990 session_deps_.proxy_service =
15991 ProxyService::CreateFixedFromPacResult("PROXY myproxy:70");
Adam Rice425cf122015-01-19 06:18:2415992
danakj1fd259a02016-04-16 03:17:0915993 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
Adam Rice425cf122015-01-19 06:18:2415994
15995 MockWrite data_writes[] = {
15996 // Try to establish a tunnel for the WebSocket connection, with
15997 // credentials. Because WebSockets have a separate set of socket pools,
15998 // they cannot and will not use the same TCP/IP connection as the
15999 // preflight HTTP request.
16000 MockWrite(
bncce36dca22015-04-21 22:11:2316001 "CONNECT www.example.org:80 HTTP/1.1\r\n"
16002 "Host: www.example.org:80\r\n"
Adam Rice425cf122015-01-19 06:18:2416003 "Proxy-Connection: keep-alive\r\n"
16004 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
16005
16006 MockWrite(
16007 "GET / HTTP/1.1\r\n"
bncce36dca22015-04-21 22:11:2316008 "Host: www.example.org\r\n"
Adam Rice425cf122015-01-19 06:18:2416009 "Connection: Upgrade\r\n"
16010 "Upgrade: websocket\r\n"
bncce36dca22015-04-21 22:11:2316011 "Origin: http://www.example.org\r\n"
Adam Rice425cf122015-01-19 06:18:2416012 "Sec-WebSocket-Version: 13\r\n"
16013 "Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==\r\n\r\n"),
16014 };
16015
16016 MockRead data_reads[] = {
16017 // HTTP CONNECT with credentials.
16018 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
16019
16020 // WebSocket connection established inside tunnel.
16021 MockRead("HTTP/1.1 101 Switching Protocols\r\n"),
16022 MockRead("Upgrade: websocket\r\n"),
16023 MockRead("Connection: Upgrade\r\n"),
16024 MockRead("Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=\r\n\r\n"),
16025 };
16026
16027 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
16028 arraysize(data_writes));
16029 session_deps_.socket_factory->AddSocketDataProvider(&data);
16030
16031 session->http_auth_cache()->Add(
16032 GURL("http://myproxy:70/"), "MyRealm1", HttpAuth::AUTH_SCHEME_BASIC,
16033 "Basic realm=MyRealm1", AuthCredentials(kFoo, kBar), "/");
16034
bnc691fda62016-08-12 00:43:1616035 std::unique_ptr<HttpNetworkTransaction> trans(
Adam Rice425cf122015-01-19 06:18:2416036 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
16037 FakeWebSocketStreamCreateHelper websocket_stream_create_helper;
16038 trans->SetWebSocketHandshakeStreamCreateHelper(
16039 &websocket_stream_create_helper);
16040
16041 TestCompletionCallback callback;
16042
tfarina42834112016-09-22 13:38:2016043 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0116044 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
Adam Rice425cf122015-01-19 06:18:2416045
16046 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0116047 EXPECT_THAT(rv, IsOk());
Adam Rice425cf122015-01-19 06:18:2416048
16049 const HttpResponseInfo* response = trans->GetResponseInfo();
16050 ASSERT_TRUE(response);
wezca1070932016-05-26 20:30:5216051 ASSERT_TRUE(response->headers);
Adam Rice425cf122015-01-19 06:18:2416052
16053 EXPECT_EQ(101, response->headers->response_code());
16054
16055 trans.reset();
16056 session->CloseAllConnections();
16057}
16058
bncd16676a2016-07-20 16:23:0116059TEST_F(HttpNetworkTransactionTest, TotalNetworkBytesPost) {
danakj1fd259a02016-04-16 03:17:0916060 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:2216061 element_readers.push_back(
ricea2deef682016-09-09 08:04:0716062 base::MakeUnique<UploadBytesElementReader>("foo", 3));
olli.raula6df48b2a2015-11-26 07:40:2216063 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
sclittlefb249892015-09-10 21:33:2216064
16065 HttpRequestInfo request;
16066 request.method = "POST";
16067 request.url = GURL("http://www.foo.com/");
16068 request.upload_data_stream = &upload_data_stream;
16069
danakj1fd259a02016-04-16 03:17:0916070 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1616071 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
sclittlefb249892015-09-10 21:33:2216072 MockWrite data_writes[] = {
16073 MockWrite("POST / HTTP/1.1\r\n"
16074 "Host: www.foo.com\r\n"
16075 "Connection: keep-alive\r\n"
16076 "Content-Length: 3\r\n\r\n"),
16077 MockWrite("foo"),
16078 };
16079
16080 MockRead data_reads[] = {
16081 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello world"),
16082 MockRead(SYNCHRONOUS, OK),
16083 };
16084 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
16085 arraysize(data_writes));
16086 session_deps_.socket_factory->AddSocketDataProvider(&data);
16087
16088 TestCompletionCallback callback;
16089
16090 EXPECT_EQ(ERR_IO_PENDING,
tfarina42834112016-09-22 13:38:2016091 trans.Start(&request, callback.callback(), NetLogWithSource()));
robpercival214763f2016-07-01 23:27:0116092 EXPECT_THAT(callback.WaitForResult(), IsOk());
sclittlefb249892015-09-10 21:33:2216093
16094 std::string response_data;
bnc691fda62016-08-12 00:43:1616095 EXPECT_THAT(ReadTransaction(&trans, &response_data), IsOk());
sclittlefb249892015-09-10 21:33:2216096
16097 EXPECT_EQ(CountWriteBytes(data_writes, arraysize(data_writes)),
bnc691fda62016-08-12 00:43:1616098 trans.GetTotalSentBytes());
sclittlefb249892015-09-10 21:33:2216099 EXPECT_EQ(CountReadBytes(data_reads, arraysize(data_reads)),
bnc691fda62016-08-12 00:43:1616100 trans.GetTotalReceivedBytes());
sclittlefb249892015-09-10 21:33:2216101}
16102
bncd16676a2016-07-20 16:23:0116103TEST_F(HttpNetworkTransactionTest, TotalNetworkBytesPost100Continue) {
danakj1fd259a02016-04-16 03:17:0916104 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:2216105 element_readers.push_back(
ricea2deef682016-09-09 08:04:0716106 base::MakeUnique<UploadBytesElementReader>("foo", 3));
olli.raula6df48b2a2015-11-26 07:40:2216107 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
sclittlefb249892015-09-10 21:33:2216108
16109 HttpRequestInfo request;
16110 request.method = "POST";
16111 request.url = GURL("http://www.foo.com/");
16112 request.upload_data_stream = &upload_data_stream;
16113
danakj1fd259a02016-04-16 03:17:0916114 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1616115 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
sclittlefb249892015-09-10 21:33:2216116 MockWrite data_writes[] = {
16117 MockWrite("POST / HTTP/1.1\r\n"
16118 "Host: www.foo.com\r\n"
16119 "Connection: keep-alive\r\n"
16120 "Content-Length: 3\r\n\r\n"),
16121 MockWrite("foo"),
16122 };
16123
16124 MockRead data_reads[] = {
16125 MockRead("HTTP/1.1 100 Continue\r\n\r\n"),
16126 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello world"),
16127 MockRead(SYNCHRONOUS, OK),
16128 };
16129 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
16130 arraysize(data_writes));
16131 session_deps_.socket_factory->AddSocketDataProvider(&data);
16132
16133 TestCompletionCallback callback;
16134
16135 EXPECT_EQ(ERR_IO_PENDING,
tfarina42834112016-09-22 13:38:2016136 trans.Start(&request, callback.callback(), NetLogWithSource()));
robpercival214763f2016-07-01 23:27:0116137 EXPECT_THAT(callback.WaitForResult(), IsOk());
sclittlefb249892015-09-10 21:33:2216138
16139 std::string response_data;
bnc691fda62016-08-12 00:43:1616140 EXPECT_THAT(ReadTransaction(&trans, &response_data), IsOk());
sclittlefb249892015-09-10 21:33:2216141
16142 EXPECT_EQ(CountWriteBytes(data_writes, arraysize(data_writes)),
bnc691fda62016-08-12 00:43:1616143 trans.GetTotalSentBytes());
sclittlefb249892015-09-10 21:33:2216144 EXPECT_EQ(CountReadBytes(data_reads, arraysize(data_reads)),
bnc691fda62016-08-12 00:43:1616145 trans.GetTotalReceivedBytes());
sclittlefb249892015-09-10 21:33:2216146}
16147
bncd16676a2016-07-20 16:23:0116148TEST_F(HttpNetworkTransactionTest, TotalNetworkBytesChunkedPost) {
sclittlefb249892015-09-10 21:33:2216149 ChunkedUploadDataStream upload_data_stream(0);
16150
16151 HttpRequestInfo request;
16152 request.method = "POST";
16153 request.url = GURL("http://www.foo.com/");
16154 request.upload_data_stream = &upload_data_stream;
16155
danakj1fd259a02016-04-16 03:17:0916156 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1616157 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
sclittlefb249892015-09-10 21:33:2216158 // Send headers successfully, but get an error while sending the body.
16159 MockWrite data_writes[] = {
16160 MockWrite("POST / HTTP/1.1\r\n"
16161 "Host: www.foo.com\r\n"
16162 "Connection: keep-alive\r\n"
16163 "Transfer-Encoding: chunked\r\n\r\n"),
16164 MockWrite("1\r\nf\r\n"), MockWrite("2\r\noo\r\n"), MockWrite("0\r\n\r\n"),
16165 };
16166
16167 MockRead data_reads[] = {
16168 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello world"),
16169 MockRead(SYNCHRONOUS, OK),
16170 };
16171 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
16172 arraysize(data_writes));
16173 session_deps_.socket_factory->AddSocketDataProvider(&data);
16174
16175 TestCompletionCallback callback;
16176
16177 EXPECT_EQ(ERR_IO_PENDING,
tfarina42834112016-09-22 13:38:2016178 trans.Start(&request, callback.callback(), NetLogWithSource()));
sclittlefb249892015-09-10 21:33:2216179
16180 base::RunLoop().RunUntilIdle();
16181 upload_data_stream.AppendData("f", 1, false);
16182
16183 base::RunLoop().RunUntilIdle();
16184 upload_data_stream.AppendData("oo", 2, true);
16185
robpercival214763f2016-07-01 23:27:0116186 EXPECT_THAT(callback.WaitForResult(), IsOk());
sclittlefb249892015-09-10 21:33:2216187
16188 std::string response_data;
bnc691fda62016-08-12 00:43:1616189 EXPECT_THAT(ReadTransaction(&trans, &response_data), IsOk());
sclittlefb249892015-09-10 21:33:2216190
16191 EXPECT_EQ(CountWriteBytes(data_writes, arraysize(data_writes)),
bnc691fda62016-08-12 00:43:1616192 trans.GetTotalSentBytes());
sclittlefb249892015-09-10 21:33:2216193 EXPECT_EQ(CountReadBytes(data_reads, arraysize(data_reads)),
bnc691fda62016-08-12 00:43:1616194 trans.GetTotalReceivedBytes());
sclittlefb249892015-09-10 21:33:2216195}
16196
rdsmith1d343be52016-10-21 20:37:5016197// Confirm that transactions whose throttle is created in (and stays in)
16198// the unthrottled state are not blocked.
16199TEST_F(HttpNetworkTransactionTest, ThrottlingUnthrottled) {
16200 TestNetworkStreamThrottler* throttler(nullptr);
16201 std::unique_ptr<HttpNetworkSession> session(
16202 CreateSessionWithThrottler(&session_deps_, &throttler));
16203
16204 // Send a simple request and make sure it goes through.
16205 HttpRequestInfo request;
16206 request.method = "GET";
16207 request.url = GURL("http://www.example.org/");
16208
16209 std::unique_ptr<HttpTransaction> trans(
16210 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
16211
16212 MockWrite data_writes[] = {
16213 MockWrite("GET / HTTP/1.1\r\n"
16214 "Host: www.example.org\r\n"
16215 "Connection: keep-alive\r\n\r\n"),
16216 };
16217 MockRead data_reads[] = {
16218 MockRead("HTTP/1.0 200 OK\r\n\r\n"), MockRead("hello world"),
16219 MockRead(SYNCHRONOUS, OK),
16220 };
16221 StaticSocketDataProvider reads(data_reads, arraysize(data_reads), data_writes,
16222 arraysize(data_writes));
16223 session_deps_.socket_factory->AddSocketDataProvider(&reads);
16224
16225 TestCompletionCallback callback;
16226 trans->Start(&request, callback.callback(), NetLogWithSource());
16227 EXPECT_EQ(OK, callback.WaitForResult());
16228}
16229
16230// Confirm requests can be blocked by a throttler, and are resumed
16231// when the throttle is unblocked.
16232TEST_F(HttpNetworkTransactionTest, ThrottlingBasic) {
16233 TestNetworkStreamThrottler* throttler(nullptr);
16234 std::unique_ptr<HttpNetworkSession> session(
16235 CreateSessionWithThrottler(&session_deps_, &throttler));
16236
16237 // Send a simple request and make sure it goes through.
16238 HttpRequestInfo request;
16239 request.method = "GET";
16240 request.url = GURL("http://www.example.org/");
16241
16242 MockWrite data_writes[] = {
16243 MockWrite("GET / HTTP/1.1\r\n"
16244 "Host: www.example.org\r\n"
16245 "Connection: keep-alive\r\n\r\n"),
16246 };
16247 MockRead data_reads[] = {
16248 MockRead("HTTP/1.0 200 OK\r\n\r\n"), MockRead("hello world"),
16249 MockRead(SYNCHRONOUS, OK),
16250 };
16251 StaticSocketDataProvider reads(data_reads, arraysize(data_reads), data_writes,
16252 arraysize(data_writes));
16253 session_deps_.socket_factory->AddSocketDataProvider(&reads);
16254
16255 // Start a request that will be throttled at start; confirm it
16256 // doesn't complete.
16257 throttler->set_throttle_new_requests(true);
16258 std::unique_ptr<HttpTransaction> trans(
16259 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
16260
16261 TestCompletionCallback callback;
16262 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
16263 EXPECT_EQ(ERR_IO_PENDING, rv);
16264
16265 base::RunLoop().RunUntilIdle();
16266 EXPECT_EQ(LOAD_STATE_THROTTLED, trans->GetLoadState());
16267 EXPECT_FALSE(callback.have_result());
16268
16269 // Confirm the request goes on to complete when unthrottled.
16270 throttler->UnthrottleAllRequests();
16271 base::RunLoop().RunUntilIdle();
16272 ASSERT_TRUE(callback.have_result());
16273 EXPECT_EQ(OK, callback.WaitForResult());
16274}
16275
16276// Destroy a request while it's throttled.
16277TEST_F(HttpNetworkTransactionTest, ThrottlingDestruction) {
16278 TestNetworkStreamThrottler* throttler(nullptr);
16279 std::unique_ptr<HttpNetworkSession> session(
16280 CreateSessionWithThrottler(&session_deps_, &throttler));
16281
16282 // Send a simple request and make sure it goes through.
16283 HttpRequestInfo request;
16284 request.method = "GET";
16285 request.url = GURL("http://www.example.org/");
16286
16287 MockWrite data_writes[] = {
16288 MockWrite("GET / HTTP/1.1\r\n"
16289 "Host: www.example.org\r\n"
16290 "Connection: keep-alive\r\n\r\n"),
16291 };
16292 MockRead data_reads[] = {
16293 MockRead("HTTP/1.0 200 OK\r\n\r\n"), MockRead("hello world"),
16294 MockRead(SYNCHRONOUS, OK),
16295 };
16296 StaticSocketDataProvider reads(data_reads, arraysize(data_reads), data_writes,
16297 arraysize(data_writes));
16298 session_deps_.socket_factory->AddSocketDataProvider(&reads);
16299
16300 // Start a request that will be throttled at start; confirm it
16301 // doesn't complete.
16302 throttler->set_throttle_new_requests(true);
16303 std::unique_ptr<HttpTransaction> trans(
16304 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
16305
16306 TestCompletionCallback callback;
16307 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
16308 EXPECT_EQ(ERR_IO_PENDING, rv);
16309
16310 base::RunLoop().RunUntilIdle();
16311 EXPECT_EQ(LOAD_STATE_THROTTLED, trans->GetLoadState());
16312 EXPECT_FALSE(callback.have_result());
16313
16314 EXPECT_EQ(1u, throttler->num_outstanding_requests());
16315 trans.reset();
16316 EXPECT_EQ(0u, throttler->num_outstanding_requests());
16317}
16318
16319// Confirm the throttler receives SetPriority calls.
16320TEST_F(HttpNetworkTransactionTest, ThrottlingPrioritySet) {
16321 TestNetworkStreamThrottler* throttler(nullptr);
16322 std::unique_ptr<HttpNetworkSession> session(
16323 CreateSessionWithThrottler(&session_deps_, &throttler));
16324
16325 // Send a simple request and make sure it goes through.
16326 HttpRequestInfo request;
16327 request.method = "GET";
16328 request.url = GURL("http://www.example.org/");
16329
16330 MockWrite data_writes[] = {
16331 MockWrite("GET / HTTP/1.1\r\n"
16332 "Host: www.example.org\r\n"
16333 "Connection: keep-alive\r\n\r\n"),
16334 };
16335 MockRead data_reads[] = {
16336 MockRead("HTTP/1.0 200 OK\r\n\r\n"), MockRead("hello world"),
16337 MockRead(SYNCHRONOUS, OK),
16338 };
16339 StaticSocketDataProvider reads(data_reads, arraysize(data_reads), data_writes,
16340 arraysize(data_writes));
16341 session_deps_.socket_factory->AddSocketDataProvider(&reads);
16342
16343 throttler->set_throttle_new_requests(true);
16344 std::unique_ptr<HttpTransaction> trans(
16345 new HttpNetworkTransaction(IDLE, session.get()));
16346 // Start the transaction to associate a throttle with it.
16347 TestCompletionCallback callback;
16348 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
16349 EXPECT_EQ(ERR_IO_PENDING, rv);
16350
16351 EXPECT_EQ(0, throttler->num_set_priority_calls());
16352 trans->SetPriority(LOW);
16353 EXPECT_EQ(1, throttler->num_set_priority_calls());
16354 EXPECT_EQ(LOW, throttler->last_priority_set());
16355
16356 throttler->UnthrottleAllRequests();
16357 base::RunLoop().RunUntilIdle();
16358 ASSERT_TRUE(callback.have_result());
16359 EXPECT_EQ(OK, callback.WaitForResult());
16360}
16361
16362// Confirm that unthrottling from a SetPriority call by the
16363// throttler works properly.
16364TEST_F(HttpNetworkTransactionTest, ThrottlingPrioritySetUnthrottle) {
16365 TestNetworkStreamThrottler* throttler(nullptr);
16366 std::unique_ptr<HttpNetworkSession> session(
16367 CreateSessionWithThrottler(&session_deps_, &throttler));
16368
16369 // Send a simple request and make sure it goes through.
16370 HttpRequestInfo request;
16371 request.method = "GET";
16372 request.url = GURL("http://www.example.org/");
16373
16374 MockWrite data_writes[] = {
16375 MockWrite("GET / HTTP/1.1\r\n"
16376 "Host: www.example.org\r\n"
16377 "Connection: keep-alive\r\n\r\n"),
16378 };
16379 MockRead data_reads[] = {
16380 MockRead("HTTP/1.0 200 OK\r\n\r\n"), MockRead("hello world"),
16381 MockRead(SYNCHRONOUS, OK),
16382 };
16383 StaticSocketDataProvider reads(data_reads, arraysize(data_reads), data_writes,
16384 arraysize(data_writes));
16385 session_deps_.socket_factory->AddSocketDataProvider(&reads);
16386
16387 StaticSocketDataProvider reads1(data_reads, arraysize(data_reads),
16388 data_writes, arraysize(data_writes));
16389 session_deps_.socket_factory->AddSocketDataProvider(&reads1);
16390
16391 // Start a request that will be throttled at start; confirm it
16392 // doesn't complete.
16393 throttler->set_throttle_new_requests(true);
16394 std::unique_ptr<HttpTransaction> trans(
16395 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
16396
16397 TestCompletionCallback callback;
16398 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
16399 EXPECT_EQ(ERR_IO_PENDING, rv);
16400
16401 base::RunLoop().RunUntilIdle();
16402 EXPECT_EQ(LOAD_STATE_THROTTLED, trans->GetLoadState());
16403 EXPECT_FALSE(callback.have_result());
16404
16405 // Create a new request, call SetPriority on it to unthrottle,
16406 // and make sure that allows the original request to complete.
16407 std::unique_ptr<HttpTransaction> trans1(
16408 new HttpNetworkTransaction(LOW, session.get()));
16409 throttler->set_priority_change_closure(
16410 base::Bind(&TestNetworkStreamThrottler::UnthrottleAllRequests,
16411 base::Unretained(throttler)));
16412
16413 // Start the transaction to associate a throttle with it.
16414 TestCompletionCallback callback1;
16415 rv = trans1->Start(&request, callback1.callback(), NetLogWithSource());
16416 EXPECT_EQ(ERR_IO_PENDING, rv);
16417
16418 trans1->SetPriority(IDLE);
16419
16420 base::RunLoop().RunUntilIdle();
16421 ASSERT_TRUE(callback.have_result());
16422 EXPECT_EQ(OK, callback.WaitForResult());
16423 ASSERT_TRUE(callback1.have_result());
16424 EXPECT_EQ(OK, callback1.WaitForResult());
16425}
16426
16427// Transaction will be destroyed when the unique_ptr goes out of scope.
16428void DestroyTransaction(std::unique_ptr<HttpTransaction> transaction) {}
16429
16430// Confirm that destroying a transaction from a SetPriority call by the
16431// throttler works properly.
16432TEST_F(HttpNetworkTransactionTest, ThrottlingPrioritySetDestroy) {
16433 TestNetworkStreamThrottler* throttler(nullptr);
16434 std::unique_ptr<HttpNetworkSession> session(
16435 CreateSessionWithThrottler(&session_deps_, &throttler));
16436
16437 // Send a simple request and make sure it goes through.
16438 HttpRequestInfo request;
16439 request.method = "GET";
16440 request.url = GURL("http://www.example.org/");
16441
16442 MockWrite data_writes[] = {
16443 MockWrite("GET / HTTP/1.1\r\n"
16444 "Host: www.example.org\r\n"
16445 "Connection: keep-alive\r\n\r\n"),
16446 };
16447 MockRead data_reads[] = {
16448 MockRead("HTTP/1.0 200 OK\r\n\r\n"), MockRead("hello world"),
16449 MockRead(SYNCHRONOUS, OK),
16450 };
16451 StaticSocketDataProvider reads(data_reads, arraysize(data_reads), data_writes,
16452 arraysize(data_writes));
16453 session_deps_.socket_factory->AddSocketDataProvider(&reads);
16454
16455 StaticSocketDataProvider reads1(data_reads, arraysize(data_reads),
16456 data_writes, arraysize(data_writes));
16457 session_deps_.socket_factory->AddSocketDataProvider(&reads1);
16458
16459 // Start a request that will be throttled at start; confirm it
16460 // doesn't complete.
16461 throttler->set_throttle_new_requests(true);
16462 std::unique_ptr<HttpTransaction> trans(
16463 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
16464
16465 TestCompletionCallback callback;
16466 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
16467 EXPECT_EQ(ERR_IO_PENDING, rv);
16468
16469 base::RunLoop().RunUntilIdle();
16470 EXPECT_EQ(LOAD_STATE_THROTTLED, trans->GetLoadState());
16471 EXPECT_FALSE(callback.have_result());
16472
16473 // Arrange for the set priority call on the above transaction to delete
16474 // the transaction.
16475 HttpTransaction* trans_ptr(trans.get());
16476 throttler->set_priority_change_closure(
16477 base::Bind(&DestroyTransaction, base::Passed(&trans)));
16478
16479 // Call it and check results (partially a "doesn't crash" test).
16480 trans_ptr->SetPriority(IDLE);
16481 trans_ptr = nullptr; // No longer a valid pointer.
16482
16483 base::RunLoop().RunUntilIdle();
16484 ASSERT_FALSE(callback.have_result());
16485}
16486
nharperb7441ef2016-01-25 23:54:1416487#if !defined(OS_IOS)
bncd16676a2016-07-20 16:23:0116488TEST_F(HttpNetworkTransactionTest, TokenBindingSpdy) {
fdoraya89e673c2017-01-31 21:44:2116489 // Required by ChannelIDService.
16490 base::test::ScopedTaskScheduler scoped_task_scheduler(
16491 base::MessageLoop::current());
16492
nharperb7441ef2016-01-25 23:54:1416493 const std::string https_url = "https://www.example.com";
16494 HttpRequestInfo request;
16495 request.url = GURL(https_url);
16496 request.method = "GET";
16497
16498 SSLSocketDataProvider ssl(ASYNC, OK);
16499 ssl.token_binding_negotiated = true;
16500 ssl.token_binding_key_param = TB_PARAM_ECDSAP256;
bnc3cf2a592016-08-11 14:48:3616501 ssl.next_proto = kProtoHTTP2;
nharperb7441ef2016-01-25 23:54:1416502 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
16503
bnc42331402016-07-25 13:36:1516504 SpdySerializedFrame resp(spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
bncdf80d44fd2016-07-15 20:27:4116505 SpdySerializedFrame body(spdy_util_.ConstructSpdyDataFrame(1, true));
16506 MockRead reads[] = {CreateMockRead(resp), CreateMockRead(body),
nharperb7441ef2016-01-25 23:54:1416507 MockRead(ASYNC, ERR_IO_PENDING)};
16508 StaticSocketDataProvider data(reads, arraysize(reads), nullptr, 0);
16509 session_deps_.socket_factory->AddSocketDataProvider(&data);
fdoraya89e673c2017-01-31 21:44:2116510 session_deps_.channel_id_service.reset(
16511 new ChannelIDService(new DefaultChannelIDStore(nullptr)));
danakj1fd259a02016-04-16 03:17:0916512 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
nharperb7441ef2016-01-25 23:54:1416513
16514 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
16515 TestCompletionCallback callback;
16516 EXPECT_EQ(ERR_IO_PENDING,
tfarina42834112016-09-22 13:38:2016517 trans.Start(&request, callback.callback(), NetLogWithSource()));
fdoray92e35a72016-06-10 15:54:5516518 base::RunLoop().RunUntilIdle();
nharperb7441ef2016-01-25 23:54:1416519
16520 EXPECT_TRUE(trans.GetResponseInfo()->was_fetched_via_spdy);
16521 HttpRequestHeaders headers;
16522 ASSERT_TRUE(trans.GetFullRequestHeaders(&headers));
16523 EXPECT_TRUE(headers.HasHeader(HttpRequestHeaders::kTokenBinding));
16524}
16525#endif // !defined(OS_IOS)
16526
[email protected]89ceba9a2009-03-21 03:46:0616527} // namespace net