blob: 542cb97379222e6e117adad2075faab94c0c9dca [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"
bnc8f8f7d302017-04-24 18:08:0686#include "net/spdy/chromium/spdy_session.h"
87#include "net/spdy/chromium/spdy_session_pool.h"
88#include "net/spdy/chromium/spdy_test_util_common.h"
89#include "net/spdy/core/spdy_framer.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_);
vmpstr6d9996c82017-02-23 00:43:25139 for (auto* throttle : outstanding_throttles_copy) {
rdsmithbf8c3c12016-11-18 18:16:24140 if (throttle->IsBlocked())
rdsmith1d343be52016-10-21 20:37:50141 throttle->Unthrottle();
142 }
143 }
144
145 void set_throttle_new_requests(bool throttle_new_requests) {
146 throttle_new_requests_ = throttle_new_requests;
147 }
148
149 // Includes both throttled and unthrottled throttles.
150 size_t num_outstanding_requests() const {
151 return outstanding_throttles_.size();
152 }
153
154 int num_set_priority_calls() const { return num_set_priority_calls_; }
155 RequestPriority last_priority_set() const { return last_priority_set_; }
156 void set_priority_change_closure(
157 const base::Closure& priority_change_closure) {
158 priority_change_closure_ = priority_change_closure;
159 }
160
161 private:
162 class TestThrottle : public NetworkThrottleManager::Throttle {
163 public:
164 ~TestThrottle() override { throttler_->OnThrottleDestroyed(this); }
165
166 // Throttle
rdsmithbf8c3c12016-11-18 18:16:24167 bool IsBlocked() const override { return throttled_; }
168 RequestPriority Priority() const override {
169 NOTREACHED();
170 return IDLE;
171 }
rdsmith1d343be52016-10-21 20:37:50172 void SetPriority(RequestPriority priority) override {
173 throttler_->SetPriorityCalled(priority);
174 }
175
176 TestThrottle(bool throttled,
177 ThrottleDelegate* delegate,
178 TestNetworkStreamThrottler* throttler)
179 : throttled_(throttled), delegate_(delegate), throttler_(throttler) {}
180
181 void Unthrottle() {
182 EXPECT_TRUE(throttled_);
183
184 throttled_ = false;
rdsmithbf8c3c12016-11-18 18:16:24185 delegate_->OnThrottleUnblocked(this);
rdsmith1d343be52016-10-21 20:37:50186 }
187
188 bool throttled_;
189 ThrottleDelegate* delegate_;
190 TestNetworkStreamThrottler* throttler_;
191 };
192
193 void OnThrottleDestroyed(TestThrottle* throttle) {
194 EXPECT_NE(0u, outstanding_throttles_.count(throttle));
195 outstanding_throttles_.erase(throttle);
196 }
197
198 void SetPriorityCalled(RequestPriority priority) {
199 ++num_set_priority_calls_;
200 last_priority_set_ = priority;
201 if (!priority_change_closure_.is_null())
202 priority_change_closure_.Run();
203 }
204
205 // Includes both throttled and unthrottled throttles.
206 std::set<TestThrottle*> outstanding_throttles_;
207 bool throttle_new_requests_;
208 int num_set_priority_calls_;
209 RequestPriority last_priority_set_;
210 base::Closure priority_change_closure_;
211
212 DISALLOW_COPY_AND_ASSIGN(TestNetworkStreamThrottler);
213};
214
[email protected]42cba2fb2013-03-29 19:58:57215const base::string16 kBar(ASCIIToUTF16("bar"));
216const base::string16 kBar2(ASCIIToUTF16("bar2"));
217const base::string16 kBar3(ASCIIToUTF16("bar3"));
218const base::string16 kBaz(ASCIIToUTF16("baz"));
219const base::string16 kFirst(ASCIIToUTF16("first"));
220const base::string16 kFoo(ASCIIToUTF16("foo"));
221const base::string16 kFoo2(ASCIIToUTF16("foo2"));
222const base::string16 kFoo3(ASCIIToUTF16("foo3"));
223const base::string16 kFou(ASCIIToUTF16("fou"));
224const base::string16 kSecond(ASCIIToUTF16("second"));
225const base::string16 kTestingNTLM(ASCIIToUTF16("testing-ntlm"));
226const base::string16 kWrongPassword(ASCIIToUTF16("wrongpassword"));
[email protected]13c8a092010-07-29 06:15:44227
bnc2df4b522016-07-08 18:17:43228const char kAlternativeServiceHttpHeader[] =
229 "Alt-Svc: h2=\"mail.example.org:443\"\r\n";
230
ttuttle859dc7a2015-04-23 19:42:29231int GetIdleSocketCountInTransportSocketPool(HttpNetworkSession* session) {
232 return session->GetTransportSocketPool(HttpNetworkSession::NORMAL_SOCKET_POOL)
233 ->IdleSocketCount();
[email protected]e5c026642012-03-17 00:14:02234}
235
ttuttle859dc7a2015-04-23 19:42:29236int GetIdleSocketCountInSSLSocketPool(HttpNetworkSession* session) {
237 return session->GetSSLSocketPool(HttpNetworkSession::NORMAL_SOCKET_POOL)
238 ->IdleSocketCount();
[email protected]e5c026642012-03-17 00:14:02239}
240
ttuttle859dc7a2015-04-23 19:42:29241bool IsTransportSocketPoolStalled(HttpNetworkSession* session) {
242 return session->GetTransportSocketPool(HttpNetworkSession::NORMAL_SOCKET_POOL)
243 ->IsStalled();
[email protected]043b68c82013-08-22 23:41:52244}
245
[email protected]f3da152d2012-06-02 01:00:57246// Takes in a Value created from a NetLogHttpResponseParameter, and returns
247// a JSONified list of headers as a single string. Uses single quotes instead
248// of double quotes for easier comparison. Returns false on failure.
[email protected]ea5ef4c2013-06-13 22:50:27249bool GetHeaders(base::DictionaryValue* params, std::string* headers) {
[email protected]f3da152d2012-06-02 01:00:57250 if (!params)
251 return false;
[email protected]ea5ef4c2013-06-13 22:50:27252 base::ListValue* header_list;
[email protected]f3da152d2012-06-02 01:00:57253 if (!params->GetList("headers", &header_list))
254 return false;
255 std::string double_quote_headers;
estade8d046462015-05-16 01:02:34256 base::JSONWriter::Write(*header_list, &double_quote_headers);
[email protected]466c9862013-12-03 22:05:28257 base::ReplaceChars(double_quote_headers, "\"", "'", headers);
[email protected]f3da152d2012-06-02 01:00:57258 return true;
259}
260
[email protected]029c83b62013-01-24 05:28:20261// Tests LoadTimingInfo in the case a socket is reused and no PAC script is
262// used.
ttuttle859dc7a2015-04-23 19:42:29263void TestLoadTimingReused(const LoadTimingInfo& load_timing_info) {
[email protected]029c83b62013-01-24 05:28:20264 EXPECT_TRUE(load_timing_info.socket_reused);
mikecironef22f9812016-10-04 03:40:19265 EXPECT_NE(NetLogSource::kInvalidId, load_timing_info.socket_log_id);
[email protected]58e32bb2013-01-21 18:23:25266
[email protected]029c83b62013-01-24 05:28:20267 EXPECT_TRUE(load_timing_info.proxy_resolve_start.is_null());
268 EXPECT_TRUE(load_timing_info.proxy_resolve_end.is_null());
269
ttuttle859dc7a2015-04-23 19:42:29270 ExpectConnectTimingHasNoTimes(load_timing_info.connect_timing);
[email protected]029c83b62013-01-24 05:28:20271 EXPECT_FALSE(load_timing_info.send_start.is_null());
[email protected]58e32bb2013-01-21 18:23:25272
273 EXPECT_LE(load_timing_info.send_start, load_timing_info.send_end);
[email protected]58e32bb2013-01-21 18:23:25274
[email protected]3b23a222013-05-15 21:33:25275 // Set at a higher level.
[email protected]58e32bb2013-01-21 18:23:25276 EXPECT_TRUE(load_timing_info.request_start_time.is_null());
277 EXPECT_TRUE(load_timing_info.request_start.is_null());
[email protected]3b23a222013-05-15 21:33:25278 EXPECT_TRUE(load_timing_info.receive_headers_end.is_null());
[email protected]58e32bb2013-01-21 18:23:25279}
280
[email protected]029c83b62013-01-24 05:28:20281// Tests LoadTimingInfo in the case a new socket is used and no PAC script is
282// used.
ttuttle859dc7a2015-04-23 19:42:29283void TestLoadTimingNotReused(const LoadTimingInfo& load_timing_info,
[email protected]58e32bb2013-01-21 18:23:25284 int connect_timing_flags) {
[email protected]029c83b62013-01-24 05:28:20285 EXPECT_FALSE(load_timing_info.socket_reused);
mikecironef22f9812016-10-04 03:40:19286 EXPECT_NE(NetLogSource::kInvalidId, load_timing_info.socket_log_id);
[email protected]029c83b62013-01-24 05:28:20287
288 EXPECT_TRUE(load_timing_info.proxy_resolve_start.is_null());
289 EXPECT_TRUE(load_timing_info.proxy_resolve_end.is_null());
290
ttuttle859dc7a2015-04-23 19:42:29291 ExpectConnectTimingHasTimes(load_timing_info.connect_timing,
292 connect_timing_flags);
[email protected]029c83b62013-01-24 05:28:20293 EXPECT_LE(load_timing_info.connect_timing.connect_end,
294 load_timing_info.send_start);
295
296 EXPECT_LE(load_timing_info.send_start, load_timing_info.send_end);
[email protected]029c83b62013-01-24 05:28:20297
[email protected]3b23a222013-05-15 21:33:25298 // Set at a higher level.
[email protected]029c83b62013-01-24 05:28:20299 EXPECT_TRUE(load_timing_info.request_start_time.is_null());
300 EXPECT_TRUE(load_timing_info.request_start.is_null());
[email protected]3b23a222013-05-15 21:33:25301 EXPECT_TRUE(load_timing_info.receive_headers_end.is_null());
[email protected]029c83b62013-01-24 05:28:20302}
303
304// Tests LoadTimingInfo in the case a socket is reused and a PAC script is
305// used.
ttuttle859dc7a2015-04-23 19:42:29306void TestLoadTimingReusedWithPac(const LoadTimingInfo& load_timing_info) {
[email protected]029c83b62013-01-24 05:28:20307 EXPECT_TRUE(load_timing_info.socket_reused);
mikecironef22f9812016-10-04 03:40:19308 EXPECT_NE(NetLogSource::kInvalidId, load_timing_info.socket_log_id);
[email protected]029c83b62013-01-24 05:28:20309
ttuttle859dc7a2015-04-23 19:42:29310 ExpectConnectTimingHasNoTimes(load_timing_info.connect_timing);
[email protected]029c83b62013-01-24 05:28:20311
312 EXPECT_FALSE(load_timing_info.proxy_resolve_start.is_null());
313 EXPECT_LE(load_timing_info.proxy_resolve_start,
314 load_timing_info.proxy_resolve_end);
315 EXPECT_LE(load_timing_info.proxy_resolve_end,
316 load_timing_info.send_start);
317 EXPECT_LE(load_timing_info.send_start, load_timing_info.send_end);
[email protected]029c83b62013-01-24 05:28:20318
[email protected]3b23a222013-05-15 21:33:25319 // Set at a higher level.
[email protected]029c83b62013-01-24 05:28:20320 EXPECT_TRUE(load_timing_info.request_start_time.is_null());
321 EXPECT_TRUE(load_timing_info.request_start.is_null());
[email protected]3b23a222013-05-15 21:33:25322 EXPECT_TRUE(load_timing_info.receive_headers_end.is_null());
[email protected]029c83b62013-01-24 05:28:20323}
324
325// Tests LoadTimingInfo in the case a new socket is used and a PAC script is
326// used.
ttuttle859dc7a2015-04-23 19:42:29327void TestLoadTimingNotReusedWithPac(const LoadTimingInfo& load_timing_info,
[email protected]029c83b62013-01-24 05:28:20328 int connect_timing_flags) {
329 EXPECT_FALSE(load_timing_info.socket_reused);
mikecironef22f9812016-10-04 03:40:19330 EXPECT_NE(NetLogSource::kInvalidId, load_timing_info.socket_log_id);
[email protected]029c83b62013-01-24 05:28:20331
332 EXPECT_FALSE(load_timing_info.proxy_resolve_start.is_null());
333 EXPECT_LE(load_timing_info.proxy_resolve_start,
334 load_timing_info.proxy_resolve_end);
335 EXPECT_LE(load_timing_info.proxy_resolve_end,
336 load_timing_info.connect_timing.connect_start);
ttuttle859dc7a2015-04-23 19:42:29337 ExpectConnectTimingHasTimes(load_timing_info.connect_timing,
338 connect_timing_flags);
[email protected]029c83b62013-01-24 05:28:20339 EXPECT_LE(load_timing_info.connect_timing.connect_end,
340 load_timing_info.send_start);
341
342 EXPECT_LE(load_timing_info.send_start, load_timing_info.send_end);
[email protected]029c83b62013-01-24 05:28:20343
[email protected]3b23a222013-05-15 21:33:25344 // Set at a higher level.
[email protected]029c83b62013-01-24 05:28:20345 EXPECT_TRUE(load_timing_info.request_start_time.is_null());
346 EXPECT_TRUE(load_timing_info.request_start.is_null());
[email protected]3b23a222013-05-15 21:33:25347 EXPECT_TRUE(load_timing_info.receive_headers_end.is_null());
[email protected]58e32bb2013-01-21 18:23:25348}
349
ttuttle859dc7a2015-04-23 19:42:29350void AddWebSocketHeaders(HttpRequestHeaders* headers) {
Adam Rice425cf122015-01-19 06:18:24351 headers->SetHeader("Connection", "Upgrade");
352 headers->SetHeader("Upgrade", "websocket");
bncce36dca22015-04-21 22:11:23353 headers->SetHeader("Origin", "http://www.example.org");
Adam Rice425cf122015-01-19 06:18:24354 headers->SetHeader("Sec-WebSocket-Version", "13");
355 headers->SetHeader("Sec-WebSocket-Key", "dGhlIHNhbXBsZSBub25jZQ==");
356}
357
danakj1fd259a02016-04-16 03:17:09358std::unique_ptr<HttpNetworkSession> CreateSession(
mmenkee65e7af2015-10-13 17:16:42359 SpdySessionDependencies* session_deps) {
[email protected]c6bf8152012-12-02 07:43:34360 return SpdySessionDependencies::SpdyCreateSession(session_deps);
[email protected]e8d536192008-10-17 22:21:14361}
362
rdsmith1d343be52016-10-21 20:37:50363// Note that the pointer written into |*throttler| will only be valid
364// for the lifetime of the returned HttpNetworkSession.
365std::unique_ptr<HttpNetworkSession> CreateSessionWithThrottler(
366 SpdySessionDependencies* session_deps,
367 TestNetworkStreamThrottler** throttler) {
368 std::unique_ptr<HttpNetworkSession> session(
369 SpdySessionDependencies::SpdyCreateSession(session_deps));
370
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)) {
bnca86731e2017-04-17 12:31:28401 session_deps_.enable_http2_alternative_service = 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 {}
xunjieli92feb332017-03-03 17:19:23687 void CloseIdleSocketsInGroup(const std::string& group_name) override {}
dmichaeld6e570d2014-12-18 22:30:57688 int IdleSocketCount() const override { return 0; }
689 int IdleSocketCountInGroup(const std::string& group_name) const override {
[email protected]04e5be32009-06-26 20:00:31690 return 0;
691 }
dmichaeld6e570d2014-12-18 22:30:57692 LoadState GetLoadState(const std::string& group_name,
693 const ClientSocketHandle* handle) const override {
[email protected]04e5be32009-06-26 20:00:31694 return LOAD_STATE_IDLE;
695 }
dmichaeld6e570d2014-12-18 22:30:57696 base::TimeDelta ConnectionTimeout() const override {
[email protected]a796bcec2010-03-22 17:17:26697 return base::TimeDelta();
698 }
[email protected]d80a4322009-08-14 07:07:49699
700 private:
[email protected]04e5be32009-06-26 20:00:31701 std::string last_group_name_;
702};
703
[email protected]ab739042011-04-07 15:22:28704typedef CaptureGroupNameSocketPool<TransportClientSocketPool>
705CaptureGroupNameTransportSocketPool;
[email protected]e772db3f2010-07-12 18:11:13706typedef CaptureGroupNameSocketPool<HttpProxyClientSocketPool>
707CaptureGroupNameHttpProxySocketPool;
[email protected]2d731a32010-04-29 01:04:06708typedef CaptureGroupNameSocketPool<SOCKSClientSocketPool>
[email protected]2227c692010-05-04 15:36:11709CaptureGroupNameSOCKSSocketPool;
[email protected]e60e47a2010-07-14 03:37:18710typedef CaptureGroupNameSocketPool<SSLClientSocketPool>
711CaptureGroupNameSSLSocketPool;
712
rkaplowd90695c2015-03-25 22:12:41713template <typename ParentPool>
[email protected]e60e47a2010-07-14 03:37:18714CaptureGroupNameSocketPool<ParentPool>::CaptureGroupNameSocketPool(
[email protected]9e1bdd32011-02-03 21:48:34715 HostResolver* host_resolver,
716 CertVerifier* /* cert_verifier */)
tbansal7b403bcc2016-04-13 22:33:21717 : ParentPool(0, 0, host_resolver, NULL, NULL, NULL) {}
[email protected]e60e47a2010-07-14 03:37:18718
hashimoto0d3e4fb2015-01-09 05:02:50719template <>
[email protected]2df19bb2010-08-25 20:13:46720CaptureGroupNameHttpProxySocketPool::CaptureGroupNameSocketPool(
hashimotodae13b02015-01-15 04:28:21721 HostResolver* /* host_resolver */,
[email protected]9e1bdd32011-02-03 21:48:34722 CertVerifier* /* cert_verifier */)
rkaplowd90695c2015-03-25 22:12:41723 : HttpProxyClientSocketPool(0, 0, NULL, NULL, NULL) {
hashimoto0d3e4fb2015-01-09 05:02:50724}
[email protected]2df19bb2010-08-25 20:13:46725
[email protected]007b3f82013-04-09 08:46:45726template <>
[email protected]e60e47a2010-07-14 03:37:18727CaptureGroupNameSSLSocketPool::CaptureGroupNameSocketPool(
hashimotodae13b02015-01-15 04:28:21728 HostResolver* /* host_resolver */,
[email protected]9e1bdd32011-02-03 21:48:34729 CertVerifier* cert_verifier)
[email protected]007b3f82013-04-09 08:46:45730 : SSLClientSocketPool(0,
731 0,
[email protected]007b3f82013-04-09 08:46:45732 cert_verifier,
733 NULL,
734 NULL,
[email protected]284303b62013-11-28 15:11:54735 NULL,
eranm6571b2b2014-12-03 15:53:23736 NULL,
[email protected]007b3f82013-04-09 08:46:45737 std::string(),
738 NULL,
739 NULL,
740 NULL,
741 NULL,
742 NULL,
[email protected]8e458552014-08-05 00:02:15743 NULL) {
744}
[email protected]2227c692010-05-04 15:36:11745
[email protected]231d5a32008-09-13 00:45:27746//-----------------------------------------------------------------------------
747
[email protected]79cb5c12011-09-12 13:12:04748// Helper functions for validating that AuthChallengeInfo's are correctly
749// configured for common cases.
750bool CheckBasicServerAuth(const AuthChallengeInfo* auth_challenge) {
751 if (!auth_challenge)
752 return false;
753 EXPECT_FALSE(auth_challenge->is_proxy);
asanka098c0092016-06-16 20:18:43754 EXPECT_EQ("http://www.example.org", auth_challenge->challenger.Serialize());
[email protected]79cb5c12011-09-12 13:12:04755 EXPECT_EQ("MyRealm1", auth_challenge->realm);
aberentbba302d2015-12-03 10:20:19756 EXPECT_EQ(kBasicAuthScheme, auth_challenge->scheme);
[email protected]79cb5c12011-09-12 13:12:04757 return true;
758}
759
760bool CheckBasicProxyAuth(const AuthChallengeInfo* auth_challenge) {
761 if (!auth_challenge)
762 return false;
763 EXPECT_TRUE(auth_challenge->is_proxy);
asanka098c0092016-06-16 20:18:43764 EXPECT_EQ("http://myproxy:70", auth_challenge->challenger.Serialize());
765 EXPECT_EQ("MyRealm1", auth_challenge->realm);
766 EXPECT_EQ(kBasicAuthScheme, auth_challenge->scheme);
767 return true;
768}
769
770bool CheckBasicSecureProxyAuth(const AuthChallengeInfo* auth_challenge) {
771 if (!auth_challenge)
772 return false;
773 EXPECT_TRUE(auth_challenge->is_proxy);
774 EXPECT_EQ("https://myproxy:70", auth_challenge->challenger.Serialize());
[email protected]79cb5c12011-09-12 13:12:04775 EXPECT_EQ("MyRealm1", auth_challenge->realm);
aberentbba302d2015-12-03 10:20:19776 EXPECT_EQ(kBasicAuthScheme, auth_challenge->scheme);
[email protected]79cb5c12011-09-12 13:12:04777 return true;
778}
779
780bool CheckDigestServerAuth(const AuthChallengeInfo* auth_challenge) {
781 if (!auth_challenge)
782 return false;
783 EXPECT_FALSE(auth_challenge->is_proxy);
asanka098c0092016-06-16 20:18:43784 EXPECT_EQ("http://www.example.org", auth_challenge->challenger.Serialize());
[email protected]79cb5c12011-09-12 13:12:04785 EXPECT_EQ("digestive", auth_challenge->realm);
aberentbba302d2015-12-03 10:20:19786 EXPECT_EQ(kDigestAuthScheme, auth_challenge->scheme);
[email protected]79cb5c12011-09-12 13:12:04787 return true;
788}
789
thakis84dff942015-07-28 20:47:38790#if defined(NTLM_PORTABLE)
[email protected]79cb5c12011-09-12 13:12:04791bool CheckNTLMServerAuth(const AuthChallengeInfo* auth_challenge) {
792 if (!auth_challenge)
793 return false;
794 EXPECT_FALSE(auth_challenge->is_proxy);
asanka098c0092016-06-16 20:18:43795 EXPECT_EQ("http://172.22.68.17", auth_challenge->challenger.Serialize());
[email protected]79cb5c12011-09-12 13:12:04796 EXPECT_EQ(std::string(), auth_challenge->realm);
aberentbba302d2015-12-03 10:20:19797 EXPECT_EQ(kNtlmAuthScheme, auth_challenge->scheme);
[email protected]79cb5c12011-09-12 13:12:04798 return true;
799}
thakis84dff942015-07-28 20:47:38800#endif // defined(NTLM_PORTABLE)
[email protected]79cb5c12011-09-12 13:12:04801
[email protected]448d4ca52012-03-04 04:12:23802} // namespace
803
bncd16676a2016-07-20 16:23:01804TEST_F(HttpNetworkTransactionTest, Basic) {
danakj1fd259a02016-04-16 03:17:09805 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:16806 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]231d5a32008-09-13 00:45:27807}
808
bncd16676a2016-07-20 16:23:01809TEST_F(HttpNetworkTransactionTest, SimpleGET) {
[email protected]231d5a32008-09-13 00:45:27810 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:35811 MockRead("HTTP/1.0 200 OK\r\n\r\n"),
812 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:06813 MockRead(SYNCHRONOUS, OK),
[email protected]231d5a32008-09-13 00:45:27814 };
[email protected]31a2bfe2010-02-09 08:03:39815 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
816 arraysize(data_reads));
robpercival214763f2016-07-01 23:27:01817 EXPECT_THAT(out.rv, IsOk());
[email protected]231d5a32008-09-13 00:45:27818 EXPECT_EQ("HTTP/1.0 200 OK", out.status_line);
819 EXPECT_EQ("hello world", out.response_data);
sclittlefb249892015-09-10 21:33:22820 int64_t reads_size = CountReadBytes(data_reads, arraysize(data_reads));
821 EXPECT_EQ(reads_size, out.total_received_bytes);
ttuttle1f2d7e92015-04-28 16:17:47822 EXPECT_EQ(0u, out.connection_attempts.size());
ttuttled9dbc652015-09-29 20:00:59823
824 EXPECT_FALSE(out.remote_endpoint_after_start.address().empty());
[email protected]231d5a32008-09-13 00:45:27825}
826
827// Response with no status line.
bncd16676a2016-07-20 16:23:01828TEST_F(HttpNetworkTransactionTest, SimpleGETNoHeaders) {
[email protected]231d5a32008-09-13 00:45:27829 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:35830 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:06831 MockRead(SYNCHRONOUS, OK),
[email protected]231d5a32008-09-13 00:45:27832 };
[email protected]31a2bfe2010-02-09 08:03:39833 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
834 arraysize(data_reads));
mmenkea2dcd3bf2016-08-16 21:49:41835 EXPECT_THAT(out.rv, IsOk());
836 EXPECT_EQ("HTTP/0.9 200 OK", out.status_line);
837 EXPECT_EQ("hello world", out.response_data);
838 int64_t reads_size = CountReadBytes(data_reads, arraysize(data_reads));
839 EXPECT_EQ(reads_size, out.total_received_bytes);
[email protected]231d5a32008-09-13 00:45:27840}
841
mmenkea7da6da2016-09-01 21:56:52842// Response with no status line, and a weird port. Should fail by default.
843TEST_F(HttpNetworkTransactionTest, SimpleGETNoHeadersWeirdPort) {
844 MockRead data_reads[] = {
845 MockRead("hello world"), MockRead(SYNCHRONOUS, OK),
846 };
847
848 StaticSocketDataProvider data(data_reads, arraysize(data_reads), nullptr, 0);
849 session_deps_.socket_factory->AddSocketDataProvider(&data);
850
851 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
852
krasinc06a72a2016-12-21 03:42:46853 HttpRequestInfo request;
mmenkea7da6da2016-09-01 21:56:52854 std::unique_ptr<HttpTransaction> trans(
855 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
856
mmenkea7da6da2016-09-01 21:56:52857 request.method = "GET";
858 request.url = GURL("http://www.example.com:2000/");
859 TestCompletionCallback callback;
tfarina42834112016-09-22 13:38:20860 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
mmenkea7da6da2016-09-01 21:56:52861 EXPECT_THAT(callback.GetResult(rv), IsError(ERR_INVALID_HTTP_RESPONSE));
862}
863
864// Response with no status line, and a weird port. Option to allow weird ports
865// enabled.
866TEST_F(HttpNetworkTransactionTest, SimpleGETNoHeadersWeirdPortAllowed) {
867 MockRead data_reads[] = {
868 MockRead("hello world"), MockRead(SYNCHRONOUS, OK),
869 };
870
871 StaticSocketDataProvider data(data_reads, arraysize(data_reads), nullptr, 0);
872 session_deps_.socket_factory->AddSocketDataProvider(&data);
873 session_deps_.http_09_on_non_default_ports_enabled = true;
874 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
875
krasinc06a72a2016-12-21 03:42:46876 HttpRequestInfo request;
mmenkea7da6da2016-09-01 21:56:52877 std::unique_ptr<HttpTransaction> trans(
878 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
879
mmenkea7da6da2016-09-01 21:56:52880 request.method = "GET";
881 request.url = GURL("http://www.example.com:2000/");
882 TestCompletionCallback callback;
tfarina42834112016-09-22 13:38:20883 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
mmenkea7da6da2016-09-01 21:56:52884 EXPECT_THAT(callback.GetResult(rv), IsOk());
885
886 const HttpResponseInfo* info = trans->GetResponseInfo();
887 ASSERT_TRUE(info->headers);
888 EXPECT_EQ("HTTP/0.9 200 OK", info->headers->GetStatusLine());
889
890 // Don't bother to read the body - that's verified elsewhere, important thing
891 // is that the option to allow HTTP/0.9 on non-default ports is respected.
892}
893
[email protected]231d5a32008-09-13 00:45:27894// Allow up to 4 bytes of junk to precede status line.
bncd16676a2016-07-20 16:23:01895TEST_F(HttpNetworkTransactionTest, StatusLineJunk3Bytes) {
[email protected]231d5a32008-09-13 00:45:27896 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:35897 MockRead("xxxHTTP/1.0 404 Not Found\nServer: blah\n\nDATA"),
[email protected]8ddf8322012-02-23 18:08:06898 MockRead(SYNCHRONOUS, OK),
[email protected]231d5a32008-09-13 00:45:27899 };
[email protected]31a2bfe2010-02-09 08:03:39900 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
901 arraysize(data_reads));
robpercival214763f2016-07-01 23:27:01902 EXPECT_THAT(out.rv, IsOk());
[email protected]231d5a32008-09-13 00:45:27903 EXPECT_EQ("HTTP/1.0 404 Not Found", out.status_line);
904 EXPECT_EQ("DATA", out.response_data);
sclittlefb249892015-09-10 21:33:22905 int64_t reads_size = CountReadBytes(data_reads, arraysize(data_reads));
906 EXPECT_EQ(reads_size, out.total_received_bytes);
[email protected]231d5a32008-09-13 00:45:27907}
908
909// Allow up to 4 bytes of junk to precede status line.
bncd16676a2016-07-20 16:23:01910TEST_F(HttpNetworkTransactionTest, StatusLineJunk4Bytes) {
[email protected]231d5a32008-09-13 00:45:27911 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:35912 MockRead("\n\nQJHTTP/1.0 404 Not Found\nServer: blah\n\nDATA"),
[email protected]8ddf8322012-02-23 18:08:06913 MockRead(SYNCHRONOUS, OK),
[email protected]231d5a32008-09-13 00:45:27914 };
[email protected]31a2bfe2010-02-09 08:03:39915 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
916 arraysize(data_reads));
robpercival214763f2016-07-01 23:27:01917 EXPECT_THAT(out.rv, IsOk());
[email protected]231d5a32008-09-13 00:45:27918 EXPECT_EQ("HTTP/1.0 404 Not Found", out.status_line);
919 EXPECT_EQ("DATA", out.response_data);
sclittlefb249892015-09-10 21:33:22920 int64_t reads_size = CountReadBytes(data_reads, arraysize(data_reads));
921 EXPECT_EQ(reads_size, out.total_received_bytes);
[email protected]231d5a32008-09-13 00:45:27922}
923
924// Beyond 4 bytes of slop and it should fail to find a status line.
bncd16676a2016-07-20 16:23:01925TEST_F(HttpNetworkTransactionTest, StatusLineJunk5Bytes) {
[email protected]231d5a32008-09-13 00:45:27926 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:35927 MockRead("xxxxxHTTP/1.1 404 Not Found\nServer: blah"),
[email protected]8ddf8322012-02-23 18:08:06928 MockRead(SYNCHRONOUS, OK),
[email protected]231d5a32008-09-13 00:45:27929 };
[email protected]31a2bfe2010-02-09 08:03:39930 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
931 arraysize(data_reads));
mmenkea2dcd3bf2016-08-16 21:49:41932 EXPECT_THAT(out.rv, IsOk());
933 EXPECT_EQ("HTTP/0.9 200 OK", out.status_line);
934 EXPECT_EQ("xxxxxHTTP/1.1 404 Not Found\nServer: blah", out.response_data);
935 int64_t reads_size = CountReadBytes(data_reads, arraysize(data_reads));
936 EXPECT_EQ(reads_size, out.total_received_bytes);
[email protected]231d5a32008-09-13 00:45:27937}
938
939// Same as StatusLineJunk4Bytes, except the read chunks are smaller.
bncd16676a2016-07-20 16:23:01940TEST_F(HttpNetworkTransactionTest, StatusLineJunk4Bytes_Slow) {
[email protected]231d5a32008-09-13 00:45:27941 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:35942 MockRead("\n"),
943 MockRead("\n"),
944 MockRead("Q"),
945 MockRead("J"),
946 MockRead("HTTP/1.0 404 Not Found\nServer: blah\n\nDATA"),
[email protected]8ddf8322012-02-23 18:08:06947 MockRead(SYNCHRONOUS, OK),
[email protected]231d5a32008-09-13 00:45:27948 };
[email protected]31a2bfe2010-02-09 08:03:39949 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
950 arraysize(data_reads));
robpercival214763f2016-07-01 23:27:01951 EXPECT_THAT(out.rv, IsOk());
[email protected]231d5a32008-09-13 00:45:27952 EXPECT_EQ("HTTP/1.0 404 Not Found", out.status_line);
953 EXPECT_EQ("DATA", out.response_data);
sclittlefb249892015-09-10 21:33:22954 int64_t reads_size = CountReadBytes(data_reads, arraysize(data_reads));
955 EXPECT_EQ(reads_size, out.total_received_bytes);
[email protected]231d5a32008-09-13 00:45:27956}
957
958// Close the connection before enough bytes to have a status line.
bncd16676a2016-07-20 16:23:01959TEST_F(HttpNetworkTransactionTest, StatusLinePartial) {
[email protected]231d5a32008-09-13 00:45:27960 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:35961 MockRead("HTT"),
[email protected]8ddf8322012-02-23 18:08:06962 MockRead(SYNCHRONOUS, OK),
[email protected]231d5a32008-09-13 00:45:27963 };
[email protected]31a2bfe2010-02-09 08:03:39964 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
965 arraysize(data_reads));
mmenkea2dcd3bf2016-08-16 21:49:41966 EXPECT_THAT(out.rv, IsOk());
967 EXPECT_EQ("HTTP/0.9 200 OK", out.status_line);
968 EXPECT_EQ("HTT", out.response_data);
969 int64_t reads_size = CountReadBytes(data_reads, arraysize(data_reads));
970 EXPECT_EQ(reads_size, out.total_received_bytes);
initial.commit586acc5fe2008-07-26 22:42:52971}
972
[email protected]f9d44aa2008-09-23 23:57:17973// Simulate a 204 response, lacking a Content-Length header, sent over a
974// persistent connection. The response should still terminate since a 204
975// cannot have a response body.
bncd16676a2016-07-20 16:23:01976TEST_F(HttpNetworkTransactionTest, StopsReading204) {
[email protected]b8015c42013-12-24 15:18:19977 char junk[] = "junk";
[email protected]f9d44aa2008-09-23 23:57:17978 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:35979 MockRead("HTTP/1.1 204 No Content\r\n\r\n"),
[email protected]b8015c42013-12-24 15:18:19980 MockRead(junk), // Should not be read!!
[email protected]8ddf8322012-02-23 18:08:06981 MockRead(SYNCHRONOUS, OK),
[email protected]f9d44aa2008-09-23 23:57:17982 };
[email protected]31a2bfe2010-02-09 08:03:39983 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
984 arraysize(data_reads));
robpercival214763f2016-07-01 23:27:01985 EXPECT_THAT(out.rv, IsOk());
[email protected]f9d44aa2008-09-23 23:57:17986 EXPECT_EQ("HTTP/1.1 204 No Content", out.status_line);
987 EXPECT_EQ("", out.response_data);
sclittlefb249892015-09-10 21:33:22988 int64_t reads_size = CountReadBytes(data_reads, arraysize(data_reads));
989 int64_t response_size = reads_size - strlen(junk);
990 EXPECT_EQ(response_size, out.total_received_bytes);
[email protected]f9d44aa2008-09-23 23:57:17991}
992
[email protected]0877e3d2009-10-17 22:29:57993// A simple request using chunked encoding with some extra data after.
bncd16676a2016-07-20 16:23:01994TEST_F(HttpNetworkTransactionTest, ChunkedEncoding) {
[email protected]b8015c42013-12-24 15:18:19995 std::string final_chunk = "0\r\n\r\n";
996 std::string extra_data = "HTTP/1.1 200 OK\r\n";
997 std::string last_read = final_chunk + extra_data;
[email protected]0877e3d2009-10-17 22:29:57998 MockRead data_reads[] = {
999 MockRead("HTTP/1.1 200 OK\r\nTransfer-Encoding: chunked\r\n\r\n"),
1000 MockRead("5\r\nHello\r\n"),
1001 MockRead("1\r\n"),
1002 MockRead(" \r\n"),
1003 MockRead("5\r\nworld\r\n"),
[email protected]b8015c42013-12-24 15:18:191004 MockRead(last_read.data()),
[email protected]8ddf8322012-02-23 18:08:061005 MockRead(SYNCHRONOUS, OK),
[email protected]0877e3d2009-10-17 22:29:571006 };
[email protected]31a2bfe2010-02-09 08:03:391007 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
1008 arraysize(data_reads));
robpercival214763f2016-07-01 23:27:011009 EXPECT_THAT(out.rv, IsOk());
[email protected]0877e3d2009-10-17 22:29:571010 EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
1011 EXPECT_EQ("Hello world", out.response_data);
sclittlefb249892015-09-10 21:33:221012 int64_t reads_size = CountReadBytes(data_reads, arraysize(data_reads));
1013 int64_t response_size = reads_size - extra_data.size();
1014 EXPECT_EQ(response_size, out.total_received_bytes);
[email protected]0877e3d2009-10-17 22:29:571015}
1016
[email protected]9fe44f52010-09-23 18:36:001017// Next tests deal with http://crbug.com/56344.
1018
bncd16676a2016-07-20 16:23:011019TEST_F(HttpNetworkTransactionTest,
[email protected]9fe44f52010-09-23 18:36:001020 MultipleContentLengthHeadersNoTransferEncoding) {
1021 MockRead data_reads[] = {
1022 MockRead("HTTP/1.1 200 OK\r\n"),
1023 MockRead("Content-Length: 10\r\n"),
1024 MockRead("Content-Length: 5\r\n\r\n"),
1025 };
1026 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
1027 arraysize(data_reads));
robpercival214763f2016-07-01 23:27:011028 EXPECT_THAT(out.rv, IsError(ERR_RESPONSE_HEADERS_MULTIPLE_CONTENT_LENGTH));
[email protected]9fe44f52010-09-23 18:36:001029}
1030
bncd16676a2016-07-20 16:23:011031TEST_F(HttpNetworkTransactionTest,
[email protected]44b52042010-10-29 22:48:041032 DuplicateContentLengthHeadersNoTransferEncoding) {
1033 MockRead data_reads[] = {
1034 MockRead("HTTP/1.1 200 OK\r\n"),
1035 MockRead("Content-Length: 5\r\n"),
1036 MockRead("Content-Length: 5\r\n\r\n"),
1037 MockRead("Hello"),
1038 };
1039 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
1040 arraysize(data_reads));
robpercival214763f2016-07-01 23:27:011041 EXPECT_THAT(out.rv, IsOk());
[email protected]44b52042010-10-29 22:48:041042 EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
1043 EXPECT_EQ("Hello", out.response_data);
1044}
1045
bncd16676a2016-07-20 16:23:011046TEST_F(HttpNetworkTransactionTest,
[email protected]44b52042010-10-29 22:48:041047 ComplexContentLengthHeadersNoTransferEncoding) {
1048 // More than 2 dupes.
1049 {
1050 MockRead data_reads[] = {
1051 MockRead("HTTP/1.1 200 OK\r\n"),
1052 MockRead("Content-Length: 5\r\n"),
1053 MockRead("Content-Length: 5\r\n"),
1054 MockRead("Content-Length: 5\r\n\r\n"),
1055 MockRead("Hello"),
1056 };
1057 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
1058 arraysize(data_reads));
robpercival214763f2016-07-01 23:27:011059 EXPECT_THAT(out.rv, IsOk());
[email protected]44b52042010-10-29 22:48:041060 EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
1061 EXPECT_EQ("Hello", out.response_data);
1062 }
1063 // HTTP/1.0
1064 {
1065 MockRead data_reads[] = {
1066 MockRead("HTTP/1.0 200 OK\r\n"),
1067 MockRead("Content-Length: 5\r\n"),
1068 MockRead("Content-Length: 5\r\n"),
1069 MockRead("Content-Length: 5\r\n\r\n"),
1070 MockRead("Hello"),
1071 };
1072 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
1073 arraysize(data_reads));
robpercival214763f2016-07-01 23:27:011074 EXPECT_THAT(out.rv, IsOk());
[email protected]44b52042010-10-29 22:48:041075 EXPECT_EQ("HTTP/1.0 200 OK", out.status_line);
1076 EXPECT_EQ("Hello", out.response_data);
1077 }
1078 // 2 dupes and one mismatched.
1079 {
1080 MockRead data_reads[] = {
1081 MockRead("HTTP/1.1 200 OK\r\n"),
1082 MockRead("Content-Length: 10\r\n"),
1083 MockRead("Content-Length: 10\r\n"),
1084 MockRead("Content-Length: 5\r\n\r\n"),
1085 };
1086 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
1087 arraysize(data_reads));
robpercival214763f2016-07-01 23:27:011088 EXPECT_THAT(out.rv, IsError(ERR_RESPONSE_HEADERS_MULTIPLE_CONTENT_LENGTH));
[email protected]44b52042010-10-29 22:48:041089 }
1090}
1091
bncd16676a2016-07-20 16:23:011092TEST_F(HttpNetworkTransactionTest,
[email protected]9fe44f52010-09-23 18:36:001093 MultipleContentLengthHeadersTransferEncoding) {
1094 MockRead data_reads[] = {
1095 MockRead("HTTP/1.1 200 OK\r\n"),
1096 MockRead("Content-Length: 666\r\n"),
1097 MockRead("Content-Length: 1337\r\n"),
1098 MockRead("Transfer-Encoding: chunked\r\n\r\n"),
1099 MockRead("5\r\nHello\r\n"),
1100 MockRead("1\r\n"),
1101 MockRead(" \r\n"),
1102 MockRead("5\r\nworld\r\n"),
1103 MockRead("0\r\n\r\nHTTP/1.1 200 OK\r\n"),
[email protected]8ddf8322012-02-23 18:08:061104 MockRead(SYNCHRONOUS, OK),
[email protected]9fe44f52010-09-23 18:36:001105 };
1106 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
1107 arraysize(data_reads));
robpercival214763f2016-07-01 23:27:011108 EXPECT_THAT(out.rv, IsOk());
[email protected]9fe44f52010-09-23 18:36:001109 EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
1110 EXPECT_EQ("Hello world", out.response_data);
1111}
1112
[email protected]1628fe92011-10-04 23:04:551113// Next tests deal with http://crbug.com/98895.
1114
1115// Checks that a single Content-Disposition header results in no error.
bncd16676a2016-07-20 16:23:011116TEST_F(HttpNetworkTransactionTest, SingleContentDispositionHeader) {
[email protected]1628fe92011-10-04 23:04:551117 MockRead data_reads[] = {
1118 MockRead("HTTP/1.1 200 OK\r\n"),
1119 MockRead("Content-Disposition: attachment;filename=\"salutations.txt\"r\n"),
1120 MockRead("Content-Length: 5\r\n\r\n"),
1121 MockRead("Hello"),
1122 };
1123 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
1124 arraysize(data_reads));
robpercival214763f2016-07-01 23:27:011125 EXPECT_THAT(out.rv, IsOk());
[email protected]1628fe92011-10-04 23:04:551126 EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
1127 EXPECT_EQ("Hello", out.response_data);
1128}
1129
[email protected]54a9c6e52012-03-21 20:10:591130// Checks that two identical Content-Disposition headers result in no error.
bncd16676a2016-07-20 16:23:011131TEST_F(HttpNetworkTransactionTest, TwoIdenticalContentDispositionHeaders) {
[email protected]1628fe92011-10-04 23:04:551132 MockRead data_reads[] = {
1133 MockRead("HTTP/1.1 200 OK\r\n"),
1134 MockRead("Content-Disposition: attachment;filename=\"greetings.txt\"r\n"),
1135 MockRead("Content-Disposition: attachment;filename=\"greetings.txt\"r\n"),
1136 MockRead("Content-Length: 5\r\n\r\n"),
1137 MockRead("Hello"),
1138 };
1139 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
1140 arraysize(data_reads));
robpercival214763f2016-07-01 23:27:011141 EXPECT_THAT(out.rv, IsOk());
[email protected]54a9c6e52012-03-21 20:10:591142 EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
1143 EXPECT_EQ("Hello", out.response_data);
[email protected]1628fe92011-10-04 23:04:551144}
1145
1146// Checks that two distinct Content-Disposition headers result in an error.
bncd16676a2016-07-20 16:23:011147TEST_F(HttpNetworkTransactionTest, TwoDistinctContentDispositionHeaders) {
[email protected]1628fe92011-10-04 23:04:551148 MockRead data_reads[] = {
1149 MockRead("HTTP/1.1 200 OK\r\n"),
1150 MockRead("Content-Disposition: attachment;filename=\"greetings.txt\"r\n"),
1151 MockRead("Content-Disposition: attachment;filename=\"hi.txt\"r\n"),
1152 MockRead("Content-Length: 5\r\n\r\n"),
1153 MockRead("Hello"),
1154 };
1155 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
1156 arraysize(data_reads));
robpercival214763f2016-07-01 23:27:011157 EXPECT_THAT(out.rv,
1158 IsError(ERR_RESPONSE_HEADERS_MULTIPLE_CONTENT_DISPOSITION));
[email protected]1628fe92011-10-04 23:04:551159}
1160
[email protected]54a9c6e52012-03-21 20:10:591161// Checks that two identical Location headers result in no error.
1162// Also tests Location header behavior.
bncd16676a2016-07-20 16:23:011163TEST_F(HttpNetworkTransactionTest, TwoIdenticalLocationHeaders) {
[email protected]1628fe92011-10-04 23:04:551164 MockRead data_reads[] = {
1165 MockRead("HTTP/1.1 302 Redirect\r\n"),
1166 MockRead("Location: http://good.com/\r\n"),
[email protected]54a9c6e52012-03-21 20:10:591167 MockRead("Location: http://good.com/\r\n"),
[email protected]1628fe92011-10-04 23:04:551168 MockRead("Content-Length: 0\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:061169 MockRead(SYNCHRONOUS, OK),
[email protected]1628fe92011-10-04 23:04:551170 };
1171
1172 HttpRequestInfo request;
1173 request.method = "GET";
1174 request.url = GURL("http://redirect.com/");
[email protected]1628fe92011-10-04 23:04:551175
danakj1fd259a02016-04-16 03:17:091176 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:161177 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]1628fe92011-10-04 23:04:551178
1179 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:071180 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1628fe92011-10-04 23:04:551181
[email protected]49639fa2011-12-20 23:22:411182 TestCompletionCallback callback;
[email protected]1628fe92011-10-04 23:04:551183
tfarina42834112016-09-22 13:38:201184 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:011185 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]1628fe92011-10-04 23:04:551186
robpercival214763f2016-07-01 23:27:011187 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]1628fe92011-10-04 23:04:551188
bnc691fda62016-08-12 00:43:161189 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:521190 ASSERT_TRUE(response);
1191 ASSERT_TRUE(response->headers);
[email protected]1628fe92011-10-04 23:04:551192 EXPECT_EQ("HTTP/1.1 302 Redirect", response->headers->GetStatusLine());
1193 std::string url;
1194 EXPECT_TRUE(response->headers->IsRedirect(&url));
1195 EXPECT_EQ("http://good.com/", url);
tbansal2ecbbc72016-10-06 17:15:471196 EXPECT_TRUE(response->proxy_server.is_direct());
[email protected]1628fe92011-10-04 23:04:551197}
1198
[email protected]1628fe92011-10-04 23:04:551199// Checks that two distinct Location headers result in an error.
bncd16676a2016-07-20 16:23:011200TEST_F(HttpNetworkTransactionTest, TwoDistinctLocationHeaders) {
[email protected]1628fe92011-10-04 23:04:551201 MockRead data_reads[] = {
1202 MockRead("HTTP/1.1 302 Redirect\r\n"),
1203 MockRead("Location: http://good.com/\r\n"),
1204 MockRead("Location: http://evil.com/\r\n"),
1205 MockRead("Content-Length: 0\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:061206 MockRead(SYNCHRONOUS, OK),
[email protected]1628fe92011-10-04 23:04:551207 };
1208 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
1209 arraysize(data_reads));
robpercival214763f2016-07-01 23:27:011210 EXPECT_THAT(out.rv, IsError(ERR_RESPONSE_HEADERS_MULTIPLE_LOCATION));
[email protected]1628fe92011-10-04 23:04:551211}
1212
[email protected]ef0faf2e72009-03-05 23:27:231213// Do a request using the HEAD method. Verify that we don't try to read the
1214// message body (since HEAD has none).
bncd16676a2016-07-20 16:23:011215TEST_F(HttpNetworkTransactionTest, Head) {
[email protected]1c773ea12009-04-28 19:58:421216 HttpRequestInfo request;
[email protected]ef0faf2e72009-03-05 23:27:231217 request.method = "HEAD";
bncce36dca22015-04-21 22:11:231218 request.url = GURL("http://www.example.org/");
[email protected]ef0faf2e72009-03-05 23:27:231219
danakj1fd259a02016-04-16 03:17:091220 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:161221 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
ryansturm49a8cb12016-06-15 16:51:091222 BeforeHeadersSentHandler headers_handler;
bnc691fda62016-08-12 00:43:161223 trans.SetBeforeHeadersSentCallback(
ryansturm49a8cb12016-06-15 16:51:091224 base::Bind(&BeforeHeadersSentHandler::OnBeforeHeadersSent,
1225 base::Unretained(&headers_handler)));
[email protected]cb9bf6ca2011-01-28 13:15:271226
[email protected]ef0faf2e72009-03-05 23:27:231227 MockWrite data_writes1[] = {
csharrisonf473dd192015-08-18 13:54:131228 MockWrite("HEAD / HTTP/1.1\r\n"
1229 "Host: www.example.org\r\n"
1230 "Connection: keep-alive\r\n\r\n"),
[email protected]ef0faf2e72009-03-05 23:27:231231 };
1232 MockRead data_reads1[] = {
mmenked39192ee2015-12-09 00:57:231233 MockRead("HTTP/1.1 404 Not Found\r\n"), MockRead("Server: Blah\r\n"),
1234 MockRead("Content-Length: 1234\r\n\r\n"),
[email protected]ef0faf2e72009-03-05 23:27:231235
mmenked39192ee2015-12-09 00:57:231236 // No response body because the test stops reading here.
1237 MockRead(SYNCHRONOUS, ERR_UNEXPECTED),
[email protected]ef0faf2e72009-03-05 23:27:231238 };
1239
[email protected]31a2bfe2010-02-09 08:03:391240 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
1241 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:071242 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]ef0faf2e72009-03-05 23:27:231243
[email protected]49639fa2011-12-20 23:22:411244 TestCompletionCallback callback1;
[email protected]ef0faf2e72009-03-05 23:27:231245
tfarina42834112016-09-22 13:38:201246 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:011247 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]ef0faf2e72009-03-05 23:27:231248
1249 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:011250 EXPECT_THAT(rv, IsOk());
[email protected]ef0faf2e72009-03-05 23:27:231251
bnc691fda62016-08-12 00:43:161252 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:521253 ASSERT_TRUE(response);
[email protected]ef0faf2e72009-03-05 23:27:231254
1255 // Check that the headers got parsed.
wezca1070932016-05-26 20:30:521256 EXPECT_TRUE(response->headers);
[email protected]ef0faf2e72009-03-05 23:27:231257 EXPECT_EQ(1234, response->headers->GetContentLength());
1258 EXPECT_EQ("HTTP/1.1 404 Not Found", response->headers->GetStatusLine());
tbansal2ecbbc72016-10-06 17:15:471259 EXPECT_TRUE(response->proxy_server.is_direct());
ryansturm49a8cb12016-06-15 16:51:091260 EXPECT_TRUE(headers_handler.observed_before_headers_sent());
1261 EXPECT_FALSE(headers_handler.observed_before_headers_sent_with_proxy());
[email protected]ef0faf2e72009-03-05 23:27:231262
1263 std::string server_header;
olli.raulaee489a52016-01-25 08:37:101264 size_t iter = 0;
[email protected]ef0faf2e72009-03-05 23:27:231265 bool has_server_header = response->headers->EnumerateHeader(
1266 &iter, "Server", &server_header);
1267 EXPECT_TRUE(has_server_header);
1268 EXPECT_EQ("Blah", server_header);
1269
1270 // Reading should give EOF right away, since there is no message body
1271 // (despite non-zero content-length).
1272 std::string response_data;
bnc691fda62016-08-12 00:43:161273 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:011274 EXPECT_THAT(rv, IsOk());
[email protected]ef0faf2e72009-03-05 23:27:231275 EXPECT_EQ("", response_data);
1276}
1277
bncd16676a2016-07-20 16:23:011278TEST_F(HttpNetworkTransactionTest, ReuseConnection) {
danakj1fd259a02016-04-16 03:17:091279 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
initial.commit586acc5fe2008-07-26 22:42:521280
1281 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:351282 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
1283 MockRead("hello"),
1284 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
1285 MockRead("world"),
[email protected]8ddf8322012-02-23 18:08:061286 MockRead(SYNCHRONOUS, OK),
initial.commit586acc5fe2008-07-26 22:42:521287 };
[email protected]31a2bfe2010-02-09 08:03:391288 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:071289 session_deps_.socket_factory->AddSocketDataProvider(&data);
initial.commit586acc5fe2008-07-26 22:42:521290
[email protected]0b0bf032010-09-21 18:08:501291 const char* const kExpectedResponseData[] = {
initial.commit586acc5fe2008-07-26 22:42:521292 "hello", "world"
1293 };
1294
1295 for (int i = 0; i < 2; ++i) {
[email protected]1c773ea12009-04-28 19:58:421296 HttpRequestInfo request;
initial.commit586acc5fe2008-07-26 22:42:521297 request.method = "GET";
bncce36dca22015-04-21 22:11:231298 request.url = GURL("http://www.example.org/");
initial.commit586acc5fe2008-07-26 22:42:521299
bnc691fda62016-08-12 00:43:161300 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:271301
[email protected]49639fa2011-12-20 23:22:411302 TestCompletionCallback callback;
initial.commit586acc5fe2008-07-26 22:42:521303
tfarina42834112016-09-22 13:38:201304 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:011305 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
initial.commit586acc5fe2008-07-26 22:42:521306
1307 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:011308 EXPECT_THAT(rv, IsOk());
initial.commit586acc5fe2008-07-26 22:42:521309
bnc691fda62016-08-12 00:43:161310 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:521311 ASSERT_TRUE(response);
initial.commit586acc5fe2008-07-26 22:42:521312
wezca1070932016-05-26 20:30:521313 EXPECT_TRUE(response->headers);
[email protected]3d2a59b2008-09-26 19:44:251314 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
tbansal2ecbbc72016-10-06 17:15:471315 EXPECT_TRUE(response->proxy_server.is_direct());
initial.commit586acc5fe2008-07-26 22:42:521316
1317 std::string response_data;
bnc691fda62016-08-12 00:43:161318 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:011319 EXPECT_THAT(rv, IsOk());
[email protected]3d2a59b2008-09-26 19:44:251320 EXPECT_EQ(kExpectedResponseData[i], response_data);
initial.commit586acc5fe2008-07-26 22:42:521321 }
1322}
1323
bncd16676a2016-07-20 16:23:011324TEST_F(HttpNetworkTransactionTest, Ignores100) {
danakj1fd259a02016-04-16 03:17:091325 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:221326 element_readers.push_back(
ricea2deef682016-09-09 08:04:071327 base::MakeUnique<UploadBytesElementReader>("foo", 3));
olli.raula6df48b2a2015-11-26 07:40:221328 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]329b68b2012-11-14 17:54:271329
[email protected]1c773ea12009-04-28 19:58:421330 HttpRequestInfo request;
initial.commit586acc5fe2008-07-26 22:42:521331 request.method = "POST";
1332 request.url = GURL("http://www.foo.com/");
[email protected]329b68b2012-11-14 17:54:271333 request.upload_data_stream = &upload_data_stream;
initial.commit586acc5fe2008-07-26 22:42:521334
shivanishab9a143952016-09-19 17:23:411335 // Check the upload progress returned before initialization is correct.
1336 UploadProgress progress = request.upload_data_stream->GetUploadProgress();
1337 EXPECT_EQ(0u, progress.size());
1338 EXPECT_EQ(0u, progress.position());
1339
danakj1fd259a02016-04-16 03:17:091340 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:161341 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:271342
initial.commit586acc5fe2008-07-26 22:42:521343 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:351344 MockRead("HTTP/1.0 100 Continue\r\n\r\n"),
1345 MockRead("HTTP/1.0 200 OK\r\n\r\n"),
1346 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:061347 MockRead(SYNCHRONOUS, OK),
initial.commit586acc5fe2008-07-26 22:42:521348 };
[email protected]31a2bfe2010-02-09 08:03:391349 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:071350 session_deps_.socket_factory->AddSocketDataProvider(&data);
initial.commit586acc5fe2008-07-26 22:42:521351
[email protected]49639fa2011-12-20 23:22:411352 TestCompletionCallback callback;
initial.commit586acc5fe2008-07-26 22:42:521353
tfarina42834112016-09-22 13:38:201354 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:011355 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
initial.commit586acc5fe2008-07-26 22:42:521356
1357 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:011358 EXPECT_THAT(rv, IsOk());
initial.commit586acc5fe2008-07-26 22:42:521359
bnc691fda62016-08-12 00:43:161360 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:521361 ASSERT_TRUE(response);
initial.commit586acc5fe2008-07-26 22:42:521362
wezca1070932016-05-26 20:30:521363 EXPECT_TRUE(response->headers);
[email protected]3d2a59b2008-09-26 19:44:251364 EXPECT_EQ("HTTP/1.0 200 OK", response->headers->GetStatusLine());
initial.commit586acc5fe2008-07-26 22:42:521365
1366 std::string response_data;
bnc691fda62016-08-12 00:43:161367 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:011368 EXPECT_THAT(rv, IsOk());
[email protected]3d2a59b2008-09-26 19:44:251369 EXPECT_EQ("hello world", response_data);
initial.commit586acc5fe2008-07-26 22:42:521370}
1371
[email protected]3a2d3662009-03-27 03:49:141372// This test is almost the same as Ignores100 above, but the response contains
1373// a 102 instead of a 100. Also, instead of HTTP/1.0 the response is
[email protected]0877e3d2009-10-17 22:29:571374// HTTP/1.1 and the two status headers are read in one read.
bncd16676a2016-07-20 16:23:011375TEST_F(HttpNetworkTransactionTest, Ignores1xx) {
[email protected]1c773ea12009-04-28 19:58:421376 HttpRequestInfo request;
[email protected]3a2d3662009-03-27 03:49:141377 request.method = "GET";
1378 request.url = GURL("http://www.foo.com/");
[email protected]3a2d3662009-03-27 03:49:141379
danakj1fd259a02016-04-16 03:17:091380 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:161381 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:271382
[email protected]3a2d3662009-03-27 03:49:141383 MockRead data_reads[] = {
[email protected]0877e3d2009-10-17 22:29:571384 MockRead("HTTP/1.1 102 Unspecified status code\r\n\r\n"
1385 "HTTP/1.1 200 OK\r\n\r\n"),
[email protected]3a2d3662009-03-27 03:49:141386 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:061387 MockRead(SYNCHRONOUS, OK),
[email protected]3a2d3662009-03-27 03:49:141388 };
[email protected]31a2bfe2010-02-09 08:03:391389 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:071390 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]3a2d3662009-03-27 03:49:141391
[email protected]49639fa2011-12-20 23:22:411392 TestCompletionCallback callback;
[email protected]3a2d3662009-03-27 03:49:141393
tfarina42834112016-09-22 13:38:201394 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:011395 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]3a2d3662009-03-27 03:49:141396
1397 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:011398 EXPECT_THAT(rv, IsOk());
[email protected]3a2d3662009-03-27 03:49:141399
bnc691fda62016-08-12 00:43:161400 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:521401 ASSERT_TRUE(response);
[email protected]3a2d3662009-03-27 03:49:141402
wezca1070932016-05-26 20:30:521403 EXPECT_TRUE(response->headers);
[email protected]3a2d3662009-03-27 03:49:141404 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
1405
1406 std::string response_data;
bnc691fda62016-08-12 00:43:161407 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:011408 EXPECT_THAT(rv, IsOk());
[email protected]3a2d3662009-03-27 03:49:141409 EXPECT_EQ("hello world", response_data);
1410}
1411
bncd16676a2016-07-20 16:23:011412TEST_F(HttpNetworkTransactionTest, Incomplete100ThenEOF) {
zmo9528c9f42015-08-04 22:12:081413 HttpRequestInfo request;
1414 request.method = "POST";
1415 request.url = GURL("http://www.foo.com/");
zmo9528c9f42015-08-04 22:12:081416
danakj1fd259a02016-04-16 03:17:091417 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:161418 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
zmo9528c9f42015-08-04 22:12:081419
1420 MockRead data_reads[] = {
1421 MockRead(SYNCHRONOUS, "HTTP/1.0 100 Continue\r\n"),
1422 MockRead(ASYNC, 0),
[email protected]ee9410e72010-01-07 01:42:381423 };
zmo9528c9f42015-08-04 22:12:081424 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
1425 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]ee9410e72010-01-07 01:42:381426
zmo9528c9f42015-08-04 22:12:081427 TestCompletionCallback callback;
[email protected]ee9410e72010-01-07 01:42:381428
tfarina42834112016-09-22 13:38:201429 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:011430 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]ee9410e72010-01-07 01:42:381431
zmo9528c9f42015-08-04 22:12:081432 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:011433 EXPECT_THAT(rv, IsOk());
[email protected]ee9410e72010-01-07 01:42:381434
zmo9528c9f42015-08-04 22:12:081435 std::string response_data;
bnc691fda62016-08-12 00:43:161436 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:011437 EXPECT_THAT(rv, IsOk());
zmo9528c9f42015-08-04 22:12:081438 EXPECT_EQ("", response_data);
[email protected]ee9410e72010-01-07 01:42:381439}
1440
bncd16676a2016-07-20 16:23:011441TEST_F(HttpNetworkTransactionTest, EmptyResponse) {
[email protected]ee9410e72010-01-07 01:42:381442 HttpRequestInfo request;
1443 request.method = "POST";
1444 request.url = GURL("http://www.foo.com/");
[email protected]ee9410e72010-01-07 01:42:381445
danakj1fd259a02016-04-16 03:17:091446 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:161447 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:271448
[email protected]ee9410e72010-01-07 01:42:381449 MockRead data_reads[] = {
[email protected]8ddf8322012-02-23 18:08:061450 MockRead(ASYNC, 0),
[email protected]ee9410e72010-01-07 01:42:381451 };
[email protected]31a2bfe2010-02-09 08:03:391452 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:071453 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]ee9410e72010-01-07 01:42:381454
[email protected]49639fa2011-12-20 23:22:411455 TestCompletionCallback callback;
[email protected]ee9410e72010-01-07 01:42:381456
tfarina42834112016-09-22 13:38:201457 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:011458 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]ee9410e72010-01-07 01:42:381459
1460 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:011461 EXPECT_THAT(rv, IsError(ERR_EMPTY_RESPONSE));
[email protected]ee9410e72010-01-07 01:42:381462}
1463
[email protected]23e482282013-06-14 16:08:021464void HttpNetworkTransactionTest::KeepAliveConnectionResendRequestTest(
[email protected]202965992011-12-07 23:04:511465 const MockWrite* write_failure,
1466 const MockRead* read_failure) {
[email protected]1c773ea12009-04-28 19:58:421467 HttpRequestInfo request;
initial.commit586acc5fe2008-07-26 22:42:521468 request.method = "GET";
1469 request.url = GURL("http://www.foo.com/");
initial.commit586acc5fe2008-07-26 22:42:521470
vishal.b62985ca92015-04-17 08:45:511471 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:071472 session_deps_.net_log = &net_log;
danakj1fd259a02016-04-16 03:17:091473 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:271474
[email protected]202965992011-12-07 23:04:511475 // Written data for successfully sending both requests.
1476 MockWrite data1_writes[] = {
1477 MockWrite("GET / HTTP/1.1\r\n"
1478 "Host: www.foo.com\r\n"
1479 "Connection: keep-alive\r\n\r\n"),
1480 MockWrite("GET / HTTP/1.1\r\n"
1481 "Host: www.foo.com\r\n"
1482 "Connection: keep-alive\r\n\r\n")
1483 };
1484
1485 // Read results for the first request.
initial.commit586acc5fe2008-07-26 22:42:521486 MockRead data1_reads[] = {
[email protected]217e6022008-09-29 18:18:351487 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
1488 MockRead("hello"),
[email protected]8ddf8322012-02-23 18:08:061489 MockRead(ASYNC, OK),
initial.commit586acc5fe2008-07-26 22:42:521490 };
[email protected]202965992011-12-07 23:04:511491
1492 if (write_failure) {
[email protected]a34f61ee2014-03-18 20:59:491493 ASSERT_FALSE(read_failure);
[email protected]202965992011-12-07 23:04:511494 data1_writes[1] = *write_failure;
1495 } else {
1496 ASSERT_TRUE(read_failure);
1497 data1_reads[2] = *read_failure;
1498 }
1499
1500 StaticSocketDataProvider data1(data1_reads, arraysize(data1_reads),
1501 data1_writes, arraysize(data1_writes));
[email protected]bb88e1d32013-05-03 23:11:071502 session_deps_.socket_factory->AddSocketDataProvider(&data1);
initial.commit586acc5fe2008-07-26 22:42:521503
1504 MockRead data2_reads[] = {
[email protected]217e6022008-09-29 18:18:351505 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
1506 MockRead("world"),
[email protected]8ddf8322012-02-23 18:08:061507 MockRead(ASYNC, OK),
initial.commit586acc5fe2008-07-26 22:42:521508 };
[email protected]31a2bfe2010-02-09 08:03:391509 StaticSocketDataProvider data2(data2_reads, arraysize(data2_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:071510 session_deps_.socket_factory->AddSocketDataProvider(&data2);
initial.commit586acc5fe2008-07-26 22:42:521511
thestig9d3bb0c2015-01-24 00:49:511512 const char* const kExpectedResponseData[] = {
initial.commit586acc5fe2008-07-26 22:42:521513 "hello", "world"
1514 };
1515
mikecironef22f9812016-10-04 03:40:191516 uint32_t first_socket_log_id = NetLogSource::kInvalidId;
initial.commit586acc5fe2008-07-26 22:42:521517 for (int i = 0; i < 2; ++i) {
[email protected]49639fa2011-12-20 23:22:411518 TestCompletionCallback callback;
initial.commit586acc5fe2008-07-26 22:42:521519
bnc691fda62016-08-12 00:43:161520 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
initial.commit586acc5fe2008-07-26 22:42:521521
tfarina42834112016-09-22 13:38:201522 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:011523 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
initial.commit586acc5fe2008-07-26 22:42:521524
1525 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:011526 EXPECT_THAT(rv, IsOk());
initial.commit586acc5fe2008-07-26 22:42:521527
[email protected]58e32bb2013-01-21 18:23:251528 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:161529 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]58e32bb2013-01-21 18:23:251530 TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_DNS_TIMES);
1531 if (i == 0) {
1532 first_socket_log_id = load_timing_info.socket_log_id;
1533 } else {
1534 // The second request should be using a new socket.
1535 EXPECT_NE(first_socket_log_id, load_timing_info.socket_log_id);
1536 }
1537
bnc691fda62016-08-12 00:43:161538 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:521539 ASSERT_TRUE(response);
initial.commit586acc5fe2008-07-26 22:42:521540
wezca1070932016-05-26 20:30:521541 EXPECT_TRUE(response->headers);
tbansal2ecbbc72016-10-06 17:15:471542 EXPECT_TRUE(response->proxy_server.is_direct());
[email protected]3d2a59b2008-09-26 19:44:251543 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
initial.commit586acc5fe2008-07-26 22:42:521544
1545 std::string response_data;
bnc691fda62016-08-12 00:43:161546 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:011547 EXPECT_THAT(rv, IsOk());
[email protected]3d2a59b2008-09-26 19:44:251548 EXPECT_EQ(kExpectedResponseData[i], response_data);
initial.commit586acc5fe2008-07-26 22:42:521549 }
1550}
[email protected]3d2a59b2008-09-26 19:44:251551
[email protected]a34f61ee2014-03-18 20:59:491552void HttpNetworkTransactionTest::PreconnectErrorResendRequestTest(
1553 const MockWrite* write_failure,
[email protected]09356c652014-03-25 15:36:101554 const MockRead* read_failure,
1555 bool use_spdy) {
[email protected]a34f61ee2014-03-18 20:59:491556 HttpRequestInfo request;
1557 request.method = "GET";
[email protected]09356c652014-03-25 15:36:101558 request.url = GURL("https://www.foo.com/");
[email protected]a34f61ee2014-03-18 20:59:491559
vishal.b62985ca92015-04-17 08:45:511560 TestNetLog net_log;
[email protected]a34f61ee2014-03-18 20:59:491561 session_deps_.net_log = &net_log;
danakj1fd259a02016-04-16 03:17:091562 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]a34f61ee2014-03-18 20:59:491563
[email protected]09356c652014-03-25 15:36:101564 SSLSocketDataProvider ssl1(ASYNC, OK);
1565 SSLSocketDataProvider ssl2(ASYNC, OK);
1566 if (use_spdy) {
bnc3cf2a592016-08-11 14:48:361567 ssl1.next_proto = kProtoHTTP2;
1568 ssl2.next_proto = kProtoHTTP2;
[email protected]09356c652014-03-25 15:36:101569 }
1570 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl1);
1571 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
[email protected]a34f61ee2014-03-18 20:59:491572
[email protected]09356c652014-03-25 15:36:101573 // SPDY versions of the request and response.
bncdf80d44fd2016-07-15 20:27:411574 SpdySerializedFrame spdy_request(spdy_util_.ConstructSpdyGet(
bnc38dcd392016-02-09 23:19:491575 request.url.spec().c_str(), 1, DEFAULT_PRIORITY));
bncdf80d44fd2016-07-15 20:27:411576 SpdySerializedFrame spdy_response(
bnc42331402016-07-25 13:36:151577 spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
bncdf80d44fd2016-07-15 20:27:411578 SpdySerializedFrame spdy_data(
1579 spdy_util_.ConstructSpdyDataFrame(1, "hello", 5, true));
[email protected]a34f61ee2014-03-18 20:59:491580
[email protected]09356c652014-03-25 15:36:101581 // HTTP/1.1 versions of the request and response.
1582 const char kHttpRequest[] = "GET / HTTP/1.1\r\n"
1583 "Host: www.foo.com\r\n"
1584 "Connection: keep-alive\r\n\r\n";
1585 const char kHttpResponse[] = "HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n";
1586 const char kHttpData[] = "hello";
1587
1588 std::vector<MockRead> data1_reads;
1589 std::vector<MockWrite> data1_writes;
[email protected]a34f61ee2014-03-18 20:59:491590 if (write_failure) {
1591 ASSERT_FALSE(read_failure);
[email protected]09356c652014-03-25 15:36:101592 data1_writes.push_back(*write_failure);
1593 data1_reads.push_back(MockRead(ASYNC, OK));
[email protected]a34f61ee2014-03-18 20:59:491594 } else {
1595 ASSERT_TRUE(read_failure);
[email protected]09356c652014-03-25 15:36:101596 if (use_spdy) {
bncdf80d44fd2016-07-15 20:27:411597 data1_writes.push_back(CreateMockWrite(spdy_request));
[email protected]09356c652014-03-25 15:36:101598 } else {
1599 data1_writes.push_back(MockWrite(kHttpRequest));
1600 }
1601 data1_reads.push_back(*read_failure);
[email protected]a34f61ee2014-03-18 20:59:491602 }
1603
[email protected]09356c652014-03-25 15:36:101604 StaticSocketDataProvider data1(&data1_reads[0], data1_reads.size(),
1605 &data1_writes[0], data1_writes.size());
[email protected]a34f61ee2014-03-18 20:59:491606 session_deps_.socket_factory->AddSocketDataProvider(&data1);
1607
[email protected]09356c652014-03-25 15:36:101608 std::vector<MockRead> data2_reads;
1609 std::vector<MockWrite> data2_writes;
1610
1611 if (use_spdy) {
bncdf80d44fd2016-07-15 20:27:411612 data2_writes.push_back(CreateMockWrite(spdy_request, 0, ASYNC));
[email protected]09356c652014-03-25 15:36:101613
bncdf80d44fd2016-07-15 20:27:411614 data2_reads.push_back(CreateMockRead(spdy_response, 1, ASYNC));
1615 data2_reads.push_back(CreateMockRead(spdy_data, 2, ASYNC));
[email protected]09356c652014-03-25 15:36:101616 data2_reads.push_back(MockRead(ASYNC, OK, 3));
1617 } else {
1618 data2_writes.push_back(
1619 MockWrite(ASYNC, kHttpRequest, strlen(kHttpRequest), 0));
1620
1621 data2_reads.push_back(
1622 MockRead(ASYNC, kHttpResponse, strlen(kHttpResponse), 1));
1623 data2_reads.push_back(MockRead(ASYNC, kHttpData, strlen(kHttpData), 2));
1624 data2_reads.push_back(MockRead(ASYNC, OK, 3));
1625 }
rch8e6c6c42015-05-01 14:05:131626 SequencedSocketData data2(&data2_reads[0], data2_reads.size(),
1627 &data2_writes[0], data2_writes.size());
[email protected]a34f61ee2014-03-18 20:59:491628 session_deps_.socket_factory->AddSocketDataProvider(&data2);
1629
1630 // Preconnect a socket.
nharper8cdb0fb2016-04-22 21:34:591631 session->http_stream_factory()->PreconnectStreams(1, request);
[email protected]a34f61ee2014-03-18 20:59:491632 // Wait for the preconnect to complete.
1633 // TODO(davidben): Some way to wait for an idle socket count might be handy.
1634 base::RunLoop().RunUntilIdle();
[email protected]09356c652014-03-25 15:36:101635 EXPECT_EQ(1, GetIdleSocketCountInSSLSocketPool(session.get()));
[email protected]a34f61ee2014-03-18 20:59:491636
1637 // Make the request.
1638 TestCompletionCallback callback;
1639
bnc691fda62016-08-12 00:43:161640 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]a34f61ee2014-03-18 20:59:491641
tfarina42834112016-09-22 13:38:201642 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:011643 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]a34f61ee2014-03-18 20:59:491644
1645 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:011646 EXPECT_THAT(rv, IsOk());
[email protected]a34f61ee2014-03-18 20:59:491647
1648 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:161649 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]09356c652014-03-25 15:36:101650 TestLoadTimingNotReused(
1651 load_timing_info,
1652 CONNECT_TIMING_HAS_DNS_TIMES|CONNECT_TIMING_HAS_SSL_TIMES);
[email protected]a34f61ee2014-03-18 20:59:491653
bnc691fda62016-08-12 00:43:161654 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:521655 ASSERT_TRUE(response);
[email protected]a34f61ee2014-03-18 20:59:491656
wezca1070932016-05-26 20:30:521657 EXPECT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:021658 if (response->was_fetched_via_spdy) {
1659 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
1660 } else {
1661 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
1662 }
[email protected]a34f61ee2014-03-18 20:59:491663
1664 std::string response_data;
bnc691fda62016-08-12 00:43:161665 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:011666 EXPECT_THAT(rv, IsOk());
[email protected]09356c652014-03-25 15:36:101667 EXPECT_EQ(kHttpData, response_data);
[email protected]a34f61ee2014-03-18 20:59:491668}
1669
bncd16676a2016-07-20 16:23:011670TEST_F(HttpNetworkTransactionTest, KeepAliveConnectionNotConnectedOnWrite) {
[email protected]8ddf8322012-02-23 18:08:061671 MockWrite write_failure(ASYNC, ERR_SOCKET_NOT_CONNECTED);
[email protected]202965992011-12-07 23:04:511672 KeepAliveConnectionResendRequestTest(&write_failure, NULL);
1673}
1674
bncd16676a2016-07-20 16:23:011675TEST_F(HttpNetworkTransactionTest, KeepAliveConnectionReset) {
[email protected]8ddf8322012-02-23 18:08:061676 MockRead read_failure(ASYNC, ERR_CONNECTION_RESET);
[email protected]202965992011-12-07 23:04:511677 KeepAliveConnectionResendRequestTest(NULL, &read_failure);
[email protected]3d2a59b2008-09-26 19:44:251678}
1679
bncd16676a2016-07-20 16:23:011680TEST_F(HttpNetworkTransactionTest, KeepAliveConnectionEOF) {
[email protected]8ddf8322012-02-23 18:08:061681 MockRead read_failure(SYNCHRONOUS, OK); // EOF
[email protected]202965992011-12-07 23:04:511682 KeepAliveConnectionResendRequestTest(NULL, &read_failure);
[email protected]3d2a59b2008-09-26 19:44:251683}
1684
[email protected]d58ceea82014-06-04 10:55:541685// Make sure that on a 408 response (Request Timeout), the request is retried,
1686// if the socket was a reused keep alive socket.
bncd16676a2016-07-20 16:23:011687TEST_F(HttpNetworkTransactionTest, KeepAlive408) {
[email protected]d58ceea82014-06-04 10:55:541688 MockRead read_failure(SYNCHRONOUS,
1689 "HTTP/1.1 408 Request Timeout\r\n"
1690 "Connection: Keep-Alive\r\n"
1691 "Content-Length: 6\r\n\r\n"
1692 "Pickle");
1693 KeepAliveConnectionResendRequestTest(NULL, &read_failure);
1694}
1695
bncd16676a2016-07-20 16:23:011696TEST_F(HttpNetworkTransactionTest, PreconnectErrorNotConnectedOnWrite) {
[email protected]a34f61ee2014-03-18 20:59:491697 MockWrite write_failure(ASYNC, ERR_SOCKET_NOT_CONNECTED);
[email protected]09356c652014-03-25 15:36:101698 PreconnectErrorResendRequestTest(&write_failure, NULL, false);
[email protected]a34f61ee2014-03-18 20:59:491699}
1700
bncd16676a2016-07-20 16:23:011701TEST_F(HttpNetworkTransactionTest, PreconnectErrorReset) {
[email protected]a34f61ee2014-03-18 20:59:491702 MockRead read_failure(ASYNC, ERR_CONNECTION_RESET);
[email protected]09356c652014-03-25 15:36:101703 PreconnectErrorResendRequestTest(NULL, &read_failure, false);
[email protected]a34f61ee2014-03-18 20:59:491704}
1705
bncd16676a2016-07-20 16:23:011706TEST_F(HttpNetworkTransactionTest, PreconnectErrorEOF) {
[email protected]a34f61ee2014-03-18 20:59:491707 MockRead read_failure(SYNCHRONOUS, OK); // EOF
[email protected]09356c652014-03-25 15:36:101708 PreconnectErrorResendRequestTest(NULL, &read_failure, false);
1709}
1710
bncd16676a2016-07-20 16:23:011711TEST_F(HttpNetworkTransactionTest, PreconnectErrorAsyncEOF) {
[email protected]09356c652014-03-25 15:36:101712 MockRead read_failure(ASYNC, OK); // EOF
1713 PreconnectErrorResendRequestTest(NULL, &read_failure, false);
1714}
1715
[email protected]d58ceea82014-06-04 10:55:541716// Make sure that on a 408 response (Request Timeout), the request is retried,
1717// if the socket was a preconnected (UNUSED_IDLE) socket.
bncd16676a2016-07-20 16:23:011718TEST_F(HttpNetworkTransactionTest, RetryOnIdle408) {
[email protected]d58ceea82014-06-04 10:55:541719 MockRead read_failure(SYNCHRONOUS,
1720 "HTTP/1.1 408 Request Timeout\r\n"
1721 "Connection: Keep-Alive\r\n"
1722 "Content-Length: 6\r\n\r\n"
1723 "Pickle");
1724 KeepAliveConnectionResendRequestTest(NULL, &read_failure);
1725 PreconnectErrorResendRequestTest(NULL, &read_failure, false);
1726}
1727
bncd16676a2016-07-20 16:23:011728TEST_F(HttpNetworkTransactionTest, SpdyPreconnectErrorNotConnectedOnWrite) {
[email protected]09356c652014-03-25 15:36:101729 MockWrite write_failure(ASYNC, ERR_SOCKET_NOT_CONNECTED);
1730 PreconnectErrorResendRequestTest(&write_failure, NULL, true);
1731}
1732
bncd16676a2016-07-20 16:23:011733TEST_F(HttpNetworkTransactionTest, SpdyPreconnectErrorReset) {
[email protected]09356c652014-03-25 15:36:101734 MockRead read_failure(ASYNC, ERR_CONNECTION_RESET);
1735 PreconnectErrorResendRequestTest(NULL, &read_failure, true);
1736}
1737
bncd16676a2016-07-20 16:23:011738TEST_F(HttpNetworkTransactionTest, SpdyPreconnectErrorEOF) {
[email protected]09356c652014-03-25 15:36:101739 MockRead read_failure(SYNCHRONOUS, OK); // EOF
1740 PreconnectErrorResendRequestTest(NULL, &read_failure, true);
1741}
1742
bncd16676a2016-07-20 16:23:011743TEST_F(HttpNetworkTransactionTest, SpdyPreconnectErrorAsyncEOF) {
[email protected]09356c652014-03-25 15:36:101744 MockRead read_failure(ASYNC, OK); // EOF
1745 PreconnectErrorResendRequestTest(NULL, &read_failure, true);
[email protected]a34f61ee2014-03-18 20:59:491746}
1747
bncd16676a2016-07-20 16:23:011748TEST_F(HttpNetworkTransactionTest, NonKeepAliveConnectionReset) {
[email protected]1c773ea12009-04-28 19:58:421749 HttpRequestInfo request;
[email protected]3d2a59b2008-09-26 19:44:251750 request.method = "GET";
bncce36dca22015-04-21 22:11:231751 request.url = GURL("http://www.example.org/");
[email protected]3d2a59b2008-09-26 19:44:251752
danakj1fd259a02016-04-16 03:17:091753 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:161754 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:271755
[email protected]3d2a59b2008-09-26 19:44:251756 MockRead data_reads[] = {
[email protected]8ddf8322012-02-23 18:08:061757 MockRead(ASYNC, ERR_CONNECTION_RESET),
[email protected]217e6022008-09-29 18:18:351758 MockRead("HTTP/1.0 200 OK\r\n\r\n"), // Should not be used
1759 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:061760 MockRead(SYNCHRONOUS, OK),
[email protected]3d2a59b2008-09-26 19:44:251761 };
[email protected]31a2bfe2010-02-09 08:03:391762 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:071763 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]3d2a59b2008-09-26 19:44:251764
[email protected]49639fa2011-12-20 23:22:411765 TestCompletionCallback callback;
[email protected]3d2a59b2008-09-26 19:44:251766
tfarina42834112016-09-22 13:38:201767 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:011768 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]3d2a59b2008-09-26 19:44:251769
1770 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:011771 EXPECT_THAT(rv, IsError(ERR_CONNECTION_RESET));
ttuttled9dbc652015-09-29 20:00:591772
1773 IPEndPoint endpoint;
bnc691fda62016-08-12 00:43:161774 EXPECT_TRUE(trans.GetRemoteEndpoint(&endpoint));
ttuttled9dbc652015-09-29 20:00:591775 EXPECT_LT(0u, endpoint.address().size());
[email protected]3d2a59b2008-09-26 19:44:251776}
1777
1778// What do various browsers do when the server closes a non-keepalive
1779// connection without sending any response header or body?
1780//
1781// IE7: error page
1782// Safari 3.1.2 (Windows): error page
1783// Firefox 3.0.1: blank page
1784// Opera 9.52: after five attempts, blank page
[email protected]1c773ea12009-04-28 19:58:421785// Us with WinHTTP: error page (ERR_INVALID_RESPONSE)
1786// Us: error page (EMPTY_RESPONSE)
bncd16676a2016-07-20 16:23:011787TEST_F(HttpNetworkTransactionTest, NonKeepAliveConnectionEOF) {
[email protected]3d2a59b2008-09-26 19:44:251788 MockRead data_reads[] = {
[email protected]8ddf8322012-02-23 18:08:061789 MockRead(SYNCHRONOUS, OK), // EOF
[email protected]217e6022008-09-29 18:18:351790 MockRead("HTTP/1.0 200 OK\r\n\r\n"), // Should not be used
1791 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:061792 MockRead(SYNCHRONOUS, OK),
[email protected]3d2a59b2008-09-26 19:44:251793 };
[email protected]31a2bfe2010-02-09 08:03:391794 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
1795 arraysize(data_reads));
robpercival214763f2016-07-01 23:27:011796 EXPECT_THAT(out.rv, IsError(ERR_EMPTY_RESPONSE));
[email protected]3d2a59b2008-09-26 19:44:251797}
[email protected]1826a402014-01-08 15:40:481798
[email protected]7a5378b2012-11-04 03:25:171799// Next 2 cases (KeepAliveEarlyClose and KeepAliveEarlyClose2) are regression
1800// tests. There was a bug causing HttpNetworkTransaction to hang in the
1801// destructor in such situations.
1802// See http://crbug.com/154712 and http://crbug.com/156609.
bncd16676a2016-07-20 16:23:011803TEST_F(HttpNetworkTransactionTest, KeepAliveEarlyClose) {
[email protected]7a5378b2012-11-04 03:25:171804 HttpRequestInfo request;
1805 request.method = "GET";
bncce36dca22015-04-21 22:11:231806 request.url = GURL("http://www.example.org/");
[email protected]7a5378b2012-11-04 03:25:171807
danakj1fd259a02016-04-16 03:17:091808 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:161809 std::unique_ptr<HttpNetworkTransaction> trans(
[email protected]90499482013-06-01 00:39:501810 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]7a5378b2012-11-04 03:25:171811
1812 MockRead data_reads[] = {
1813 MockRead("HTTP/1.0 200 OK\r\n"),
1814 MockRead("Connection: keep-alive\r\n"),
1815 MockRead("Content-Length: 100\r\n\r\n"),
1816 MockRead("hello"),
1817 MockRead(SYNCHRONOUS, 0),
1818 };
1819 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:071820 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]7a5378b2012-11-04 03:25:171821
1822 TestCompletionCallback callback;
1823
tfarina42834112016-09-22 13:38:201824 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:011825 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]7a5378b2012-11-04 03:25:171826
1827 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:011828 EXPECT_THAT(rv, IsOk());
[email protected]7a5378b2012-11-04 03:25:171829
1830 scoped_refptr<IOBufferWithSize> io_buf(new IOBufferWithSize(100));
[email protected]90499482013-06-01 00:39:501831 rv = trans->Read(io_buf.get(), io_buf->size(), callback.callback());
[email protected]7a5378b2012-11-04 03:25:171832 if (rv == ERR_IO_PENDING)
1833 rv = callback.WaitForResult();
1834 EXPECT_EQ(5, rv);
[email protected]90499482013-06-01 00:39:501835 rv = trans->Read(io_buf.get(), io_buf->size(), callback.callback());
robpercival214763f2016-07-01 23:27:011836 EXPECT_THAT(rv, IsError(ERR_CONTENT_LENGTH_MISMATCH));
[email protected]7a5378b2012-11-04 03:25:171837
1838 trans.reset();
fdoray92e35a72016-06-10 15:54:551839 base::RunLoop().RunUntilIdle();
[email protected]7a5378b2012-11-04 03:25:171840 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
1841}
1842
bncd16676a2016-07-20 16:23:011843TEST_F(HttpNetworkTransactionTest, KeepAliveEarlyClose2) {
[email protected]7a5378b2012-11-04 03:25:171844 HttpRequestInfo request;
1845 request.method = "GET";
bncce36dca22015-04-21 22:11:231846 request.url = GURL("http://www.example.org/");
[email protected]7a5378b2012-11-04 03:25:171847
danakj1fd259a02016-04-16 03:17:091848 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:161849 std::unique_ptr<HttpNetworkTransaction> trans(
[email protected]90499482013-06-01 00:39:501850 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]7a5378b2012-11-04 03:25:171851
1852 MockRead data_reads[] = {
1853 MockRead("HTTP/1.0 200 OK\r\n"),
1854 MockRead("Connection: keep-alive\r\n"),
1855 MockRead("Content-Length: 100\r\n\r\n"),
1856 MockRead(SYNCHRONOUS, 0),
1857 };
1858 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:071859 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]7a5378b2012-11-04 03:25:171860
1861 TestCompletionCallback callback;
1862
tfarina42834112016-09-22 13:38:201863 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:011864 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]7a5378b2012-11-04 03:25:171865
1866 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:011867 EXPECT_THAT(rv, IsOk());
[email protected]7a5378b2012-11-04 03:25:171868
1869 scoped_refptr<IOBufferWithSize> io_buf(new IOBufferWithSize(100));
[email protected]90499482013-06-01 00:39:501870 rv = trans->Read(io_buf.get(), io_buf->size(), callback.callback());
[email protected]7a5378b2012-11-04 03:25:171871 if (rv == ERR_IO_PENDING)
1872 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:011873 EXPECT_THAT(rv, IsError(ERR_CONTENT_LENGTH_MISMATCH));
[email protected]7a5378b2012-11-04 03:25:171874
1875 trans.reset();
fdoray92e35a72016-06-10 15:54:551876 base::RunLoop().RunUntilIdle();
[email protected]7a5378b2012-11-04 03:25:171877 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
1878}
1879
[email protected]0b0bf032010-09-21 18:08:501880// Test that we correctly reuse a keep-alive connection after not explicitly
1881// reading the body.
bncd16676a2016-07-20 16:23:011882TEST_F(HttpNetworkTransactionTest, KeepAliveAfterUnreadBody) {
[email protected]fc31d6a42010-06-24 18:05:131883 HttpRequestInfo request;
1884 request.method = "GET";
1885 request.url = GURL("http://www.foo.com/");
[email protected]fc31d6a42010-06-24 18:05:131886
vishal.b62985ca92015-04-17 08:45:511887 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:071888 session_deps_.net_log = &net_log;
danakj1fd259a02016-04-16 03:17:091889 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:271890
mmenkecc2298e2015-12-07 18:20:181891 const char* request_data =
1892 "GET / HTTP/1.1\r\n"
1893 "Host: www.foo.com\r\n"
1894 "Connection: keep-alive\r\n\r\n";
1895 MockWrite data_writes[] = {
1896 MockWrite(ASYNC, 0, request_data), MockWrite(ASYNC, 2, request_data),
1897 MockWrite(ASYNC, 4, request_data), MockWrite(ASYNC, 6, request_data),
1898 MockWrite(ASYNC, 8, request_data), MockWrite(ASYNC, 10, request_data),
1899 MockWrite(ASYNC, 12, request_data), MockWrite(ASYNC, 14, request_data),
1900 MockWrite(ASYNC, 17, request_data), MockWrite(ASYNC, 20, request_data),
1901 };
1902
[email protected]0b0bf032010-09-21 18:08:501903 // Note that because all these reads happen in the same
1904 // StaticSocketDataProvider, it shows that the same socket is being reused for
1905 // all transactions.
mmenkecc2298e2015-12-07 18:20:181906 MockRead data_reads[] = {
1907 MockRead(ASYNC, 1, "HTTP/1.1 204 No Content\r\n\r\n"),
1908 MockRead(ASYNC, 3, "HTTP/1.1 205 Reset Content\r\n\r\n"),
1909 MockRead(ASYNC, 5, "HTTP/1.1 304 Not Modified\r\n\r\n"),
1910 MockRead(ASYNC, 7,
1911 "HTTP/1.1 302 Found\r\n"
1912 "Content-Length: 0\r\n\r\n"),
1913 MockRead(ASYNC, 9,
1914 "HTTP/1.1 302 Found\r\n"
1915 "Content-Length: 5\r\n\r\n"
1916 "hello"),
1917 MockRead(ASYNC, 11,
1918 "HTTP/1.1 301 Moved Permanently\r\n"
1919 "Content-Length: 0\r\n\r\n"),
1920 MockRead(ASYNC, 13,
1921 "HTTP/1.1 301 Moved Permanently\r\n"
1922 "Content-Length: 5\r\n\r\n"
1923 "hello"),
[email protected]fc31d6a42010-06-24 18:05:131924
mmenkecc2298e2015-12-07 18:20:181925 // In the next two rounds, IsConnectedAndIdle returns false, due to
1926 // the set_busy_before_sync_reads(true) call, while the
1927 // HttpNetworkTransaction is being shut down, but the socket is still
1928 // reuseable. See http://crbug.com/544255.
1929 MockRead(ASYNC, 15,
1930 "HTTP/1.1 200 Hunky-Dory\r\n"
1931 "Content-Length: 5\r\n\r\n"),
1932 MockRead(SYNCHRONOUS, 16, "hello"),
[email protected]fc31d6a42010-06-24 18:05:131933
mmenkecc2298e2015-12-07 18:20:181934 MockRead(ASYNC, 18,
1935 "HTTP/1.1 200 Hunky-Dory\r\n"
1936 "Content-Length: 5\r\n\r\n"
1937 "he"),
1938 MockRead(SYNCHRONOUS, 19, "llo"),
1939
1940 // The body of the final request is actually read.
1941 MockRead(ASYNC, 21, "HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
1942 MockRead(ASYNC, 22, "hello"),
1943 };
1944 SequencedSocketData data(data_reads, arraysize(data_reads), data_writes,
1945 arraysize(data_writes));
1946 data.set_busy_before_sync_reads(true);
1947 session_deps_.socket_factory->AddSocketDataProvider(&data);
1948
1949 const int kNumUnreadBodies = arraysize(data_writes) - 1;
[email protected]0b0bf032010-09-21 18:08:501950 std::string response_lines[kNumUnreadBodies];
1951
mikecironef22f9812016-10-04 03:40:191952 uint32_t first_socket_log_id = NetLogSource::kInvalidId;
mmenkecc2298e2015-12-07 18:20:181953 for (size_t i = 0; i < kNumUnreadBodies; ++i) {
[email protected]49639fa2011-12-20 23:22:411954 TestCompletionCallback callback;
[email protected]fc31d6a42010-06-24 18:05:131955
bnc691fda62016-08-12 00:43:161956 std::unique_ptr<HttpNetworkTransaction> trans(
[email protected]90499482013-06-01 00:39:501957 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]fc31d6a42010-06-24 18:05:131958
tfarina42834112016-09-22 13:38:201959 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:011960 EXPECT_THAT(callback.GetResult(rv), IsOk());
[email protected]fc31d6a42010-06-24 18:05:131961
[email protected]58e32bb2013-01-21 18:23:251962 LoadTimingInfo load_timing_info;
1963 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
1964 if (i == 0) {
1965 TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_DNS_TIMES);
1966 first_socket_log_id = load_timing_info.socket_log_id;
1967 } else {
1968 TestLoadTimingReused(load_timing_info);
1969 EXPECT_EQ(first_socket_log_id, load_timing_info.socket_log_id);
1970 }
1971
[email protected]fc31d6a42010-06-24 18:05:131972 const HttpResponseInfo* response = trans->GetResponseInfo();
mmenkecc2298e2015-12-07 18:20:181973 ASSERT_TRUE(response);
[email protected]fc31d6a42010-06-24 18:05:131974
mmenkecc2298e2015-12-07 18:20:181975 ASSERT_TRUE(response->headers);
[email protected]0b0bf032010-09-21 18:08:501976 response_lines[i] = response->headers->GetStatusLine();
1977
mmenkecc2298e2015-12-07 18:20:181978 // Delete the transaction without reading the response bodies. Then spin
1979 // the message loop, so the response bodies are drained.
1980 trans.reset();
1981 base::RunLoop().RunUntilIdle();
[email protected]fc31d6a42010-06-24 18:05:131982 }
[email protected]0b0bf032010-09-21 18:08:501983
1984 const char* const kStatusLines[] = {
mmenkecc2298e2015-12-07 18:20:181985 "HTTP/1.1 204 No Content",
1986 "HTTP/1.1 205 Reset Content",
1987 "HTTP/1.1 304 Not Modified",
1988 "HTTP/1.1 302 Found",
1989 "HTTP/1.1 302 Found",
1990 "HTTP/1.1 301 Moved Permanently",
1991 "HTTP/1.1 301 Moved Permanently",
1992 "HTTP/1.1 200 Hunky-Dory",
1993 "HTTP/1.1 200 Hunky-Dory",
[email protected]0b0bf032010-09-21 18:08:501994 };
1995
mostynb91e0da982015-01-20 19:17:271996 static_assert(kNumUnreadBodies == arraysize(kStatusLines),
1997 "forgot to update kStatusLines");
[email protected]0b0bf032010-09-21 18:08:501998
1999 for (int i = 0; i < kNumUnreadBodies; ++i)
2000 EXPECT_EQ(kStatusLines[i], response_lines[i]);
2001
[email protected]49639fa2011-12-20 23:22:412002 TestCompletionCallback callback;
bnc691fda62016-08-12 00:43:162003 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:202004 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012005 EXPECT_THAT(callback.GetResult(rv), IsOk());
bnc691fda62016-08-12 00:43:162006 const HttpResponseInfo* response = trans.GetResponseInfo();
mmenkecc2298e2015-12-07 18:20:182007 ASSERT_TRUE(response);
2008 ASSERT_TRUE(response->headers);
[email protected]0b0bf032010-09-21 18:08:502009 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
2010 std::string response_data;
bnc691fda62016-08-12 00:43:162011 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:012012 EXPECT_THAT(rv, IsOk());
[email protected]0b0bf032010-09-21 18:08:502013 EXPECT_EQ("hello", response_data);
[email protected]fc31d6a42010-06-24 18:05:132014}
2015
mmenke5f94fda2016-06-02 20:54:132016// Sockets that receive extra data after a response is complete should not be
2017// reused.
bncd16676a2016-07-20 16:23:012018TEST_F(HttpNetworkTransactionTest, KeepAliveWithUnusedData1) {
mmenke5f94fda2016-06-02 20:54:132019 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
2020 MockWrite data_writes1[] = {
2021 MockWrite("HEAD / HTTP/1.1\r\n"
2022 "Host: www.borked.com\r\n"
2023 "Connection: keep-alive\r\n\r\n"),
2024 };
2025
2026 MockRead data_reads1[] = {
2027 MockRead("HTTP/1.1 200 OK\r\n"
2028 "Connection: keep-alive\r\n"
2029 "Content-Length: 22\r\n\r\n"
2030 "This server is borked."),
2031 };
2032
2033 MockWrite data_writes2[] = {
2034 MockWrite("GET /foo HTTP/1.1\r\n"
2035 "Host: www.borked.com\r\n"
2036 "Connection: keep-alive\r\n\r\n"),
2037 };
2038
2039 MockRead data_reads2[] = {
2040 MockRead("HTTP/1.1 200 OK\r\n"
2041 "Content-Length: 3\r\n\r\n"
2042 "foo"),
2043 };
2044 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
2045 data_writes1, arraysize(data_writes1));
2046 session_deps_.socket_factory->AddSocketDataProvider(&data1);
2047 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
2048 data_writes2, arraysize(data_writes2));
2049 session_deps_.socket_factory->AddSocketDataProvider(&data2);
2050
2051 TestCompletionCallback callback;
2052 HttpRequestInfo request1;
2053 request1.method = "HEAD";
2054 request1.url = GURL("http://www.borked.com/");
2055
bnc691fda62016-08-12 00:43:162056 std::unique_ptr<HttpNetworkTransaction> trans1(
mmenke5f94fda2016-06-02 20:54:132057 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
tfarina42834112016-09-22 13:38:202058 int rv = trans1->Start(&request1, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012059 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenke5f94fda2016-06-02 20:54:132060
2061 const HttpResponseInfo* response1 = trans1->GetResponseInfo();
2062 ASSERT_TRUE(response1);
2063 ASSERT_TRUE(response1->headers);
2064 EXPECT_EQ(200, response1->headers->response_code());
2065 EXPECT_TRUE(response1->headers->IsKeepAlive());
2066
2067 std::string response_data1;
robpercival214763f2016-07-01 23:27:012068 EXPECT_THAT(ReadTransaction(trans1.get(), &response_data1), IsOk());
mmenke5f94fda2016-06-02 20:54:132069 EXPECT_EQ("", response_data1);
2070 // Deleting the transaction attempts to release the socket back into the
2071 // socket pool.
2072 trans1.reset();
2073
2074 HttpRequestInfo request2;
2075 request2.method = "GET";
2076 request2.url = GURL("http://www.borked.com/foo");
2077
bnc691fda62016-08-12 00:43:162078 std::unique_ptr<HttpNetworkTransaction> trans2(
mmenke5f94fda2016-06-02 20:54:132079 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
tfarina42834112016-09-22 13:38:202080 rv = trans2->Start(&request2, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012081 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenke5f94fda2016-06-02 20:54:132082
2083 const HttpResponseInfo* response2 = trans2->GetResponseInfo();
2084 ASSERT_TRUE(response2);
2085 ASSERT_TRUE(response2->headers);
2086 EXPECT_EQ(200, response2->headers->response_code());
2087
2088 std::string response_data2;
robpercival214763f2016-07-01 23:27:012089 EXPECT_THAT(ReadTransaction(trans2.get(), &response_data2), IsOk());
mmenke5f94fda2016-06-02 20:54:132090 EXPECT_EQ("foo", response_data2);
2091}
2092
bncd16676a2016-07-20 16:23:012093TEST_F(HttpNetworkTransactionTest, KeepAliveWithUnusedData2) {
mmenke5f94fda2016-06-02 20:54:132094 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
2095 MockWrite data_writes1[] = {
2096 MockWrite("GET / HTTP/1.1\r\n"
2097 "Host: www.borked.com\r\n"
2098 "Connection: keep-alive\r\n\r\n"),
2099 };
2100
2101 MockRead data_reads1[] = {
2102 MockRead("HTTP/1.1 200 OK\r\n"
2103 "Connection: keep-alive\r\n"
2104 "Content-Length: 22\r\n\r\n"
2105 "This server is borked."
2106 "Bonus data!"),
2107 };
2108
2109 MockWrite data_writes2[] = {
2110 MockWrite("GET /foo HTTP/1.1\r\n"
2111 "Host: www.borked.com\r\n"
2112 "Connection: keep-alive\r\n\r\n"),
2113 };
2114
2115 MockRead data_reads2[] = {
2116 MockRead("HTTP/1.1 200 OK\r\n"
2117 "Content-Length: 3\r\n\r\n"
2118 "foo"),
2119 };
2120 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
2121 data_writes1, arraysize(data_writes1));
2122 session_deps_.socket_factory->AddSocketDataProvider(&data1);
2123 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
2124 data_writes2, arraysize(data_writes2));
2125 session_deps_.socket_factory->AddSocketDataProvider(&data2);
2126
2127 TestCompletionCallback callback;
2128 HttpRequestInfo request1;
2129 request1.method = "GET";
2130 request1.url = GURL("http://www.borked.com/");
2131
bnc691fda62016-08-12 00:43:162132 std::unique_ptr<HttpNetworkTransaction> trans1(
mmenke5f94fda2016-06-02 20:54:132133 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
tfarina42834112016-09-22 13:38:202134 int rv = trans1->Start(&request1, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012135 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenke5f94fda2016-06-02 20:54:132136
2137 const HttpResponseInfo* response1 = trans1->GetResponseInfo();
2138 ASSERT_TRUE(response1);
2139 ASSERT_TRUE(response1->headers);
2140 EXPECT_EQ(200, response1->headers->response_code());
2141 EXPECT_TRUE(response1->headers->IsKeepAlive());
2142
2143 std::string response_data1;
robpercival214763f2016-07-01 23:27:012144 EXPECT_THAT(ReadTransaction(trans1.get(), &response_data1), IsOk());
mmenke5f94fda2016-06-02 20:54:132145 EXPECT_EQ("This server is borked.", response_data1);
2146 // Deleting the transaction attempts to release the socket back into the
2147 // socket pool.
2148 trans1.reset();
2149
2150 HttpRequestInfo request2;
2151 request2.method = "GET";
2152 request2.url = GURL("http://www.borked.com/foo");
2153
bnc691fda62016-08-12 00:43:162154 std::unique_ptr<HttpNetworkTransaction> trans2(
mmenke5f94fda2016-06-02 20:54:132155 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
tfarina42834112016-09-22 13:38:202156 rv = trans2->Start(&request2, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012157 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenke5f94fda2016-06-02 20:54:132158
2159 const HttpResponseInfo* response2 = trans2->GetResponseInfo();
2160 ASSERT_TRUE(response2);
2161 ASSERT_TRUE(response2->headers);
2162 EXPECT_EQ(200, response2->headers->response_code());
2163
2164 std::string response_data2;
robpercival214763f2016-07-01 23:27:012165 EXPECT_THAT(ReadTransaction(trans2.get(), &response_data2), IsOk());
mmenke5f94fda2016-06-02 20:54:132166 EXPECT_EQ("foo", response_data2);
2167}
2168
bncd16676a2016-07-20 16:23:012169TEST_F(HttpNetworkTransactionTest, KeepAliveWithUnusedData3) {
mmenke5f94fda2016-06-02 20:54:132170 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
2171 MockWrite data_writes1[] = {
2172 MockWrite("GET / HTTP/1.1\r\n"
2173 "Host: www.borked.com\r\n"
2174 "Connection: keep-alive\r\n\r\n"),
2175 };
2176
2177 MockRead data_reads1[] = {
2178 MockRead("HTTP/1.1 200 OK\r\n"
2179 "Connection: keep-alive\r\n"
2180 "Transfer-Encoding: chunked\r\n\r\n"),
2181 MockRead("16\r\nThis server is borked.\r\n"),
2182 MockRead("0\r\n\r\nBonus data!"),
2183 };
2184
2185 MockWrite data_writes2[] = {
2186 MockWrite("GET /foo HTTP/1.1\r\n"
2187 "Host: www.borked.com\r\n"
2188 "Connection: keep-alive\r\n\r\n"),
2189 };
2190
2191 MockRead data_reads2[] = {
2192 MockRead("HTTP/1.1 200 OK\r\n"
2193 "Content-Length: 3\r\n\r\n"
2194 "foo"),
2195 };
2196 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
2197 data_writes1, arraysize(data_writes1));
2198 session_deps_.socket_factory->AddSocketDataProvider(&data1);
2199 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
2200 data_writes2, arraysize(data_writes2));
2201 session_deps_.socket_factory->AddSocketDataProvider(&data2);
2202
2203 TestCompletionCallback callback;
2204 HttpRequestInfo request1;
2205 request1.method = "GET";
2206 request1.url = GURL("http://www.borked.com/");
2207
bnc691fda62016-08-12 00:43:162208 std::unique_ptr<HttpNetworkTransaction> trans1(
mmenke5f94fda2016-06-02 20:54:132209 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
tfarina42834112016-09-22 13:38:202210 int rv = trans1->Start(&request1, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012211 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenke5f94fda2016-06-02 20:54:132212
2213 const HttpResponseInfo* response1 = trans1->GetResponseInfo();
2214 ASSERT_TRUE(response1);
2215 ASSERT_TRUE(response1->headers);
2216 EXPECT_EQ(200, response1->headers->response_code());
2217 EXPECT_TRUE(response1->headers->IsKeepAlive());
2218
2219 std::string response_data1;
robpercival214763f2016-07-01 23:27:012220 EXPECT_THAT(ReadTransaction(trans1.get(), &response_data1), IsOk());
mmenke5f94fda2016-06-02 20:54:132221 EXPECT_EQ("This server is borked.", response_data1);
2222 // Deleting the transaction attempts to release the socket back into the
2223 // socket pool.
2224 trans1.reset();
2225
2226 HttpRequestInfo request2;
2227 request2.method = "GET";
2228 request2.url = GURL("http://www.borked.com/foo");
2229
bnc691fda62016-08-12 00:43:162230 std::unique_ptr<HttpNetworkTransaction> trans2(
mmenke5f94fda2016-06-02 20:54:132231 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
tfarina42834112016-09-22 13:38:202232 rv = trans2->Start(&request2, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012233 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenke5f94fda2016-06-02 20:54:132234
2235 const HttpResponseInfo* response2 = trans2->GetResponseInfo();
2236 ASSERT_TRUE(response2);
2237 ASSERT_TRUE(response2->headers);
2238 EXPECT_EQ(200, response2->headers->response_code());
2239
2240 std::string response_data2;
robpercival214763f2016-07-01 23:27:012241 EXPECT_THAT(ReadTransaction(trans2.get(), &response_data2), IsOk());
mmenke5f94fda2016-06-02 20:54:132242 EXPECT_EQ("foo", response_data2);
2243}
2244
2245// This is a little different from the others - it tests the case that the
2246// HttpStreamParser doesn't know if there's extra data on a socket or not when
2247// the HttpNetworkTransaction is torn down, because the response body hasn't
2248// been read from yet, but the request goes through the HttpResponseBodyDrainer.
bncd16676a2016-07-20 16:23:012249TEST_F(HttpNetworkTransactionTest, KeepAliveWithUnusedData4) {
mmenke5f94fda2016-06-02 20:54:132250 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
2251 MockWrite data_writes1[] = {
2252 MockWrite("GET / HTTP/1.1\r\n"
2253 "Host: www.borked.com\r\n"
2254 "Connection: keep-alive\r\n\r\n"),
2255 };
2256
2257 MockRead data_reads1[] = {
2258 MockRead("HTTP/1.1 200 OK\r\n"
2259 "Connection: keep-alive\r\n"
2260 "Transfer-Encoding: chunked\r\n\r\n"),
2261 MockRead("16\r\nThis server is borked.\r\n"),
2262 MockRead("0\r\n\r\nBonus data!"),
2263 };
2264 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
2265 data_writes1, arraysize(data_writes1));
2266 session_deps_.socket_factory->AddSocketDataProvider(&data1);
2267
2268 TestCompletionCallback callback;
2269 HttpRequestInfo request1;
2270 request1.method = "GET";
2271 request1.url = GURL("http://www.borked.com/");
2272
bnc691fda62016-08-12 00:43:162273 std::unique_ptr<HttpNetworkTransaction> trans1(
mmenke5f94fda2016-06-02 20:54:132274 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
tfarina42834112016-09-22 13:38:202275 int rv = trans1->Start(&request1, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012276 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenke5f94fda2016-06-02 20:54:132277
2278 const HttpResponseInfo* response1 = trans1->GetResponseInfo();
2279 ASSERT_TRUE(response1);
2280 ASSERT_TRUE(response1->headers);
2281 EXPECT_EQ(200, response1->headers->response_code());
2282 EXPECT_TRUE(response1->headers->IsKeepAlive());
2283
2284 // Deleting the transaction creates an HttpResponseBodyDrainer to read the
2285 // response body.
2286 trans1.reset();
2287
2288 // Let the HttpResponseBodyDrainer drain the socket. It should determine the
2289 // socket can't be reused, rather than returning it to the socket pool.
2290 base::RunLoop().RunUntilIdle();
2291
2292 // There should be no idle sockets in the pool.
2293 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
2294}
2295
[email protected]038e9a32008-10-08 22:40:162296// Test the request-challenge-retry sequence for basic auth.
2297// (basic auth is the easiest to mock, because it has no randomness).
bncd16676a2016-07-20 16:23:012298TEST_F(HttpNetworkTransactionTest, BasicAuth) {
[email protected]1c773ea12009-04-28 19:58:422299 HttpRequestInfo request;
[email protected]038e9a32008-10-08 22:40:162300 request.method = "GET";
bncce36dca22015-04-21 22:11:232301 request.url = GURL("http://www.example.org/");
[email protected]038e9a32008-10-08 22:40:162302
vishal.b62985ca92015-04-17 08:45:512303 TestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:072304 session_deps_.net_log = &log;
danakj1fd259a02016-04-16 03:17:092305 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:162306 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:272307
[email protected]f9ee6b52008-11-08 06:46:232308 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:232309 MockWrite(
2310 "GET / HTTP/1.1\r\n"
2311 "Host: www.example.org\r\n"
2312 "Connection: keep-alive\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:232313 };
2314
[email protected]038e9a32008-10-08 22:40:162315 MockRead data_reads1[] = {
2316 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
2317 // Give a couple authenticate options (only the middle one is actually
2318 // supported).
[email protected]22927ad2009-09-21 19:56:192319 MockRead("WWW-Authenticate: Basic invalid\r\n"), // Malformed.
[email protected]038e9a32008-10-08 22:40:162320 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2321 MockRead("WWW-Authenticate: UNSUPPORTED realm=\"FOO\"\r\n"),
2322 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
2323 // Large content-length -- won't matter, as connection will be reset.
2324 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:062325 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]038e9a32008-10-08 22:40:162326 };
2327
2328 // After calling trans->RestartWithAuth(), this is the request we should
2329 // be issuing -- the final header line contains the credentials.
2330 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:232331 MockWrite(
2332 "GET / HTTP/1.1\r\n"
2333 "Host: www.example.org\r\n"
2334 "Connection: keep-alive\r\n"
2335 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]038e9a32008-10-08 22:40:162336 };
2337
2338 // Lastly, the server responds with the actual content.
2339 MockRead data_reads2[] = {
2340 MockRead("HTTP/1.0 200 OK\r\n"),
2341 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
2342 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:062343 MockRead(SYNCHRONOUS, OK),
[email protected]038e9a32008-10-08 22:40:162344 };
2345
[email protected]31a2bfe2010-02-09 08:03:392346 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
2347 data_writes1, arraysize(data_writes1));
2348 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
2349 data_writes2, arraysize(data_writes2));
[email protected]bb88e1d32013-05-03 23:11:072350 session_deps_.socket_factory->AddSocketDataProvider(&data1);
2351 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]038e9a32008-10-08 22:40:162352
[email protected]49639fa2011-12-20 23:22:412353 TestCompletionCallback callback1;
[email protected]038e9a32008-10-08 22:40:162354
tfarina42834112016-09-22 13:38:202355 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012356 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]038e9a32008-10-08 22:40:162357
2358 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:012359 EXPECT_THAT(rv, IsOk());
[email protected]038e9a32008-10-08 22:40:162360
[email protected]58e32bb2013-01-21 18:23:252361 LoadTimingInfo load_timing_info1;
bnc691fda62016-08-12 00:43:162362 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info1));
[email protected]58e32bb2013-01-21 18:23:252363 TestLoadTimingNotReused(load_timing_info1, CONNECT_TIMING_HAS_DNS_TIMES);
2364
sclittlefb249892015-09-10 21:33:222365 int64_t writes_size1 = CountWriteBytes(data_writes1, arraysize(data_writes1));
bnc691fda62016-08-12 00:43:162366 EXPECT_EQ(writes_size1, trans.GetTotalSentBytes());
sclittlefb249892015-09-10 21:33:222367 int64_t reads_size1 = CountReadBytes(data_reads1, arraysize(data_reads1));
bnc691fda62016-08-12 00:43:162368 EXPECT_EQ(reads_size1, trans.GetTotalReceivedBytes());
[email protected]b8015c42013-12-24 15:18:192369
bnc691fda62016-08-12 00:43:162370 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:522371 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:042372 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]038e9a32008-10-08 22:40:162373
[email protected]49639fa2011-12-20 23:22:412374 TestCompletionCallback callback2;
[email protected]038e9a32008-10-08 22:40:162375
bnc691fda62016-08-12 00:43:162376 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar), callback2.callback());
robpercival214763f2016-07-01 23:27:012377 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]038e9a32008-10-08 22:40:162378
2379 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:012380 EXPECT_THAT(rv, IsOk());
[email protected]038e9a32008-10-08 22:40:162381
[email protected]58e32bb2013-01-21 18:23:252382 LoadTimingInfo load_timing_info2;
bnc691fda62016-08-12 00:43:162383 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info2));
[email protected]58e32bb2013-01-21 18:23:252384 TestLoadTimingNotReused(load_timing_info2, CONNECT_TIMING_HAS_DNS_TIMES);
2385 // The load timing after restart should have a new socket ID, and times after
2386 // those of the first load timing.
2387 EXPECT_LE(load_timing_info1.receive_headers_end,
2388 load_timing_info2.connect_timing.connect_start);
2389 EXPECT_NE(load_timing_info1.socket_log_id, load_timing_info2.socket_log_id);
2390
sclittlefb249892015-09-10 21:33:222391 int64_t writes_size2 = CountWriteBytes(data_writes2, arraysize(data_writes2));
bnc691fda62016-08-12 00:43:162392 EXPECT_EQ(writes_size1 + writes_size2, trans.GetTotalSentBytes());
sclittlefb249892015-09-10 21:33:222393 int64_t reads_size2 = CountReadBytes(data_reads2, arraysize(data_reads2));
bnc691fda62016-08-12 00:43:162394 EXPECT_EQ(reads_size1 + reads_size2, trans.GetTotalReceivedBytes());
[email protected]b8015c42013-12-24 15:18:192395
bnc691fda62016-08-12 00:43:162396 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:522397 ASSERT_TRUE(response);
2398 EXPECT_FALSE(response->auth_challenge);
[email protected]038e9a32008-10-08 22:40:162399 EXPECT_EQ(100, response->headers->GetContentLength());
[email protected]038e9a32008-10-08 22:40:162400}
2401
ttuttled9dbc652015-09-29 20:00:592402// Test the request-challenge-retry sequence for basic auth.
2403// (basic auth is the easiest to mock, because it has no randomness).
bncd16676a2016-07-20 16:23:012404TEST_F(HttpNetworkTransactionTest, BasicAuthWithAddressChange) {
ttuttled9dbc652015-09-29 20:00:592405 HttpRequestInfo request;
2406 request.method = "GET";
2407 request.url = GURL("http://www.example.org/");
ttuttled9dbc652015-09-29 20:00:592408
2409 TestNetLog log;
2410 MockHostResolver* resolver = new MockHostResolver();
2411 session_deps_.net_log = &log;
2412 session_deps_.host_resolver.reset(resolver);
danakj1fd259a02016-04-16 03:17:092413 std::unique_ptr<HttpNetworkSession> session = CreateSession(&session_deps_);
bnc691fda62016-08-12 00:43:162414 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
ttuttled9dbc652015-09-29 20:00:592415
2416 resolver->rules()->ClearRules();
2417 resolver->rules()->AddRule("www.example.org", "127.0.0.1");
2418
2419 MockWrite data_writes1[] = {
2420 MockWrite("GET / HTTP/1.1\r\n"
2421 "Host: www.example.org\r\n"
2422 "Connection: keep-alive\r\n\r\n"),
2423 };
2424
2425 MockRead data_reads1[] = {
2426 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
2427 // Give a couple authenticate options (only the middle one is actually
2428 // supported).
2429 MockRead("WWW-Authenticate: Basic invalid\r\n"), // Malformed.
2430 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2431 MockRead("WWW-Authenticate: UNSUPPORTED realm=\"FOO\"\r\n"),
2432 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
2433 // Large content-length -- won't matter, as connection will be reset.
2434 MockRead("Content-Length: 10000\r\n\r\n"),
2435 MockRead(SYNCHRONOUS, ERR_FAILED),
2436 };
2437
2438 // After calling trans->RestartWithAuth(), this is the request we should
2439 // be issuing -- the final header line contains the credentials.
2440 MockWrite data_writes2[] = {
2441 MockWrite("GET / HTTP/1.1\r\n"
2442 "Host: www.example.org\r\n"
2443 "Connection: keep-alive\r\n"
2444 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
2445 };
2446
2447 // Lastly, the server responds with the actual content.
2448 MockRead data_reads2[] = {
2449 MockRead("HTTP/1.0 200 OK\r\n"),
2450 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
2451 MockRead("Content-Length: 100\r\n\r\n"), MockRead(SYNCHRONOUS, OK),
2452 };
2453
2454 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
2455 data_writes1, arraysize(data_writes1));
2456 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
2457 data_writes2, arraysize(data_writes2));
2458 session_deps_.socket_factory->AddSocketDataProvider(&data1);
2459 session_deps_.socket_factory->AddSocketDataProvider(&data2);
2460
2461 TestCompletionCallback callback1;
2462
bnc691fda62016-08-12 00:43:162463 EXPECT_EQ(OK, callback1.GetResult(trans.Start(&request, callback1.callback(),
tfarina42834112016-09-22 13:38:202464 NetLogWithSource())));
ttuttled9dbc652015-09-29 20:00:592465
2466 LoadTimingInfo load_timing_info1;
bnc691fda62016-08-12 00:43:162467 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info1));
ttuttled9dbc652015-09-29 20:00:592468 TestLoadTimingNotReused(load_timing_info1, CONNECT_TIMING_HAS_DNS_TIMES);
2469
2470 int64_t writes_size1 = CountWriteBytes(data_writes1, arraysize(data_writes1));
bnc691fda62016-08-12 00:43:162471 EXPECT_EQ(writes_size1, trans.GetTotalSentBytes());
ttuttled9dbc652015-09-29 20:00:592472 int64_t reads_size1 = CountReadBytes(data_reads1, arraysize(data_reads1));
bnc691fda62016-08-12 00:43:162473 EXPECT_EQ(reads_size1, trans.GetTotalReceivedBytes());
ttuttled9dbc652015-09-29 20:00:592474
bnc691fda62016-08-12 00:43:162475 const HttpResponseInfo* response = trans.GetResponseInfo();
ttuttled9dbc652015-09-29 20:00:592476 ASSERT_TRUE(response);
2477 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
2478
2479 IPEndPoint endpoint;
bnc691fda62016-08-12 00:43:162480 EXPECT_TRUE(trans.GetRemoteEndpoint(&endpoint));
ttuttled9dbc652015-09-29 20:00:592481 ASSERT_FALSE(endpoint.address().empty());
2482 EXPECT_EQ("127.0.0.1:80", endpoint.ToString());
2483
2484 resolver->rules()->ClearRules();
2485 resolver->rules()->AddRule("www.example.org", "127.0.0.2");
2486
2487 TestCompletionCallback callback2;
2488
bnc691fda62016-08-12 00:43:162489 EXPECT_EQ(OK, callback2.GetResult(trans.RestartWithAuth(
ttuttled9dbc652015-09-29 20:00:592490 AuthCredentials(kFoo, kBar), callback2.callback())));
2491
2492 LoadTimingInfo load_timing_info2;
bnc691fda62016-08-12 00:43:162493 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info2));
ttuttled9dbc652015-09-29 20:00:592494 TestLoadTimingNotReused(load_timing_info2, CONNECT_TIMING_HAS_DNS_TIMES);
2495 // The load timing after restart should have a new socket ID, and times after
2496 // those of the first load timing.
2497 EXPECT_LE(load_timing_info1.receive_headers_end,
2498 load_timing_info2.connect_timing.connect_start);
2499 EXPECT_NE(load_timing_info1.socket_log_id, load_timing_info2.socket_log_id);
2500
2501 int64_t writes_size2 = CountWriteBytes(data_writes2, arraysize(data_writes2));
bnc691fda62016-08-12 00:43:162502 EXPECT_EQ(writes_size1 + writes_size2, trans.GetTotalSentBytes());
ttuttled9dbc652015-09-29 20:00:592503 int64_t reads_size2 = CountReadBytes(data_reads2, arraysize(data_reads2));
bnc691fda62016-08-12 00:43:162504 EXPECT_EQ(reads_size1 + reads_size2, trans.GetTotalReceivedBytes());
ttuttled9dbc652015-09-29 20:00:592505
bnc691fda62016-08-12 00:43:162506 response = trans.GetResponseInfo();
ttuttled9dbc652015-09-29 20:00:592507 ASSERT_TRUE(response);
wezca1070932016-05-26 20:30:522508 EXPECT_FALSE(response->auth_challenge);
ttuttled9dbc652015-09-29 20:00:592509 EXPECT_EQ(100, response->headers->GetContentLength());
2510
bnc691fda62016-08-12 00:43:162511 EXPECT_TRUE(trans.GetRemoteEndpoint(&endpoint));
ttuttled9dbc652015-09-29 20:00:592512 ASSERT_FALSE(endpoint.address().empty());
2513 EXPECT_EQ("127.0.0.2:80", endpoint.ToString());
2514}
2515
bncd16676a2016-07-20 16:23:012516TEST_F(HttpNetworkTransactionTest, DoNotSendAuth) {
[email protected]861fcd52009-08-26 02:33:462517 HttpRequestInfo request;
2518 request.method = "GET";
bncce36dca22015-04-21 22:11:232519 request.url = GURL("http://www.example.org/");
ttuttle859dc7a2015-04-23 19:42:292520 request.load_flags = LOAD_DO_NOT_SEND_AUTH_DATA;
[email protected]861fcd52009-08-26 02:33:462521
danakj1fd259a02016-04-16 03:17:092522 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:162523 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:272524
[email protected]861fcd52009-08-26 02:33:462525 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:232526 MockWrite(
2527 "GET / HTTP/1.1\r\n"
2528 "Host: www.example.org\r\n"
2529 "Connection: keep-alive\r\n\r\n"),
[email protected]861fcd52009-08-26 02:33:462530 };
2531
2532 MockRead data_reads[] = {
2533 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
2534 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2535 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
2536 // Large content-length -- won't matter, as connection will be reset.
2537 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:062538 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]861fcd52009-08-26 02:33:462539 };
2540
[email protected]31a2bfe2010-02-09 08:03:392541 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
2542 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:072543 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]49639fa2011-12-20 23:22:412544 TestCompletionCallback callback;
[email protected]861fcd52009-08-26 02:33:462545
tfarina42834112016-09-22 13:38:202546 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012547 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]861fcd52009-08-26 02:33:462548
2549 rv = callback.WaitForResult();
2550 EXPECT_EQ(0, rv);
2551
sclittlefb249892015-09-10 21:33:222552 int64_t writes_size = CountWriteBytes(data_writes, arraysize(data_writes));
bnc691fda62016-08-12 00:43:162553 EXPECT_EQ(writes_size, trans.GetTotalSentBytes());
sclittlefb249892015-09-10 21:33:222554 int64_t reads_size = CountReadBytes(data_reads, arraysize(data_reads));
bnc691fda62016-08-12 00:43:162555 EXPECT_EQ(reads_size, trans.GetTotalReceivedBytes());
[email protected]b8015c42013-12-24 15:18:192556
bnc691fda62016-08-12 00:43:162557 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:522558 ASSERT_TRUE(response);
2559 EXPECT_FALSE(response->auth_challenge);
[email protected]861fcd52009-08-26 02:33:462560}
2561
[email protected]2d2697f92009-02-18 21:00:322562// Test the request-challenge-retry sequence for basic auth, over a keep-alive
2563// connection.
bncd16676a2016-07-20 16:23:012564TEST_F(HttpNetworkTransactionTest, BasicAuthKeepAlive) {
mmenkecc2298e2015-12-07 18:20:182565 // On the second pass, the body read of the auth challenge is synchronous, so
2566 // IsConnectedAndIdle returns false. The socket should still be drained and
2567 // reused. See http://crbug.com/544255.
2568 for (int i = 0; i < 2; ++i) {
2569 HttpRequestInfo request;
2570 request.method = "GET";
2571 request.url = GURL("http://www.example.org/");
[email protected]2d2697f92009-02-18 21:00:322572
mmenkecc2298e2015-12-07 18:20:182573 TestNetLog log;
2574 session_deps_.net_log = &log;
danakj1fd259a02016-04-16 03:17:092575 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:272576
mmenkecc2298e2015-12-07 18:20:182577 MockWrite data_writes[] = {
2578 MockWrite(ASYNC, 0,
2579 "GET / HTTP/1.1\r\n"
2580 "Host: www.example.org\r\n"
2581 "Connection: keep-alive\r\n\r\n"),
[email protected]2d2697f92009-02-18 21:00:322582
bnc691fda62016-08-12 00:43:162583 // After calling trans.RestartWithAuth(), this is the request we should
mmenkecc2298e2015-12-07 18:20:182584 // be issuing -- the final header line contains the credentials.
2585 MockWrite(ASYNC, 6,
2586 "GET / HTTP/1.1\r\n"
2587 "Host: www.example.org\r\n"
2588 "Connection: keep-alive\r\n"
2589 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
2590 };
[email protected]2d2697f92009-02-18 21:00:322591
mmenkecc2298e2015-12-07 18:20:182592 MockRead data_reads[] = {
2593 MockRead(ASYNC, 1, "HTTP/1.1 401 Unauthorized\r\n"),
2594 MockRead(ASYNC, 2, "WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2595 MockRead(ASYNC, 3, "Content-Type: text/html; charset=iso-8859-1\r\n"),
2596 MockRead(ASYNC, 4, "Content-Length: 14\r\n\r\n"),
2597 MockRead(i == 0 ? ASYNC : SYNCHRONOUS, 5, "Unauthorized\r\n"),
[email protected]2d2697f92009-02-18 21:00:322598
mmenkecc2298e2015-12-07 18:20:182599 // Lastly, the server responds with the actual content.
2600 MockRead(ASYNC, 7, "HTTP/1.1 200 OK\r\n"),
2601 MockRead(ASYNC, 8, "Content-Type: text/html; charset=iso-8859-1\r\n"),
2602 MockRead(ASYNC, 9, "Content-Length: 5\r\n\r\n"),
2603 MockRead(ASYNC, 10, "Hello"),
2604 };
[email protected]2d2697f92009-02-18 21:00:322605
mmenkecc2298e2015-12-07 18:20:182606 SequencedSocketData data(data_reads, arraysize(data_reads), data_writes,
2607 arraysize(data_writes));
2608 data.set_busy_before_sync_reads(true);
2609 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]2d0a4f92011-05-05 16:38:462610
mmenkecc2298e2015-12-07 18:20:182611 TestCompletionCallback callback1;
[email protected]2d2697f92009-02-18 21:00:322612
bnc691fda62016-08-12 00:43:162613 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:202614 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012615 ASSERT_THAT(callback1.GetResult(rv), IsOk());
[email protected]2d2697f92009-02-18 21:00:322616
mmenkecc2298e2015-12-07 18:20:182617 LoadTimingInfo load_timing_info1;
bnc691fda62016-08-12 00:43:162618 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info1));
mmenkecc2298e2015-12-07 18:20:182619 TestLoadTimingNotReused(load_timing_info1, CONNECT_TIMING_HAS_DNS_TIMES);
[email protected]2d2697f92009-02-18 21:00:322620
bnc691fda62016-08-12 00:43:162621 const HttpResponseInfo* response = trans.GetResponseInfo();
mmenkecc2298e2015-12-07 18:20:182622 ASSERT_TRUE(response);
2623 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]2d2697f92009-02-18 21:00:322624
mmenkecc2298e2015-12-07 18:20:182625 TestCompletionCallback callback2;
[email protected]58e32bb2013-01-21 18:23:252626
bnc691fda62016-08-12 00:43:162627 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar),
2628 callback2.callback());
robpercival214763f2016-07-01 23:27:012629 ASSERT_THAT(callback2.GetResult(rv), IsOk());
[email protected]2d2697f92009-02-18 21:00:322630
mmenkecc2298e2015-12-07 18:20:182631 LoadTimingInfo load_timing_info2;
bnc691fda62016-08-12 00:43:162632 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info2));
mmenkecc2298e2015-12-07 18:20:182633 TestLoadTimingReused(load_timing_info2);
2634 // The load timing after restart should have the same socket ID, and times
2635 // those of the first load timing.
2636 EXPECT_LE(load_timing_info1.receive_headers_end,
2637 load_timing_info2.send_start);
2638 EXPECT_EQ(load_timing_info1.socket_log_id, load_timing_info2.socket_log_id);
[email protected]2d2697f92009-02-18 21:00:322639
bnc691fda62016-08-12 00:43:162640 response = trans.GetResponseInfo();
mmenkecc2298e2015-12-07 18:20:182641 ASSERT_TRUE(response);
2642 EXPECT_FALSE(response->auth_challenge);
2643 EXPECT_EQ(5, response->headers->GetContentLength());
[email protected]2d2697f92009-02-18 21:00:322644
mmenkecc2298e2015-12-07 18:20:182645 std::string response_data;
bnc691fda62016-08-12 00:43:162646 EXPECT_THAT(ReadTransaction(&trans, &response_data), IsOk());
[email protected]2d2697f92009-02-18 21:00:322647
mmenkecc2298e2015-12-07 18:20:182648 int64_t writes_size = CountWriteBytes(data_writes, arraysize(data_writes));
bnc691fda62016-08-12 00:43:162649 EXPECT_EQ(writes_size, trans.GetTotalSentBytes());
mmenkecc2298e2015-12-07 18:20:182650 int64_t reads_size = CountReadBytes(data_reads, arraysize(data_reads));
bnc691fda62016-08-12 00:43:162651 EXPECT_EQ(reads_size, trans.GetTotalReceivedBytes());
mmenkecc2298e2015-12-07 18:20:182652 }
[email protected]2d2697f92009-02-18 21:00:322653}
2654
2655// Test the request-challenge-retry sequence for basic auth, over a keep-alive
2656// connection and with no response body to drain.
bncd16676a2016-07-20 16:23:012657TEST_F(HttpNetworkTransactionTest, BasicAuthKeepAliveNoBody) {
[email protected]1c773ea12009-04-28 19:58:422658 HttpRequestInfo request;
[email protected]2d2697f92009-02-18 21:00:322659 request.method = "GET";
bncce36dca22015-04-21 22:11:232660 request.url = GURL("http://www.example.org/");
[email protected]2d2697f92009-02-18 21:00:322661
danakj1fd259a02016-04-16 03:17:092662 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:272663
[email protected]2d2697f92009-02-18 21:00:322664 MockWrite data_writes1[] = {
bnc691fda62016-08-12 00:43:162665 MockWrite("GET / HTTP/1.1\r\n"
2666 "Host: www.example.org\r\n"
2667 "Connection: keep-alive\r\n\r\n"),
[email protected]2d2697f92009-02-18 21:00:322668
bnc691fda62016-08-12 00:43:162669 // After calling trans.RestartWithAuth(), this is the request we should
bncce36dca22015-04-21 22:11:232670 // be issuing -- the final header line contains the credentials.
bnc691fda62016-08-12 00:43:162671 MockWrite("GET / HTTP/1.1\r\n"
2672 "Host: www.example.org\r\n"
2673 "Connection: keep-alive\r\n"
2674 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]2d2697f92009-02-18 21:00:322675 };
2676
[email protected]2d2697f92009-02-18 21:00:322677 MockRead data_reads1[] = {
2678 MockRead("HTTP/1.1 401 Unauthorized\r\n"),
2679 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
[email protected]11203f012009-11-12 23:02:312680 MockRead("Content-Length: 0\r\n\r\n"), // No response body.
[email protected]2d2697f92009-02-18 21:00:322681
2682 // Lastly, the server responds with the actual content.
2683 MockRead("HTTP/1.1 200 OK\r\n"),
2684 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
[email protected]0b0bf032010-09-21 18:08:502685 MockRead("Content-Length: 5\r\n\r\n"),
2686 MockRead("hello"),
[email protected]2d2697f92009-02-18 21:00:322687 };
2688
[email protected]2d0a4f92011-05-05 16:38:462689 // An incorrect reconnect would cause this to be read.
2690 MockRead data_reads2[] = {
[email protected]8ddf8322012-02-23 18:08:062691 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]2d0a4f92011-05-05 16:38:462692 };
2693
[email protected]31a2bfe2010-02-09 08:03:392694 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
2695 data_writes1, arraysize(data_writes1));
[email protected]2d0a4f92011-05-05 16:38:462696 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
2697 NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:072698 session_deps_.socket_factory->AddSocketDataProvider(&data1);
2699 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]2d2697f92009-02-18 21:00:322700
[email protected]49639fa2011-12-20 23:22:412701 TestCompletionCallback callback1;
[email protected]2d2697f92009-02-18 21:00:322702
bnc691fda62016-08-12 00:43:162703 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:202704 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012705 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2d2697f92009-02-18 21:00:322706
2707 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:012708 EXPECT_THAT(rv, IsOk());
[email protected]2d2697f92009-02-18 21:00:322709
bnc691fda62016-08-12 00:43:162710 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:522711 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:042712 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]2d2697f92009-02-18 21:00:322713
[email protected]49639fa2011-12-20 23:22:412714 TestCompletionCallback callback2;
[email protected]2d2697f92009-02-18 21:00:322715
bnc691fda62016-08-12 00:43:162716 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar), callback2.callback());
robpercival214763f2016-07-01 23:27:012717 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2d2697f92009-02-18 21:00:322718
2719 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:012720 EXPECT_THAT(rv, IsOk());
[email protected]2d2697f92009-02-18 21:00:322721
bnc691fda62016-08-12 00:43:162722 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:522723 ASSERT_TRUE(response);
2724 EXPECT_FALSE(response->auth_challenge);
[email protected]0b0bf032010-09-21 18:08:502725 EXPECT_EQ(5, response->headers->GetContentLength());
[email protected]2d2697f92009-02-18 21:00:322726}
2727
2728// Test the request-challenge-retry sequence for basic auth, over a keep-alive
2729// connection and with a large response body to drain.
bncd16676a2016-07-20 16:23:012730TEST_F(HttpNetworkTransactionTest, BasicAuthKeepAliveLargeBody) {
[email protected]1c773ea12009-04-28 19:58:422731 HttpRequestInfo request;
[email protected]2d2697f92009-02-18 21:00:322732 request.method = "GET";
bncce36dca22015-04-21 22:11:232733 request.url = GURL("http://www.example.org/");
[email protected]2d2697f92009-02-18 21:00:322734
danakj1fd259a02016-04-16 03:17:092735 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:272736
[email protected]2d2697f92009-02-18 21:00:322737 MockWrite data_writes1[] = {
bnc691fda62016-08-12 00:43:162738 MockWrite("GET / HTTP/1.1\r\n"
2739 "Host: www.example.org\r\n"
2740 "Connection: keep-alive\r\n\r\n"),
[email protected]2d2697f92009-02-18 21:00:322741
bnc691fda62016-08-12 00:43:162742 // After calling trans.RestartWithAuth(), this is the request we should
bncce36dca22015-04-21 22:11:232743 // be issuing -- the final header line contains the credentials.
bnc691fda62016-08-12 00:43:162744 MockWrite("GET / HTTP/1.1\r\n"
2745 "Host: www.example.org\r\n"
2746 "Connection: keep-alive\r\n"
2747 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]2d2697f92009-02-18 21:00:322748 };
2749
2750 // Respond with 5 kb of response body.
2751 std::string large_body_string("Unauthorized");
2752 large_body_string.append(5 * 1024, ' ');
2753 large_body_string.append("\r\n");
2754
2755 MockRead data_reads1[] = {
2756 MockRead("HTTP/1.1 401 Unauthorized\r\n"),
2757 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2758 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
2759 // 5134 = 12 + 5 * 1024 + 2
2760 MockRead("Content-Length: 5134\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:062761 MockRead(ASYNC, large_body_string.data(), large_body_string.size()),
[email protected]2d2697f92009-02-18 21:00:322762
2763 // Lastly, the server responds with the actual content.
2764 MockRead("HTTP/1.1 200 OK\r\n"),
2765 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
[email protected]0b0bf032010-09-21 18:08:502766 MockRead("Content-Length: 5\r\n\r\n"),
2767 MockRead("hello"),
[email protected]2d2697f92009-02-18 21:00:322768 };
2769
[email protected]2d0a4f92011-05-05 16:38:462770 // An incorrect reconnect would cause this to be read.
2771 MockRead data_reads2[] = {
[email protected]8ddf8322012-02-23 18:08:062772 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]2d0a4f92011-05-05 16:38:462773 };
2774
[email protected]31a2bfe2010-02-09 08:03:392775 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
2776 data_writes1, arraysize(data_writes1));
[email protected]2d0a4f92011-05-05 16:38:462777 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
2778 NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:072779 session_deps_.socket_factory->AddSocketDataProvider(&data1);
2780 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]2d2697f92009-02-18 21:00:322781
[email protected]49639fa2011-12-20 23:22:412782 TestCompletionCallback callback1;
[email protected]2d2697f92009-02-18 21:00:322783
bnc691fda62016-08-12 00:43:162784 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:202785 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012786 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2d2697f92009-02-18 21:00:322787
2788 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:012789 EXPECT_THAT(rv, IsOk());
[email protected]2d2697f92009-02-18 21:00:322790
bnc691fda62016-08-12 00:43:162791 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:522792 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:042793 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]2d2697f92009-02-18 21:00:322794
[email protected]49639fa2011-12-20 23:22:412795 TestCompletionCallback callback2;
[email protected]2d2697f92009-02-18 21:00:322796
bnc691fda62016-08-12 00:43:162797 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar), callback2.callback());
robpercival214763f2016-07-01 23:27:012798 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2d2697f92009-02-18 21:00:322799
2800 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:012801 EXPECT_THAT(rv, IsOk());
[email protected]2d2697f92009-02-18 21:00:322802
bnc691fda62016-08-12 00:43:162803 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:522804 ASSERT_TRUE(response);
2805 EXPECT_FALSE(response->auth_challenge);
[email protected]0b0bf032010-09-21 18:08:502806 EXPECT_EQ(5, response->headers->GetContentLength());
[email protected]2d2697f92009-02-18 21:00:322807}
2808
2809// Test the request-challenge-retry sequence for basic auth, over a keep-alive
[email protected]11203f012009-11-12 23:02:312810// connection, but the server gets impatient and closes the connection.
bncd16676a2016-07-20 16:23:012811TEST_F(HttpNetworkTransactionTest, BasicAuthKeepAliveImpatientServer) {
[email protected]11203f012009-11-12 23:02:312812 HttpRequestInfo request;
2813 request.method = "GET";
bncce36dca22015-04-21 22:11:232814 request.url = GURL("http://www.example.org/");
[email protected]11203f012009-11-12 23:02:312815
danakj1fd259a02016-04-16 03:17:092816 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:272817
[email protected]11203f012009-11-12 23:02:312818 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:232819 MockWrite(
2820 "GET / HTTP/1.1\r\n"
2821 "Host: www.example.org\r\n"
2822 "Connection: keep-alive\r\n\r\n"),
2823 // This simulates the seemingly successful write to a closed connection
2824 // if the bug is not fixed.
2825 MockWrite(
2826 "GET / HTTP/1.1\r\n"
2827 "Host: www.example.org\r\n"
2828 "Connection: keep-alive\r\n"
2829 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]11203f012009-11-12 23:02:312830 };
2831
2832 MockRead data_reads1[] = {
2833 MockRead("HTTP/1.1 401 Unauthorized\r\n"),
2834 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2835 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
2836 MockRead("Content-Length: 14\r\n\r\n"),
2837 // Tell MockTCPClientSocket to simulate the server closing the connection.
[email protected]8ddf8322012-02-23 18:08:062838 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
[email protected]11203f012009-11-12 23:02:312839 MockRead("Unauthorized\r\n"),
[email protected]8ddf8322012-02-23 18:08:062840 MockRead(SYNCHRONOUS, OK), // The server closes the connection.
[email protected]11203f012009-11-12 23:02:312841 };
2842
bnc691fda62016-08-12 00:43:162843 // After calling trans.RestartWithAuth(), this is the request we should
[email protected]11203f012009-11-12 23:02:312844 // be issuing -- the final header line contains the credentials.
2845 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:232846 MockWrite(
2847 "GET / HTTP/1.1\r\n"
2848 "Host: www.example.org\r\n"
2849 "Connection: keep-alive\r\n"
2850 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]11203f012009-11-12 23:02:312851 };
2852
2853 // Lastly, the server responds with the actual content.
2854 MockRead data_reads2[] = {
2855 MockRead("HTTP/1.1 200 OK\r\n"),
2856 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
[email protected]0b0bf032010-09-21 18:08:502857 MockRead("Content-Length: 5\r\n\r\n"),
2858 MockRead("hello"),
[email protected]11203f012009-11-12 23:02:312859 };
2860
[email protected]31a2bfe2010-02-09 08:03:392861 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
2862 data_writes1, arraysize(data_writes1));
2863 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
2864 data_writes2, arraysize(data_writes2));
[email protected]bb88e1d32013-05-03 23:11:072865 session_deps_.socket_factory->AddSocketDataProvider(&data1);
2866 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]11203f012009-11-12 23:02:312867
[email protected]49639fa2011-12-20 23:22:412868 TestCompletionCallback callback1;
[email protected]11203f012009-11-12 23:02:312869
bnc691fda62016-08-12 00:43:162870 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:202871 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012872 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]11203f012009-11-12 23:02:312873
2874 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:012875 EXPECT_THAT(rv, IsOk());
[email protected]11203f012009-11-12 23:02:312876
bnc691fda62016-08-12 00:43:162877 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:522878 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:042879 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]11203f012009-11-12 23:02:312880
[email protected]49639fa2011-12-20 23:22:412881 TestCompletionCallback callback2;
[email protected]11203f012009-11-12 23:02:312882
bnc691fda62016-08-12 00:43:162883 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar), callback2.callback());
robpercival214763f2016-07-01 23:27:012884 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]11203f012009-11-12 23:02:312885
2886 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:012887 EXPECT_THAT(rv, IsOk());
[email protected]11203f012009-11-12 23:02:312888
bnc691fda62016-08-12 00:43:162889 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:522890 ASSERT_TRUE(response);
2891 EXPECT_FALSE(response->auth_challenge);
[email protected]0b0bf032010-09-21 18:08:502892 EXPECT_EQ(5, response->headers->GetContentLength());
[email protected]11203f012009-11-12 23:02:312893}
2894
[email protected]394816e92010-08-03 07:38:592895// Test the request-challenge-retry sequence for basic auth, over a connection
2896// that requires a restart when setting up an SSL tunnel.
bncd16676a2016-07-20 16:23:012897TEST_F(HttpNetworkTransactionTest, BasicAuthProxyNoKeepAliveHttp10) {
ttuttle34f63b52015-03-05 04:33:012898 HttpRequestInfo request;
2899 request.method = "GET";
bncce36dca22015-04-21 22:11:232900 request.url = GURL("https://www.example.org/");
ttuttle34f63b52015-03-05 04:33:012901 // when the no authentication data flag is set.
ttuttle859dc7a2015-04-23 19:42:292902 request.load_flags = LOAD_DO_NOT_SEND_AUTH_DATA;
ttuttle34f63b52015-03-05 04:33:012903
2904 // Configure against proxy server "myproxy:70".
rdsmith82957ad2015-09-16 19:42:032905 session_deps_.proxy_service =
2906 ProxyService::CreateFixedFromPacResult("PROXY myproxy:70");
vishal.b62985ca92015-04-17 08:45:512907 BoundTestNetLog log;
ttuttle34f63b52015-03-05 04:33:012908 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:092909 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
ttuttle34f63b52015-03-05 04:33:012910
2911 // Since we have proxy, should try to establish tunnel.
2912 MockWrite data_writes1[] = {
mmenkee71e15332015-10-07 16:39:542913 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:172914 "Host: www.example.org:443\r\n"
mmenkee71e15332015-10-07 16:39:542915 "Proxy-Connection: keep-alive\r\n\r\n"),
ttuttle34f63b52015-03-05 04:33:012916 };
2917
mmenkee71e15332015-10-07 16:39:542918 // The proxy responds to the connect with a 407, using a non-persistent
ttuttle34f63b52015-03-05 04:33:012919 // connection.
2920 MockRead data_reads1[] = {
2921 // No credentials.
2922 MockRead("HTTP/1.0 407 Proxy Authentication Required\r\n"),
2923 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n\r\n"),
mmenkee71e15332015-10-07 16:39:542924 };
ttuttle34f63b52015-03-05 04:33:012925
mmenkee71e15332015-10-07 16:39:542926 // Since the first connection couldn't be reused, need to establish another
2927 // once given credentials.
2928 MockWrite data_writes2[] = {
2929 // After calling trans->RestartWithAuth(), this is the request we should
2930 // be issuing -- the final header line contains the credentials.
2931 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:172932 "Host: www.example.org:443\r\n"
mmenkee71e15332015-10-07 16:39:542933 "Proxy-Connection: keep-alive\r\n"
2934 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
2935
2936 MockWrite("GET / HTTP/1.1\r\n"
2937 "Host: www.example.org\r\n"
2938 "Connection: keep-alive\r\n\r\n"),
2939 };
2940
2941 MockRead data_reads2[] = {
ttuttle34f63b52015-03-05 04:33:012942 MockRead("HTTP/1.0 200 Connection Established\r\n\r\n"),
2943
2944 MockRead("HTTP/1.1 200 OK\r\n"),
2945 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
2946 MockRead("Content-Length: 5\r\n\r\n"),
2947 MockRead(SYNCHRONOUS, "hello"),
2948 };
2949
2950 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
2951 data_writes1, arraysize(data_writes1));
2952 session_deps_.socket_factory->AddSocketDataProvider(&data1);
mmenkee71e15332015-10-07 16:39:542953 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
2954 data_writes2, arraysize(data_writes2));
2955 session_deps_.socket_factory->AddSocketDataProvider(&data2);
ttuttle34f63b52015-03-05 04:33:012956 SSLSocketDataProvider ssl(ASYNC, OK);
2957 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
2958
2959 TestCompletionCallback callback1;
2960
bnc691fda62016-08-12 00:43:162961 std::unique_ptr<HttpNetworkTransaction> trans(
ttuttle34f63b52015-03-05 04:33:012962 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
2963
2964 int rv = trans->Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:012965 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
ttuttle34f63b52015-03-05 04:33:012966
2967 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:012968 EXPECT_THAT(rv, IsOk());
mmenke43758e62015-05-04 21:09:462969 TestNetLogEntry::List entries;
ttuttle34f63b52015-03-05 04:33:012970 log.GetEntries(&entries);
2971 size_t pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:002972 entries, 0, NetLogEventType::HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
2973 NetLogEventPhase::NONE);
ttuttle34f63b52015-03-05 04:33:012974 ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:002975 entries, pos,
2976 NetLogEventType::HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
2977 NetLogEventPhase::NONE);
ttuttle34f63b52015-03-05 04:33:012978
2979 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:522980 ASSERT_TRUE(response);
ttuttle34f63b52015-03-05 04:33:012981 EXPECT_FALSE(response->headers->IsKeepAlive());
wezca1070932016-05-26 20:30:522982 ASSERT_TRUE(response->headers);
ttuttle34f63b52015-03-05 04:33:012983 EXPECT_EQ(407, response->headers->response_code());
2984 EXPECT_TRUE(HttpVersion(1, 0) == response->headers->GetHttpVersion());
2985 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
2986
2987 LoadTimingInfo load_timing_info;
2988 // CONNECT requests and responses are handled at the connect job level, so
2989 // the transaction does not yet have a connection.
2990 EXPECT_FALSE(trans->GetLoadTimingInfo(&load_timing_info));
2991
2992 TestCompletionCallback callback2;
2993
2994 rv =
2995 trans->RestartWithAuth(AuthCredentials(kFoo, kBar), callback2.callback());
robpercival214763f2016-07-01 23:27:012996 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
ttuttle34f63b52015-03-05 04:33:012997
2998 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:012999 EXPECT_THAT(rv, IsOk());
ttuttle34f63b52015-03-05 04:33:013000
3001 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:523002 ASSERT_TRUE(response);
ttuttle34f63b52015-03-05 04:33:013003
3004 EXPECT_TRUE(response->headers->IsKeepAlive());
3005 EXPECT_EQ(200, response->headers->response_code());
3006 EXPECT_EQ(5, response->headers->GetContentLength());
3007 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
3008
3009 // The password prompt info should not be set.
wezca1070932016-05-26 20:30:523010 EXPECT_FALSE(response->auth_challenge);
ttuttle34f63b52015-03-05 04:33:013011
3012 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
3013 TestLoadTimingNotReusedWithPac(load_timing_info,
3014 CONNECT_TIMING_HAS_SSL_TIMES);
3015
3016 trans.reset();
3017 session->CloseAllConnections();
3018}
3019
3020// Test the request-challenge-retry sequence for basic auth, over a connection
3021// that requires a restart when setting up an SSL tunnel.
bncd16676a2016-07-20 16:23:013022TEST_F(HttpNetworkTransactionTest, BasicAuthProxyNoKeepAliveHttp11) {
[email protected]394816e92010-08-03 07:38:593023 HttpRequestInfo request;
3024 request.method = "GET";
bncce36dca22015-04-21 22:11:233025 request.url = GURL("https://www.example.org/");
[email protected]394816e92010-08-03 07:38:593026 // when the no authentication data flag is set.
ttuttle859dc7a2015-04-23 19:42:293027 request.load_flags = LOAD_DO_NOT_SEND_AUTH_DATA;
[email protected]394816e92010-08-03 07:38:593028
[email protected]cb9bf6ca2011-01-28 13:15:273029 // Configure against proxy server "myproxy:70".
rdsmith82957ad2015-09-16 19:42:033030 session_deps_.proxy_service =
3031 ProxyService::CreateFixedFromPacResult("PROXY myproxy:70");
vishal.b62985ca92015-04-17 08:45:513032 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:073033 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:093034 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:273035
[email protected]394816e92010-08-03 07:38:593036 // Since we have proxy, should try to establish tunnel.
3037 MockWrite data_writes1[] = {
mmenkee71e15332015-10-07 16:39:543038 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:173039 "Host: www.example.org:443\r\n"
mmenkee71e15332015-10-07 16:39:543040 "Proxy-Connection: keep-alive\r\n\r\n"),
mmenkee0b5c882015-08-26 20:29:113041 };
3042
mmenkee71e15332015-10-07 16:39:543043 // The proxy responds to the connect with a 407, using a non-persistent
mmenke0fd148d2015-09-30 23:00:083044 // connection.
3045 MockRead data_reads1[] = {
mmenkee71e15332015-10-07 16:39:543046 // No credentials.
3047 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
3048 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
3049 MockRead("Proxy-Connection: close\r\n\r\n"),
3050 };
mmenkee0b5c882015-08-26 20:29:113051
mmenkee71e15332015-10-07 16:39:543052 MockWrite data_writes2[] = {
3053 // After calling trans->RestartWithAuth(), this is the request we should
3054 // be issuing -- the final header line contains the credentials.
3055 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:173056 "Host: www.example.org:443\r\n"
mmenkee71e15332015-10-07 16:39:543057 "Proxy-Connection: keep-alive\r\n"
3058 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
mmenke0fd148d2015-09-30 23:00:083059
mmenkee71e15332015-10-07 16:39:543060 MockWrite("GET / HTTP/1.1\r\n"
3061 "Host: www.example.org\r\n"
3062 "Connection: keep-alive\r\n\r\n"),
3063 };
3064
3065 MockRead data_reads2[] = {
3066 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
3067
3068 MockRead("HTTP/1.1 200 OK\r\n"),
3069 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
3070 MockRead("Content-Length: 5\r\n\r\n"),
3071 MockRead(SYNCHRONOUS, "hello"),
[email protected]394816e92010-08-03 07:38:593072 };
3073
3074 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
3075 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:073076 session_deps_.socket_factory->AddSocketDataProvider(&data1);
mmenkee71e15332015-10-07 16:39:543077 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
3078 data_writes2, arraysize(data_writes2));
3079 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]8ddf8322012-02-23 18:08:063080 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:073081 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]394816e92010-08-03 07:38:593082
[email protected]49639fa2011-12-20 23:22:413083 TestCompletionCallback callback1;
[email protected]394816e92010-08-03 07:38:593084
bnc691fda62016-08-12 00:43:163085 std::unique_ptr<HttpNetworkTransaction> trans(
[email protected]90499482013-06-01 00:39:503086 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]0b0bf032010-09-21 18:08:503087
[email protected]49639fa2011-12-20 23:22:413088 int rv = trans->Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:013089 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]394816e92010-08-03 07:38:593090
3091 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:013092 EXPECT_THAT(rv, IsOk());
mmenke43758e62015-05-04 21:09:463093 TestNetLogEntry::List entries;
[email protected]b2fcd0e2010-12-01 15:19:403094 log.GetEntries(&entries);
[email protected]394816e92010-08-03 07:38:593095 size_t pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:003096 entries, 0, NetLogEventType::HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
3097 NetLogEventPhase::NONE);
[email protected]394816e92010-08-03 07:38:593098 ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:403099 entries, pos,
mikecirone8b85c432016-09-08 19:11:003100 NetLogEventType::HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
3101 NetLogEventPhase::NONE);
[email protected]394816e92010-08-03 07:38:593102
3103 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:523104 ASSERT_TRUE(response);
ttuttle34f63b52015-03-05 04:33:013105 EXPECT_FALSE(response->headers->IsKeepAlive());
wezca1070932016-05-26 20:30:523106 ASSERT_TRUE(response->headers);
[email protected]394816e92010-08-03 07:38:593107 EXPECT_EQ(407, response->headers->response_code());
3108 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
[email protected]79cb5c12011-09-12 13:12:043109 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
[email protected]394816e92010-08-03 07:38:593110
[email protected]029c83b62013-01-24 05:28:203111 LoadTimingInfo load_timing_info;
3112 // CONNECT requests and responses are handled at the connect job level, so
3113 // the transaction does not yet have a connection.
3114 EXPECT_FALSE(trans->GetLoadTimingInfo(&load_timing_info));
3115
[email protected]49639fa2011-12-20 23:22:413116 TestCompletionCallback callback2;
[email protected]394816e92010-08-03 07:38:593117
[email protected]49639fa2011-12-20 23:22:413118 rv = trans->RestartWithAuth(
3119 AuthCredentials(kFoo, kBar), callback2.callback());
robpercival214763f2016-07-01 23:27:013120 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]394816e92010-08-03 07:38:593121
3122 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:013123 EXPECT_THAT(rv, IsOk());
[email protected]394816e92010-08-03 07:38:593124
3125 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:523126 ASSERT_TRUE(response);
[email protected]394816e92010-08-03 07:38:593127
3128 EXPECT_TRUE(response->headers->IsKeepAlive());
3129 EXPECT_EQ(200, response->headers->response_code());
[email protected]0b0bf032010-09-21 18:08:503130 EXPECT_EQ(5, response->headers->GetContentLength());
[email protected]394816e92010-08-03 07:38:593131 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
3132
3133 // The password prompt info should not be set.
wezca1070932016-05-26 20:30:523134 EXPECT_FALSE(response->auth_challenge);
[email protected]0b0bf032010-09-21 18:08:503135
[email protected]029c83b62013-01-24 05:28:203136 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
3137 TestLoadTimingNotReusedWithPac(load_timing_info,
3138 CONNECT_TIMING_HAS_SSL_TIMES);
3139
[email protected]0b0bf032010-09-21 18:08:503140 trans.reset();
[email protected]102e27c2011-02-23 01:01:313141 session->CloseAllConnections();
[email protected]394816e92010-08-03 07:38:593142}
3143
[email protected]11203f012009-11-12 23:02:313144// Test the request-challenge-retry sequence for basic auth, over a keep-alive
ttuttle34f63b52015-03-05 04:33:013145// proxy connection with HTTP/1.0 responses, when setting up an SSL tunnel.
bncd16676a2016-07-20 16:23:013146TEST_F(HttpNetworkTransactionTest, BasicAuthProxyKeepAliveHttp10) {
mmenked39192ee2015-12-09 00:57:233147 // On the second pass, the body read of the auth challenge is synchronous, so
3148 // IsConnectedAndIdle returns false. The socket should still be drained and
3149 // reused. See http://crbug.com/544255.
3150 for (int i = 0; i < 2; ++i) {
3151 HttpRequestInfo request;
3152 request.method = "GET";
3153 request.url = GURL("https://www.example.org/");
3154 // Ensure that proxy authentication is attempted even
3155 // when the no authentication data flag is set.
3156 request.load_flags = LOAD_DO_NOT_SEND_AUTH_DATA;
ttuttle34f63b52015-03-05 04:33:013157
mmenked39192ee2015-12-09 00:57:233158 // Configure against proxy server "myproxy:70".
3159 session_deps_.proxy_service = ProxyService::CreateFixed("myproxy:70");
3160 BoundTestNetLog log;
3161 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:093162 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
ttuttle34f63b52015-03-05 04:33:013163
bnc691fda62016-08-12 00:43:163164 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
ttuttle34f63b52015-03-05 04:33:013165
mmenked39192ee2015-12-09 00:57:233166 // Since we have proxy, should try to establish tunnel.
3167 MockWrite data_writes1[] = {
3168 MockWrite(ASYNC, 0,
3169 "CONNECT www.example.org:443 HTTP/1.1\r\n"
3170 "Host: www.example.org:443\r\n"
3171 "Proxy-Connection: keep-alive\r\n\r\n"),
ttuttle34f63b52015-03-05 04:33:013172
bnc691fda62016-08-12 00:43:163173 // After calling trans.RestartWithAuth(), this is the request we should
mmenked39192ee2015-12-09 00:57:233174 // be issuing -- the final header line contains the credentials.
3175 MockWrite(ASYNC, 3,
3176 "CONNECT www.example.org:443 HTTP/1.1\r\n"
3177 "Host: www.example.org:443\r\n"
3178 "Proxy-Connection: keep-alive\r\n"
3179 "Proxy-Authorization: Basic Zm9vOmJheg==\r\n\r\n"),
3180 };
ttuttle34f63b52015-03-05 04:33:013181
mmenked39192ee2015-12-09 00:57:233182 // The proxy responds to the connect with a 407, using a persistent
3183 // connection. (Since it's HTTP/1.0, keep-alive has to be explicit.)
3184 MockRead data_reads1[] = {
3185 // No credentials.
3186 MockRead(ASYNC, 1,
3187 "HTTP/1.0 407 Proxy Authentication Required\r\n"
3188 "Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"
3189 "Proxy-Connection: keep-alive\r\n"
3190 "Content-Length: 10\r\n\r\n"),
3191 MockRead(i == 0 ? ASYNC : SYNCHRONOUS, 2, "0123456789"),
ttuttle34f63b52015-03-05 04:33:013192
mmenked39192ee2015-12-09 00:57:233193 // Wrong credentials (wrong password).
3194 MockRead(ASYNC, 4,
3195 "HTTP/1.0 407 Proxy Authentication Required\r\n"
3196 "Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"
3197 "Proxy-Connection: keep-alive\r\n"
3198 "Content-Length: 10\r\n\r\n"),
3199 // No response body because the test stops reading here.
3200 MockRead(SYNCHRONOUS, ERR_UNEXPECTED, 5),
3201 };
ttuttle34f63b52015-03-05 04:33:013202
mmenked39192ee2015-12-09 00:57:233203 SequencedSocketData data1(data_reads1, arraysize(data_reads1), data_writes1,
3204 arraysize(data_writes1));
3205 data1.set_busy_before_sync_reads(true);
3206 session_deps_.socket_factory->AddSocketDataProvider(&data1);
ttuttle34f63b52015-03-05 04:33:013207
mmenked39192ee2015-12-09 00:57:233208 TestCompletionCallback callback1;
ttuttle34f63b52015-03-05 04:33:013209
bnc691fda62016-08-12 00:43:163210 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:013211 EXPECT_THAT(callback1.GetResult(rv), IsOk());
ttuttle34f63b52015-03-05 04:33:013212
mmenked39192ee2015-12-09 00:57:233213 TestNetLogEntry::List entries;
3214 log.GetEntries(&entries);
3215 size_t pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:003216 entries, 0, NetLogEventType::HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
3217 NetLogEventPhase::NONE);
mmenked39192ee2015-12-09 00:57:233218 ExpectLogContainsSomewhere(
3219 entries, pos,
mikecirone8b85c432016-09-08 19:11:003220 NetLogEventType::HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
3221 NetLogEventPhase::NONE);
ttuttle34f63b52015-03-05 04:33:013222
bnc691fda62016-08-12 00:43:163223 const HttpResponseInfo* response = trans.GetResponseInfo();
mmenked39192ee2015-12-09 00:57:233224 ASSERT_TRUE(response);
3225 ASSERT_TRUE(response->headers);
3226 EXPECT_TRUE(response->headers->IsKeepAlive());
3227 EXPECT_EQ(407, response->headers->response_code());
3228 EXPECT_EQ(10, response->headers->GetContentLength());
3229 EXPECT_TRUE(HttpVersion(1, 0) == response->headers->GetHttpVersion());
3230 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
ttuttle34f63b52015-03-05 04:33:013231
mmenked39192ee2015-12-09 00:57:233232 TestCompletionCallback callback2;
ttuttle34f63b52015-03-05 04:33:013233
mmenked39192ee2015-12-09 00:57:233234 // Wrong password (should be "bar").
bnc691fda62016-08-12 00:43:163235 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBaz),
3236 callback2.callback());
robpercival214763f2016-07-01 23:27:013237 EXPECT_THAT(callback2.GetResult(rv), IsOk());
ttuttle34f63b52015-03-05 04:33:013238
bnc691fda62016-08-12 00:43:163239 response = trans.GetResponseInfo();
mmenked39192ee2015-12-09 00:57:233240 ASSERT_TRUE(response);
3241 ASSERT_TRUE(response->headers);
3242 EXPECT_TRUE(response->headers->IsKeepAlive());
3243 EXPECT_EQ(407, response->headers->response_code());
3244 EXPECT_EQ(10, response->headers->GetContentLength());
3245 EXPECT_TRUE(HttpVersion(1, 0) == response->headers->GetHttpVersion());
3246 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
ttuttle34f63b52015-03-05 04:33:013247
mmenked39192ee2015-12-09 00:57:233248 // Flush the idle socket before the NetLog and HttpNetworkTransaction go
3249 // out of scope.
3250 session->CloseAllConnections();
3251 }
ttuttle34f63b52015-03-05 04:33:013252}
3253
3254// Test the request-challenge-retry sequence for basic auth, over a keep-alive
3255// proxy connection with HTTP/1.1 responses, when setting up an SSL tunnel.
bncd16676a2016-07-20 16:23:013256TEST_F(HttpNetworkTransactionTest, BasicAuthProxyKeepAliveHttp11) {
mmenked39192ee2015-12-09 00:57:233257 // On the second pass, the body read of the auth challenge is synchronous, so
3258 // IsConnectedAndIdle returns false. The socket should still be drained and
3259 // reused. See http://crbug.com/544255.
3260 for (int i = 0; i < 2; ++i) {
3261 HttpRequestInfo request;
3262 request.method = "GET";
3263 request.url = GURL("https://www.example.org/");
3264 // Ensure that proxy authentication is attempted even
3265 // when the no authentication data flag is set.
3266 request.load_flags = LOAD_DO_NOT_SEND_AUTH_DATA;
3267
3268 // Configure against proxy server "myproxy:70".
3269 session_deps_.proxy_service = ProxyService::CreateFixed("myproxy:70");
3270 BoundTestNetLog log;
3271 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:093272 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
mmenked39192ee2015-12-09 00:57:233273
bnc691fda62016-08-12 00:43:163274 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
mmenked39192ee2015-12-09 00:57:233275
3276 // Since we have proxy, should try to establish tunnel.
3277 MockWrite data_writes1[] = {
3278 MockWrite(ASYNC, 0,
3279 "CONNECT www.example.org:443 HTTP/1.1\r\n"
3280 "Host: www.example.org:443\r\n"
3281 "Proxy-Connection: keep-alive\r\n\r\n"),
3282
bnc691fda62016-08-12 00:43:163283 // After calling trans.RestartWithAuth(), this is the request we should
mmenked39192ee2015-12-09 00:57:233284 // be issuing -- the final header line contains the credentials.
3285 MockWrite(ASYNC, 3,
3286 "CONNECT www.example.org:443 HTTP/1.1\r\n"
3287 "Host: www.example.org:443\r\n"
3288 "Proxy-Connection: keep-alive\r\n"
3289 "Proxy-Authorization: Basic Zm9vOmJheg==\r\n\r\n"),
3290 };
3291
3292 // The proxy responds to the connect with a 407, using a persistent
3293 // connection. (Since it's HTTP/1.0, keep-alive has to be explicit.)
3294 MockRead data_reads1[] = {
3295 // No credentials.
3296 MockRead(ASYNC, 1,
3297 "HTTP/1.1 407 Proxy Authentication Required\r\n"
3298 "Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"
3299 "Content-Length: 10\r\n\r\n"),
3300 MockRead(i == 0 ? ASYNC : SYNCHRONOUS, 2, "0123456789"),
3301
3302 // Wrong credentials (wrong password).
3303 MockRead(ASYNC, 4,
3304 "HTTP/1.1 407 Proxy Authentication Required\r\n"
3305 "Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"
3306 "Content-Length: 10\r\n\r\n"),
3307 // No response body because the test stops reading here.
3308 MockRead(SYNCHRONOUS, ERR_UNEXPECTED, 5),
3309 };
3310
3311 SequencedSocketData data1(data_reads1, arraysize(data_reads1), data_writes1,
3312 arraysize(data_writes1));
3313 data1.set_busy_before_sync_reads(true);
3314 session_deps_.socket_factory->AddSocketDataProvider(&data1);
3315
3316 TestCompletionCallback callback1;
3317
bnc691fda62016-08-12 00:43:163318 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:013319 EXPECT_THAT(callback1.GetResult(rv), IsOk());
mmenked39192ee2015-12-09 00:57:233320
3321 TestNetLogEntry::List entries;
3322 log.GetEntries(&entries);
3323 size_t pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:003324 entries, 0, NetLogEventType::HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
3325 NetLogEventPhase::NONE);
mmenked39192ee2015-12-09 00:57:233326 ExpectLogContainsSomewhere(
3327 entries, pos,
mikecirone8b85c432016-09-08 19:11:003328 NetLogEventType::HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
3329 NetLogEventPhase::NONE);
mmenked39192ee2015-12-09 00:57:233330
bnc691fda62016-08-12 00:43:163331 const HttpResponseInfo* response = trans.GetResponseInfo();
mmenked39192ee2015-12-09 00:57:233332 ASSERT_TRUE(response);
3333 ASSERT_TRUE(response->headers);
3334 EXPECT_TRUE(response->headers->IsKeepAlive());
3335 EXPECT_EQ(407, response->headers->response_code());
3336 EXPECT_EQ(10, response->headers->GetContentLength());
3337 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
3338 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
3339
3340 TestCompletionCallback callback2;
3341
3342 // Wrong password (should be "bar").
bnc691fda62016-08-12 00:43:163343 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBaz),
3344 callback2.callback());
robpercival214763f2016-07-01 23:27:013345 EXPECT_THAT(callback2.GetResult(rv), IsOk());
mmenked39192ee2015-12-09 00:57:233346
bnc691fda62016-08-12 00:43:163347 response = trans.GetResponseInfo();
mmenked39192ee2015-12-09 00:57:233348 ASSERT_TRUE(response);
3349 ASSERT_TRUE(response->headers);
3350 EXPECT_TRUE(response->headers->IsKeepAlive());
3351 EXPECT_EQ(407, response->headers->response_code());
3352 EXPECT_EQ(10, response->headers->GetContentLength());
3353 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
3354 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
3355
3356 // Flush the idle socket before the NetLog and HttpNetworkTransaction go
3357 // out of scope.
3358 session->CloseAllConnections();
3359 }
3360}
3361
3362// Test the request-challenge-retry sequence for basic auth, over a keep-alive
3363// proxy connection with HTTP/1.1 responses, when setting up an SSL tunnel, in
3364// the case the server sends extra data on the original socket, so it can't be
3365// reused.
bncd16676a2016-07-20 16:23:013366TEST_F(HttpNetworkTransactionTest, BasicAuthProxyKeepAliveExtraData) {
[email protected]cb9bf6ca2011-01-28 13:15:273367 HttpRequestInfo request;
3368 request.method = "GET";
bncce36dca22015-04-21 22:11:233369 request.url = GURL("https://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:273370 // when the no authentication data flag is set.
ttuttle859dc7a2015-04-23 19:42:293371 request.load_flags = LOAD_DO_NOT_SEND_AUTH_DATA;
[email protected]cb9bf6ca2011-01-28 13:15:273372
[email protected]2d2697f92009-02-18 21:00:323373 // Configure against proxy server "myproxy:70".
mmenked39192ee2015-12-09 00:57:233374 session_deps_.proxy_service =
3375 ProxyService::CreateFixedFromPacResult("PROXY myproxy:70");
vishal.b62985ca92015-04-17 08:45:513376 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:073377 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:093378 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]2d2697f92009-02-18 21:00:323379
[email protected]2d2697f92009-02-18 21:00:323380 // Since we have proxy, should try to establish tunnel.
3381 MockWrite data_writes1[] = {
mmenked39192ee2015-12-09 00:57:233382 MockWrite(ASYNC, 0,
3383 "CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:173384 "Host: www.example.org:443\r\n"
3385 "Proxy-Connection: keep-alive\r\n\r\n"),
mmenked39192ee2015-12-09 00:57:233386 };
[email protected]2d2697f92009-02-18 21:00:323387
mmenked39192ee2015-12-09 00:57:233388 // The proxy responds to the connect with a 407, using a persistent, but sends
3389 // extra data, so the socket cannot be reused.
3390 MockRead data_reads1[] = {
3391 // No credentials.
3392 MockRead(ASYNC, 1,
3393 "HTTP/1.1 407 Proxy Authentication Required\r\n"
3394 "Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"
3395 "Content-Length: 10\r\n\r\n"),
3396 MockRead(SYNCHRONOUS, 2, "0123456789"),
3397 MockRead(SYNCHRONOUS, 3, "I'm broken!"),
3398 };
3399
3400 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:233401 // After calling trans->RestartWithAuth(), this is the request we should
3402 // be issuing -- the final header line contains the credentials.
mmenked39192ee2015-12-09 00:57:233403 MockWrite(ASYNC, 0,
3404 "CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:173405 "Host: www.example.org:443\r\n"
3406 "Proxy-Connection: keep-alive\r\n"
mmenked39192ee2015-12-09 00:57:233407 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
3408
3409 MockWrite(ASYNC, 2,
3410 "GET / HTTP/1.1\r\n"
3411 "Host: www.example.org\r\n"
3412 "Connection: keep-alive\r\n\r\n"),
[email protected]2d2697f92009-02-18 21:00:323413 };
3414
mmenked39192ee2015-12-09 00:57:233415 MockRead data_reads2[] = {
3416 MockRead(ASYNC, 1, "HTTP/1.1 200 Connection Established\r\n\r\n"),
[email protected]2d2697f92009-02-18 21:00:323417
mmenked39192ee2015-12-09 00:57:233418 MockRead(ASYNC, 3,
3419 "HTTP/1.1 200 OK\r\n"
3420 "Content-Type: text/html; charset=iso-8859-1\r\n"
3421 "Content-Length: 5\r\n\r\n"),
3422 // No response body because the test stops reading here.
3423 MockRead(SYNCHRONOUS, ERR_UNEXPECTED, 4),
[email protected]2d2697f92009-02-18 21:00:323424 };
3425
mmenked39192ee2015-12-09 00:57:233426 SequencedSocketData data1(data_reads1, arraysize(data_reads1), data_writes1,
3427 arraysize(data_writes1));
3428 data1.set_busy_before_sync_reads(true);
[email protected]bb88e1d32013-05-03 23:11:073429 session_deps_.socket_factory->AddSocketDataProvider(&data1);
mmenked39192ee2015-12-09 00:57:233430 SequencedSocketData data2(data_reads2, arraysize(data_reads2), data_writes2,
3431 arraysize(data_writes2));
3432 session_deps_.socket_factory->AddSocketDataProvider(&data2);
3433 SSLSocketDataProvider ssl(ASYNC, OK);
3434 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]2d2697f92009-02-18 21:00:323435
[email protected]49639fa2011-12-20 23:22:413436 TestCompletionCallback callback1;
[email protected]2d2697f92009-02-18 21:00:323437
bnc691fda62016-08-12 00:43:163438 std::unique_ptr<HttpNetworkTransaction> trans(
mmenked39192ee2015-12-09 00:57:233439 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]2d2697f92009-02-18 21:00:323440
mmenked39192ee2015-12-09 00:57:233441 int rv = trans->Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:013442 EXPECT_THAT(callback1.GetResult(rv), IsOk());
mmenked39192ee2015-12-09 00:57:233443
mmenke43758e62015-05-04 21:09:463444 TestNetLogEntry::List entries;
[email protected]b2fcd0e2010-12-01 15:19:403445 log.GetEntries(&entries);
[email protected]dbb83db2010-05-11 18:13:393446 size_t pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:003447 entries, 0, NetLogEventType::HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
3448 NetLogEventPhase::NONE);
[email protected]dbb83db2010-05-11 18:13:393449 ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:403450 entries, pos,
mikecirone8b85c432016-09-08 19:11:003451 NetLogEventType::HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
3452 NetLogEventPhase::NONE);
[email protected]2d2697f92009-02-18 21:00:323453
[email protected]1c773ea12009-04-28 19:58:423454 const HttpResponseInfo* response = trans->GetResponseInfo();
ttuttle7933c112015-01-06 00:55:243455 ASSERT_TRUE(response);
3456 ASSERT_TRUE(response->headers);
[email protected]2d2697f92009-02-18 21:00:323457 EXPECT_TRUE(response->headers->IsKeepAlive());
3458 EXPECT_EQ(407, response->headers->response_code());
[email protected]1c773ea12009-04-28 19:58:423459 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
[email protected]79cb5c12011-09-12 13:12:043460 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
[email protected]2d2697f92009-02-18 21:00:323461
mmenked39192ee2015-12-09 00:57:233462 LoadTimingInfo load_timing_info;
3463 // CONNECT requests and responses are handled at the connect job level, so
3464 // the transaction does not yet have a connection.
3465 EXPECT_FALSE(trans->GetLoadTimingInfo(&load_timing_info));
3466
[email protected]49639fa2011-12-20 23:22:413467 TestCompletionCallback callback2;
[email protected]2d2697f92009-02-18 21:00:323468
mmenked39192ee2015-12-09 00:57:233469 rv =
3470 trans->RestartWithAuth(AuthCredentials(kFoo, kBar), callback2.callback());
robpercival214763f2016-07-01 23:27:013471 EXPECT_THAT(callback2.GetResult(rv), IsOk());
[email protected]2d2697f92009-02-18 21:00:323472
[email protected]2d2697f92009-02-18 21:00:323473 EXPECT_TRUE(response->headers->IsKeepAlive());
mmenked39192ee2015-12-09 00:57:233474 EXPECT_EQ(200, response->headers->response_code());
3475 EXPECT_EQ(5, response->headers->GetContentLength());
[email protected]1c773ea12009-04-28 19:58:423476 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
[email protected]e772db3f2010-07-12 18:11:133477
mmenked39192ee2015-12-09 00:57:233478 // The password prompt info should not be set.
3479 EXPECT_FALSE(response->auth_challenge);
3480
3481 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
3482 TestLoadTimingNotReusedWithPac(load_timing_info,
3483 CONNECT_TIMING_HAS_SSL_TIMES);
3484
3485 trans.reset();
[email protected]102e27c2011-02-23 01:01:313486 session->CloseAllConnections();
[email protected]2d2697f92009-02-18 21:00:323487}
3488
mmenkee71e15332015-10-07 16:39:543489// Test the case a proxy closes a socket while the challenge body is being
3490// drained.
bncd16676a2016-07-20 16:23:013491TEST_F(HttpNetworkTransactionTest, BasicAuthProxyKeepAliveHangupDuringBody) {
mmenkee71e15332015-10-07 16:39:543492 HttpRequestInfo request;
3493 request.method = "GET";
3494 request.url = GURL("https://www.example.org/");
3495 // Ensure that proxy authentication is attempted even
3496 // when the no authentication data flag is set.
3497 request.load_flags = LOAD_DO_NOT_SEND_AUTH_DATA;
3498
3499 // Configure against proxy server "myproxy:70".
3500 session_deps_.proxy_service = ProxyService::CreateFixed("myproxy:70");
danakj1fd259a02016-04-16 03:17:093501 std::unique_ptr<HttpNetworkSession> session = CreateSession(&session_deps_);
mmenkee71e15332015-10-07 16:39:543502
bnc691fda62016-08-12 00:43:163503 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
mmenkee71e15332015-10-07 16:39:543504
3505 // Since we have proxy, should try to establish tunnel.
3506 MockWrite data_writes1[] = {
3507 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:173508 "Host: www.example.org:443\r\n"
mmenkee71e15332015-10-07 16:39:543509 "Proxy-Connection: keep-alive\r\n\r\n"),
3510 };
3511
3512 // The proxy responds to the connect with a 407, using a persistent
3513 // connection.
3514 MockRead data_reads1[] = {
3515 // No credentials.
3516 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
3517 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
3518 MockRead("Content-Length: 10\r\n\r\n"), MockRead("spam!"),
3519 // Server hands up in the middle of the body.
3520 MockRead(ASYNC, ERR_CONNECTION_CLOSED),
3521 };
3522
3523 MockWrite data_writes2[] = {
bnc691fda62016-08-12 00:43:163524 // After calling trans.RestartWithAuth(), this is the request we should
mmenkee71e15332015-10-07 16:39:543525 // be issuing -- the final header line contains the credentials.
3526 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:173527 "Host: www.example.org:443\r\n"
mmenkee71e15332015-10-07 16:39:543528 "Proxy-Connection: keep-alive\r\n"
3529 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
3530
3531 MockWrite("GET / HTTP/1.1\r\n"
3532 "Host: www.example.org\r\n"
3533 "Connection: keep-alive\r\n\r\n"),
3534 };
3535
3536 MockRead data_reads2[] = {
3537 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
3538
3539 MockRead("HTTP/1.1 200 OK\r\n"),
3540 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
3541 MockRead("Content-Length: 5\r\n\r\n"),
3542 MockRead(SYNCHRONOUS, "hello"),
3543 };
3544
3545 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
3546 data_writes1, arraysize(data_writes1));
3547 session_deps_.socket_factory->AddSocketDataProvider(&data1);
3548 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
3549 data_writes2, arraysize(data_writes2));
3550 session_deps_.socket_factory->AddSocketDataProvider(&data2);
3551 SSLSocketDataProvider ssl(ASYNC, OK);
3552 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
3553
3554 TestCompletionCallback callback;
3555
tfarina42834112016-09-22 13:38:203556 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:013557 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenkee71e15332015-10-07 16:39:543558
bnc691fda62016-08-12 00:43:163559 const HttpResponseInfo* response = trans.GetResponseInfo();
mmenkee71e15332015-10-07 16:39:543560 ASSERT_TRUE(response);
3561 ASSERT_TRUE(response->headers);
3562 EXPECT_TRUE(response->headers->IsKeepAlive());
3563 EXPECT_EQ(407, response->headers->response_code());
3564 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
3565
bnc691fda62016-08-12 00:43:163566 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar), callback.callback());
robpercival214763f2016-07-01 23:27:013567 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenkee71e15332015-10-07 16:39:543568
bnc691fda62016-08-12 00:43:163569 response = trans.GetResponseInfo();
mmenkee71e15332015-10-07 16:39:543570 ASSERT_TRUE(response);
3571 ASSERT_TRUE(response->headers);
3572 EXPECT_TRUE(response->headers->IsKeepAlive());
3573 EXPECT_EQ(200, response->headers->response_code());
3574 std::string body;
bnc691fda62016-08-12 00:43:163575 EXPECT_THAT(ReadTransaction(&trans, &body), IsOk());
mmenkee71e15332015-10-07 16:39:543576 EXPECT_EQ("hello", body);
3577}
3578
[email protected]a8e9b162009-03-12 00:06:443579// Test that we don't read the response body when we fail to establish a tunnel,
3580// even if the user cancels the proxy's auth attempt.
bncd16676a2016-07-20 16:23:013581TEST_F(HttpNetworkTransactionTest, BasicAuthProxyCancelTunnel) {
[email protected]cb9bf6ca2011-01-28 13:15:273582 HttpRequestInfo request;
3583 request.method = "GET";
bncce36dca22015-04-21 22:11:233584 request.url = GURL("https://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:273585
[email protected]a8e9b162009-03-12 00:06:443586 // Configure against proxy server "myproxy:70".
rdsmith82957ad2015-09-16 19:42:033587 session_deps_.proxy_service = ProxyService::CreateFixed("myproxy:70");
[email protected]a8e9b162009-03-12 00:06:443588
danakj1fd259a02016-04-16 03:17:093589 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]a8e9b162009-03-12 00:06:443590
bnc691fda62016-08-12 00:43:163591 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]a8e9b162009-03-12 00:06:443592
[email protected]a8e9b162009-03-12 00:06:443593 // Since we have proxy, should try to establish tunnel.
3594 MockWrite data_writes[] = {
rsleevidb16bb02015-11-12 23:47:173595 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
3596 "Host: www.example.org:443\r\n"
3597 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]a8e9b162009-03-12 00:06:443598 };
3599
3600 // The proxy responds to the connect with a 407.
3601 MockRead data_reads[] = {
ttuttle7933c112015-01-06 00:55:243602 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
3603 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
3604 MockRead("Content-Length: 10\r\n\r\n"),
mmenked39192ee2015-12-09 00:57:233605 MockRead("0123456789"),
ttuttle7933c112015-01-06 00:55:243606 MockRead(SYNCHRONOUS, ERR_UNEXPECTED),
[email protected]a8e9b162009-03-12 00:06:443607 };
3608
[email protected]31a2bfe2010-02-09 08:03:393609 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
3610 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:073611 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]a8e9b162009-03-12 00:06:443612
[email protected]49639fa2011-12-20 23:22:413613 TestCompletionCallback callback;
[email protected]a8e9b162009-03-12 00:06:443614
tfarina42834112016-09-22 13:38:203615 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:013616 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]a8e9b162009-03-12 00:06:443617
3618 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:013619 EXPECT_THAT(rv, IsOk());
[email protected]a8e9b162009-03-12 00:06:443620
bnc691fda62016-08-12 00:43:163621 const HttpResponseInfo* response = trans.GetResponseInfo();
ttuttle7933c112015-01-06 00:55:243622 ASSERT_TRUE(response);
3623 ASSERT_TRUE(response->headers);
[email protected]a8e9b162009-03-12 00:06:443624 EXPECT_TRUE(response->headers->IsKeepAlive());
3625 EXPECT_EQ(407, response->headers->response_code());
[email protected]1c773ea12009-04-28 19:58:423626 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
[email protected]a8e9b162009-03-12 00:06:443627
3628 std::string response_data;
bnc691fda62016-08-12 00:43:163629 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:013630 EXPECT_THAT(rv, IsError(ERR_TUNNEL_CONNECTION_FAILED));
[email protected]e60e47a2010-07-14 03:37:183631
3632 // Flush the idle socket before the HttpNetworkTransaction goes out of scope.
[email protected]102e27c2011-02-23 01:01:313633 session->CloseAllConnections();
[email protected]a8e9b162009-03-12 00:06:443634}
3635
ttuttle7933c112015-01-06 00:55:243636// Test that we don't pass extraneous headers from the proxy's response to the
3637// caller when the proxy responds to CONNECT with 407.
bncd16676a2016-07-20 16:23:013638TEST_F(HttpNetworkTransactionTest, SanitizeProxyAuthHeaders) {
ttuttle7933c112015-01-06 00:55:243639 HttpRequestInfo request;
3640 request.method = "GET";
bncce36dca22015-04-21 22:11:233641 request.url = GURL("https://www.example.org/");
ttuttle7933c112015-01-06 00:55:243642
3643 // Configure against proxy server "myproxy:70".
rdsmith82957ad2015-09-16 19:42:033644 session_deps_.proxy_service = ProxyService::CreateFixed("myproxy:70");
ttuttle7933c112015-01-06 00:55:243645
danakj1fd259a02016-04-16 03:17:093646 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
ttuttle7933c112015-01-06 00:55:243647
bnc691fda62016-08-12 00:43:163648 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
ttuttle7933c112015-01-06 00:55:243649
3650 // Since we have proxy, should try to establish tunnel.
3651 MockWrite data_writes[] = {
rsleevidb16bb02015-11-12 23:47:173652 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
3653 "Host: www.example.org:443\r\n"
3654 "Proxy-Connection: keep-alive\r\n\r\n"),
ttuttle7933c112015-01-06 00:55:243655 };
3656
3657 // The proxy responds to the connect with a 407.
3658 MockRead data_reads[] = {
3659 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
3660 MockRead("X-Foo: bar\r\n"),
3661 MockRead("Set-Cookie: foo=bar\r\n"),
3662 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
3663 MockRead("Content-Length: 10\r\n\r\n"),
mmenked39192ee2015-12-09 00:57:233664 MockRead(SYNCHRONOUS, ERR_UNEXPECTED),
ttuttle7933c112015-01-06 00:55:243665 };
3666
3667 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
3668 arraysize(data_writes));
3669 session_deps_.socket_factory->AddSocketDataProvider(&data);
3670
3671 TestCompletionCallback callback;
3672
tfarina42834112016-09-22 13:38:203673 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:013674 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
ttuttle7933c112015-01-06 00:55:243675
3676 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:013677 EXPECT_THAT(rv, IsOk());
ttuttle7933c112015-01-06 00:55:243678
bnc691fda62016-08-12 00:43:163679 const HttpResponseInfo* response = trans.GetResponseInfo();
ttuttle7933c112015-01-06 00:55:243680 ASSERT_TRUE(response);
3681 ASSERT_TRUE(response->headers);
3682 EXPECT_TRUE(response->headers->IsKeepAlive());
3683 EXPECT_EQ(407, response->headers->response_code());
3684 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
3685 EXPECT_FALSE(response->headers->HasHeader("X-Foo"));
3686 EXPECT_FALSE(response->headers->HasHeader("Set-Cookie"));
3687
3688 std::string response_data;
bnc691fda62016-08-12 00:43:163689 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:013690 EXPECT_THAT(rv, IsError(ERR_TUNNEL_CONNECTION_FAILED));
ttuttle7933c112015-01-06 00:55:243691
3692 // Flush the idle socket before the HttpNetworkTransaction goes out of scope.
3693 session->CloseAllConnections();
3694}
3695
[email protected]8fdbcd22010-05-05 02:54:523696// Test when a server (non-proxy) returns a 407 (proxy-authenticate).
3697// The request should fail with ERR_UNEXPECTED_PROXY_AUTH.
bncd16676a2016-07-20 16:23:013698TEST_F(HttpNetworkTransactionTest, UnexpectedProxyAuth) {
[email protected]8fdbcd22010-05-05 02:54:523699 HttpRequestInfo request;
3700 request.method = "GET";
bncce36dca22015-04-21 22:11:233701 request.url = GURL("http://www.example.org/");
[email protected]8fdbcd22010-05-05 02:54:523702
[email protected]cb9bf6ca2011-01-28 13:15:273703 // We are using a DIRECT connection (i.e. no proxy) for this session.
danakj1fd259a02016-04-16 03:17:093704 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:163705 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:273706
[email protected]8fdbcd22010-05-05 02:54:523707 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:233708 MockWrite(
3709 "GET / HTTP/1.1\r\n"
3710 "Host: www.example.org\r\n"
3711 "Connection: keep-alive\r\n\r\n"),
[email protected]8fdbcd22010-05-05 02:54:523712 };
3713
3714 MockRead data_reads1[] = {
3715 MockRead("HTTP/1.0 407 Proxy Auth required\r\n"),
3716 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
3717 // Large content-length -- won't matter, as connection will be reset.
3718 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:063719 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]8fdbcd22010-05-05 02:54:523720 };
3721
3722 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
3723 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:073724 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8fdbcd22010-05-05 02:54:523725
[email protected]49639fa2011-12-20 23:22:413726 TestCompletionCallback callback;
[email protected]8fdbcd22010-05-05 02:54:523727
tfarina42834112016-09-22 13:38:203728 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:013729 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]8fdbcd22010-05-05 02:54:523730
3731 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:013732 EXPECT_THAT(rv, IsError(ERR_UNEXPECTED_PROXY_AUTH));
[email protected]8fdbcd22010-05-05 02:54:523733}
3734
[email protected]7a67a8152010-11-05 18:31:103735// Tests when an HTTPS server (non-proxy) returns a 407 (proxy-authentication)
3736// through a non-authenticating proxy. The request should fail with
3737// ERR_UNEXPECTED_PROXY_AUTH.
3738// Note that it is impossible to detect if an HTTP server returns a 407 through
3739// a non-authenticating proxy - there is nothing to indicate whether the
3740// response came from the proxy or the server, so it is treated as if the proxy
3741// issued the challenge.
bncd16676a2016-07-20 16:23:013742TEST_F(HttpNetworkTransactionTest, HttpsServerRequestsProxyAuthThroughProxy) {
[email protected]cb9bf6ca2011-01-28 13:15:273743 HttpRequestInfo request;
3744 request.method = "GET";
bncce36dca22015-04-21 22:11:233745 request.url = GURL("https://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:273746
rdsmith82957ad2015-09-16 19:42:033747 session_deps_.proxy_service = ProxyService::CreateFixed("myproxy:70");
vishal.b62985ca92015-04-17 08:45:513748 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:073749 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:093750 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]7a67a8152010-11-05 18:31:103751
[email protected]7a67a8152010-11-05 18:31:103752 // Since we have proxy, should try to establish tunnel.
3753 MockWrite data_writes1[] = {
rsleevidb16bb02015-11-12 23:47:173754 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
3755 "Host: www.example.org:443\r\n"
3756 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]7a67a8152010-11-05 18:31:103757
rsleevidb16bb02015-11-12 23:47:173758 MockWrite("GET / HTTP/1.1\r\n"
3759 "Host: www.example.org\r\n"
3760 "Connection: keep-alive\r\n\r\n"),
[email protected]7a67a8152010-11-05 18:31:103761 };
3762
3763 MockRead data_reads1[] = {
3764 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
3765
3766 MockRead("HTTP/1.1 407 Unauthorized\r\n"),
3767 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
3768 MockRead("\r\n"),
[email protected]8ddf8322012-02-23 18:08:063769 MockRead(SYNCHRONOUS, OK),
[email protected]7a67a8152010-11-05 18:31:103770 };
3771
3772 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
3773 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:073774 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8ddf8322012-02-23 18:08:063775 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:073776 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]7a67a8152010-11-05 18:31:103777
[email protected]49639fa2011-12-20 23:22:413778 TestCompletionCallback callback1;
[email protected]7a67a8152010-11-05 18:31:103779
bnc691fda62016-08-12 00:43:163780 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]7a67a8152010-11-05 18:31:103781
bnc691fda62016-08-12 00:43:163782 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:013783 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]7a67a8152010-11-05 18:31:103784
3785 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:013786 EXPECT_THAT(rv, IsError(ERR_UNEXPECTED_PROXY_AUTH));
mmenke43758e62015-05-04 21:09:463787 TestNetLogEntry::List entries;
[email protected]b2fcd0e2010-12-01 15:19:403788 log.GetEntries(&entries);
[email protected]7a67a8152010-11-05 18:31:103789 size_t pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:003790 entries, 0, NetLogEventType::HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
3791 NetLogEventPhase::NONE);
[email protected]7a67a8152010-11-05 18:31:103792 ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:403793 entries, pos,
mikecirone8b85c432016-09-08 19:11:003794 NetLogEventType::HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
3795 NetLogEventPhase::NONE);
[email protected]7a67a8152010-11-05 18:31:103796}
[email protected]2df19bb2010-08-25 20:13:463797
mmenke2a1781d2015-10-07 19:25:333798// Test a proxy auth scheme that allows default credentials and a proxy server
3799// that uses non-persistent connections.
bncd16676a2016-07-20 16:23:013800TEST_F(HttpNetworkTransactionTest,
mmenke2a1781d2015-10-07 19:25:333801 AuthAllowsDefaultCredentialsTunnelConnectionClose) {
3802 HttpRequestInfo request;
3803 request.method = "GET";
3804 request.url = GURL("https://www.example.org/");
3805
3806 // Configure against proxy server "myproxy:70".
3807 session_deps_.proxy_service =
3808 ProxyService::CreateFixedFromPacResult("PROXY myproxy:70");
3809
danakj1fd259a02016-04-16 03:17:093810 std::unique_ptr<HttpAuthHandlerMock::Factory> auth_handler_factory(
mmenke2a1781d2015-10-07 19:25:333811 new HttpAuthHandlerMock::Factory());
3812 auth_handler_factory->set_do_init_from_challenge(true);
danakj1fd259a02016-04-16 03:17:093813 std::unique_ptr<HttpAuthHandlerMock> mock_handler(new HttpAuthHandlerMock());
mmenke2a1781d2015-10-07 19:25:333814 mock_handler->set_allows_default_credentials(true);
3815 auth_handler_factory->AddMockHandler(mock_handler.release(),
3816 HttpAuth::AUTH_PROXY);
dchengc7eeda422015-12-26 03:56:483817 session_deps_.http_auth_handler_factory = std::move(auth_handler_factory);
mmenke2a1781d2015-10-07 19:25:333818
3819 // Add NetLog just so can verify load timing information gets a NetLog ID.
3820 NetLog net_log;
3821 session_deps_.net_log = &net_log;
danakj1fd259a02016-04-16 03:17:093822 std::unique_ptr<HttpNetworkSession> session = CreateSession(&session_deps_);
mmenke2a1781d2015-10-07 19:25:333823
3824 // Since we have proxy, should try to establish tunnel.
3825 MockWrite data_writes1[] = {
3826 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:173827 "Host: www.example.org:443\r\n"
mmenke2a1781d2015-10-07 19:25:333828 "Proxy-Connection: keep-alive\r\n\r\n"),
3829 };
3830
3831 // The proxy responds to the connect with a 407, using a non-persistent
3832 // connection.
3833 MockRead data_reads1[] = {
3834 // No credentials.
3835 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
3836 MockRead("Proxy-Authenticate: Mock\r\n"),
3837 MockRead("Proxy-Connection: close\r\n\r\n"),
3838 };
3839
3840 // Since the first connection couldn't be reused, need to establish another
3841 // once given credentials.
3842 MockWrite data_writes2[] = {
3843 // After calling trans->RestartWithAuth(), this is the request we should
3844 // be issuing -- the final header line contains the credentials.
3845 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:173846 "Host: www.example.org:443\r\n"
mmenke2a1781d2015-10-07 19:25:333847 "Proxy-Connection: keep-alive\r\n"
3848 "Proxy-Authorization: auth_token\r\n\r\n"),
3849
3850 MockWrite("GET / HTTP/1.1\r\n"
3851 "Host: www.example.org\r\n"
3852 "Connection: keep-alive\r\n\r\n"),
3853 };
3854
3855 MockRead data_reads2[] = {
3856 MockRead("HTTP/1.0 200 Connection Established\r\n\r\n"),
3857
3858 MockRead("HTTP/1.1 200 OK\r\n"),
3859 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
3860 MockRead("Content-Length: 5\r\n\r\n"),
3861 MockRead(SYNCHRONOUS, "hello"),
3862 };
3863
3864 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
3865 data_writes1, arraysize(data_writes1));
3866 session_deps_.socket_factory->AddSocketDataProvider(&data1);
3867 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
3868 data_writes2, arraysize(data_writes2));
3869 session_deps_.socket_factory->AddSocketDataProvider(&data2);
3870 SSLSocketDataProvider ssl(ASYNC, OK);
3871 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
3872
bnc691fda62016-08-12 00:43:163873 std::unique_ptr<HttpNetworkTransaction> trans(
mmenke2a1781d2015-10-07 19:25:333874 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
3875
3876 TestCompletionCallback callback;
tfarina42834112016-09-22 13:38:203877 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:013878 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenke2a1781d2015-10-07 19:25:333879
3880 const HttpResponseInfo* response = trans->GetResponseInfo();
3881 ASSERT_TRUE(response);
3882 ASSERT_TRUE(response->headers);
3883 EXPECT_FALSE(response->headers->IsKeepAlive());
3884 EXPECT_EQ(407, response->headers->response_code());
3885 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
3886 EXPECT_TRUE(trans->IsReadyToRestartForAuth());
wezca1070932016-05-26 20:30:523887 EXPECT_FALSE(response->auth_challenge);
mmenke2a1781d2015-10-07 19:25:333888
3889 LoadTimingInfo load_timing_info;
3890 // CONNECT requests and responses are handled at the connect job level, so
3891 // the transaction does not yet have a connection.
3892 EXPECT_FALSE(trans->GetLoadTimingInfo(&load_timing_info));
3893
3894 rv = trans->RestartWithAuth(AuthCredentials(), callback.callback());
robpercival214763f2016-07-01 23:27:013895 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenke2a1781d2015-10-07 19:25:333896 response = trans->GetResponseInfo();
3897 ASSERT_TRUE(response);
3898 ASSERT_TRUE(response->headers);
3899 EXPECT_TRUE(response->headers->IsKeepAlive());
3900 EXPECT_EQ(200, response->headers->response_code());
3901 EXPECT_EQ(5, response->headers->GetContentLength());
3902 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
3903
3904 // The password prompt info should not be set.
3905 EXPECT_FALSE(response->auth_challenge);
3906
3907 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
3908 TestLoadTimingNotReusedWithPac(load_timing_info,
3909 CONNECT_TIMING_HAS_SSL_TIMES);
3910
3911 trans.reset();
3912 session->CloseAllConnections();
3913}
3914
3915// Test a proxy auth scheme that allows default credentials and a proxy server
3916// that hangs up when credentials are initially sent.
bncd16676a2016-07-20 16:23:013917TEST_F(HttpNetworkTransactionTest,
mmenke2a1781d2015-10-07 19:25:333918 AuthAllowsDefaultCredentialsTunnelServerClosesConnection) {
3919 HttpRequestInfo request;
3920 request.method = "GET";
3921 request.url = GURL("https://www.example.org/");
3922
3923 // Configure against proxy server "myproxy:70".
3924 session_deps_.proxy_service =
3925 ProxyService::CreateFixedFromPacResult("PROXY myproxy:70");
3926
danakj1fd259a02016-04-16 03:17:093927 std::unique_ptr<HttpAuthHandlerMock::Factory> auth_handler_factory(
mmenke2a1781d2015-10-07 19:25:333928 new HttpAuthHandlerMock::Factory());
3929 auth_handler_factory->set_do_init_from_challenge(true);
danakj1fd259a02016-04-16 03:17:093930 std::unique_ptr<HttpAuthHandlerMock> mock_handler(new HttpAuthHandlerMock());
mmenke2a1781d2015-10-07 19:25:333931 mock_handler->set_allows_default_credentials(true);
3932 auth_handler_factory->AddMockHandler(mock_handler.release(),
3933 HttpAuth::AUTH_PROXY);
dchengc7eeda422015-12-26 03:56:483934 session_deps_.http_auth_handler_factory = std::move(auth_handler_factory);
mmenke2a1781d2015-10-07 19:25:333935
3936 // Add NetLog just so can verify load timing information gets a NetLog ID.
3937 NetLog net_log;
3938 session_deps_.net_log = &net_log;
danakj1fd259a02016-04-16 03:17:093939 std::unique_ptr<HttpNetworkSession> session = CreateSession(&session_deps_);
mmenke2a1781d2015-10-07 19:25:333940
3941 // Should try to establish tunnel.
3942 MockWrite data_writes1[] = {
3943 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:173944 "Host: www.example.org:443\r\n"
mmenke2a1781d2015-10-07 19:25:333945 "Proxy-Connection: keep-alive\r\n\r\n"),
3946
3947 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:173948 "Host: www.example.org:443\r\n"
mmenke2a1781d2015-10-07 19:25:333949 "Proxy-Connection: keep-alive\r\n"
3950 "Proxy-Authorization: auth_token\r\n\r\n"),
3951 };
3952
3953 // The proxy responds to the connect with a 407, using a non-persistent
3954 // connection.
3955 MockRead data_reads1[] = {
3956 // No credentials.
3957 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
3958 MockRead("Proxy-Authenticate: Mock\r\n\r\n"),
3959 MockRead(SYNCHRONOUS, ERR_CONNECTION_CLOSED),
3960 };
3961
3962 // Since the first connection was closed, need to establish another once given
3963 // credentials.
3964 MockWrite data_writes2[] = {
3965 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:173966 "Host: www.example.org:443\r\n"
mmenke2a1781d2015-10-07 19:25:333967 "Proxy-Connection: keep-alive\r\n"
3968 "Proxy-Authorization: auth_token\r\n\r\n"),
3969
3970 MockWrite("GET / HTTP/1.1\r\n"
3971 "Host: www.example.org\r\n"
3972 "Connection: keep-alive\r\n\r\n"),
3973 };
3974
3975 MockRead data_reads2[] = {
3976 MockRead("HTTP/1.0 200 Connection Established\r\n\r\n"),
3977
3978 MockRead("HTTP/1.1 200 OK\r\n"),
3979 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
3980 MockRead("Content-Length: 5\r\n\r\n"),
3981 MockRead(SYNCHRONOUS, "hello"),
3982 };
3983
3984 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
3985 data_writes1, arraysize(data_writes1));
3986 session_deps_.socket_factory->AddSocketDataProvider(&data1);
3987 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
3988 data_writes2, arraysize(data_writes2));
3989 session_deps_.socket_factory->AddSocketDataProvider(&data2);
3990 SSLSocketDataProvider ssl(ASYNC, OK);
3991 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
3992
bnc691fda62016-08-12 00:43:163993 std::unique_ptr<HttpNetworkTransaction> trans(
mmenke2a1781d2015-10-07 19:25:333994 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
3995
3996 TestCompletionCallback callback;
tfarina42834112016-09-22 13:38:203997 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:013998 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenke2a1781d2015-10-07 19:25:333999
4000 const HttpResponseInfo* response = trans->GetResponseInfo();
4001 ASSERT_TRUE(response);
4002 ASSERT_TRUE(response->headers);
4003 EXPECT_TRUE(response->headers->IsKeepAlive());
4004 EXPECT_EQ(407, response->headers->response_code());
4005 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
4006 EXPECT_TRUE(trans->IsReadyToRestartForAuth());
4007 EXPECT_FALSE(response->auth_challenge);
4008
4009 LoadTimingInfo load_timing_info;
4010 // CONNECT requests and responses are handled at the connect job level, so
4011 // the transaction does not yet have a connection.
4012 EXPECT_FALSE(trans->GetLoadTimingInfo(&load_timing_info));
4013
4014 rv = trans->RestartWithAuth(AuthCredentials(), callback.callback());
robpercival214763f2016-07-01 23:27:014015 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenke2a1781d2015-10-07 19:25:334016
4017 response = trans->GetResponseInfo();
4018 ASSERT_TRUE(response);
4019 ASSERT_TRUE(response->headers);
4020 EXPECT_TRUE(response->headers->IsKeepAlive());
4021 EXPECT_EQ(200, response->headers->response_code());
4022 EXPECT_EQ(5, response->headers->GetContentLength());
4023 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
4024
4025 // The password prompt info should not be set.
wezca1070932016-05-26 20:30:524026 EXPECT_FALSE(response->auth_challenge);
mmenke2a1781d2015-10-07 19:25:334027
4028 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
4029 TestLoadTimingNotReusedWithPac(load_timing_info,
4030 CONNECT_TIMING_HAS_SSL_TIMES);
4031
4032 trans.reset();
4033 session->CloseAllConnections();
4034}
4035
4036// Test a proxy auth scheme that allows default credentials and a proxy server
4037// that hangs up when credentials are initially sent, and hangs up again when
4038// they are retried.
bncd16676a2016-07-20 16:23:014039TEST_F(HttpNetworkTransactionTest,
mmenke2a1781d2015-10-07 19:25:334040 AuthAllowsDefaultCredentialsTunnelServerClosesConnectionTwice) {
4041 HttpRequestInfo request;
4042 request.method = "GET";
4043 request.url = GURL("https://www.example.org/");
4044
4045 // Configure against proxy server "myproxy:70".
4046 session_deps_.proxy_service =
4047 ProxyService::CreateFixedFromPacResult("PROXY myproxy:70");
4048
danakj1fd259a02016-04-16 03:17:094049 std::unique_ptr<HttpAuthHandlerMock::Factory> auth_handler_factory(
mmenke2a1781d2015-10-07 19:25:334050 new HttpAuthHandlerMock::Factory());
4051 auth_handler_factory->set_do_init_from_challenge(true);
danakj1fd259a02016-04-16 03:17:094052 std::unique_ptr<HttpAuthHandlerMock> mock_handler(new HttpAuthHandlerMock());
mmenke2a1781d2015-10-07 19:25:334053 mock_handler->set_allows_default_credentials(true);
4054 auth_handler_factory->AddMockHandler(mock_handler.release(),
4055 HttpAuth::AUTH_PROXY);
dchengc7eeda422015-12-26 03:56:484056 session_deps_.http_auth_handler_factory = std::move(auth_handler_factory);
mmenke2a1781d2015-10-07 19:25:334057
4058 // Add NetLog just so can verify load timing information gets a NetLog ID.
4059 NetLog net_log;
4060 session_deps_.net_log = &net_log;
danakj1fd259a02016-04-16 03:17:094061 std::unique_ptr<HttpNetworkSession> session = CreateSession(&session_deps_);
mmenke2a1781d2015-10-07 19:25:334062
4063 // Should try to establish tunnel.
4064 MockWrite data_writes1[] = {
4065 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:174066 "Host: www.example.org:443\r\n"
mmenke2a1781d2015-10-07 19:25:334067 "Proxy-Connection: keep-alive\r\n\r\n"),
4068
4069 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:174070 "Host: www.example.org:443\r\n"
mmenke2a1781d2015-10-07 19:25:334071 "Proxy-Connection: keep-alive\r\n"
4072 "Proxy-Authorization: auth_token\r\n\r\n"),
4073 };
4074
4075 // The proxy responds to the connect with a 407, and then hangs up after the
4076 // second request is sent.
4077 MockRead data_reads1[] = {
4078 // No credentials.
4079 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
4080 MockRead("Content-Length: 0\r\n"),
4081 MockRead("Proxy-Connection: keep-alive\r\n"),
4082 MockRead("Proxy-Authenticate: Mock\r\n\r\n"),
4083 MockRead(SYNCHRONOUS, ERR_CONNECTION_CLOSED),
4084 };
4085
4086 // HttpNetworkTransaction sees a reused connection that was closed with
4087 // ERR_CONNECTION_CLOSED, realized it might have been a race, so retries the
4088 // request.
4089 MockWrite data_writes2[] = {
4090 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:174091 "Host: www.example.org:443\r\n"
mmenke2a1781d2015-10-07 19:25:334092 "Proxy-Connection: keep-alive\r\n\r\n"),
4093 };
4094
4095 // The proxy, having had more than enough of us, just hangs up.
4096 MockRead data_reads2[] = {
4097 // No credentials.
4098 MockRead(SYNCHRONOUS, ERR_CONNECTION_CLOSED),
4099 };
4100
4101 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
4102 data_writes1, arraysize(data_writes1));
4103 session_deps_.socket_factory->AddSocketDataProvider(&data1);
4104 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
4105 data_writes2, arraysize(data_writes2));
4106 session_deps_.socket_factory->AddSocketDataProvider(&data2);
4107
bnc691fda62016-08-12 00:43:164108 std::unique_ptr<HttpNetworkTransaction> trans(
mmenke2a1781d2015-10-07 19:25:334109 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
4110
4111 TestCompletionCallback callback;
tfarina42834112016-09-22 13:38:204112 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:014113 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenke2a1781d2015-10-07 19:25:334114
4115 const HttpResponseInfo* response = trans->GetResponseInfo();
4116 ASSERT_TRUE(response);
4117 ASSERT_TRUE(response->headers);
4118 EXPECT_TRUE(response->headers->IsKeepAlive());
4119 EXPECT_EQ(407, response->headers->response_code());
4120 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
4121 EXPECT_TRUE(trans->IsReadyToRestartForAuth());
4122 EXPECT_FALSE(response->auth_challenge);
4123
4124 LoadTimingInfo load_timing_info;
4125 EXPECT_FALSE(trans->GetLoadTimingInfo(&load_timing_info));
4126
4127 rv = trans->RestartWithAuth(AuthCredentials(), callback.callback());
robpercival214763f2016-07-01 23:27:014128 EXPECT_THAT(callback.GetResult(rv), IsError(ERR_EMPTY_RESPONSE));
mmenke2a1781d2015-10-07 19:25:334129
4130 trans.reset();
4131 session->CloseAllConnections();
4132}
4133
4134// Test a proxy auth scheme that allows default credentials and a proxy server
4135// that hangs up when credentials are initially sent, and sends a challenge
4136// again they are retried.
bncd16676a2016-07-20 16:23:014137TEST_F(HttpNetworkTransactionTest,
mmenke2a1781d2015-10-07 19:25:334138 AuthAllowsDefaultCredentialsTunnelServerChallengesTwice) {
4139 HttpRequestInfo request;
4140 request.method = "GET";
4141 request.url = GURL("https://www.example.org/");
4142
4143 // Configure against proxy server "myproxy:70".
4144 session_deps_.proxy_service =
4145 ProxyService::CreateFixedFromPacResult("PROXY myproxy:70");
4146
danakj1fd259a02016-04-16 03:17:094147 std::unique_ptr<HttpAuthHandlerMock::Factory> auth_handler_factory(
mmenke2a1781d2015-10-07 19:25:334148 new HttpAuthHandlerMock::Factory());
4149 auth_handler_factory->set_do_init_from_challenge(true);
danakj1fd259a02016-04-16 03:17:094150 std::unique_ptr<HttpAuthHandlerMock> mock_handler(new HttpAuthHandlerMock());
mmenke2a1781d2015-10-07 19:25:334151 mock_handler->set_allows_default_credentials(true);
4152 auth_handler_factory->AddMockHandler(mock_handler.release(),
4153 HttpAuth::AUTH_PROXY);
4154 // Add another handler for the second challenge. It supports default
4155 // credentials, but they shouldn't be used, since they were already tried.
4156 mock_handler.reset(new HttpAuthHandlerMock());
4157 mock_handler->set_allows_default_credentials(true);
4158 auth_handler_factory->AddMockHandler(mock_handler.release(),
4159 HttpAuth::AUTH_PROXY);
dchengc7eeda422015-12-26 03:56:484160 session_deps_.http_auth_handler_factory = std::move(auth_handler_factory);
mmenke2a1781d2015-10-07 19:25:334161
4162 // Add NetLog just so can verify load timing information gets a NetLog ID.
4163 NetLog net_log;
4164 session_deps_.net_log = &net_log;
danakj1fd259a02016-04-16 03:17:094165 std::unique_ptr<HttpNetworkSession> session = CreateSession(&session_deps_);
mmenke2a1781d2015-10-07 19:25:334166
4167 // Should try to establish tunnel.
4168 MockWrite data_writes1[] = {
4169 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:174170 "Host: www.example.org:443\r\n"
mmenke2a1781d2015-10-07 19:25:334171 "Proxy-Connection: keep-alive\r\n\r\n"),
4172 };
4173
4174 // The proxy responds to the connect with a 407, using a non-persistent
4175 // connection.
4176 MockRead data_reads1[] = {
4177 // No credentials.
4178 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
4179 MockRead("Proxy-Authenticate: Mock\r\n"),
4180 MockRead("Proxy-Connection: close\r\n\r\n"),
4181 };
4182
4183 // Since the first connection was closed, need to establish another once given
4184 // credentials.
4185 MockWrite data_writes2[] = {
4186 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:174187 "Host: www.example.org:443\r\n"
mmenke2a1781d2015-10-07 19:25:334188 "Proxy-Connection: keep-alive\r\n"
4189 "Proxy-Authorization: auth_token\r\n\r\n"),
4190 };
4191
4192 MockRead data_reads2[] = {
4193 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
4194 MockRead("Proxy-Authenticate: Mock\r\n"),
4195 MockRead("Proxy-Connection: close\r\n\r\n"),
4196 };
4197
4198 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
4199 data_writes1, arraysize(data_writes1));
4200 session_deps_.socket_factory->AddSocketDataProvider(&data1);
4201 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
4202 data_writes2, arraysize(data_writes2));
4203 session_deps_.socket_factory->AddSocketDataProvider(&data2);
4204 SSLSocketDataProvider ssl(ASYNC, OK);
4205 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
4206
bnc691fda62016-08-12 00:43:164207 std::unique_ptr<HttpNetworkTransaction> trans(
mmenke2a1781d2015-10-07 19:25:334208 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
4209
4210 TestCompletionCallback callback;
tfarina42834112016-09-22 13:38:204211 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:014212 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenke2a1781d2015-10-07 19:25:334213
4214 const HttpResponseInfo* response = trans->GetResponseInfo();
4215 ASSERT_TRUE(response);
4216 ASSERT_TRUE(response->headers);
4217 EXPECT_EQ(407, response->headers->response_code());
4218 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
4219 EXPECT_TRUE(trans->IsReadyToRestartForAuth());
4220 EXPECT_FALSE(response->auth_challenge);
4221
4222 LoadTimingInfo load_timing_info;
4223 EXPECT_FALSE(trans->GetLoadTimingInfo(&load_timing_info));
4224
4225 rv = trans->RestartWithAuth(AuthCredentials(), callback.callback());
robpercival214763f2016-07-01 23:27:014226 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenke2a1781d2015-10-07 19:25:334227 response = trans->GetResponseInfo();
4228 ASSERT_TRUE(response);
4229 ASSERT_TRUE(response->headers);
4230 EXPECT_EQ(407, response->headers->response_code());
4231 EXPECT_FALSE(trans->IsReadyToRestartForAuth());
4232 EXPECT_TRUE(response->auth_challenge);
4233
4234 trans.reset();
4235 session->CloseAllConnections();
4236}
4237
asankae2257db2016-10-11 22:03:164238// A more nuanced test than GenerateAuthToken test which asserts that
4239// ERR_INVALID_AUTH_CREDENTIALS does not cause the auth scheme to be
4240// unnecessarily invalidated, and that if the server co-operates, the
4241// authentication handshake can continue with the same scheme but with a
4242// different identity.
4243TEST_F(HttpNetworkTransactionTest, NonPermanentGenerateAuthTokenError) {
4244 HttpRequestInfo request;
4245 request.method = "GET";
4246 request.url = GURL("http://www.example.org/");
4247
4248 std::unique_ptr<HttpAuthHandlerMock::Factory> auth_handler_factory(
4249 new HttpAuthHandlerMock::Factory());
4250 auth_handler_factory->set_do_init_from_challenge(true);
4251
4252 // First handler. Uses default credentials, but barfs at generate auth token.
4253 std::unique_ptr<HttpAuthHandlerMock> mock_handler(new HttpAuthHandlerMock());
4254 mock_handler->set_allows_default_credentials(true);
4255 mock_handler->set_allows_explicit_credentials(true);
4256 mock_handler->set_connection_based(true);
4257 mock_handler->SetGenerateExpectation(true, ERR_INVALID_AUTH_CREDENTIALS);
4258 auth_handler_factory->AddMockHandler(mock_handler.release(),
4259 HttpAuth::AUTH_SERVER);
4260
4261 // Add another handler for the second challenge. It supports default
4262 // credentials, but they shouldn't be used, since they were already tried.
4263 mock_handler.reset(new HttpAuthHandlerMock());
4264 mock_handler->set_allows_default_credentials(true);
4265 mock_handler->set_allows_explicit_credentials(true);
4266 mock_handler->set_connection_based(true);
4267 auth_handler_factory->AddMockHandler(mock_handler.release(),
4268 HttpAuth::AUTH_SERVER);
4269 session_deps_.http_auth_handler_factory = std::move(auth_handler_factory);
4270
4271 std::unique_ptr<HttpNetworkSession> session = CreateSession(&session_deps_);
4272
4273 MockWrite data_writes1[] = {
4274 MockWrite("GET / HTTP/1.1\r\n"
4275 "Host: www.example.org\r\n"
4276 "Connection: keep-alive\r\n\r\n"),
4277 };
4278
4279 MockRead data_reads1[] = {
4280 MockRead("HTTP/1.1 401 Authentication Required\r\n"
4281 "WWW-Authenticate: Mock\r\n"
4282 "Connection: keep-alive\r\n\r\n"),
4283 };
4284
4285 // Identical to data_writes1[]. The AuthHandler encounters a
4286 // ERR_INVALID_AUTH_CREDENTIALS during the GenerateAuthToken stage, so the
4287 // transaction procceds without an authorization header.
4288 MockWrite data_writes2[] = {
4289 MockWrite("GET / HTTP/1.1\r\n"
4290 "Host: www.example.org\r\n"
4291 "Connection: keep-alive\r\n\r\n"),
4292 };
4293
4294 MockRead data_reads2[] = {
4295 MockRead("HTTP/1.1 401 Authentication Required\r\n"
4296 "WWW-Authenticate: Mock\r\n"
4297 "Connection: keep-alive\r\n\r\n"),
4298 };
4299
4300 MockWrite data_writes3[] = {
4301 MockWrite("GET / HTTP/1.1\r\n"
4302 "Host: www.example.org\r\n"
4303 "Connection: keep-alive\r\n"
4304 "Authorization: auth_token\r\n\r\n"),
4305 };
4306
4307 MockRead data_reads3[] = {
4308 MockRead("HTTP/1.1 200 OK\r\n"
4309 "Content-Length: 5\r\n"
4310 "Content-Type: text/plain\r\n"
4311 "Connection: keep-alive\r\n\r\n"
4312 "Hello"),
4313 };
4314
4315 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
4316 data_writes1, arraysize(data_writes1));
4317 session_deps_.socket_factory->AddSocketDataProvider(&data1);
4318
4319 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
4320 data_writes2, arraysize(data_writes2));
4321 session_deps_.socket_factory->AddSocketDataProvider(&data2);
4322
4323 StaticSocketDataProvider data3(data_reads3, arraysize(data_reads3),
4324 data_writes3, arraysize(data_writes3));
4325 session_deps_.socket_factory->AddSocketDataProvider(&data3);
4326
4327 std::unique_ptr<HttpNetworkTransaction> trans(
4328 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
4329
4330 TestCompletionCallback callback;
4331 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
4332 EXPECT_THAT(callback.GetResult(rv), IsOk());
4333
4334 const HttpResponseInfo* response = trans->GetResponseInfo();
4335 ASSERT_TRUE(response);
4336 ASSERT_TRUE(response->headers);
4337 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
4338
4339 // The following three tests assert that an authentication challenge was
4340 // received and that the stack is ready to respond to the challenge using
4341 // ambient credentials.
4342 EXPECT_EQ(401, response->headers->response_code());
4343 EXPECT_TRUE(trans->IsReadyToRestartForAuth());
4344 EXPECT_FALSE(response->auth_challenge);
4345
4346 rv = trans->RestartWithAuth(AuthCredentials(), callback.callback());
4347 EXPECT_THAT(callback.GetResult(rv), IsOk());
4348 response = trans->GetResponseInfo();
4349 ASSERT_TRUE(response);
4350 ASSERT_TRUE(response->headers);
4351
4352 // The following three tests assert that an authentication challenge was
4353 // received and that the stack needs explicit credentials before it is ready
4354 // to respond to the challenge.
4355 EXPECT_EQ(401, response->headers->response_code());
4356 EXPECT_FALSE(trans->IsReadyToRestartForAuth());
4357 EXPECT_TRUE(response->auth_challenge);
4358
4359 rv = trans->RestartWithAuth(AuthCredentials(), callback.callback());
4360 EXPECT_THAT(callback.GetResult(rv), IsOk());
4361 response = trans->GetResponseInfo();
4362 ASSERT_TRUE(response);
4363 ASSERT_TRUE(response->headers);
4364 EXPECT_EQ(200, response->headers->response_code());
4365
4366 trans.reset();
4367 session->CloseAllConnections();
4368}
4369
[email protected]029c83b62013-01-24 05:28:204370// Test the load timing for HTTPS requests with an HTTP proxy.
bncd16676a2016-07-20 16:23:014371TEST_F(HttpNetworkTransactionTest, HttpProxyLoadTimingNoPacTwoRequests) {
[email protected]029c83b62013-01-24 05:28:204372 HttpRequestInfo request1;
4373 request1.method = "GET";
bncce36dca22015-04-21 22:11:234374 request1.url = GURL("https://www.example.org/1");
[email protected]029c83b62013-01-24 05:28:204375
4376 HttpRequestInfo request2;
4377 request2.method = "GET";
bncce36dca22015-04-21 22:11:234378 request2.url = GURL("https://www.example.org/2");
[email protected]029c83b62013-01-24 05:28:204379
4380 // Configure against proxy server "myproxy:70".
brettwc1213d92016-11-12 03:41:134381 session_deps_.proxy_service = ProxyService::CreateFixed("myproxy:70");
vishal.b62985ca92015-04-17 08:45:514382 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:074383 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:094384 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]029c83b62013-01-24 05:28:204385
4386 // Since we have proxy, should try to establish tunnel.
4387 MockWrite data_writes1[] = {
rsleevidb16bb02015-11-12 23:47:174388 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
4389 "Host: www.example.org:443\r\n"
4390 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]029c83b62013-01-24 05:28:204391
rsleevidb16bb02015-11-12 23:47:174392 MockWrite("GET /1 HTTP/1.1\r\n"
4393 "Host: www.example.org\r\n"
4394 "Connection: keep-alive\r\n\r\n"),
[email protected]029c83b62013-01-24 05:28:204395
rsleevidb16bb02015-11-12 23:47:174396 MockWrite("GET /2 HTTP/1.1\r\n"
4397 "Host: www.example.org\r\n"
4398 "Connection: keep-alive\r\n\r\n"),
[email protected]029c83b62013-01-24 05:28:204399 };
4400
4401 // The proxy responds to the connect with a 407, using a persistent
4402 // connection.
4403 MockRead data_reads1[] = {
4404 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
4405
4406 MockRead("HTTP/1.1 200 OK\r\n"),
4407 MockRead("Content-Length: 1\r\n\r\n"),
4408 MockRead(SYNCHRONOUS, "1"),
4409
4410 MockRead("HTTP/1.1 200 OK\r\n"),
4411 MockRead("Content-Length: 2\r\n\r\n"),
4412 MockRead(SYNCHRONOUS, "22"),
4413 };
4414
4415 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
4416 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:074417 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]029c83b62013-01-24 05:28:204418 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:074419 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]029c83b62013-01-24 05:28:204420
4421 TestCompletionCallback callback1;
bnc691fda62016-08-12 00:43:164422 std::unique_ptr<HttpNetworkTransaction> trans1(
[email protected]90499482013-06-01 00:39:504423 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]029c83b62013-01-24 05:28:204424
4425 int rv = trans1->Start(&request1, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:014426 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]029c83b62013-01-24 05:28:204427
4428 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:014429 EXPECT_THAT(rv, IsOk());
[email protected]029c83b62013-01-24 05:28:204430
4431 const HttpResponseInfo* response1 = trans1->GetResponseInfo();
wezca1070932016-05-26 20:30:524432 ASSERT_TRUE(response1);
tbansal2ecbbc72016-10-06 17:15:474433 EXPECT_TRUE(response1->proxy_server.is_http());
wezca1070932016-05-26 20:30:524434 ASSERT_TRUE(response1->headers);
[email protected]029c83b62013-01-24 05:28:204435 EXPECT_EQ(1, response1->headers->GetContentLength());
4436
4437 LoadTimingInfo load_timing_info1;
4438 EXPECT_TRUE(trans1->GetLoadTimingInfo(&load_timing_info1));
4439 TestLoadTimingNotReused(load_timing_info1, CONNECT_TIMING_HAS_SSL_TIMES);
4440
4441 trans1.reset();
4442
4443 TestCompletionCallback callback2;
bnc691fda62016-08-12 00:43:164444 std::unique_ptr<HttpNetworkTransaction> trans2(
[email protected]90499482013-06-01 00:39:504445 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]029c83b62013-01-24 05:28:204446
4447 rv = trans2->Start(&request2, callback2.callback(), log.bound());
robpercival214763f2016-07-01 23:27:014448 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]029c83b62013-01-24 05:28:204449
4450 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:014451 EXPECT_THAT(rv, IsOk());
[email protected]029c83b62013-01-24 05:28:204452
4453 const HttpResponseInfo* response2 = trans2->GetResponseInfo();
wezca1070932016-05-26 20:30:524454 ASSERT_TRUE(response2);
tbansal2ecbbc72016-10-06 17:15:474455 EXPECT_TRUE(response2->proxy_server.is_http());
wezca1070932016-05-26 20:30:524456 ASSERT_TRUE(response2->headers);
[email protected]029c83b62013-01-24 05:28:204457 EXPECT_EQ(2, response2->headers->GetContentLength());
4458
4459 LoadTimingInfo load_timing_info2;
4460 EXPECT_TRUE(trans2->GetLoadTimingInfo(&load_timing_info2));
4461 TestLoadTimingReused(load_timing_info2);
4462
4463 EXPECT_EQ(load_timing_info1.socket_log_id, load_timing_info2.socket_log_id);
4464
4465 trans2.reset();
4466 session->CloseAllConnections();
4467}
4468
4469// Test the load timing for HTTPS requests with an HTTP proxy and a PAC script.
bncd16676a2016-07-20 16:23:014470TEST_F(HttpNetworkTransactionTest, HttpProxyLoadTimingWithPacTwoRequests) {
[email protected]029c83b62013-01-24 05:28:204471 HttpRequestInfo request1;
4472 request1.method = "GET";
bncce36dca22015-04-21 22:11:234473 request1.url = GURL("https://www.example.org/1");
[email protected]029c83b62013-01-24 05:28:204474
4475 HttpRequestInfo request2;
4476 request2.method = "GET";
bncce36dca22015-04-21 22:11:234477 request2.url = GURL("https://www.example.org/2");
[email protected]029c83b62013-01-24 05:28:204478
4479 // Configure against proxy server "myproxy:70".
rdsmith82957ad2015-09-16 19:42:034480 session_deps_.proxy_service =
4481 ProxyService::CreateFixedFromPacResult("PROXY myproxy:70");
vishal.b62985ca92015-04-17 08:45:514482 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:074483 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:094484 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]029c83b62013-01-24 05:28:204485
4486 // Since we have proxy, should try to establish tunnel.
4487 MockWrite data_writes1[] = {
rsleevidb16bb02015-11-12 23:47:174488 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
4489 "Host: www.example.org:443\r\n"
4490 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]029c83b62013-01-24 05:28:204491
rsleevidb16bb02015-11-12 23:47:174492 MockWrite("GET /1 HTTP/1.1\r\n"
4493 "Host: www.example.org\r\n"
4494 "Connection: keep-alive\r\n\r\n"),
[email protected]029c83b62013-01-24 05:28:204495
rsleevidb16bb02015-11-12 23:47:174496 MockWrite("GET /2 HTTP/1.1\r\n"
4497 "Host: www.example.org\r\n"
4498 "Connection: keep-alive\r\n\r\n"),
[email protected]029c83b62013-01-24 05:28:204499 };
4500
4501 // The proxy responds to the connect with a 407, using a persistent
4502 // connection.
4503 MockRead data_reads1[] = {
4504 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
4505
4506 MockRead("HTTP/1.1 200 OK\r\n"),
4507 MockRead("Content-Length: 1\r\n\r\n"),
4508 MockRead(SYNCHRONOUS, "1"),
4509
4510 MockRead("HTTP/1.1 200 OK\r\n"),
4511 MockRead("Content-Length: 2\r\n\r\n"),
4512 MockRead(SYNCHRONOUS, "22"),
4513 };
4514
4515 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
4516 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:074517 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]029c83b62013-01-24 05:28:204518 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:074519 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]029c83b62013-01-24 05:28:204520
4521 TestCompletionCallback callback1;
bnc691fda62016-08-12 00:43:164522 std::unique_ptr<HttpNetworkTransaction> trans1(
[email protected]90499482013-06-01 00:39:504523 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]029c83b62013-01-24 05:28:204524
4525 int rv = trans1->Start(&request1, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:014526 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]029c83b62013-01-24 05:28:204527
4528 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:014529 EXPECT_THAT(rv, IsOk());
[email protected]029c83b62013-01-24 05:28:204530
4531 const HttpResponseInfo* response1 = trans1->GetResponseInfo();
wezca1070932016-05-26 20:30:524532 ASSERT_TRUE(response1);
4533 ASSERT_TRUE(response1->headers);
[email protected]029c83b62013-01-24 05:28:204534 EXPECT_EQ(1, response1->headers->GetContentLength());
4535
4536 LoadTimingInfo load_timing_info1;
4537 EXPECT_TRUE(trans1->GetLoadTimingInfo(&load_timing_info1));
4538 TestLoadTimingNotReusedWithPac(load_timing_info1,
4539 CONNECT_TIMING_HAS_SSL_TIMES);
4540
4541 trans1.reset();
4542
4543 TestCompletionCallback callback2;
bnc691fda62016-08-12 00:43:164544 std::unique_ptr<HttpNetworkTransaction> trans2(
[email protected]90499482013-06-01 00:39:504545 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]029c83b62013-01-24 05:28:204546
4547 rv = trans2->Start(&request2, callback2.callback(), log.bound());
robpercival214763f2016-07-01 23:27:014548 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]029c83b62013-01-24 05:28:204549
4550 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:014551 EXPECT_THAT(rv, IsOk());
[email protected]029c83b62013-01-24 05:28:204552
4553 const HttpResponseInfo* response2 = trans2->GetResponseInfo();
wezca1070932016-05-26 20:30:524554 ASSERT_TRUE(response2);
4555 ASSERT_TRUE(response2->headers);
[email protected]029c83b62013-01-24 05:28:204556 EXPECT_EQ(2, response2->headers->GetContentLength());
4557
4558 LoadTimingInfo load_timing_info2;
4559 EXPECT_TRUE(trans2->GetLoadTimingInfo(&load_timing_info2));
4560 TestLoadTimingReusedWithPac(load_timing_info2);
4561
4562 EXPECT_EQ(load_timing_info1.socket_log_id, load_timing_info2.socket_log_id);
4563
4564 trans2.reset();
4565 session->CloseAllConnections();
4566}
4567
[email protected]2df19bb2010-08-25 20:13:464568// Test a simple get through an HTTPS Proxy.
bncd16676a2016-07-20 16:23:014569TEST_F(HttpNetworkTransactionTest, HttpsProxyGet) {
[email protected]cb9bf6ca2011-01-28 13:15:274570 HttpRequestInfo request;
4571 request.method = "GET";
bncce36dca22015-04-21 22:11:234572 request.url = GURL("http://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:274573
[email protected]2df19bb2010-08-25 20:13:464574 // Configure against https proxy server "proxy:70".
rdsmith82957ad2015-09-16 19:42:034575 session_deps_.proxy_service = ProxyService::CreateFixed("https://proxy:70");
vishal.b62985ca92015-04-17 08:45:514576 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:074577 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:094578 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]2df19bb2010-08-25 20:13:464579
[email protected]2df19bb2010-08-25 20:13:464580 // Since we have proxy, should use full url
4581 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:234582 MockWrite(
4583 "GET http://www.example.org/ HTTP/1.1\r\n"
4584 "Host: www.example.org\r\n"
4585 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]2df19bb2010-08-25 20:13:464586 };
4587
4588 MockRead data_reads1[] = {
4589 MockRead("HTTP/1.1 200 OK\r\n"),
4590 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
4591 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:064592 MockRead(SYNCHRONOUS, OK),
[email protected]2df19bb2010-08-25 20:13:464593 };
4594
4595 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
4596 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:074597 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8ddf8322012-02-23 18:08:064598 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:074599 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]2df19bb2010-08-25 20:13:464600
[email protected]49639fa2011-12-20 23:22:414601 TestCompletionCallback callback1;
[email protected]2df19bb2010-08-25 20:13:464602
bnc691fda62016-08-12 00:43:164603 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]0b0bf032010-09-21 18:08:504604
bnc691fda62016-08-12 00:43:164605 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:014606 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2df19bb2010-08-25 20:13:464607
4608 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:014609 EXPECT_THAT(rv, IsOk());
[email protected]2df19bb2010-08-25 20:13:464610
[email protected]58e32bb2013-01-21 18:23:254611 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:164612 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]58e32bb2013-01-21 18:23:254613 TestLoadTimingNotReused(load_timing_info,
4614 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
4615
bnc691fda62016-08-12 00:43:164616 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:524617 ASSERT_TRUE(response);
[email protected]2df19bb2010-08-25 20:13:464618
tbansal2ecbbc72016-10-06 17:15:474619 EXPECT_TRUE(response->proxy_server.is_https());
[email protected]2df19bb2010-08-25 20:13:464620 EXPECT_TRUE(response->headers->IsKeepAlive());
4621 EXPECT_EQ(200, response->headers->response_code());
4622 EXPECT_EQ(100, response->headers->GetContentLength());
4623 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
4624
4625 // The password prompt info should not be set.
wezca1070932016-05-26 20:30:524626 EXPECT_FALSE(response->auth_challenge);
[email protected]2df19bb2010-08-25 20:13:464627}
4628
[email protected]7642b5ae2010-09-01 20:55:174629// Test a SPDY get through an HTTPS Proxy.
bncd16676a2016-07-20 16:23:014630TEST_F(HttpNetworkTransactionTest, HttpsProxySpdyGet) {
[email protected]cb9bf6ca2011-01-28 13:15:274631 HttpRequestInfo request;
4632 request.method = "GET";
bncce36dca22015-04-21 22:11:234633 request.url = GURL("http://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:274634
[email protected]7642b5ae2010-09-01 20:55:174635 // Configure against https proxy server "proxy:70".
rdsmith82957ad2015-09-16 19:42:034636 session_deps_.proxy_service = ProxyService::CreateFixed("https://proxy:70");
vishal.b62985ca92015-04-17 08:45:514637 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:074638 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:094639 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]7642b5ae2010-09-01 20:55:174640
bncce36dca22015-04-21 22:11:234641 // fetch http://www.example.org/ via SPDY
bncdf80d44fd2016-07-15 20:27:414642 SpdySerializedFrame req(
bncb26024382016-06-29 02:39:454643 spdy_util_.ConstructSpdyGet("http://www.example.org/", 1, LOWEST));
bncdf80d44fd2016-07-15 20:27:414644 MockWrite spdy_writes[] = {CreateMockWrite(req, 0)};
[email protected]7642b5ae2010-09-01 20:55:174645
bnc42331402016-07-25 13:36:154646 SpdySerializedFrame resp(spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
bncdf80d44fd2016-07-15 20:27:414647 SpdySerializedFrame data(spdy_util_.ConstructSpdyDataFrame(1, true));
[email protected]7642b5ae2010-09-01 20:55:174648 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:414649 CreateMockRead(resp, 1), CreateMockRead(data, 2), MockRead(ASYNC, 0, 3),
[email protected]7642b5ae2010-09-01 20:55:174650 };
4651
rch8e6c6c42015-05-01 14:05:134652 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
4653 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:074654 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]7642b5ae2010-09-01 20:55:174655
[email protected]8ddf8322012-02-23 18:08:064656 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:364657 ssl.next_proto = kProtoHTTP2;
[email protected]bb88e1d32013-05-03 23:11:074658 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]7642b5ae2010-09-01 20:55:174659
[email protected]49639fa2011-12-20 23:22:414660 TestCompletionCallback callback1;
[email protected]7642b5ae2010-09-01 20:55:174661
bnc691fda62016-08-12 00:43:164662 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]0b0bf032010-09-21 18:08:504663
bnc691fda62016-08-12 00:43:164664 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:014665 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]7642b5ae2010-09-01 20:55:174666
4667 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:014668 EXPECT_THAT(rv, IsOk());
[email protected]7642b5ae2010-09-01 20:55:174669
[email protected]58e32bb2013-01-21 18:23:254670 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:164671 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]58e32bb2013-01-21 18:23:254672 TestLoadTimingNotReused(load_timing_info,
4673 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
4674
bnc691fda62016-08-12 00:43:164675 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:524676 ASSERT_TRUE(response);
tbansal2ecbbc72016-10-06 17:15:474677 EXPECT_TRUE(response->proxy_server.is_https());
wezca1070932016-05-26 20:30:524678 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:024679 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]7642b5ae2010-09-01 20:55:174680
4681 std::string response_data;
bnc691fda62016-08-12 00:43:164682 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
[email protected]448d4ca52012-03-04 04:12:234683 EXPECT_EQ(kUploadData, response_data);
[email protected]7642b5ae2010-09-01 20:55:174684}
4685
[email protected]1c173852014-06-19 12:51:504686// Verifies that a session which races and wins against the owning transaction
4687// (completing prior to host resolution), doesn't fail the transaction.
4688// Regression test for crbug.com/334413.
bncd16676a2016-07-20 16:23:014689TEST_F(HttpNetworkTransactionTest, HttpsProxySpdyGetWithSessionRace) {
[email protected]1c173852014-06-19 12:51:504690 HttpRequestInfo request;
4691 request.method = "GET";
bncce36dca22015-04-21 22:11:234692 request.url = GURL("http://www.example.org/");
[email protected]1c173852014-06-19 12:51:504693
4694 // Configure SPDY proxy server "proxy:70".
rdsmith82957ad2015-09-16 19:42:034695 session_deps_.proxy_service = ProxyService::CreateFixed("https://proxy:70");
vishal.b62985ca92015-04-17 08:45:514696 BoundTestNetLog log;
[email protected]1c173852014-06-19 12:51:504697 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:094698 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]1c173852014-06-19 12:51:504699
bncce36dca22015-04-21 22:11:234700 // Fetch http://www.example.org/ through the SPDY proxy.
bncdf80d44fd2016-07-15 20:27:414701 SpdySerializedFrame req(
bncb26024382016-06-29 02:39:454702 spdy_util_.ConstructSpdyGet("http://www.example.org/", 1, LOWEST));
bncdf80d44fd2016-07-15 20:27:414703 MockWrite spdy_writes[] = {CreateMockWrite(req, 0)};
[email protected]1c173852014-06-19 12:51:504704
bnc42331402016-07-25 13:36:154705 SpdySerializedFrame resp(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
bncdf80d44fd2016-07-15 20:27:414706 SpdySerializedFrame data(spdy_util_.ConstructSpdyDataFrame(1, true));
[email protected]1c173852014-06-19 12:51:504707 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:414708 CreateMockRead(resp, 1), CreateMockRead(data, 2), MockRead(ASYNC, 0, 3),
[email protected]1c173852014-06-19 12:51:504709 };
4710
rch8e6c6c42015-05-01 14:05:134711 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
4712 arraysize(spdy_writes));
[email protected]1c173852014-06-19 12:51:504713 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
4714
4715 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:364716 ssl.next_proto = kProtoHTTP2;
[email protected]1c173852014-06-19 12:51:504717 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
4718
4719 TestCompletionCallback callback1;
4720
bnc691fda62016-08-12 00:43:164721 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]1c173852014-06-19 12:51:504722
4723 // Stall the hostname resolution begun by the transaction.
4724 session_deps_.host_resolver->set_synchronous_mode(false);
4725 session_deps_.host_resolver->set_ondemand_mode(true);
4726
bnc691fda62016-08-12 00:43:164727 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:014728 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]1c173852014-06-19 12:51:504729
4730 // Race a session to the proxy, which completes first.
4731 session_deps_.host_resolver->set_ondemand_mode(false);
4732 SpdySessionKey key(
4733 HostPortPair("proxy", 70), ProxyServer::Direct(), PRIVACY_MODE_DISABLED);
4734 base::WeakPtr<SpdySession> spdy_session =
mmenkee65e7af2015-10-13 17:16:424735 CreateSecureSpdySession(session.get(), key, log.bound());
[email protected]1c173852014-06-19 12:51:504736
4737 // Unstall the resolution begun by the transaction.
4738 session_deps_.host_resolver->set_ondemand_mode(true);
4739 session_deps_.host_resolver->ResolveAllPending();
4740
4741 EXPECT_FALSE(callback1.have_result());
4742 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:014743 EXPECT_THAT(rv, IsOk());
[email protected]1c173852014-06-19 12:51:504744
bnc691fda62016-08-12 00:43:164745 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:524746 ASSERT_TRUE(response);
4747 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:024748 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]1c173852014-06-19 12:51:504749
4750 std::string response_data;
bnc691fda62016-08-12 00:43:164751 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
[email protected]1c173852014-06-19 12:51:504752 EXPECT_EQ(kUploadData, response_data);
4753}
4754
[email protected]dc7bd1c52010-11-12 00:01:134755// Test a SPDY get through an HTTPS Proxy.
bncd16676a2016-07-20 16:23:014756TEST_F(HttpNetworkTransactionTest, HttpsProxySpdyGetWithProxyAuth) {
[email protected]cb9bf6ca2011-01-28 13:15:274757 HttpRequestInfo request;
4758 request.method = "GET";
bncce36dca22015-04-21 22:11:234759 request.url = GURL("http://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:274760
[email protected]79cb5c12011-09-12 13:12:044761 // Configure against https proxy server "myproxy:70".
rdsmith82957ad2015-09-16 19:42:034762 session_deps_.proxy_service = ProxyService::CreateFixed("https://myproxy:70");
vishal.b62985ca92015-04-17 08:45:514763 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:074764 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:094765 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]dc7bd1c52010-11-12 00:01:134766
[email protected]dc7bd1c52010-11-12 00:01:134767 // The first request will be a bare GET, the second request will be a
4768 // GET with a Proxy-Authorization header.
bncb26024382016-06-29 02:39:454769 spdy_util_.set_default_url(request.url);
bncdf80d44fd2016-07-15 20:27:414770 SpdySerializedFrame req_get(
bnc38dcd392016-02-09 23:19:494771 spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST, false));
rdsmithebb50aa2015-11-12 03:44:384772 spdy_util_.UpdateWithStreamDestruction(1);
[email protected]dc7bd1c52010-11-12 00:01:134773 const char* const kExtraAuthorizationHeaders[] = {
[email protected]cdf8f7e72013-05-23 10:56:464774 "proxy-authorization", "Basic Zm9vOmJhcg=="
[email protected]dc7bd1c52010-11-12 00:01:134775 };
bncdf80d44fd2016-07-15 20:27:414776 SpdySerializedFrame req_get_authorization(spdy_util_.ConstructSpdyGet(
4777 kExtraAuthorizationHeaders, arraysize(kExtraAuthorizationHeaders) / 2, 3,
4778 LOWEST, false));
[email protected]dc7bd1c52010-11-12 00:01:134779 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:414780 CreateMockWrite(req_get, 0), CreateMockWrite(req_get_authorization, 3),
[email protected]dc7bd1c52010-11-12 00:01:134781 };
4782
4783 // The first response is a 407 proxy authentication challenge, and the second
4784 // response will be a 200 response since the second request includes a valid
4785 // Authorization header.
4786 const char* const kExtraAuthenticationHeaders[] = {
[email protected]cdf8f7e72013-05-23 10:56:464787 "proxy-authenticate", "Basic realm=\"MyRealm1\""
[email protected]dc7bd1c52010-11-12 00:01:134788 };
bnc42331402016-07-25 13:36:154789 SpdySerializedFrame resp_authentication(spdy_util_.ConstructSpdyReplyError(
bncc9f762a2016-12-06 20:38:234790 "407", kExtraAuthenticationHeaders,
bncdf80d44fd2016-07-15 20:27:414791 arraysize(kExtraAuthenticationHeaders) / 2, 1));
4792 SpdySerializedFrame body_authentication(
4793 spdy_util_.ConstructSpdyDataFrame(1, true));
bnc42331402016-07-25 13:36:154794 SpdySerializedFrame resp_data(spdy_util_.ConstructSpdyGetReply(NULL, 0, 3));
bncdf80d44fd2016-07-15 20:27:414795 SpdySerializedFrame body_data(spdy_util_.ConstructSpdyDataFrame(3, true));
[email protected]dc7bd1c52010-11-12 00:01:134796 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:414797 CreateMockRead(resp_authentication, 1),
bnceb9aa7112017-01-05 01:03:464798 CreateMockRead(body_authentication, 2, SYNCHRONOUS),
bncdf80d44fd2016-07-15 20:27:414799 CreateMockRead(resp_data, 4),
4800 CreateMockRead(body_data, 5),
rch8e6c6c42015-05-01 14:05:134801 MockRead(ASYNC, 0, 6),
[email protected]dc7bd1c52010-11-12 00:01:134802 };
4803
rch8e6c6c42015-05-01 14:05:134804 SequencedSocketData data(spdy_reads, arraysize(spdy_reads), spdy_writes,
4805 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:074806 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]dc7bd1c52010-11-12 00:01:134807
[email protected]8ddf8322012-02-23 18:08:064808 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:364809 ssl.next_proto = kProtoHTTP2;
[email protected]bb88e1d32013-05-03 23:11:074810 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]dc7bd1c52010-11-12 00:01:134811
[email protected]49639fa2011-12-20 23:22:414812 TestCompletionCallback callback1;
[email protected]dc7bd1c52010-11-12 00:01:134813
bnc691fda62016-08-12 00:43:164814 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]dc7bd1c52010-11-12 00:01:134815
bnc691fda62016-08-12 00:43:164816 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:014817 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]dc7bd1c52010-11-12 00:01:134818
4819 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:014820 EXPECT_THAT(rv, IsOk());
[email protected]dc7bd1c52010-11-12 00:01:134821
bnc691fda62016-08-12 00:43:164822 const HttpResponseInfo* const response = trans.GetResponseInfo();
[email protected]dc7bd1c52010-11-12 00:01:134823
wezca1070932016-05-26 20:30:524824 ASSERT_TRUE(response);
4825 ASSERT_TRUE(response->headers);
[email protected]dc7bd1c52010-11-12 00:01:134826 EXPECT_EQ(407, response->headers->response_code());
4827 EXPECT_TRUE(response->was_fetched_via_spdy);
asanka098c0092016-06-16 20:18:434828 EXPECT_TRUE(CheckBasicSecureProxyAuth(response->auth_challenge.get()));
[email protected]dc7bd1c52010-11-12 00:01:134829
[email protected]49639fa2011-12-20 23:22:414830 TestCompletionCallback callback2;
[email protected]dc7bd1c52010-11-12 00:01:134831
bnc691fda62016-08-12 00:43:164832 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar), callback2.callback());
robpercival214763f2016-07-01 23:27:014833 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]dc7bd1c52010-11-12 00:01:134834
4835 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:014836 EXPECT_THAT(rv, IsOk());
[email protected]dc7bd1c52010-11-12 00:01:134837
bnc691fda62016-08-12 00:43:164838 const HttpResponseInfo* const response_restart = trans.GetResponseInfo();
[email protected]dc7bd1c52010-11-12 00:01:134839
wezca1070932016-05-26 20:30:524840 ASSERT_TRUE(response_restart);
4841 ASSERT_TRUE(response_restart->headers);
[email protected]dc7bd1c52010-11-12 00:01:134842 EXPECT_EQ(200, response_restart->headers->response_code());
4843 // The password prompt info should not be set.
wezca1070932016-05-26 20:30:524844 EXPECT_FALSE(response_restart->auth_challenge);
[email protected]dc7bd1c52010-11-12 00:01:134845}
4846
[email protected]d9da5fe2010-10-13 22:37:164847// Test a SPDY CONNECT through an HTTPS Proxy to an HTTPS (non-SPDY) Server.
bncd16676a2016-07-20 16:23:014848TEST_F(HttpNetworkTransactionTest, HttpsProxySpdyConnectHttps) {
[email protected]cb9bf6ca2011-01-28 13:15:274849 HttpRequestInfo request;
4850 request.method = "GET";
bncce36dca22015-04-21 22:11:234851 request.url = GURL("https://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:274852
[email protected]d9da5fe2010-10-13 22:37:164853 // Configure against https proxy server "proxy:70".
rdsmith82957ad2015-09-16 19:42:034854 session_deps_.proxy_service = ProxyService::CreateFixed("https://proxy:70");
vishal.b62985ca92015-04-17 08:45:514855 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:074856 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:094857 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]d9da5fe2010-10-13 22:37:164858
bnc691fda62016-08-12 00:43:164859 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]d9da5fe2010-10-13 22:37:164860
bncce36dca22015-04-21 22:11:234861 // CONNECT to www.example.org:443 via SPDY
bncdf80d44fd2016-07-15 20:27:414862 SpdySerializedFrame connect(spdy_util_.ConstructSpdyConnect(
bncce36dca22015-04-21 22:11:234863 NULL, 0, 1, LOWEST, HostPortPair("www.example.org", 443)));
4864 // fetch https://www.example.org/ via HTTP
[email protected]d9da5fe2010-10-13 22:37:164865
bncce36dca22015-04-21 22:11:234866 const char get[] =
4867 "GET / HTTP/1.1\r\n"
4868 "Host: www.example.org\r\n"
4869 "Connection: keep-alive\r\n\r\n";
bncdf80d44fd2016-07-15 20:27:414870 SpdySerializedFrame wrapped_get(
4871 spdy_util_.ConstructSpdyDataFrame(1, get, strlen(get), false));
bnc42331402016-07-25 13:36:154872 SpdySerializedFrame conn_resp(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
[email protected]d9da5fe2010-10-13 22:37:164873 const char resp[] = "HTTP/1.1 200 OK\r\n"
4874 "Content-Length: 10\r\n\r\n";
bncdf80d44fd2016-07-15 20:27:414875 SpdySerializedFrame wrapped_get_resp(
4876 spdy_util_.ConstructSpdyDataFrame(1, resp, strlen(resp), false));
4877 SpdySerializedFrame wrapped_body(
4878 spdy_util_.ConstructSpdyDataFrame(1, "1234567890", 10, false));
4879 SpdySerializedFrame window_update(
4880 spdy_util_.ConstructSpdyWindowUpdate(1, wrapped_get_resp.size()));
[email protected]8d2f7012012-02-16 00:08:044881
4882 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:414883 CreateMockWrite(connect, 0), CreateMockWrite(wrapped_get, 2),
4884 CreateMockWrite(window_update, 6),
[email protected]8d2f7012012-02-16 00:08:044885 };
4886
[email protected]d9da5fe2010-10-13 22:37:164887 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:414888 CreateMockRead(conn_resp, 1, ASYNC),
4889 CreateMockRead(wrapped_get_resp, 3, ASYNC),
4890 CreateMockRead(wrapped_body, 4, ASYNC),
4891 CreateMockRead(wrapped_body, 5, ASYNC),
rch8e6c6c42015-05-01 14:05:134892 MockRead(ASYNC, 0, 7),
[email protected]d9da5fe2010-10-13 22:37:164893 };
4894
rch8e6c6c42015-05-01 14:05:134895 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
4896 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:074897 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]d9da5fe2010-10-13 22:37:164898
[email protected]8ddf8322012-02-23 18:08:064899 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:364900 ssl.next_proto = kProtoHTTP2;
[email protected]bb88e1d32013-05-03 23:11:074901 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]8ddf8322012-02-23 18:08:064902 SSLSocketDataProvider ssl2(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:074903 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
[email protected]d9da5fe2010-10-13 22:37:164904
[email protected]49639fa2011-12-20 23:22:414905 TestCompletionCallback callback1;
[email protected]d9da5fe2010-10-13 22:37:164906
bnc691fda62016-08-12 00:43:164907 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:014908 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]d9da5fe2010-10-13 22:37:164909
4910 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:014911 ASSERT_THAT(rv, IsOk());
[email protected]d9da5fe2010-10-13 22:37:164912
[email protected]58e32bb2013-01-21 18:23:254913 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:164914 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]58e32bb2013-01-21 18:23:254915 TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_SSL_TIMES);
4916
bnc691fda62016-08-12 00:43:164917 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:524918 ASSERT_TRUE(response);
4919 ASSERT_TRUE(response->headers);
[email protected]d9da5fe2010-10-13 22:37:164920 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
4921
4922 std::string response_data;
bnc691fda62016-08-12 00:43:164923 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
[email protected]d9da5fe2010-10-13 22:37:164924 EXPECT_EQ("1234567890", response_data);
4925}
4926
4927// Test a SPDY CONNECT through an HTTPS Proxy to a SPDY server.
bncd16676a2016-07-20 16:23:014928TEST_F(HttpNetworkTransactionTest, HttpsProxySpdyConnectSpdy) {
4929 SpdyTestUtil spdy_util_wrapped;
rdsmithebb50aa2015-11-12 03:44:384930
[email protected]cb9bf6ca2011-01-28 13:15:274931 HttpRequestInfo request;
4932 request.method = "GET";
bncce36dca22015-04-21 22:11:234933 request.url = GURL("https://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:274934
[email protected]d9da5fe2010-10-13 22:37:164935 // Configure against https proxy server "proxy:70".
rdsmith82957ad2015-09-16 19:42:034936 session_deps_.proxy_service = ProxyService::CreateFixed("https://proxy:70");
vishal.b62985ca92015-04-17 08:45:514937 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:074938 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:094939 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]d9da5fe2010-10-13 22:37:164940
bnc691fda62016-08-12 00:43:164941 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]d9da5fe2010-10-13 22:37:164942
bncce36dca22015-04-21 22:11:234943 // CONNECT to www.example.org:443 via SPDY
bncdf80d44fd2016-07-15 20:27:414944 SpdySerializedFrame connect(spdy_util_.ConstructSpdyConnect(
bncce36dca22015-04-21 22:11:234945 NULL, 0, 1, LOWEST, HostPortPair("www.example.org", 443)));
4946 // fetch https://www.example.org/ via SPDY
4947 const char kMyUrl[] = "https://www.example.org/";
bncdf80d44fd2016-07-15 20:27:414948 SpdySerializedFrame get(
bnc38dcd392016-02-09 23:19:494949 spdy_util_wrapped.ConstructSpdyGet(kMyUrl, 1, LOWEST));
bncdf80d44fd2016-07-15 20:27:414950 SpdySerializedFrame wrapped_get(spdy_util_.ConstructWrappedSpdyFrame(get, 1));
bnc42331402016-07-25 13:36:154951 SpdySerializedFrame conn_resp(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
bncdf80d44fd2016-07-15 20:27:414952 SpdySerializedFrame get_resp(
bnc42331402016-07-25 13:36:154953 spdy_util_wrapped.ConstructSpdyGetReply(NULL, 0, 1));
bncdf80d44fd2016-07-15 20:27:414954 SpdySerializedFrame wrapped_get_resp(
[email protected]23e482282013-06-14 16:08:024955 spdy_util_.ConstructWrappedSpdyFrame(get_resp, 1));
bncdf80d44fd2016-07-15 20:27:414956 SpdySerializedFrame body(spdy_util_wrapped.ConstructSpdyDataFrame(1, true));
4957 SpdySerializedFrame wrapped_body(
[email protected]23e482282013-06-14 16:08:024958 spdy_util_.ConstructWrappedSpdyFrame(body, 1));
bncdf80d44fd2016-07-15 20:27:414959 SpdySerializedFrame window_update_get_resp(
4960 spdy_util_.ConstructSpdyWindowUpdate(1, wrapped_get_resp.size()));
4961 SpdySerializedFrame window_update_body(
4962 spdy_util_.ConstructSpdyWindowUpdate(1, wrapped_body.size()));
[email protected]8d2f7012012-02-16 00:08:044963
4964 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:414965 CreateMockWrite(connect, 0), CreateMockWrite(wrapped_get, 2),
4966 CreateMockWrite(window_update_get_resp, 6),
4967 CreateMockWrite(window_update_body, 7),
[email protected]8d2f7012012-02-16 00:08:044968 };
4969
[email protected]d9da5fe2010-10-13 22:37:164970 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:414971 CreateMockRead(conn_resp, 1, ASYNC),
rch32320842015-05-16 15:57:094972 MockRead(ASYNC, ERR_IO_PENDING, 3),
bncdf80d44fd2016-07-15 20:27:414973 CreateMockRead(wrapped_get_resp, 4, ASYNC),
4974 CreateMockRead(wrapped_body, 5, ASYNC),
rch8e6c6c42015-05-01 14:05:134975 MockRead(ASYNC, 0, 8),
[email protected]d9da5fe2010-10-13 22:37:164976 };
4977
rch32320842015-05-16 15:57:094978 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
4979 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:074980 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]d9da5fe2010-10-13 22:37:164981
[email protected]8ddf8322012-02-23 18:08:064982 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:364983 ssl.next_proto = kProtoHTTP2;
[email protected]bb88e1d32013-05-03 23:11:074984 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]8ddf8322012-02-23 18:08:064985 SSLSocketDataProvider ssl2(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:364986 ssl2.next_proto = kProtoHTTP2;
[email protected]bb88e1d32013-05-03 23:11:074987 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
[email protected]d9da5fe2010-10-13 22:37:164988
[email protected]49639fa2011-12-20 23:22:414989 TestCompletionCallback callback1;
[email protected]d9da5fe2010-10-13 22:37:164990
bnc691fda62016-08-12 00:43:164991 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:014992 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]d9da5fe2010-10-13 22:37:164993
rch32320842015-05-16 15:57:094994 // Allow the SpdyProxyClientSocket's write callback to complete.
fdoray92e35a72016-06-10 15:54:554995 base::RunLoop().RunUntilIdle();
rch32320842015-05-16 15:57:094996 // Now allow the read of the response to complete.
mmenkee24011922015-12-17 22:12:594997 spdy_data.Resume();
[email protected]d9da5fe2010-10-13 22:37:164998 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:014999 EXPECT_THAT(rv, IsOk());
[email protected]d9da5fe2010-10-13 22:37:165000
[email protected]58e32bb2013-01-21 18:23:255001 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:165002 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]58e32bb2013-01-21 18:23:255003 TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_SSL_TIMES);
5004
bnc691fda62016-08-12 00:43:165005 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:525006 ASSERT_TRUE(response);
5007 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:025008 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]d9da5fe2010-10-13 22:37:165009
5010 std::string response_data;
bnc691fda62016-08-12 00:43:165011 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
[email protected]448d4ca52012-03-04 04:12:235012 EXPECT_EQ(kUploadData, response_data);
[email protected]d9da5fe2010-10-13 22:37:165013}
5014
5015// Test a SPDY CONNECT failure through an HTTPS Proxy.
bncd16676a2016-07-20 16:23:015016TEST_F(HttpNetworkTransactionTest, HttpsProxySpdyConnectFailure) {
[email protected]cb9bf6ca2011-01-28 13:15:275017 HttpRequestInfo request;
5018 request.method = "GET";
bncce36dca22015-04-21 22:11:235019 request.url = GURL("https://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:275020
[email protected]d9da5fe2010-10-13 22:37:165021 // Configure against https proxy server "proxy:70".
rdsmith82957ad2015-09-16 19:42:035022 session_deps_.proxy_service = ProxyService::CreateFixed("https://proxy:70");
vishal.b62985ca92015-04-17 08:45:515023 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:075024 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:095025 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]d9da5fe2010-10-13 22:37:165026
bnc691fda62016-08-12 00:43:165027 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]d9da5fe2010-10-13 22:37:165028
bncce36dca22015-04-21 22:11:235029 // CONNECT to www.example.org:443 via SPDY
bncdf80d44fd2016-07-15 20:27:415030 SpdySerializedFrame connect(spdy_util_.ConstructSpdyConnect(
bncce36dca22015-04-21 22:11:235031 NULL, 0, 1, LOWEST, HostPortPair("www.example.org", 443)));
bncdf80d44fd2016-07-15 20:27:415032 SpdySerializedFrame get(
diannahu9904e272017-02-03 14:40:085033 spdy_util_.ConstructSpdyRstStream(1, ERROR_CODE_CANCEL));
[email protected]d9da5fe2010-10-13 22:37:165034
5035 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:415036 CreateMockWrite(connect, 0), CreateMockWrite(get, 2),
[email protected]d9da5fe2010-10-13 22:37:165037 };
5038
bnc42331402016-07-25 13:36:155039 SpdySerializedFrame resp(spdy_util_.ConstructSpdyReplyError(1));
bncdf80d44fd2016-07-15 20:27:415040 SpdySerializedFrame data(spdy_util_.ConstructSpdyDataFrame(1, true));
[email protected]d9da5fe2010-10-13 22:37:165041 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:415042 CreateMockRead(resp, 1, ASYNC), MockRead(ASYNC, 0, 3),
[email protected]d9da5fe2010-10-13 22:37:165043 };
5044
rch8e6c6c42015-05-01 14:05:135045 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
5046 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:075047 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]d9da5fe2010-10-13 22:37:165048
[email protected]8ddf8322012-02-23 18:08:065049 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:365050 ssl.next_proto = kProtoHTTP2;
[email protected]bb88e1d32013-05-03 23:11:075051 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]8ddf8322012-02-23 18:08:065052 SSLSocketDataProvider ssl2(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:365053 ssl2.next_proto = kProtoHTTP2;
[email protected]bb88e1d32013-05-03 23:11:075054 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
[email protected]d9da5fe2010-10-13 22:37:165055
[email protected]49639fa2011-12-20 23:22:415056 TestCompletionCallback callback1;
[email protected]d9da5fe2010-10-13 22:37:165057
bnc691fda62016-08-12 00:43:165058 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:015059 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]d9da5fe2010-10-13 22:37:165060
5061 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:015062 EXPECT_THAT(rv, IsError(ERR_TUNNEL_CONNECTION_FAILED));
[email protected]d9da5fe2010-10-13 22:37:165063
ttuttle960fcbf2016-04-19 13:26:325064 // TODO(juliatuttle): Anything else to check here?
[email protected]d9da5fe2010-10-13 22:37:165065}
5066
[email protected]f6c63db52013-02-02 00:35:225067// Test load timing in the case of two HTTPS (non-SPDY) requests through a SPDY
5068// HTTPS Proxy to different servers.
bncd16676a2016-07-20 16:23:015069TEST_F(HttpNetworkTransactionTest,
[email protected]f6c63db52013-02-02 00:35:225070 HttpsProxySpdyConnectHttpsLoadTimingTwoRequestsTwoServers) {
5071 // Configure against https proxy server "proxy:70".
rdsmith82957ad2015-09-16 19:42:035072 session_deps_.proxy_service = ProxyService::CreateFixed("https://proxy:70");
vishal.b62985ca92015-04-17 08:45:515073 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:075074 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:095075 std::unique_ptr<HttpNetworkSession> session(
mmenke11eb5152015-06-09 14:50:505076 SpdySessionDependencies::SpdyCreateSession(&session_deps_));
[email protected]f6c63db52013-02-02 00:35:225077
5078 HttpRequestInfo request1;
5079 request1.method = "GET";
bncce36dca22015-04-21 22:11:235080 request1.url = GURL("https://www.example.org/");
[email protected]f6c63db52013-02-02 00:35:225081 request1.load_flags = 0;
5082
5083 HttpRequestInfo request2;
5084 request2.method = "GET";
bncce36dca22015-04-21 22:11:235085 request2.url = GURL("https://mail.example.org/");
[email protected]f6c63db52013-02-02 00:35:225086 request2.load_flags = 0;
5087
bncce36dca22015-04-21 22:11:235088 // CONNECT to www.example.org:443 via SPDY.
bncdf80d44fd2016-07-15 20:27:415089 SpdySerializedFrame connect1(spdy_util_.ConstructSpdyConnect(
bncce36dca22015-04-21 22:11:235090 NULL, 0, 1, LOWEST, HostPortPair("www.example.org", 443)));
bnc42331402016-07-25 13:36:155091 SpdySerializedFrame conn_resp1(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
[email protected]f6c63db52013-02-02 00:35:225092
bncce36dca22015-04-21 22:11:235093 // Fetch https://www.example.org/ via HTTP.
5094 const char get1[] =
5095 "GET / HTTP/1.1\r\n"
5096 "Host: www.example.org\r\n"
[email protected]f6c63db52013-02-02 00:35:225097 "Connection: keep-alive\r\n\r\n";
bncdf80d44fd2016-07-15 20:27:415098 SpdySerializedFrame wrapped_get1(
5099 spdy_util_.ConstructSpdyDataFrame(1, get1, strlen(get1), false));
[email protected]f6c63db52013-02-02 00:35:225100 const char resp1[] = "HTTP/1.1 200 OK\r\n"
5101 "Content-Length: 1\r\n\r\n";
bncdf80d44fd2016-07-15 20:27:415102 SpdySerializedFrame wrapped_get_resp1(
5103 spdy_util_.ConstructSpdyDataFrame(1, resp1, strlen(resp1), false));
5104 SpdySerializedFrame wrapped_body1(
5105 spdy_util_.ConstructSpdyDataFrame(1, "1", 1, false));
5106 SpdySerializedFrame window_update(
5107 spdy_util_.ConstructSpdyWindowUpdate(1, wrapped_get_resp1.size()));
[email protected]f6c63db52013-02-02 00:35:225108
bncce36dca22015-04-21 22:11:235109 // CONNECT to mail.example.org:443 via SPDY.
[email protected]745aa9c2014-06-27 02:21:295110 SpdyHeaderBlock connect2_block;
5111 connect2_block[spdy_util_.GetMethodKey()] = "CONNECT";
bnca9b9e222016-07-11 20:10:405112 connect2_block[spdy_util_.GetHostKey()] = "mail.example.org:443";
bnc42331402016-07-25 13:36:155113 SpdySerializedFrame connect2(spdy_util_.ConstructSpdyHeaders(
5114 3, std::move(connect2_block), LOWEST, false));
[email protected]601e03f12014-04-06 16:26:395115
bnc42331402016-07-25 13:36:155116 SpdySerializedFrame conn_resp2(spdy_util_.ConstructSpdyGetReply(NULL, 0, 3));
[email protected]f6c63db52013-02-02 00:35:225117
bncce36dca22015-04-21 22:11:235118 // Fetch https://mail.example.org/ via HTTP.
5119 const char get2[] =
5120 "GET / HTTP/1.1\r\n"
5121 "Host: mail.example.org\r\n"
[email protected]f6c63db52013-02-02 00:35:225122 "Connection: keep-alive\r\n\r\n";
bncdf80d44fd2016-07-15 20:27:415123 SpdySerializedFrame wrapped_get2(
5124 spdy_util_.ConstructSpdyDataFrame(3, get2, strlen(get2), false));
[email protected]f6c63db52013-02-02 00:35:225125 const char resp2[] = "HTTP/1.1 200 OK\r\n"
5126 "Content-Length: 2\r\n\r\n";
bncdf80d44fd2016-07-15 20:27:415127 SpdySerializedFrame wrapped_get_resp2(
5128 spdy_util_.ConstructSpdyDataFrame(3, resp2, strlen(resp2), false));
5129 SpdySerializedFrame wrapped_body2(
5130 spdy_util_.ConstructSpdyDataFrame(3, "22", 2, false));
[email protected]f6c63db52013-02-02 00:35:225131
5132 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:415133 CreateMockWrite(connect1, 0), CreateMockWrite(wrapped_get1, 2),
5134 CreateMockWrite(connect2, 5), CreateMockWrite(wrapped_get2, 7),
[email protected]f6c63db52013-02-02 00:35:225135 };
5136
5137 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:415138 CreateMockRead(conn_resp1, 1, ASYNC),
5139 CreateMockRead(wrapped_get_resp1, 3, ASYNC),
5140 CreateMockRead(wrapped_body1, 4, ASYNC),
5141 CreateMockRead(conn_resp2, 6, ASYNC),
5142 CreateMockRead(wrapped_get_resp2, 8, ASYNC),
5143 CreateMockRead(wrapped_body2, 9, ASYNC),
5144 MockRead(ASYNC, 0, 10),
[email protected]f6c63db52013-02-02 00:35:225145 };
5146
mmenke11eb5152015-06-09 14:50:505147 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
5148 arraysize(spdy_writes));
5149 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]f6c63db52013-02-02 00:35:225150
5151 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:365152 ssl.next_proto = kProtoHTTP2;
mmenke11eb5152015-06-09 14:50:505153 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]f6c63db52013-02-02 00:35:225154 SSLSocketDataProvider ssl2(ASYNC, OK);
mmenke11eb5152015-06-09 14:50:505155 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
[email protected]f6c63db52013-02-02 00:35:225156 SSLSocketDataProvider ssl3(ASYNC, OK);
mmenke11eb5152015-06-09 14:50:505157 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl3);
[email protected]f6c63db52013-02-02 00:35:225158
5159 TestCompletionCallback callback;
5160
bnc691fda62016-08-12 00:43:165161 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:205162 int rv = trans.Start(&request1, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:015163 EXPECT_THAT(callback.GetResult(rv), IsOk());
[email protected]f6c63db52013-02-02 00:35:225164
5165 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:165166 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]f6c63db52013-02-02 00:35:225167 TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_SSL_TIMES);
5168
bnc691fda62016-08-12 00:43:165169 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:525170 ASSERT_TRUE(response);
5171 ASSERT_TRUE(response->headers);
[email protected]f6c63db52013-02-02 00:35:225172 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
5173
5174 std::string response_data;
ttuttle859dc7a2015-04-23 19:42:295175 scoped_refptr<IOBuffer> buf(new IOBuffer(256));
bnc691fda62016-08-12 00:43:165176 rv = trans.Read(buf.get(), 256, callback.callback());
mmenke11eb5152015-06-09 14:50:505177 EXPECT_EQ(1, callback.GetResult(rv));
[email protected]f6c63db52013-02-02 00:35:225178
bnc691fda62016-08-12 00:43:165179 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:205180 rv = trans2.Start(&request2, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:015181 EXPECT_THAT(callback.GetResult(rv), IsOk());
[email protected]f6c63db52013-02-02 00:35:225182
5183 LoadTimingInfo load_timing_info2;
bnc691fda62016-08-12 00:43:165184 EXPECT_TRUE(trans2.GetLoadTimingInfo(&load_timing_info2));
[email protected]f6c63db52013-02-02 00:35:225185 // Even though the SPDY connection is reused, a new tunnelled connection has
5186 // to be created, so the socket's load timing looks like a fresh connection.
5187 TestLoadTimingNotReused(load_timing_info2, CONNECT_TIMING_HAS_SSL_TIMES);
5188
5189 // The requests should have different IDs, since they each are using their own
5190 // separate stream.
5191 EXPECT_NE(load_timing_info.socket_log_id, load_timing_info2.socket_log_id);
5192
bnc691fda62016-08-12 00:43:165193 rv = trans2.Read(buf.get(), 256, callback.callback());
mmenke11eb5152015-06-09 14:50:505194 EXPECT_EQ(2, callback.GetResult(rv));
[email protected]f6c63db52013-02-02 00:35:225195}
5196
5197// Test load timing in the case of two HTTPS (non-SPDY) requests through a SPDY
5198// HTTPS Proxy to the same server.
bncd16676a2016-07-20 16:23:015199TEST_F(HttpNetworkTransactionTest,
[email protected]f6c63db52013-02-02 00:35:225200 HttpsProxySpdyConnectHttpsLoadTimingTwoRequestsSameServer) {
5201 // Configure against https proxy server "proxy:70".
rdsmith82957ad2015-09-16 19:42:035202 session_deps_.proxy_service = ProxyService::CreateFixed("https://proxy:70");
vishal.b62985ca92015-04-17 08:45:515203 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:075204 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:095205 std::unique_ptr<HttpNetworkSession> session(
mmenke11eb5152015-06-09 14:50:505206 SpdySessionDependencies::SpdyCreateSession(&session_deps_));
[email protected]f6c63db52013-02-02 00:35:225207
5208 HttpRequestInfo request1;
5209 request1.method = "GET";
bncce36dca22015-04-21 22:11:235210 request1.url = GURL("https://www.example.org/");
[email protected]f6c63db52013-02-02 00:35:225211 request1.load_flags = 0;
5212
5213 HttpRequestInfo request2;
5214 request2.method = "GET";
bncce36dca22015-04-21 22:11:235215 request2.url = GURL("https://www.example.org/2");
[email protected]f6c63db52013-02-02 00:35:225216 request2.load_flags = 0;
5217
bncce36dca22015-04-21 22:11:235218 // CONNECT to www.example.org:443 via SPDY.
bncdf80d44fd2016-07-15 20:27:415219 SpdySerializedFrame connect1(spdy_util_.ConstructSpdyConnect(
bncce36dca22015-04-21 22:11:235220 NULL, 0, 1, LOWEST, HostPortPair("www.example.org", 443)));
bnc42331402016-07-25 13:36:155221 SpdySerializedFrame conn_resp1(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
[email protected]f6c63db52013-02-02 00:35:225222
bncce36dca22015-04-21 22:11:235223 // Fetch https://www.example.org/ via HTTP.
5224 const char get1[] =
5225 "GET / HTTP/1.1\r\n"
5226 "Host: www.example.org\r\n"
[email protected]f6c63db52013-02-02 00:35:225227 "Connection: keep-alive\r\n\r\n";
bncdf80d44fd2016-07-15 20:27:415228 SpdySerializedFrame wrapped_get1(
5229 spdy_util_.ConstructSpdyDataFrame(1, get1, strlen(get1), false));
[email protected]f6c63db52013-02-02 00:35:225230 const char resp1[] = "HTTP/1.1 200 OK\r\n"
5231 "Content-Length: 1\r\n\r\n";
bncdf80d44fd2016-07-15 20:27:415232 SpdySerializedFrame wrapped_get_resp1(
5233 spdy_util_.ConstructSpdyDataFrame(1, resp1, strlen(resp1), false));
5234 SpdySerializedFrame wrapped_body1(
5235 spdy_util_.ConstructSpdyDataFrame(1, "1", 1, false));
5236 SpdySerializedFrame window_update(
5237 spdy_util_.ConstructSpdyWindowUpdate(1, wrapped_get_resp1.size()));
[email protected]f6c63db52013-02-02 00:35:225238
bncce36dca22015-04-21 22:11:235239 // Fetch https://www.example.org/2 via HTTP.
5240 const char get2[] =
5241 "GET /2 HTTP/1.1\r\n"
5242 "Host: www.example.org\r\n"
[email protected]f6c63db52013-02-02 00:35:225243 "Connection: keep-alive\r\n\r\n";
bncdf80d44fd2016-07-15 20:27:415244 SpdySerializedFrame wrapped_get2(
5245 spdy_util_.ConstructSpdyDataFrame(1, get2, strlen(get2), false));
[email protected]f6c63db52013-02-02 00:35:225246 const char resp2[] = "HTTP/1.1 200 OK\r\n"
5247 "Content-Length: 2\r\n\r\n";
bncdf80d44fd2016-07-15 20:27:415248 SpdySerializedFrame wrapped_get_resp2(
5249 spdy_util_.ConstructSpdyDataFrame(1, resp2, strlen(resp2), false));
5250 SpdySerializedFrame wrapped_body2(
5251 spdy_util_.ConstructSpdyDataFrame(1, "22", 2, false));
[email protected]f6c63db52013-02-02 00:35:225252
5253 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:415254 CreateMockWrite(connect1, 0), CreateMockWrite(wrapped_get1, 2),
5255 CreateMockWrite(wrapped_get2, 5),
[email protected]f6c63db52013-02-02 00:35:225256 };
5257
5258 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:415259 CreateMockRead(conn_resp1, 1, ASYNC),
5260 CreateMockRead(wrapped_get_resp1, 3, ASYNC),
bnceb9aa7112017-01-05 01:03:465261 CreateMockRead(wrapped_body1, 4, SYNCHRONOUS),
bncdf80d44fd2016-07-15 20:27:415262 CreateMockRead(wrapped_get_resp2, 6, ASYNC),
bnceb9aa7112017-01-05 01:03:465263 CreateMockRead(wrapped_body2, 7, SYNCHRONOUS),
bncdf80d44fd2016-07-15 20:27:415264 MockRead(ASYNC, 0, 8),
[email protected]f6c63db52013-02-02 00:35:225265 };
5266
mmenke11eb5152015-06-09 14:50:505267 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
5268 arraysize(spdy_writes));
5269 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]f6c63db52013-02-02 00:35:225270
5271 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:365272 ssl.next_proto = kProtoHTTP2;
mmenke11eb5152015-06-09 14:50:505273 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]f6c63db52013-02-02 00:35:225274 SSLSocketDataProvider ssl2(ASYNC, OK);
mmenke11eb5152015-06-09 14:50:505275 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
[email protected]f6c63db52013-02-02 00:35:225276
5277 TestCompletionCallback callback;
5278
bnc691fda62016-08-12 00:43:165279 std::unique_ptr<HttpNetworkTransaction> trans(
[email protected]90499482013-06-01 00:39:505280 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
tfarina42834112016-09-22 13:38:205281 int rv = trans->Start(&request1, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:015282 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]f6c63db52013-02-02 00:35:225283
5284 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:015285 EXPECT_THAT(rv, IsOk());
[email protected]f6c63db52013-02-02 00:35:225286
5287 LoadTimingInfo load_timing_info;
5288 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
5289 TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_SSL_TIMES);
5290
5291 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:525292 ASSERT_TRUE(response);
5293 ASSERT_TRUE(response->headers);
[email protected]f6c63db52013-02-02 00:35:225294 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
5295
5296 std::string response_data;
ttuttle859dc7a2015-04-23 19:42:295297 scoped_refptr<IOBuffer> buf(new IOBuffer(256));
[email protected]90499482013-06-01 00:39:505298 EXPECT_EQ(1, trans->Read(buf.get(), 256, callback.callback()));
[email protected]f6c63db52013-02-02 00:35:225299 trans.reset();
5300
bnc691fda62016-08-12 00:43:165301 std::unique_ptr<HttpNetworkTransaction> trans2(
[email protected]90499482013-06-01 00:39:505302 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
tfarina42834112016-09-22 13:38:205303 rv = trans2->Start(&request2, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:015304 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]f6c63db52013-02-02 00:35:225305
[email protected]f6c63db52013-02-02 00:35:225306 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:015307 EXPECT_THAT(rv, IsOk());
[email protected]f6c63db52013-02-02 00:35:225308
5309 LoadTimingInfo load_timing_info2;
5310 EXPECT_TRUE(trans2->GetLoadTimingInfo(&load_timing_info2));
5311 TestLoadTimingReused(load_timing_info2);
5312
5313 // The requests should have the same ID.
5314 EXPECT_EQ(load_timing_info.socket_log_id, load_timing_info2.socket_log_id);
5315
[email protected]90499482013-06-01 00:39:505316 EXPECT_EQ(2, trans2->Read(buf.get(), 256, callback.callback()));
[email protected]f6c63db52013-02-02 00:35:225317}
5318
5319// Test load timing in the case of of two HTTP requests through a SPDY HTTPS
5320// Proxy to different servers.
bncd16676a2016-07-20 16:23:015321TEST_F(HttpNetworkTransactionTest, HttpsProxySpdyLoadTimingTwoHttpRequests) {
[email protected]f6c63db52013-02-02 00:35:225322 // Configure against https proxy server "proxy:70".
rdsmith82957ad2015-09-16 19:42:035323 session_deps_.proxy_service = ProxyService::CreateFixed("https://proxy:70");
vishal.b62985ca92015-04-17 08:45:515324 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:075325 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:095326 std::unique_ptr<HttpNetworkSession> session(
mmenke11eb5152015-06-09 14:50:505327 SpdySessionDependencies::SpdyCreateSession(&session_deps_));
[email protected]f6c63db52013-02-02 00:35:225328
5329 HttpRequestInfo request1;
5330 request1.method = "GET";
bncce36dca22015-04-21 22:11:235331 request1.url = GURL("http://www.example.org/");
[email protected]f6c63db52013-02-02 00:35:225332 request1.load_flags = 0;
5333
5334 HttpRequestInfo request2;
5335 request2.method = "GET";
bncce36dca22015-04-21 22:11:235336 request2.url = GURL("http://mail.example.org/");
[email protected]f6c63db52013-02-02 00:35:225337 request2.load_flags = 0;
5338
bncce36dca22015-04-21 22:11:235339 // http://www.example.org/
bnc086b39e12016-06-24 13:05:265340 SpdyHeaderBlock headers(
bncce36dca22015-04-21 22:11:235341 spdy_util_.ConstructGetHeaderBlockForProxy("http://www.example.org/"));
bncdf80d44fd2016-07-15 20:27:415342 SpdySerializedFrame get1(
bnc42331402016-07-25 13:36:155343 spdy_util_.ConstructSpdyHeaders(1, std::move(headers), LOWEST, true));
5344 SpdySerializedFrame get_resp1(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
bncdf80d44fd2016-07-15 20:27:415345 SpdySerializedFrame body1(spdy_util_.ConstructSpdyDataFrame(1, "1", 1, true));
rdsmithebb50aa2015-11-12 03:44:385346 spdy_util_.UpdateWithStreamDestruction(1);
[email protected]f6c63db52013-02-02 00:35:225347
bncce36dca22015-04-21 22:11:235348 // http://mail.example.org/
bnc086b39e12016-06-24 13:05:265349 SpdyHeaderBlock headers2(
bncce36dca22015-04-21 22:11:235350 spdy_util_.ConstructGetHeaderBlockForProxy("http://mail.example.org/"));
bncdf80d44fd2016-07-15 20:27:415351 SpdySerializedFrame get2(
bnc42331402016-07-25 13:36:155352 spdy_util_.ConstructSpdyHeaders(3, std::move(headers2), LOWEST, true));
5353 SpdySerializedFrame get_resp2(spdy_util_.ConstructSpdyGetReply(NULL, 0, 3));
bncdf80d44fd2016-07-15 20:27:415354 SpdySerializedFrame body2(
5355 spdy_util_.ConstructSpdyDataFrame(3, "22", 2, true));
[email protected]f6c63db52013-02-02 00:35:225356
5357 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:415358 CreateMockWrite(get1, 0), CreateMockWrite(get2, 3),
[email protected]f6c63db52013-02-02 00:35:225359 };
5360
5361 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:415362 CreateMockRead(get_resp1, 1, ASYNC),
5363 CreateMockRead(body1, 2, ASYNC),
5364 CreateMockRead(get_resp2, 4, ASYNC),
5365 CreateMockRead(body2, 5, ASYNC),
5366 MockRead(ASYNC, 0, 6),
[email protected]f6c63db52013-02-02 00:35:225367 };
5368
mmenke11eb5152015-06-09 14:50:505369 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
5370 arraysize(spdy_writes));
5371 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]f6c63db52013-02-02 00:35:225372
5373 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:365374 ssl.next_proto = kProtoHTTP2;
mmenke11eb5152015-06-09 14:50:505375 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]f6c63db52013-02-02 00:35:225376
5377 TestCompletionCallback callback;
5378
bnc691fda62016-08-12 00:43:165379 std::unique_ptr<HttpNetworkTransaction> trans(
[email protected]90499482013-06-01 00:39:505380 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
tfarina42834112016-09-22 13:38:205381 int rv = trans->Start(&request1, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:015382 EXPECT_THAT(callback.GetResult(rv), IsOk());
[email protected]f6c63db52013-02-02 00:35:225383
5384 LoadTimingInfo load_timing_info;
5385 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
5386 TestLoadTimingNotReused(load_timing_info,
5387 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
5388
5389 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:525390 ASSERT_TRUE(response);
5391 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:025392 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]f6c63db52013-02-02 00:35:225393
5394 std::string response_data;
ttuttle859dc7a2015-04-23 19:42:295395 scoped_refptr<IOBuffer> buf(new IOBuffer(256));
mmenke11eb5152015-06-09 14:50:505396 rv = trans->Read(buf.get(), 256, callback.callback());
5397 EXPECT_EQ(1, callback.GetResult(rv));
[email protected]f6c63db52013-02-02 00:35:225398 // Delete the first request, so the second one can reuse the socket.
5399 trans.reset();
5400
bnc691fda62016-08-12 00:43:165401 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:205402 rv = trans2.Start(&request2, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:015403 EXPECT_THAT(callback.GetResult(rv), IsOk());
[email protected]f6c63db52013-02-02 00:35:225404
5405 LoadTimingInfo load_timing_info2;
bnc691fda62016-08-12 00:43:165406 EXPECT_TRUE(trans2.GetLoadTimingInfo(&load_timing_info2));
[email protected]f6c63db52013-02-02 00:35:225407 TestLoadTimingReused(load_timing_info2);
5408
5409 // The requests should have the same ID.
5410 EXPECT_EQ(load_timing_info.socket_log_id, load_timing_info2.socket_log_id);
5411
bnc691fda62016-08-12 00:43:165412 rv = trans2.Read(buf.get(), 256, callback.callback());
mmenke11eb5152015-06-09 14:50:505413 EXPECT_EQ(2, callback.GetResult(rv));
[email protected]f6c63db52013-02-02 00:35:225414}
5415
[email protected]2df19bb2010-08-25 20:13:465416// Test the challenge-response-retry sequence through an HTTPS Proxy
bncd16676a2016-07-20 16:23:015417TEST_F(HttpNetworkTransactionTest, HttpsProxyAuthRetry) {
[email protected]2df19bb2010-08-25 20:13:465418 HttpRequestInfo request;
5419 request.method = "GET";
bncce36dca22015-04-21 22:11:235420 request.url = GURL("http://www.example.org/");
[email protected]2df19bb2010-08-25 20:13:465421 // when the no authentication data flag is set.
ttuttle859dc7a2015-04-23 19:42:295422 request.load_flags = LOAD_DO_NOT_SEND_AUTH_DATA;
[email protected]2df19bb2010-08-25 20:13:465423
[email protected]79cb5c12011-09-12 13:12:045424 // Configure against https proxy server "myproxy:70".
rdsmith82957ad2015-09-16 19:42:035425 session_deps_.proxy_service = ProxyService::CreateFixed("https://myproxy:70");
vishal.b62985ca92015-04-17 08:45:515426 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:075427 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:095428 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:275429
[email protected]2df19bb2010-08-25 20:13:465430 // Since we have proxy, should use full url
5431 MockWrite data_writes1[] = {
bnc691fda62016-08-12 00:43:165432 MockWrite("GET http://www.example.org/ HTTP/1.1\r\n"
5433 "Host: www.example.org\r\n"
5434 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]2df19bb2010-08-25 20:13:465435
bnc691fda62016-08-12 00:43:165436 // After calling trans.RestartWithAuth(), this is the request we should
bncce36dca22015-04-21 22:11:235437 // be issuing -- the final header line contains the credentials.
bnc691fda62016-08-12 00:43:165438 MockWrite("GET http://www.example.org/ HTTP/1.1\r\n"
5439 "Host: www.example.org\r\n"
5440 "Proxy-Connection: keep-alive\r\n"
5441 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]2df19bb2010-08-25 20:13:465442 };
5443
5444 // The proxy responds to the GET with a 407, using a persistent
5445 // connection.
5446 MockRead data_reads1[] = {
5447 // No credentials.
5448 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
5449 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
5450 MockRead("Proxy-Connection: keep-alive\r\n"),
5451 MockRead("Content-Length: 0\r\n\r\n"),
5452
5453 MockRead("HTTP/1.1 200 OK\r\n"),
5454 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
5455 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:065456 MockRead(SYNCHRONOUS, OK),
[email protected]2df19bb2010-08-25 20:13:465457 };
5458
5459 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
5460 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:075461 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8ddf8322012-02-23 18:08:065462 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:075463 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]2df19bb2010-08-25 20:13:465464
[email protected]49639fa2011-12-20 23:22:415465 TestCompletionCallback callback1;
[email protected]2df19bb2010-08-25 20:13:465466
bnc691fda62016-08-12 00:43:165467 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]0b0bf032010-09-21 18:08:505468
bnc691fda62016-08-12 00:43:165469 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:015470 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2df19bb2010-08-25 20:13:465471
5472 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:015473 EXPECT_THAT(rv, IsOk());
[email protected]2df19bb2010-08-25 20:13:465474
[email protected]58e32bb2013-01-21 18:23:255475 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:165476 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]58e32bb2013-01-21 18:23:255477 TestLoadTimingNotReused(load_timing_info,
5478 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
5479
bnc691fda62016-08-12 00:43:165480 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:525481 ASSERT_TRUE(response);
5482 ASSERT_TRUE(response->headers);
[email protected]2df19bb2010-08-25 20:13:465483 EXPECT_EQ(407, response->headers->response_code());
5484 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
asanka098c0092016-06-16 20:18:435485 EXPECT_TRUE(CheckBasicSecureProxyAuth(response->auth_challenge.get()));
[email protected]2df19bb2010-08-25 20:13:465486
[email protected]49639fa2011-12-20 23:22:415487 TestCompletionCallback callback2;
[email protected]2df19bb2010-08-25 20:13:465488
bnc691fda62016-08-12 00:43:165489 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar), callback2.callback());
robpercival214763f2016-07-01 23:27:015490 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2df19bb2010-08-25 20:13:465491
5492 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:015493 EXPECT_THAT(rv, IsOk());
[email protected]2df19bb2010-08-25 20:13:465494
[email protected]58e32bb2013-01-21 18:23:255495 load_timing_info = LoadTimingInfo();
bnc691fda62016-08-12 00:43:165496 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]58e32bb2013-01-21 18:23:255497 // Retrying with HTTP AUTH is considered to be reusing a socket.
5498 TestLoadTimingReused(load_timing_info);
5499
bnc691fda62016-08-12 00:43:165500 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:525501 ASSERT_TRUE(response);
[email protected]2df19bb2010-08-25 20:13:465502
5503 EXPECT_TRUE(response->headers->IsKeepAlive());
5504 EXPECT_EQ(200, response->headers->response_code());
5505 EXPECT_EQ(100, response->headers->GetContentLength());
5506 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
5507
5508 // The password prompt info should not be set.
wezca1070932016-05-26 20:30:525509 EXPECT_FALSE(response->auth_challenge);
[email protected]2df19bb2010-08-25 20:13:465510}
5511
[email protected]23e482282013-06-14 16:08:025512void HttpNetworkTransactionTest::ConnectStatusHelperWithExpectedStatus(
[email protected]c744cf22009-02-27 07:28:085513 const MockRead& status, int expected_status) {
[email protected]1c773ea12009-04-28 19:58:425514 HttpRequestInfo request;
[email protected]c744cf22009-02-27 07:28:085515 request.method = "GET";
bncce36dca22015-04-21 22:11:235516 request.url = GURL("https://www.example.org/");
[email protected]c744cf22009-02-27 07:28:085517
[email protected]cb9bf6ca2011-01-28 13:15:275518 // Configure against proxy server "myproxy:70".
rdsmith82957ad2015-09-16 19:42:035519 session_deps_.proxy_service = ProxyService::CreateFixed("myproxy:70");
danakj1fd259a02016-04-16 03:17:095520 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:275521
[email protected]c744cf22009-02-27 07:28:085522 // Since we have proxy, should try to establish tunnel.
5523 MockWrite data_writes[] = {
rsleevidb16bb02015-11-12 23:47:175524 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
5525 "Host: www.example.org:443\r\n"
5526 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]c744cf22009-02-27 07:28:085527 };
5528
5529 MockRead data_reads[] = {
mmenked39192ee2015-12-09 00:57:235530 status, MockRead("Content-Length: 10\r\n\r\n"),
5531 // No response body because the test stops reading here.
5532 MockRead(SYNCHRONOUS, ERR_UNEXPECTED),
[email protected]c744cf22009-02-27 07:28:085533 };
5534
[email protected]31a2bfe2010-02-09 08:03:395535 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
5536 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:075537 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]c744cf22009-02-27 07:28:085538
[email protected]49639fa2011-12-20 23:22:415539 TestCompletionCallback callback;
[email protected]c744cf22009-02-27 07:28:085540
bnc691fda62016-08-12 00:43:165541 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]0b0bf032010-09-21 18:08:505542
tfarina42834112016-09-22 13:38:205543 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:015544 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]c744cf22009-02-27 07:28:085545
5546 rv = callback.WaitForResult();
5547 EXPECT_EQ(expected_status, rv);
5548}
5549
[email protected]23e482282013-06-14 16:08:025550void HttpNetworkTransactionTest::ConnectStatusHelper(
[email protected]448d4ca52012-03-04 04:12:235551 const MockRead& status) {
[email protected]c744cf22009-02-27 07:28:085552 ConnectStatusHelperWithExpectedStatus(
[email protected]1c773ea12009-04-28 19:58:425553 status, ERR_TUNNEL_CONNECTION_FAILED);
[email protected]c744cf22009-02-27 07:28:085554}
5555
bncd16676a2016-07-20 16:23:015556TEST_F(HttpNetworkTransactionTest, ConnectStatus100) {
[email protected]c744cf22009-02-27 07:28:085557 ConnectStatusHelper(MockRead("HTTP/1.1 100 Continue\r\n"));
5558}
5559
bncd16676a2016-07-20 16:23:015560TEST_F(HttpNetworkTransactionTest, ConnectStatus101) {
[email protected]c744cf22009-02-27 07:28:085561 ConnectStatusHelper(MockRead("HTTP/1.1 101 Switching Protocols\r\n"));
5562}
5563
bncd16676a2016-07-20 16:23:015564TEST_F(HttpNetworkTransactionTest, ConnectStatus201) {
[email protected]c744cf22009-02-27 07:28:085565 ConnectStatusHelper(MockRead("HTTP/1.1 201 Created\r\n"));
5566}
5567
bncd16676a2016-07-20 16:23:015568TEST_F(HttpNetworkTransactionTest, ConnectStatus202) {
[email protected]c744cf22009-02-27 07:28:085569 ConnectStatusHelper(MockRead("HTTP/1.1 202 Accepted\r\n"));
5570}
5571
bncd16676a2016-07-20 16:23:015572TEST_F(HttpNetworkTransactionTest, ConnectStatus203) {
[email protected]c744cf22009-02-27 07:28:085573 ConnectStatusHelper(
5574 MockRead("HTTP/1.1 203 Non-Authoritative Information\r\n"));
5575}
5576
bncd16676a2016-07-20 16:23:015577TEST_F(HttpNetworkTransactionTest, ConnectStatus204) {
[email protected]c744cf22009-02-27 07:28:085578 ConnectStatusHelper(MockRead("HTTP/1.1 204 No Content\r\n"));
5579}
5580
bncd16676a2016-07-20 16:23:015581TEST_F(HttpNetworkTransactionTest, ConnectStatus205) {
[email protected]c744cf22009-02-27 07:28:085582 ConnectStatusHelper(MockRead("HTTP/1.1 205 Reset Content\r\n"));
5583}
5584
bncd16676a2016-07-20 16:23:015585TEST_F(HttpNetworkTransactionTest, ConnectStatus206) {
[email protected]c744cf22009-02-27 07:28:085586 ConnectStatusHelper(MockRead("HTTP/1.1 206 Partial Content\r\n"));
5587}
5588
bncd16676a2016-07-20 16:23:015589TEST_F(HttpNetworkTransactionTest, ConnectStatus300) {
[email protected]c744cf22009-02-27 07:28:085590 ConnectStatusHelper(MockRead("HTTP/1.1 300 Multiple Choices\r\n"));
5591}
5592
bncd16676a2016-07-20 16:23:015593TEST_F(HttpNetworkTransactionTest, ConnectStatus301) {
[email protected]c744cf22009-02-27 07:28:085594 ConnectStatusHelper(MockRead("HTTP/1.1 301 Moved Permanently\r\n"));
5595}
5596
bncd16676a2016-07-20 16:23:015597TEST_F(HttpNetworkTransactionTest, ConnectStatus302) {
[email protected]c744cf22009-02-27 07:28:085598 ConnectStatusHelper(MockRead("HTTP/1.1 302 Found\r\n"));
5599}
5600
bncd16676a2016-07-20 16:23:015601TEST_F(HttpNetworkTransactionTest, ConnectStatus303) {
[email protected]c744cf22009-02-27 07:28:085602 ConnectStatusHelper(MockRead("HTTP/1.1 303 See Other\r\n"));
5603}
5604
bncd16676a2016-07-20 16:23:015605TEST_F(HttpNetworkTransactionTest, ConnectStatus304) {
[email protected]c744cf22009-02-27 07:28:085606 ConnectStatusHelper(MockRead("HTTP/1.1 304 Not Modified\r\n"));
5607}
5608
bncd16676a2016-07-20 16:23:015609TEST_F(HttpNetworkTransactionTest, ConnectStatus305) {
[email protected]c744cf22009-02-27 07:28:085610 ConnectStatusHelper(MockRead("HTTP/1.1 305 Use Proxy\r\n"));
5611}
5612
bncd16676a2016-07-20 16:23:015613TEST_F(HttpNetworkTransactionTest, ConnectStatus306) {
[email protected]c744cf22009-02-27 07:28:085614 ConnectStatusHelper(MockRead("HTTP/1.1 306\r\n"));
5615}
5616
bncd16676a2016-07-20 16:23:015617TEST_F(HttpNetworkTransactionTest, ConnectStatus307) {
[email protected]c744cf22009-02-27 07:28:085618 ConnectStatusHelper(MockRead("HTTP/1.1 307 Temporary Redirect\r\n"));
5619}
5620
bncd16676a2016-07-20 16:23:015621TEST_F(HttpNetworkTransactionTest, ConnectStatus308) {
[email protected]0a17aab32014-04-24 03:32:375622 ConnectStatusHelper(MockRead("HTTP/1.1 308 Permanent Redirect\r\n"));
5623}
5624
bncd16676a2016-07-20 16:23:015625TEST_F(HttpNetworkTransactionTest, ConnectStatus400) {
[email protected]c744cf22009-02-27 07:28:085626 ConnectStatusHelper(MockRead("HTTP/1.1 400 Bad Request\r\n"));
5627}
5628
bncd16676a2016-07-20 16:23:015629TEST_F(HttpNetworkTransactionTest, ConnectStatus401) {
[email protected]c744cf22009-02-27 07:28:085630 ConnectStatusHelper(MockRead("HTTP/1.1 401 Unauthorized\r\n"));
5631}
5632
bncd16676a2016-07-20 16:23:015633TEST_F(HttpNetworkTransactionTest, ConnectStatus402) {
[email protected]c744cf22009-02-27 07:28:085634 ConnectStatusHelper(MockRead("HTTP/1.1 402 Payment Required\r\n"));
5635}
5636
bncd16676a2016-07-20 16:23:015637TEST_F(HttpNetworkTransactionTest, ConnectStatus403) {
[email protected]c744cf22009-02-27 07:28:085638 ConnectStatusHelper(MockRead("HTTP/1.1 403 Forbidden\r\n"));
5639}
5640
bncd16676a2016-07-20 16:23:015641TEST_F(HttpNetworkTransactionTest, ConnectStatus404) {
[email protected]c744cf22009-02-27 07:28:085642 ConnectStatusHelper(MockRead("HTTP/1.1 404 Not Found\r\n"));
5643}
5644
bncd16676a2016-07-20 16:23:015645TEST_F(HttpNetworkTransactionTest, ConnectStatus405) {
[email protected]c744cf22009-02-27 07:28:085646 ConnectStatusHelper(MockRead("HTTP/1.1 405 Method Not Allowed\r\n"));
5647}
5648
bncd16676a2016-07-20 16:23:015649TEST_F(HttpNetworkTransactionTest, ConnectStatus406) {
[email protected]c744cf22009-02-27 07:28:085650 ConnectStatusHelper(MockRead("HTTP/1.1 406 Not Acceptable\r\n"));
5651}
5652
bncd16676a2016-07-20 16:23:015653TEST_F(HttpNetworkTransactionTest, ConnectStatus407) {
[email protected]c744cf22009-02-27 07:28:085654 ConnectStatusHelperWithExpectedStatus(
5655 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
[email protected]a7ea8832010-07-12 17:54:545656 ERR_PROXY_AUTH_UNSUPPORTED);
[email protected]c744cf22009-02-27 07:28:085657}
5658
bncd16676a2016-07-20 16:23:015659TEST_F(HttpNetworkTransactionTest, ConnectStatus408) {
[email protected]c744cf22009-02-27 07:28:085660 ConnectStatusHelper(MockRead("HTTP/1.1 408 Request Timeout\r\n"));
5661}
5662
bncd16676a2016-07-20 16:23:015663TEST_F(HttpNetworkTransactionTest, ConnectStatus409) {
[email protected]c744cf22009-02-27 07:28:085664 ConnectStatusHelper(MockRead("HTTP/1.1 409 Conflict\r\n"));
5665}
5666
bncd16676a2016-07-20 16:23:015667TEST_F(HttpNetworkTransactionTest, ConnectStatus410) {
[email protected]c744cf22009-02-27 07:28:085668 ConnectStatusHelper(MockRead("HTTP/1.1 410 Gone\r\n"));
5669}
5670
bncd16676a2016-07-20 16:23:015671TEST_F(HttpNetworkTransactionTest, ConnectStatus411) {
[email protected]c744cf22009-02-27 07:28:085672 ConnectStatusHelper(MockRead("HTTP/1.1 411 Length Required\r\n"));
5673}
5674
bncd16676a2016-07-20 16:23:015675TEST_F(HttpNetworkTransactionTest, ConnectStatus412) {
[email protected]c744cf22009-02-27 07:28:085676 ConnectStatusHelper(MockRead("HTTP/1.1 412 Precondition Failed\r\n"));
5677}
5678
bncd16676a2016-07-20 16:23:015679TEST_F(HttpNetworkTransactionTest, ConnectStatus413) {
[email protected]c744cf22009-02-27 07:28:085680 ConnectStatusHelper(MockRead("HTTP/1.1 413 Request Entity Too Large\r\n"));
5681}
5682
bncd16676a2016-07-20 16:23:015683TEST_F(HttpNetworkTransactionTest, ConnectStatus414) {
[email protected]c744cf22009-02-27 07:28:085684 ConnectStatusHelper(MockRead("HTTP/1.1 414 Request-URI Too Long\r\n"));
5685}
5686
bncd16676a2016-07-20 16:23:015687TEST_F(HttpNetworkTransactionTest, ConnectStatus415) {
[email protected]c744cf22009-02-27 07:28:085688 ConnectStatusHelper(MockRead("HTTP/1.1 415 Unsupported Media Type\r\n"));
5689}
5690
bncd16676a2016-07-20 16:23:015691TEST_F(HttpNetworkTransactionTest, ConnectStatus416) {
[email protected]c744cf22009-02-27 07:28:085692 ConnectStatusHelper(
5693 MockRead("HTTP/1.1 416 Requested Range Not Satisfiable\r\n"));
5694}
5695
bncd16676a2016-07-20 16:23:015696TEST_F(HttpNetworkTransactionTest, ConnectStatus417) {
[email protected]c744cf22009-02-27 07:28:085697 ConnectStatusHelper(MockRead("HTTP/1.1 417 Expectation Failed\r\n"));
5698}
5699
bncd16676a2016-07-20 16:23:015700TEST_F(HttpNetworkTransactionTest, ConnectStatus500) {
[email protected]c744cf22009-02-27 07:28:085701 ConnectStatusHelper(MockRead("HTTP/1.1 500 Internal Server Error\r\n"));
5702}
5703
bncd16676a2016-07-20 16:23:015704TEST_F(HttpNetworkTransactionTest, ConnectStatus501) {
[email protected]c744cf22009-02-27 07:28:085705 ConnectStatusHelper(MockRead("HTTP/1.1 501 Not Implemented\r\n"));
5706}
5707
bncd16676a2016-07-20 16:23:015708TEST_F(HttpNetworkTransactionTest, ConnectStatus502) {
[email protected]c744cf22009-02-27 07:28:085709 ConnectStatusHelper(MockRead("HTTP/1.1 502 Bad Gateway\r\n"));
5710}
5711
bncd16676a2016-07-20 16:23:015712TEST_F(HttpNetworkTransactionTest, ConnectStatus503) {
[email protected]c744cf22009-02-27 07:28:085713 ConnectStatusHelper(MockRead("HTTP/1.1 503 Service Unavailable\r\n"));
5714}
5715
bncd16676a2016-07-20 16:23:015716TEST_F(HttpNetworkTransactionTest, ConnectStatus504) {
[email protected]c744cf22009-02-27 07:28:085717 ConnectStatusHelper(MockRead("HTTP/1.1 504 Gateway Timeout\r\n"));
5718}
5719
bncd16676a2016-07-20 16:23:015720TEST_F(HttpNetworkTransactionTest, ConnectStatus505) {
[email protected]c744cf22009-02-27 07:28:085721 ConnectStatusHelper(MockRead("HTTP/1.1 505 HTTP Version Not Supported\r\n"));
5722}
5723
[email protected]038e9a32008-10-08 22:40:165724// Test the flow when both the proxy server AND origin server require
5725// authentication. Again, this uses basic auth for both since that is
5726// the simplest to mock.
bncd16676a2016-07-20 16:23:015727TEST_F(HttpNetworkTransactionTest, BasicAuthProxyThenServer) {
[email protected]cb9bf6ca2011-01-28 13:15:275728 HttpRequestInfo request;
5729 request.method = "GET";
bncce36dca22015-04-21 22:11:235730 request.url = GURL("http://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:275731
[email protected]038e9a32008-10-08 22:40:165732 // Configure against proxy server "myproxy:70".
rdsmith82957ad2015-09-16 19:42:035733 session_deps_.proxy_service = ProxyService::CreateFixed("myproxy:70");
danakj1fd259a02016-04-16 03:17:095734 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]3fe8d2f82013-10-17 08:56:075735
bnc691fda62016-08-12 00:43:165736 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]038e9a32008-10-08 22:40:165737
[email protected]f9ee6b52008-11-08 06:46:235738 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:235739 MockWrite(
5740 "GET http://www.example.org/ HTTP/1.1\r\n"
5741 "Host: www.example.org\r\n"
5742 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:235743 };
5744
[email protected]038e9a32008-10-08 22:40:165745 MockRead data_reads1[] = {
5746 MockRead("HTTP/1.0 407 Unauthorized\r\n"),
5747 // Give a couple authenticate options (only the middle one is actually
5748 // supported).
[email protected]22927ad2009-09-21 19:56:195749 MockRead("Proxy-Authenticate: Basic invalid\r\n"), // Malformed.
[email protected]038e9a32008-10-08 22:40:165750 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
5751 MockRead("Proxy-Authenticate: UNSUPPORTED realm=\"FOO\"\r\n"),
5752 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
5753 // Large content-length -- won't matter, as connection will be reset.
5754 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:065755 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]038e9a32008-10-08 22:40:165756 };
5757
bnc691fda62016-08-12 00:43:165758 // After calling trans.RestartWithAuth() the first time, this is the
[email protected]038e9a32008-10-08 22:40:165759 // request we should be issuing -- the final header line contains the
5760 // proxy's credentials.
5761 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:235762 MockWrite(
5763 "GET http://www.example.org/ HTTP/1.1\r\n"
5764 "Host: www.example.org\r\n"
5765 "Proxy-Connection: keep-alive\r\n"
5766 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]038e9a32008-10-08 22:40:165767 };
5768
5769 // Now the proxy server lets the request pass through to origin server.
5770 // The origin server responds with a 401.
5771 MockRead data_reads2[] = {
5772 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
5773 // Note: We are using the same realm-name as the proxy server. This is
5774 // completely valid, as realms are unique across hosts.
5775 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
5776 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
5777 MockRead("Content-Length: 2000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:065778 MockRead(SYNCHRONOUS, ERR_FAILED), // Won't be reached.
[email protected]038e9a32008-10-08 22:40:165779 };
5780
bnc691fda62016-08-12 00:43:165781 // After calling trans.RestartWithAuth() the second time, we should send
[email protected]038e9a32008-10-08 22:40:165782 // the credentials for both the proxy and origin server.
5783 MockWrite data_writes3[] = {
bncce36dca22015-04-21 22:11:235784 MockWrite(
5785 "GET http://www.example.org/ HTTP/1.1\r\n"
5786 "Host: www.example.org\r\n"
5787 "Proxy-Connection: keep-alive\r\n"
5788 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n"
5789 "Authorization: Basic Zm9vMjpiYXIy\r\n\r\n"),
[email protected]038e9a32008-10-08 22:40:165790 };
5791
5792 // Lastly we get the desired content.
5793 MockRead data_reads3[] = {
5794 MockRead("HTTP/1.0 200 OK\r\n"),
5795 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
5796 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:065797 MockRead(SYNCHRONOUS, OK),
[email protected]038e9a32008-10-08 22:40:165798 };
5799
[email protected]31a2bfe2010-02-09 08:03:395800 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
5801 data_writes1, arraysize(data_writes1));
5802 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
5803 data_writes2, arraysize(data_writes2));
5804 StaticSocketDataProvider data3(data_reads3, arraysize(data_reads3),
5805 data_writes3, arraysize(data_writes3));
[email protected]bb88e1d32013-05-03 23:11:075806 session_deps_.socket_factory->AddSocketDataProvider(&data1);
5807 session_deps_.socket_factory->AddSocketDataProvider(&data2);
5808 session_deps_.socket_factory->AddSocketDataProvider(&data3);
[email protected]038e9a32008-10-08 22:40:165809
[email protected]49639fa2011-12-20 23:22:415810 TestCompletionCallback callback1;
[email protected]038e9a32008-10-08 22:40:165811
tfarina42834112016-09-22 13:38:205812 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:015813 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]038e9a32008-10-08 22:40:165814
5815 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:015816 EXPECT_THAT(rv, IsOk());
[email protected]038e9a32008-10-08 22:40:165817
bnc691fda62016-08-12 00:43:165818 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:525819 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:045820 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
[email protected]038e9a32008-10-08 22:40:165821
[email protected]49639fa2011-12-20 23:22:415822 TestCompletionCallback callback2;
[email protected]038e9a32008-10-08 22:40:165823
bnc691fda62016-08-12 00:43:165824 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar), callback2.callback());
robpercival214763f2016-07-01 23:27:015825 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]038e9a32008-10-08 22:40:165826
5827 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:015828 EXPECT_THAT(rv, IsOk());
[email protected]038e9a32008-10-08 22:40:165829
bnc691fda62016-08-12 00:43:165830 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:525831 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:045832 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]038e9a32008-10-08 22:40:165833
[email protected]49639fa2011-12-20 23:22:415834 TestCompletionCallback callback3;
[email protected]038e9a32008-10-08 22:40:165835
bnc691fda62016-08-12 00:43:165836 rv = trans.RestartWithAuth(AuthCredentials(kFoo2, kBar2),
5837 callback3.callback());
robpercival214763f2016-07-01 23:27:015838 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]038e9a32008-10-08 22:40:165839
5840 rv = callback3.WaitForResult();
robpercival214763f2016-07-01 23:27:015841 EXPECT_THAT(rv, IsOk());
[email protected]038e9a32008-10-08 22:40:165842
bnc691fda62016-08-12 00:43:165843 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:525844 EXPECT_FALSE(response->auth_challenge);
[email protected]038e9a32008-10-08 22:40:165845 EXPECT_EQ(100, response->headers->GetContentLength());
[email protected]038e9a32008-10-08 22:40:165846}
[email protected]4ddaf2502008-10-23 18:26:195847
[email protected]ea9dc9a2009-09-05 00:43:325848// For the NTLM implementation using SSPI, we skip the NTLM tests since we
5849// can't hook into its internals to cause it to generate predictable NTLM
5850// authorization headers.
5851#if defined(NTLM_PORTABLE)
[email protected]385a4672009-03-11 22:21:295852// The NTLM authentication unit tests were generated by capturing the HTTP
5853// requests and responses using Fiddler 2 and inspecting the generated random
5854// bytes in the debugger.
5855
5856// Enter the correct password and authenticate successfully.
bncd16676a2016-07-20 16:23:015857TEST_F(HttpNetworkTransactionTest, NTLMAuth1) {
[email protected]1c773ea12009-04-28 19:58:425858 HttpRequestInfo request;
[email protected]3f918782009-02-28 01:29:245859 request.method = "GET";
5860 request.url = GURL("http://172.22.68.17/kids/login.aspx");
[email protected]2217aa22013-10-11 03:03:545861
5862 // Ensure load is not disrupted by flags which suppress behaviour specific
5863 // to other auth schemes.
5864 request.load_flags = LOAD_DO_NOT_USE_EMBEDDED_IDENTITY;
[email protected]3f918782009-02-28 01:29:245865
[email protected]cb9bf6ca2011-01-28 13:15:275866 HttpAuthHandlerNTLM::ScopedProcSetter proc_setter(MockGenerateRandom1,
5867 MockGetHostName);
danakj1fd259a02016-04-16 03:17:095868 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:275869
[email protected]3f918782009-02-28 01:29:245870 MockWrite data_writes1[] = {
5871 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
5872 "Host: 172.22.68.17\r\n"
5873 "Connection: keep-alive\r\n\r\n"),
5874 };
5875
5876 MockRead data_reads1[] = {
5877 MockRead("HTTP/1.1 401 Access Denied\r\n"),
[email protected]aef04272010-06-28 18:03:045878 // Negotiate and NTLM are often requested together. However, we only want
5879 // to test NTLM. Since Negotiate is preferred over NTLM, we have to skip
5880 // the header that requests Negotiate for this test.
[email protected]3f918782009-02-28 01:29:245881 MockRead("WWW-Authenticate: NTLM\r\n"),
5882 MockRead("Connection: close\r\n"),
5883 MockRead("Content-Length: 42\r\n"),
[email protected]076c85082009-04-10 23:21:365884 MockRead("Content-Type: text/html\r\n\r\n"),
[email protected]3f918782009-02-28 01:29:245885 // Missing content -- won't matter, as connection will be reset.
[email protected]8ddf8322012-02-23 18:08:065886 MockRead(SYNCHRONOUS, ERR_UNEXPECTED),
[email protected]3f918782009-02-28 01:29:245887 };
5888
5889 MockWrite data_writes2[] = {
bnc691fda62016-08-12 00:43:165890 // After restarting with a null identity, this is the
5891 // request we should be issuing -- the final header line contains a Type
5892 // 1 message.
5893 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
5894 "Host: 172.22.68.17\r\n"
5895 "Connection: keep-alive\r\n"
5896 "Authorization: NTLM "
5897 "TlRMTVNTUAABAAAAB4IIAAAAAAAAAAAAAAAAAAAAAAA=\r\n\r\n"),
[email protected]3f918782009-02-28 01:29:245898
bnc691fda62016-08-12 00:43:165899 // After calling trans.RestartWithAuth(), we should send a Type 3 message
5900 // (the credentials for the origin server). The second request continues
5901 // on the same connection.
5902 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
5903 "Host: 172.22.68.17\r\n"
5904 "Connection: keep-alive\r\n"
5905 "Authorization: NTLM TlRMTVNTUAADAAAAGAAYAGgAAAAYABgAgA"
5906 "AAAAAAAABAAAAAGAAYAEAAAAAQABAAWAAAAAAAAAAAAAAABYIIAHQA"
5907 "ZQBzAHQAaQBuAGcALQBuAHQAbABtAFcAVABDAC0AVwBJAE4ANwBVKW"
5908 "Yma5xzVAAAAAAAAAAAAAAAAAAAAACH+gWcm+YsP9Tqb9zCR3WAeZZX"
5909 "ahlhx5I=\r\n\r\n"),
[email protected]3f918782009-02-28 01:29:245910 };
5911
5912 MockRead data_reads2[] = {
5913 // The origin server responds with a Type 2 message.
5914 MockRead("HTTP/1.1 401 Access Denied\r\n"),
5915 MockRead("WWW-Authenticate: NTLM "
[email protected]385a4672009-03-11 22:21:295916 "TlRMTVNTUAACAAAADAAMADgAAAAFgokCjGpMpPGlYKkAAAAAAAAAALo"
[email protected]3f918782009-02-28 01:29:245917 "AugBEAAAABQEoCgAAAA9HAE8ATwBHAEwARQACAAwARwBPAE8ARwBMAE"
5918 "UAAQAaAEEASwBFAEUAUwBBAFIAQQAtAEMATwBSAFAABAAeAGMAbwByA"
5919 "HAALgBnAG8AbwBnAGwAZQAuAGMAbwBtAAMAQABhAGsAZQBlAHMAYQBy"
5920 "AGEALQBjAG8AcgBwAC4AYQBkAC4AYwBvAHIAcAAuAGcAbwBvAGcAbAB"
5921 "lAC4AYwBvAG0ABQAeAGMAbwByAHAALgBnAG8AbwBnAGwAZQAuAGMAbw"
5922 "BtAAAAAAA=\r\n"),
5923 MockRead("Content-Length: 42\r\n"),
[email protected]076c85082009-04-10 23:21:365924 MockRead("Content-Type: text/html\r\n\r\n"),
[email protected]3f918782009-02-28 01:29:245925 MockRead("You are not authorized to view this page\r\n"),
5926
5927 // Lastly we get the desired content.
5928 MockRead("HTTP/1.1 200 OK\r\n"),
5929 MockRead("Content-Type: text/html; charset=utf-8\r\n"),
5930 MockRead("Content-Length: 13\r\n\r\n"),
5931 MockRead("Please Login\r\n"),
[email protected]8ddf8322012-02-23 18:08:065932 MockRead(SYNCHRONOUS, OK),
[email protected]3f918782009-02-28 01:29:245933 };
5934
[email protected]31a2bfe2010-02-09 08:03:395935 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
5936 data_writes1, arraysize(data_writes1));
5937 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
5938 data_writes2, arraysize(data_writes2));
[email protected]bb88e1d32013-05-03 23:11:075939 session_deps_.socket_factory->AddSocketDataProvider(&data1);
5940 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]3f918782009-02-28 01:29:245941
[email protected]49639fa2011-12-20 23:22:415942 TestCompletionCallback callback1;
[email protected]3f918782009-02-28 01:29:245943
bnc691fda62016-08-12 00:43:165944 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]0b0bf032010-09-21 18:08:505945
tfarina42834112016-09-22 13:38:205946 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:015947 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]3f918782009-02-28 01:29:245948
5949 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:015950 EXPECT_THAT(rv, IsOk());
[email protected]3f918782009-02-28 01:29:245951
bnc691fda62016-08-12 00:43:165952 EXPECT_FALSE(trans.IsReadyToRestartForAuth());
[email protected]0757e7702009-03-27 04:00:225953
bnc691fda62016-08-12 00:43:165954 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:525955 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:045956 EXPECT_TRUE(CheckNTLMServerAuth(response->auth_challenge.get()));
[email protected]3f918782009-02-28 01:29:245957
[email protected]49639fa2011-12-20 23:22:415958 TestCompletionCallback callback2;
[email protected]10af5fe72011-01-31 16:17:255959
bnc691fda62016-08-12 00:43:165960 rv = trans.RestartWithAuth(AuthCredentials(kTestingNTLM, kTestingNTLM),
5961 callback2.callback());
robpercival214763f2016-07-01 23:27:015962 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]10af5fe72011-01-31 16:17:255963
5964 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:015965 EXPECT_THAT(rv, IsOk());
[email protected]10af5fe72011-01-31 16:17:255966
bnc691fda62016-08-12 00:43:165967 EXPECT_TRUE(trans.IsReadyToRestartForAuth());
[email protected]10af5fe72011-01-31 16:17:255968
bnc691fda62016-08-12 00:43:165969 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:525970 ASSERT_TRUE(response);
5971 EXPECT_FALSE(response->auth_challenge);
[email protected]10af5fe72011-01-31 16:17:255972
[email protected]49639fa2011-12-20 23:22:415973 TestCompletionCallback callback3;
[email protected]3f918782009-02-28 01:29:245974
bnc691fda62016-08-12 00:43:165975 rv = trans.RestartWithAuth(AuthCredentials(), callback3.callback());
robpercival214763f2016-07-01 23:27:015976 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]3f918782009-02-28 01:29:245977
[email protected]0757e7702009-03-27 04:00:225978 rv = callback3.WaitForResult();
robpercival214763f2016-07-01 23:27:015979 EXPECT_THAT(rv, IsOk());
[email protected]3f918782009-02-28 01:29:245980
bnc691fda62016-08-12 00:43:165981 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:525982 ASSERT_TRUE(response);
5983 EXPECT_FALSE(response->auth_challenge);
[email protected]3f918782009-02-28 01:29:245984 EXPECT_EQ(13, response->headers->GetContentLength());
5985}
5986
[email protected]385a4672009-03-11 22:21:295987// Enter a wrong password, and then the correct one.
bncd16676a2016-07-20 16:23:015988TEST_F(HttpNetworkTransactionTest, NTLMAuth2) {
[email protected]1c773ea12009-04-28 19:58:425989 HttpRequestInfo request;
[email protected]385a4672009-03-11 22:21:295990 request.method = "GET";
5991 request.url = GURL("http://172.22.68.17/kids/login.aspx");
[email protected]385a4672009-03-11 22:21:295992
[email protected]cb9bf6ca2011-01-28 13:15:275993 HttpAuthHandlerNTLM::ScopedProcSetter proc_setter(MockGenerateRandom2,
5994 MockGetHostName);
danakj1fd259a02016-04-16 03:17:095995 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:275996
[email protected]385a4672009-03-11 22:21:295997 MockWrite data_writes1[] = {
5998 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
5999 "Host: 172.22.68.17\r\n"
6000 "Connection: keep-alive\r\n\r\n"),
6001 };
6002
6003 MockRead data_reads1[] = {
6004 MockRead("HTTP/1.1 401 Access Denied\r\n"),
[email protected]aef04272010-06-28 18:03:046005 // Negotiate and NTLM are often requested together. However, we only want
6006 // to test NTLM. Since Negotiate is preferred over NTLM, we have to skip
6007 // the header that requests Negotiate for this test.
[email protected]385a4672009-03-11 22:21:296008 MockRead("WWW-Authenticate: NTLM\r\n"),
6009 MockRead("Connection: close\r\n"),
6010 MockRead("Content-Length: 42\r\n"),
[email protected]076c85082009-04-10 23:21:366011 MockRead("Content-Type: text/html\r\n\r\n"),
[email protected]385a4672009-03-11 22:21:296012 // Missing content -- won't matter, as connection will be reset.
[email protected]8ddf8322012-02-23 18:08:066013 MockRead(SYNCHRONOUS, ERR_UNEXPECTED),
[email protected]385a4672009-03-11 22:21:296014 };
6015
6016 MockWrite data_writes2[] = {
bnc691fda62016-08-12 00:43:166017 // After restarting with a null identity, this is the
6018 // request we should be issuing -- the final header line contains a Type
6019 // 1 message.
6020 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
6021 "Host: 172.22.68.17\r\n"
6022 "Connection: keep-alive\r\n"
6023 "Authorization: NTLM "
6024 "TlRMTVNTUAABAAAAB4IIAAAAAAAAAAAAAAAAAAAAAAA=\r\n\r\n"),
[email protected]385a4672009-03-11 22:21:296025
bnc691fda62016-08-12 00:43:166026 // After calling trans.RestartWithAuth(), we should send a Type 3 message
6027 // (the credentials for the origin server). The second request continues
6028 // on the same connection.
6029 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
6030 "Host: 172.22.68.17\r\n"
6031 "Connection: keep-alive\r\n"
6032 "Authorization: NTLM TlRMTVNTUAADAAAAGAAYAGgAAAAYABgAgA"
6033 "AAAAAAAABAAAAAGAAYAEAAAAAQABAAWAAAAAAAAAAAAAAABYIIAHQA"
6034 "ZQBzAHQAaQBuAGcALQBuAHQAbABtAFcAVABDAC0AVwBJAE4ANwCWeY"
6035 "XnSZNwoQAAAAAAAAAAAAAAAAAAAADLa34/phTTKzNTWdub+uyFleOj"
6036 "4Ww7b7E=\r\n\r\n"),
[email protected]385a4672009-03-11 22:21:296037 };
6038
6039 MockRead data_reads2[] = {
6040 // The origin server responds with a Type 2 message.
6041 MockRead("HTTP/1.1 401 Access Denied\r\n"),
6042 MockRead("WWW-Authenticate: NTLM "
6043 "TlRMTVNTUAACAAAADAAMADgAAAAFgokCbVWUZezVGpAAAAAAAAAAALo"
6044 "AugBEAAAABQEoCgAAAA9HAE8ATwBHAEwARQACAAwARwBPAE8ARwBMAE"
6045 "UAAQAaAEEASwBFAEUAUwBBAFIAQQAtAEMATwBSAFAABAAeAGMAbwByA"
6046 "HAALgBnAG8AbwBnAGwAZQAuAGMAbwBtAAMAQABhAGsAZQBlAHMAYQBy"
6047 "AGEALQBjAG8AcgBwAC4AYQBkAC4AYwBvAHIAcAAuAGcAbwBvAGcAbAB"
6048 "lAC4AYwBvAG0ABQAeAGMAbwByAHAALgBnAG8AbwBnAGwAZQAuAGMAbw"
6049 "BtAAAAAAA=\r\n"),
6050 MockRead("Content-Length: 42\r\n"),
[email protected]076c85082009-04-10 23:21:366051 MockRead("Content-Type: text/html\r\n\r\n"),
[email protected]385a4672009-03-11 22:21:296052 MockRead("You are not authorized to view this page\r\n"),
6053
6054 // Wrong password.
6055 MockRead("HTTP/1.1 401 Access Denied\r\n"),
[email protected]385a4672009-03-11 22:21:296056 MockRead("WWW-Authenticate: NTLM\r\n"),
6057 MockRead("Connection: close\r\n"),
6058 MockRead("Content-Length: 42\r\n"),
[email protected]076c85082009-04-10 23:21:366059 MockRead("Content-Type: text/html\r\n\r\n"),
[email protected]385a4672009-03-11 22:21:296060 // Missing content -- won't matter, as connection will be reset.
[email protected]8ddf8322012-02-23 18:08:066061 MockRead(SYNCHRONOUS, ERR_UNEXPECTED),
[email protected]385a4672009-03-11 22:21:296062 };
6063
6064 MockWrite data_writes3[] = {
bnc691fda62016-08-12 00:43:166065 // After restarting with a null identity, this is the
6066 // request we should be issuing -- the final header line contains a Type
6067 // 1 message.
6068 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
6069 "Host: 172.22.68.17\r\n"
6070 "Connection: keep-alive\r\n"
6071 "Authorization: NTLM "
6072 "TlRMTVNTUAABAAAAB4IIAAAAAAAAAAAAAAAAAAAAAAA=\r\n\r\n"),
[email protected]385a4672009-03-11 22:21:296073
bnc691fda62016-08-12 00:43:166074 // After calling trans.RestartWithAuth(), we should send a Type 3 message
6075 // (the credentials for the origin server). The second request continues
6076 // on the same connection.
6077 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
6078 "Host: 172.22.68.17\r\n"
6079 "Connection: keep-alive\r\n"
6080 "Authorization: NTLM TlRMTVNTUAADAAAAGAAYAGgAAAAYABgAgA"
6081 "AAAAAAAABAAAAAGAAYAEAAAAAQABAAWAAAAAAAAAAAAAAABYIIAHQA"
6082 "ZQBzAHQAaQBuAGcALQBuAHQAbABtAFcAVABDAC0AVwBJAE4ANwBO54"
6083 "dFMVvTHwAAAAAAAAAAAAAAAAAAAACS7sT6Uzw7L0L//WUqlIaVWpbI"
6084 "+4MUm7c=\r\n\r\n"),
[email protected]385a4672009-03-11 22:21:296085 };
6086
6087 MockRead data_reads3[] = {
6088 // The origin server responds with a Type 2 message.
6089 MockRead("HTTP/1.1 401 Access Denied\r\n"),
6090 MockRead("WWW-Authenticate: NTLM "
6091 "TlRMTVNTUAACAAAADAAMADgAAAAFgokCL24VN8dgOR8AAAAAAAAAALo"
6092 "AugBEAAAABQEoCgAAAA9HAE8ATwBHAEwARQACAAwARwBPAE8ARwBMAE"
6093 "UAAQAaAEEASwBFAEUAUwBBAFIAQQAtAEMATwBSAFAABAAeAGMAbwByA"
6094 "HAALgBnAG8AbwBnAGwAZQAuAGMAbwBtAAMAQABhAGsAZQBlAHMAYQBy"
6095 "AGEALQBjAG8AcgBwAC4AYQBkAC4AYwBvAHIAcAAuAGcAbwBvAGcAbAB"
6096 "lAC4AYwBvAG0ABQAeAGMAbwByAHAALgBnAG8AbwBnAGwAZQAuAGMAbw"
6097 "BtAAAAAAA=\r\n"),
6098 MockRead("Content-Length: 42\r\n"),
[email protected]076c85082009-04-10 23:21:366099 MockRead("Content-Type: text/html\r\n\r\n"),
[email protected]385a4672009-03-11 22:21:296100 MockRead("You are not authorized to view this page\r\n"),
6101
6102 // Lastly we get the desired content.
6103 MockRead("HTTP/1.1 200 OK\r\n"),
6104 MockRead("Content-Type: text/html; charset=utf-8\r\n"),
6105 MockRead("Content-Length: 13\r\n\r\n"),
6106 MockRead("Please Login\r\n"),
[email protected]8ddf8322012-02-23 18:08:066107 MockRead(SYNCHRONOUS, OK),
[email protected]385a4672009-03-11 22:21:296108 };
6109
[email protected]31a2bfe2010-02-09 08:03:396110 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
6111 data_writes1, arraysize(data_writes1));
6112 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
6113 data_writes2, arraysize(data_writes2));
6114 StaticSocketDataProvider data3(data_reads3, arraysize(data_reads3),
6115 data_writes3, arraysize(data_writes3));
[email protected]bb88e1d32013-05-03 23:11:076116 session_deps_.socket_factory->AddSocketDataProvider(&data1);
6117 session_deps_.socket_factory->AddSocketDataProvider(&data2);
6118 session_deps_.socket_factory->AddSocketDataProvider(&data3);
[email protected]385a4672009-03-11 22:21:296119
[email protected]49639fa2011-12-20 23:22:416120 TestCompletionCallback callback1;
[email protected]385a4672009-03-11 22:21:296121
bnc691fda62016-08-12 00:43:166122 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]0b0bf032010-09-21 18:08:506123
tfarina42834112016-09-22 13:38:206124 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:016125 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]385a4672009-03-11 22:21:296126
6127 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:016128 EXPECT_THAT(rv, IsOk());
[email protected]385a4672009-03-11 22:21:296129
bnc691fda62016-08-12 00:43:166130 EXPECT_FALSE(trans.IsReadyToRestartForAuth());
[email protected]385a4672009-03-11 22:21:296131
bnc691fda62016-08-12 00:43:166132 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:526133 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:046134 EXPECT_TRUE(CheckNTLMServerAuth(response->auth_challenge.get()));
[email protected]385a4672009-03-11 22:21:296135
[email protected]49639fa2011-12-20 23:22:416136 TestCompletionCallback callback2;
[email protected]385a4672009-03-11 22:21:296137
[email protected]0757e7702009-03-27 04:00:226138 // Enter the wrong password.
bnc691fda62016-08-12 00:43:166139 rv = trans.RestartWithAuth(AuthCredentials(kTestingNTLM, kWrongPassword),
6140 callback2.callback());
robpercival214763f2016-07-01 23:27:016141 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]385a4672009-03-11 22:21:296142
[email protected]10af5fe72011-01-31 16:17:256143 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:016144 EXPECT_THAT(rv, IsOk());
[email protected]385a4672009-03-11 22:21:296145
bnc691fda62016-08-12 00:43:166146 EXPECT_TRUE(trans.IsReadyToRestartForAuth());
[email protected]49639fa2011-12-20 23:22:416147 TestCompletionCallback callback3;
bnc691fda62016-08-12 00:43:166148 rv = trans.RestartWithAuth(AuthCredentials(), callback3.callback());
robpercival214763f2016-07-01 23:27:016149 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]10af5fe72011-01-31 16:17:256150 rv = callback3.WaitForResult();
robpercival214763f2016-07-01 23:27:016151 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:166152 EXPECT_FALSE(trans.IsReadyToRestartForAuth());
[email protected]0757e7702009-03-27 04:00:226153
bnc691fda62016-08-12 00:43:166154 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:526155 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:046156 EXPECT_TRUE(CheckNTLMServerAuth(response->auth_challenge.get()));
[email protected]0757e7702009-03-27 04:00:226157
[email protected]49639fa2011-12-20 23:22:416158 TestCompletionCallback callback4;
[email protected]0757e7702009-03-27 04:00:226159
6160 // Now enter the right password.
bnc691fda62016-08-12 00:43:166161 rv = trans.RestartWithAuth(AuthCredentials(kTestingNTLM, kTestingNTLM),
6162 callback4.callback());
robpercival214763f2016-07-01 23:27:016163 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]10af5fe72011-01-31 16:17:256164
6165 rv = callback4.WaitForResult();
robpercival214763f2016-07-01 23:27:016166 EXPECT_THAT(rv, IsOk());
[email protected]10af5fe72011-01-31 16:17:256167
bnc691fda62016-08-12 00:43:166168 EXPECT_TRUE(trans.IsReadyToRestartForAuth());
[email protected]10af5fe72011-01-31 16:17:256169
[email protected]49639fa2011-12-20 23:22:416170 TestCompletionCallback callback5;
[email protected]10af5fe72011-01-31 16:17:256171
6172 // One more roundtrip
bnc691fda62016-08-12 00:43:166173 rv = trans.RestartWithAuth(AuthCredentials(), callback5.callback());
robpercival214763f2016-07-01 23:27:016174 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]0757e7702009-03-27 04:00:226175
6176 rv = callback5.WaitForResult();
robpercival214763f2016-07-01 23:27:016177 EXPECT_THAT(rv, IsOk());
[email protected]0757e7702009-03-27 04:00:226178
bnc691fda62016-08-12 00:43:166179 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:526180 EXPECT_FALSE(response->auth_challenge);
[email protected]385a4672009-03-11 22:21:296181 EXPECT_EQ(13, response->headers->GetContentLength());
6182}
[email protected]ea9dc9a2009-09-05 00:43:326183#endif // NTLM_PORTABLE
[email protected]385a4672009-03-11 22:21:296184
[email protected]4ddaf2502008-10-23 18:26:196185// Test reading a server response which has only headers, and no body.
6186// After some maximum number of bytes is consumed, the transaction should
6187// fail with ERR_RESPONSE_HEADERS_TOO_BIG.
bncd16676a2016-07-20 16:23:016188TEST_F(HttpNetworkTransactionTest, LargeHeadersNoBody) {
[email protected]1c773ea12009-04-28 19:58:426189 HttpRequestInfo request;
[email protected]4ddaf2502008-10-23 18:26:196190 request.method = "GET";
bncce36dca22015-04-21 22:11:236191 request.url = GURL("http://www.example.org/");
[email protected]4ddaf2502008-10-23 18:26:196192
danakj1fd259a02016-04-16 03:17:096193 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:166194 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:276195
[email protected]b75b7b2f2009-10-06 00:54:536196 // Respond with 300 kb of headers (we should fail after 256 kb).
[email protected]15a5ccf82008-10-23 19:57:436197 std::string large_headers_string;
[email protected]b75b7b2f2009-10-06 00:54:536198 FillLargeHeadersString(&large_headers_string, 300 * 1024);
[email protected]4ddaf2502008-10-23 18:26:196199
6200 MockRead data_reads[] = {
6201 MockRead("HTTP/1.0 200 OK\r\n"),
[email protected]8ddf8322012-02-23 18:08:066202 MockRead(ASYNC, large_headers_string.data(), large_headers_string.size()),
[email protected]4ddaf2502008-10-23 18:26:196203 MockRead("\r\nBODY"),
[email protected]8ddf8322012-02-23 18:08:066204 MockRead(SYNCHRONOUS, OK),
[email protected]4ddaf2502008-10-23 18:26:196205 };
[email protected]31a2bfe2010-02-09 08:03:396206 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:076207 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]4ddaf2502008-10-23 18:26:196208
[email protected]49639fa2011-12-20 23:22:416209 TestCompletionCallback callback;
[email protected]4ddaf2502008-10-23 18:26:196210
tfarina42834112016-09-22 13:38:206211 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:016212 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]4ddaf2502008-10-23 18:26:196213
6214 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:016215 EXPECT_THAT(rv, IsError(ERR_RESPONSE_HEADERS_TOO_BIG));
[email protected]4ddaf2502008-10-23 18:26:196216}
[email protected]f4e426b2008-11-05 00:24:496217
6218// Make sure that we don't try to reuse a TCPClientSocket when failing to
6219// establish tunnel.
6220// http://code.google.com/p/chromium/issues/detail?id=3772
bncd16676a2016-07-20 16:23:016221TEST_F(HttpNetworkTransactionTest, DontRecycleTransportSocketForSSLTunnel) {
[email protected]cb9bf6ca2011-01-28 13:15:276222 HttpRequestInfo request;
6223 request.method = "GET";
bncce36dca22015-04-21 22:11:236224 request.url = GURL("https://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:276225
[email protected]f4e426b2008-11-05 00:24:496226 // Configure against proxy server "myproxy:70".
rdsmith82957ad2015-09-16 19:42:036227 session_deps_.proxy_service = ProxyService::CreateFixed("myproxy:70");
[email protected]db8f44c2008-12-13 04:52:016228
danakj1fd259a02016-04-16 03:17:096229 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]f4e426b2008-11-05 00:24:496230
bnc691fda62016-08-12 00:43:166231 std::unique_ptr<HttpNetworkTransaction> trans(
[email protected]90499482013-06-01 00:39:506232 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]f4e426b2008-11-05 00:24:496233
[email protected]f4e426b2008-11-05 00:24:496234 // Since we have proxy, should try to establish tunnel.
6235 MockWrite data_writes1[] = {
rsleevidb16bb02015-11-12 23:47:176236 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
6237 "Host: www.example.org:443\r\n"
6238 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]f4e426b2008-11-05 00:24:496239 };
6240
[email protected]77848d12008-11-14 00:00:226241 // The proxy responds to the connect with a 404, using a persistent
[email protected]f4e426b2008-11-05 00:24:496242 // connection. Usually a proxy would return 501 (not implemented),
6243 // or 200 (tunnel established).
6244 MockRead data_reads1[] = {
mmenked39192ee2015-12-09 00:57:236245 MockRead("HTTP/1.1 404 Not Found\r\n"),
6246 MockRead("Content-Length: 10\r\n\r\n"),
6247 MockRead(SYNCHRONOUS, ERR_UNEXPECTED),
[email protected]f4e426b2008-11-05 00:24:496248 };
6249
[email protected]31a2bfe2010-02-09 08:03:396250 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
6251 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:076252 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]f4e426b2008-11-05 00:24:496253
[email protected]49639fa2011-12-20 23:22:416254 TestCompletionCallback callback1;
[email protected]f4e426b2008-11-05 00:24:496255
tfarina42834112016-09-22 13:38:206256 int rv = trans->Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:016257 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]f4e426b2008-11-05 00:24:496258
6259 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:016260 EXPECT_THAT(rv, IsError(ERR_TUNNEL_CONNECTION_FAILED));
[email protected]f4e426b2008-11-05 00:24:496261
[email protected]b4404c02009-04-10 16:38:526262 // Empty the current queue. This is necessary because idle sockets are
6263 // added to the connection pool asynchronously with a PostTask.
fdoray92e35a72016-06-10 15:54:556264 base::RunLoop().RunUntilIdle();
[email protected]b4404c02009-04-10 16:38:526265
[email protected]f4e426b2008-11-05 00:24:496266 // We now check to make sure the TCPClientSocket was not added back to
6267 // the pool.
[email protected]90499482013-06-01 00:39:506268 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]f4e426b2008-11-05 00:24:496269 trans.reset();
fdoray92e35a72016-06-10 15:54:556270 base::RunLoop().RunUntilIdle();
[email protected]f4e426b2008-11-05 00:24:496271 // Make sure that the socket didn't get recycled after calling the destructor.
[email protected]90499482013-06-01 00:39:506272 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]f4e426b2008-11-05 00:24:496273}
[email protected]372d34a2008-11-05 21:30:516274
[email protected]1b157c02009-04-21 01:55:406275// Make sure that we recycle a socket after reading all of the response body.
bncd16676a2016-07-20 16:23:016276TEST_F(HttpNetworkTransactionTest, RecycleSocket) {
[email protected]1c773ea12009-04-28 19:58:426277 HttpRequestInfo request;
[email protected]1b157c02009-04-21 01:55:406278 request.method = "GET";
bncce36dca22015-04-21 22:11:236279 request.url = GURL("http://www.example.org/");
[email protected]1b157c02009-04-21 01:55:406280
danakj1fd259a02016-04-16 03:17:096281 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:276282
bnc691fda62016-08-12 00:43:166283 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:276284
[email protected]1b157c02009-04-21 01:55:406285 MockRead data_reads[] = {
6286 // A part of the response body is received with the response headers.
6287 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 11\r\n\r\nhel"),
6288 // The rest of the response body is received in two parts.
6289 MockRead("lo"),
6290 MockRead(" world"),
6291 MockRead("junk"), // Should not be read!!
[email protected]8ddf8322012-02-23 18:08:066292 MockRead(SYNCHRONOUS, OK),
[email protected]1b157c02009-04-21 01:55:406293 };
6294
[email protected]31a2bfe2010-02-09 08:03:396295 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:076296 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1b157c02009-04-21 01:55:406297
[email protected]49639fa2011-12-20 23:22:416298 TestCompletionCallback callback;
[email protected]1b157c02009-04-21 01:55:406299
tfarina42834112016-09-22 13:38:206300 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:016301 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]1b157c02009-04-21 01:55:406302
6303 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:016304 EXPECT_THAT(rv, IsOk());
[email protected]1b157c02009-04-21 01:55:406305
bnc691fda62016-08-12 00:43:166306 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:526307 ASSERT_TRUE(response);
[email protected]1b157c02009-04-21 01:55:406308
wezca1070932016-05-26 20:30:526309 EXPECT_TRUE(response->headers);
[email protected]1b157c02009-04-21 01:55:406310 std::string status_line = response->headers->GetStatusLine();
6311 EXPECT_EQ("HTTP/1.1 200 OK", status_line);
6312
[email protected]90499482013-06-01 00:39:506313 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]1b157c02009-04-21 01:55:406314
6315 std::string response_data;
bnc691fda62016-08-12 00:43:166316 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:016317 EXPECT_THAT(rv, IsOk());
[email protected]1b157c02009-04-21 01:55:406318 EXPECT_EQ("hello world", response_data);
6319
6320 // Empty the current queue. This is necessary because idle sockets are
6321 // added to the connection pool asynchronously with a PostTask.
fdoray92e35a72016-06-10 15:54:556322 base::RunLoop().RunUntilIdle();
[email protected]1b157c02009-04-21 01:55:406323
6324 // We now check to make sure the socket was added back to the pool.
[email protected]90499482013-06-01 00:39:506325 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]1b157c02009-04-21 01:55:406326}
6327
[email protected]76a505b2010-08-25 06:23:006328// Make sure that we recycle a SSL socket after reading all of the response
6329// body.
bncd16676a2016-07-20 16:23:016330TEST_F(HttpNetworkTransactionTest, RecycleSSLSocket) {
[email protected]76a505b2010-08-25 06:23:006331 HttpRequestInfo request;
6332 request.method = "GET";
bncce36dca22015-04-21 22:11:236333 request.url = GURL("https://www.example.org/");
[email protected]76a505b2010-08-25 06:23:006334
6335 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:236336 MockWrite(
6337 "GET / HTTP/1.1\r\n"
6338 "Host: www.example.org\r\n"
6339 "Connection: keep-alive\r\n\r\n"),
[email protected]76a505b2010-08-25 06:23:006340 };
6341
6342 MockRead data_reads[] = {
6343 MockRead("HTTP/1.1 200 OK\r\n"),
6344 MockRead("Content-Length: 11\r\n\r\n"),
6345 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:066346 MockRead(SYNCHRONOUS, OK),
[email protected]76a505b2010-08-25 06:23:006347 };
6348
[email protected]8ddf8322012-02-23 18:08:066349 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:076350 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]76a505b2010-08-25 06:23:006351
6352 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
6353 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:076354 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]76a505b2010-08-25 06:23:006355
[email protected]49639fa2011-12-20 23:22:416356 TestCompletionCallback callback;
[email protected]76a505b2010-08-25 06:23:006357
danakj1fd259a02016-04-16 03:17:096358 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:166359 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]76a505b2010-08-25 06:23:006360
tfarina42834112016-09-22 13:38:206361 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
[email protected]76a505b2010-08-25 06:23:006362
robpercival214763f2016-07-01 23:27:016363 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
6364 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]76a505b2010-08-25 06:23:006365
bnc691fda62016-08-12 00:43:166366 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:526367 ASSERT_TRUE(response);
6368 ASSERT_TRUE(response->headers);
[email protected]76a505b2010-08-25 06:23:006369 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
6370
[email protected]90499482013-06-01 00:39:506371 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]76a505b2010-08-25 06:23:006372
6373 std::string response_data;
bnc691fda62016-08-12 00:43:166374 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:016375 EXPECT_THAT(rv, IsOk());
[email protected]76a505b2010-08-25 06:23:006376 EXPECT_EQ("hello world", response_data);
6377
6378 // Empty the current queue. This is necessary because idle sockets are
6379 // added to the connection pool asynchronously with a PostTask.
fdoray92e35a72016-06-10 15:54:556380 base::RunLoop().RunUntilIdle();
[email protected]76a505b2010-08-25 06:23:006381
6382 // We now check to make sure the socket was added back to the pool.
[email protected]90499482013-06-01 00:39:506383 EXPECT_EQ(1, GetIdleSocketCountInSSLSocketPool(session.get()));
[email protected]76a505b2010-08-25 06:23:006384}
6385
6386// Grab a SSL socket, use it, and put it back into the pool. Then, reuse it
6387// from the pool and make sure that we recover okay.
bncd16676a2016-07-20 16:23:016388TEST_F(HttpNetworkTransactionTest, RecycleDeadSSLSocket) {
[email protected]76a505b2010-08-25 06:23:006389 HttpRequestInfo request;
6390 request.method = "GET";
bncce36dca22015-04-21 22:11:236391 request.url = GURL("https://www.example.org/");
[email protected]76a505b2010-08-25 06:23:006392
6393 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:236394 MockWrite(
6395 "GET / HTTP/1.1\r\n"
6396 "Host: www.example.org\r\n"
6397 "Connection: keep-alive\r\n\r\n"),
6398 MockWrite(
6399 "GET / HTTP/1.1\r\n"
6400 "Host: www.example.org\r\n"
6401 "Connection: keep-alive\r\n\r\n"),
[email protected]76a505b2010-08-25 06:23:006402 };
6403
6404 MockRead data_reads[] = {
mmenke911ee0222015-12-04 03:58:426405 MockRead("HTTP/1.1 200 OK\r\n"), MockRead("Content-Length: 11\r\n\r\n"),
6406 MockRead("hello world"), MockRead(ASYNC, ERR_CONNECTION_CLOSED)};
[email protected]76a505b2010-08-25 06:23:006407
[email protected]8ddf8322012-02-23 18:08:066408 SSLSocketDataProvider ssl(ASYNC, OK);
6409 SSLSocketDataProvider ssl2(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:076410 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
6411 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
[email protected]76a505b2010-08-25 06:23:006412
6413 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
6414 data_writes, arraysize(data_writes));
6415 StaticSocketDataProvider data2(data_reads, arraysize(data_reads),
6416 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:076417 session_deps_.socket_factory->AddSocketDataProvider(&data);
6418 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]76a505b2010-08-25 06:23:006419
[email protected]49639fa2011-12-20 23:22:416420 TestCompletionCallback callback;
[email protected]76a505b2010-08-25 06:23:006421
danakj1fd259a02016-04-16 03:17:096422 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:166423 std::unique_ptr<HttpNetworkTransaction> trans(
[email protected]90499482013-06-01 00:39:506424 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]76a505b2010-08-25 06:23:006425
tfarina42834112016-09-22 13:38:206426 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
[email protected]76a505b2010-08-25 06:23:006427
robpercival214763f2016-07-01 23:27:016428 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
6429 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]76a505b2010-08-25 06:23:006430
6431 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:526432 ASSERT_TRUE(response);
6433 ASSERT_TRUE(response->headers);
[email protected]76a505b2010-08-25 06:23:006434 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
6435
[email protected]90499482013-06-01 00:39:506436 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]76a505b2010-08-25 06:23:006437
6438 std::string response_data;
6439 rv = ReadTransaction(trans.get(), &response_data);
robpercival214763f2016-07-01 23:27:016440 EXPECT_THAT(rv, IsOk());
[email protected]76a505b2010-08-25 06:23:006441 EXPECT_EQ("hello world", response_data);
6442
6443 // Empty the current queue. This is necessary because idle sockets are
6444 // added to the connection pool asynchronously with a PostTask.
fdoray92e35a72016-06-10 15:54:556445 base::RunLoop().RunUntilIdle();
[email protected]76a505b2010-08-25 06:23:006446
6447 // We now check to make sure the socket was added back to the pool.
[email protected]90499482013-06-01 00:39:506448 EXPECT_EQ(1, GetIdleSocketCountInSSLSocketPool(session.get()));
[email protected]76a505b2010-08-25 06:23:006449
6450 // Now start the second transaction, which should reuse the previous socket.
6451
[email protected]90499482013-06-01 00:39:506452 trans.reset(new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]76a505b2010-08-25 06:23:006453
tfarina42834112016-09-22 13:38:206454 rv = trans->Start(&request, callback.callback(), NetLogWithSource());
[email protected]76a505b2010-08-25 06:23:006455
robpercival214763f2016-07-01 23:27:016456 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
6457 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]76a505b2010-08-25 06:23:006458
6459 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:526460 ASSERT_TRUE(response);
6461 ASSERT_TRUE(response->headers);
[email protected]76a505b2010-08-25 06:23:006462 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
6463
[email protected]90499482013-06-01 00:39:506464 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]76a505b2010-08-25 06:23:006465
6466 rv = ReadTransaction(trans.get(), &response_data);
robpercival214763f2016-07-01 23:27:016467 EXPECT_THAT(rv, IsOk());
[email protected]76a505b2010-08-25 06:23:006468 EXPECT_EQ("hello world", response_data);
6469
6470 // Empty the current queue. This is necessary because idle sockets are
6471 // added to the connection pool asynchronously with a PostTask.
fdoray92e35a72016-06-10 15:54:556472 base::RunLoop().RunUntilIdle();
[email protected]76a505b2010-08-25 06:23:006473
6474 // We now check to make sure the socket was added back to the pool.
[email protected]90499482013-06-01 00:39:506475 EXPECT_EQ(1, GetIdleSocketCountInSSLSocketPool(session.get()));
[email protected]76a505b2010-08-25 06:23:006476}
6477
maksim.sisov0adf8592016-07-15 06:25:566478// Grab a socket, use it, and put it back into the pool. Then, make
6479// low memory notification and ensure the socket pool is flushed.
bncd16676a2016-07-20 16:23:016480TEST_F(HttpNetworkTransactionTest, FlushSocketPoolOnLowMemoryNotifications) {
maksim.sisov0adf8592016-07-15 06:25:566481 HttpRequestInfo request;
6482 request.method = "GET";
6483 request.url = GURL("http://www.example.org/");
6484 request.load_flags = 0;
6485
6486 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
6487
bnc691fda62016-08-12 00:43:166488 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
maksim.sisov0adf8592016-07-15 06:25:566489
6490 MockRead data_reads[] = {
6491 // A part of the response body is received with the response headers.
6492 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 11\r\n\r\nhel"),
6493 // The rest of the response body is received in two parts.
6494 MockRead("lo"), MockRead(" world"),
6495 MockRead("junk"), // Should not be read!!
6496 MockRead(SYNCHRONOUS, OK),
6497 };
6498
6499 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
6500 session_deps_.socket_factory->AddSocketDataProvider(&data);
6501
6502 TestCompletionCallback callback;
6503
tfarina42834112016-09-22 13:38:206504 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
maksim.sisov0adf8592016-07-15 06:25:566505 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
6506
6507 EXPECT_THAT(callback.GetResult(rv), IsOk());
6508
bnc691fda62016-08-12 00:43:166509 const HttpResponseInfo* response = trans.GetResponseInfo();
maksim.sisov0adf8592016-07-15 06:25:566510 ASSERT_TRUE(response);
6511 EXPECT_TRUE(response->headers);
6512 std::string status_line = response->headers->GetStatusLine();
6513 EXPECT_EQ("HTTP/1.1 200 OK", status_line);
6514
6515 // Make memory critical notification and ensure the transaction still has been
6516 // operating right.
6517 base::MemoryPressureListener::NotifyMemoryPressure(
6518 base::MemoryPressureListener::MEMORY_PRESSURE_LEVEL_CRITICAL);
6519 base::RunLoop().RunUntilIdle();
6520
6521 // Socket should not be flushed as long as it is not idle.
6522 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
6523
6524 std::string response_data;
bnc691fda62016-08-12 00:43:166525 rv = ReadTransaction(&trans, &response_data);
maksim.sisov0adf8592016-07-15 06:25:566526 EXPECT_THAT(rv, IsOk());
6527 EXPECT_EQ("hello world", response_data);
6528
6529 // Empty the current queue. This is necessary because idle sockets are
6530 // added to the connection pool asynchronously with a PostTask.
6531 base::RunLoop().RunUntilIdle();
6532
6533 // We now check to make sure the socket was added back to the pool.
6534 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
6535
6536 // Idle sockets should be flushed now.
6537 base::MemoryPressureListener::NotifyMemoryPressure(
6538 base::MemoryPressureListener::MEMORY_PRESSURE_LEVEL_CRITICAL);
6539 base::RunLoop().RunUntilIdle();
6540
6541 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
6542}
6543
6544// Grab an SSL socket, use it, and put it back into the pool. Then, make
6545// low memory notification and ensure the socket pool is flushed.
bncd16676a2016-07-20 16:23:016546TEST_F(HttpNetworkTransactionTest, FlushSSLSocketPoolOnLowMemoryNotifications) {
maksim.sisov0adf8592016-07-15 06:25:566547 HttpRequestInfo request;
6548 request.method = "GET";
6549 request.url = GURL("https://www.example.org/");
6550 request.load_flags = 0;
6551
6552 MockWrite data_writes[] = {
6553 MockWrite("GET / HTTP/1.1\r\n"
6554 "Host: www.example.org\r\n"
6555 "Connection: keep-alive\r\n\r\n"),
6556 };
6557
6558 MockRead data_reads[] = {
6559 MockRead("HTTP/1.1 200 OK\r\n"), MockRead("Content-Length: 11\r\n\r\n"),
6560 MockRead("hello world"), MockRead(ASYNC, ERR_CONNECTION_CLOSED)};
6561
6562 SSLSocketDataProvider ssl(ASYNC, OK);
6563 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
6564
6565 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
6566 arraysize(data_writes));
6567 session_deps_.socket_factory->AddSocketDataProvider(&data);
6568
6569 TestCompletionCallback callback;
6570
6571 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:166572 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
maksim.sisov0adf8592016-07-15 06:25:566573
6574 EXPECT_EQ(0, GetIdleSocketCountInSSLSocketPool(session.get()));
tfarina42834112016-09-22 13:38:206575 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
maksim.sisov0adf8592016-07-15 06:25:566576
6577 EXPECT_THAT(callback.GetResult(rv), IsOk());
6578
bnc691fda62016-08-12 00:43:166579 const HttpResponseInfo* response = trans.GetResponseInfo();
maksim.sisov0adf8592016-07-15 06:25:566580 ASSERT_TRUE(response);
6581 ASSERT_TRUE(response->headers);
6582 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
6583
6584 // Make memory critical notification and ensure the transaction still has been
6585 // operating right.
6586 base::MemoryPressureListener::NotifyMemoryPressure(
6587 base::MemoryPressureListener::MEMORY_PRESSURE_LEVEL_CRITICAL);
6588 base::RunLoop().RunUntilIdle();
6589
6590 EXPECT_EQ(0, GetIdleSocketCountInSSLSocketPool(session.get()));
6591
6592 std::string response_data;
bnc691fda62016-08-12 00:43:166593 rv = ReadTransaction(&trans, &response_data);
maksim.sisov0adf8592016-07-15 06:25:566594 EXPECT_THAT(rv, IsOk());
6595 EXPECT_EQ("hello world", response_data);
6596
6597 // Empty the current queue. This is necessary because idle sockets are
6598 // added to the connection pool asynchronously with a PostTask.
6599 base::RunLoop().RunUntilIdle();
6600
6601 // We now check to make sure the socket was added back to the pool.
6602 EXPECT_EQ(1, GetIdleSocketCountInSSLSocketPool(session.get()));
6603
6604 // Make memory notification once again and ensure idle socket is closed.
6605 base::MemoryPressureListener::NotifyMemoryPressure(
6606 base::MemoryPressureListener::MEMORY_PRESSURE_LEVEL_CRITICAL);
6607 base::RunLoop().RunUntilIdle();
6608
6609 EXPECT_EQ(0, GetIdleSocketCountInSSLSocketPool(session.get()));
6610}
6611
[email protected]b4404c02009-04-10 16:38:526612// Make sure that we recycle a socket after a zero-length response.
6613// http://crbug.com/9880
bncd16676a2016-07-20 16:23:016614TEST_F(HttpNetworkTransactionTest, RecycleSocketAfterZeroContentLength) {
[email protected]1c773ea12009-04-28 19:58:426615 HttpRequestInfo request;
[email protected]b4404c02009-04-10 16:38:526616 request.method = "GET";
bncce36dca22015-04-21 22:11:236617 request.url = GURL(
6618 "http://www.example.org/csi?v=3&s=web&action=&"
6619 "tran=undefined&ei=mAXcSeegAo-SMurloeUN&"
6620 "e=17259,18167,19592,19773,19981,20133,20173,20233&"
6621 "rt=prt.2642,ol.2649,xjs.2951");
[email protected]b4404c02009-04-10 16:38:526622
danakj1fd259a02016-04-16 03:17:096623 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:276624
[email protected]b4404c02009-04-10 16:38:526625 MockRead data_reads[] = {
6626 MockRead("HTTP/1.1 204 No Content\r\n"
6627 "Content-Length: 0\r\n"
6628 "Content-Type: text/html\r\n\r\n"),
6629 MockRead("junk"), // Should not be read!!
[email protected]8ddf8322012-02-23 18:08:066630 MockRead(SYNCHRONOUS, OK),
[email protected]b4404c02009-04-10 16:38:526631 };
6632
[email protected]31a2bfe2010-02-09 08:03:396633 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:076634 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]b4404c02009-04-10 16:38:526635
mmenkecc2298e2015-12-07 18:20:186636 // Transaction must be created after the MockReads, so it's destroyed before
6637 // them.
bnc691fda62016-08-12 00:43:166638 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
mmenkecc2298e2015-12-07 18:20:186639
[email protected]49639fa2011-12-20 23:22:416640 TestCompletionCallback callback;
[email protected]b4404c02009-04-10 16:38:526641
tfarina42834112016-09-22 13:38:206642 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:016643 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]b4404c02009-04-10 16:38:526644
6645 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:016646 EXPECT_THAT(rv, IsOk());
[email protected]b4404c02009-04-10 16:38:526647
bnc691fda62016-08-12 00:43:166648 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:526649 ASSERT_TRUE(response);
[email protected]b4404c02009-04-10 16:38:526650
wezca1070932016-05-26 20:30:526651 EXPECT_TRUE(response->headers);
[email protected]b4404c02009-04-10 16:38:526652 std::string status_line = response->headers->GetStatusLine();
6653 EXPECT_EQ("HTTP/1.1 204 No Content", status_line);
6654
[email protected]90499482013-06-01 00:39:506655 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]b4404c02009-04-10 16:38:526656
6657 std::string response_data;
bnc691fda62016-08-12 00:43:166658 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:016659 EXPECT_THAT(rv, IsOk());
[email protected]b4404c02009-04-10 16:38:526660 EXPECT_EQ("", response_data);
6661
6662 // Empty the current queue. This is necessary because idle sockets are
6663 // added to the connection pool asynchronously with a PostTask.
fdoray92e35a72016-06-10 15:54:556664 base::RunLoop().RunUntilIdle();
[email protected]b4404c02009-04-10 16:38:526665
6666 // We now check to make sure the socket was added back to the pool.
[email protected]90499482013-06-01 00:39:506667 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]b4404c02009-04-10 16:38:526668}
6669
bncd16676a2016-07-20 16:23:016670TEST_F(HttpNetworkTransactionTest, ResendRequestOnWriteBodyError) {
danakj1fd259a02016-04-16 03:17:096671 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:226672 element_readers.push_back(
ricea2deef682016-09-09 08:04:076673 base::MakeUnique<UploadBytesElementReader>("foo", 3));
olli.raula6df48b2a2015-11-26 07:40:226674 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]329b68b2012-11-14 17:54:276675
[email protected]1c773ea12009-04-28 19:58:426676 HttpRequestInfo request[2];
[email protected]372d34a2008-11-05 21:30:516677 // Transaction 1: a GET request that succeeds. The socket is recycled
6678 // after use.
6679 request[0].method = "GET";
6680 request[0].url = GURL("http://www.google.com/");
6681 request[0].load_flags = 0;
6682 // Transaction 2: a POST request. Reuses the socket kept alive from
6683 // transaction 1. The first attempts fails when writing the POST data.
6684 // This causes the transaction to retry with a new socket. The second
6685 // attempt succeeds.
6686 request[1].method = "POST";
6687 request[1].url = GURL("http://www.google.com/login.cgi");
[email protected]329b68b2012-11-14 17:54:276688 request[1].upload_data_stream = &upload_data_stream;
[email protected]372d34a2008-11-05 21:30:516689 request[1].load_flags = 0;
6690
danakj1fd259a02016-04-16 03:17:096691 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]372d34a2008-11-05 21:30:516692
6693 // The first socket is used for transaction 1 and the first attempt of
6694 // transaction 2.
6695
6696 // The response of transaction 1.
6697 MockRead data_reads1[] = {
6698 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 11\r\n\r\n"),
6699 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:066700 MockRead(SYNCHRONOUS, OK),
[email protected]372d34a2008-11-05 21:30:516701 };
6702 // The mock write results of transaction 1 and the first attempt of
6703 // transaction 2.
6704 MockWrite data_writes1[] = {
[email protected]8ddf8322012-02-23 18:08:066705 MockWrite(SYNCHRONOUS, 64), // GET
6706 MockWrite(SYNCHRONOUS, 93), // POST
6707 MockWrite(SYNCHRONOUS, ERR_CONNECTION_ABORTED), // POST data
[email protected]372d34a2008-11-05 21:30:516708 };
[email protected]31a2bfe2010-02-09 08:03:396709 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
6710 data_writes1, arraysize(data_writes1));
[email protected]372d34a2008-11-05 21:30:516711
6712 // The second socket is used for the second attempt of transaction 2.
6713
6714 // The response of transaction 2.
6715 MockRead data_reads2[] = {
6716 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 7\r\n\r\n"),
6717 MockRead("welcome"),
[email protected]8ddf8322012-02-23 18:08:066718 MockRead(SYNCHRONOUS, OK),
[email protected]372d34a2008-11-05 21:30:516719 };
6720 // The mock write results of the second attempt of transaction 2.
6721 MockWrite data_writes2[] = {
[email protected]8ddf8322012-02-23 18:08:066722 MockWrite(SYNCHRONOUS, 93), // POST
6723 MockWrite(SYNCHRONOUS, 3), // POST data
[email protected]372d34a2008-11-05 21:30:516724 };
[email protected]31a2bfe2010-02-09 08:03:396725 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
6726 data_writes2, arraysize(data_writes2));
[email protected]372d34a2008-11-05 21:30:516727
[email protected]bb88e1d32013-05-03 23:11:076728 session_deps_.socket_factory->AddSocketDataProvider(&data1);
6729 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]372d34a2008-11-05 21:30:516730
thestig9d3bb0c2015-01-24 00:49:516731 const char* const kExpectedResponseData[] = {
[email protected]372d34a2008-11-05 21:30:516732 "hello world", "welcome"
6733 };
6734
6735 for (int i = 0; i < 2; ++i) {
bnc691fda62016-08-12 00:43:166736 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]372d34a2008-11-05 21:30:516737
[email protected]49639fa2011-12-20 23:22:416738 TestCompletionCallback callback;
[email protected]372d34a2008-11-05 21:30:516739
tfarina42834112016-09-22 13:38:206740 int rv = trans.Start(&request[i], callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:016741 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]372d34a2008-11-05 21:30:516742
6743 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:016744 EXPECT_THAT(rv, IsOk());
[email protected]372d34a2008-11-05 21:30:516745
bnc691fda62016-08-12 00:43:166746 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:526747 ASSERT_TRUE(response);
[email protected]372d34a2008-11-05 21:30:516748
wezca1070932016-05-26 20:30:526749 EXPECT_TRUE(response->headers);
[email protected]372d34a2008-11-05 21:30:516750 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
6751
6752 std::string response_data;
bnc691fda62016-08-12 00:43:166753 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:016754 EXPECT_THAT(rv, IsOk());
[email protected]372d34a2008-11-05 21:30:516755 EXPECT_EQ(kExpectedResponseData[i], response_data);
6756 }
6757}
[email protected]f9ee6b52008-11-08 06:46:236758
6759// Test the request-challenge-retry sequence for basic auth when there is
6760// an identity in the URL. The request should be sent as normal, but when
[email protected]2262e3a2012-05-22 16:08:166761// it fails the identity from the URL is used to answer the challenge.
bncd16676a2016-07-20 16:23:016762TEST_F(HttpNetworkTransactionTest, AuthIdentityInURL) {
[email protected]1c773ea12009-04-28 19:58:426763 HttpRequestInfo request;
[email protected]f9ee6b52008-11-08 06:46:236764 request.method = "GET";
bncce36dca22015-04-21 22:11:236765 request.url = GURL("http://foo:b@[email protected]/");
[email protected]7b08ba62012-02-10 20:19:416766 request.load_flags = LOAD_NORMAL;
[email protected]a97cca42009-08-14 01:00:296767
danakj1fd259a02016-04-16 03:17:096768 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:166769 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:276770
[email protected]a97cca42009-08-14 01:00:296771 // The password contains an escaped character -- for this test to pass it
6772 // will need to be unescaped by HttpNetworkTransaction.
6773 EXPECT_EQ("b%40r", request.url.password());
6774
[email protected]f9ee6b52008-11-08 06:46:236775 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:236776 MockWrite(
6777 "GET / HTTP/1.1\r\n"
6778 "Host: www.example.org\r\n"
6779 "Connection: keep-alive\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:236780 };
6781
6782 MockRead data_reads1[] = {
6783 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
6784 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
6785 MockRead("Content-Length: 10\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:066786 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]f9ee6b52008-11-08 06:46:236787 };
6788
[email protected]2262e3a2012-05-22 16:08:166789 // After the challenge above, the transaction will be restarted using the
6790 // identity from the url (foo, b@r) to answer the challenge.
6791 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:236792 MockWrite(
6793 "GET / HTTP/1.1\r\n"
6794 "Host: www.example.org\r\n"
6795 "Connection: keep-alive\r\n"
6796 "Authorization: Basic Zm9vOmJAcg==\r\n\r\n"),
[email protected]2262e3a2012-05-22 16:08:166797 };
6798
6799 MockRead data_reads2[] = {
6800 MockRead("HTTP/1.0 200 OK\r\n"),
6801 MockRead("Content-Length: 100\r\n\r\n"),
6802 MockRead(SYNCHRONOUS, OK),
6803 };
6804
[email protected]31a2bfe2010-02-09 08:03:396805 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
6806 data_writes1, arraysize(data_writes1));
[email protected]2262e3a2012-05-22 16:08:166807 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
6808 data_writes2, arraysize(data_writes2));
[email protected]bb88e1d32013-05-03 23:11:076809 session_deps_.socket_factory->AddSocketDataProvider(&data1);
6810 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]f9ee6b52008-11-08 06:46:236811
[email protected]49639fa2011-12-20 23:22:416812 TestCompletionCallback callback1;
tfarina42834112016-09-22 13:38:206813 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:016814 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]f9ee6b52008-11-08 06:46:236815 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:016816 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:166817 EXPECT_TRUE(trans.IsReadyToRestartForAuth());
[email protected]2262e3a2012-05-22 16:08:166818
6819 TestCompletionCallback callback2;
bnc691fda62016-08-12 00:43:166820 rv = trans.RestartWithAuth(AuthCredentials(), callback2.callback());
robpercival214763f2016-07-01 23:27:016821 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2262e3a2012-05-22 16:08:166822 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:016823 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:166824 EXPECT_FALSE(trans.IsReadyToRestartForAuth());
[email protected]0757e7702009-03-27 04:00:226825
bnc691fda62016-08-12 00:43:166826 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:526827 ASSERT_TRUE(response);
[email protected]2262e3a2012-05-22 16:08:166828
6829 // There is no challenge info, since the identity in URL worked.
wezca1070932016-05-26 20:30:526830 EXPECT_FALSE(response->auth_challenge);
[email protected]2262e3a2012-05-22 16:08:166831
6832 EXPECT_EQ(100, response->headers->GetContentLength());
6833
6834 // Empty the current queue.
fdoray92e35a72016-06-10 15:54:556835 base::RunLoop().RunUntilIdle();
[email protected]2262e3a2012-05-22 16:08:166836}
6837
6838// Test the request-challenge-retry sequence for basic auth when there is an
6839// incorrect identity in the URL. The identity from the URL should be used only
6840// once.
bncd16676a2016-07-20 16:23:016841TEST_F(HttpNetworkTransactionTest, WrongAuthIdentityInURL) {
[email protected]2262e3a2012-05-22 16:08:166842 HttpRequestInfo request;
6843 request.method = "GET";
6844 // Note: the URL has a username:password in it. The password "baz" is
6845 // wrong (should be "bar").
bncce36dca22015-04-21 22:11:236846 request.url = GURL("http://foo:[email protected]/");
[email protected]2262e3a2012-05-22 16:08:166847
6848 request.load_flags = LOAD_NORMAL;
6849
danakj1fd259a02016-04-16 03:17:096850 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:166851 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]2262e3a2012-05-22 16:08:166852
6853 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:236854 MockWrite(
6855 "GET / HTTP/1.1\r\n"
6856 "Host: www.example.org\r\n"
6857 "Connection: keep-alive\r\n\r\n"),
[email protected]2262e3a2012-05-22 16:08:166858 };
6859
6860 MockRead data_reads1[] = {
6861 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
6862 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
6863 MockRead("Content-Length: 10\r\n\r\n"),
6864 MockRead(SYNCHRONOUS, ERR_FAILED),
6865 };
6866
6867 // After the challenge above, the transaction will be restarted using the
6868 // identity from the url (foo, baz) to answer the challenge.
6869 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:236870 MockWrite(
6871 "GET / HTTP/1.1\r\n"
6872 "Host: www.example.org\r\n"
6873 "Connection: keep-alive\r\n"
6874 "Authorization: Basic Zm9vOmJheg==\r\n\r\n"),
[email protected]2262e3a2012-05-22 16:08:166875 };
6876
6877 MockRead data_reads2[] = {
6878 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
6879 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
6880 MockRead("Content-Length: 10\r\n\r\n"),
6881 MockRead(SYNCHRONOUS, ERR_FAILED),
6882 };
6883
6884 // After the challenge above, the transaction will be restarted using the
6885 // identity supplied by the user (foo, bar) to answer the challenge.
6886 MockWrite data_writes3[] = {
bncce36dca22015-04-21 22:11:236887 MockWrite(
6888 "GET / HTTP/1.1\r\n"
6889 "Host: www.example.org\r\n"
6890 "Connection: keep-alive\r\n"
6891 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]2262e3a2012-05-22 16:08:166892 };
6893
6894 MockRead data_reads3[] = {
6895 MockRead("HTTP/1.0 200 OK\r\n"),
6896 MockRead("Content-Length: 100\r\n\r\n"),
6897 MockRead(SYNCHRONOUS, OK),
6898 };
6899
6900 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
6901 data_writes1, arraysize(data_writes1));
6902 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
6903 data_writes2, arraysize(data_writes2));
6904 StaticSocketDataProvider data3(data_reads3, arraysize(data_reads3),
6905 data_writes3, arraysize(data_writes3));
[email protected]bb88e1d32013-05-03 23:11:076906 session_deps_.socket_factory->AddSocketDataProvider(&data1);
6907 session_deps_.socket_factory->AddSocketDataProvider(&data2);
6908 session_deps_.socket_factory->AddSocketDataProvider(&data3);
[email protected]2262e3a2012-05-22 16:08:166909
6910 TestCompletionCallback callback1;
6911
tfarina42834112016-09-22 13:38:206912 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:016913 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2262e3a2012-05-22 16:08:166914
6915 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:016916 EXPECT_THAT(rv, IsOk());
[email protected]2262e3a2012-05-22 16:08:166917
bnc691fda62016-08-12 00:43:166918 EXPECT_TRUE(trans.IsReadyToRestartForAuth());
[email protected]2262e3a2012-05-22 16:08:166919 TestCompletionCallback callback2;
bnc691fda62016-08-12 00:43:166920 rv = trans.RestartWithAuth(AuthCredentials(), callback2.callback());
robpercival214763f2016-07-01 23:27:016921 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2262e3a2012-05-22 16:08:166922 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:016923 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:166924 EXPECT_FALSE(trans.IsReadyToRestartForAuth());
[email protected]2262e3a2012-05-22 16:08:166925
bnc691fda62016-08-12 00:43:166926 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:526927 ASSERT_TRUE(response);
[email protected]2262e3a2012-05-22 16:08:166928 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
6929
6930 TestCompletionCallback callback3;
bnc691fda62016-08-12 00:43:166931 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar), callback3.callback());
robpercival214763f2016-07-01 23:27:016932 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2262e3a2012-05-22 16:08:166933 rv = callback3.WaitForResult();
robpercival214763f2016-07-01 23:27:016934 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:166935 EXPECT_FALSE(trans.IsReadyToRestartForAuth());
[email protected]2262e3a2012-05-22 16:08:166936
bnc691fda62016-08-12 00:43:166937 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:526938 ASSERT_TRUE(response);
[email protected]2262e3a2012-05-22 16:08:166939
6940 // There is no challenge info, since the identity worked.
wezca1070932016-05-26 20:30:526941 EXPECT_FALSE(response->auth_challenge);
[email protected]2262e3a2012-05-22 16:08:166942
6943 EXPECT_EQ(100, response->headers->GetContentLength());
6944
[email protected]ea9dc9a2009-09-05 00:43:326945 // Empty the current queue.
fdoray92e35a72016-06-10 15:54:556946 base::RunLoop().RunUntilIdle();
[email protected]ea9dc9a2009-09-05 00:43:326947}
6948
[email protected]2217aa22013-10-11 03:03:546949
6950// Test the request-challenge-retry sequence for basic auth when there is a
6951// correct identity in the URL, but its use is being suppressed. The identity
6952// from the URL should never be used.
bncd16676a2016-07-20 16:23:016953TEST_F(HttpNetworkTransactionTest, AuthIdentityInURLSuppressed) {
[email protected]2217aa22013-10-11 03:03:546954 HttpRequestInfo request;
6955 request.method = "GET";
bncce36dca22015-04-21 22:11:236956 request.url = GURL("http://foo:[email protected]/");
[email protected]2217aa22013-10-11 03:03:546957 request.load_flags = LOAD_DO_NOT_USE_EMBEDDED_IDENTITY;
6958
danakj1fd259a02016-04-16 03:17:096959 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:166960 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]2217aa22013-10-11 03:03:546961
6962 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:236963 MockWrite(
6964 "GET / HTTP/1.1\r\n"
6965 "Host: www.example.org\r\n"
6966 "Connection: keep-alive\r\n\r\n"),
[email protected]2217aa22013-10-11 03:03:546967 };
6968
6969 MockRead data_reads1[] = {
6970 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
6971 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
6972 MockRead("Content-Length: 10\r\n\r\n"),
6973 MockRead(SYNCHRONOUS, ERR_FAILED),
6974 };
6975
6976 // After the challenge above, the transaction will be restarted using the
6977 // identity supplied by the user, not the one in the URL, to answer the
6978 // challenge.
6979 MockWrite data_writes3[] = {
bncce36dca22015-04-21 22:11:236980 MockWrite(
6981 "GET / HTTP/1.1\r\n"
6982 "Host: www.example.org\r\n"
6983 "Connection: keep-alive\r\n"
6984 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]2217aa22013-10-11 03:03:546985 };
6986
6987 MockRead data_reads3[] = {
6988 MockRead("HTTP/1.0 200 OK\r\n"),
6989 MockRead("Content-Length: 100\r\n\r\n"),
6990 MockRead(SYNCHRONOUS, OK),
6991 };
6992
6993 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
6994 data_writes1, arraysize(data_writes1));
6995 StaticSocketDataProvider data3(data_reads3, arraysize(data_reads3),
6996 data_writes3, arraysize(data_writes3));
6997 session_deps_.socket_factory->AddSocketDataProvider(&data1);
6998 session_deps_.socket_factory->AddSocketDataProvider(&data3);
6999
7000 TestCompletionCallback callback1;
tfarina42834112016-09-22 13:38:207001 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:017002 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2217aa22013-10-11 03:03:547003 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:017004 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:167005 EXPECT_FALSE(trans.IsReadyToRestartForAuth());
[email protected]2217aa22013-10-11 03:03:547006
bnc691fda62016-08-12 00:43:167007 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:527008 ASSERT_TRUE(response);
[email protected]2217aa22013-10-11 03:03:547009 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
7010
7011 TestCompletionCallback callback3;
bnc691fda62016-08-12 00:43:167012 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar), callback3.callback());
robpercival214763f2016-07-01 23:27:017013 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2217aa22013-10-11 03:03:547014 rv = callback3.WaitForResult();
robpercival214763f2016-07-01 23:27:017015 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:167016 EXPECT_FALSE(trans.IsReadyToRestartForAuth());
[email protected]2217aa22013-10-11 03:03:547017
bnc691fda62016-08-12 00:43:167018 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:527019 ASSERT_TRUE(response);
[email protected]2217aa22013-10-11 03:03:547020
7021 // There is no challenge info, since the identity worked.
wezca1070932016-05-26 20:30:527022 EXPECT_FALSE(response->auth_challenge);
[email protected]2217aa22013-10-11 03:03:547023 EXPECT_EQ(100, response->headers->GetContentLength());
7024
7025 // Empty the current queue.
fdoray92e35a72016-06-10 15:54:557026 base::RunLoop().RunUntilIdle();
[email protected]2217aa22013-10-11 03:03:547027}
7028
[email protected]f9ee6b52008-11-08 06:46:237029// Test that previously tried username/passwords for a realm get re-used.
bncd16676a2016-07-20 16:23:017030TEST_F(HttpNetworkTransactionTest, BasicAuthCacheAndPreauth) {
danakj1fd259a02016-04-16 03:17:097031 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]f9ee6b52008-11-08 06:46:237032
7033 // Transaction 1: authenticate (foo, bar) on MyRealm1
7034 {
[email protected]1c773ea12009-04-28 19:58:427035 HttpRequestInfo request;
[email protected]f9ee6b52008-11-08 06:46:237036 request.method = "GET";
bncce36dca22015-04-21 22:11:237037 request.url = GURL("http://www.example.org/x/y/z");
[email protected]f9ee6b52008-11-08 06:46:237038
bnc691fda62016-08-12 00:43:167039 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:277040
[email protected]f9ee6b52008-11-08 06:46:237041 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:237042 MockWrite(
7043 "GET /x/y/z HTTP/1.1\r\n"
7044 "Host: www.example.org\r\n"
7045 "Connection: keep-alive\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:237046 };
7047
7048 MockRead data_reads1[] = {
7049 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
7050 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
7051 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067052 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]f9ee6b52008-11-08 06:46:237053 };
7054
7055 // Resend with authorization (username=foo, password=bar)
7056 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:237057 MockWrite(
7058 "GET /x/y/z HTTP/1.1\r\n"
7059 "Host: www.example.org\r\n"
7060 "Connection: keep-alive\r\n"
7061 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:237062 };
7063
7064 // Sever accepts the authorization.
7065 MockRead data_reads2[] = {
7066 MockRead("HTTP/1.0 200 OK\r\n"),
7067 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067068 MockRead(SYNCHRONOUS, OK),
[email protected]f9ee6b52008-11-08 06:46:237069 };
7070
[email protected]31a2bfe2010-02-09 08:03:397071 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
7072 data_writes1, arraysize(data_writes1));
7073 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
7074 data_writes2, arraysize(data_writes2));
[email protected]bb88e1d32013-05-03 23:11:077075 session_deps_.socket_factory->AddSocketDataProvider(&data1);
7076 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]f9ee6b52008-11-08 06:46:237077
[email protected]49639fa2011-12-20 23:22:417078 TestCompletionCallback callback1;
[email protected]f9ee6b52008-11-08 06:46:237079
tfarina42834112016-09-22 13:38:207080 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:017081 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]f9ee6b52008-11-08 06:46:237082
7083 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:017084 EXPECT_THAT(rv, IsOk());
[email protected]f9ee6b52008-11-08 06:46:237085
bnc691fda62016-08-12 00:43:167086 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:527087 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:047088 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]f9ee6b52008-11-08 06:46:237089
[email protected]49639fa2011-12-20 23:22:417090 TestCompletionCallback callback2;
[email protected]f9ee6b52008-11-08 06:46:237091
bnc691fda62016-08-12 00:43:167092 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar),
7093 callback2.callback());
robpercival214763f2016-07-01 23:27:017094 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]f9ee6b52008-11-08 06:46:237095
7096 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:017097 EXPECT_THAT(rv, IsOk());
[email protected]f9ee6b52008-11-08 06:46:237098
bnc691fda62016-08-12 00:43:167099 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:527100 ASSERT_TRUE(response);
7101 EXPECT_FALSE(response->auth_challenge);
[email protected]f9ee6b52008-11-08 06:46:237102 EXPECT_EQ(100, response->headers->GetContentLength());
7103 }
7104
7105 // ------------------------------------------------------------------------
7106
7107 // Transaction 2: authenticate (foo2, bar2) on MyRealm2
7108 {
[email protected]1c773ea12009-04-28 19:58:427109 HttpRequestInfo request;
[email protected]f9ee6b52008-11-08 06:46:237110 request.method = "GET";
7111 // Note that Transaction 1 was at /x/y/z, so this is in the same
7112 // protection space as MyRealm1.
bncce36dca22015-04-21 22:11:237113 request.url = GURL("http://www.example.org/x/y/a/b");
[email protected]f9ee6b52008-11-08 06:46:237114
bnc691fda62016-08-12 00:43:167115 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:277116
[email protected]f9ee6b52008-11-08 06:46:237117 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:237118 MockWrite(
7119 "GET /x/y/a/b HTTP/1.1\r\n"
7120 "Host: www.example.org\r\n"
7121 "Connection: keep-alive\r\n"
7122 // Send preemptive authorization for MyRealm1
7123 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:237124 };
7125
7126 // The server didn't like the preemptive authorization, and
7127 // challenges us for a different realm (MyRealm2).
7128 MockRead data_reads1[] = {
7129 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
7130 MockRead("WWW-Authenticate: Basic realm=\"MyRealm2\"\r\n"),
7131 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067132 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]f9ee6b52008-11-08 06:46:237133 };
7134
7135 // Resend with authorization for MyRealm2 (username=foo2, password=bar2)
7136 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:237137 MockWrite(
7138 "GET /x/y/a/b HTTP/1.1\r\n"
7139 "Host: www.example.org\r\n"
7140 "Connection: keep-alive\r\n"
7141 "Authorization: Basic Zm9vMjpiYXIy\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:237142 };
7143
7144 // Sever accepts the authorization.
7145 MockRead data_reads2[] = {
7146 MockRead("HTTP/1.0 200 OK\r\n"),
7147 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067148 MockRead(SYNCHRONOUS, OK),
[email protected]f9ee6b52008-11-08 06:46:237149 };
7150
[email protected]31a2bfe2010-02-09 08:03:397151 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
7152 data_writes1, arraysize(data_writes1));
7153 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
7154 data_writes2, arraysize(data_writes2));
[email protected]bb88e1d32013-05-03 23:11:077155 session_deps_.socket_factory->AddSocketDataProvider(&data1);
7156 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]f9ee6b52008-11-08 06:46:237157
[email protected]49639fa2011-12-20 23:22:417158 TestCompletionCallback callback1;
[email protected]f9ee6b52008-11-08 06:46:237159
tfarina42834112016-09-22 13:38:207160 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:017161 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]f9ee6b52008-11-08 06:46:237162
7163 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:017164 EXPECT_THAT(rv, IsOk());
[email protected]f9ee6b52008-11-08 06:46:237165
bnc691fda62016-08-12 00:43:167166 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:527167 ASSERT_TRUE(response);
7168 ASSERT_TRUE(response->auth_challenge);
[email protected]79cb5c12011-09-12 13:12:047169 EXPECT_FALSE(response->auth_challenge->is_proxy);
asanka098c0092016-06-16 20:18:437170 EXPECT_EQ("http://www.example.org",
7171 response->auth_challenge->challenger.Serialize());
[email protected]79cb5c12011-09-12 13:12:047172 EXPECT_EQ("MyRealm2", response->auth_challenge->realm);
aberentbba302d2015-12-03 10:20:197173 EXPECT_EQ(kBasicAuthScheme, response->auth_challenge->scheme);
[email protected]f9ee6b52008-11-08 06:46:237174
[email protected]49639fa2011-12-20 23:22:417175 TestCompletionCallback callback2;
[email protected]f9ee6b52008-11-08 06:46:237176
bnc691fda62016-08-12 00:43:167177 rv = trans.RestartWithAuth(AuthCredentials(kFoo2, kBar2),
7178 callback2.callback());
robpercival214763f2016-07-01 23:27:017179 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]f9ee6b52008-11-08 06:46:237180
7181 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:017182 EXPECT_THAT(rv, IsOk());
[email protected]f9ee6b52008-11-08 06:46:237183
bnc691fda62016-08-12 00:43:167184 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:527185 ASSERT_TRUE(response);
7186 EXPECT_FALSE(response->auth_challenge);
[email protected]f9ee6b52008-11-08 06:46:237187 EXPECT_EQ(100, response->headers->GetContentLength());
7188 }
7189
7190 // ------------------------------------------------------------------------
7191
7192 // Transaction 3: Resend a request in MyRealm's protection space --
7193 // succeed with preemptive authorization.
7194 {
[email protected]1c773ea12009-04-28 19:58:427195 HttpRequestInfo request;
[email protected]f9ee6b52008-11-08 06:46:237196 request.method = "GET";
bncce36dca22015-04-21 22:11:237197 request.url = GURL("http://www.example.org/x/y/z2");
[email protected]f9ee6b52008-11-08 06:46:237198
bnc691fda62016-08-12 00:43:167199 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:277200
[email protected]f9ee6b52008-11-08 06:46:237201 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:237202 MockWrite(
7203 "GET /x/y/z2 HTTP/1.1\r\n"
7204 "Host: www.example.org\r\n"
7205 "Connection: keep-alive\r\n"
7206 // The authorization for MyRealm1 gets sent preemptively
7207 // (since the url is in the same protection space)
7208 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:237209 };
7210
7211 // Sever accepts the preemptive authorization
7212 MockRead data_reads1[] = {
7213 MockRead("HTTP/1.0 200 OK\r\n"),
7214 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067215 MockRead(SYNCHRONOUS, OK),
[email protected]f9ee6b52008-11-08 06:46:237216 };
7217
[email protected]31a2bfe2010-02-09 08:03:397218 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
7219 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:077220 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]f9ee6b52008-11-08 06:46:237221
[email protected]49639fa2011-12-20 23:22:417222 TestCompletionCallback callback1;
[email protected]f9ee6b52008-11-08 06:46:237223
tfarina42834112016-09-22 13:38:207224 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:017225 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]f9ee6b52008-11-08 06:46:237226
7227 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:017228 EXPECT_THAT(rv, IsOk());
[email protected]f9ee6b52008-11-08 06:46:237229
bnc691fda62016-08-12 00:43:167230 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:527231 ASSERT_TRUE(response);
[email protected]f9ee6b52008-11-08 06:46:237232
wezca1070932016-05-26 20:30:527233 EXPECT_FALSE(response->auth_challenge);
[email protected]f9ee6b52008-11-08 06:46:237234 EXPECT_EQ(100, response->headers->GetContentLength());
7235 }
7236
7237 // ------------------------------------------------------------------------
7238
7239 // Transaction 4: request another URL in MyRealm (however the
7240 // url is not known to belong to the protection space, so no pre-auth).
7241 {
[email protected]1c773ea12009-04-28 19:58:427242 HttpRequestInfo request;
[email protected]f9ee6b52008-11-08 06:46:237243 request.method = "GET";
bncce36dca22015-04-21 22:11:237244 request.url = GURL("http://www.example.org/x/1");
[email protected]f9ee6b52008-11-08 06:46:237245
bnc691fda62016-08-12 00:43:167246 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:277247
[email protected]f9ee6b52008-11-08 06:46:237248 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:237249 MockWrite(
7250 "GET /x/1 HTTP/1.1\r\n"
7251 "Host: www.example.org\r\n"
7252 "Connection: keep-alive\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:237253 };
7254
7255 MockRead data_reads1[] = {
7256 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
7257 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
7258 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067259 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]f9ee6b52008-11-08 06:46:237260 };
7261
7262 // Resend with authorization from MyRealm's cache.
7263 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:237264 MockWrite(
7265 "GET /x/1 HTTP/1.1\r\n"
7266 "Host: www.example.org\r\n"
7267 "Connection: keep-alive\r\n"
7268 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:237269 };
7270
7271 // Sever accepts the authorization.
7272 MockRead data_reads2[] = {
7273 MockRead("HTTP/1.0 200 OK\r\n"),
7274 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067275 MockRead(SYNCHRONOUS, OK),
[email protected]f9ee6b52008-11-08 06:46:237276 };
7277
[email protected]31a2bfe2010-02-09 08:03:397278 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
7279 data_writes1, arraysize(data_writes1));
7280 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
7281 data_writes2, arraysize(data_writes2));
[email protected]bb88e1d32013-05-03 23:11:077282 session_deps_.socket_factory->AddSocketDataProvider(&data1);
7283 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]f9ee6b52008-11-08 06:46:237284
[email protected]49639fa2011-12-20 23:22:417285 TestCompletionCallback callback1;
[email protected]f9ee6b52008-11-08 06:46:237286
tfarina42834112016-09-22 13:38:207287 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:017288 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]f9ee6b52008-11-08 06:46:237289
7290 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:017291 EXPECT_THAT(rv, IsOk());
[email protected]f9ee6b52008-11-08 06:46:237292
bnc691fda62016-08-12 00:43:167293 EXPECT_TRUE(trans.IsReadyToRestartForAuth());
[email protected]49639fa2011-12-20 23:22:417294 TestCompletionCallback callback2;
bnc691fda62016-08-12 00:43:167295 rv = trans.RestartWithAuth(AuthCredentials(), callback2.callback());
robpercival214763f2016-07-01 23:27:017296 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]0757e7702009-03-27 04:00:227297 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:017298 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:167299 EXPECT_FALSE(trans.IsReadyToRestartForAuth());
[email protected]0757e7702009-03-27 04:00:227300
bnc691fda62016-08-12 00:43:167301 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:527302 ASSERT_TRUE(response);
7303 EXPECT_FALSE(response->auth_challenge);
[email protected]f9ee6b52008-11-08 06:46:237304 EXPECT_EQ(100, response->headers->GetContentLength());
7305 }
7306
7307 // ------------------------------------------------------------------------
7308
7309 // Transaction 5: request a URL in MyRealm, but the server rejects the
7310 // cached identity. Should invalidate and re-prompt.
7311 {
[email protected]1c773ea12009-04-28 19:58:427312 HttpRequestInfo request;
[email protected]f9ee6b52008-11-08 06:46:237313 request.method = "GET";
bncce36dca22015-04-21 22:11:237314 request.url = GURL("http://www.example.org/p/q/t");
[email protected]f9ee6b52008-11-08 06:46:237315
bnc691fda62016-08-12 00:43:167316 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:277317
[email protected]f9ee6b52008-11-08 06:46:237318 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:237319 MockWrite(
7320 "GET /p/q/t HTTP/1.1\r\n"
7321 "Host: www.example.org\r\n"
7322 "Connection: keep-alive\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:237323 };
7324
7325 MockRead data_reads1[] = {
7326 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
7327 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
7328 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067329 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]f9ee6b52008-11-08 06:46:237330 };
7331
7332 // Resend with authorization from cache for MyRealm.
7333 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:237334 MockWrite(
7335 "GET /p/q/t HTTP/1.1\r\n"
7336 "Host: www.example.org\r\n"
7337 "Connection: keep-alive\r\n"
7338 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:237339 };
7340
7341 // Sever rejects the authorization.
7342 MockRead data_reads2[] = {
7343 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
7344 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
7345 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067346 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]f9ee6b52008-11-08 06:46:237347 };
7348
7349 // At this point we should prompt for new credentials for MyRealm.
7350 // Restart with username=foo3, password=foo4.
7351 MockWrite data_writes3[] = {
bncce36dca22015-04-21 22:11:237352 MockWrite(
7353 "GET /p/q/t HTTP/1.1\r\n"
7354 "Host: www.example.org\r\n"
7355 "Connection: keep-alive\r\n"
7356 "Authorization: Basic Zm9vMzpiYXIz\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:237357 };
7358
7359 // Sever accepts the authorization.
7360 MockRead data_reads3[] = {
7361 MockRead("HTTP/1.0 200 OK\r\n"),
7362 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067363 MockRead(SYNCHRONOUS, OK),
[email protected]f9ee6b52008-11-08 06:46:237364 };
7365
[email protected]31a2bfe2010-02-09 08:03:397366 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
7367 data_writes1, arraysize(data_writes1));
7368 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
7369 data_writes2, arraysize(data_writes2));
7370 StaticSocketDataProvider data3(data_reads3, arraysize(data_reads3),
7371 data_writes3, arraysize(data_writes3));
[email protected]bb88e1d32013-05-03 23:11:077372 session_deps_.socket_factory->AddSocketDataProvider(&data1);
7373 session_deps_.socket_factory->AddSocketDataProvider(&data2);
7374 session_deps_.socket_factory->AddSocketDataProvider(&data3);
[email protected]f9ee6b52008-11-08 06:46:237375
[email protected]49639fa2011-12-20 23:22:417376 TestCompletionCallback callback1;
[email protected]f9ee6b52008-11-08 06:46:237377
tfarina42834112016-09-22 13:38:207378 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:017379 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]f9ee6b52008-11-08 06:46:237380
7381 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:017382 EXPECT_THAT(rv, IsOk());
[email protected]f9ee6b52008-11-08 06:46:237383
bnc691fda62016-08-12 00:43:167384 EXPECT_TRUE(trans.IsReadyToRestartForAuth());
[email protected]49639fa2011-12-20 23:22:417385 TestCompletionCallback callback2;
bnc691fda62016-08-12 00:43:167386 rv = trans.RestartWithAuth(AuthCredentials(), callback2.callback());
robpercival214763f2016-07-01 23:27:017387 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]0757e7702009-03-27 04:00:227388 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:017389 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:167390 EXPECT_FALSE(trans.IsReadyToRestartForAuth());
[email protected]0757e7702009-03-27 04:00:227391
bnc691fda62016-08-12 00:43:167392 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:527393 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:047394 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]f9ee6b52008-11-08 06:46:237395
[email protected]49639fa2011-12-20 23:22:417396 TestCompletionCallback callback3;
[email protected]f9ee6b52008-11-08 06:46:237397
bnc691fda62016-08-12 00:43:167398 rv = trans.RestartWithAuth(AuthCredentials(kFoo3, kBar3),
7399 callback3.callback());
robpercival214763f2016-07-01 23:27:017400 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]f9ee6b52008-11-08 06:46:237401
[email protected]0757e7702009-03-27 04:00:227402 rv = callback3.WaitForResult();
robpercival214763f2016-07-01 23:27:017403 EXPECT_THAT(rv, IsOk());
[email protected]f9ee6b52008-11-08 06:46:237404
bnc691fda62016-08-12 00:43:167405 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:527406 ASSERT_TRUE(response);
7407 EXPECT_FALSE(response->auth_challenge);
[email protected]f9ee6b52008-11-08 06:46:237408 EXPECT_EQ(100, response->headers->GetContentLength());
7409 }
7410}
[email protected]89ceba9a2009-03-21 03:46:067411
[email protected]3c32c5f2010-05-18 15:18:127412// Tests that nonce count increments when multiple auth attempts
7413// are started with the same nonce.
bncd16676a2016-07-20 16:23:017414TEST_F(HttpNetworkTransactionTest, DigestPreAuthNonceCount) {
[email protected]54fea2562010-11-17 14:40:447415 HttpAuthHandlerDigest::Factory* digest_factory =
7416 new HttpAuthHandlerDigest::Factory();
7417 HttpAuthHandlerDigest::FixedNonceGenerator* nonce_generator =
7418 new HttpAuthHandlerDigest::FixedNonceGenerator("0123456789abcdef");
7419 digest_factory->set_nonce_generator(nonce_generator);
[email protected]bb88e1d32013-05-03 23:11:077420 session_deps_.http_auth_handler_factory.reset(digest_factory);
danakj1fd259a02016-04-16 03:17:097421 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]3c32c5f2010-05-18 15:18:127422
7423 // Transaction 1: authenticate (foo, bar) on MyRealm1
7424 {
[email protected]3c32c5f2010-05-18 15:18:127425 HttpRequestInfo request;
7426 request.method = "GET";
bncce36dca22015-04-21 22:11:237427 request.url = GURL("http://www.example.org/x/y/z");
[email protected]3c32c5f2010-05-18 15:18:127428
bnc691fda62016-08-12 00:43:167429 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:277430
[email protected]3c32c5f2010-05-18 15:18:127431 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:237432 MockWrite(
7433 "GET /x/y/z HTTP/1.1\r\n"
7434 "Host: www.example.org\r\n"
7435 "Connection: keep-alive\r\n\r\n"),
[email protected]3c32c5f2010-05-18 15:18:127436 };
7437
7438 MockRead data_reads1[] = {
7439 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
7440 MockRead("WWW-Authenticate: Digest realm=\"digestive\", nonce=\"OU812\", "
7441 "algorithm=MD5, qop=\"auth\"\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067442 MockRead(SYNCHRONOUS, OK),
[email protected]3c32c5f2010-05-18 15:18:127443 };
7444
7445 // Resend with authorization (username=foo, password=bar)
7446 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:237447 MockWrite(
7448 "GET /x/y/z HTTP/1.1\r\n"
7449 "Host: www.example.org\r\n"
7450 "Connection: keep-alive\r\n"
7451 "Authorization: Digest username=\"foo\", realm=\"digestive\", "
7452 "nonce=\"OU812\", uri=\"/x/y/z\", algorithm=MD5, "
7453 "response=\"03ffbcd30add722589c1de345d7a927f\", qop=auth, "
7454 "nc=00000001, cnonce=\"0123456789abcdef\"\r\n\r\n"),
[email protected]3c32c5f2010-05-18 15:18:127455 };
7456
7457 // Sever accepts the authorization.
7458 MockRead data_reads2[] = {
zmo9528c9f42015-08-04 22:12:087459 MockRead("HTTP/1.0 200 OK\r\n"),
7460 MockRead(SYNCHRONOUS, OK),
[email protected]3c32c5f2010-05-18 15:18:127461 };
7462
7463 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
7464 data_writes1, arraysize(data_writes1));
7465 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
7466 data_writes2, arraysize(data_writes2));
[email protected]bb88e1d32013-05-03 23:11:077467 session_deps_.socket_factory->AddSocketDataProvider(&data1);
7468 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]3c32c5f2010-05-18 15:18:127469
[email protected]49639fa2011-12-20 23:22:417470 TestCompletionCallback callback1;
[email protected]3c32c5f2010-05-18 15:18:127471
tfarina42834112016-09-22 13:38:207472 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:017473 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]3c32c5f2010-05-18 15:18:127474
7475 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:017476 EXPECT_THAT(rv, IsOk());
[email protected]3c32c5f2010-05-18 15:18:127477
bnc691fda62016-08-12 00:43:167478 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:527479 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:047480 EXPECT_TRUE(CheckDigestServerAuth(response->auth_challenge.get()));
[email protected]3c32c5f2010-05-18 15:18:127481
[email protected]49639fa2011-12-20 23:22:417482 TestCompletionCallback callback2;
[email protected]3c32c5f2010-05-18 15:18:127483
bnc691fda62016-08-12 00:43:167484 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar),
7485 callback2.callback());
robpercival214763f2016-07-01 23:27:017486 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]3c32c5f2010-05-18 15:18:127487
7488 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:017489 EXPECT_THAT(rv, IsOk());
[email protected]3c32c5f2010-05-18 15:18:127490
bnc691fda62016-08-12 00:43:167491 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:527492 ASSERT_TRUE(response);
7493 EXPECT_FALSE(response->auth_challenge);
[email protected]3c32c5f2010-05-18 15:18:127494 }
7495
7496 // ------------------------------------------------------------------------
7497
7498 // Transaction 2: Request another resource in digestive's protection space.
7499 // This will preemptively add an Authorization header which should have an
7500 // "nc" value of 2 (as compared to 1 in the first use.
7501 {
[email protected]3c32c5f2010-05-18 15:18:127502 HttpRequestInfo request;
7503 request.method = "GET";
7504 // Note that Transaction 1 was at /x/y/z, so this is in the same
7505 // protection space as digest.
bncce36dca22015-04-21 22:11:237506 request.url = GURL("http://www.example.org/x/y/a/b");
[email protected]3c32c5f2010-05-18 15:18:127507
bnc691fda62016-08-12 00:43:167508 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:277509
[email protected]3c32c5f2010-05-18 15:18:127510 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:237511 MockWrite(
7512 "GET /x/y/a/b HTTP/1.1\r\n"
7513 "Host: www.example.org\r\n"
7514 "Connection: keep-alive\r\n"
7515 "Authorization: Digest username=\"foo\", realm=\"digestive\", "
7516 "nonce=\"OU812\", uri=\"/x/y/a/b\", algorithm=MD5, "
7517 "response=\"d6f9a2c07d1c5df7b89379dca1269b35\", qop=auth, "
7518 "nc=00000002, cnonce=\"0123456789abcdef\"\r\n\r\n"),
[email protected]3c32c5f2010-05-18 15:18:127519 };
7520
7521 // Sever accepts the authorization.
7522 MockRead data_reads1[] = {
7523 MockRead("HTTP/1.0 200 OK\r\n"),
7524 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067525 MockRead(SYNCHRONOUS, OK),
[email protected]3c32c5f2010-05-18 15:18:127526 };
7527
7528 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
7529 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:077530 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]3c32c5f2010-05-18 15:18:127531
[email protected]49639fa2011-12-20 23:22:417532 TestCompletionCallback callback1;
[email protected]3c32c5f2010-05-18 15:18:127533
tfarina42834112016-09-22 13:38:207534 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:017535 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]3c32c5f2010-05-18 15:18:127536
7537 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:017538 EXPECT_THAT(rv, IsOk());
[email protected]3c32c5f2010-05-18 15:18:127539
bnc691fda62016-08-12 00:43:167540 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:527541 ASSERT_TRUE(response);
7542 EXPECT_FALSE(response->auth_challenge);
[email protected]3c32c5f2010-05-18 15:18:127543 }
7544}
7545
[email protected]89ceba9a2009-03-21 03:46:067546// Test the ResetStateForRestart() private method.
bncd16676a2016-07-20 16:23:017547TEST_F(HttpNetworkTransactionTest, ResetStateForRestart) {
[email protected]89ceba9a2009-03-21 03:46:067548 // Create a transaction (the dependencies aren't important).
danakj1fd259a02016-04-16 03:17:097549 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:167550 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]89ceba9a2009-03-21 03:46:067551
7552 // Setup some state (which we expect ResetStateForRestart() will clear).
bnc691fda62016-08-12 00:43:167553 trans.read_buf_ = new IOBuffer(15);
7554 trans.read_buf_len_ = 15;
7555 trans.request_headers_.SetHeader("Authorization", "NTLM");
[email protected]89ceba9a2009-03-21 03:46:067556
7557 // Setup state in response_
bnc691fda62016-08-12 00:43:167558 HttpResponseInfo* response = &trans.response_;
[email protected]0877e3d2009-10-17 22:29:577559 response->auth_challenge = new AuthChallengeInfo();
[email protected]70d66502011-09-23 00:55:087560 response->ssl_info.cert_status = static_cast<CertStatus>(-1); // Nonsensical.
[email protected]0877e3d2009-10-17 22:29:577561 response->response_time = base::Time::Now();
7562 response->was_cached = true; // (Wouldn't ever actually be true...)
[email protected]89ceba9a2009-03-21 03:46:067563
7564 { // Setup state for response_.vary_data
7565 HttpRequestInfo request;
7566 std::string temp("HTTP/1.1 200 OK\nVary: foo, bar\n\n");
7567 std::replace(temp.begin(), temp.end(), '\n', '\0');
[email protected]ad8e04a2010-11-01 04:16:277568 scoped_refptr<HttpResponseHeaders> headers(new HttpResponseHeaders(temp));
[email protected]8c76ae22010-04-20 22:15:437569 request.extra_headers.SetHeader("Foo", "1");
7570 request.extra_headers.SetHeader("bar", "23");
[email protected]90499482013-06-01 00:39:507571 EXPECT_TRUE(response->vary_data.Init(request, *headers.get()));
[email protected]89ceba9a2009-03-21 03:46:067572 }
7573
7574 // Cause the above state to be reset.
bnc691fda62016-08-12 00:43:167575 trans.ResetStateForRestart();
[email protected]89ceba9a2009-03-21 03:46:067576
7577 // Verify that the state that needed to be reset, has been reset.
bnc691fda62016-08-12 00:43:167578 EXPECT_FALSE(trans.read_buf_);
7579 EXPECT_EQ(0, trans.read_buf_len_);
7580 EXPECT_TRUE(trans.request_headers_.IsEmpty());
wezca1070932016-05-26 20:30:527581 EXPECT_FALSE(response->auth_challenge);
7582 EXPECT_FALSE(response->headers);
[email protected]34f40942010-10-04 00:34:047583 EXPECT_FALSE(response->was_cached);
[email protected]70d66502011-09-23 00:55:087584 EXPECT_EQ(0U, response->ssl_info.cert_status);
[email protected]0877e3d2009-10-17 22:29:577585 EXPECT_FALSE(response->vary_data.is_valid());
[email protected]89ceba9a2009-03-21 03:46:067586}
7587
[email protected]bacff652009-03-31 17:50:337588// Test HTTPS connections to a site with a bad certificate
bncd16676a2016-07-20 16:23:017589TEST_F(HttpNetworkTransactionTest, HTTPSBadCertificate) {
[email protected]bacff652009-03-31 17:50:337590 HttpRequestInfo request;
7591 request.method = "GET";
bncce36dca22015-04-21 22:11:237592 request.url = GURL("https://www.example.org/");
[email protected]bacff652009-03-31 17:50:337593
danakj1fd259a02016-04-16 03:17:097594 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:167595 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:277596
[email protected]bacff652009-03-31 17:50:337597 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:237598 MockWrite(
7599 "GET / HTTP/1.1\r\n"
7600 "Host: www.example.org\r\n"
7601 "Connection: keep-alive\r\n\r\n"),
[email protected]bacff652009-03-31 17:50:337602 };
7603
7604 MockRead data_reads[] = {
7605 MockRead("HTTP/1.0 200 OK\r\n"),
7606 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
7607 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067608 MockRead(SYNCHRONOUS, OK),
[email protected]bacff652009-03-31 17:50:337609 };
7610
[email protected]5ecc992a42009-11-11 01:41:597611 StaticSocketDataProvider ssl_bad_certificate;
[email protected]31a2bfe2010-02-09 08:03:397612 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
7613 data_writes, arraysize(data_writes));
[email protected]8ddf8322012-02-23 18:08:067614 SSLSocketDataProvider ssl_bad(ASYNC, ERR_CERT_AUTHORITY_INVALID);
7615 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bacff652009-03-31 17:50:337616
[email protected]bb88e1d32013-05-03 23:11:077617 session_deps_.socket_factory->AddSocketDataProvider(&ssl_bad_certificate);
7618 session_deps_.socket_factory->AddSocketDataProvider(&data);
7619 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_bad);
7620 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]bacff652009-03-31 17:50:337621
[email protected]49639fa2011-12-20 23:22:417622 TestCompletionCallback callback;
[email protected]bacff652009-03-31 17:50:337623
tfarina42834112016-09-22 13:38:207624 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:017625 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]bacff652009-03-31 17:50:337626
7627 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:017628 EXPECT_THAT(rv, IsError(ERR_CERT_AUTHORITY_INVALID));
[email protected]bacff652009-03-31 17:50:337629
bnc691fda62016-08-12 00:43:167630 rv = trans.RestartIgnoringLastError(callback.callback());
robpercival214763f2016-07-01 23:27:017631 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]bacff652009-03-31 17:50:337632
7633 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:017634 EXPECT_THAT(rv, IsOk());
[email protected]bacff652009-03-31 17:50:337635
bnc691fda62016-08-12 00:43:167636 const HttpResponseInfo* response = trans.GetResponseInfo();
[email protected]bacff652009-03-31 17:50:337637
wezca1070932016-05-26 20:30:527638 ASSERT_TRUE(response);
[email protected]bacff652009-03-31 17:50:337639 EXPECT_EQ(100, response->headers->GetContentLength());
7640}
7641
7642// Test HTTPS connections to a site with a bad certificate, going through a
7643// proxy
bncd16676a2016-07-20 16:23:017644TEST_F(HttpNetworkTransactionTest, HTTPSBadCertificateViaProxy) {
rdsmith82957ad2015-09-16 19:42:037645 session_deps_.proxy_service = ProxyService::CreateFixed("myproxy:70");
[email protected]bacff652009-03-31 17:50:337646
7647 HttpRequestInfo request;
7648 request.method = "GET";
bncce36dca22015-04-21 22:11:237649 request.url = GURL("https://www.example.org/");
[email protected]bacff652009-03-31 17:50:337650
7651 MockWrite proxy_writes[] = {
rsleevidb16bb02015-11-12 23:47:177652 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
7653 "Host: www.example.org:443\r\n"
7654 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]bacff652009-03-31 17:50:337655 };
7656
7657 MockRead proxy_reads[] = {
7658 MockRead("HTTP/1.0 200 Connected\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067659 MockRead(SYNCHRONOUS, OK)
[email protected]bacff652009-03-31 17:50:337660 };
7661
7662 MockWrite data_writes[] = {
rsleevidb16bb02015-11-12 23:47:177663 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
7664 "Host: www.example.org:443\r\n"
7665 "Proxy-Connection: keep-alive\r\n\r\n"),
7666 MockWrite("GET / HTTP/1.1\r\n"
7667 "Host: www.example.org\r\n"
7668 "Connection: keep-alive\r\n\r\n"),
[email protected]bacff652009-03-31 17:50:337669 };
7670
7671 MockRead data_reads[] = {
7672 MockRead("HTTP/1.0 200 Connected\r\n\r\n"),
7673 MockRead("HTTP/1.0 200 OK\r\n"),
7674 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
7675 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067676 MockRead(SYNCHRONOUS, OK),
[email protected]bacff652009-03-31 17:50:337677 };
7678
[email protected]31a2bfe2010-02-09 08:03:397679 StaticSocketDataProvider ssl_bad_certificate(
7680 proxy_reads, arraysize(proxy_reads),
7681 proxy_writes, arraysize(proxy_writes));
7682 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
7683 data_writes, arraysize(data_writes));
[email protected]8ddf8322012-02-23 18:08:067684 SSLSocketDataProvider ssl_bad(ASYNC, ERR_CERT_AUTHORITY_INVALID);
7685 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bacff652009-03-31 17:50:337686
[email protected]bb88e1d32013-05-03 23:11:077687 session_deps_.socket_factory->AddSocketDataProvider(&ssl_bad_certificate);
7688 session_deps_.socket_factory->AddSocketDataProvider(&data);
7689 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_bad);
7690 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]bacff652009-03-31 17:50:337691
[email protected]49639fa2011-12-20 23:22:417692 TestCompletionCallback callback;
[email protected]bacff652009-03-31 17:50:337693
7694 for (int i = 0; i < 2; i++) {
[email protected]bb88e1d32013-05-03 23:11:077695 session_deps_.socket_factory->ResetNextMockIndexes();
[email protected]bacff652009-03-31 17:50:337696
danakj1fd259a02016-04-16 03:17:097697 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:167698 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]bacff652009-03-31 17:50:337699
tfarina42834112016-09-22 13:38:207700 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:017701 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]bacff652009-03-31 17:50:337702
7703 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:017704 EXPECT_THAT(rv, IsError(ERR_CERT_AUTHORITY_INVALID));
[email protected]bacff652009-03-31 17:50:337705
bnc691fda62016-08-12 00:43:167706 rv = trans.RestartIgnoringLastError(callback.callback());
robpercival214763f2016-07-01 23:27:017707 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]bacff652009-03-31 17:50:337708
7709 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:017710 EXPECT_THAT(rv, IsOk());
[email protected]bacff652009-03-31 17:50:337711
bnc691fda62016-08-12 00:43:167712 const HttpResponseInfo* response = trans.GetResponseInfo();
[email protected]bacff652009-03-31 17:50:337713
wezca1070932016-05-26 20:30:527714 ASSERT_TRUE(response);
[email protected]bacff652009-03-31 17:50:337715 EXPECT_EQ(100, response->headers->GetContentLength());
7716 }
7717}
7718
[email protected]2df19bb2010-08-25 20:13:467719
7720// Test HTTPS connections to a site, going through an HTTPS proxy
bncd16676a2016-07-20 16:23:017721TEST_F(HttpNetworkTransactionTest, HTTPSViaHttpsProxy) {
rdsmith82957ad2015-09-16 19:42:037722 session_deps_.proxy_service =
7723 ProxyService::CreateFixedFromPacResult("HTTPS proxy:70");
vishal.b62985ca92015-04-17 08:45:517724 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:077725 session_deps_.net_log = &net_log;
[email protected]2df19bb2010-08-25 20:13:467726
7727 HttpRequestInfo request;
7728 request.method = "GET";
bncce36dca22015-04-21 22:11:237729 request.url = GURL("https://www.example.org/");
[email protected]2df19bb2010-08-25 20:13:467730
7731 MockWrite data_writes[] = {
rsleevidb16bb02015-11-12 23:47:177732 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
7733 "Host: www.example.org:443\r\n"
7734 "Proxy-Connection: keep-alive\r\n\r\n"),
7735 MockWrite("GET / HTTP/1.1\r\n"
7736 "Host: www.example.org\r\n"
7737 "Connection: keep-alive\r\n\r\n"),
[email protected]2df19bb2010-08-25 20:13:467738 };
7739
7740 MockRead data_reads[] = {
7741 MockRead("HTTP/1.0 200 Connected\r\n\r\n"),
7742 MockRead("HTTP/1.1 200 OK\r\n"),
7743 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
7744 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067745 MockRead(SYNCHRONOUS, OK),
[email protected]2df19bb2010-08-25 20:13:467746 };
7747
7748 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
7749 data_writes, arraysize(data_writes));
[email protected]8ddf8322012-02-23 18:08:067750 SSLSocketDataProvider proxy_ssl(ASYNC, OK); // SSL to the proxy
7751 SSLSocketDataProvider tunnel_ssl(ASYNC, OK); // SSL through the tunnel
[email protected]2df19bb2010-08-25 20:13:467752
[email protected]bb88e1d32013-05-03 23:11:077753 session_deps_.socket_factory->AddSocketDataProvider(&data);
7754 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy_ssl);
7755 session_deps_.socket_factory->AddSSLSocketDataProvider(&tunnel_ssl);
[email protected]2df19bb2010-08-25 20:13:467756
[email protected]49639fa2011-12-20 23:22:417757 TestCompletionCallback callback;
[email protected]2df19bb2010-08-25 20:13:467758
danakj1fd259a02016-04-16 03:17:097759 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:167760 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]2df19bb2010-08-25 20:13:467761
tfarina42834112016-09-22 13:38:207762 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:017763 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2df19bb2010-08-25 20:13:467764
7765 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:017766 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:167767 const HttpResponseInfo* response = trans.GetResponseInfo();
[email protected]2df19bb2010-08-25 20:13:467768
wezca1070932016-05-26 20:30:527769 ASSERT_TRUE(response);
[email protected]2df19bb2010-08-25 20:13:467770
tbansal2ecbbc72016-10-06 17:15:477771 EXPECT_TRUE(response->proxy_server.is_https());
[email protected]2df19bb2010-08-25 20:13:467772 EXPECT_TRUE(response->headers->IsKeepAlive());
7773 EXPECT_EQ(200, response->headers->response_code());
7774 EXPECT_EQ(100, response->headers->GetContentLength());
7775 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
[email protected]029c83b62013-01-24 05:28:207776
7777 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:167778 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]029c83b62013-01-24 05:28:207779 TestLoadTimingNotReusedWithPac(load_timing_info,
7780 CONNECT_TIMING_HAS_SSL_TIMES);
[email protected]2df19bb2010-08-25 20:13:467781}
7782
[email protected]511f6f52010-12-17 03:58:297783// Test an HTTPS Proxy's ability to redirect a CONNECT request
bncd16676a2016-07-20 16:23:017784TEST_F(HttpNetworkTransactionTest, RedirectOfHttpsConnectViaHttpsProxy) {
rdsmith82957ad2015-09-16 19:42:037785 session_deps_.proxy_service =
7786 ProxyService::CreateFixedFromPacResult("HTTPS proxy:70");
vishal.b62985ca92015-04-17 08:45:517787 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:077788 session_deps_.net_log = &net_log;
[email protected]511f6f52010-12-17 03:58:297789
7790 HttpRequestInfo request;
7791 request.method = "GET";
bncce36dca22015-04-21 22:11:237792 request.url = GURL("https://www.example.org/");
[email protected]511f6f52010-12-17 03:58:297793
7794 MockWrite data_writes[] = {
rsleevidb16bb02015-11-12 23:47:177795 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
7796 "Host: www.example.org:443\r\n"
7797 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]511f6f52010-12-17 03:58:297798 };
7799
7800 MockRead data_reads[] = {
7801 MockRead("HTTP/1.1 302 Redirect\r\n"),
7802 MockRead("Location: http://login.example.com/\r\n"),
7803 MockRead("Content-Length: 0\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067804 MockRead(SYNCHRONOUS, OK),
[email protected]511f6f52010-12-17 03:58:297805 };
7806
7807 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
7808 data_writes, arraysize(data_writes));
[email protected]8ddf8322012-02-23 18:08:067809 SSLSocketDataProvider proxy_ssl(ASYNC, OK); // SSL to the proxy
[email protected]511f6f52010-12-17 03:58:297810
[email protected]bb88e1d32013-05-03 23:11:077811 session_deps_.socket_factory->AddSocketDataProvider(&data);
7812 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy_ssl);
[email protected]511f6f52010-12-17 03:58:297813
[email protected]49639fa2011-12-20 23:22:417814 TestCompletionCallback callback;
[email protected]511f6f52010-12-17 03:58:297815
danakj1fd259a02016-04-16 03:17:097816 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:167817 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]511f6f52010-12-17 03:58:297818
tfarina42834112016-09-22 13:38:207819 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:017820 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]511f6f52010-12-17 03:58:297821
7822 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:017823 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:167824 const HttpResponseInfo* response = trans.GetResponseInfo();
[email protected]511f6f52010-12-17 03:58:297825
wezca1070932016-05-26 20:30:527826 ASSERT_TRUE(response);
[email protected]511f6f52010-12-17 03:58:297827
7828 EXPECT_EQ(302, response->headers->response_code());
7829 std::string url;
7830 EXPECT_TRUE(response->headers->IsRedirect(&url));
7831 EXPECT_EQ("http://login.example.com/", url);
[email protected]029c83b62013-01-24 05:28:207832
7833 // In the case of redirects from proxies, HttpNetworkTransaction returns
7834 // timing for the proxy connection instead of the connection to the host,
7835 // and no send / receive times.
7836 // See HttpNetworkTransaction::OnHttpsProxyTunnelResponse.
7837 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:167838 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]029c83b62013-01-24 05:28:207839
7840 EXPECT_FALSE(load_timing_info.socket_reused);
mikecironef22f9812016-10-04 03:40:197841 EXPECT_NE(NetLogSource::kInvalidId, load_timing_info.socket_log_id);
[email protected]029c83b62013-01-24 05:28:207842
7843 EXPECT_FALSE(load_timing_info.proxy_resolve_start.is_null());
7844 EXPECT_LE(load_timing_info.proxy_resolve_start,
7845 load_timing_info.proxy_resolve_end);
7846 EXPECT_LE(load_timing_info.proxy_resolve_end,
7847 load_timing_info.connect_timing.connect_start);
7848 ExpectConnectTimingHasTimes(
7849 load_timing_info.connect_timing,
7850 CONNECT_TIMING_HAS_DNS_TIMES | CONNECT_TIMING_HAS_SSL_TIMES);
7851
7852 EXPECT_TRUE(load_timing_info.send_start.is_null());
7853 EXPECT_TRUE(load_timing_info.send_end.is_null());
7854 EXPECT_TRUE(load_timing_info.receive_headers_end.is_null());
[email protected]511f6f52010-12-17 03:58:297855}
7856
7857// Test an HTTPS (SPDY) Proxy's ability to redirect a CONNECT request
bncd16676a2016-07-20 16:23:017858TEST_F(HttpNetworkTransactionTest, RedirectOfHttpsConnectViaSpdyProxy) {
rdsmith82957ad2015-09-16 19:42:037859 session_deps_.proxy_service = ProxyService::CreateFixed("https://proxy:70");
[email protected]511f6f52010-12-17 03:58:297860
7861 HttpRequestInfo request;
7862 request.method = "GET";
bncce36dca22015-04-21 22:11:237863 request.url = GURL("https://www.example.org/");
[email protected]511f6f52010-12-17 03:58:297864
bncdf80d44fd2016-07-15 20:27:417865 SpdySerializedFrame conn(spdy_util_.ConstructSpdyConnect(
bncce36dca22015-04-21 22:11:237866 NULL, 0, 1, LOWEST, HostPortPair("www.example.org", 443)));
bncdf80d44fd2016-07-15 20:27:417867 SpdySerializedFrame goaway(
diannahu9904e272017-02-03 14:40:087868 spdy_util_.ConstructSpdyRstStream(1, ERROR_CODE_CANCEL));
[email protected]511f6f52010-12-17 03:58:297869 MockWrite data_writes[] = {
bncdf80d44fd2016-07-15 20:27:417870 CreateMockWrite(conn, 0, SYNCHRONOUS),
7871 CreateMockWrite(goaway, 2, SYNCHRONOUS),
[email protected]511f6f52010-12-17 03:58:297872 };
7873
7874 static const char* const kExtraHeaders[] = {
7875 "location",
7876 "http://login.example.com/",
7877 };
bnc42331402016-07-25 13:36:157878 SpdySerializedFrame resp(spdy_util_.ConstructSpdyReplyError(
bncc9f762a2016-12-06 20:38:237879 "302", kExtraHeaders, arraysize(kExtraHeaders) / 2, 1));
[email protected]511f6f52010-12-17 03:58:297880 MockRead data_reads[] = {
bncdf80d44fd2016-07-15 20:27:417881 CreateMockRead(resp, 1), MockRead(ASYNC, 0, 3), // EOF
[email protected]511f6f52010-12-17 03:58:297882 };
7883
rch8e6c6c42015-05-01 14:05:137884 SequencedSocketData data(data_reads, arraysize(data_reads), data_writes,
7885 arraysize(data_writes));
[email protected]8ddf8322012-02-23 18:08:067886 SSLSocketDataProvider proxy_ssl(ASYNC, OK); // SSL to the proxy
bnc3cf2a592016-08-11 14:48:367887 proxy_ssl.next_proto = kProtoHTTP2;
[email protected]511f6f52010-12-17 03:58:297888
[email protected]bb88e1d32013-05-03 23:11:077889 session_deps_.socket_factory->AddSocketDataProvider(&data);
7890 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy_ssl);
[email protected]511f6f52010-12-17 03:58:297891
[email protected]49639fa2011-12-20 23:22:417892 TestCompletionCallback callback;
[email protected]511f6f52010-12-17 03:58:297893
danakj1fd259a02016-04-16 03:17:097894 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:167895 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]511f6f52010-12-17 03:58:297896
tfarina42834112016-09-22 13:38:207897 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:017898 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]511f6f52010-12-17 03:58:297899
7900 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:017901 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:167902 const HttpResponseInfo* response = trans.GetResponseInfo();
[email protected]511f6f52010-12-17 03:58:297903
wezca1070932016-05-26 20:30:527904 ASSERT_TRUE(response);
[email protected]511f6f52010-12-17 03:58:297905
7906 EXPECT_EQ(302, response->headers->response_code());
7907 std::string url;
7908 EXPECT_TRUE(response->headers->IsRedirect(&url));
7909 EXPECT_EQ("http://login.example.com/", url);
7910}
7911
[email protected]4eddbc732012-08-09 05:40:177912// Test that an HTTPS proxy's response to a CONNECT request is filtered.
bncd16676a2016-07-20 16:23:017913TEST_F(HttpNetworkTransactionTest, ErrorResponseToHttpsConnectViaHttpsProxy) {
rdsmith82957ad2015-09-16 19:42:037914 session_deps_.proxy_service = ProxyService::CreateFixed("https://proxy:70");
[email protected]511f6f52010-12-17 03:58:297915
7916 HttpRequestInfo request;
7917 request.method = "GET";
bncce36dca22015-04-21 22:11:237918 request.url = GURL("https://www.example.org/");
[email protected]511f6f52010-12-17 03:58:297919
7920 MockWrite data_writes[] = {
rsleevidb16bb02015-11-12 23:47:177921 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
7922 "Host: www.example.org:443\r\n"
7923 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]511f6f52010-12-17 03:58:297924 };
7925
7926 MockRead data_reads[] = {
7927 MockRead("HTTP/1.1 404 Not Found\r\n"),
7928 MockRead("Content-Length: 23\r\n\r\n"),
7929 MockRead("The host does not exist"),
[email protected]8ddf8322012-02-23 18:08:067930 MockRead(SYNCHRONOUS, OK),
[email protected]511f6f52010-12-17 03:58:297931 };
7932
7933 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
7934 data_writes, arraysize(data_writes));
[email protected]8ddf8322012-02-23 18:08:067935 SSLSocketDataProvider proxy_ssl(ASYNC, OK); // SSL to the proxy
[email protected]511f6f52010-12-17 03:58:297936
[email protected]bb88e1d32013-05-03 23:11:077937 session_deps_.socket_factory->AddSocketDataProvider(&data);
7938 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy_ssl);
[email protected]511f6f52010-12-17 03:58:297939
[email protected]49639fa2011-12-20 23:22:417940 TestCompletionCallback callback;
[email protected]511f6f52010-12-17 03:58:297941
danakj1fd259a02016-04-16 03:17:097942 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:167943 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]511f6f52010-12-17 03:58:297944
tfarina42834112016-09-22 13:38:207945 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:017946 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]511f6f52010-12-17 03:58:297947
7948 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:017949 EXPECT_THAT(rv, IsError(ERR_TUNNEL_CONNECTION_FAILED));
[email protected]511f6f52010-12-17 03:58:297950
ttuttle960fcbf2016-04-19 13:26:327951 // TODO(juliatuttle): Anything else to check here?
[email protected]511f6f52010-12-17 03:58:297952}
7953
[email protected]4eddbc732012-08-09 05:40:177954// Test that a SPDY proxy's response to a CONNECT request is filtered.
bncd16676a2016-07-20 16:23:017955TEST_F(HttpNetworkTransactionTest, ErrorResponseToHttpsConnectViaSpdyProxy) {
rdsmith82957ad2015-09-16 19:42:037956 session_deps_.proxy_service = ProxyService::CreateFixed("https://proxy:70");
[email protected]511f6f52010-12-17 03:58:297957
7958 HttpRequestInfo request;
7959 request.method = "GET";
bncce36dca22015-04-21 22:11:237960 request.url = GURL("https://www.example.org/");
[email protected]511f6f52010-12-17 03:58:297961
bncdf80d44fd2016-07-15 20:27:417962 SpdySerializedFrame conn(spdy_util_.ConstructSpdyConnect(
bncce36dca22015-04-21 22:11:237963 NULL, 0, 1, LOWEST, HostPortPair("www.example.org", 443)));
bncdf80d44fd2016-07-15 20:27:417964 SpdySerializedFrame rst(
diannahu9904e272017-02-03 14:40:087965 spdy_util_.ConstructSpdyRstStream(1, ERROR_CODE_CANCEL));
[email protected]511f6f52010-12-17 03:58:297966 MockWrite data_writes[] = {
bncdf80d44fd2016-07-15 20:27:417967 CreateMockWrite(conn, 0), CreateMockWrite(rst, 3),
[email protected]511f6f52010-12-17 03:58:297968 };
7969
7970 static const char* const kExtraHeaders[] = {
7971 "location",
7972 "http://login.example.com/",
7973 };
bnc42331402016-07-25 13:36:157974 SpdySerializedFrame resp(spdy_util_.ConstructSpdyReplyError(
bncc9f762a2016-12-06 20:38:237975 "404", kExtraHeaders, arraysize(kExtraHeaders) / 2, 1));
bncdf80d44fd2016-07-15 20:27:417976 SpdySerializedFrame body(spdy_util_.ConstructSpdyDataFrame(
bncb03b1092016-04-06 11:19:557977 1, "The host does not exist", 23, true));
[email protected]511f6f52010-12-17 03:58:297978 MockRead data_reads[] = {
bncdf80d44fd2016-07-15 20:27:417979 CreateMockRead(resp, 1), CreateMockRead(body, 2),
rch8e6c6c42015-05-01 14:05:137980 MockRead(ASYNC, 0, 4), // EOF
[email protected]511f6f52010-12-17 03:58:297981 };
7982
rch8e6c6c42015-05-01 14:05:137983 SequencedSocketData data(data_reads, arraysize(data_reads), data_writes,
7984 arraysize(data_writes));
[email protected]8ddf8322012-02-23 18:08:067985 SSLSocketDataProvider proxy_ssl(ASYNC, OK); // SSL to the proxy
bnc3cf2a592016-08-11 14:48:367986 proxy_ssl.next_proto = kProtoHTTP2;
[email protected]511f6f52010-12-17 03:58:297987
[email protected]bb88e1d32013-05-03 23:11:077988 session_deps_.socket_factory->AddSocketDataProvider(&data);
7989 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy_ssl);
[email protected]511f6f52010-12-17 03:58:297990
[email protected]49639fa2011-12-20 23:22:417991 TestCompletionCallback callback;
[email protected]511f6f52010-12-17 03:58:297992
danakj1fd259a02016-04-16 03:17:097993 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:167994 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]511f6f52010-12-17 03:58:297995
tfarina42834112016-09-22 13:38:207996 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:017997 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]511f6f52010-12-17 03:58:297998
7999 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:018000 EXPECT_THAT(rv, IsError(ERR_TUNNEL_CONNECTION_FAILED));
[email protected]511f6f52010-12-17 03:58:298001
ttuttle960fcbf2016-04-19 13:26:328002 // TODO(juliatuttle): Anything else to check here?
[email protected]511f6f52010-12-17 03:58:298003}
8004
[email protected]0c5fb722012-02-28 11:50:358005// Test the request-challenge-retry sequence for basic auth, through
8006// a SPDY proxy over a single SPDY session.
bncd16676a2016-07-20 16:23:018007TEST_F(HttpNetworkTransactionTest, BasicAuthSpdyProxy) {
[email protected]0c5fb722012-02-28 11:50:358008 HttpRequestInfo request;
8009 request.method = "GET";
bncce36dca22015-04-21 22:11:238010 request.url = GURL("https://www.example.org/");
[email protected]0c5fb722012-02-28 11:50:358011 // when the no authentication data flag is set.
ttuttle859dc7a2015-04-23 19:42:298012 request.load_flags = LOAD_DO_NOT_SEND_AUTH_DATA;
[email protected]0c5fb722012-02-28 11:50:358013
8014 // Configure against https proxy server "myproxy:70".
rdsmith82957ad2015-09-16 19:42:038015 session_deps_.proxy_service =
8016 ProxyService::CreateFixedFromPacResult("HTTPS myproxy:70");
vishal.b62985ca92015-04-17 08:45:518017 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:078018 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:098019 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]0c5fb722012-02-28 11:50:358020
8021 // Since we have proxy, should try to establish tunnel.
bncdf80d44fd2016-07-15 20:27:418022 SpdySerializedFrame req(spdy_util_.ConstructSpdyConnect(
bncce36dca22015-04-21 22:11:238023 NULL, 0, 1, LOWEST, HostPortPair("www.example.org", 443)));
bncdf80d44fd2016-07-15 20:27:418024 SpdySerializedFrame rst(
diannahu9904e272017-02-03 14:40:088025 spdy_util_.ConstructSpdyRstStream(1, ERROR_CODE_CANCEL));
rdsmithebb50aa2015-11-12 03:44:388026 spdy_util_.UpdateWithStreamDestruction(1);
[email protected]0c5fb722012-02-28 11:50:358027
bnc691fda62016-08-12 00:43:168028 // After calling trans.RestartWithAuth(), this is the request we should
[email protected]0c5fb722012-02-28 11:50:358029 // be issuing -- the final header line contains the credentials.
8030 const char* const kAuthCredentials[] = {
8031 "proxy-authorization", "Basic Zm9vOmJhcg==",
8032 };
bncdf80d44fd2016-07-15 20:27:418033 SpdySerializedFrame connect2(spdy_util_.ConstructSpdyConnect(
lgarrona91df87f2014-12-05 00:51:348034 kAuthCredentials, arraysize(kAuthCredentials) / 2, 3, LOWEST,
bncce36dca22015-04-21 22:11:238035 HostPortPair("www.example.org", 443)));
8036 // fetch https://www.example.org/ via HTTP
8037 const char get[] =
8038 "GET / HTTP/1.1\r\n"
8039 "Host: www.example.org\r\n"
8040 "Connection: keep-alive\r\n\r\n";
bncdf80d44fd2016-07-15 20:27:418041 SpdySerializedFrame wrapped_get(
8042 spdy_util_.ConstructSpdyDataFrame(3, get, strlen(get), false));
[email protected]0c5fb722012-02-28 11:50:358043
8044 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:418045 CreateMockWrite(req, 0, ASYNC), CreateMockWrite(rst, 2, ASYNC),
8046 CreateMockWrite(connect2, 3), CreateMockWrite(wrapped_get, 5),
[email protected]0c5fb722012-02-28 11:50:358047 };
8048
8049 // The proxy responds to the connect with a 407, using a persistent
8050 // connection.
thestig9d3bb0c2015-01-24 00:49:518051 const char kAuthStatus[] = "407";
[email protected]0c5fb722012-02-28 11:50:358052 const char* const kAuthChallenge[] = {
[email protected]0c5fb722012-02-28 11:50:358053 "proxy-authenticate", "Basic realm=\"MyRealm1\"",
8054 };
bnc42331402016-07-25 13:36:158055 SpdySerializedFrame conn_auth_resp(spdy_util_.ConstructSpdyReplyError(
bncdf80d44fd2016-07-15 20:27:418056 kAuthStatus, kAuthChallenge, arraysize(kAuthChallenge) / 2, 1));
[email protected]0c5fb722012-02-28 11:50:358057
bnc42331402016-07-25 13:36:158058 SpdySerializedFrame conn_resp(spdy_util_.ConstructSpdyGetReply(NULL, 0, 3));
[email protected]0c5fb722012-02-28 11:50:358059 const char resp[] = "HTTP/1.1 200 OK\r\n"
8060 "Content-Length: 5\r\n\r\n";
8061
bncdf80d44fd2016-07-15 20:27:418062 SpdySerializedFrame wrapped_get_resp(
8063 spdy_util_.ConstructSpdyDataFrame(3, resp, strlen(resp), false));
8064 SpdySerializedFrame wrapped_body(
8065 spdy_util_.ConstructSpdyDataFrame(3, "hello", 5, false));
[email protected]0c5fb722012-02-28 11:50:358066 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:418067 CreateMockRead(conn_auth_resp, 1, ASYNC),
8068 CreateMockRead(conn_resp, 4, ASYNC),
8069 CreateMockRead(wrapped_get_resp, 6, ASYNC),
8070 CreateMockRead(wrapped_body, 7, ASYNC),
rch8e6c6c42015-05-01 14:05:138071 MockRead(ASYNC, OK, 8), // EOF. May or may not be read.
[email protected]0c5fb722012-02-28 11:50:358072 };
8073
rch8e6c6c42015-05-01 14:05:138074 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
8075 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:078076 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]0c5fb722012-02-28 11:50:358077 // Negotiate SPDY to the proxy
8078 SSLSocketDataProvider proxy(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:368079 proxy.next_proto = kProtoHTTP2;
[email protected]bb88e1d32013-05-03 23:11:078080 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy);
[email protected]0c5fb722012-02-28 11:50:358081 // Vanilla SSL to the server
8082 SSLSocketDataProvider server(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:078083 session_deps_.socket_factory->AddSSLSocketDataProvider(&server);
[email protected]0c5fb722012-02-28 11:50:358084
8085 TestCompletionCallback callback1;
8086
bnc691fda62016-08-12 00:43:168087 std::unique_ptr<HttpNetworkTransaction> trans(
[email protected]90499482013-06-01 00:39:508088 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]0c5fb722012-02-28 11:50:358089
8090 int rv = trans->Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:018091 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]0c5fb722012-02-28 11:50:358092
8093 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:018094 EXPECT_THAT(rv, IsOk());
mmenke43758e62015-05-04 21:09:468095 TestNetLogEntry::List entries;
[email protected]0c5fb722012-02-28 11:50:358096 log.GetEntries(&entries);
8097 size_t pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:008098 entries, 0, NetLogEventType::HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
8099 NetLogEventPhase::NONE);
[email protected]0c5fb722012-02-28 11:50:358100 ExpectLogContainsSomewhere(
8101 entries, pos,
mikecirone8b85c432016-09-08 19:11:008102 NetLogEventType::HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
8103 NetLogEventPhase::NONE);
[email protected]0c5fb722012-02-28 11:50:358104
8105 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:528106 ASSERT_TRUE(response);
8107 ASSERT_TRUE(response->headers);
[email protected]0c5fb722012-02-28 11:50:358108 EXPECT_EQ(407, response->headers->response_code());
8109 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
wezca1070932016-05-26 20:30:528110 EXPECT_TRUE(response->auth_challenge);
asanka098c0092016-06-16 20:18:438111 EXPECT_TRUE(CheckBasicSecureProxyAuth(response->auth_challenge.get()));
[email protected]0c5fb722012-02-28 11:50:358112
8113 TestCompletionCallback callback2;
8114
8115 rv = trans->RestartWithAuth(AuthCredentials(kFoo, kBar),
8116 callback2.callback());
robpercival214763f2016-07-01 23:27:018117 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]0c5fb722012-02-28 11:50:358118
8119 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:018120 EXPECT_THAT(rv, IsOk());
[email protected]0c5fb722012-02-28 11:50:358121
8122 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:528123 ASSERT_TRUE(response);
[email protected]0c5fb722012-02-28 11:50:358124
8125 EXPECT_TRUE(response->headers->IsKeepAlive());
8126 EXPECT_EQ(200, response->headers->response_code());
8127 EXPECT_EQ(5, response->headers->GetContentLength());
8128 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
8129
8130 // The password prompt info should not be set.
wezca1070932016-05-26 20:30:528131 EXPECT_FALSE(response->auth_challenge);
[email protected]0c5fb722012-02-28 11:50:358132
[email protected]029c83b62013-01-24 05:28:208133 LoadTimingInfo load_timing_info;
8134 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
8135 TestLoadTimingNotReusedWithPac(load_timing_info,
8136 CONNECT_TIMING_HAS_SSL_TIMES);
8137
[email protected]0c5fb722012-02-28 11:50:358138 trans.reset();
8139 session->CloseAllConnections();
8140}
8141
[email protected]7c6f7ba2012-04-03 04:09:298142// Test that an explicitly trusted SPDY proxy can push a resource from an
8143// origin that is different from that of its associated resource.
bncd16676a2016-07-20 16:23:018144TEST_F(HttpNetworkTransactionTest, CrossOriginSPDYProxyPush) {
tbansal28e68f82016-02-04 02:56:158145 // Configure the proxy delegate to allow cross-origin SPDY pushes.
danakj1fd259a02016-04-16 03:17:098146 std::unique_ptr<TestProxyDelegate> proxy_delegate(new TestProxyDelegate());
tbansal28e68f82016-02-04 02:56:158147 proxy_delegate->set_trusted_spdy_proxy(net::ProxyServer::FromURI(
8148 "https://myproxy:443", net::ProxyServer::SCHEME_HTTP));
[email protected]7c6f7ba2012-04-03 04:09:298149 HttpRequestInfo request;
8150 HttpRequestInfo push_request;
8151
[email protected]7c6f7ba2012-04-03 04:09:298152 request.method = "GET";
bncce36dca22015-04-21 22:11:238153 request.url = GURL("http://www.example.org/");
[email protected]7c6f7ba2012-04-03 04:09:298154 push_request.method = "GET";
8155 push_request.url = GURL("http://www.another-origin.com/foo.dat");
8156
tbansal28e68f82016-02-04 02:56:158157 // Configure against https proxy server "myproxy:443".
rdsmith82957ad2015-09-16 19:42:038158 session_deps_.proxy_service =
tbansal28e68f82016-02-04 02:56:158159 ProxyService::CreateFixedFromPacResult("HTTPS myproxy:443");
vishal.b62985ca92015-04-17 08:45:518160 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:078161 session_deps_.net_log = log.bound().net_log();
[email protected]61b4efc2012-04-27 18:12:508162
inlinechan894515af2016-12-09 02:40:108163 session_deps_.proxy_delegate = std::move(proxy_delegate);
[email protected]61b4efc2012-04-27 18:12:508164
danakj1fd259a02016-04-16 03:17:098165 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]7c6f7ba2012-04-03 04:09:298166
bncdf80d44fd2016-07-15 20:27:418167 SpdySerializedFrame stream1_syn(
bncb26024382016-06-29 02:39:458168 spdy_util_.ConstructSpdyGet("http://www.example.org/", 1, LOWEST));
tombergan5d22c182017-01-11 02:05:358169 SpdySerializedFrame stream2_priority(
8170 spdy_util_.ConstructSpdyPriority(2, 1, IDLE, true));
[email protected]7c6f7ba2012-04-03 04:09:298171
8172 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:418173 CreateMockWrite(stream1_syn, 0, ASYNC),
tombergan5d22c182017-01-11 02:05:358174 CreateMockWrite(stream2_priority, 3, ASYNC),
[email protected]7c6f7ba2012-04-03 04:09:298175 };
8176
bncdf80d44fd2016-07-15 20:27:418177 SpdySerializedFrame stream1_reply(
bnc42331402016-07-25 13:36:158178 spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
[email protected]7c6f7ba2012-04-03 04:09:298179
bncdf80d44fd2016-07-15 20:27:418180 SpdySerializedFrame stream1_body(spdy_util_.ConstructSpdyDataFrame(1, true));
[email protected]7c6f7ba2012-04-03 04:09:298181
bncdf80d44fd2016-07-15 20:27:418182 SpdySerializedFrame stream2_syn(spdy_util_.ConstructSpdyPush(
bncb03b1092016-04-06 11:19:558183 NULL, 0, 2, 1, "http://www.another-origin.com/foo.dat"));
[email protected]8a0fc822013-06-27 20:52:438184 const char kPushedData[] = "pushed";
bncdf80d44fd2016-07-15 20:27:418185 SpdySerializedFrame stream2_body(spdy_util_.ConstructSpdyDataFrame(
8186 2, kPushedData, strlen(kPushedData), true));
[email protected]7c6f7ba2012-04-03 04:09:298187
8188 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:418189 CreateMockRead(stream1_reply, 1, ASYNC),
8190 CreateMockRead(stream2_syn, 2, ASYNC),
tombergan5d22c182017-01-11 02:05:358191 CreateMockRead(stream1_body, 4, ASYNC),
8192 CreateMockRead(stream2_body, 5, ASYNC),
8193 MockRead(SYNCHRONOUS, ERR_IO_PENDING, 6), // Force a hang
[email protected]7c6f7ba2012-04-03 04:09:298194 };
8195
rch8e6c6c42015-05-01 14:05:138196 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
8197 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:078198 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]7c6f7ba2012-04-03 04:09:298199 // Negotiate SPDY to the proxy
8200 SSLSocketDataProvider proxy(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:368201 proxy.next_proto = kProtoHTTP2;
[email protected]bb88e1d32013-05-03 23:11:078202 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy);
[email protected]7c6f7ba2012-04-03 04:09:298203
bnc691fda62016-08-12 00:43:168204 std::unique_ptr<HttpNetworkTransaction> trans(
[email protected]90499482013-06-01 00:39:508205 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]7c6f7ba2012-04-03 04:09:298206 TestCompletionCallback callback;
8207 int rv = trans->Start(&request, callback.callback(), log.bound());
robpercival214763f2016-07-01 23:27:018208 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]7c6f7ba2012-04-03 04:09:298209
8210 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:018211 EXPECT_THAT(rv, IsOk());
[email protected]7c6f7ba2012-04-03 04:09:298212 const HttpResponseInfo* response = trans->GetResponseInfo();
8213
bnc691fda62016-08-12 00:43:168214 std::unique_ptr<HttpNetworkTransaction> push_trans(
[email protected]90499482013-06-01 00:39:508215 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
8216 rv = push_trans->Start(&push_request, callback.callback(), log.bound());
robpercival214763f2016-07-01 23:27:018217 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]7c6f7ba2012-04-03 04:09:298218
8219 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:018220 EXPECT_THAT(rv, IsOk());
[email protected]7c6f7ba2012-04-03 04:09:298221 const HttpResponseInfo* push_response = push_trans->GetResponseInfo();
8222
wezca1070932016-05-26 20:30:528223 ASSERT_TRUE(response);
[email protected]7c6f7ba2012-04-03 04:09:298224 EXPECT_TRUE(response->headers->IsKeepAlive());
8225
8226 EXPECT_EQ(200, response->headers->response_code());
8227 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
8228
8229 std::string response_data;
8230 rv = ReadTransaction(trans.get(), &response_data);
robpercival214763f2016-07-01 23:27:018231 EXPECT_THAT(rv, IsOk());
[email protected]7c6f7ba2012-04-03 04:09:298232 EXPECT_EQ("hello!", response_data);
8233
[email protected]029c83b62013-01-24 05:28:208234 LoadTimingInfo load_timing_info;
8235 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
8236 TestLoadTimingNotReusedWithPac(load_timing_info,
8237 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
8238
[email protected]7c6f7ba2012-04-03 04:09:298239 // Verify the pushed stream.
wezca1070932016-05-26 20:30:528240 EXPECT_TRUE(push_response->headers);
[email protected]7c6f7ba2012-04-03 04:09:298241 EXPECT_EQ(200, push_response->headers->response_code());
8242
8243 rv = ReadTransaction(push_trans.get(), &response_data);
robpercival214763f2016-07-01 23:27:018244 EXPECT_THAT(rv, IsOk());
[email protected]7c6f7ba2012-04-03 04:09:298245 EXPECT_EQ("pushed", response_data);
8246
[email protected]029c83b62013-01-24 05:28:208247 LoadTimingInfo push_load_timing_info;
8248 EXPECT_TRUE(push_trans->GetLoadTimingInfo(&push_load_timing_info));
8249 TestLoadTimingReusedWithPac(push_load_timing_info);
8250 // The transactions should share a socket ID, despite being for different
8251 // origins.
8252 EXPECT_EQ(load_timing_info.socket_log_id,
8253 push_load_timing_info.socket_log_id);
8254
[email protected]7c6f7ba2012-04-03 04:09:298255 trans.reset();
8256 push_trans.reset();
8257 session->CloseAllConnections();
8258}
8259
[email protected]8c843192012-04-05 07:15:008260// Test that an explicitly trusted SPDY proxy cannot push HTTPS content.
bncd16676a2016-07-20 16:23:018261TEST_F(HttpNetworkTransactionTest, CrossOriginProxyPushCorrectness) {
tbansal28e68f82016-02-04 02:56:158262 // Configure the proxy delegate to allow cross-origin SPDY pushes.
danakj1fd259a02016-04-16 03:17:098263 std::unique_ptr<TestProxyDelegate> proxy_delegate(new TestProxyDelegate());
tbansal28e68f82016-02-04 02:56:158264 proxy_delegate->set_trusted_spdy_proxy(net::ProxyServer::FromURI(
8265 "https://myproxy:443", net::ProxyServer::SCHEME_HTTP));
[email protected]8c843192012-04-05 07:15:008266 HttpRequestInfo request;
8267
8268 request.method = "GET";
bncce36dca22015-04-21 22:11:238269 request.url = GURL("http://www.example.org/");
[email protected]8c843192012-04-05 07:15:008270
tbansal28e68f82016-02-04 02:56:158271 session_deps_.proxy_service =
8272 ProxyService::CreateFixed("https://myproxy:443");
vishal.b62985ca92015-04-17 08:45:518273 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:078274 session_deps_.net_log = log.bound().net_log();
[email protected]61b4efc2012-04-27 18:12:508275
8276 // Enable cross-origin push.
inlinechan894515af2016-12-09 02:40:108277 session_deps_.proxy_delegate = std::move(proxy_delegate);
[email protected]61b4efc2012-04-27 18:12:508278
danakj1fd259a02016-04-16 03:17:098279 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]8c843192012-04-05 07:15:008280
bncdf80d44fd2016-07-15 20:27:418281 SpdySerializedFrame stream1_syn(
bncb26024382016-06-29 02:39:458282 spdy_util_.ConstructSpdyGet("http://www.example.org/", 1, LOWEST));
[email protected]8c843192012-04-05 07:15:008283
bncdf80d44fd2016-07-15 20:27:418284 SpdySerializedFrame push_rst(
diannahu9904e272017-02-03 14:40:088285 spdy_util_.ConstructSpdyRstStream(2, ERROR_CODE_REFUSED_STREAM));
[email protected]8c843192012-04-05 07:15:008286
8287 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:418288 CreateMockWrite(stream1_syn, 0, ASYNC), CreateMockWrite(push_rst, 3),
[email protected]8c843192012-04-05 07:15:008289 };
8290
bncdf80d44fd2016-07-15 20:27:418291 SpdySerializedFrame stream1_reply(
bnc42331402016-07-25 13:36:158292 spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
[email protected]8c843192012-04-05 07:15:008293
bncdf80d44fd2016-07-15 20:27:418294 SpdySerializedFrame stream1_body(spdy_util_.ConstructSpdyDataFrame(1, true));
[email protected]8c843192012-04-05 07:15:008295
bncdf80d44fd2016-07-15 20:27:418296 SpdySerializedFrame stream2_syn(spdy_util_.ConstructSpdyPush(
bncb03b1092016-04-06 11:19:558297 NULL, 0, 2, 1, "https://www.another-origin.com/foo.dat"));
[email protected]8c843192012-04-05 07:15:008298
8299 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:418300 CreateMockRead(stream1_reply, 1, ASYNC),
8301 CreateMockRead(stream2_syn, 2, ASYNC),
8302 CreateMockRead(stream1_body, 4, ASYNC),
mmenkee24011922015-12-17 22:12:598303 MockRead(SYNCHRONOUS, ERR_IO_PENDING, 5), // Force a hang
[email protected]8c843192012-04-05 07:15:008304 };
8305
rch8e6c6c42015-05-01 14:05:138306 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
8307 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:078308 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]8c843192012-04-05 07:15:008309 // Negotiate SPDY to the proxy
8310 SSLSocketDataProvider proxy(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:368311 proxy.next_proto = kProtoHTTP2;
[email protected]bb88e1d32013-05-03 23:11:078312 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy);
[email protected]8c843192012-04-05 07:15:008313
bnc691fda62016-08-12 00:43:168314 std::unique_ptr<HttpNetworkTransaction> trans(
[email protected]90499482013-06-01 00:39:508315 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]8c843192012-04-05 07:15:008316 TestCompletionCallback callback;
8317 int rv = trans->Start(&request, callback.callback(), log.bound());
robpercival214763f2016-07-01 23:27:018318 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]8c843192012-04-05 07:15:008319
8320 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:018321 EXPECT_THAT(rv, IsOk());
[email protected]8c843192012-04-05 07:15:008322 const HttpResponseInfo* response = trans->GetResponseInfo();
8323
wezca1070932016-05-26 20:30:528324 ASSERT_TRUE(response);
[email protected]8c843192012-04-05 07:15:008325 EXPECT_TRUE(response->headers->IsKeepAlive());
8326
8327 EXPECT_EQ(200, response->headers->response_code());
8328 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
8329
8330 std::string response_data;
8331 rv = ReadTransaction(trans.get(), &response_data);
robpercival214763f2016-07-01 23:27:018332 EXPECT_THAT(rv, IsOk());
[email protected]8c843192012-04-05 07:15:008333 EXPECT_EQ("hello!", response_data);
8334
8335 trans.reset();
8336 session->CloseAllConnections();
8337}
8338
tbansal8ef1d3e2016-02-03 04:05:428339// Test that an explicitly trusted SPDY proxy can push same-origin HTTPS
8340// resources.
bncd16676a2016-07-20 16:23:018341TEST_F(HttpNetworkTransactionTest, SameOriginProxyPushCorrectness) {
tbansal28e68f82016-02-04 02:56:158342 // Configure the proxy delegate to allow cross-origin SPDY pushes.
danakj1fd259a02016-04-16 03:17:098343 std::unique_ptr<TestProxyDelegate> proxy_delegate(new TestProxyDelegate());
tbansal28e68f82016-02-04 02:56:158344 proxy_delegate->set_trusted_spdy_proxy(
8345 net::ProxyServer::FromURI("myproxy:70", net::ProxyServer::SCHEME_HTTP));
8346
tbansal8ef1d3e2016-02-03 04:05:428347 HttpRequestInfo request;
8348
8349 request.method = "GET";
8350 request.url = GURL("http://www.example.org/");
8351
8352 // Configure against https proxy server "myproxy:70".
8353 session_deps_.proxy_service = ProxyService::CreateFixed("https://myproxy:70");
8354 BoundTestNetLog log;
8355 session_deps_.net_log = log.bound().net_log();
8356
8357 // Enable cross-origin push.
inlinechan894515af2016-12-09 02:40:108358 session_deps_.proxy_delegate = std::move(proxy_delegate);
tbansal8ef1d3e2016-02-03 04:05:428359
danakj1fd259a02016-04-16 03:17:098360 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
tbansal8ef1d3e2016-02-03 04:05:428361
bncdf80d44fd2016-07-15 20:27:418362 SpdySerializedFrame stream1_syn(
bncb26024382016-06-29 02:39:458363 spdy_util_.ConstructSpdyGet("http://www.example.org/", 1, LOWEST));
tombergan5d22c182017-01-11 02:05:358364 SpdySerializedFrame stream2_priority(
8365 spdy_util_.ConstructSpdyPriority(2, 1, IDLE, true));
tbansal8ef1d3e2016-02-03 04:05:428366
8367 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:418368 CreateMockWrite(stream1_syn, 0, ASYNC),
tombergan5d22c182017-01-11 02:05:358369 CreateMockWrite(stream2_priority, 3, ASYNC),
tbansal8ef1d3e2016-02-03 04:05:428370 };
8371
bncdf80d44fd2016-07-15 20:27:418372 SpdySerializedFrame stream1_reply(
bnc42331402016-07-25 13:36:158373 spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
tbansal8ef1d3e2016-02-03 04:05:428374
bncdf80d44fd2016-07-15 20:27:418375 SpdySerializedFrame stream2_syn(spdy_util_.ConstructSpdyPush(
bnc38dcd392016-02-09 23:19:498376 nullptr, 0, 2, 1, "https://myproxy:70/foo.dat"));
8377
bncdf80d44fd2016-07-15 20:27:418378 SpdySerializedFrame stream1_body(spdy_util_.ConstructSpdyDataFrame(1, true));
tbansal8ef1d3e2016-02-03 04:05:428379
bncdf80d44fd2016-07-15 20:27:418380 SpdySerializedFrame stream2_reply(
bnc42331402016-07-25 13:36:158381 spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
tbansal8ef1d3e2016-02-03 04:05:428382
bncdf80d44fd2016-07-15 20:27:418383 SpdySerializedFrame stream2_body(spdy_util_.ConstructSpdyDataFrame(1, true));
tbansal8ef1d3e2016-02-03 04:05:428384
8385 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:418386 CreateMockRead(stream1_reply, 1, ASYNC),
8387 CreateMockRead(stream2_syn, 2, ASYNC),
tombergan5d22c182017-01-11 02:05:358388 CreateMockRead(stream1_body, 4, ASYNC),
8389 CreateMockRead(stream2_body, 5, ASYNC),
8390 MockRead(SYNCHRONOUS, ERR_IO_PENDING, 6), // Force a hang
tbansal8ef1d3e2016-02-03 04:05:428391 };
8392
8393 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
8394 arraysize(spdy_writes));
8395 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
8396 // Negotiate SPDY to the proxy
8397 SSLSocketDataProvider proxy(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:368398 proxy.next_proto = kProtoHTTP2;
tbansal8ef1d3e2016-02-03 04:05:428399 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy);
8400
bnc691fda62016-08-12 00:43:168401 std::unique_ptr<HttpNetworkTransaction> trans(
tbansal8ef1d3e2016-02-03 04:05:428402 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
8403 TestCompletionCallback callback;
8404 int rv = trans->Start(&request, callback.callback(), log.bound());
robpercival214763f2016-07-01 23:27:018405 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
tbansal8ef1d3e2016-02-03 04:05:428406
8407 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:018408 EXPECT_THAT(rv, IsOk());
tbansal8ef1d3e2016-02-03 04:05:428409 const HttpResponseInfo* response = trans->GetResponseInfo();
8410
wezca1070932016-05-26 20:30:528411 ASSERT_TRUE(response);
tbansal8ef1d3e2016-02-03 04:05:428412 EXPECT_TRUE(response->headers->IsKeepAlive());
8413
8414 EXPECT_EQ(200, response->headers->response_code());
8415 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
8416
8417 std::string response_data;
8418 rv = ReadTransaction(trans.get(), &response_data);
robpercival214763f2016-07-01 23:27:018419 EXPECT_THAT(rv, IsOk());
tbansal8ef1d3e2016-02-03 04:05:428420 EXPECT_EQ("hello!", response_data);
8421
8422 trans.reset();
8423 session->CloseAllConnections();
8424}
8425
[email protected]2df19bb2010-08-25 20:13:468426// Test HTTPS connections to a site with a bad certificate, going through an
8427// HTTPS proxy
bncd16676a2016-07-20 16:23:018428TEST_F(HttpNetworkTransactionTest, HTTPSBadCertificateViaHttpsProxy) {
rdsmith82957ad2015-09-16 19:42:038429 session_deps_.proxy_service = ProxyService::CreateFixed("https://proxy:70");
[email protected]2df19bb2010-08-25 20:13:468430
8431 HttpRequestInfo request;
8432 request.method = "GET";
bncce36dca22015-04-21 22:11:238433 request.url = GURL("https://www.example.org/");
[email protected]2df19bb2010-08-25 20:13:468434
8435 // Attempt to fetch the URL from a server with a bad cert
8436 MockWrite bad_cert_writes[] = {
rsleevidb16bb02015-11-12 23:47:178437 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
8438 "Host: www.example.org:443\r\n"
8439 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]2df19bb2010-08-25 20:13:468440 };
8441
8442 MockRead bad_cert_reads[] = {
8443 MockRead("HTTP/1.0 200 Connected\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:068444 MockRead(SYNCHRONOUS, OK)
[email protected]2df19bb2010-08-25 20:13:468445 };
8446
8447 // Attempt to fetch the URL with a good cert
8448 MockWrite good_data_writes[] = {
rsleevidb16bb02015-11-12 23:47:178449 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
8450 "Host: www.example.org:443\r\n"
8451 "Proxy-Connection: keep-alive\r\n\r\n"),
8452 MockWrite("GET / HTTP/1.1\r\n"
8453 "Host: www.example.org\r\n"
8454 "Connection: keep-alive\r\n\r\n"),
[email protected]2df19bb2010-08-25 20:13:468455 };
8456
8457 MockRead good_cert_reads[] = {
8458 MockRead("HTTP/1.0 200 Connected\r\n\r\n"),
8459 MockRead("HTTP/1.0 200 OK\r\n"),
8460 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
8461 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:068462 MockRead(SYNCHRONOUS, OK),
[email protected]2df19bb2010-08-25 20:13:468463 };
8464
8465 StaticSocketDataProvider ssl_bad_certificate(
8466 bad_cert_reads, arraysize(bad_cert_reads),
8467 bad_cert_writes, arraysize(bad_cert_writes));
8468 StaticSocketDataProvider data(good_cert_reads, arraysize(good_cert_reads),
8469 good_data_writes, arraysize(good_data_writes));
[email protected]8ddf8322012-02-23 18:08:068470 SSLSocketDataProvider ssl_bad(ASYNC, ERR_CERT_AUTHORITY_INVALID);
8471 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]2df19bb2010-08-25 20:13:468472
8473 // SSL to the proxy, then CONNECT request, then SSL with bad certificate
[email protected]bb88e1d32013-05-03 23:11:078474 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
8475 session_deps_.socket_factory->AddSocketDataProvider(&ssl_bad_certificate);
8476 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_bad);
[email protected]2df19bb2010-08-25 20:13:468477
8478 // SSL to the proxy, then CONNECT request, then valid SSL certificate
[email protected]bb88e1d32013-05-03 23:11:078479 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
8480 session_deps_.socket_factory->AddSocketDataProvider(&data);
8481 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]2df19bb2010-08-25 20:13:468482
[email protected]49639fa2011-12-20 23:22:418483 TestCompletionCallback callback;
[email protected]2df19bb2010-08-25 20:13:468484
danakj1fd259a02016-04-16 03:17:098485 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:168486 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]2df19bb2010-08-25 20:13:468487
tfarina42834112016-09-22 13:38:208488 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:018489 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2df19bb2010-08-25 20:13:468490
8491 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:018492 EXPECT_THAT(rv, IsError(ERR_CERT_AUTHORITY_INVALID));
[email protected]2df19bb2010-08-25 20:13:468493
bnc691fda62016-08-12 00:43:168494 rv = trans.RestartIgnoringLastError(callback.callback());
robpercival214763f2016-07-01 23:27:018495 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2df19bb2010-08-25 20:13:468496
8497 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:018498 EXPECT_THAT(rv, IsOk());
[email protected]2df19bb2010-08-25 20:13:468499
bnc691fda62016-08-12 00:43:168500 const HttpResponseInfo* response = trans.GetResponseInfo();
[email protected]2df19bb2010-08-25 20:13:468501
wezca1070932016-05-26 20:30:528502 ASSERT_TRUE(response);
[email protected]2df19bb2010-08-25 20:13:468503 EXPECT_EQ(100, response->headers->GetContentLength());
8504}
8505
bncd16676a2016-07-20 16:23:018506TEST_F(HttpNetworkTransactionTest, BuildRequest_UserAgent) {
[email protected]1c773ea12009-04-28 19:58:428507 HttpRequestInfo request;
8508 request.method = "GET";
bncce36dca22015-04-21 22:11:238509 request.url = GURL("http://www.example.org/");
[email protected]8c76ae22010-04-20 22:15:438510 request.extra_headers.SetHeader(HttpRequestHeaders::kUserAgent,
8511 "Chromium Ultra Awesome X Edition");
[email protected]1c773ea12009-04-28 19:58:428512
danakj1fd259a02016-04-16 03:17:098513 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:168514 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:278515
[email protected]1c773ea12009-04-28 19:58:428516 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:238517 MockWrite(
8518 "GET / HTTP/1.1\r\n"
8519 "Host: www.example.org\r\n"
8520 "Connection: keep-alive\r\n"
8521 "User-Agent: Chromium Ultra Awesome X Edition\r\n\r\n"),
[email protected]1c773ea12009-04-28 19:58:428522 };
8523
8524 // Lastly, the server responds with the actual content.
8525 MockRead data_reads[] = {
8526 MockRead("HTTP/1.0 200 OK\r\n"),
8527 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
8528 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:068529 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:428530 };
8531
[email protected]31a2bfe2010-02-09 08:03:398532 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
8533 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:078534 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:428535
[email protected]49639fa2011-12-20 23:22:418536 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:428537
tfarina42834112016-09-22 13:38:208538 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:018539 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]1c773ea12009-04-28 19:58:428540
8541 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:018542 EXPECT_THAT(rv, IsOk());
[email protected]1c773ea12009-04-28 19:58:428543}
8544
bncd16676a2016-07-20 16:23:018545TEST_F(HttpNetworkTransactionTest, BuildRequest_UserAgentOverTunnel) {
[email protected]da81f132010-08-18 23:39:298546 HttpRequestInfo request;
8547 request.method = "GET";
bncce36dca22015-04-21 22:11:238548 request.url = GURL("https://www.example.org/");
[email protected]da81f132010-08-18 23:39:298549 request.extra_headers.SetHeader(HttpRequestHeaders::kUserAgent,
8550 "Chromium Ultra Awesome X Edition");
8551
rdsmith82957ad2015-09-16 19:42:038552 session_deps_.proxy_service = ProxyService::CreateFixed("myproxy:70");
danakj1fd259a02016-04-16 03:17:098553 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:168554 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:278555
[email protected]da81f132010-08-18 23:39:298556 MockWrite data_writes[] = {
rsleevidb16bb02015-11-12 23:47:178557 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
8558 "Host: www.example.org:443\r\n"
8559 "Proxy-Connection: keep-alive\r\n"
8560 "User-Agent: Chromium Ultra Awesome X Edition\r\n\r\n"),
[email protected]da81f132010-08-18 23:39:298561 };
8562 MockRead data_reads[] = {
8563 // Return an error, so the transaction stops here (this test isn't
8564 // interested in the rest).
8565 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
8566 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
8567 MockRead("Proxy-Connection: close\r\n\r\n"),
8568 };
8569
8570 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
8571 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:078572 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]da81f132010-08-18 23:39:298573
[email protected]49639fa2011-12-20 23:22:418574 TestCompletionCallback callback;
[email protected]da81f132010-08-18 23:39:298575
tfarina42834112016-09-22 13:38:208576 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:018577 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]da81f132010-08-18 23:39:298578
8579 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:018580 EXPECT_THAT(rv, IsOk());
[email protected]da81f132010-08-18 23:39:298581}
8582
bncd16676a2016-07-20 16:23:018583TEST_F(HttpNetworkTransactionTest, BuildRequest_Referer) {
[email protected]1c773ea12009-04-28 19:58:428584 HttpRequestInfo request;
8585 request.method = "GET";
bncce36dca22015-04-21 22:11:238586 request.url = GURL("http://www.example.org/");
[email protected]c10450102011-06-27 09:06:168587 request.extra_headers.SetHeader(HttpRequestHeaders::kReferer,
8588 "http://the.previous.site.com/");
[email protected]1c773ea12009-04-28 19:58:428589
danakj1fd259a02016-04-16 03:17:098590 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:168591 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:278592
[email protected]1c773ea12009-04-28 19:58:428593 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:238594 MockWrite(
8595 "GET / HTTP/1.1\r\n"
8596 "Host: www.example.org\r\n"
8597 "Connection: keep-alive\r\n"
8598 "Referer: http://the.previous.site.com/\r\n\r\n"),
[email protected]1c773ea12009-04-28 19:58:428599 };
8600
8601 // Lastly, the server responds with the actual content.
8602 MockRead data_reads[] = {
8603 MockRead("HTTP/1.0 200 OK\r\n"),
8604 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
8605 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:068606 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:428607 };
8608
[email protected]31a2bfe2010-02-09 08:03:398609 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
8610 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:078611 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:428612
[email protected]49639fa2011-12-20 23:22:418613 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:428614
tfarina42834112016-09-22 13:38:208615 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:018616 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]1c773ea12009-04-28 19:58:428617
8618 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:018619 EXPECT_THAT(rv, IsOk());
[email protected]1c773ea12009-04-28 19:58:428620}
8621
bncd16676a2016-07-20 16:23:018622TEST_F(HttpNetworkTransactionTest, BuildRequest_PostContentLengthZero) {
[email protected]1c773ea12009-04-28 19:58:428623 HttpRequestInfo request;
8624 request.method = "POST";
bncce36dca22015-04-21 22:11:238625 request.url = GURL("http://www.example.org/");
[email protected]1c773ea12009-04-28 19:58:428626
danakj1fd259a02016-04-16 03:17:098627 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:168628 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:278629
[email protected]1c773ea12009-04-28 19:58:428630 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:238631 MockWrite(
8632 "POST / HTTP/1.1\r\n"
8633 "Host: www.example.org\r\n"
8634 "Connection: keep-alive\r\n"
8635 "Content-Length: 0\r\n\r\n"),
[email protected]1c773ea12009-04-28 19:58:428636 };
8637
8638 // Lastly, the server responds with the actual content.
8639 MockRead data_reads[] = {
8640 MockRead("HTTP/1.0 200 OK\r\n"),
8641 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
8642 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:068643 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:428644 };
8645
[email protected]31a2bfe2010-02-09 08:03:398646 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
8647 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:078648 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:428649
[email protected]49639fa2011-12-20 23:22:418650 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:428651
tfarina42834112016-09-22 13:38:208652 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:018653 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]1c773ea12009-04-28 19:58:428654
8655 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:018656 EXPECT_THAT(rv, IsOk());
[email protected]1c773ea12009-04-28 19:58:428657}
8658
bncd16676a2016-07-20 16:23:018659TEST_F(HttpNetworkTransactionTest, BuildRequest_PutContentLengthZero) {
[email protected]1c773ea12009-04-28 19:58:428660 HttpRequestInfo request;
8661 request.method = "PUT";
bncce36dca22015-04-21 22:11:238662 request.url = GURL("http://www.example.org/");
[email protected]1c773ea12009-04-28 19:58:428663
danakj1fd259a02016-04-16 03:17:098664 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:168665 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:278666
[email protected]1c773ea12009-04-28 19:58:428667 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:238668 MockWrite(
8669 "PUT / HTTP/1.1\r\n"
8670 "Host: www.example.org\r\n"
8671 "Connection: keep-alive\r\n"
8672 "Content-Length: 0\r\n\r\n"),
[email protected]1c773ea12009-04-28 19:58:428673 };
8674
8675 // Lastly, the server responds with the actual content.
8676 MockRead data_reads[] = {
8677 MockRead("HTTP/1.0 200 OK\r\n"),
8678 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
8679 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:068680 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:428681 };
8682
[email protected]31a2bfe2010-02-09 08:03:398683 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
8684 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:078685 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:428686
[email protected]49639fa2011-12-20 23:22:418687 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:428688
tfarina42834112016-09-22 13:38:208689 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:018690 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]1c773ea12009-04-28 19:58:428691
8692 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:018693 EXPECT_THAT(rv, IsOk());
[email protected]1c773ea12009-04-28 19:58:428694}
8695
bncd16676a2016-07-20 16:23:018696TEST_F(HttpNetworkTransactionTest, BuildRequest_HeadContentLengthZero) {
[email protected]1c773ea12009-04-28 19:58:428697 HttpRequestInfo request;
8698 request.method = "HEAD";
bncce36dca22015-04-21 22:11:238699 request.url = GURL("http://www.example.org/");
[email protected]1c773ea12009-04-28 19:58:428700
danakj1fd259a02016-04-16 03:17:098701 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:168702 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:278703
[email protected]1c773ea12009-04-28 19:58:428704 MockWrite data_writes[] = {
csharrisonf473dd192015-08-18 13:54:138705 MockWrite("HEAD / HTTP/1.1\r\n"
8706 "Host: www.example.org\r\n"
8707 "Connection: keep-alive\r\n\r\n"),
[email protected]1c773ea12009-04-28 19:58:428708 };
8709
8710 // Lastly, the server responds with the actual content.
8711 MockRead data_reads[] = {
8712 MockRead("HTTP/1.0 200 OK\r\n"),
8713 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
8714 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:068715 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:428716 };
8717
[email protected]31a2bfe2010-02-09 08:03:398718 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
8719 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:078720 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:428721
[email protected]49639fa2011-12-20 23:22:418722 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:428723
tfarina42834112016-09-22 13:38:208724 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:018725 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]1c773ea12009-04-28 19:58:428726
8727 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:018728 EXPECT_THAT(rv, IsOk());
[email protected]1c773ea12009-04-28 19:58:428729}
8730
bncd16676a2016-07-20 16:23:018731TEST_F(HttpNetworkTransactionTest, BuildRequest_CacheControlNoCache) {
[email protected]1c773ea12009-04-28 19:58:428732 HttpRequestInfo request;
8733 request.method = "GET";
bncce36dca22015-04-21 22:11:238734 request.url = GURL("http://www.example.org/");
[email protected]1c773ea12009-04-28 19:58:428735 request.load_flags = LOAD_BYPASS_CACHE;
8736
danakj1fd259a02016-04-16 03:17:098737 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:168738 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:278739
[email protected]1c773ea12009-04-28 19:58:428740 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:238741 MockWrite(
8742 "GET / HTTP/1.1\r\n"
8743 "Host: www.example.org\r\n"
8744 "Connection: keep-alive\r\n"
8745 "Pragma: no-cache\r\n"
8746 "Cache-Control: no-cache\r\n\r\n"),
[email protected]1c773ea12009-04-28 19:58:428747 };
8748
8749 // Lastly, the server responds with the actual content.
8750 MockRead data_reads[] = {
8751 MockRead("HTTP/1.0 200 OK\r\n"),
8752 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
8753 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:068754 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:428755 };
8756
[email protected]31a2bfe2010-02-09 08:03:398757 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
8758 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:078759 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:428760
[email protected]49639fa2011-12-20 23:22:418761 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:428762
tfarina42834112016-09-22 13:38:208763 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:018764 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]1c773ea12009-04-28 19:58:428765
8766 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:018767 EXPECT_THAT(rv, IsOk());
[email protected]1c773ea12009-04-28 19:58:428768}
8769
bncd16676a2016-07-20 16:23:018770TEST_F(HttpNetworkTransactionTest, BuildRequest_CacheControlValidateCache) {
[email protected]1c773ea12009-04-28 19:58:428771 HttpRequestInfo request;
8772 request.method = "GET";
bncce36dca22015-04-21 22:11:238773 request.url = GURL("http://www.example.org/");
[email protected]1c773ea12009-04-28 19:58:428774 request.load_flags = LOAD_VALIDATE_CACHE;
8775
danakj1fd259a02016-04-16 03:17:098776 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:168777 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:278778
[email protected]1c773ea12009-04-28 19:58:428779 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:238780 MockWrite(
8781 "GET / HTTP/1.1\r\n"
8782 "Host: www.example.org\r\n"
8783 "Connection: keep-alive\r\n"
8784 "Cache-Control: max-age=0\r\n\r\n"),
[email protected]1c773ea12009-04-28 19:58:428785 };
8786
8787 // Lastly, the server responds with the actual content.
8788 MockRead data_reads[] = {
8789 MockRead("HTTP/1.0 200 OK\r\n"),
8790 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
8791 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:068792 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:428793 };
8794
[email protected]31a2bfe2010-02-09 08:03:398795 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
8796 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:078797 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:428798
[email protected]49639fa2011-12-20 23:22:418799 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:428800
tfarina42834112016-09-22 13:38:208801 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:018802 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]1c773ea12009-04-28 19:58:428803
8804 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:018805 EXPECT_THAT(rv, IsOk());
[email protected]1c773ea12009-04-28 19:58:428806}
8807
bncd16676a2016-07-20 16:23:018808TEST_F(HttpNetworkTransactionTest, BuildRequest_ExtraHeaders) {
[email protected]1c773ea12009-04-28 19:58:428809 HttpRequestInfo request;
8810 request.method = "GET";
bncce36dca22015-04-21 22:11:238811 request.url = GURL("http://www.example.org/");
[email protected]8c76ae22010-04-20 22:15:438812 request.extra_headers.SetHeader("FooHeader", "Bar");
[email protected]1c773ea12009-04-28 19:58:428813
danakj1fd259a02016-04-16 03:17:098814 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:168815 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:278816
[email protected]1c773ea12009-04-28 19:58:428817 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:238818 MockWrite(
8819 "GET / HTTP/1.1\r\n"
8820 "Host: www.example.org\r\n"
8821 "Connection: keep-alive\r\n"
8822 "FooHeader: Bar\r\n\r\n"),
[email protected]1c773ea12009-04-28 19:58:428823 };
8824
8825 // Lastly, the server responds with the actual content.
8826 MockRead data_reads[] = {
8827 MockRead("HTTP/1.0 200 OK\r\n"),
8828 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
8829 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:068830 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:428831 };
8832
[email protected]31a2bfe2010-02-09 08:03:398833 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
8834 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:078835 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:428836
[email protected]49639fa2011-12-20 23:22:418837 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:428838
tfarina42834112016-09-22 13:38:208839 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:018840 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]1c773ea12009-04-28 19:58:428841
8842 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:018843 EXPECT_THAT(rv, IsOk());
[email protected]1c773ea12009-04-28 19:58:428844}
8845
bncd16676a2016-07-20 16:23:018846TEST_F(HttpNetworkTransactionTest, BuildRequest_ExtraHeadersStripped) {
[email protected]270c6412010-03-29 22:02:478847 HttpRequestInfo request;
8848 request.method = "GET";
bncce36dca22015-04-21 22:11:238849 request.url = GURL("http://www.example.org/");
[email protected]8c76ae22010-04-20 22:15:438850 request.extra_headers.SetHeader("referer", "www.foo.com");
8851 request.extra_headers.SetHeader("hEllo", "Kitty");
8852 request.extra_headers.SetHeader("FoO", "bar");
[email protected]270c6412010-03-29 22:02:478853
danakj1fd259a02016-04-16 03:17:098854 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:168855 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:278856
[email protected]270c6412010-03-29 22:02:478857 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:238858 MockWrite(
8859 "GET / HTTP/1.1\r\n"
8860 "Host: www.example.org\r\n"
8861 "Connection: keep-alive\r\n"
8862 "referer: www.foo.com\r\n"
8863 "hEllo: Kitty\r\n"
8864 "FoO: bar\r\n\r\n"),
[email protected]270c6412010-03-29 22:02:478865 };
8866
8867 // Lastly, the server responds with the actual content.
8868 MockRead data_reads[] = {
8869 MockRead("HTTP/1.0 200 OK\r\n"),
8870 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
8871 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:068872 MockRead(SYNCHRONOUS, OK),
[email protected]270c6412010-03-29 22:02:478873 };
8874
8875 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
8876 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:078877 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]270c6412010-03-29 22:02:478878
[email protected]49639fa2011-12-20 23:22:418879 TestCompletionCallback callback;
[email protected]270c6412010-03-29 22:02:478880
tfarina42834112016-09-22 13:38:208881 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:018882 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]270c6412010-03-29 22:02:478883
8884 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:018885 EXPECT_THAT(rv, IsOk());
[email protected]270c6412010-03-29 22:02:478886}
8887
bncd16676a2016-07-20 16:23:018888TEST_F(HttpNetworkTransactionTest, SOCKS4_HTTP_GET) {
[email protected]cb9bf6ca2011-01-28 13:15:278889 HttpRequestInfo request;
8890 request.method = "GET";
bncce36dca22015-04-21 22:11:238891 request.url = GURL("http://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:278892
rdsmith82957ad2015-09-16 19:42:038893 session_deps_.proxy_service =
8894 ProxyService::CreateFixedFromPacResult("SOCKS myproxy:1080");
vishal.b62985ca92015-04-17 08:45:518895 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:078896 session_deps_.net_log = &net_log;
[email protected]3cd17242009-06-23 02:59:028897
danakj1fd259a02016-04-16 03:17:098898 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:168899 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]3cd17242009-06-23 02:59:028900
[email protected]3cd17242009-06-23 02:59:028901 char write_buffer[] = { 0x04, 0x01, 0x00, 0x50, 127, 0, 0, 1, 0 };
8902 char read_buffer[] = { 0x00, 0x5A, 0x00, 0x00, 0, 0, 0, 0 };
8903
8904 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:238905 MockWrite(ASYNC, write_buffer, arraysize(write_buffer)),
8906 MockWrite(
8907 "GET / HTTP/1.1\r\n"
8908 "Host: www.example.org\r\n"
8909 "Connection: keep-alive\r\n\r\n")};
[email protected]3cd17242009-06-23 02:59:028910
8911 MockRead data_reads[] = {
[email protected]8ddf8322012-02-23 18:08:068912 MockRead(ASYNC, read_buffer, arraysize(read_buffer)),
[email protected]3cd17242009-06-23 02:59:028913 MockRead("HTTP/1.0 200 OK\r\n"),
8914 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n\r\n"),
8915 MockRead("Payload"),
[email protected]8ddf8322012-02-23 18:08:068916 MockRead(SYNCHRONOUS, OK)
[email protected]3cd17242009-06-23 02:59:028917 };
8918
[email protected]31a2bfe2010-02-09 08:03:398919 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
8920 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:078921 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]3cd17242009-06-23 02:59:028922
[email protected]49639fa2011-12-20 23:22:418923 TestCompletionCallback callback;
[email protected]3cd17242009-06-23 02:59:028924
tfarina42834112016-09-22 13:38:208925 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:018926 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]3cd17242009-06-23 02:59:028927
8928 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:018929 EXPECT_THAT(rv, IsOk());
[email protected]3cd17242009-06-23 02:59:028930
bnc691fda62016-08-12 00:43:168931 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:528932 ASSERT_TRUE(response);
[email protected]3cd17242009-06-23 02:59:028933
tbansal2ecbbc72016-10-06 17:15:478934 EXPECT_EQ(ProxyServer::SCHEME_SOCKS4, response->proxy_server.scheme());
[email protected]029c83b62013-01-24 05:28:208935 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:168936 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]029c83b62013-01-24 05:28:208937 TestLoadTimingNotReusedWithPac(load_timing_info,
8938 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
8939
[email protected]3cd17242009-06-23 02:59:028940 std::string response_text;
bnc691fda62016-08-12 00:43:168941 rv = ReadTransaction(&trans, &response_text);
robpercival214763f2016-07-01 23:27:018942 EXPECT_THAT(rv, IsOk());
[email protected]3cd17242009-06-23 02:59:028943 EXPECT_EQ("Payload", response_text);
8944}
8945
bncd16676a2016-07-20 16:23:018946TEST_F(HttpNetworkTransactionTest, SOCKS4_SSL_GET) {
[email protected]cb9bf6ca2011-01-28 13:15:278947 HttpRequestInfo request;
8948 request.method = "GET";
bncce36dca22015-04-21 22:11:238949 request.url = GURL("https://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:278950
rdsmith82957ad2015-09-16 19:42:038951 session_deps_.proxy_service =
8952 ProxyService::CreateFixedFromPacResult("SOCKS myproxy:1080");
vishal.b62985ca92015-04-17 08:45:518953 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:078954 session_deps_.net_log = &net_log;
[email protected]3cd17242009-06-23 02:59:028955
danakj1fd259a02016-04-16 03:17:098956 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:168957 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]3cd17242009-06-23 02:59:028958
[email protected]3cd17242009-06-23 02:59:028959 unsigned char write_buffer[] = { 0x04, 0x01, 0x01, 0xBB, 127, 0, 0, 1, 0 };
8960 unsigned char read_buffer[] = { 0x00, 0x5A, 0x00, 0x00, 0, 0, 0, 0 };
8961
8962 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:238963 MockWrite(ASYNC, reinterpret_cast<char*>(write_buffer),
8964 arraysize(write_buffer)),
8965 MockWrite(
8966 "GET / HTTP/1.1\r\n"
8967 "Host: www.example.org\r\n"
8968 "Connection: keep-alive\r\n\r\n")};
[email protected]3cd17242009-06-23 02:59:028969
8970 MockRead data_reads[] = {
[email protected]f871ee152012-07-27 19:02:018971 MockRead(ASYNC, reinterpret_cast<char*>(read_buffer),
8972 arraysize(read_buffer)),
[email protected]e0c27be2009-07-15 13:09:358973 MockRead("HTTP/1.0 200 OK\r\n"),
8974 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n\r\n"),
8975 MockRead("Payload"),
[email protected]8ddf8322012-02-23 18:08:068976 MockRead(SYNCHRONOUS, OK)
[email protected]e0c27be2009-07-15 13:09:358977 };
8978
[email protected]31a2bfe2010-02-09 08:03:398979 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
8980 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:078981 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]e0c27be2009-07-15 13:09:358982
[email protected]8ddf8322012-02-23 18:08:068983 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:078984 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]e0c27be2009-07-15 13:09:358985
[email protected]49639fa2011-12-20 23:22:418986 TestCompletionCallback callback;
[email protected]e0c27be2009-07-15 13:09:358987
tfarina42834112016-09-22 13:38:208988 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:018989 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]e0c27be2009-07-15 13:09:358990
8991 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:018992 EXPECT_THAT(rv, IsOk());
[email protected]e0c27be2009-07-15 13:09:358993
[email protected]029c83b62013-01-24 05:28:208994 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:168995 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]029c83b62013-01-24 05:28:208996 TestLoadTimingNotReusedWithPac(load_timing_info,
8997 CONNECT_TIMING_HAS_SSL_TIMES);
8998
bnc691fda62016-08-12 00:43:168999 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:529000 ASSERT_TRUE(response);
tbansal2ecbbc72016-10-06 17:15:479001 EXPECT_EQ(ProxyServer::SCHEME_SOCKS4, response->proxy_server.scheme());
[email protected]e0c27be2009-07-15 13:09:359002
9003 std::string response_text;
bnc691fda62016-08-12 00:43:169004 rv = ReadTransaction(&trans, &response_text);
robpercival214763f2016-07-01 23:27:019005 EXPECT_THAT(rv, IsOk());
[email protected]e0c27be2009-07-15 13:09:359006 EXPECT_EQ("Payload", response_text);
9007}
9008
bncd16676a2016-07-20 16:23:019009TEST_F(HttpNetworkTransactionTest, SOCKS4_HTTP_GET_no_PAC) {
[email protected]029c83b62013-01-24 05:28:209010 HttpRequestInfo request;
9011 request.method = "GET";
bncce36dca22015-04-21 22:11:239012 request.url = GURL("http://www.example.org/");
[email protected]029c83b62013-01-24 05:28:209013
rdsmith82957ad2015-09-16 19:42:039014 session_deps_.proxy_service =
9015 ProxyService::CreateFixed("socks4://myproxy:1080");
vishal.b62985ca92015-04-17 08:45:519016 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:079017 session_deps_.net_log = &net_log;
[email protected]029c83b62013-01-24 05:28:209018
danakj1fd259a02016-04-16 03:17:099019 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:169020 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]029c83b62013-01-24 05:28:209021
9022 char write_buffer[] = { 0x04, 0x01, 0x00, 0x50, 127, 0, 0, 1, 0 };
9023 char read_buffer[] = { 0x00, 0x5A, 0x00, 0x00, 0, 0, 0, 0 };
9024
9025 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:239026 MockWrite(ASYNC, write_buffer, arraysize(write_buffer)),
9027 MockWrite(
9028 "GET / HTTP/1.1\r\n"
9029 "Host: www.example.org\r\n"
9030 "Connection: keep-alive\r\n\r\n")};
[email protected]029c83b62013-01-24 05:28:209031
9032 MockRead data_reads[] = {
9033 MockRead(ASYNC, read_buffer, arraysize(read_buffer)),
9034 MockRead("HTTP/1.0 200 OK\r\n"),
9035 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n\r\n"),
9036 MockRead("Payload"),
9037 MockRead(SYNCHRONOUS, OK)
9038 };
9039
9040 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
9041 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:079042 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]029c83b62013-01-24 05:28:209043
9044 TestCompletionCallback callback;
9045
tfarina42834112016-09-22 13:38:209046 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:019047 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]029c83b62013-01-24 05:28:209048
9049 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:019050 EXPECT_THAT(rv, IsOk());
[email protected]029c83b62013-01-24 05:28:209051
bnc691fda62016-08-12 00:43:169052 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:529053 ASSERT_TRUE(response);
[email protected]029c83b62013-01-24 05:28:209054
9055 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:169056 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]029c83b62013-01-24 05:28:209057 TestLoadTimingNotReused(load_timing_info,
9058 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
9059
9060 std::string response_text;
bnc691fda62016-08-12 00:43:169061 rv = ReadTransaction(&trans, &response_text);
robpercival214763f2016-07-01 23:27:019062 EXPECT_THAT(rv, IsOk());
[email protected]029c83b62013-01-24 05:28:209063 EXPECT_EQ("Payload", response_text);
9064}
9065
bncd16676a2016-07-20 16:23:019066TEST_F(HttpNetworkTransactionTest, SOCKS5_HTTP_GET) {
[email protected]cb9bf6ca2011-01-28 13:15:279067 HttpRequestInfo request;
9068 request.method = "GET";
bncce36dca22015-04-21 22:11:239069 request.url = GURL("http://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:279070
rdsmith82957ad2015-09-16 19:42:039071 session_deps_.proxy_service =
9072 ProxyService::CreateFixedFromPacResult("SOCKS5 myproxy:1080");
vishal.b62985ca92015-04-17 08:45:519073 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:079074 session_deps_.net_log = &net_log;
[email protected]e0c27be2009-07-15 13:09:359075
danakj1fd259a02016-04-16 03:17:099076 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:169077 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]e0c27be2009-07-15 13:09:359078
[email protected]e0c27be2009-07-15 13:09:359079 const char kSOCKS5GreetRequest[] = { 0x05, 0x01, 0x00 };
9080 const char kSOCKS5GreetResponse[] = { 0x05, 0x00 };
[email protected]f209dba2009-12-18 00:24:379081 const char kSOCKS5OkRequest[] = {
bncce36dca22015-04-21 22:11:239082 0x05, // Version
9083 0x01, // Command (CONNECT)
9084 0x00, // Reserved.
9085 0x03, // Address type (DOMAINNAME).
9086 0x0F, // Length of domain (15)
9087 'w', 'w', 'w', '.', 'e', 'x', 'a', 'm', 'p', 'l', 'e', // Domain string
9088 '.', 'o', 'r', 'g', 0x00, 0x50, // 16-bit port (80)
[email protected]f209dba2009-12-18 00:24:379089 };
[email protected]e0c27be2009-07-15 13:09:359090 const char kSOCKS5OkResponse[] =
9091 { 0x05, 0x00, 0x00, 0x01, 127, 0, 0, 1, 0x00, 0x50 };
9092
9093 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:239094 MockWrite(ASYNC, kSOCKS5GreetRequest, arraysize(kSOCKS5GreetRequest)),
9095 MockWrite(ASYNC, kSOCKS5OkRequest, arraysize(kSOCKS5OkRequest)),
9096 MockWrite(
9097 "GET / HTTP/1.1\r\n"
9098 "Host: www.example.org\r\n"
9099 "Connection: keep-alive\r\n\r\n")};
[email protected]e0c27be2009-07-15 13:09:359100
9101 MockRead data_reads[] = {
[email protected]f871ee152012-07-27 19:02:019102 MockRead(ASYNC, kSOCKS5GreetResponse, arraysize(kSOCKS5GreetResponse)),
9103 MockRead(ASYNC, kSOCKS5OkResponse, arraysize(kSOCKS5OkResponse)),
[email protected]e0c27be2009-07-15 13:09:359104 MockRead("HTTP/1.0 200 OK\r\n"),
9105 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n\r\n"),
9106 MockRead("Payload"),
[email protected]8ddf8322012-02-23 18:08:069107 MockRead(SYNCHRONOUS, OK)
[email protected]e0c27be2009-07-15 13:09:359108 };
9109
[email protected]31a2bfe2010-02-09 08:03:399110 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
9111 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:079112 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]e0c27be2009-07-15 13:09:359113
[email protected]49639fa2011-12-20 23:22:419114 TestCompletionCallback callback;
[email protected]e0c27be2009-07-15 13:09:359115
tfarina42834112016-09-22 13:38:209116 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:019117 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]e0c27be2009-07-15 13:09:359118
9119 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:019120 EXPECT_THAT(rv, IsOk());
[email protected]e0c27be2009-07-15 13:09:359121
bnc691fda62016-08-12 00:43:169122 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:529123 ASSERT_TRUE(response);
tbansal2ecbbc72016-10-06 17:15:479124 EXPECT_EQ(ProxyServer::SCHEME_SOCKS5, response->proxy_server.scheme());
[email protected]e0c27be2009-07-15 13:09:359125
[email protected]029c83b62013-01-24 05:28:209126 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:169127 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]029c83b62013-01-24 05:28:209128 TestLoadTimingNotReusedWithPac(load_timing_info,
9129 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
9130
[email protected]e0c27be2009-07-15 13:09:359131 std::string response_text;
bnc691fda62016-08-12 00:43:169132 rv = ReadTransaction(&trans, &response_text);
robpercival214763f2016-07-01 23:27:019133 EXPECT_THAT(rv, IsOk());
[email protected]e0c27be2009-07-15 13:09:359134 EXPECT_EQ("Payload", response_text);
9135}
9136
bncd16676a2016-07-20 16:23:019137TEST_F(HttpNetworkTransactionTest, SOCKS5_SSL_GET) {
[email protected]cb9bf6ca2011-01-28 13:15:279138 HttpRequestInfo request;
9139 request.method = "GET";
bncce36dca22015-04-21 22:11:239140 request.url = GURL("https://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:279141
rdsmith82957ad2015-09-16 19:42:039142 session_deps_.proxy_service =
9143 ProxyService::CreateFixedFromPacResult("SOCKS5 myproxy:1080");
vishal.b62985ca92015-04-17 08:45:519144 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:079145 session_deps_.net_log = &net_log;
[email protected]e0c27be2009-07-15 13:09:359146
danakj1fd259a02016-04-16 03:17:099147 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:169148 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]e0c27be2009-07-15 13:09:359149
[email protected]e0c27be2009-07-15 13:09:359150 const char kSOCKS5GreetRequest[] = { 0x05, 0x01, 0x00 };
9151 const char kSOCKS5GreetResponse[] = { 0x05, 0x00 };
[email protected]f209dba2009-12-18 00:24:379152 const unsigned char kSOCKS5OkRequest[] = {
bncce36dca22015-04-21 22:11:239153 0x05, // Version
9154 0x01, // Command (CONNECT)
9155 0x00, // Reserved.
9156 0x03, // Address type (DOMAINNAME).
9157 0x0F, // Length of domain (15)
9158 'w', 'w', 'w', '.', 'e', 'x', 'a', 'm', 'p', 'l', 'e', // Domain string
9159 '.', 'o', 'r', 'g', 0x01, 0xBB, // 16-bit port (443)
[email protected]f209dba2009-12-18 00:24:379160 };
9161
[email protected]e0c27be2009-07-15 13:09:359162 const char kSOCKS5OkResponse[] =
9163 { 0x05, 0x00, 0x00, 0x01, 0, 0, 0, 0, 0x00, 0x00 };
9164
9165 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:239166 MockWrite(ASYNC, kSOCKS5GreetRequest, arraysize(kSOCKS5GreetRequest)),
9167 MockWrite(ASYNC, reinterpret_cast<const char*>(kSOCKS5OkRequest),
9168 arraysize(kSOCKS5OkRequest)),
9169 MockWrite(
9170 "GET / HTTP/1.1\r\n"
9171 "Host: www.example.org\r\n"
9172 "Connection: keep-alive\r\n\r\n")};
[email protected]e0c27be2009-07-15 13:09:359173
9174 MockRead data_reads[] = {
[email protected]f871ee152012-07-27 19:02:019175 MockRead(ASYNC, kSOCKS5GreetResponse, arraysize(kSOCKS5GreetResponse)),
9176 MockRead(ASYNC, kSOCKS5OkResponse, arraysize(kSOCKS5OkResponse)),
[email protected]3cd17242009-06-23 02:59:029177 MockRead("HTTP/1.0 200 OK\r\n"),
9178 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n\r\n"),
9179 MockRead("Payload"),
[email protected]8ddf8322012-02-23 18:08:069180 MockRead(SYNCHRONOUS, OK)
[email protected]3cd17242009-06-23 02:59:029181 };
9182
[email protected]31a2bfe2010-02-09 08:03:399183 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
9184 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:079185 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]3cd17242009-06-23 02:59:029186
[email protected]8ddf8322012-02-23 18:08:069187 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:079188 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]3cd17242009-06-23 02:59:029189
[email protected]49639fa2011-12-20 23:22:419190 TestCompletionCallback callback;
[email protected]3cd17242009-06-23 02:59:029191
tfarina42834112016-09-22 13:38:209192 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:019193 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]3cd17242009-06-23 02:59:029194
9195 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:019196 EXPECT_THAT(rv, IsOk());
[email protected]3cd17242009-06-23 02:59:029197
bnc691fda62016-08-12 00:43:169198 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:529199 ASSERT_TRUE(response);
tbansal2ecbbc72016-10-06 17:15:479200 EXPECT_EQ(ProxyServer::SCHEME_SOCKS5, response->proxy_server.scheme());
[email protected]3cd17242009-06-23 02:59:029201
[email protected]029c83b62013-01-24 05:28:209202 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:169203 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]029c83b62013-01-24 05:28:209204 TestLoadTimingNotReusedWithPac(load_timing_info,
9205 CONNECT_TIMING_HAS_SSL_TIMES);
9206
[email protected]3cd17242009-06-23 02:59:029207 std::string response_text;
bnc691fda62016-08-12 00:43:169208 rv = ReadTransaction(&trans, &response_text);
robpercival214763f2016-07-01 23:27:019209 EXPECT_THAT(rv, IsOk());
[email protected]3cd17242009-06-23 02:59:029210 EXPECT_EQ("Payload", response_text);
9211}
9212
[email protected]448d4ca52012-03-04 04:12:239213namespace {
9214
[email protected]04e5be32009-06-26 20:00:319215// Tests that for connection endpoints the group names are correctly set.
[email protected]2d731a32010-04-29 01:04:069216
9217struct GroupNameTest {
9218 std::string proxy_server;
9219 std::string url;
9220 std::string expected_group_name;
[email protected]e60e47a2010-07-14 03:37:189221 bool ssl;
[email protected]2d731a32010-04-29 01:04:069222};
9223
danakj1fd259a02016-04-16 03:17:099224std::unique_ptr<HttpNetworkSession> SetupSessionForGroupNameTests(
[email protected]bb88e1d32013-05-03 23:11:079225 SpdySessionDependencies* session_deps_) {
danakj1fd259a02016-04-16 03:17:099226 std::unique_ptr<HttpNetworkSession> session(CreateSession(session_deps_));
[email protected]2d731a32010-04-29 01:04:069227
bnc525e175a2016-06-20 12:36:409228 HttpServerProperties* http_server_properties =
[email protected]17291a022011-10-10 07:32:539229 session->http_server_properties();
bnc3472afd2016-11-17 15:27:219230 AlternativeService alternative_service(kProtoHTTP2, "", 444);
bnc7dc7e1b42015-07-28 14:43:129231 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
bnccacc0992015-03-20 20:22:229232 http_server_properties->SetAlternativeService(
bncaa60ff402016-06-22 19:12:429233 url::SchemeHostPort("https", "host.with.alternate", 443),
zhongyi3d4a55e72016-04-22 20:36:469234 alternative_service, expiration);
[email protected]2d731a32010-04-29 01:04:069235
9236 return session;
9237}
9238
mmenkee65e7af2015-10-13 17:16:429239int GroupNameTransactionHelper(const std::string& url,
9240 HttpNetworkSession* session) {
[email protected]2d731a32010-04-29 01:04:069241 HttpRequestInfo request;
9242 request.method = "GET";
9243 request.url = GURL(url);
[email protected]2d731a32010-04-29 01:04:069244
bnc691fda62016-08-12 00:43:169245 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session);
[email protected]cb9bf6ca2011-01-28 13:15:279246
[email protected]49639fa2011-12-20 23:22:419247 TestCompletionCallback callback;
[email protected]2d731a32010-04-29 01:04:069248
9249 // We do not complete this request, the dtor will clean the transaction up.
tfarina42834112016-09-22 13:38:209250 return trans.Start(&request, callback.callback(), NetLogWithSource());
[email protected]2d731a32010-04-29 01:04:069251}
9252
[email protected]448d4ca52012-03-04 04:12:239253} // namespace
9254
bncd16676a2016-07-20 16:23:019255TEST_F(HttpNetworkTransactionTest, GroupNameForDirectConnections) {
[email protected]2d731a32010-04-29 01:04:069256 const GroupNameTest tests[] = {
bncce36dca22015-04-21 22:11:239257 {
9258 "", // unused
9259 "http://www.example.org/direct",
9260 "www.example.org:80",
9261 false,
9262 },
9263 {
9264 "", // unused
9265 "http://[2001:1418:13:1::25]/direct",
9266 "[2001:1418:13:1::25]:80",
9267 false,
9268 },
[email protected]04e5be32009-06-26 20:00:319269
bncce36dca22015-04-21 22:11:239270 // SSL Tests
9271 {
9272 "", // unused
9273 "https://www.example.org/direct_ssl",
9274 "ssl/www.example.org:443",
9275 true,
9276 },
9277 {
9278 "", // unused
9279 "https://[2001:1418:13:1::25]/direct",
9280 "ssl/[2001:1418:13:1::25]:443",
9281 true,
9282 },
9283 {
9284 "", // unused
bncaa60ff402016-06-22 19:12:429285 "https://host.with.alternate/direct",
bncce36dca22015-04-21 22:11:239286 "ssl/host.with.alternate:443",
9287 true,
9288 },
[email protected]2d731a32010-04-29 01:04:069289 };
[email protected]2ff8b312010-04-26 22:20:549290
viettrungluue4a8b882014-10-16 06:17:389291 for (size_t i = 0; i < arraysize(tests); ++i) {
rdsmith82957ad2015-09-16 19:42:039292 session_deps_.proxy_service =
9293 ProxyService::CreateFixed(tests[i].proxy_server);
danakj1fd259a02016-04-16 03:17:099294 std::unique_ptr<HttpNetworkSession> session(
bnca9b9e222016-07-11 20:10:409295 SetupSessionForGroupNameTests(&session_deps_));
[email protected]2d731a32010-04-29 01:04:069296
mmenkee65e7af2015-10-13 17:16:429297 HttpNetworkSessionPeer peer(session.get());
[email protected]ab739042011-04-07 15:22:289298 CaptureGroupNameTransportSocketPool* transport_conn_pool =
9299 new CaptureGroupNameTransportSocketPool(NULL, NULL);
[email protected]2431756e2010-09-29 20:26:139300 CaptureGroupNameSSLSocketPool* ssl_conn_pool =
[email protected]9e1bdd32011-02-03 21:48:349301 new CaptureGroupNameSSLSocketPool(NULL, NULL);
danakj1fd259a02016-04-16 03:17:099302 std::unique_ptr<MockClientSocketPoolManager> mock_pool_manager(
[email protected]831e4a32013-11-14 02:14:449303 new MockClientSocketPoolManager);
[email protected]a42dbd142011-11-17 16:42:029304 mock_pool_manager->SetTransportSocketPool(transport_conn_pool);
9305 mock_pool_manager->SetSSLSocketPool(ssl_conn_pool);
dchengc7eeda422015-12-26 03:56:489306 peer.SetClientSocketPoolManager(std::move(mock_pool_manager));
[email protected]2d731a32010-04-29 01:04:069307
9308 EXPECT_EQ(ERR_IO_PENDING,
mmenkee65e7af2015-10-13 17:16:429309 GroupNameTransactionHelper(tests[i].url, session.get()));
[email protected]e60e47a2010-07-14 03:37:189310 if (tests[i].ssl)
9311 EXPECT_EQ(tests[i].expected_group_name,
9312 ssl_conn_pool->last_group_name_received());
9313 else
9314 EXPECT_EQ(tests[i].expected_group_name,
[email protected]ab739042011-04-07 15:22:289315 transport_conn_pool->last_group_name_received());
[email protected]2d731a32010-04-29 01:04:069316 }
[email protected]2d731a32010-04-29 01:04:069317}
9318
bncd16676a2016-07-20 16:23:019319TEST_F(HttpNetworkTransactionTest, GroupNameForHTTPProxyConnections) {
[email protected]2d731a32010-04-29 01:04:069320 const GroupNameTest tests[] = {
bncce36dca22015-04-21 22:11:239321 {
9322 "http_proxy",
9323 "http://www.example.org/http_proxy_normal",
9324 "www.example.org:80",
9325 false,
9326 },
[email protected]2d731a32010-04-29 01:04:069327
bncce36dca22015-04-21 22:11:239328 // SSL Tests
9329 {
9330 "http_proxy",
9331 "https://www.example.org/http_connect_ssl",
9332 "ssl/www.example.org:443",
9333 true,
9334 },
[email protected]af3490e2010-10-16 21:02:299335
bncce36dca22015-04-21 22:11:239336 {
9337 "http_proxy",
bncaa60ff402016-06-22 19:12:429338 "https://host.with.alternate/direct",
bncce36dca22015-04-21 22:11:239339 "ssl/host.with.alternate:443",
9340 true,
9341 },
[email protected]45499252013-01-23 17:12:569342
bncce36dca22015-04-21 22:11:239343 {
9344 "http_proxy",
9345 "ftp://ftp.google.com/http_proxy_normal",
9346 "ftp/ftp.google.com:21",
9347 false,
9348 },
[email protected]2d731a32010-04-29 01:04:069349 };
9350
viettrungluue4a8b882014-10-16 06:17:389351 for (size_t i = 0; i < arraysize(tests); ++i) {
rdsmith82957ad2015-09-16 19:42:039352 session_deps_.proxy_service =
9353 ProxyService::CreateFixed(tests[i].proxy_server);
danakj1fd259a02016-04-16 03:17:099354 std::unique_ptr<HttpNetworkSession> session(
bnca9b9e222016-07-11 20:10:409355 SetupSessionForGroupNameTests(&session_deps_));
[email protected]2d731a32010-04-29 01:04:069356
mmenkee65e7af2015-10-13 17:16:429357 HttpNetworkSessionPeer peer(session.get());
[email protected]2d731a32010-04-29 01:04:069358
[email protected]e60e47a2010-07-14 03:37:189359 HostPortPair proxy_host("http_proxy", 80);
[email protected]2431756e2010-09-29 20:26:139360 CaptureGroupNameHttpProxySocketPool* http_proxy_pool =
[email protected]9e1bdd32011-02-03 21:48:349361 new CaptureGroupNameHttpProxySocketPool(NULL, NULL);
[email protected]2431756e2010-09-29 20:26:139362 CaptureGroupNameSSLSocketPool* ssl_conn_pool =
[email protected]9e1bdd32011-02-03 21:48:349363 new CaptureGroupNameSSLSocketPool(NULL, NULL);
[email protected]a42dbd142011-11-17 16:42:029364
danakj1fd259a02016-04-16 03:17:099365 std::unique_ptr<MockClientSocketPoolManager> mock_pool_manager(
[email protected]831e4a32013-11-14 02:14:449366 new MockClientSocketPoolManager);
aviadef3442016-10-03 18:50:399367 mock_pool_manager->SetSocketPoolForHTTPProxy(
9368 proxy_host, base::WrapUnique(http_proxy_pool));
9369 mock_pool_manager->SetSocketPoolForSSLWithProxy(
9370 proxy_host, base::WrapUnique(ssl_conn_pool));
dchengc7eeda422015-12-26 03:56:489371 peer.SetClientSocketPoolManager(std::move(mock_pool_manager));
[email protected]2d731a32010-04-29 01:04:069372
9373 EXPECT_EQ(ERR_IO_PENDING,
mmenkee65e7af2015-10-13 17:16:429374 GroupNameTransactionHelper(tests[i].url, session.get()));
[email protected]e60e47a2010-07-14 03:37:189375 if (tests[i].ssl)
9376 EXPECT_EQ(tests[i].expected_group_name,
9377 ssl_conn_pool->last_group_name_received());
9378 else
9379 EXPECT_EQ(tests[i].expected_group_name,
9380 http_proxy_pool->last_group_name_received());
[email protected]2d731a32010-04-29 01:04:069381 }
[email protected]2d731a32010-04-29 01:04:069382}
9383
bncd16676a2016-07-20 16:23:019384TEST_F(HttpNetworkTransactionTest, GroupNameForSOCKSConnections) {
[email protected]2d731a32010-04-29 01:04:069385 const GroupNameTest tests[] = {
bncce36dca22015-04-21 22:11:239386 {
9387 "socks4://socks_proxy:1080",
9388 "http://www.example.org/socks4_direct",
9389 "socks4/www.example.org:80",
9390 false,
9391 },
9392 {
9393 "socks5://socks_proxy:1080",
9394 "http://www.example.org/socks5_direct",
9395 "socks5/www.example.org:80",
9396 false,
9397 },
[email protected]2d731a32010-04-29 01:04:069398
bncce36dca22015-04-21 22:11:239399 // SSL Tests
9400 {
9401 "socks4://socks_proxy:1080",
9402 "https://www.example.org/socks4_ssl",
9403 "socks4/ssl/www.example.org:443",
9404 true,
9405 },
9406 {
9407 "socks5://socks_proxy:1080",
9408 "https://www.example.org/socks5_ssl",
9409 "socks5/ssl/www.example.org:443",
9410 true,
9411 },
[email protected]af3490e2010-10-16 21:02:299412
bncce36dca22015-04-21 22:11:239413 {
9414 "socks4://socks_proxy:1080",
bncaa60ff402016-06-22 19:12:429415 "https://host.with.alternate/direct",
bncce36dca22015-04-21 22:11:239416 "socks4/ssl/host.with.alternate:443",
9417 true,
9418 },
[email protected]04e5be32009-06-26 20:00:319419 };
9420
viettrungluue4a8b882014-10-16 06:17:389421 for (size_t i = 0; i < arraysize(tests); ++i) {
rdsmith82957ad2015-09-16 19:42:039422 session_deps_.proxy_service =
9423 ProxyService::CreateFixed(tests[i].proxy_server);
danakj1fd259a02016-04-16 03:17:099424 std::unique_ptr<HttpNetworkSession> session(
bnca9b9e222016-07-11 20:10:409425 SetupSessionForGroupNameTests(&session_deps_));
[email protected]8b114dd72011-03-25 05:33:029426
mmenkee65e7af2015-10-13 17:16:429427 HttpNetworkSessionPeer peer(session.get());
[email protected]04e5be32009-06-26 20:00:319428
[email protected]e60e47a2010-07-14 03:37:189429 HostPortPair proxy_host("socks_proxy", 1080);
[email protected]2431756e2010-09-29 20:26:139430 CaptureGroupNameSOCKSSocketPool* socks_conn_pool =
[email protected]9e1bdd32011-02-03 21:48:349431 new CaptureGroupNameSOCKSSocketPool(NULL, NULL);
[email protected]2431756e2010-09-29 20:26:139432 CaptureGroupNameSSLSocketPool* ssl_conn_pool =
[email protected]9e1bdd32011-02-03 21:48:349433 new CaptureGroupNameSSLSocketPool(NULL, NULL);
[email protected]a42dbd142011-11-17 16:42:029434
danakj1fd259a02016-04-16 03:17:099435 std::unique_ptr<MockClientSocketPoolManager> mock_pool_manager(
[email protected]831e4a32013-11-14 02:14:449436 new MockClientSocketPoolManager);
aviadef3442016-10-03 18:50:399437 mock_pool_manager->SetSocketPoolForSOCKSProxy(
9438 proxy_host, base::WrapUnique(socks_conn_pool));
9439 mock_pool_manager->SetSocketPoolForSSLWithProxy(
9440 proxy_host, base::WrapUnique(ssl_conn_pool));
dchengc7eeda422015-12-26 03:56:489441 peer.SetClientSocketPoolManager(std::move(mock_pool_manager));
[email protected]04e5be32009-06-26 20:00:319442
bnc691fda62016-08-12 00:43:169443 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]04e5be32009-06-26 20:00:319444
[email protected]2d731a32010-04-29 01:04:069445 EXPECT_EQ(ERR_IO_PENDING,
mmenkee65e7af2015-10-13 17:16:429446 GroupNameTransactionHelper(tests[i].url, session.get()));
[email protected]e60e47a2010-07-14 03:37:189447 if (tests[i].ssl)
9448 EXPECT_EQ(tests[i].expected_group_name,
9449 ssl_conn_pool->last_group_name_received());
9450 else
9451 EXPECT_EQ(tests[i].expected_group_name,
9452 socks_conn_pool->last_group_name_received());
[email protected]04e5be32009-06-26 20:00:319453 }
9454}
9455
bncd16676a2016-07-20 16:23:019456TEST_F(HttpNetworkTransactionTest, ReconsiderProxyAfterFailedConnection) {
[email protected]cb9bf6ca2011-01-28 13:15:279457 HttpRequestInfo request;
9458 request.method = "GET";
bncce36dca22015-04-21 22:11:239459 request.url = GURL("http://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:279460
rdsmith82957ad2015-09-16 19:42:039461 session_deps_.proxy_service =
9462 ProxyService::CreateFixed("myproxy:70;foobar:80");
[email protected]b59ff372009-07-15 22:04:329463
[email protected]69719062010-01-05 20:09:219464 // This simulates failure resolving all hostnames; that means we will fail
9465 // connecting to both proxies (myproxy:70 and foobar:80).
[email protected]bb88e1d32013-05-03 23:11:079466 session_deps_.host_resolver->rules()->AddSimulatedFailure("*");
[email protected]b59ff372009-07-15 22:04:329467
danakj1fd259a02016-04-16 03:17:099468 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:169469 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]9172a982009-06-06 00:30:259470
[email protected]49639fa2011-12-20 23:22:419471 TestCompletionCallback callback;
[email protected]9172a982009-06-06 00:30:259472
tfarina42834112016-09-22 13:38:209473 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:019474 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]9172a982009-06-06 00:30:259475
[email protected]9172a982009-06-06 00:30:259476 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:019477 EXPECT_THAT(rv, IsError(ERR_PROXY_CONNECTION_FAILED));
[email protected]9172a982009-06-06 00:30:259478}
9479
[email protected]685af592010-05-11 19:31:249480// Base test to make sure that when the load flags for a request specify to
9481// bypass the cache, the DNS cache is not used.
[email protected]23e482282013-06-14 16:08:029482void HttpNetworkTransactionTest::BypassHostCacheOnRefreshHelper(
[email protected]bb88e1d32013-05-03 23:11:079483 int load_flags) {
[email protected]cb9bf6ca2011-01-28 13:15:279484 // Issue a request, asking to bypass the cache(s).
maksim.sisov31452af2016-07-27 06:38:109485 HttpRequestInfo request_info;
9486 request_info.method = "GET";
9487 request_info.load_flags = load_flags;
9488 request_info.url = GURL("http://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:279489
[email protected]a2c2fb92009-07-18 07:31:049490 // Select a host resolver that does caching.
[email protected]bb88e1d32013-05-03 23:11:079491 session_deps_.host_resolver.reset(new MockCachingHostResolver);
[email protected]b59ff372009-07-15 22:04:329492
danakj1fd259a02016-04-16 03:17:099493 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:169494 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]3b9cca42009-06-16 01:08:289495
bncce36dca22015-04-21 22:11:239496 // Warm up the host cache so it has an entry for "www.example.org".
[email protected]3b9cca42009-06-16 01:08:289497 AddressList addrlist;
[email protected]aa22b242011-11-16 18:58:299498 TestCompletionCallback callback;
maksim.sisov31452af2016-07-27 06:38:109499 std::unique_ptr<HostResolver::Request> request1;
[email protected]bb88e1d32013-05-03 23:11:079500 int rv = session_deps_.host_resolver->Resolve(
bncce36dca22015-04-21 22:11:239501 HostResolver::RequestInfo(HostPortPair("www.example.org", 80)),
maksim.sisov31452af2016-07-27 06:38:109502 DEFAULT_PRIORITY, &addrlist, callback.callback(), &request1,
tfarina42834112016-09-22 13:38:209503 NetLogWithSource());
robpercival214763f2016-07-01 23:27:019504 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]6e78dfb2011-07-28 21:34:479505 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:019506 EXPECT_THAT(rv, IsOk());
[email protected]3b9cca42009-06-16 01:08:289507
9508 // Verify that it was added to host cache, by doing a subsequent async lookup
9509 // and confirming it completes synchronously.
maksim.sisov31452af2016-07-27 06:38:109510 std::unique_ptr<HostResolver::Request> request2;
[email protected]bb88e1d32013-05-03 23:11:079511 rv = session_deps_.host_resolver->Resolve(
bncce36dca22015-04-21 22:11:239512 HostResolver::RequestInfo(HostPortPair("www.example.org", 80)),
maksim.sisov31452af2016-07-27 06:38:109513 DEFAULT_PRIORITY, &addrlist, callback.callback(), &request2,
tfarina42834112016-09-22 13:38:209514 NetLogWithSource());
robpercival214763f2016-07-01 23:27:019515 ASSERT_THAT(rv, IsOk());
[email protected]3b9cca42009-06-16 01:08:289516
bncce36dca22015-04-21 22:11:239517 // Inject a failure the next time that "www.example.org" is resolved. This way
[email protected]3b9cca42009-06-16 01:08:289518 // we can tell if the next lookup hit the cache, or the "network".
9519 // (cache --> success, "network" --> failure).
bncce36dca22015-04-21 22:11:239520 session_deps_.host_resolver->rules()->AddSimulatedFailure("www.example.org");
[email protected]3b9cca42009-06-16 01:08:289521
9522 // Connect up a mock socket which will fail with ERR_UNEXPECTED during the
9523 // first read -- this won't be reached as the host resolution will fail first.
[email protected]8ddf8322012-02-23 18:08:069524 MockRead data_reads[] = { MockRead(SYNCHRONOUS, ERR_UNEXPECTED) };
[email protected]31a2bfe2010-02-09 08:03:399525 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:079526 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]3b9cca42009-06-16 01:08:289527
[email protected]3b9cca42009-06-16 01:08:289528 // Run the request.
tfarina42834112016-09-22 13:38:209529 rv = trans.Start(&request_info, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:019530 ASSERT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]49639fa2011-12-20 23:22:419531 rv = callback.WaitForResult();
[email protected]3b9cca42009-06-16 01:08:289532
9533 // If we bypassed the cache, we would have gotten a failure while resolving
bncce36dca22015-04-21 22:11:239534 // "www.example.org".
robpercival214763f2016-07-01 23:27:019535 EXPECT_THAT(rv, IsError(ERR_NAME_NOT_RESOLVED));
[email protected]3b9cca42009-06-16 01:08:289536}
9537
[email protected]685af592010-05-11 19:31:249538// There are multiple load flags that should trigger the host cache bypass.
9539// Test each in isolation:
bncd16676a2016-07-20 16:23:019540TEST_F(HttpNetworkTransactionTest, BypassHostCacheOnRefresh1) {
[email protected]685af592010-05-11 19:31:249541 BypassHostCacheOnRefreshHelper(LOAD_BYPASS_CACHE);
9542}
9543
bncd16676a2016-07-20 16:23:019544TEST_F(HttpNetworkTransactionTest, BypassHostCacheOnRefresh2) {
[email protected]685af592010-05-11 19:31:249545 BypassHostCacheOnRefreshHelper(LOAD_VALIDATE_CACHE);
9546}
9547
bncd16676a2016-07-20 16:23:019548TEST_F(HttpNetworkTransactionTest, BypassHostCacheOnRefresh3) {
[email protected]685af592010-05-11 19:31:249549 BypassHostCacheOnRefreshHelper(LOAD_DISABLE_CACHE);
9550}
9551
[email protected]0877e3d2009-10-17 22:29:579552// Make sure we can handle an error when writing the request.
bncd16676a2016-07-20 16:23:019553TEST_F(HttpNetworkTransactionTest, RequestWriteError) {
[email protected]0877e3d2009-10-17 22:29:579554 HttpRequestInfo request;
9555 request.method = "GET";
9556 request.url = GURL("http://www.foo.com/");
[email protected]0877e3d2009-10-17 22:29:579557
9558 MockWrite write_failure[] = {
[email protected]8ddf8322012-02-23 18:08:069559 MockWrite(ASYNC, ERR_CONNECTION_RESET),
[email protected]0877e3d2009-10-17 22:29:579560 };
[email protected]31a2bfe2010-02-09 08:03:399561 StaticSocketDataProvider data(NULL, 0,
9562 write_failure, arraysize(write_failure));
[email protected]bb88e1d32013-05-03 23:11:079563 session_deps_.socket_factory->AddSocketDataProvider(&data);
danakj1fd259a02016-04-16 03:17:099564 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]0877e3d2009-10-17 22:29:579565
[email protected]49639fa2011-12-20 23:22:419566 TestCompletionCallback callback;
[email protected]0877e3d2009-10-17 22:29:579567
bnc691fda62016-08-12 00:43:169568 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]0877e3d2009-10-17 22:29:579569
tfarina42834112016-09-22 13:38:209570 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:019571 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]0877e3d2009-10-17 22:29:579572
9573 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:019574 EXPECT_THAT(rv, IsError(ERR_CONNECTION_RESET));
ttuttled9dbc652015-09-29 20:00:599575
9576 IPEndPoint endpoint;
bnc691fda62016-08-12 00:43:169577 EXPECT_TRUE(trans.GetRemoteEndpoint(&endpoint));
ttuttled9dbc652015-09-29 20:00:599578 EXPECT_LT(0u, endpoint.address().size());
[email protected]0877e3d2009-10-17 22:29:579579}
9580
zmo9528c9f42015-08-04 22:12:089581// Check that a connection closed after the start of the headers finishes ok.
bncd16676a2016-07-20 16:23:019582TEST_F(HttpNetworkTransactionTest, ConnectionClosedAfterStartOfHeaders) {
[email protected]0877e3d2009-10-17 22:29:579583 HttpRequestInfo request;
9584 request.method = "GET";
9585 request.url = GURL("http://www.foo.com/");
[email protected]0877e3d2009-10-17 22:29:579586
9587 MockRead data_reads[] = {
9588 MockRead("HTTP/1."),
[email protected]8ddf8322012-02-23 18:08:069589 MockRead(SYNCHRONOUS, OK),
[email protected]0877e3d2009-10-17 22:29:579590 };
9591
[email protected]31a2bfe2010-02-09 08:03:399592 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:079593 session_deps_.socket_factory->AddSocketDataProvider(&data);
danakj1fd259a02016-04-16 03:17:099594 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]0877e3d2009-10-17 22:29:579595
[email protected]49639fa2011-12-20 23:22:419596 TestCompletionCallback callback;
[email protected]0877e3d2009-10-17 22:29:579597
bnc691fda62016-08-12 00:43:169598 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]0877e3d2009-10-17 22:29:579599
tfarina42834112016-09-22 13:38:209600 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:019601 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]0877e3d2009-10-17 22:29:579602
9603 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:019604 EXPECT_THAT(rv, IsOk());
zmo9528c9f42015-08-04 22:12:089605
bnc691fda62016-08-12 00:43:169606 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:529607 ASSERT_TRUE(response);
zmo9528c9f42015-08-04 22:12:089608
wezca1070932016-05-26 20:30:529609 EXPECT_TRUE(response->headers);
zmo9528c9f42015-08-04 22:12:089610 EXPECT_EQ("HTTP/1.0 200 OK", response->headers->GetStatusLine());
9611
9612 std::string response_data;
bnc691fda62016-08-12 00:43:169613 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:019614 EXPECT_THAT(rv, IsOk());
zmo9528c9f42015-08-04 22:12:089615 EXPECT_EQ("", response_data);
ttuttled9dbc652015-09-29 20:00:599616
9617 IPEndPoint endpoint;
bnc691fda62016-08-12 00:43:169618 EXPECT_TRUE(trans.GetRemoteEndpoint(&endpoint));
ttuttled9dbc652015-09-29 20:00:599619 EXPECT_LT(0u, endpoint.address().size());
[email protected]0877e3d2009-10-17 22:29:579620}
9621
9622// Make sure that a dropped connection while draining the body for auth
9623// restart does the right thing.
bncd16676a2016-07-20 16:23:019624TEST_F(HttpNetworkTransactionTest, DrainResetOK) {
[email protected]0877e3d2009-10-17 22:29:579625 HttpRequestInfo request;
9626 request.method = "GET";
bncce36dca22015-04-21 22:11:239627 request.url = GURL("http://www.example.org/");
[email protected]0877e3d2009-10-17 22:29:579628
9629 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:239630 MockWrite(
9631 "GET / HTTP/1.1\r\n"
9632 "Host: www.example.org\r\n"
9633 "Connection: keep-alive\r\n\r\n"),
[email protected]0877e3d2009-10-17 22:29:579634 };
9635
9636 MockRead data_reads1[] = {
9637 MockRead("HTTP/1.1 401 Unauthorized\r\n"),
9638 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
9639 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
9640 MockRead("Content-Length: 14\r\n\r\n"),
9641 MockRead("Unauth"),
[email protected]8ddf8322012-02-23 18:08:069642 MockRead(ASYNC, ERR_CONNECTION_RESET),
[email protected]0877e3d2009-10-17 22:29:579643 };
9644
[email protected]31a2bfe2010-02-09 08:03:399645 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
9646 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:079647 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]0877e3d2009-10-17 22:29:579648
bnc691fda62016-08-12 00:43:169649 // After calling trans.RestartWithAuth(), this is the request we should
[email protected]0877e3d2009-10-17 22:29:579650 // be issuing -- the final header line contains the credentials.
9651 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:239652 MockWrite(
9653 "GET / HTTP/1.1\r\n"
9654 "Host: www.example.org\r\n"
9655 "Connection: keep-alive\r\n"
9656 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]0877e3d2009-10-17 22:29:579657 };
9658
9659 // Lastly, the server responds with the actual content.
9660 MockRead data_reads2[] = {
9661 MockRead("HTTP/1.1 200 OK\r\n"),
9662 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
9663 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:069664 MockRead(SYNCHRONOUS, OK),
[email protected]0877e3d2009-10-17 22:29:579665 };
9666
[email protected]31a2bfe2010-02-09 08:03:399667 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
9668 data_writes2, arraysize(data_writes2));
[email protected]bb88e1d32013-05-03 23:11:079669 session_deps_.socket_factory->AddSocketDataProvider(&data2);
danakj1fd259a02016-04-16 03:17:099670 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]0877e3d2009-10-17 22:29:579671
[email protected]49639fa2011-12-20 23:22:419672 TestCompletionCallback callback1;
[email protected]0877e3d2009-10-17 22:29:579673
bnc691fda62016-08-12 00:43:169674 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]0b0bf032010-09-21 18:08:509675
tfarina42834112016-09-22 13:38:209676 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:019677 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]0877e3d2009-10-17 22:29:579678
9679 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:019680 EXPECT_THAT(rv, IsOk());
[email protected]0877e3d2009-10-17 22:29:579681
bnc691fda62016-08-12 00:43:169682 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:529683 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:049684 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]0877e3d2009-10-17 22:29:579685
[email protected]49639fa2011-12-20 23:22:419686 TestCompletionCallback callback2;
[email protected]0877e3d2009-10-17 22:29:579687
bnc691fda62016-08-12 00:43:169688 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar), callback2.callback());
robpercival214763f2016-07-01 23:27:019689 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]0877e3d2009-10-17 22:29:579690
9691 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:019692 EXPECT_THAT(rv, IsOk());
[email protected]0877e3d2009-10-17 22:29:579693
bnc691fda62016-08-12 00:43:169694 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:529695 ASSERT_TRUE(response);
9696 EXPECT_FALSE(response->auth_challenge);
[email protected]0877e3d2009-10-17 22:29:579697 EXPECT_EQ(100, response->headers->GetContentLength());
9698}
9699
9700// Test HTTPS connections going through a proxy that sends extra data.
bncd16676a2016-07-20 16:23:019701TEST_F(HttpNetworkTransactionTest, HTTPSViaProxyWithExtraData) {
rdsmith82957ad2015-09-16 19:42:039702 session_deps_.proxy_service = ProxyService::CreateFixed("myproxy:70");
[email protected]0877e3d2009-10-17 22:29:579703
9704 HttpRequestInfo request;
9705 request.method = "GET";
bncce36dca22015-04-21 22:11:239706 request.url = GURL("https://www.example.org/");
[email protected]0877e3d2009-10-17 22:29:579707
9708 MockRead proxy_reads[] = {
9709 MockRead("HTTP/1.0 200 Connected\r\n\r\nExtra data"),
[email protected]8ddf8322012-02-23 18:08:069710 MockRead(SYNCHRONOUS, OK)
[email protected]0877e3d2009-10-17 22:29:579711 };
9712
[email protected]31a2bfe2010-02-09 08:03:399713 StaticSocketDataProvider data(proxy_reads, arraysize(proxy_reads), NULL, 0);
[email protected]8ddf8322012-02-23 18:08:069714 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]0877e3d2009-10-17 22:29:579715
[email protected]bb88e1d32013-05-03 23:11:079716 session_deps_.socket_factory->AddSocketDataProvider(&data);
9717 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]0877e3d2009-10-17 22:29:579718
[email protected]49639fa2011-12-20 23:22:419719 TestCompletionCallback callback;
[email protected]0877e3d2009-10-17 22:29:579720
[email protected]bb88e1d32013-05-03 23:11:079721 session_deps_.socket_factory->ResetNextMockIndexes();
[email protected]0877e3d2009-10-17 22:29:579722
danakj1fd259a02016-04-16 03:17:099723 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:169724 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]0877e3d2009-10-17 22:29:579725
tfarina42834112016-09-22 13:38:209726 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:019727 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]0877e3d2009-10-17 22:29:579728
9729 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:019730 EXPECT_THAT(rv, IsError(ERR_TUNNEL_CONNECTION_FAILED));
[email protected]0877e3d2009-10-17 22:29:579731}
9732
bncd16676a2016-07-20 16:23:019733TEST_F(HttpNetworkTransactionTest, LargeContentLengthThenClose) {
[email protected]9492e4a2010-02-24 00:58:469734 HttpRequestInfo request;
9735 request.method = "GET";
bncce36dca22015-04-21 22:11:239736 request.url = GURL("http://www.example.org/");
[email protected]9492e4a2010-02-24 00:58:469737
danakj1fd259a02016-04-16 03:17:099738 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:169739 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:279740
[email protected]e22e1362009-11-23 21:31:129741 MockRead data_reads[] = {
9742 MockRead("HTTP/1.0 200 OK\r\nContent-Length:6719476739\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:069743 MockRead(SYNCHRONOUS, OK),
[email protected]e22e1362009-11-23 21:31:129744 };
[email protected]9492e4a2010-02-24 00:58:469745
9746 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:079747 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]9492e4a2010-02-24 00:58:469748
[email protected]49639fa2011-12-20 23:22:419749 TestCompletionCallback callback;
[email protected]9492e4a2010-02-24 00:58:469750
tfarina42834112016-09-22 13:38:209751 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:019752 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]9492e4a2010-02-24 00:58:469753
robpercival214763f2016-07-01 23:27:019754 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]9492e4a2010-02-24 00:58:469755
bnc691fda62016-08-12 00:43:169756 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:529757 ASSERT_TRUE(response);
[email protected]9492e4a2010-02-24 00:58:469758
wezca1070932016-05-26 20:30:529759 EXPECT_TRUE(response->headers);
[email protected]9492e4a2010-02-24 00:58:469760 EXPECT_EQ("HTTP/1.0 200 OK", response->headers->GetStatusLine());
9761
9762 std::string response_data;
bnc691fda62016-08-12 00:43:169763 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:019764 EXPECT_THAT(rv, IsError(ERR_CONTENT_LENGTH_MISMATCH));
[email protected]e22e1362009-11-23 21:31:129765}
9766
bncd16676a2016-07-20 16:23:019767TEST_F(HttpNetworkTransactionTest, UploadFileSmallerThanLength) {
[email protected]6cdfd7f2013-02-08 20:40:159768 base::FilePath temp_file_path;
[email protected]03d9afc02013-12-03 17:55:529769 ASSERT_TRUE(base::CreateTemporaryFile(&temp_file_path));
avibf0746c2015-12-09 19:53:149770 const uint64_t kFakeSize = 100000; // file is actually blank
[email protected]d98961652012-09-11 20:27:219771 UploadFileElementReader::ScopedOverridingContentLengthForTests
9772 overriding_content_length(kFakeSize);
[email protected]95d88ffe2010-02-04 21:25:339773
danakj1fd259a02016-04-16 03:17:099774 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
ricea2deef682016-09-09 08:04:079775 element_readers.push_back(base::MakeUnique<UploadFileElementReader>(
avibf0746c2015-12-09 19:53:149776 base::ThreadTaskRunnerHandle::Get().get(), temp_file_path, 0,
ricea2deef682016-09-09 08:04:079777 std::numeric_limits<uint64_t>::max(), base::Time()));
olli.raula6df48b2a2015-11-26 07:40:229778 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]329b68b2012-11-14 17:54:279779
9780 HttpRequestInfo request;
9781 request.method = "POST";
bncce36dca22015-04-21 22:11:239782 request.url = GURL("http://www.example.org/upload");
[email protected]329b68b2012-11-14 17:54:279783 request.upload_data_stream = &upload_data_stream;
[email protected]329b68b2012-11-14 17:54:279784
danakj1fd259a02016-04-16 03:17:099785 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:169786 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]95d88ffe2010-02-04 21:25:339787
9788 MockRead data_reads[] = {
9789 MockRead("HTTP/1.0 200 OK\r\n\r\n"),
9790 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:069791 MockRead(SYNCHRONOUS, OK),
[email protected]95d88ffe2010-02-04 21:25:339792 };
[email protected]31a2bfe2010-02-09 08:03:399793 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:079794 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]95d88ffe2010-02-04 21:25:339795
[email protected]49639fa2011-12-20 23:22:419796 TestCompletionCallback callback;
[email protected]95d88ffe2010-02-04 21:25:339797
tfarina42834112016-09-22 13:38:209798 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:019799 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]95d88ffe2010-02-04 21:25:339800
9801 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:019802 EXPECT_THAT(rv, IsError(ERR_UPLOAD_FILE_CHANGED));
[email protected]95d88ffe2010-02-04 21:25:339803
bnc691fda62016-08-12 00:43:169804 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:529805 ASSERT_TRUE(response);
[email protected]95d88ffe2010-02-04 21:25:339806
maksim.sisove869bf52016-06-23 17:11:529807 EXPECT_FALSE(response->headers);
[email protected]95d88ffe2010-02-04 21:25:339808
[email protected]dd3aa792013-07-16 19:10:239809 base::DeleteFile(temp_file_path, false);
[email protected]95d88ffe2010-02-04 21:25:339810}
9811
bncd16676a2016-07-20 16:23:019812TEST_F(HttpNetworkTransactionTest, UploadUnreadableFile) {
[email protected]6cdfd7f2013-02-08 20:40:159813 base::FilePath temp_file;
[email protected]03d9afc02013-12-03 17:55:529814 ASSERT_TRUE(base::CreateTemporaryFile(&temp_file));
[email protected]6624b4622010-03-29 19:58:369815 std::string temp_file_content("Unreadable file.");
lazyboy8df84fc2017-04-12 02:12:489816 ASSERT_EQ(static_cast<int>(temp_file_content.length()),
9817 base::WriteFile(temp_file, temp_file_content.c_str(),
9818 temp_file_content.length()));
[email protected]92be8eb2014-08-07 22:57:119819 ASSERT_TRUE(base::MakeFileUnreadable(temp_file));
[email protected]6624b4622010-03-29 19:58:369820
danakj1fd259a02016-04-16 03:17:099821 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
ricea2deef682016-09-09 08:04:079822 element_readers.push_back(base::MakeUnique<UploadFileElementReader>(
avibf0746c2015-12-09 19:53:149823 base::ThreadTaskRunnerHandle::Get().get(), temp_file, 0,
ricea2deef682016-09-09 08:04:079824 std::numeric_limits<uint64_t>::max(), base::Time()));
olli.raula6df48b2a2015-11-26 07:40:229825 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]329b68b2012-11-14 17:54:279826
9827 HttpRequestInfo request;
9828 request.method = "POST";
bncce36dca22015-04-21 22:11:239829 request.url = GURL("http://www.example.org/upload");
[email protected]329b68b2012-11-14 17:54:279830 request.upload_data_stream = &upload_data_stream;
[email protected]329b68b2012-11-14 17:54:279831
[email protected]999dd8c2013-11-12 06:45:549832 // If we try to upload an unreadable file, the transaction should fail.
danakj1fd259a02016-04-16 03:17:099833 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:169834 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]6624b4622010-03-29 19:58:369835
[email protected]999dd8c2013-11-12 06:45:549836 StaticSocketDataProvider data(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:079837 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]6624b4622010-03-29 19:58:369838
[email protected]49639fa2011-12-20 23:22:419839 TestCompletionCallback callback;
[email protected]6624b4622010-03-29 19:58:369840
tfarina42834112016-09-22 13:38:209841 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:019842 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]6624b4622010-03-29 19:58:369843
9844 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:019845 EXPECT_THAT(rv, IsError(ERR_ACCESS_DENIED));
[email protected]6624b4622010-03-29 19:58:369846
[email protected]dd3aa792013-07-16 19:10:239847 base::DeleteFile(temp_file, false);
[email protected]6624b4622010-03-29 19:58:369848}
9849
bncd16676a2016-07-20 16:23:019850TEST_F(HttpNetworkTransactionTest, CancelDuringInitRequestBody) {
[email protected]02cad5d2013-10-02 08:14:039851 class FakeUploadElementReader : public UploadElementReader {
9852 public:
9853 FakeUploadElementReader() {}
dchengb03027d2014-10-21 12:00:209854 ~FakeUploadElementReader() override {}
[email protected]02cad5d2013-10-02 08:14:039855
9856 const CompletionCallback& callback() const { return callback_; }
9857
9858 // UploadElementReader overrides:
dchengb03027d2014-10-21 12:00:209859 int Init(const CompletionCallback& callback) override {
[email protected]02cad5d2013-10-02 08:14:039860 callback_ = callback;
9861 return ERR_IO_PENDING;
9862 }
avibf0746c2015-12-09 19:53:149863 uint64_t GetContentLength() const override { return 0; }
9864 uint64_t BytesRemaining() const override { return 0; }
dchengb03027d2014-10-21 12:00:209865 int Read(IOBuffer* buf,
9866 int buf_length,
9867 const CompletionCallback& callback) override {
[email protected]02cad5d2013-10-02 08:14:039868 return ERR_FAILED;
9869 }
9870
9871 private:
9872 CompletionCallback callback_;
9873 };
9874
9875 FakeUploadElementReader* fake_reader = new FakeUploadElementReader;
danakj1fd259a02016-04-16 03:17:099876 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
9877 element_readers.push_back(base::WrapUnique(fake_reader));
olli.raula6df48b2a2015-11-26 07:40:229878 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]02cad5d2013-10-02 08:14:039879
9880 HttpRequestInfo request;
9881 request.method = "POST";
bncce36dca22015-04-21 22:11:239882 request.url = GURL("http://www.example.org/upload");
[email protected]02cad5d2013-10-02 08:14:039883 request.upload_data_stream = &upload_data_stream;
[email protected]02cad5d2013-10-02 08:14:039884
danakj1fd259a02016-04-16 03:17:099885 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:169886 std::unique_ptr<HttpNetworkTransaction> trans(
dcheng48459ac22014-08-26 00:46:419887 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]02cad5d2013-10-02 08:14:039888
9889 StaticSocketDataProvider data;
9890 session_deps_.socket_factory->AddSocketDataProvider(&data);
9891
9892 TestCompletionCallback callback;
tfarina42834112016-09-22 13:38:209893 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:019894 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
fdoray92e35a72016-06-10 15:54:559895 base::RunLoop().RunUntilIdle();
[email protected]02cad5d2013-10-02 08:14:039896
9897 // Transaction is pending on request body initialization.
9898 ASSERT_FALSE(fake_reader->callback().is_null());
9899
9900 // Return Init()'s result after the transaction gets destroyed.
9901 trans.reset();
9902 fake_reader->callback().Run(OK); // Should not crash.
9903}
9904
[email protected]aeefc9e82010-02-19 16:18:279905// Tests that changes to Auth realms are treated like auth rejections.
bncd16676a2016-07-20 16:23:019906TEST_F(HttpNetworkTransactionTest, ChangeAuthRealms) {
[email protected]aeefc9e82010-02-19 16:18:279907 HttpRequestInfo request;
9908 request.method = "GET";
bncce36dca22015-04-21 22:11:239909 request.url = GURL("http://www.example.org/");
[email protected]aeefc9e82010-02-19 16:18:279910
9911 // First transaction will request a resource and receive a Basic challenge
9912 // with realm="first_realm".
9913 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:239914 MockWrite(
9915 "GET / HTTP/1.1\r\n"
9916 "Host: www.example.org\r\n"
9917 "Connection: keep-alive\r\n"
9918 "\r\n"),
[email protected]aeefc9e82010-02-19 16:18:279919 };
9920 MockRead data_reads1[] = {
9921 MockRead("HTTP/1.1 401 Unauthorized\r\n"
9922 "WWW-Authenticate: Basic realm=\"first_realm\"\r\n"
9923 "\r\n"),
9924 };
9925
bnc691fda62016-08-12 00:43:169926 // After calling trans.RestartWithAuth(), provide an Authentication header
[email protected]aeefc9e82010-02-19 16:18:279927 // for first_realm. The server will reject and provide a challenge with
9928 // second_realm.
9929 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:239930 MockWrite(
9931 "GET / HTTP/1.1\r\n"
9932 "Host: www.example.org\r\n"
9933 "Connection: keep-alive\r\n"
9934 "Authorization: Basic Zmlyc3Q6YmF6\r\n"
9935 "\r\n"),
[email protected]aeefc9e82010-02-19 16:18:279936 };
9937 MockRead data_reads2[] = {
9938 MockRead("HTTP/1.1 401 Unauthorized\r\n"
9939 "WWW-Authenticate: Basic realm=\"second_realm\"\r\n"
9940 "\r\n"),
9941 };
9942
9943 // This again fails, and goes back to first_realm. Make sure that the
9944 // entry is removed from cache.
9945 MockWrite data_writes3[] = {
bncce36dca22015-04-21 22:11:239946 MockWrite(
9947 "GET / HTTP/1.1\r\n"
9948 "Host: www.example.org\r\n"
9949 "Connection: keep-alive\r\n"
9950 "Authorization: Basic c2Vjb25kOmZvdQ==\r\n"
9951 "\r\n"),
[email protected]aeefc9e82010-02-19 16:18:279952 };
9953 MockRead data_reads3[] = {
9954 MockRead("HTTP/1.1 401 Unauthorized\r\n"
9955 "WWW-Authenticate: Basic realm=\"first_realm\"\r\n"
9956 "\r\n"),
9957 };
9958
9959 // Try one last time (with the correct password) and get the resource.
9960 MockWrite data_writes4[] = {
bncce36dca22015-04-21 22:11:239961 MockWrite(
9962 "GET / HTTP/1.1\r\n"
9963 "Host: www.example.org\r\n"
9964 "Connection: keep-alive\r\n"
9965 "Authorization: Basic Zmlyc3Q6YmFy\r\n"
9966 "\r\n"),
[email protected]aeefc9e82010-02-19 16:18:279967 };
9968 MockRead data_reads4[] = {
9969 MockRead("HTTP/1.1 200 OK\r\n"
9970 "Content-Type: text/html; charset=iso-8859-1\r\n"
[email protected]0b0bf032010-09-21 18:08:509971 "Content-Length: 5\r\n"
9972 "\r\n"
9973 "hello"),
[email protected]aeefc9e82010-02-19 16:18:279974 };
9975
9976 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
9977 data_writes1, arraysize(data_writes1));
9978 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
9979 data_writes2, arraysize(data_writes2));
9980 StaticSocketDataProvider data3(data_reads3, arraysize(data_reads3),
9981 data_writes3, arraysize(data_writes3));
9982 StaticSocketDataProvider data4(data_reads4, arraysize(data_reads4),
9983 data_writes4, arraysize(data_writes4));
[email protected]bb88e1d32013-05-03 23:11:079984 session_deps_.socket_factory->AddSocketDataProvider(&data1);
9985 session_deps_.socket_factory->AddSocketDataProvider(&data2);
9986 session_deps_.socket_factory->AddSocketDataProvider(&data3);
9987 session_deps_.socket_factory->AddSocketDataProvider(&data4);
[email protected]aeefc9e82010-02-19 16:18:279988
[email protected]49639fa2011-12-20 23:22:419989 TestCompletionCallback callback1;
[email protected]aeefc9e82010-02-19 16:18:279990
danakj1fd259a02016-04-16 03:17:099991 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:169992 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]0b0bf032010-09-21 18:08:509993
[email protected]aeefc9e82010-02-19 16:18:279994 // Issue the first request with Authorize headers. There should be a
9995 // password prompt for first_realm waiting to be filled in after the
9996 // transaction completes.
tfarina42834112016-09-22 13:38:209997 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:019998 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]aeefc9e82010-02-19 16:18:279999 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:0110000 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:1610001 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5210002 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:0410003 const AuthChallengeInfo* challenge = response->auth_challenge.get();
wezca1070932016-05-26 20:30:5210004 ASSERT_TRUE(challenge);
[email protected]79cb5c12011-09-12 13:12:0410005 EXPECT_FALSE(challenge->is_proxy);
asanka098c0092016-06-16 20:18:4310006 EXPECT_EQ("http://www.example.org", challenge->challenger.Serialize());
[email protected]79cb5c12011-09-12 13:12:0410007 EXPECT_EQ("first_realm", challenge->realm);
aberentbba302d2015-12-03 10:20:1910008 EXPECT_EQ(kBasicAuthScheme, challenge->scheme);
[email protected]aeefc9e82010-02-19 16:18:2710009
10010 // Issue the second request with an incorrect password. There should be a
10011 // password prompt for second_realm waiting to be filled in after the
10012 // transaction completes.
[email protected]49639fa2011-12-20 23:22:4110013 TestCompletionCallback callback2;
bnc691fda62016-08-12 00:43:1610014 rv = trans.RestartWithAuth(AuthCredentials(kFirst, kBaz),
10015 callback2.callback());
robpercival214763f2016-07-01 23:27:0110016 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]aeefc9e82010-02-19 16:18:2710017 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:0110018 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:1610019 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5210020 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:0410021 challenge = response->auth_challenge.get();
wezca1070932016-05-26 20:30:5210022 ASSERT_TRUE(challenge);
[email protected]79cb5c12011-09-12 13:12:0410023 EXPECT_FALSE(challenge->is_proxy);
asanka098c0092016-06-16 20:18:4310024 EXPECT_EQ("http://www.example.org", challenge->challenger.Serialize());
[email protected]79cb5c12011-09-12 13:12:0410025 EXPECT_EQ("second_realm", challenge->realm);
aberentbba302d2015-12-03 10:20:1910026 EXPECT_EQ(kBasicAuthScheme, challenge->scheme);
[email protected]aeefc9e82010-02-19 16:18:2710027
10028 // Issue the third request with another incorrect password. There should be
10029 // a password prompt for first_realm waiting to be filled in. If the password
10030 // prompt is not present, it indicates that the HttpAuthCacheEntry for
10031 // first_realm was not correctly removed.
[email protected]49639fa2011-12-20 23:22:4110032 TestCompletionCallback callback3;
bnc691fda62016-08-12 00:43:1610033 rv = trans.RestartWithAuth(AuthCredentials(kSecond, kFou),
10034 callback3.callback());
robpercival214763f2016-07-01 23:27:0110035 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]aeefc9e82010-02-19 16:18:2710036 rv = callback3.WaitForResult();
robpercival214763f2016-07-01 23:27:0110037 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:1610038 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5210039 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:0410040 challenge = response->auth_challenge.get();
wezca1070932016-05-26 20:30:5210041 ASSERT_TRUE(challenge);
[email protected]79cb5c12011-09-12 13:12:0410042 EXPECT_FALSE(challenge->is_proxy);
asanka098c0092016-06-16 20:18:4310043 EXPECT_EQ("http://www.example.org", challenge->challenger.Serialize());
[email protected]79cb5c12011-09-12 13:12:0410044 EXPECT_EQ("first_realm", challenge->realm);
aberentbba302d2015-12-03 10:20:1910045 EXPECT_EQ(kBasicAuthScheme, challenge->scheme);
[email protected]aeefc9e82010-02-19 16:18:2710046
10047 // Issue the fourth request with the correct password and username.
[email protected]49639fa2011-12-20 23:22:4110048 TestCompletionCallback callback4;
bnc691fda62016-08-12 00:43:1610049 rv = trans.RestartWithAuth(AuthCredentials(kFirst, kBar),
10050 callback4.callback());
robpercival214763f2016-07-01 23:27:0110051 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]aeefc9e82010-02-19 16:18:2710052 rv = callback4.WaitForResult();
robpercival214763f2016-07-01 23:27:0110053 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:1610054 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5210055 ASSERT_TRUE(response);
10056 EXPECT_FALSE(response->auth_challenge);
[email protected]aeefc9e82010-02-19 16:18:2710057}
10058
bncd16676a2016-07-20 16:23:0110059TEST_F(HttpNetworkTransactionTest, HonorAlternativeServiceHeader) {
bncc958faa2015-07-31 18:14:5210060 MockRead data_reads[] = {
10061 MockRead("HTTP/1.1 200 OK\r\n"),
bnc2df4b522016-07-08 18:17:4310062 MockRead(kAlternativeServiceHttpHeader),
bncc958faa2015-07-31 18:14:5210063 MockRead("\r\n"),
10064 MockRead("hello world"),
10065 MockRead(SYNCHRONOUS, OK),
10066 };
10067
10068 HttpRequestInfo request;
10069 request.method = "GET";
bncb26024382016-06-29 02:39:4510070 request.url = GURL("https://www.example.org/");
bncc958faa2015-07-31 18:14:5210071
10072 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
bncc958faa2015-07-31 18:14:5210073 session_deps_.socket_factory->AddSocketDataProvider(&data);
10074
bncb26024382016-06-29 02:39:4510075 SSLSocketDataProvider ssl(ASYNC, OK);
10076 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
10077
bncc958faa2015-07-31 18:14:5210078 TestCompletionCallback callback;
10079
danakj1fd259a02016-04-16 03:17:0910080 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1610081 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
bncc958faa2015-07-31 18:14:5210082
tfarina42834112016-09-22 13:38:2010083 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110084 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
bncc958faa2015-07-31 18:14:5210085
bncb26024382016-06-29 02:39:4510086 url::SchemeHostPort test_server(request.url);
bnc525e175a2016-06-20 12:36:4010087 HttpServerProperties* http_server_properties =
10088 session->http_server_properties();
bncc958faa2015-07-31 18:14:5210089 AlternativeServiceVector alternative_service_vector =
bnc525e175a2016-06-20 12:36:4010090 http_server_properties->GetAlternativeServices(test_server);
bncc958faa2015-07-31 18:14:5210091 EXPECT_TRUE(alternative_service_vector.empty());
10092
robpercival214763f2016-07-01 23:27:0110093 EXPECT_THAT(callback.WaitForResult(), IsOk());
bncc958faa2015-07-31 18:14:5210094
bnc691fda62016-08-12 00:43:1610095 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5210096 ASSERT_TRUE(response);
10097 ASSERT_TRUE(response->headers);
bncc958faa2015-07-31 18:14:5210098 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
10099 EXPECT_FALSE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5210100 EXPECT_FALSE(response->was_alpn_negotiated);
bncc958faa2015-07-31 18:14:5210101
10102 std::string response_data;
bnc691fda62016-08-12 00:43:1610103 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
bncc958faa2015-07-31 18:14:5210104 EXPECT_EQ("hello world", response_data);
10105
10106 alternative_service_vector =
bnc525e175a2016-06-20 12:36:4010107 http_server_properties->GetAlternativeServices(test_server);
bncc958faa2015-07-31 18:14:5210108 ASSERT_EQ(1u, alternative_service_vector.size());
bnc3472afd2016-11-17 15:27:2110109 EXPECT_EQ(kProtoHTTP2, alternative_service_vector[0].protocol);
bncb26024382016-06-29 02:39:4510110 EXPECT_EQ("mail.example.org", alternative_service_vector[0].host);
bncc958faa2015-07-31 18:14:5210111 EXPECT_EQ(443, alternative_service_vector[0].port);
10112}
10113
bnce3dd56f2016-06-01 10:37:1110114// Regression test for https://crbug.com/615497.
bncd16676a2016-07-20 16:23:0110115TEST_F(HttpNetworkTransactionTest,
bnce3dd56f2016-06-01 10:37:1110116 DoNotParseAlternativeServiceHeaderOnInsecureRequest) {
bnce3dd56f2016-06-01 10:37:1110117 MockRead data_reads[] = {
10118 MockRead("HTTP/1.1 200 OK\r\n"),
bnc2df4b522016-07-08 18:17:4310119 MockRead(kAlternativeServiceHttpHeader),
bnce3dd56f2016-06-01 10:37:1110120 MockRead("\r\n"),
10121 MockRead("hello world"),
10122 MockRead(SYNCHRONOUS, OK),
10123 };
10124
10125 HttpRequestInfo request;
10126 request.method = "GET";
10127 request.url = GURL("http://www.example.org/");
10128 request.load_flags = 0;
10129
10130 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
10131 session_deps_.socket_factory->AddSocketDataProvider(&data);
10132
10133 TestCompletionCallback callback;
10134
10135 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1610136 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
bnce3dd56f2016-06-01 10:37:1110137
10138 url::SchemeHostPort test_server(request.url);
bnc525e175a2016-06-20 12:36:4010139 HttpServerProperties* http_server_properties =
10140 session->http_server_properties();
bnce3dd56f2016-06-01 10:37:1110141 AlternativeServiceVector alternative_service_vector =
bnc525e175a2016-06-20 12:36:4010142 http_server_properties->GetAlternativeServices(test_server);
bnce3dd56f2016-06-01 10:37:1110143 EXPECT_TRUE(alternative_service_vector.empty());
10144
tfarina42834112016-09-22 13:38:2010145 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110146 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
10147 EXPECT_THAT(callback.WaitForResult(), IsOk());
bnce3dd56f2016-06-01 10:37:1110148
bnc691fda62016-08-12 00:43:1610149 const HttpResponseInfo* response = trans.GetResponseInfo();
bnce3dd56f2016-06-01 10:37:1110150 ASSERT_TRUE(response);
10151 ASSERT_TRUE(response->headers);
10152 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
10153 EXPECT_FALSE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5210154 EXPECT_FALSE(response->was_alpn_negotiated);
bnce3dd56f2016-06-01 10:37:1110155
10156 std::string response_data;
bnc691fda62016-08-12 00:43:1610157 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
bnce3dd56f2016-06-01 10:37:1110158 EXPECT_EQ("hello world", response_data);
10159
10160 alternative_service_vector =
bnc525e175a2016-06-20 12:36:4010161 http_server_properties->GetAlternativeServices(test_server);
bnce3dd56f2016-06-01 10:37:1110162 EXPECT_TRUE(alternative_service_vector.empty());
10163}
10164
bnca86731e2017-04-17 12:31:2810165// HTTP/2 Alternative Services should be disabled by default.
bnc8bef8da22016-05-30 01:28:2510166// TODO(bnc): Remove when https://crbug.com/615413 is fixed.
bncd16676a2016-07-20 16:23:0110167TEST_F(HttpNetworkTransactionTest,
bnc8bef8da22016-05-30 01:28:2510168 DisableHTTP2AlternativeServicesWithDifferentHost) {
bnca86731e2017-04-17 12:31:2810169 session_deps_.enable_http2_alternative_service = false;
bncb26024382016-06-29 02:39:4510170
bnc8bef8da22016-05-30 01:28:2510171 HttpRequestInfo request;
10172 request.method = "GET";
bncb26024382016-06-29 02:39:4510173 request.url = GURL("https://www.example.org/");
bnc8bef8da22016-05-30 01:28:2510174 request.load_flags = 0;
10175
10176 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
10177 StaticSocketDataProvider first_data;
10178 first_data.set_connect_data(mock_connect);
10179 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
bncb26024382016-06-29 02:39:4510180 SSLSocketDataProvider ssl_http11(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3610181 ssl_http11.next_proto = kProtoHTTP11;
bncb26024382016-06-29 02:39:4510182 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_http11);
bnc8bef8da22016-05-30 01:28:2510183
10184 MockRead data_reads[] = {
10185 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello world"),
10186 MockRead(ASYNC, OK),
10187 };
10188 StaticSocketDataProvider second_data(data_reads, arraysize(data_reads), NULL,
10189 0);
10190 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
10191
10192 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
10193
bnc525e175a2016-06-20 12:36:4010194 HttpServerProperties* http_server_properties =
bnc8bef8da22016-05-30 01:28:2510195 session->http_server_properties();
bnc3472afd2016-11-17 15:27:2110196 AlternativeService alternative_service(kProtoHTTP2, "different.example.org",
10197 444);
bnc8bef8da22016-05-30 01:28:2510198 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
10199 http_server_properties->SetAlternativeService(
10200 url::SchemeHostPort(request.url), alternative_service, expiration);
10201
bnc691fda62016-08-12 00:43:1610202 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
bnc8bef8da22016-05-30 01:28:2510203 TestCompletionCallback callback;
10204
tfarina42834112016-09-22 13:38:2010205 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
bnc8bef8da22016-05-30 01:28:2510206 // Alternative service is not used, request fails.
robpercival214763f2016-07-01 23:27:0110207 EXPECT_THAT(callback.GetResult(rv), IsError(ERR_CONNECTION_REFUSED));
bnc8bef8da22016-05-30 01:28:2510208}
10209
bnce3dd56f2016-06-01 10:37:1110210// Regression test for https://crbug.com/615497:
10211// Alternative Services should be disabled for http origin.
bncd16676a2016-07-20 16:23:0110212TEST_F(HttpNetworkTransactionTest,
bnce3dd56f2016-06-01 10:37:1110213 DisableAlternativeServicesForInsecureOrigin) {
bnce3dd56f2016-06-01 10:37:1110214 HttpRequestInfo request;
10215 request.method = "GET";
10216 request.url = GURL("http://www.example.org/");
10217 request.load_flags = 0;
10218
10219 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
10220 StaticSocketDataProvider first_data;
10221 first_data.set_connect_data(mock_connect);
10222 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
10223
10224 MockRead data_reads[] = {
10225 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello world"),
10226 MockRead(ASYNC, OK),
10227 };
10228 StaticSocketDataProvider second_data(data_reads, arraysize(data_reads), NULL,
10229 0);
10230 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
10231
10232 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
10233
bnc525e175a2016-06-20 12:36:4010234 HttpServerProperties* http_server_properties =
bnce3dd56f2016-06-01 10:37:1110235 session->http_server_properties();
bnc3472afd2016-11-17 15:27:2110236 AlternativeService alternative_service(kProtoHTTP2, "", 444);
bnce3dd56f2016-06-01 10:37:1110237 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
10238 http_server_properties->SetAlternativeService(
10239 url::SchemeHostPort(request.url), alternative_service, expiration);
10240
bnc691fda62016-08-12 00:43:1610241 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
bnce3dd56f2016-06-01 10:37:1110242 TestCompletionCallback callback;
10243
tfarina42834112016-09-22 13:38:2010244 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
bnce3dd56f2016-06-01 10:37:1110245 // Alternative service is not used, request fails.
robpercival214763f2016-07-01 23:27:0110246 EXPECT_THAT(callback.GetResult(rv), IsError(ERR_CONNECTION_REFUSED));
bnce3dd56f2016-06-01 10:37:1110247}
10248
bncd16676a2016-07-20 16:23:0110249TEST_F(HttpNetworkTransactionTest, ClearAlternativeServices) {
bnc4f575852015-10-14 18:35:0810250 // Set an alternative service for origin.
danakj1fd259a02016-04-16 03:17:0910251 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc525e175a2016-06-20 12:36:4010252 HttpServerProperties* http_server_properties =
10253 session->http_server_properties();
bncb26024382016-06-29 02:39:4510254 url::SchemeHostPort test_server("https", "www.example.org", 443);
bnc3472afd2016-11-17 15:27:2110255 AlternativeService alternative_service(kProtoQUIC, "", 80);
bnc4f575852015-10-14 18:35:0810256 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
bnc525e175a2016-06-20 12:36:4010257 http_server_properties->SetAlternativeService(
10258 test_server, alternative_service, expiration);
bnc4f575852015-10-14 18:35:0810259 AlternativeServiceVector alternative_service_vector =
bnc525e175a2016-06-20 12:36:4010260 http_server_properties->GetAlternativeServices(test_server);
bnc4f575852015-10-14 18:35:0810261 EXPECT_EQ(1u, alternative_service_vector.size());
10262
10263 // Send a clear header.
10264 MockRead data_reads[] = {
10265 MockRead("HTTP/1.1 200 OK\r\n"),
10266 MockRead("Alt-Svc: clear\r\n"),
10267 MockRead("\r\n"),
10268 MockRead("hello world"),
10269 MockRead(SYNCHRONOUS, OK),
10270 };
10271 StaticSocketDataProvider data(data_reads, arraysize(data_reads), nullptr, 0);
10272 session_deps_.socket_factory->AddSocketDataProvider(&data);
10273
bncb26024382016-06-29 02:39:4510274 SSLSocketDataProvider ssl(ASYNC, OK);
10275 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
10276
bnc4f575852015-10-14 18:35:0810277 HttpRequestInfo request;
10278 request.method = "GET";
bncb26024382016-06-29 02:39:4510279 request.url = GURL("https://www.example.org/");
bnc4f575852015-10-14 18:35:0810280
10281 TestCompletionCallback callback;
10282
bnc691fda62016-08-12 00:43:1610283 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
bnc4f575852015-10-14 18:35:0810284
tfarina42834112016-09-22 13:38:2010285 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110286 EXPECT_THAT(callback.GetResult(rv), IsOk());
bnc4f575852015-10-14 18:35:0810287
bnc691fda62016-08-12 00:43:1610288 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5210289 ASSERT_TRUE(response);
10290 ASSERT_TRUE(response->headers);
bnc4f575852015-10-14 18:35:0810291 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
10292 EXPECT_FALSE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5210293 EXPECT_FALSE(response->was_alpn_negotiated);
bnc4f575852015-10-14 18:35:0810294
10295 std::string response_data;
bnc691fda62016-08-12 00:43:1610296 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
bnc4f575852015-10-14 18:35:0810297 EXPECT_EQ("hello world", response_data);
10298
10299 alternative_service_vector =
bnc525e175a2016-06-20 12:36:4010300 http_server_properties->GetAlternativeServices(test_server);
bnc4f575852015-10-14 18:35:0810301 EXPECT_TRUE(alternative_service_vector.empty());
10302}
10303
bncd16676a2016-07-20 16:23:0110304TEST_F(HttpNetworkTransactionTest, HonorMultipleAlternativeServiceHeaders) {
bncc958faa2015-07-31 18:14:5210305 MockRead data_reads[] = {
10306 MockRead("HTTP/1.1 200 OK\r\n"),
bnc2df4b522016-07-08 18:17:4310307 MockRead("Alt-Svc: h2=\"www.example.com:443\","),
10308 MockRead("h2=\":1234\"\r\n\r\n"),
bncc958faa2015-07-31 18:14:5210309 MockRead("hello world"),
10310 MockRead(SYNCHRONOUS, OK),
10311 };
10312
10313 HttpRequestInfo request;
10314 request.method = "GET";
bncb26024382016-06-29 02:39:4510315 request.url = GURL("https://www.example.org/");
bncc958faa2015-07-31 18:14:5210316
10317 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
bncc958faa2015-07-31 18:14:5210318 session_deps_.socket_factory->AddSocketDataProvider(&data);
10319
bncb26024382016-06-29 02:39:4510320 SSLSocketDataProvider ssl(ASYNC, OK);
10321 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
10322
bncc958faa2015-07-31 18:14:5210323 TestCompletionCallback callback;
10324
danakj1fd259a02016-04-16 03:17:0910325 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1610326 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
bncc958faa2015-07-31 18:14:5210327
tfarina42834112016-09-22 13:38:2010328 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110329 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
bncc958faa2015-07-31 18:14:5210330
bncb26024382016-06-29 02:39:4510331 url::SchemeHostPort test_server("https", "www.example.org", 443);
bnc525e175a2016-06-20 12:36:4010332 HttpServerProperties* http_server_properties =
10333 session->http_server_properties();
bncc958faa2015-07-31 18:14:5210334 AlternativeServiceVector alternative_service_vector =
bnc525e175a2016-06-20 12:36:4010335 http_server_properties->GetAlternativeServices(test_server);
bncc958faa2015-07-31 18:14:5210336 EXPECT_TRUE(alternative_service_vector.empty());
10337
robpercival214763f2016-07-01 23:27:0110338 EXPECT_THAT(callback.WaitForResult(), IsOk());
bncc958faa2015-07-31 18:14:5210339
bnc691fda62016-08-12 00:43:1610340 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5210341 ASSERT_TRUE(response);
10342 ASSERT_TRUE(response->headers);
bncc958faa2015-07-31 18:14:5210343 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
10344 EXPECT_FALSE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5210345 EXPECT_FALSE(response->was_alpn_negotiated);
bncc958faa2015-07-31 18:14:5210346
10347 std::string response_data;
bnc691fda62016-08-12 00:43:1610348 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
bncc958faa2015-07-31 18:14:5210349 EXPECT_EQ("hello world", response_data);
10350
10351 alternative_service_vector =
bnc525e175a2016-06-20 12:36:4010352 http_server_properties->GetAlternativeServices(test_server);
bncc958faa2015-07-31 18:14:5210353 ASSERT_EQ(2u, alternative_service_vector.size());
bnc3472afd2016-11-17 15:27:2110354 EXPECT_EQ(kProtoHTTP2, alternative_service_vector[0].protocol);
bncc958faa2015-07-31 18:14:5210355 EXPECT_EQ("www.example.com", alternative_service_vector[0].host);
10356 EXPECT_EQ(443, alternative_service_vector[0].port);
bnc3472afd2016-11-17 15:27:2110357 EXPECT_EQ(kProtoHTTP2, alternative_service_vector[1].protocol);
bncc958faa2015-07-31 18:14:5210358 EXPECT_EQ("www.example.org", alternative_service_vector[1].host);
10359 EXPECT_EQ(1234, alternative_service_vector[1].port);
10360}
10361
bncd16676a2016-07-20 16:23:0110362TEST_F(HttpNetworkTransactionTest, IdentifyQuicBroken) {
zhongyi3d4a55e72016-04-22 20:36:4610363 url::SchemeHostPort server("https", "origin.example.org", 443);
zhongyi48704c182015-12-07 07:52:0210364 HostPortPair alternative("alternative.example.org", 443);
10365 std::string origin_url = "https://origin.example.org:443";
10366 std::string alternative_url = "https://alternative.example.org:443";
10367
10368 // Negotiate HTTP/1.1 with alternative.example.org.
10369 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3610370 ssl.next_proto = kProtoHTTP11;
zhongyi48704c182015-12-07 07:52:0210371 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
10372
10373 // HTTP/1.1 data for request.
10374 MockWrite http_writes[] = {
10375 MockWrite("GET / HTTP/1.1\r\n"
10376 "Host: alternative.example.org\r\n"
10377 "Connection: keep-alive\r\n\r\n"),
10378 };
10379
10380 MockRead http_reads[] = {
10381 MockRead("HTTP/1.1 200 OK\r\n"
10382 "Content-Type: text/html; charset=iso-8859-1\r\n"
10383 "Content-Length: 40\r\n\r\n"
10384 "first HTTP/1.1 response from alternative"),
10385 };
10386 StaticSocketDataProvider http_data(http_reads, arraysize(http_reads),
10387 http_writes, arraysize(http_writes));
10388 session_deps_.socket_factory->AddSocketDataProvider(&http_data);
10389
10390 StaticSocketDataProvider data_refused;
10391 data_refused.set_connect_data(MockConnect(ASYNC, ERR_CONNECTION_REFUSED));
10392 session_deps_.socket_factory->AddSocketDataProvider(&data_refused);
10393
zhongyi3d4a55e72016-04-22 20:36:4610394 // Set up a QUIC alternative service for server.
danakj1fd259a02016-04-16 03:17:0910395 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc525e175a2016-06-20 12:36:4010396 HttpServerProperties* http_server_properties =
zhongyi48704c182015-12-07 07:52:0210397 session->http_server_properties();
bnc3472afd2016-11-17 15:27:2110398 AlternativeService alternative_service(kProtoQUIC, alternative);
zhongyi48704c182015-12-07 07:52:0210399 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyi3d4a55e72016-04-22 20:36:4610400 http_server_properties->SetAlternativeService(server, alternative_service,
rchdc7b9052016-03-17 20:51:5010401 expiration);
zhongyi48704c182015-12-07 07:52:0210402 // Mark the QUIC alternative service as broken.
10403 http_server_properties->MarkAlternativeServiceBroken(alternative_service);
10404
zhongyi48704c182015-12-07 07:52:0210405 HttpRequestInfo request;
krasinc06a72a2016-12-21 03:42:4610406 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
zhongyi48704c182015-12-07 07:52:0210407 request.method = "GET";
10408 request.url = GURL(origin_url);
zhongyi48704c182015-12-07 07:52:0210409 TestCompletionCallback callback;
10410 NetErrorDetails details;
10411 EXPECT_FALSE(details.quic_broken);
10412
tfarina42834112016-09-22 13:38:2010413 trans.Start(&request, callback.callback(), NetLogWithSource());
bnc691fda62016-08-12 00:43:1610414 trans.PopulateNetErrorDetails(&details);
zhongyi48704c182015-12-07 07:52:0210415 EXPECT_TRUE(details.quic_broken);
10416}
10417
bncd16676a2016-07-20 16:23:0110418TEST_F(HttpNetworkTransactionTest, IdentifyQuicNotBroken) {
zhongyi3d4a55e72016-04-22 20:36:4610419 url::SchemeHostPort server("https", "origin.example.org", 443);
zhongyi48704c182015-12-07 07:52:0210420 HostPortPair alternative1("alternative1.example.org", 443);
10421 HostPortPair alternative2("alternative2.example.org", 443);
10422 std::string origin_url = "https://origin.example.org:443";
10423 std::string alternative_url1 = "https://alternative1.example.org:443";
10424 std::string alternative_url2 = "https://alternative2.example.org:443";
10425
10426 // Negotiate HTTP/1.1 with alternative1.example.org.
10427 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3610428 ssl.next_proto = kProtoHTTP11;
zhongyi48704c182015-12-07 07:52:0210429 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
10430
10431 // HTTP/1.1 data for request.
10432 MockWrite http_writes[] = {
10433 MockWrite("GET / HTTP/1.1\r\n"
10434 "Host: alternative1.example.org\r\n"
10435 "Connection: keep-alive\r\n\r\n"),
10436 };
10437
10438 MockRead http_reads[] = {
10439 MockRead("HTTP/1.1 200 OK\r\n"
10440 "Content-Type: text/html; charset=iso-8859-1\r\n"
10441 "Content-Length: 40\r\n\r\n"
10442 "first HTTP/1.1 response from alternative1"),
10443 };
10444 StaticSocketDataProvider http_data(http_reads, arraysize(http_reads),
10445 http_writes, arraysize(http_writes));
10446 session_deps_.socket_factory->AddSocketDataProvider(&http_data);
10447
10448 StaticSocketDataProvider data_refused;
10449 data_refused.set_connect_data(MockConnect(ASYNC, ERR_CONNECTION_REFUSED));
10450 session_deps_.socket_factory->AddSocketDataProvider(&data_refused);
10451
danakj1fd259a02016-04-16 03:17:0910452 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc525e175a2016-06-20 12:36:4010453 HttpServerProperties* http_server_properties =
zhongyi48704c182015-12-07 07:52:0210454 session->http_server_properties();
10455
zhongyi3d4a55e72016-04-22 20:36:4610456 // Set up two QUIC alternative services for server.
zhongyi48704c182015-12-07 07:52:0210457 AlternativeServiceInfoVector alternative_service_info_vector;
10458 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
10459
bnc3472afd2016-11-17 15:27:2110460 AlternativeService alternative_service1(kProtoQUIC, alternative1);
rchdc7b9052016-03-17 20:51:5010461 AlternativeServiceInfo alternative_service_info1(alternative_service1,
zhongyi48704c182015-12-07 07:52:0210462 expiration);
10463 alternative_service_info_vector.push_back(alternative_service_info1);
bnc3472afd2016-11-17 15:27:2110464 AlternativeService alternative_service2(kProtoQUIC, alternative2);
rchdc7b9052016-03-17 20:51:5010465 AlternativeServiceInfo alternative_service_info2(alternative_service2,
zhongyi48704c182015-12-07 07:52:0210466 expiration);
10467 alternative_service_info_vector.push_back(alternative_service_info2);
10468
10469 http_server_properties->SetAlternativeServices(
zhongyi3d4a55e72016-04-22 20:36:4610470 server, alternative_service_info_vector);
zhongyi48704c182015-12-07 07:52:0210471
10472 // Mark one of the QUIC alternative service as broken.
10473 http_server_properties->MarkAlternativeServiceBroken(alternative_service1);
10474
10475 const AlternativeServiceVector alternative_service_vector =
zhongyi3d4a55e72016-04-22 20:36:4610476 http_server_properties->GetAlternativeServices(server);
zhongyi48704c182015-12-07 07:52:0210477
zhongyi48704c182015-12-07 07:52:0210478 HttpRequestInfo request;
krasinc06a72a2016-12-21 03:42:4610479 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
zhongyi48704c182015-12-07 07:52:0210480 request.method = "GET";
10481 request.url = GURL(origin_url);
zhongyi48704c182015-12-07 07:52:0210482 TestCompletionCallback callback;
10483 NetErrorDetails details;
10484 EXPECT_FALSE(details.quic_broken);
10485
tfarina42834112016-09-22 13:38:2010486 trans.Start(&request, callback.callback(), NetLogWithSource());
bnc691fda62016-08-12 00:43:1610487 trans.PopulateNetErrorDetails(&details);
zhongyi48704c182015-12-07 07:52:0210488 EXPECT_FALSE(details.quic_broken);
10489}
10490
bncd16676a2016-07-20 16:23:0110491TEST_F(HttpNetworkTransactionTest, MarkBrokenAlternateProtocolAndFallback) {
[email protected]564b4912010-03-09 16:30:4210492 HttpRequestInfo request;
10493 request.method = "GET";
bncb26024382016-06-29 02:39:4510494 request.url = GURL("https://www.example.org/");
[email protected]564b4912010-03-09 16:30:4210495
[email protected]d973e99a2012-02-17 21:02:3610496 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
[email protected]564b4912010-03-09 16:30:4210497 StaticSocketDataProvider first_data;
10498 first_data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:0710499 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
bncb26024382016-06-29 02:39:4510500 SSLSocketDataProvider ssl_http11(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3610501 ssl_http11.next_proto = kProtoHTTP11;
bncb26024382016-06-29 02:39:4510502 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_http11);
[email protected]564b4912010-03-09 16:30:4210503
10504 MockRead data_reads[] = {
10505 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
10506 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:0610507 MockRead(ASYNC, OK),
[email protected]564b4912010-03-09 16:30:4210508 };
10509 StaticSocketDataProvider second_data(
10510 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0710511 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
[email protected]564b4912010-03-09 16:30:4210512
danakj1fd259a02016-04-16 03:17:0910513 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]564b4912010-03-09 16:30:4210514
bnc525e175a2016-06-20 12:36:4010515 HttpServerProperties* http_server_properties =
[email protected]17291a022011-10-10 07:32:5310516 session->http_server_properties();
zhongyi3d4a55e72016-04-22 20:36:4610517 const url::SchemeHostPort server(request.url);
[email protected]3912662a32011-10-04 00:51:1110518 // Port must be < 1024, or the header will be ignored (since initial port was
10519 // port 80 (another restricted port).
bncd9b132e2015-07-08 05:16:1010520 const AlternativeService alternative_service(
bnc3472afd2016-11-17 15:27:2110521 kProtoHTTP2, "www.example.org",
bncd9b132e2015-07-08 05:16:1010522 666); // Port is ignored by MockConnect anyway.
bnc7dc7e1b42015-07-28 14:43:1210523 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyi3d4a55e72016-04-22 20:36:4610524 http_server_properties->SetAlternativeService(server, alternative_service,
10525 expiration);
[email protected]564b4912010-03-09 16:30:4210526
bnc691fda62016-08-12 00:43:1610527 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]49639fa2011-12-20 23:22:4110528 TestCompletionCallback callback;
[email protected]564b4912010-03-09 16:30:4210529
tfarina42834112016-09-22 13:38:2010530 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110531 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
10532 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]564b4912010-03-09 16:30:4210533
bnc691fda62016-08-12 00:43:1610534 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5210535 ASSERT_TRUE(response);
10536 ASSERT_TRUE(response->headers);
[email protected]564b4912010-03-09 16:30:4210537 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
10538
10539 std::string response_data;
bnc691fda62016-08-12 00:43:1610540 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
[email protected]564b4912010-03-09 16:30:4210541 EXPECT_EQ("hello world", response_data);
10542
bncd9b132e2015-07-08 05:16:1010543 const AlternativeServiceVector alternative_service_vector =
zhongyi3d4a55e72016-04-22 20:36:4610544 http_server_properties->GetAlternativeServices(server);
bncd9b132e2015-07-08 05:16:1010545 ASSERT_EQ(1u, alternative_service_vector.size());
10546 EXPECT_EQ(alternative_service, alternative_service_vector[0]);
10547 EXPECT_TRUE(http_server_properties->IsAlternativeServiceBroken(
10548 alternative_service_vector[0]));
[email protected]564b4912010-03-09 16:30:4210549}
10550
bnc55ff9da2015-08-19 18:42:3510551// Ensure that we are not allowed to redirect traffic via an alternate protocol
10552// to an unrestricted (port >= 1024) when the original traffic was on a
10553// restricted port (port < 1024). Ensure that we can redirect in all other
10554// cases.
bncd16676a2016-07-20 16:23:0110555TEST_F(HttpNetworkTransactionTest, AlternateProtocolPortRestrictedBlocked) {
[email protected]3912662a32011-10-04 00:51:1110556 HttpRequestInfo restricted_port_request;
10557 restricted_port_request.method = "GET";
bncb26024382016-06-29 02:39:4510558 restricted_port_request.url = GURL("https://www.example.org:1023/");
[email protected]3912662a32011-10-04 00:51:1110559 restricted_port_request.load_flags = 0;
10560
[email protected]d973e99a2012-02-17 21:02:3610561 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
[email protected]3912662a32011-10-04 00:51:1110562 StaticSocketDataProvider first_data;
10563 first_data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:0710564 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
[email protected]3912662a32011-10-04 00:51:1110565
10566 MockRead data_reads[] = {
10567 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
10568 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:0610569 MockRead(ASYNC, OK),
[email protected]3912662a32011-10-04 00:51:1110570 };
10571 StaticSocketDataProvider second_data(
10572 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0710573 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
bncb26024382016-06-29 02:39:4510574 SSLSocketDataProvider ssl_http11(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3610575 ssl_http11.next_proto = kProtoHTTP11;
bncb26024382016-06-29 02:39:4510576 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_http11);
[email protected]3912662a32011-10-04 00:51:1110577
danakj1fd259a02016-04-16 03:17:0910578 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]3912662a32011-10-04 00:51:1110579
bnc525e175a2016-06-20 12:36:4010580 HttpServerProperties* http_server_properties =
[email protected]17291a022011-10-10 07:32:5310581 session->http_server_properties();
[email protected]3912662a32011-10-04 00:51:1110582 const int kUnrestrictedAlternatePort = 1024;
bnc3472afd2016-11-17 15:27:2110583 AlternativeService alternative_service(kProtoHTTP2, "www.example.org",
10584 kUnrestrictedAlternatePort);
bnc7dc7e1b42015-07-28 14:43:1210585 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
bnccacc0992015-03-20 20:22:2210586 http_server_properties->SetAlternativeService(
zhongyi3d4a55e72016-04-22 20:36:4610587 url::SchemeHostPort(restricted_port_request.url), alternative_service,
rchdc7b9052016-03-17 20:51:5010588 expiration);
[email protected]3912662a32011-10-04 00:51:1110589
bnc691fda62016-08-12 00:43:1610590 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]49639fa2011-12-20 23:22:4110591 TestCompletionCallback callback;
[email protected]3912662a32011-10-04 00:51:1110592
tfarina42834112016-09-22 13:38:2010593 int rv = trans.Start(&restricted_port_request, callback.callback(),
10594 NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110595 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]3912662a32011-10-04 00:51:1110596 // Invalid change to unrestricted port should fail.
robpercival214763f2016-07-01 23:27:0110597 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_CONNECTION_REFUSED));
[email protected]c54c6962013-02-01 04:53:1910598}
[email protected]3912662a32011-10-04 00:51:1110599
bnc55ff9da2015-08-19 18:42:3510600// Ensure that we are allowed to redirect traffic via an alternate protocol to
10601// an unrestricted (port >= 1024) when the original traffic was on a restricted
10602// port (port < 1024) if we set |enable_user_alternate_protocol_ports|.
bncd16676a2016-07-20 16:23:0110603TEST_F(HttpNetworkTransactionTest, AlternateProtocolPortRestrictedPermitted) {
[email protected]bb88e1d32013-05-03 23:11:0710604 session_deps_.enable_user_alternate_protocol_ports = true;
[email protected]c54c6962013-02-01 04:53:1910605
10606 HttpRequestInfo restricted_port_request;
10607 restricted_port_request.method = "GET";
bncb26024382016-06-29 02:39:4510608 restricted_port_request.url = GURL("https://www.example.org:1023/");
[email protected]c54c6962013-02-01 04:53:1910609 restricted_port_request.load_flags = 0;
10610
10611 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
10612 StaticSocketDataProvider first_data;
10613 first_data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:0710614 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
[email protected]c54c6962013-02-01 04:53:1910615
10616 MockRead data_reads[] = {
10617 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
10618 MockRead("hello world"),
10619 MockRead(ASYNC, OK),
10620 };
10621 StaticSocketDataProvider second_data(
10622 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0710623 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
bncb26024382016-06-29 02:39:4510624 SSLSocketDataProvider ssl_http11(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3610625 ssl_http11.next_proto = kProtoHTTP11;
bncb26024382016-06-29 02:39:4510626 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_http11);
[email protected]c54c6962013-02-01 04:53:1910627
danakj1fd259a02016-04-16 03:17:0910628 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]c54c6962013-02-01 04:53:1910629
bnc525e175a2016-06-20 12:36:4010630 HttpServerProperties* http_server_properties =
[email protected]c54c6962013-02-01 04:53:1910631 session->http_server_properties();
10632 const int kUnrestrictedAlternatePort = 1024;
bnc3472afd2016-11-17 15:27:2110633 AlternativeService alternative_service(kProtoHTTP2, "www.example.org",
10634 kUnrestrictedAlternatePort);
bnc7dc7e1b42015-07-28 14:43:1210635 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
bnccacc0992015-03-20 20:22:2210636 http_server_properties->SetAlternativeService(
zhongyi3d4a55e72016-04-22 20:36:4610637 url::SchemeHostPort(restricted_port_request.url), alternative_service,
rchdc7b9052016-03-17 20:51:5010638 expiration);
[email protected]c54c6962013-02-01 04:53:1910639
bnc691fda62016-08-12 00:43:1610640 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]c54c6962013-02-01 04:53:1910641 TestCompletionCallback callback;
10642
tfarina42834112016-09-22 13:38:2010643 EXPECT_EQ(ERR_IO_PENDING,
10644 trans.Start(&restricted_port_request, callback.callback(),
10645 NetLogWithSource()));
[email protected]c54c6962013-02-01 04:53:1910646 // Change to unrestricted port should succeed.
robpercival214763f2016-07-01 23:27:0110647 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]3912662a32011-10-04 00:51:1110648}
10649
bnc55ff9da2015-08-19 18:42:3510650// Ensure that we are not allowed to redirect traffic via an alternate protocol
10651// to an unrestricted (port >= 1024) when the original traffic was on a
10652// restricted port (port < 1024). Ensure that we can redirect in all other
10653// cases.
bncd16676a2016-07-20 16:23:0110654TEST_F(HttpNetworkTransactionTest, AlternateProtocolPortRestrictedAllowed) {
[email protected]3912662a32011-10-04 00:51:1110655 HttpRequestInfo restricted_port_request;
10656 restricted_port_request.method = "GET";
bncb26024382016-06-29 02:39:4510657 restricted_port_request.url = GURL("https://www.example.org:1023/");
[email protected]3912662a32011-10-04 00:51:1110658 restricted_port_request.load_flags = 0;
10659
[email protected]d973e99a2012-02-17 21:02:3610660 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
[email protected]3912662a32011-10-04 00:51:1110661 StaticSocketDataProvider first_data;
10662 first_data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:0710663 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
[email protected]3912662a32011-10-04 00:51:1110664
10665 MockRead data_reads[] = {
10666 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
10667 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:0610668 MockRead(ASYNC, OK),
[email protected]3912662a32011-10-04 00:51:1110669 };
10670 StaticSocketDataProvider second_data(
10671 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0710672 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
[email protected]3912662a32011-10-04 00:51:1110673
bncb26024382016-06-29 02:39:4510674 SSLSocketDataProvider ssl(ASYNC, OK);
10675 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
10676
danakj1fd259a02016-04-16 03:17:0910677 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]3912662a32011-10-04 00:51:1110678
bnc525e175a2016-06-20 12:36:4010679 HttpServerProperties* http_server_properties =
[email protected]17291a022011-10-10 07:32:5310680 session->http_server_properties();
[email protected]3912662a32011-10-04 00:51:1110681 const int kRestrictedAlternatePort = 80;
bnc3472afd2016-11-17 15:27:2110682 AlternativeService alternative_service(kProtoHTTP2, "www.example.org",
10683 kRestrictedAlternatePort);
bnc7dc7e1b42015-07-28 14:43:1210684 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
bnccacc0992015-03-20 20:22:2210685 http_server_properties->SetAlternativeService(
zhongyi3d4a55e72016-04-22 20:36:4610686 url::SchemeHostPort(restricted_port_request.url), alternative_service,
rchdc7b9052016-03-17 20:51:5010687 expiration);
[email protected]3912662a32011-10-04 00:51:1110688
bnc691fda62016-08-12 00:43:1610689 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]49639fa2011-12-20 23:22:4110690 TestCompletionCallback callback;
[email protected]3912662a32011-10-04 00:51:1110691
tfarina42834112016-09-22 13:38:2010692 int rv = trans.Start(&restricted_port_request, callback.callback(),
10693 NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110694 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]3912662a32011-10-04 00:51:1110695 // Valid change to restricted port should pass.
robpercival214763f2016-07-01 23:27:0110696 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]3912662a32011-10-04 00:51:1110697}
10698
bnc55ff9da2015-08-19 18:42:3510699// Ensure that we are not allowed to redirect traffic via an alternate protocol
10700// to an unrestricted (port >= 1024) when the original traffic was on a
10701// restricted port (port < 1024). Ensure that we can redirect in all other
10702// cases.
bncd16676a2016-07-20 16:23:0110703TEST_F(HttpNetworkTransactionTest, AlternateProtocolPortUnrestrictedAllowed1) {
[email protected]3912662a32011-10-04 00:51:1110704 HttpRequestInfo unrestricted_port_request;
10705 unrestricted_port_request.method = "GET";
bncb26024382016-06-29 02:39:4510706 unrestricted_port_request.url = GURL("https://www.example.org:1024/");
[email protected]3912662a32011-10-04 00:51:1110707 unrestricted_port_request.load_flags = 0;
10708
[email protected]d973e99a2012-02-17 21:02:3610709 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
[email protected]3912662a32011-10-04 00:51:1110710 StaticSocketDataProvider first_data;
10711 first_data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:0710712 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
[email protected]3912662a32011-10-04 00:51:1110713
10714 MockRead data_reads[] = {
10715 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
10716 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:0610717 MockRead(ASYNC, OK),
[email protected]3912662a32011-10-04 00:51:1110718 };
10719 StaticSocketDataProvider second_data(
10720 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0710721 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
bncb26024382016-06-29 02:39:4510722 SSLSocketDataProvider ssl_http11(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3610723 ssl_http11.next_proto = kProtoHTTP11;
bncb26024382016-06-29 02:39:4510724 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_http11);
[email protected]3912662a32011-10-04 00:51:1110725
danakj1fd259a02016-04-16 03:17:0910726 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]3912662a32011-10-04 00:51:1110727
bnc525e175a2016-06-20 12:36:4010728 HttpServerProperties* http_server_properties =
[email protected]17291a022011-10-10 07:32:5310729 session->http_server_properties();
[email protected]3912662a32011-10-04 00:51:1110730 const int kRestrictedAlternatePort = 80;
bnc3472afd2016-11-17 15:27:2110731 AlternativeService alternative_service(kProtoHTTP2, "www.example.org",
10732 kRestrictedAlternatePort);
bnc7dc7e1b42015-07-28 14:43:1210733 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
bnccacc0992015-03-20 20:22:2210734 http_server_properties->SetAlternativeService(
zhongyi3d4a55e72016-04-22 20:36:4610735 url::SchemeHostPort(unrestricted_port_request.url), alternative_service,
rchdc7b9052016-03-17 20:51:5010736 expiration);
[email protected]3912662a32011-10-04 00:51:1110737
bnc691fda62016-08-12 00:43:1610738 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]49639fa2011-12-20 23:22:4110739 TestCompletionCallback callback;
[email protected]3912662a32011-10-04 00:51:1110740
bnc691fda62016-08-12 00:43:1610741 int rv = trans.Start(&unrestricted_port_request, callback.callback(),
tfarina42834112016-09-22 13:38:2010742 NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110743 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]3912662a32011-10-04 00:51:1110744 // Valid change to restricted port should pass.
robpercival214763f2016-07-01 23:27:0110745 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]3912662a32011-10-04 00:51:1110746}
10747
bnc55ff9da2015-08-19 18:42:3510748// Ensure that we are not allowed to redirect traffic via an alternate protocol
10749// to an unrestricted (port >= 1024) when the original traffic was on a
10750// restricted port (port < 1024). Ensure that we can redirect in all other
10751// cases.
bncd16676a2016-07-20 16:23:0110752TEST_F(HttpNetworkTransactionTest, AlternateProtocolPortUnrestrictedAllowed2) {
[email protected]3912662a32011-10-04 00:51:1110753 HttpRequestInfo unrestricted_port_request;
10754 unrestricted_port_request.method = "GET";
bncb26024382016-06-29 02:39:4510755 unrestricted_port_request.url = GURL("https://www.example.org:1024/");
[email protected]3912662a32011-10-04 00:51:1110756 unrestricted_port_request.load_flags = 0;
10757
[email protected]d973e99a2012-02-17 21:02:3610758 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
[email protected]3912662a32011-10-04 00:51:1110759 StaticSocketDataProvider first_data;
10760 first_data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:0710761 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
[email protected]3912662a32011-10-04 00:51:1110762
10763 MockRead data_reads[] = {
10764 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
10765 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:0610766 MockRead(ASYNC, OK),
[email protected]3912662a32011-10-04 00:51:1110767 };
10768 StaticSocketDataProvider second_data(
10769 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0710770 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
[email protected]3912662a32011-10-04 00:51:1110771
bncb26024382016-06-29 02:39:4510772 SSLSocketDataProvider ssl(ASYNC, OK);
10773 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
10774
danakj1fd259a02016-04-16 03:17:0910775 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]3912662a32011-10-04 00:51:1110776
bnc525e175a2016-06-20 12:36:4010777 HttpServerProperties* http_server_properties =
[email protected]17291a022011-10-10 07:32:5310778 session->http_server_properties();
bnc0bbb02622015-07-23 10:06:2210779 const int kUnrestrictedAlternatePort = 1025;
bnc3472afd2016-11-17 15:27:2110780 AlternativeService alternative_service(kProtoHTTP2, "www.example.org",
10781 kUnrestrictedAlternatePort);
bnc7dc7e1b42015-07-28 14:43:1210782 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
bnccacc0992015-03-20 20:22:2210783 http_server_properties->SetAlternativeService(
zhongyi3d4a55e72016-04-22 20:36:4610784 url::SchemeHostPort(unrestricted_port_request.url), alternative_service,
rchdc7b9052016-03-17 20:51:5010785 expiration);
[email protected]3912662a32011-10-04 00:51:1110786
bnc691fda62016-08-12 00:43:1610787 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]49639fa2011-12-20 23:22:4110788 TestCompletionCallback callback;
[email protected]3912662a32011-10-04 00:51:1110789
bnc691fda62016-08-12 00:43:1610790 int rv = trans.Start(&unrestricted_port_request, callback.callback(),
tfarina42834112016-09-22 13:38:2010791 NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110792 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]3912662a32011-10-04 00:51:1110793 // Valid change to an unrestricted port should pass.
robpercival214763f2016-07-01 23:27:0110794 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]3912662a32011-10-04 00:51:1110795}
10796
bnc55ff9da2015-08-19 18:42:3510797// Ensure that we are not allowed to redirect traffic via an alternate protocol
10798// to an unsafe port, and that we resume the second HttpStreamFactoryImpl::Job
10799// once the alternate protocol request fails.
bncd16676a2016-07-20 16:23:0110800TEST_F(HttpNetworkTransactionTest, AlternateProtocolUnsafeBlocked) {
[email protected]eb6234e2012-01-19 01:50:0210801 HttpRequestInfo request;
10802 request.method = "GET";
bncce36dca22015-04-21 22:11:2310803 request.url = GURL("http://www.example.org/");
[email protected]eb6234e2012-01-19 01:50:0210804
10805 // The alternate protocol request will error out before we attempt to connect,
10806 // so only the standard HTTP request will try to connect.
10807 MockRead data_reads[] = {
10808 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
10809 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:0610810 MockRead(ASYNC, OK),
[email protected]eb6234e2012-01-19 01:50:0210811 };
10812 StaticSocketDataProvider data(
10813 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0710814 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]eb6234e2012-01-19 01:50:0210815
danakj1fd259a02016-04-16 03:17:0910816 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]eb6234e2012-01-19 01:50:0210817
bnc525e175a2016-06-20 12:36:4010818 HttpServerProperties* http_server_properties =
[email protected]eb6234e2012-01-19 01:50:0210819 session->http_server_properties();
10820 const int kUnsafePort = 7;
bnc3472afd2016-11-17 15:27:2110821 AlternativeService alternative_service(kProtoHTTP2, "www.example.org",
10822 kUnsafePort);
bnc7dc7e1b42015-07-28 14:43:1210823 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
bnccacc0992015-03-20 20:22:2210824 http_server_properties->SetAlternativeService(
zhongyi3d4a55e72016-04-22 20:36:4610825 url::SchemeHostPort(request.url), alternative_service, expiration);
[email protected]eb6234e2012-01-19 01:50:0210826
bnc691fda62016-08-12 00:43:1610827 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]eb6234e2012-01-19 01:50:0210828 TestCompletionCallback callback;
10829
tfarina42834112016-09-22 13:38:2010830 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110831 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]eb6234e2012-01-19 01:50:0210832 // The HTTP request should succeed.
robpercival214763f2016-07-01 23:27:0110833 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]eb6234e2012-01-19 01:50:0210834
bnc691fda62016-08-12 00:43:1610835 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5210836 ASSERT_TRUE(response);
10837 ASSERT_TRUE(response->headers);
[email protected]eb6234e2012-01-19 01:50:0210838 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
10839
10840 std::string response_data;
bnc691fda62016-08-12 00:43:1610841 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
[email protected]eb6234e2012-01-19 01:50:0210842 EXPECT_EQ("hello world", response_data);
10843}
10844
bncd16676a2016-07-20 16:23:0110845TEST_F(HttpNetworkTransactionTest, UseAlternateProtocolForNpnSpdy) {
[email protected]2ff8b312010-04-26 22:20:5410846 HttpRequestInfo request;
10847 request.method = "GET";
bncb26024382016-06-29 02:39:4510848 request.url = GURL("https://www.example.org/");
[email protected]2ff8b312010-04-26 22:20:5410849
10850 MockRead data_reads[] = {
bncc958faa2015-07-31 18:14:5210851 MockRead("HTTP/1.1 200 OK\r\n"),
bnc2df4b522016-07-08 18:17:4310852 MockRead(kAlternativeServiceHttpHeader),
bncc958faa2015-07-31 18:14:5210853 MockRead("\r\n"),
10854 MockRead("hello world"),
10855 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
10856 MockRead(ASYNC, OK)};
[email protected]2ff8b312010-04-26 22:20:5410857
10858 StaticSocketDataProvider first_transaction(
10859 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0710860 session_deps_.socket_factory->AddSocketDataProvider(&first_transaction);
bncb26024382016-06-29 02:39:4510861 SSLSocketDataProvider ssl_http11(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3610862 ssl_http11.next_proto = kProtoHTTP11;
bncb26024382016-06-29 02:39:4510863 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_http11);
[email protected]2ff8b312010-04-26 22:20:5410864
bnc032658ba2016-09-26 18:17:1510865 AddSSLSocketData();
[email protected]2ff8b312010-04-26 22:20:5410866
bncdf80d44fd2016-07-15 20:27:4110867 SpdySerializedFrame req(
bncb26024382016-06-29 02:39:4510868 spdy_util_.ConstructSpdyGet("https://www.example.org/", 1, LOWEST));
bncdf80d44fd2016-07-15 20:27:4110869 MockWrite spdy_writes[] = {CreateMockWrite(req, 0)};
[email protected]2ff8b312010-04-26 22:20:5410870
bnc42331402016-07-25 13:36:1510871 SpdySerializedFrame resp(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
bncdf80d44fd2016-07-15 20:27:4110872 SpdySerializedFrame data(spdy_util_.ConstructSpdyDataFrame(1, true));
[email protected]2ff8b312010-04-26 22:20:5410873 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:4110874 CreateMockRead(resp, 1), CreateMockRead(data, 2), MockRead(ASYNC, 0, 3),
[email protected]2ff8b312010-04-26 22:20:5410875 };
10876
rch8e6c6c42015-05-01 14:05:1310877 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
10878 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:0710879 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]2ff8b312010-04-26 22:20:5410880
[email protected]d973e99a2012-02-17 21:02:3610881 MockConnect never_finishing_connect(SYNCHRONOUS, ERR_IO_PENDING);
[email protected]2d6728692011-03-12 01:39:5510882 StaticSocketDataProvider hanging_non_alternate_protocol_socket(
10883 NULL, 0, NULL, 0);
10884 hanging_non_alternate_protocol_socket.set_connect_data(
10885 never_finishing_connect);
[email protected]bb88e1d32013-05-03 23:11:0710886 session_deps_.socket_factory->AddSocketDataProvider(
[email protected]2d6728692011-03-12 01:39:5510887 &hanging_non_alternate_protocol_socket);
10888
[email protected]49639fa2011-12-20 23:22:4110889 TestCompletionCallback callback;
[email protected]2ff8b312010-04-26 22:20:5410890
danakj1fd259a02016-04-16 03:17:0910891 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1610892 std::unique_ptr<HttpNetworkTransaction> trans(
[email protected]90499482013-06-01 00:39:5010893 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]2ff8b312010-04-26 22:20:5410894
tfarina42834112016-09-22 13:38:2010895 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110896 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
10897 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]2ff8b312010-04-26 22:20:5410898
10899 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5210900 ASSERT_TRUE(response);
10901 ASSERT_TRUE(response->headers);
[email protected]2ff8b312010-04-26 22:20:5410902 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
10903
10904 std::string response_data;
robpercival214763f2016-07-01 23:27:0110905 ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
[email protected]2ff8b312010-04-26 22:20:5410906 EXPECT_EQ("hello world", response_data);
10907
[email protected]90499482013-06-01 00:39:5010908 trans.reset(new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]2ff8b312010-04-26 22:20:5410909
tfarina42834112016-09-22 13:38:2010910 rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110911 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
10912 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]2ff8b312010-04-26 22:20:5410913
10914 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5210915 ASSERT_TRUE(response);
10916 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0210917 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]65041fa2010-05-21 06:56:5310918 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5210919 EXPECT_TRUE(response->was_alpn_negotiated);
[email protected]2ff8b312010-04-26 22:20:5410920
robpercival214763f2016-07-01 23:27:0110921 ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
[email protected]2ff8b312010-04-26 22:20:5410922 EXPECT_EQ("hello!", response_data);
[email protected]2ff8b312010-04-26 22:20:5410923}
10924
bncd16676a2016-07-20 16:23:0110925TEST_F(HttpNetworkTransactionTest, AlternateProtocolWithSpdyLateBinding) {
[email protected]2d6728692011-03-12 01:39:5510926 HttpRequestInfo request;
10927 request.method = "GET";
bncb26024382016-06-29 02:39:4510928 request.url = GURL("https://www.example.org/");
[email protected]2d6728692011-03-12 01:39:5510929
bncb26024382016-06-29 02:39:4510930 // First transaction receives Alt-Svc header over HTTP/1.1.
[email protected]2d6728692011-03-12 01:39:5510931 MockRead data_reads[] = {
bncc958faa2015-07-31 18:14:5210932 MockRead("HTTP/1.1 200 OK\r\n"),
bnc2df4b522016-07-08 18:17:4310933 MockRead(kAlternativeServiceHttpHeader),
bncc958faa2015-07-31 18:14:5210934 MockRead("\r\n"),
10935 MockRead("hello world"),
10936 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
10937 MockRead(ASYNC, OK),
[email protected]2d6728692011-03-12 01:39:5510938 };
10939
bncb26024382016-06-29 02:39:4510940 StaticSocketDataProvider http11_data(data_reads, arraysize(data_reads), NULL,
10941 0);
10942 session_deps_.socket_factory->AddSocketDataProvider(&http11_data);
[email protected]2d6728692011-03-12 01:39:5510943
bncb26024382016-06-29 02:39:4510944 SSLSocketDataProvider ssl_http11(ASYNC, OK);
10945 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_http11);
10946
10947 // Second transaction starts an alternative and a non-alternative Job.
10948 // Both sockets hang.
[email protected]d973e99a2012-02-17 21:02:3610949 MockConnect never_finishing_connect(SYNCHRONOUS, ERR_IO_PENDING);
mmenkecc2298e2015-12-07 18:20:1810950 StaticSocketDataProvider hanging_socket1(NULL, 0, NULL, 0);
10951 hanging_socket1.set_connect_data(never_finishing_connect);
mmenkecc2298e2015-12-07 18:20:1810952 session_deps_.socket_factory->AddSocketDataProvider(&hanging_socket1);
10953
10954 StaticSocketDataProvider hanging_socket2(NULL, 0, NULL, 0);
10955 hanging_socket2.set_connect_data(never_finishing_connect);
10956 session_deps_.socket_factory->AddSocketDataProvider(&hanging_socket2);
[email protected]2d6728692011-03-12 01:39:5510957
bncb26024382016-06-29 02:39:4510958 // Third transaction starts an alternative and a non-alternative job.
10959 // The non-alternative job hangs, but the alternative one succeeds.
10960 // The second transaction, still pending, binds to this socket.
bncdf80d44fd2016-07-15 20:27:4110961 SpdySerializedFrame req1(
bncb26024382016-06-29 02:39:4510962 spdy_util_.ConstructSpdyGet("https://www.example.org/", 1, LOWEST));
bncdf80d44fd2016-07-15 20:27:4110963 SpdySerializedFrame req2(
bncb26024382016-06-29 02:39:4510964 spdy_util_.ConstructSpdyGet("https://www.example.org/", 3, LOWEST));
[email protected]2d6728692011-03-12 01:39:5510965 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:4110966 CreateMockWrite(req1, 0), CreateMockWrite(req2, 1),
[email protected]2d6728692011-03-12 01:39:5510967 };
bnc42331402016-07-25 13:36:1510968 SpdySerializedFrame resp1(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
bncdf80d44fd2016-07-15 20:27:4110969 SpdySerializedFrame data1(spdy_util_.ConstructSpdyDataFrame(1, true));
bnc42331402016-07-25 13:36:1510970 SpdySerializedFrame resp2(spdy_util_.ConstructSpdyGetReply(NULL, 0, 3));
bncdf80d44fd2016-07-15 20:27:4110971 SpdySerializedFrame data2(spdy_util_.ConstructSpdyDataFrame(3, true));
[email protected]2d6728692011-03-12 01:39:5510972 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:4110973 CreateMockRead(resp1, 2), CreateMockRead(data1, 3),
10974 CreateMockRead(resp2, 4), CreateMockRead(data2, 5),
rch8e6c6c42015-05-01 14:05:1310975 MockRead(ASYNC, 0, 6),
[email protected]2d6728692011-03-12 01:39:5510976 };
10977
rch8e6c6c42015-05-01 14:05:1310978 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
10979 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:0710980 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]2d6728692011-03-12 01:39:5510981
bnc032658ba2016-09-26 18:17:1510982 AddSSLSocketData();
bncb26024382016-06-29 02:39:4510983
mmenkecc2298e2015-12-07 18:20:1810984 StaticSocketDataProvider hanging_socket3(NULL, 0, NULL, 0);
10985 hanging_socket3.set_connect_data(never_finishing_connect);
10986 session_deps_.socket_factory->AddSocketDataProvider(&hanging_socket3);
[email protected]2d6728692011-03-12 01:39:5510987
danakj1fd259a02016-04-16 03:17:0910988 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]49639fa2011-12-20 23:22:4110989 TestCompletionCallback callback1;
[email protected]90499482013-06-01 00:39:5010990 HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
[email protected]2d6728692011-03-12 01:39:5510991
tfarina42834112016-09-22 13:38:2010992 int rv = trans1.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110993 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
10994 EXPECT_THAT(callback1.WaitForResult(), IsOk());
[email protected]2d6728692011-03-12 01:39:5510995
10996 const HttpResponseInfo* response = trans1.GetResponseInfo();
wezca1070932016-05-26 20:30:5210997 ASSERT_TRUE(response);
10998 ASSERT_TRUE(response->headers);
[email protected]2d6728692011-03-12 01:39:5510999 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
11000
11001 std::string response_data;
robpercival214763f2016-07-01 23:27:0111002 ASSERT_THAT(ReadTransaction(&trans1, &response_data), IsOk());
[email protected]2d6728692011-03-12 01:39:5511003 EXPECT_EQ("hello world", response_data);
11004
[email protected]49639fa2011-12-20 23:22:4111005 TestCompletionCallback callback2;
[email protected]90499482013-06-01 00:39:5011006 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:2011007 rv = trans2.Start(&request, callback2.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0111008 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2d6728692011-03-12 01:39:5511009
[email protected]49639fa2011-12-20 23:22:4111010 TestCompletionCallback callback3;
[email protected]90499482013-06-01 00:39:5011011 HttpNetworkTransaction trans3(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:2011012 rv = trans3.Start(&request, callback3.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0111013 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2d6728692011-03-12 01:39:5511014
robpercival214763f2016-07-01 23:27:0111015 EXPECT_THAT(callback2.WaitForResult(), IsOk());
11016 EXPECT_THAT(callback3.WaitForResult(), IsOk());
[email protected]2d6728692011-03-12 01:39:5511017
11018 response = trans2.GetResponseInfo();
wezca1070932016-05-26 20:30:5211019 ASSERT_TRUE(response);
11020 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0211021 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]2d6728692011-03-12 01:39:5511022 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5211023 EXPECT_TRUE(response->was_alpn_negotiated);
robpercival214763f2016-07-01 23:27:0111024 ASSERT_THAT(ReadTransaction(&trans2, &response_data), IsOk());
[email protected]2d6728692011-03-12 01:39:5511025 EXPECT_EQ("hello!", response_data);
11026
11027 response = trans3.GetResponseInfo();
wezca1070932016-05-26 20:30:5211028 ASSERT_TRUE(response);
11029 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0211030 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]2d6728692011-03-12 01:39:5511031 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5211032 EXPECT_TRUE(response->was_alpn_negotiated);
robpercival214763f2016-07-01 23:27:0111033 ASSERT_THAT(ReadTransaction(&trans3, &response_data), IsOk());
[email protected]2d6728692011-03-12 01:39:5511034 EXPECT_EQ("hello!", response_data);
[email protected]2d6728692011-03-12 01:39:5511035}
11036
bncd16676a2016-07-20 16:23:0111037TEST_F(HttpNetworkTransactionTest, StallAlternativeServiceForNpnSpdy) {
[email protected]2d6728692011-03-12 01:39:5511038 HttpRequestInfo request;
11039 request.method = "GET";
bncb26024382016-06-29 02:39:4511040 request.url = GURL("https://www.example.org/");
[email protected]2d6728692011-03-12 01:39:5511041
11042 MockRead data_reads[] = {
bncc958faa2015-07-31 18:14:5211043 MockRead("HTTP/1.1 200 OK\r\n"),
bnc2df4b522016-07-08 18:17:4311044 MockRead(kAlternativeServiceHttpHeader),
bncc958faa2015-07-31 18:14:5211045 MockRead("\r\n"),
11046 MockRead("hello world"),
11047 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
11048 MockRead(ASYNC, OK),
[email protected]2d6728692011-03-12 01:39:5511049 };
11050
11051 StaticSocketDataProvider first_transaction(
11052 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0711053 session_deps_.socket_factory->AddSocketDataProvider(&first_transaction);
[email protected]2d6728692011-03-12 01:39:5511054
[email protected]8ddf8322012-02-23 18:08:0611055 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:0711056 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]2d6728692011-03-12 01:39:5511057
[email protected]d973e99a2012-02-17 21:02:3611058 MockConnect never_finishing_connect(SYNCHRONOUS, ERR_IO_PENDING);
[email protected]2d6728692011-03-12 01:39:5511059 StaticSocketDataProvider hanging_alternate_protocol_socket(
11060 NULL, 0, NULL, 0);
11061 hanging_alternate_protocol_socket.set_connect_data(
11062 never_finishing_connect);
[email protected]bb88e1d32013-05-03 23:11:0711063 session_deps_.socket_factory->AddSocketDataProvider(
[email protected]2d6728692011-03-12 01:39:5511064 &hanging_alternate_protocol_socket);
11065
bncb26024382016-06-29 02:39:4511066 // 2nd request is just a copy of the first one, over HTTP/1.1 again.
mmenkecc2298e2015-12-07 18:20:1811067 StaticSocketDataProvider second_transaction(data_reads, arraysize(data_reads),
11068 NULL, 0);
11069 session_deps_.socket_factory->AddSocketDataProvider(&second_transaction);
bncb26024382016-06-29 02:39:4511070 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]2d6728692011-03-12 01:39:5511071
[email protected]49639fa2011-12-20 23:22:4111072 TestCompletionCallback callback;
[email protected]2d6728692011-03-12 01:39:5511073
danakj1fd259a02016-04-16 03:17:0911074 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1611075 std::unique_ptr<HttpNetworkTransaction> trans(
[email protected]90499482013-06-01 00:39:5011076 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]2d6728692011-03-12 01:39:5511077
tfarina42834112016-09-22 13:38:2011078 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0111079 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
11080 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]2d6728692011-03-12 01:39:5511081
11082 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5211083 ASSERT_TRUE(response);
11084 ASSERT_TRUE(response->headers);
[email protected]2d6728692011-03-12 01:39:5511085 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
11086
11087 std::string response_data;
robpercival214763f2016-07-01 23:27:0111088 ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
[email protected]2d6728692011-03-12 01:39:5511089 EXPECT_EQ("hello world", response_data);
11090
[email protected]90499482013-06-01 00:39:5011091 trans.reset(new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]2d6728692011-03-12 01:39:5511092
tfarina42834112016-09-22 13:38:2011093 rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0111094 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
11095 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]2d6728692011-03-12 01:39:5511096
11097 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5211098 ASSERT_TRUE(response);
11099 ASSERT_TRUE(response->headers);
[email protected]2d6728692011-03-12 01:39:5511100 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
11101 EXPECT_FALSE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5211102 EXPECT_FALSE(response->was_alpn_negotiated);
[email protected]2d6728692011-03-12 01:39:5511103
robpercival214763f2016-07-01 23:27:0111104 ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
[email protected]2d6728692011-03-12 01:39:5511105 EXPECT_EQ("hello world", response_data);
[email protected]2d6728692011-03-12 01:39:5511106}
11107
[email protected]631f1322010-04-30 17:59:1111108class CapturingProxyResolver : public ProxyResolver {
11109 public:
sammce90c9212015-05-27 23:43:3511110 CapturingProxyResolver() {}
dchengb03027d2014-10-21 12:00:2011111 ~CapturingProxyResolver() override {}
[email protected]631f1322010-04-30 17:59:1111112
dchengb03027d2014-10-21 12:00:2011113 int GetProxyForURL(const GURL& url,
11114 ProxyInfo* results,
11115 const CompletionCallback& callback,
maksim.sisov7e157262016-10-20 11:19:5511116 std::unique_ptr<Request>* request,
tfarina42834112016-09-22 13:38:2011117 const NetLogWithSource& net_log) override {
[email protected]fae7669f2010-08-02 21:49:4011118 ProxyServer proxy_server(ProxyServer::SCHEME_HTTP,
11119 HostPortPair("myproxy", 80));
[email protected]d911f1b2010-05-05 22:39:4211120 results->UseProxyServer(proxy_server);
[email protected]631f1322010-04-30 17:59:1111121 resolved_.push_back(url);
[email protected]d911f1b2010-05-05 22:39:4211122 return OK;
[email protected]631f1322010-04-30 17:59:1111123 }
11124
[email protected]24476402010-07-20 20:55:1711125 const std::vector<GURL>& resolved() const { return resolved_; }
11126
11127 private:
[email protected]631f1322010-04-30 17:59:1111128 std::vector<GURL> resolved_;
11129
11130 DISALLOW_COPY_AND_ASSIGN(CapturingProxyResolver);
11131};
11132
sammce64b2362015-04-29 03:50:2311133class CapturingProxyResolverFactory : public ProxyResolverFactory {
11134 public:
11135 explicit CapturingProxyResolverFactory(CapturingProxyResolver* resolver)
11136 : ProxyResolverFactory(false), resolver_(resolver) {}
11137
11138 int CreateProxyResolver(
11139 const scoped_refptr<ProxyResolverScriptData>& pac_script,
danakj1fd259a02016-04-16 03:17:0911140 std::unique_ptr<ProxyResolver>* resolver,
sammce64b2362015-04-29 03:50:2311141 const net::CompletionCallback& callback,
danakj1fd259a02016-04-16 03:17:0911142 std::unique_ptr<Request>* request) override {
sammce64b2362015-04-29 03:50:2311143 resolver->reset(new ForwardingProxyResolver(resolver_));
11144 return OK;
11145 }
11146
11147 private:
11148 ProxyResolver* resolver_;
11149};
11150
bnc2e884782016-08-11 19:45:1911151// Test that proxy is resolved using the origin url,
11152// regardless of the alternative server.
11153TEST_F(HttpNetworkTransactionTest, UseOriginNotAlternativeForProxy) {
11154 // Configure proxy to bypass www.example.org, which is the origin URL.
11155 ProxyConfig proxy_config;
11156 proxy_config.proxy_rules().ParseFromString("myproxy:70");
11157 proxy_config.proxy_rules().bypass_rules.AddRuleFromString("www.example.org");
11158 auto proxy_config_service =
11159 base::MakeUnique<ProxyConfigServiceFixed>(proxy_config);
11160
11161 CapturingProxyResolver capturing_proxy_resolver;
11162 auto proxy_resolver_factory = base::MakeUnique<CapturingProxyResolverFactory>(
11163 &capturing_proxy_resolver);
11164
11165 TestNetLog net_log;
11166
11167 session_deps_.proxy_service = base::MakeUnique<ProxyService>(
11168 std::move(proxy_config_service), std::move(proxy_resolver_factory),
11169 &net_log);
11170
11171 session_deps_.net_log = &net_log;
11172
11173 // Configure alternative service with a hostname that is not bypassed by the
11174 // proxy.
11175 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
11176 HttpServerProperties* http_server_properties =
11177 session->http_server_properties();
11178 url::SchemeHostPort server("https", "www.example.org", 443);
11179 HostPortPair alternative("www.example.com", 443);
bnc3472afd2016-11-17 15:27:2111180 AlternativeService alternative_service(kProtoHTTP2, alternative);
bnc2e884782016-08-11 19:45:1911181 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
11182 http_server_properties->SetAlternativeService(server, alternative_service,
11183 expiration);
11184
11185 // Non-alternative job should hang.
11186 MockConnect never_finishing_connect(SYNCHRONOUS, ERR_IO_PENDING);
11187 StaticSocketDataProvider hanging_alternate_protocol_socket(nullptr, 0,
11188 nullptr, 0);
11189 hanging_alternate_protocol_socket.set_connect_data(never_finishing_connect);
11190 session_deps_.socket_factory->AddSocketDataProvider(
11191 &hanging_alternate_protocol_socket);
11192
bnc032658ba2016-09-26 18:17:1511193 AddSSLSocketData();
bnc2e884782016-08-11 19:45:1911194
11195 HttpRequestInfo request;
11196 request.method = "GET";
11197 request.url = GURL("https://www.example.org/");
11198 request.load_flags = 0;
11199
11200 SpdySerializedFrame req(
11201 spdy_util_.ConstructSpdyGet("https://www.example.org/", 1, LOWEST));
11202
11203 MockWrite spdy_writes[] = {CreateMockWrite(req, 0)};
11204
11205 SpdySerializedFrame resp(spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
11206 SpdySerializedFrame data(spdy_util_.ConstructSpdyDataFrame(1, true));
11207 MockRead spdy_reads[] = {
11208 CreateMockRead(resp, 1), CreateMockRead(data, 2), MockRead(ASYNC, 0, 3),
11209 };
11210
11211 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
11212 arraysize(spdy_writes));
11213 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
11214
11215 TestCompletionCallback callback;
11216
11217 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
11218
tfarina42834112016-09-22 13:38:2011219 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
bnc2e884782016-08-11 19:45:1911220 EXPECT_THAT(callback.GetResult(rv), IsOk());
11221
11222 const HttpResponseInfo* response = trans.GetResponseInfo();
11223 ASSERT_TRUE(response);
11224 ASSERT_TRUE(response->headers);
11225 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
11226 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5211227 EXPECT_TRUE(response->was_alpn_negotiated);
bnc2e884782016-08-11 19:45:1911228
11229 std::string response_data;
11230 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
11231 EXPECT_EQ("hello!", response_data);
11232
11233 // Origin host bypasses proxy, no resolution should have happened.
11234 ASSERT_TRUE(capturing_proxy_resolver.resolved().empty());
11235}
11236
bncd16676a2016-07-20 16:23:0111237TEST_F(HttpNetworkTransactionTest, UseAlternativeServiceForTunneledNpnSpdy) {
[email protected]631f1322010-04-30 17:59:1111238 ProxyConfig proxy_config;
[email protected]d911f1b2010-05-05 22:39:4211239 proxy_config.set_auto_detect(true);
11240 proxy_config.set_pac_url(GURL("http://fooproxyurl"));
[email protected]2227c692010-05-04 15:36:1111241
sammc5dd160c2015-04-02 02:43:1311242 CapturingProxyResolver capturing_proxy_resolver;
ricea2deef682016-09-09 08:04:0711243 session_deps_.proxy_service.reset(
11244 new ProxyService(base::MakeUnique<ProxyConfigServiceFixed>(proxy_config),
11245 base::MakeUnique<CapturingProxyResolverFactory>(
11246 &capturing_proxy_resolver),
11247 NULL));
vishal.b62985ca92015-04-17 08:45:5111248 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:0711249 session_deps_.net_log = &net_log;
[email protected]631f1322010-04-30 17:59:1111250
11251 HttpRequestInfo request;
11252 request.method = "GET";
bncb26024382016-06-29 02:39:4511253 request.url = GURL("https://www.example.org/");
[email protected]631f1322010-04-30 17:59:1111254
11255 MockRead data_reads[] = {
bncc958faa2015-07-31 18:14:5211256 MockRead("HTTP/1.1 200 OK\r\n"),
bnc2df4b522016-07-08 18:17:4311257 MockRead(kAlternativeServiceHttpHeader),
bncc958faa2015-07-31 18:14:5211258 MockRead("\r\n"),
11259 MockRead("hello world"),
11260 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
11261 MockRead(ASYNC, OK),
[email protected]631f1322010-04-30 17:59:1111262 };
11263
11264 StaticSocketDataProvider first_transaction(
11265 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0711266 session_deps_.socket_factory->AddSocketDataProvider(&first_transaction);
bncb26024382016-06-29 02:39:4511267 SSLSocketDataProvider ssl_http11(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3611268 ssl_http11.next_proto = kProtoHTTP11;
bncb26024382016-06-29 02:39:4511269 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_http11);
[email protected]631f1322010-04-30 17:59:1111270
bnc032658ba2016-09-26 18:17:1511271 AddSSLSocketData();
[email protected]631f1322010-04-30 17:59:1111272
bncdf80d44fd2016-07-15 20:27:4111273 SpdySerializedFrame req(
bncb26024382016-06-29 02:39:4511274 spdy_util_.ConstructSpdyGet("https://www.example.org/", 1, LOWEST));
[email protected]631f1322010-04-30 17:59:1111275 MockWrite spdy_writes[] = {
rch8e6c6c42015-05-01 14:05:1311276 MockWrite(ASYNC, 0,
bnc8bef8da22016-05-30 01:28:2511277 "CONNECT www.example.org:443 HTTP/1.1\r\n"
11278 "Host: www.example.org:443\r\n"
rch8e6c6c42015-05-01 14:05:1311279 "Proxy-Connection: keep-alive\r\n\r\n"),
bncdf80d44fd2016-07-15 20:27:4111280 CreateMockWrite(req, 2),
[email protected]631f1322010-04-30 17:59:1111281 };
11282
[email protected]d911f1b2010-05-05 22:39:4211283 const char kCONNECTResponse[] = "HTTP/1.1 200 Connected\r\n\r\n";
11284
bnc42331402016-07-25 13:36:1511285 SpdySerializedFrame resp(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
bncdf80d44fd2016-07-15 20:27:4111286 SpdySerializedFrame data(spdy_util_.ConstructSpdyDataFrame(1, true));
[email protected]631f1322010-04-30 17:59:1111287 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:4111288 MockRead(ASYNC, 1, kCONNECTResponse), CreateMockRead(resp, 3),
11289 CreateMockRead(data, 4), MockRead(SYNCHRONOUS, ERR_IO_PENDING, 5),
[email protected]631f1322010-04-30 17:59:1111290 };
11291
rch8e6c6c42015-05-01 14:05:1311292 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
11293 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:0711294 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]631f1322010-04-30 17:59:1111295
[email protected]d973e99a2012-02-17 21:02:3611296 MockConnect never_finishing_connect(SYNCHRONOUS, ERR_IO_PENDING);
[email protected]2d6728692011-03-12 01:39:5511297 StaticSocketDataProvider hanging_non_alternate_protocol_socket(
11298 NULL, 0, NULL, 0);
11299 hanging_non_alternate_protocol_socket.set_connect_data(
11300 never_finishing_connect);
[email protected]bb88e1d32013-05-03 23:11:0711301 session_deps_.socket_factory->AddSocketDataProvider(
[email protected]2d6728692011-03-12 01:39:5511302 &hanging_non_alternate_protocol_socket);
11303
[email protected]49639fa2011-12-20 23:22:4111304 TestCompletionCallback callback;
[email protected]631f1322010-04-30 17:59:1111305
danakj1fd259a02016-04-16 03:17:0911306 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1611307 std::unique_ptr<HttpNetworkTransaction> trans(
[email protected]90499482013-06-01 00:39:5011308 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]631f1322010-04-30 17:59:1111309
tfarina42834112016-09-22 13:38:2011310 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
mmenkea2dcd3bf2016-08-16 21:49:4111311 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
11312 EXPECT_THAT(callback.WaitForResult(), IsOk());
11313
11314 const HttpResponseInfo* response = trans->GetResponseInfo();
11315 ASSERT_TRUE(response);
11316 ASSERT_TRUE(response->headers);
11317 EXPECT_EQ("HTTP/0.9 200 OK", response->headers->GetStatusLine());
11318 EXPECT_FALSE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5211319 EXPECT_TRUE(response->was_alpn_negotiated);
mmenkea2dcd3bf2016-08-16 21:49:4111320
11321 std::string response_data;
11322 ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
11323 EXPECT_EQ("hello world", response_data);
[email protected]631f1322010-04-30 17:59:1111324
[email protected]90499482013-06-01 00:39:5011325 trans.reset(new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]631f1322010-04-30 17:59:1111326
tfarina42834112016-09-22 13:38:2011327 rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0111328 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
11329 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]631f1322010-04-30 17:59:1111330
mmenkea2dcd3bf2016-08-16 21:49:4111331 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5211332 ASSERT_TRUE(response);
11333 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0211334 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]65041fa2010-05-21 06:56:5311335 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5211336 EXPECT_TRUE(response->was_alpn_negotiated);
[email protected]631f1322010-04-30 17:59:1111337
robpercival214763f2016-07-01 23:27:0111338 ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
[email protected]631f1322010-04-30 17:59:1111339 EXPECT_EQ("hello!", response_data);
bncb26024382016-06-29 02:39:4511340 ASSERT_EQ(2u, capturing_proxy_resolver.resolved().size());
11341 EXPECT_EQ("https://www.example.org/",
sammc5dd160c2015-04-02 02:43:1311342 capturing_proxy_resolver.resolved()[0].spec());
bncce36dca22015-04-21 22:11:2311343 EXPECT_EQ("https://www.example.org/",
sammc5dd160c2015-04-02 02:43:1311344 capturing_proxy_resolver.resolved()[1].spec());
[email protected]631f1322010-04-30 17:59:1111345
[email protected]029c83b62013-01-24 05:28:2011346 LoadTimingInfo load_timing_info;
11347 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
11348 TestLoadTimingNotReusedWithPac(load_timing_info,
11349 CONNECT_TIMING_HAS_SSL_TIMES);
[email protected]631f1322010-04-30 17:59:1111350}
[email protected]631f1322010-04-30 17:59:1111351
bncd16676a2016-07-20 16:23:0111352TEST_F(HttpNetworkTransactionTest,
bnc1c196c6e2016-05-28 13:51:4811353 UseAlternativeServiceForNpnSpdyWithExistingSpdySession) {
[email protected]2ff8b312010-04-26 22:20:5411354 HttpRequestInfo request;
11355 request.method = "GET";
bncb26024382016-06-29 02:39:4511356 request.url = GURL("https://www.example.org/");
[email protected]2ff8b312010-04-26 22:20:5411357
11358 MockRead data_reads[] = {
bncc958faa2015-07-31 18:14:5211359 MockRead("HTTP/1.1 200 OK\r\n"),
bnc2df4b522016-07-08 18:17:4311360 MockRead(kAlternativeServiceHttpHeader),
bncc958faa2015-07-31 18:14:5211361 MockRead("\r\n"),
11362 MockRead("hello world"),
11363 MockRead(ASYNC, OK),
[email protected]2ff8b312010-04-26 22:20:5411364 };
11365
11366 StaticSocketDataProvider first_transaction(
11367 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0711368 session_deps_.socket_factory->AddSocketDataProvider(&first_transaction);
bncb26024382016-06-29 02:39:4511369 SSLSocketDataProvider ssl_http11(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3611370 ssl_http11.next_proto = kProtoHTTP11;
bncb26024382016-06-29 02:39:4511371 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_http11);
[email protected]2ff8b312010-04-26 22:20:5411372
bnc032658ba2016-09-26 18:17:1511373 AddSSLSocketData();
[email protected]2ff8b312010-04-26 22:20:5411374
bncdf80d44fd2016-07-15 20:27:4111375 SpdySerializedFrame req(
bncb26024382016-06-29 02:39:4511376 spdy_util_.ConstructSpdyGet("https://www.example.org/", 1, LOWEST));
bncdf80d44fd2016-07-15 20:27:4111377 MockWrite spdy_writes[] = {CreateMockWrite(req, 0)};
[email protected]2ff8b312010-04-26 22:20:5411378
bnc42331402016-07-25 13:36:1511379 SpdySerializedFrame resp(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
bncdf80d44fd2016-07-15 20:27:4111380 SpdySerializedFrame data(spdy_util_.ConstructSpdyDataFrame(1, true));
[email protected]2ff8b312010-04-26 22:20:5411381 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:4111382 CreateMockRead(resp, 1), CreateMockRead(data, 2), MockRead(ASYNC, 0, 3),
[email protected]2ff8b312010-04-26 22:20:5411383 };
11384
rch8e6c6c42015-05-01 14:05:1311385 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
11386 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:0711387 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]2ff8b312010-04-26 22:20:5411388
[email protected]83039bb2011-12-09 18:43:5511389 TestCompletionCallback callback;
[email protected]2ff8b312010-04-26 22:20:5411390
danakj1fd259a02016-04-16 03:17:0911391 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]2ff8b312010-04-26 22:20:5411392
bnc691fda62016-08-12 00:43:1611393 std::unique_ptr<HttpNetworkTransaction> trans(
[email protected]90499482013-06-01 00:39:5011394 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]2ff8b312010-04-26 22:20:5411395
tfarina42834112016-09-22 13:38:2011396 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0111397 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
11398 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]2ff8b312010-04-26 22:20:5411399
11400 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5211401 ASSERT_TRUE(response);
11402 ASSERT_TRUE(response->headers);
[email protected]2ff8b312010-04-26 22:20:5411403 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
11404
11405 std::string response_data;
robpercival214763f2016-07-01 23:27:0111406 ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
[email protected]2ff8b312010-04-26 22:20:5411407 EXPECT_EQ("hello world", response_data);
11408
11409 // Set up an initial SpdySession in the pool to reuse.
bnc8bef8da22016-05-30 01:28:2511410 HostPortPair host_port_pair("www.example.org", 443);
[email protected]e6d017652013-05-17 18:01:4011411 SpdySessionKey key(host_port_pair, ProxyServer::Direct(),
[email protected]314b03992014-04-01 01:28:5311412 PRIVACY_MODE_DISABLED);
[email protected]795cbf82013-07-22 09:37:2711413 base::WeakPtr<SpdySession> spdy_session =
tfarina42834112016-09-22 13:38:2011414 CreateSecureSpdySession(session.get(), key, NetLogWithSource());
[email protected]02b0c342010-09-25 21:09:3811415
[email protected]90499482013-06-01 00:39:5011416 trans.reset(new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]2ff8b312010-04-26 22:20:5411417
tfarina42834112016-09-22 13:38:2011418 rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0111419 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
11420 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]2ff8b312010-04-26 22:20:5411421
11422 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5211423 ASSERT_TRUE(response);
11424 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0211425 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]65041fa2010-05-21 06:56:5311426 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5211427 EXPECT_TRUE(response->was_alpn_negotiated);
[email protected]2ff8b312010-04-26 22:20:5411428
robpercival214763f2016-07-01 23:27:0111429 ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
[email protected]2ff8b312010-04-26 22:20:5411430 EXPECT_EQ("hello!", response_data);
[email protected]564b4912010-03-09 16:30:4211431}
11432
[email protected]044de0642010-06-17 10:42:1511433// GenerateAuthToken is a mighty big test.
11434// It tests all permutation of GenerateAuthToken behavior:
11435// - Synchronous and Asynchronous completion.
11436// - OK or error on completion.
11437// - Direct connection, non-authenticating proxy, and authenticating proxy.
11438// - HTTP or HTTPS backend (to include proxy tunneling).
11439// - Non-authenticating and authenticating backend.
11440//
[email protected]fe3b7dc2012-02-03 19:52:0911441// In all, there are 44 reasonable permuations (for example, if there are
[email protected]044de0642010-06-17 10:42:1511442// problems generating an auth token for an authenticating proxy, we don't
11443// need to test all permutations of the backend server).
11444//
11445// The test proceeds by going over each of the configuration cases, and
11446// potentially running up to three rounds in each of the tests. The TestConfig
11447// specifies both the configuration for the test as well as the expectations
11448// for the results.
bncd16676a2016-07-20 16:23:0111449TEST_F(HttpNetworkTransactionTest, GenerateAuthToken) {
[email protected]0b0bf032010-09-21 18:08:5011450 static const char kServer[] = "http://www.example.com";
11451 static const char kSecureServer[] = "https://www.example.com";
11452 static const char kProxy[] = "myproxy:70";
[email protected]044de0642010-06-17 10:42:1511453
11454 enum AuthTiming {
11455 AUTH_NONE,
11456 AUTH_SYNC,
11457 AUTH_ASYNC,
11458 };
11459
11460 const MockWrite kGet(
11461 "GET / HTTP/1.1\r\n"
11462 "Host: www.example.com\r\n"
11463 "Connection: keep-alive\r\n\r\n");
11464 const MockWrite kGetProxy(
11465 "GET http://www.example.com/ HTTP/1.1\r\n"
11466 "Host: www.example.com\r\n"
11467 "Proxy-Connection: keep-alive\r\n\r\n");
11468 const MockWrite kGetAuth(
11469 "GET / HTTP/1.1\r\n"
11470 "Host: www.example.com\r\n"
11471 "Connection: keep-alive\r\n"
11472 "Authorization: auth_token\r\n\r\n");
11473 const MockWrite kGetProxyAuth(
11474 "GET http://www.example.com/ HTTP/1.1\r\n"
11475 "Host: www.example.com\r\n"
11476 "Proxy-Connection: keep-alive\r\n"
11477 "Proxy-Authorization: auth_token\r\n\r\n");
11478 const MockWrite kGetAuthThroughProxy(
11479 "GET http://www.example.com/ HTTP/1.1\r\n"
11480 "Host: www.example.com\r\n"
11481 "Proxy-Connection: keep-alive\r\n"
11482 "Authorization: auth_token\r\n\r\n");
11483 const MockWrite kGetAuthWithProxyAuth(
11484 "GET http://www.example.com/ HTTP/1.1\r\n"
11485 "Host: www.example.com\r\n"
11486 "Proxy-Connection: keep-alive\r\n"
11487 "Proxy-Authorization: auth_token\r\n"
11488 "Authorization: auth_token\r\n\r\n");
11489 const MockWrite kConnect(
11490 "CONNECT www.example.com:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:1711491 "Host: www.example.com:443\r\n"
[email protected]044de0642010-06-17 10:42:1511492 "Proxy-Connection: keep-alive\r\n\r\n");
11493 const MockWrite kConnectProxyAuth(
11494 "CONNECT www.example.com:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:1711495 "Host: www.example.com:443\r\n"
[email protected]044de0642010-06-17 10:42:1511496 "Proxy-Connection: keep-alive\r\n"
11497 "Proxy-Authorization: auth_token\r\n\r\n");
11498
11499 const MockRead kSuccess(
11500 "HTTP/1.1 200 OK\r\n"
11501 "Content-Type: text/html; charset=iso-8859-1\r\n"
11502 "Content-Length: 3\r\n\r\n"
11503 "Yes");
11504 const MockRead kFailure(
11505 "Should not be called.");
11506 const MockRead kServerChallenge(
11507 "HTTP/1.1 401 Unauthorized\r\n"
11508 "WWW-Authenticate: Mock realm=server\r\n"
11509 "Content-Type: text/html; charset=iso-8859-1\r\n"
11510 "Content-Length: 14\r\n\r\n"
11511 "Unauthorized\r\n");
11512 const MockRead kProxyChallenge(
11513 "HTTP/1.1 407 Unauthorized\r\n"
11514 "Proxy-Authenticate: Mock realm=proxy\r\n"
11515 "Proxy-Connection: close\r\n"
11516 "Content-Type: text/html; charset=iso-8859-1\r\n"
11517 "Content-Length: 14\r\n\r\n"
11518 "Unauthorized\r\n");
11519 const MockRead kProxyConnected(
11520 "HTTP/1.1 200 Connection Established\r\n\r\n");
11521
11522 // NOTE(cbentzel): I wanted TestReadWriteRound to be a simple struct with
11523 // no constructors, but the C++ compiler on Windows warns about
11524 // unspecified data in compound literals. So, moved to using constructors,
11525 // and TestRound's created with the default constructor should not be used.
11526 struct TestRound {
11527 TestRound()
11528 : expected_rv(ERR_UNEXPECTED),
11529 extra_write(NULL),
11530 extra_read(NULL) {
11531 }
11532 TestRound(const MockWrite& write_arg, const MockRead& read_arg,
11533 int expected_rv_arg)
11534 : write(write_arg),
11535 read(read_arg),
11536 expected_rv(expected_rv_arg),
11537 extra_write(NULL),
11538 extra_read(NULL) {
11539 }
11540 TestRound(const MockWrite& write_arg, const MockRead& read_arg,
11541 int expected_rv_arg, const MockWrite* extra_write_arg,
[email protected]f871ee152012-07-27 19:02:0111542 const MockRead* extra_read_arg)
[email protected]044de0642010-06-17 10:42:1511543 : write(write_arg),
11544 read(read_arg),
11545 expected_rv(expected_rv_arg),
11546 extra_write(extra_write_arg),
11547 extra_read(extra_read_arg) {
11548 }
11549 MockWrite write;
11550 MockRead read;
11551 int expected_rv;
11552 const MockWrite* extra_write;
11553 const MockRead* extra_read;
11554 };
11555
11556 static const int kNoSSL = 500;
11557
11558 struct TestConfig {
asanka463ca4262016-11-16 02:34:3111559 int line_number;
thestig9d3bb0c2015-01-24 00:49:5111560 const char* const proxy_url;
[email protected]044de0642010-06-17 10:42:1511561 AuthTiming proxy_auth_timing;
asanka463ca4262016-11-16 02:34:3111562 int first_generate_proxy_token_rv;
thestig9d3bb0c2015-01-24 00:49:5111563 const char* const server_url;
[email protected]044de0642010-06-17 10:42:1511564 AuthTiming server_auth_timing;
asanka463ca4262016-11-16 02:34:3111565 int first_generate_server_token_rv;
[email protected]044de0642010-06-17 10:42:1511566 int num_auth_rounds;
11567 int first_ssl_round;
asankae2257db2016-10-11 22:03:1611568 TestRound rounds[4];
[email protected]044de0642010-06-17 10:42:1511569 } test_configs[] = {
asankac93076192016-10-03 15:46:0211570 // Non-authenticating HTTP server with a direct connection.
asanka463ca4262016-11-16 02:34:3111571 {__LINE__,
11572 nullptr,
asankac93076192016-10-03 15:46:0211573 AUTH_NONE,
11574 OK,
11575 kServer,
11576 AUTH_NONE,
11577 OK,
11578 1,
11579 kNoSSL,
11580 {TestRound(kGet, kSuccess, OK)}},
11581 // Authenticating HTTP server with a direct connection.
asanka463ca4262016-11-16 02:34:3111582 {__LINE__,
11583 nullptr,
asankac93076192016-10-03 15:46:0211584 AUTH_NONE,
11585 OK,
11586 kServer,
11587 AUTH_SYNC,
11588 OK,
11589 2,
11590 kNoSSL,
11591 {TestRound(kGet, kServerChallenge, OK),
[email protected]044de0642010-06-17 10:42:1511592 TestRound(kGetAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3111593 {__LINE__,
11594 nullptr,
asankac93076192016-10-03 15:46:0211595 AUTH_NONE,
11596 OK,
11597 kServer,
11598 AUTH_SYNC,
11599 ERR_INVALID_AUTH_CREDENTIALS,
asankae2257db2016-10-11 22:03:1611600 3,
11601 kNoSSL,
11602 {TestRound(kGet, kServerChallenge, OK),
11603 TestRound(kGet, kServerChallenge, OK),
11604 TestRound(kGetAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3111605 {__LINE__,
11606 nullptr,
asankae2257db2016-10-11 22:03:1611607 AUTH_NONE,
11608 OK,
11609 kServer,
11610 AUTH_SYNC,
11611 ERR_UNSUPPORTED_AUTH_SCHEME,
11612 2,
11613 kNoSSL,
11614 {TestRound(kGet, kServerChallenge, OK), TestRound(kGet, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3111615 {__LINE__,
11616 nullptr,
asankae2257db2016-10-11 22:03:1611617 AUTH_NONE,
11618 OK,
11619 kServer,
11620 AUTH_SYNC,
11621 ERR_UNDOCUMENTED_SECURITY_LIBRARY_STATUS,
11622 2,
11623 kNoSSL,
11624 {TestRound(kGet, kServerChallenge, OK), TestRound(kGet, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3111625 {__LINE__,
11626 kProxy,
asankae2257db2016-10-11 22:03:1611627 AUTH_SYNC,
11628 ERR_FAILED,
11629 kServer,
11630 AUTH_NONE,
11631 OK,
11632 2,
11633 kNoSSL,
11634 {TestRound(kGetProxy, kProxyChallenge, OK),
11635 TestRound(kGetProxy, kFailure, ERR_FAILED)}},
asanka463ca4262016-11-16 02:34:3111636 {__LINE__,
11637 kProxy,
asankae2257db2016-10-11 22:03:1611638 AUTH_ASYNC,
11639 ERR_FAILED,
11640 kServer,
11641 AUTH_NONE,
11642 OK,
11643 2,
11644 kNoSSL,
11645 {TestRound(kGetProxy, kProxyChallenge, OK),
11646 TestRound(kGetProxy, kFailure, ERR_FAILED)}},
asanka463ca4262016-11-16 02:34:3111647 {__LINE__,
11648 nullptr,
asankae2257db2016-10-11 22:03:1611649 AUTH_NONE,
11650 OK,
11651 kServer,
11652 AUTH_SYNC,
11653 ERR_FAILED,
asankac93076192016-10-03 15:46:0211654 2,
11655 kNoSSL,
11656 {TestRound(kGet, kServerChallenge, OK),
asankae2257db2016-10-11 22:03:1611657 TestRound(kGet, kFailure, ERR_FAILED)}},
asanka463ca4262016-11-16 02:34:3111658 {__LINE__,
11659 nullptr,
asankae2257db2016-10-11 22:03:1611660 AUTH_NONE,
11661 OK,
11662 kServer,
11663 AUTH_ASYNC,
11664 ERR_FAILED,
11665 2,
11666 kNoSSL,
11667 {TestRound(kGet, kServerChallenge, OK),
11668 TestRound(kGet, kFailure, ERR_FAILED)}},
asanka463ca4262016-11-16 02:34:3111669 {__LINE__,
11670 nullptr,
asankac93076192016-10-03 15:46:0211671 AUTH_NONE,
11672 OK,
11673 kServer,
11674 AUTH_ASYNC,
11675 OK,
11676 2,
11677 kNoSSL,
11678 {TestRound(kGet, kServerChallenge, OK),
[email protected]044de0642010-06-17 10:42:1511679 TestRound(kGetAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3111680 {__LINE__,
11681 nullptr,
asankac93076192016-10-03 15:46:0211682 AUTH_NONE,
11683 OK,
11684 kServer,
11685 AUTH_ASYNC,
11686 ERR_INVALID_AUTH_CREDENTIALS,
asankae2257db2016-10-11 22:03:1611687 3,
asankac93076192016-10-03 15:46:0211688 kNoSSL,
11689 {TestRound(kGet, kServerChallenge, OK),
asankae2257db2016-10-11 22:03:1611690 // The second round uses a HttpAuthHandlerMock that always succeeds.
11691 TestRound(kGet, kServerChallenge, OK),
11692 TestRound(kGetAuth, kSuccess, OK)}},
asankac93076192016-10-03 15:46:0211693 // Non-authenticating HTTP server through a non-authenticating proxy.
asanka463ca4262016-11-16 02:34:3111694 {__LINE__,
11695 kProxy,
asankac93076192016-10-03 15:46:0211696 AUTH_NONE,
11697 OK,
11698 kServer,
11699 AUTH_NONE,
11700 OK,
11701 1,
11702 kNoSSL,
11703 {TestRound(kGetProxy, kSuccess, OK)}},
11704 // Authenticating HTTP server through a non-authenticating proxy.
asanka463ca4262016-11-16 02:34:3111705 {__LINE__,
11706 kProxy,
asankac93076192016-10-03 15:46:0211707 AUTH_NONE,
11708 OK,
11709 kServer,
11710 AUTH_SYNC,
11711 OK,
11712 2,
11713 kNoSSL,
11714 {TestRound(kGetProxy, kServerChallenge, OK),
[email protected]044de0642010-06-17 10:42:1511715 TestRound(kGetAuthThroughProxy, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3111716 {__LINE__,
11717 kProxy,
asankac93076192016-10-03 15:46:0211718 AUTH_NONE,
11719 OK,
11720 kServer,
11721 AUTH_SYNC,
11722 ERR_INVALID_AUTH_CREDENTIALS,
asankae2257db2016-10-11 22:03:1611723 3,
asankac93076192016-10-03 15:46:0211724 kNoSSL,
11725 {TestRound(kGetProxy, kServerChallenge, OK),
asankae2257db2016-10-11 22:03:1611726 TestRound(kGetProxy, kServerChallenge, OK),
11727 TestRound(kGetAuthThroughProxy, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3111728 {__LINE__,
11729 kProxy,
asankac93076192016-10-03 15:46:0211730 AUTH_NONE,
11731 OK,
11732 kServer,
11733 AUTH_ASYNC,
11734 OK,
11735 2,
11736 kNoSSL,
11737 {TestRound(kGetProxy, kServerChallenge, OK),
[email protected]044de0642010-06-17 10:42:1511738 TestRound(kGetAuthThroughProxy, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3111739 {__LINE__,
11740 kProxy,
asankac93076192016-10-03 15:46:0211741 AUTH_NONE,
11742 OK,
11743 kServer,
11744 AUTH_ASYNC,
11745 ERR_INVALID_AUTH_CREDENTIALS,
11746 2,
11747 kNoSSL,
11748 {TestRound(kGetProxy, kServerChallenge, OK),
asankae2257db2016-10-11 22:03:1611749 TestRound(kGetProxy, kSuccess, OK)}},
asankac93076192016-10-03 15:46:0211750 // Non-authenticating HTTP server through an authenticating proxy.
asanka463ca4262016-11-16 02:34:3111751 {__LINE__,
11752 kProxy,
asankac93076192016-10-03 15:46:0211753 AUTH_SYNC,
11754 OK,
11755 kServer,
11756 AUTH_NONE,
11757 OK,
11758 2,
11759 kNoSSL,
11760 {TestRound(kGetProxy, kProxyChallenge, OK),
[email protected]044de0642010-06-17 10:42:1511761 TestRound(kGetProxyAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3111762 {__LINE__,
11763 kProxy,
asankac93076192016-10-03 15:46:0211764 AUTH_SYNC,
11765 ERR_INVALID_AUTH_CREDENTIALS,
11766 kServer,
11767 AUTH_NONE,
11768 OK,
11769 2,
11770 kNoSSL,
11771 {TestRound(kGetProxy, kProxyChallenge, OK),
asankae2257db2016-10-11 22:03:1611772 TestRound(kGetProxy, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3111773 {__LINE__,
11774 kProxy,
asankac93076192016-10-03 15:46:0211775 AUTH_ASYNC,
11776 OK,
11777 kServer,
11778 AUTH_NONE,
11779 OK,
11780 2,
11781 kNoSSL,
11782 {TestRound(kGetProxy, kProxyChallenge, OK),
[email protected]044de0642010-06-17 10:42:1511783 TestRound(kGetProxyAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3111784 {__LINE__,
11785 kProxy,
asankac93076192016-10-03 15:46:0211786 AUTH_ASYNC,
11787 ERR_INVALID_AUTH_CREDENTIALS,
11788 kServer,
11789 AUTH_NONE,
11790 OK,
11791 2,
11792 kNoSSL,
11793 {TestRound(kGetProxy, kProxyChallenge, OK),
asankae2257db2016-10-11 22:03:1611794 TestRound(kGetProxy, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3111795 {__LINE__,
11796 kProxy,
11797 AUTH_ASYNC,
11798 ERR_INVALID_AUTH_CREDENTIALS,
11799 kServer,
11800 AUTH_NONE,
11801 OK,
11802 3,
11803 kNoSSL,
11804 {TestRound(kGetProxy, kProxyChallenge, OK),
11805 TestRound(kGetProxy, kProxyChallenge, OK),
11806 TestRound(kGetProxyAuth, kSuccess, OK)}},
asankac93076192016-10-03 15:46:0211807 // Authenticating HTTP server through an authenticating proxy.
asanka463ca4262016-11-16 02:34:3111808 {__LINE__,
11809 kProxy,
asankac93076192016-10-03 15:46:0211810 AUTH_SYNC,
11811 OK,
11812 kServer,
11813 AUTH_SYNC,
11814 OK,
11815 3,
11816 kNoSSL,
11817 {TestRound(kGetProxy, kProxyChallenge, OK),
[email protected]044de0642010-06-17 10:42:1511818 TestRound(kGetProxyAuth, kServerChallenge, OK),
11819 TestRound(kGetAuthWithProxyAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3111820 {__LINE__,
11821 kProxy,
asankac93076192016-10-03 15:46:0211822 AUTH_SYNC,
11823 OK,
11824 kServer,
11825 AUTH_SYNC,
11826 ERR_INVALID_AUTH_CREDENTIALS,
11827 3,
11828 kNoSSL,
11829 {TestRound(kGetProxy, kProxyChallenge, OK),
[email protected]044de0642010-06-17 10:42:1511830 TestRound(kGetProxyAuth, kServerChallenge, OK),
asankae2257db2016-10-11 22:03:1611831 TestRound(kGetProxyAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3111832 {__LINE__,
11833 kProxy,
asankac93076192016-10-03 15:46:0211834 AUTH_ASYNC,
11835 OK,
11836 kServer,
11837 AUTH_SYNC,
11838 OK,
11839 3,
11840 kNoSSL,
11841 {TestRound(kGetProxy, kProxyChallenge, OK),
[email protected]044de0642010-06-17 10:42:1511842 TestRound(kGetProxyAuth, kServerChallenge, OK),
11843 TestRound(kGetAuthWithProxyAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3111844 {__LINE__,
11845 kProxy,
asankac93076192016-10-03 15:46:0211846 AUTH_ASYNC,
11847 OK,
11848 kServer,
11849 AUTH_SYNC,
11850 ERR_INVALID_AUTH_CREDENTIALS,
11851 3,
11852 kNoSSL,
11853 {TestRound(kGetProxy, kProxyChallenge, OK),
[email protected]044de0642010-06-17 10:42:1511854 TestRound(kGetProxyAuth, kServerChallenge, OK),
asankae2257db2016-10-11 22:03:1611855 TestRound(kGetProxyAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3111856 {__LINE__,
11857 kProxy,
asankac93076192016-10-03 15:46:0211858 AUTH_SYNC,
11859 OK,
11860 kServer,
11861 AUTH_ASYNC,
11862 OK,
11863 3,
11864 kNoSSL,
11865 {TestRound(kGetProxy, kProxyChallenge, OK),
[email protected]044de0642010-06-17 10:42:1511866 TestRound(kGetProxyAuth, kServerChallenge, OK),
11867 TestRound(kGetAuthWithProxyAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3111868 {__LINE__,
11869 kProxy,
11870 AUTH_SYNC,
11871 ERR_INVALID_AUTH_CREDENTIALS,
11872 kServer,
11873 AUTH_ASYNC,
11874 OK,
11875 4,
11876 kNoSSL,
11877 {TestRound(kGetProxy, kProxyChallenge, OK),
11878 TestRound(kGetProxy, kProxyChallenge, OK),
11879 TestRound(kGetProxyAuth, kServerChallenge, OK),
11880 TestRound(kGetAuthWithProxyAuth, kSuccess, OK)}},
11881 {__LINE__,
11882 kProxy,
asankac93076192016-10-03 15:46:0211883 AUTH_SYNC,
11884 OK,
11885 kServer,
11886 AUTH_ASYNC,
11887 ERR_INVALID_AUTH_CREDENTIALS,
11888 3,
11889 kNoSSL,
11890 {TestRound(kGetProxy, kProxyChallenge, OK),
[email protected]044de0642010-06-17 10:42:1511891 TestRound(kGetProxyAuth, kServerChallenge, OK),
asankae2257db2016-10-11 22:03:1611892 TestRound(kGetProxyAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3111893 {__LINE__,
11894 kProxy,
asankac93076192016-10-03 15:46:0211895 AUTH_ASYNC,
11896 OK,
11897 kServer,
11898 AUTH_ASYNC,
11899 OK,
11900 3,
11901 kNoSSL,
11902 {TestRound(kGetProxy, kProxyChallenge, OK),
[email protected]044de0642010-06-17 10:42:1511903 TestRound(kGetProxyAuth, kServerChallenge, OK),
11904 TestRound(kGetAuthWithProxyAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3111905 {__LINE__,
11906 kProxy,
asankac93076192016-10-03 15:46:0211907 AUTH_ASYNC,
11908 OK,
11909 kServer,
11910 AUTH_ASYNC,
11911 ERR_INVALID_AUTH_CREDENTIALS,
11912 3,
11913 kNoSSL,
11914 {TestRound(kGetProxy, kProxyChallenge, OK),
[email protected]044de0642010-06-17 10:42:1511915 TestRound(kGetProxyAuth, kServerChallenge, OK),
asankae2257db2016-10-11 22:03:1611916 TestRound(kGetProxyAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3111917 {__LINE__,
11918 kProxy,
11919 AUTH_ASYNC,
11920 ERR_INVALID_AUTH_CREDENTIALS,
11921 kServer,
11922 AUTH_ASYNC,
11923 ERR_INVALID_AUTH_CREDENTIALS,
11924 4,
11925 kNoSSL,
11926 {TestRound(kGetProxy, kProxyChallenge, OK),
11927 TestRound(kGetProxy, kProxyChallenge, OK),
11928 TestRound(kGetProxyAuth, kServerChallenge, OK),
11929 TestRound(kGetProxyAuth, kSuccess, OK)}},
asankac93076192016-10-03 15:46:0211930 // Non-authenticating HTTPS server with a direct connection.
asanka463ca4262016-11-16 02:34:3111931 {__LINE__,
11932 nullptr,
asankac93076192016-10-03 15:46:0211933 AUTH_NONE,
11934 OK,
11935 kSecureServer,
11936 AUTH_NONE,
11937 OK,
11938 1,
11939 0,
11940 {TestRound(kGet, kSuccess, OK)}},
11941 // Authenticating HTTPS server with a direct connection.
asanka463ca4262016-11-16 02:34:3111942 {__LINE__,
11943 nullptr,
asankac93076192016-10-03 15:46:0211944 AUTH_NONE,
11945 OK,
11946 kSecureServer,
11947 AUTH_SYNC,
11948 OK,
11949 2,
11950 0,
11951 {TestRound(kGet, kServerChallenge, OK),
[email protected]044de0642010-06-17 10:42:1511952 TestRound(kGetAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3111953 {__LINE__,
11954 nullptr,
asankac93076192016-10-03 15:46:0211955 AUTH_NONE,
11956 OK,
11957 kSecureServer,
11958 AUTH_SYNC,
11959 ERR_INVALID_AUTH_CREDENTIALS,
11960 2,
11961 0,
asankae2257db2016-10-11 22:03:1611962 {TestRound(kGet, kServerChallenge, OK), TestRound(kGet, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3111963 {__LINE__,
11964 nullptr,
asankac93076192016-10-03 15:46:0211965 AUTH_NONE,
11966 OK,
11967 kSecureServer,
11968 AUTH_ASYNC,
11969 OK,
11970 2,
11971 0,
11972 {TestRound(kGet, kServerChallenge, OK),
[email protected]044de0642010-06-17 10:42:1511973 TestRound(kGetAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3111974 {__LINE__,
11975 nullptr,
asankac93076192016-10-03 15:46:0211976 AUTH_NONE,
11977 OK,
11978 kSecureServer,
11979 AUTH_ASYNC,
11980 ERR_INVALID_AUTH_CREDENTIALS,
11981 2,
11982 0,
asankae2257db2016-10-11 22:03:1611983 {TestRound(kGet, kServerChallenge, OK), TestRound(kGet, kSuccess, OK)}},
asankac93076192016-10-03 15:46:0211984 // Non-authenticating HTTPS server with a non-authenticating proxy.
asanka463ca4262016-11-16 02:34:3111985 {__LINE__,
11986 kProxy,
asankac93076192016-10-03 15:46:0211987 AUTH_NONE,
11988 OK,
11989 kSecureServer,
11990 AUTH_NONE,
11991 OK,
11992 1,
11993 0,
11994 {TestRound(kConnect, kProxyConnected, OK, &kGet, &kSuccess)}},
11995 // Authenticating HTTPS server through a non-authenticating proxy.
asanka463ca4262016-11-16 02:34:3111996 {__LINE__,
11997 kProxy,
asankac93076192016-10-03 15:46:0211998 AUTH_NONE,
11999 OK,
12000 kSecureServer,
12001 AUTH_SYNC,
12002 OK,
12003 2,
12004 0,
12005 {TestRound(kConnect, kProxyConnected, OK, &kGet, &kServerChallenge),
[email protected]044de0642010-06-17 10:42:1512006 TestRound(kGetAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112007 {__LINE__,
12008 kProxy,
asankac93076192016-10-03 15:46:0212009 AUTH_NONE,
12010 OK,
12011 kSecureServer,
12012 AUTH_SYNC,
12013 ERR_INVALID_AUTH_CREDENTIALS,
12014 2,
12015 0,
12016 {TestRound(kConnect, kProxyConnected, OK, &kGet, &kServerChallenge),
asankae2257db2016-10-11 22:03:1612017 TestRound(kGet, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112018 {__LINE__,
12019 kProxy,
asankac93076192016-10-03 15:46:0212020 AUTH_NONE,
12021 OK,
12022 kSecureServer,
12023 AUTH_ASYNC,
12024 OK,
12025 2,
12026 0,
12027 {TestRound(kConnect, kProxyConnected, OK, &kGet, &kServerChallenge),
[email protected]044de0642010-06-17 10:42:1512028 TestRound(kGetAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112029 {__LINE__,
12030 kProxy,
asankac93076192016-10-03 15:46:0212031 AUTH_NONE,
12032 OK,
12033 kSecureServer,
12034 AUTH_ASYNC,
12035 ERR_INVALID_AUTH_CREDENTIALS,
12036 2,
12037 0,
12038 {TestRound(kConnect, kProxyConnected, OK, &kGet, &kServerChallenge),
asankae2257db2016-10-11 22:03:1612039 TestRound(kGet, kSuccess, OK)}},
asankac93076192016-10-03 15:46:0212040 // Non-Authenticating HTTPS server through an authenticating proxy.
asanka463ca4262016-11-16 02:34:3112041 {__LINE__,
12042 kProxy,
asankac93076192016-10-03 15:46:0212043 AUTH_SYNC,
12044 OK,
12045 kSecureServer,
12046 AUTH_NONE,
12047 OK,
12048 2,
12049 1,
12050 {TestRound(kConnect, kProxyChallenge, OK),
[email protected]044de0642010-06-17 10:42:1512051 TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet, &kSuccess)}},
asanka463ca4262016-11-16 02:34:3112052 {__LINE__,
12053 kProxy,
asankac93076192016-10-03 15:46:0212054 AUTH_SYNC,
12055 ERR_INVALID_AUTH_CREDENTIALS,
12056 kSecureServer,
12057 AUTH_NONE,
12058 OK,
12059 2,
12060 kNoSSL,
12061 {TestRound(kConnect, kProxyChallenge, OK),
asankae2257db2016-10-11 22:03:1612062 TestRound(kConnect, kProxyConnected, OK, &kGet, &kSuccess)}},
asanka463ca4262016-11-16 02:34:3112063 {__LINE__,
12064 kProxy,
asankae2257db2016-10-11 22:03:1612065 AUTH_SYNC,
12066 ERR_UNSUPPORTED_AUTH_SCHEME,
12067 kSecureServer,
12068 AUTH_NONE,
12069 OK,
12070 2,
12071 kNoSSL,
12072 {TestRound(kConnect, kProxyChallenge, OK),
12073 TestRound(kConnect, kProxyConnected, OK, &kGet, &kSuccess)}},
asanka463ca4262016-11-16 02:34:3112074 {__LINE__,
12075 kProxy,
asankae2257db2016-10-11 22:03:1612076 AUTH_SYNC,
12077 ERR_UNEXPECTED,
12078 kSecureServer,
12079 AUTH_NONE,
12080 OK,
12081 2,
12082 kNoSSL,
12083 {TestRound(kConnect, kProxyChallenge, OK),
12084 TestRound(kConnect, kProxyConnected, ERR_UNEXPECTED)}},
asanka463ca4262016-11-16 02:34:3112085 {__LINE__,
12086 kProxy,
asankac93076192016-10-03 15:46:0212087 AUTH_ASYNC,
12088 OK,
12089 kSecureServer,
12090 AUTH_NONE,
12091 OK,
12092 2,
12093 1,
12094 {TestRound(kConnect, kProxyChallenge, OK),
[email protected]044de0642010-06-17 10:42:1512095 TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet, &kSuccess)}},
asanka463ca4262016-11-16 02:34:3112096 {__LINE__,
12097 kProxy,
asankac93076192016-10-03 15:46:0212098 AUTH_ASYNC,
12099 ERR_INVALID_AUTH_CREDENTIALS,
12100 kSecureServer,
12101 AUTH_NONE,
12102 OK,
12103 2,
12104 kNoSSL,
12105 {TestRound(kConnect, kProxyChallenge, OK),
asankae2257db2016-10-11 22:03:1612106 TestRound(kConnect, kProxyConnected, OK, &kGet, &kSuccess)}},
asankac93076192016-10-03 15:46:0212107 // Authenticating HTTPS server through an authenticating proxy.
asanka463ca4262016-11-16 02:34:3112108 {__LINE__,
12109 kProxy,
asankac93076192016-10-03 15:46:0212110 AUTH_SYNC,
12111 OK,
12112 kSecureServer,
12113 AUTH_SYNC,
12114 OK,
12115 3,
12116 1,
12117 {TestRound(kConnect, kProxyChallenge, OK),
12118 TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet,
12119 &kServerChallenge),
[email protected]044de0642010-06-17 10:42:1512120 TestRound(kGetAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112121 {__LINE__,
12122 kProxy,
asankac93076192016-10-03 15:46:0212123 AUTH_SYNC,
12124 OK,
12125 kSecureServer,
12126 AUTH_SYNC,
12127 ERR_INVALID_AUTH_CREDENTIALS,
12128 3,
12129 1,
12130 {TestRound(kConnect, kProxyChallenge, OK),
12131 TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet,
12132 &kServerChallenge),
asankae2257db2016-10-11 22:03:1612133 TestRound(kGet, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112134 {__LINE__,
12135 kProxy,
asankac93076192016-10-03 15:46:0212136 AUTH_ASYNC,
12137 OK,
12138 kSecureServer,
12139 AUTH_SYNC,
12140 OK,
12141 3,
12142 1,
12143 {TestRound(kConnect, kProxyChallenge, OK),
12144 TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet,
12145 &kServerChallenge),
[email protected]044de0642010-06-17 10:42:1512146 TestRound(kGetAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112147 {__LINE__,
12148 kProxy,
asankac93076192016-10-03 15:46:0212149 AUTH_ASYNC,
12150 OK,
12151 kSecureServer,
12152 AUTH_SYNC,
12153 ERR_INVALID_AUTH_CREDENTIALS,
12154 3,
12155 1,
12156 {TestRound(kConnect, kProxyChallenge, OK),
12157 TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet,
12158 &kServerChallenge),
asankae2257db2016-10-11 22:03:1612159 TestRound(kGet, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112160 {__LINE__,
12161 kProxy,
asankac93076192016-10-03 15:46:0212162 AUTH_SYNC,
12163 OK,
12164 kSecureServer,
12165 AUTH_ASYNC,
12166 OK,
12167 3,
12168 1,
12169 {TestRound(kConnect, kProxyChallenge, OK),
12170 TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet,
12171 &kServerChallenge),
[email protected]044de0642010-06-17 10:42:1512172 TestRound(kGetAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112173 {__LINE__,
12174 kProxy,
asankac93076192016-10-03 15:46:0212175 AUTH_SYNC,
12176 OK,
12177 kSecureServer,
12178 AUTH_ASYNC,
12179 ERR_INVALID_AUTH_CREDENTIALS,
12180 3,
12181 1,
12182 {TestRound(kConnect, kProxyChallenge, OK),
12183 TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet,
12184 &kServerChallenge),
asankae2257db2016-10-11 22:03:1612185 TestRound(kGet, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112186 {__LINE__,
12187 kProxy,
asankac93076192016-10-03 15:46:0212188 AUTH_ASYNC,
12189 OK,
12190 kSecureServer,
12191 AUTH_ASYNC,
12192 OK,
12193 3,
12194 1,
12195 {TestRound(kConnect, kProxyChallenge, OK),
12196 TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet,
12197 &kServerChallenge),
[email protected]044de0642010-06-17 10:42:1512198 TestRound(kGetAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112199 {__LINE__,
12200 kProxy,
asankac93076192016-10-03 15:46:0212201 AUTH_ASYNC,
12202 OK,
12203 kSecureServer,
12204 AUTH_ASYNC,
12205 ERR_INVALID_AUTH_CREDENTIALS,
12206 3,
12207 1,
12208 {TestRound(kConnect, kProxyChallenge, OK),
12209 TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet,
12210 &kServerChallenge),
asankae2257db2016-10-11 22:03:1612211 TestRound(kGet, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112212 {__LINE__,
12213 kProxy,
12214 AUTH_ASYNC,
12215 ERR_INVALID_AUTH_CREDENTIALS,
12216 kSecureServer,
12217 AUTH_ASYNC,
12218 ERR_INVALID_AUTH_CREDENTIALS,
12219 4,
12220 2,
12221 {TestRound(kConnect, kProxyChallenge, OK),
12222 TestRound(kConnect, kProxyChallenge, OK),
12223 TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet,
12224 &kServerChallenge),
12225 TestRound(kGet, kSuccess, OK)}},
[email protected]044de0642010-06-17 10:42:1512226 };
12227
asanka463ca4262016-11-16 02:34:3112228 for (const auto& test_config : test_configs) {
12229 SCOPED_TRACE(::testing::Message() << "Test config at "
12230 << test_config.line_number);
[email protected]2d01c262011-08-11 23:07:0812231 HttpAuthHandlerMock::Factory* auth_factory(
12232 new HttpAuthHandlerMock::Factory());
[email protected]bb88e1d32013-05-03 23:11:0712233 session_deps_.http_auth_handler_factory.reset(auth_factory);
asanka5ffd5d72016-03-23 16:20:4912234 SSLInfo empty_ssl_info;
[email protected]65d34382010-07-01 18:12:2612235
12236 // Set up authentication handlers as necessary.
[email protected]044de0642010-06-17 10:42:1512237 if (test_config.proxy_auth_timing != AUTH_NONE) {
asanka463ca4262016-11-16 02:34:3112238 for (int n = 0; n < 3; n++) {
[email protected]2d01c262011-08-11 23:07:0812239 HttpAuthHandlerMock* auth_handler(new HttpAuthHandlerMock());
12240 std::string auth_challenge = "Mock realm=proxy";
12241 GURL origin(test_config.proxy_url);
[email protected]df41d0d82014-03-13 00:43:2412242 HttpAuthChallengeTokenizer tokenizer(auth_challenge.begin(),
12243 auth_challenge.end());
[email protected]2d01c262011-08-11 23:07:0812244 auth_handler->InitFromChallenge(&tokenizer, HttpAuth::AUTH_PROXY,
tfarina42834112016-09-22 13:38:2012245 empty_ssl_info, origin,
12246 NetLogWithSource());
[email protected]2d01c262011-08-11 23:07:0812247 auth_handler->SetGenerateExpectation(
12248 test_config.proxy_auth_timing == AUTH_ASYNC,
asanka463ca4262016-11-16 02:34:3112249 n == 0 ? test_config.first_generate_proxy_token_rv : OK);
[email protected]2d01c262011-08-11 23:07:0812250 auth_factory->AddMockHandler(auth_handler, HttpAuth::AUTH_PROXY);
12251 }
[email protected]044de0642010-06-17 10:42:1512252 }
12253 if (test_config.server_auth_timing != AUTH_NONE) {
[email protected]3fd9dae2010-06-21 11:39:0012254 HttpAuthHandlerMock* auth_handler(new HttpAuthHandlerMock());
[email protected]044de0642010-06-17 10:42:1512255 std::string auth_challenge = "Mock realm=server";
12256 GURL origin(test_config.server_url);
[email protected]df41d0d82014-03-13 00:43:2412257 HttpAuthChallengeTokenizer tokenizer(auth_challenge.begin(),
12258 auth_challenge.end());
[email protected]044de0642010-06-17 10:42:1512259 auth_handler->InitFromChallenge(&tokenizer, HttpAuth::AUTH_SERVER,
tfarina42834112016-09-22 13:38:2012260 empty_ssl_info, origin,
12261 NetLogWithSource());
[email protected]044de0642010-06-17 10:42:1512262 auth_handler->SetGenerateExpectation(
12263 test_config.server_auth_timing == AUTH_ASYNC,
asanka463ca4262016-11-16 02:34:3112264 test_config.first_generate_server_token_rv);
[email protected]2d01c262011-08-11 23:07:0812265 auth_factory->AddMockHandler(auth_handler, HttpAuth::AUTH_SERVER);
asankae2257db2016-10-11 22:03:1612266
12267 // The second handler always succeeds. It should only be used where there
12268 // are multiple auth sessions for server auth in the same network
12269 // transaction using the same auth scheme.
12270 std::unique_ptr<HttpAuthHandlerMock> second_handler =
12271 base::MakeUnique<HttpAuthHandlerMock>();
12272 second_handler->InitFromChallenge(&tokenizer, HttpAuth::AUTH_SERVER,
12273 empty_ssl_info, origin,
12274 NetLogWithSource());
12275 second_handler->SetGenerateExpectation(true, OK);
12276 auth_factory->AddMockHandler(second_handler.release(),
12277 HttpAuth::AUTH_SERVER);
[email protected]044de0642010-06-17 10:42:1512278 }
12279 if (test_config.proxy_url) {
rdsmith82957ad2015-09-16 19:42:0312280 session_deps_.proxy_service =
12281 ProxyService::CreateFixed(test_config.proxy_url);
[email protected]044de0642010-06-17 10:42:1512282 } else {
rdsmith82957ad2015-09-16 19:42:0312283 session_deps_.proxy_service = ProxyService::CreateDirect();
[email protected]044de0642010-06-17 10:42:1512284 }
12285
12286 HttpRequestInfo request;
12287 request.method = "GET";
12288 request.url = GURL(test_config.server_url);
[email protected]044de0642010-06-17 10:42:1512289
danakj1fd259a02016-04-16 03:17:0912290 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]044de0642010-06-17 10:42:1512291
rchcb68dc62015-05-21 04:45:3612292 SSLSocketDataProvider ssl_socket_data_provider(SYNCHRONOUS, OK);
12293
12294 std::vector<std::vector<MockRead>> mock_reads(1);
12295 std::vector<std::vector<MockWrite>> mock_writes(1);
[email protected]044de0642010-06-17 10:42:1512296 for (int round = 0; round < test_config.num_auth_rounds; ++round) {
davidben8c7089a2017-04-17 20:38:2212297 SCOPED_TRACE(round);
[email protected]044de0642010-06-17 10:42:1512298 const TestRound& read_write_round = test_config.rounds[round];
12299
12300 // Set up expected reads and writes.
rchcb68dc62015-05-21 04:45:3612301 mock_reads.back().push_back(read_write_round.read);
12302 mock_writes.back().push_back(read_write_round.write);
12303
12304 // kProxyChallenge uses Proxy-Connection: close which means that the
12305 // socket is closed and a new one will be created for the next request.
mmenkee71e15332015-10-07 16:39:5412306 if (read_write_round.read.data == kProxyChallenge.data) {
rchcb68dc62015-05-21 04:45:3612307 mock_reads.push_back(std::vector<MockRead>());
12308 mock_writes.push_back(std::vector<MockWrite>());
[email protected]044de0642010-06-17 10:42:1512309 }
12310
rchcb68dc62015-05-21 04:45:3612311 if (read_write_round.extra_read) {
12312 mock_reads.back().push_back(*read_write_round.extra_read);
[email protected]044de0642010-06-17 10:42:1512313 }
rchcb68dc62015-05-21 04:45:3612314 if (read_write_round.extra_write) {
12315 mock_writes.back().push_back(*read_write_round.extra_write);
12316 }
[email protected]044de0642010-06-17 10:42:1512317
12318 // Add an SSL sequence if necessary.
[email protected]044de0642010-06-17 10:42:1512319 if (round >= test_config.first_ssl_round)
[email protected]bb88e1d32013-05-03 23:11:0712320 session_deps_.socket_factory->AddSSLSocketDataProvider(
[email protected]044de0642010-06-17 10:42:1512321 &ssl_socket_data_provider);
rchcb68dc62015-05-21 04:45:3612322 }
[email protected]044de0642010-06-17 10:42:1512323
danakj1fd259a02016-04-16 03:17:0912324 std::vector<std::unique_ptr<StaticSocketDataProvider>> data_providers;
rchcb68dc62015-05-21 04:45:3612325 for (size_t i = 0; i < mock_reads.size(); ++i) {
danakj1fd259a02016-04-16 03:17:0912326 data_providers.push_back(base::WrapUnique(new StaticSocketDataProvider(
davidben5f8b6bc2015-11-25 03:19:5412327 mock_reads[i].data(), mock_reads[i].size(), mock_writes[i].data(),
olli.raula525048c2015-12-10 07:38:3212328 mock_writes[i].size())));
rchcb68dc62015-05-21 04:45:3612329 session_deps_.socket_factory->AddSocketDataProvider(
olli.raula525048c2015-12-10 07:38:3212330 data_providers.back().get());
rchcb68dc62015-05-21 04:45:3612331 }
12332
mmenkecc2298e2015-12-07 18:20:1812333 // Transaction must be created after DataProviders, so it's destroyed before
12334 // they are as well.
12335 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
12336
rchcb68dc62015-05-21 04:45:3612337 for (int round = 0; round < test_config.num_auth_rounds; ++round) {
davidben8c7089a2017-04-17 20:38:2212338 SCOPED_TRACE(round);
rchcb68dc62015-05-21 04:45:3612339 const TestRound& read_write_round = test_config.rounds[round];
[email protected]044de0642010-06-17 10:42:1512340 // Start or restart the transaction.
[email protected]49639fa2011-12-20 23:22:4112341 TestCompletionCallback callback;
[email protected]044de0642010-06-17 10:42:1512342 int rv;
12343 if (round == 0) {
tfarina42834112016-09-22 13:38:2012344 rv = trans.Start(&request, callback.callback(), NetLogWithSource());
[email protected]044de0642010-06-17 10:42:1512345 } else {
[email protected]49639fa2011-12-20 23:22:4112346 rv = trans.RestartWithAuth(
12347 AuthCredentials(kFoo, kBar), callback.callback());
[email protected]044de0642010-06-17 10:42:1512348 }
12349 if (rv == ERR_IO_PENDING)
12350 rv = callback.WaitForResult();
12351
12352 // Compare results with expected data.
asankae2257db2016-10-11 22:03:1612353 EXPECT_THAT(rv, IsError(read_write_round.expected_rv));
[email protected]0b0bf032010-09-21 18:08:5012354 const HttpResponseInfo* response = trans.GetResponseInfo();
ttuttlec0c828492015-05-15 01:25:5512355 if (read_write_round.expected_rv != OK) {
[email protected]044de0642010-06-17 10:42:1512356 EXPECT_EQ(round + 1, test_config.num_auth_rounds);
12357 continue;
12358 }
12359 if (round + 1 < test_config.num_auth_rounds) {
wezca1070932016-05-26 20:30:5212360 EXPECT_TRUE(response->auth_challenge);
[email protected]044de0642010-06-17 10:42:1512361 } else {
wezca1070932016-05-26 20:30:5212362 EXPECT_FALSE(response->auth_challenge);
asankae2257db2016-10-11 22:03:1612363 EXPECT_FALSE(trans.IsReadyToRestartForAuth());
[email protected]044de0642010-06-17 10:42:1512364 }
12365 }
[email protected]e5ae96a2010-04-14 20:12:4512366 }
12367}
12368
bncd16676a2016-07-20 16:23:0112369TEST_F(HttpNetworkTransactionTest, MultiRoundAuth) {
[email protected]c871bce92010-07-15 21:51:1412370 // Do multi-round authentication and make sure it works correctly.
[email protected]c871bce92010-07-15 21:51:1412371 HttpAuthHandlerMock::Factory* auth_factory(
12372 new HttpAuthHandlerMock::Factory());
[email protected]bb88e1d32013-05-03 23:11:0712373 session_deps_.http_auth_handler_factory.reset(auth_factory);
rdsmith82957ad2015-09-16 19:42:0312374 session_deps_.proxy_service = ProxyService::CreateDirect();
[email protected]bb88e1d32013-05-03 23:11:0712375 session_deps_.host_resolver->rules()->AddRule("www.example.com", "10.0.0.1");
12376 session_deps_.host_resolver->set_synchronous_mode(true);
[email protected]c871bce92010-07-15 21:51:1412377
12378 HttpAuthHandlerMock* auth_handler(new HttpAuthHandlerMock());
12379 auth_handler->set_connection_based(true);
12380 std::string auth_challenge = "Mock realm=server";
12381 GURL origin("http://www.example.com");
[email protected]df41d0d82014-03-13 00:43:2412382 HttpAuthChallengeTokenizer tokenizer(auth_challenge.begin(),
12383 auth_challenge.end());
asanka5ffd5d72016-03-23 16:20:4912384 SSLInfo empty_ssl_info;
[email protected]c871bce92010-07-15 21:51:1412385 auth_handler->InitFromChallenge(&tokenizer, HttpAuth::AUTH_SERVER,
tfarina42834112016-09-22 13:38:2012386 empty_ssl_info, origin, NetLogWithSource());
[email protected]2d01c262011-08-11 23:07:0812387 auth_factory->AddMockHandler(auth_handler, HttpAuth::AUTH_SERVER);
[email protected]c871bce92010-07-15 21:51:1412388
[email protected]c871bce92010-07-15 21:51:1412389 int rv = OK;
12390 const HttpResponseInfo* response = NULL;
12391 HttpRequestInfo request;
12392 request.method = "GET";
12393 request.url = origin;
[email protected]cb9bf6ca2011-01-28 13:15:2712394
danakj1fd259a02016-04-16 03:17:0912395 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]7ef4cbbb2011-02-06 11:19:1012396
12397 // Use a TCP Socket Pool with only one connection per group. This is used
12398 // to validate that the TCP socket is not released to the pool between
12399 // each round of multi-round authentication.
mmenkee65e7af2015-10-13 17:16:4212400 HttpNetworkSessionPeer session_peer(session.get());
[email protected]ab739042011-04-07 15:22:2812401 TransportClientSocketPool* transport_pool = new TransportClientSocketPool(
[email protected]7ef4cbbb2011-02-06 11:19:1012402 50, // Max sockets for pool
12403 1, // Max sockets per group
tbansal7b403bcc2016-04-13 22:33:2112404 session_deps_.host_resolver.get(), session_deps_.socket_factory.get(),
12405 NULL, session_deps_.net_log);
danakj1fd259a02016-04-16 03:17:0912406 std::unique_ptr<MockClientSocketPoolManager> mock_pool_manager(
[email protected]831e4a32013-11-14 02:14:4412407 new MockClientSocketPoolManager);
[email protected]a42dbd142011-11-17 16:42:0212408 mock_pool_manager->SetTransportSocketPool(transport_pool);
dchengc7eeda422015-12-26 03:56:4812409 session_peer.SetClientSocketPoolManager(std::move(mock_pool_manager));
[email protected]7ef4cbbb2011-02-06 11:19:1012410
bnc691fda62016-08-12 00:43:1612411 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]49639fa2011-12-20 23:22:4112412 TestCompletionCallback callback;
[email protected]c871bce92010-07-15 21:51:1412413
12414 const MockWrite kGet(
12415 "GET / HTTP/1.1\r\n"
12416 "Host: www.example.com\r\n"
12417 "Connection: keep-alive\r\n\r\n");
12418 const MockWrite kGetAuth(
12419 "GET / HTTP/1.1\r\n"
12420 "Host: www.example.com\r\n"
12421 "Connection: keep-alive\r\n"
12422 "Authorization: auth_token\r\n\r\n");
12423
12424 const MockRead kServerChallenge(
12425 "HTTP/1.1 401 Unauthorized\r\n"
12426 "WWW-Authenticate: Mock realm=server\r\n"
12427 "Content-Type: text/html; charset=iso-8859-1\r\n"
12428 "Content-Length: 14\r\n\r\n"
12429 "Unauthorized\r\n");
12430 const MockRead kSuccess(
12431 "HTTP/1.1 200 OK\r\n"
12432 "Content-Type: text/html; charset=iso-8859-1\r\n"
12433 "Content-Length: 3\r\n\r\n"
12434 "Yes");
12435
12436 MockWrite writes[] = {
12437 // First round
12438 kGet,
12439 // Second round
12440 kGetAuth,
12441 // Third round
12442 kGetAuth,
[email protected]eca50e122010-09-11 14:03:3012443 // Fourth round
[email protected]7ef4cbbb2011-02-06 11:19:1012444 kGetAuth,
12445 // Competing request
12446 kGet,
[email protected]c871bce92010-07-15 21:51:1412447 };
12448 MockRead reads[] = {
12449 // First round
12450 kServerChallenge,
12451 // Second round
12452 kServerChallenge,
12453 // Third round
[email protected]eca50e122010-09-11 14:03:3012454 kServerChallenge,
12455 // Fourth round
[email protected]c871bce92010-07-15 21:51:1412456 kSuccess,
[email protected]7ef4cbbb2011-02-06 11:19:1012457 // Competing response
12458 kSuccess,
[email protected]c871bce92010-07-15 21:51:1412459 };
12460 StaticSocketDataProvider data_provider(reads, arraysize(reads),
12461 writes, arraysize(writes));
[email protected]bb88e1d32013-05-03 23:11:0712462 session_deps_.socket_factory->AddSocketDataProvider(&data_provider);
[email protected]c871bce92010-07-15 21:51:1412463
thestig9d3bb0c2015-01-24 00:49:5112464 const char kSocketGroup[] = "www.example.com:80";
[email protected]7ef4cbbb2011-02-06 11:19:1012465
12466 // First round of authentication.
[email protected]c871bce92010-07-15 21:51:1412467 auth_handler->SetGenerateExpectation(false, OK);
tfarina42834112016-09-22 13:38:2012468 rv = trans.Start(&request, callback.callback(), NetLogWithSource());
[email protected]c871bce92010-07-15 21:51:1412469 if (rv == ERR_IO_PENDING)
12470 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0112471 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:1612472 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5212473 ASSERT_TRUE(response);
12474 EXPECT_TRUE(response->auth_challenge);
[email protected]ab739042011-04-07 15:22:2812475 EXPECT_EQ(0, transport_pool->IdleSocketCountInGroup(kSocketGroup));
asanka463ca4262016-11-16 02:34:3112476 EXPECT_EQ(HttpAuthHandlerMock::State::WAIT_FOR_GENERATE_AUTH_TOKEN,
12477 auth_handler->state());
[email protected]c871bce92010-07-15 21:51:1412478
[email protected]7ef4cbbb2011-02-06 11:19:1012479 // In between rounds, another request comes in for the same domain.
12480 // It should not be able to grab the TCP socket that trans has already
12481 // claimed.
bnc691fda62016-08-12 00:43:1612482 HttpNetworkTransaction trans_compete(DEFAULT_PRIORITY, session.get());
[email protected]49639fa2011-12-20 23:22:4112483 TestCompletionCallback callback_compete;
tfarina42834112016-09-22 13:38:2012484 rv = trans_compete.Start(&request, callback_compete.callback(),
12485 NetLogWithSource());
robpercival214763f2016-07-01 23:27:0112486 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]7ef4cbbb2011-02-06 11:19:1012487 // callback_compete.WaitForResult at this point would stall forever,
12488 // since the HttpNetworkTransaction does not release the request back to
12489 // the pool until after authentication completes.
12490
12491 // Second round of authentication.
[email protected]c871bce92010-07-15 21:51:1412492 auth_handler->SetGenerateExpectation(false, OK);
bnc691fda62016-08-12 00:43:1612493 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar), callback.callback());
[email protected]c871bce92010-07-15 21:51:1412494 if (rv == ERR_IO_PENDING)
12495 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0112496 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:1612497 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5212498 ASSERT_TRUE(response);
12499 EXPECT_FALSE(response->auth_challenge);
[email protected]ab739042011-04-07 15:22:2812500 EXPECT_EQ(0, transport_pool->IdleSocketCountInGroup(kSocketGroup));
asanka463ca4262016-11-16 02:34:3112501 EXPECT_EQ(HttpAuthHandlerMock::State::WAIT_FOR_GENERATE_AUTH_TOKEN,
12502 auth_handler->state());
[email protected]c871bce92010-07-15 21:51:1412503
[email protected]7ef4cbbb2011-02-06 11:19:1012504 // Third round of authentication.
[email protected]c871bce92010-07-15 21:51:1412505 auth_handler->SetGenerateExpectation(false, OK);
bnc691fda62016-08-12 00:43:1612506 rv = trans.RestartWithAuth(AuthCredentials(), callback.callback());
[email protected]c871bce92010-07-15 21:51:1412507 if (rv == ERR_IO_PENDING)
12508 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0112509 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:1612510 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5212511 ASSERT_TRUE(response);
12512 EXPECT_FALSE(response->auth_challenge);
[email protected]ab739042011-04-07 15:22:2812513 EXPECT_EQ(0, transport_pool->IdleSocketCountInGroup(kSocketGroup));
asanka463ca4262016-11-16 02:34:3112514 EXPECT_EQ(HttpAuthHandlerMock::State::WAIT_FOR_GENERATE_AUTH_TOKEN,
12515 auth_handler->state());
[email protected]eca50e122010-09-11 14:03:3012516
[email protected]7ef4cbbb2011-02-06 11:19:1012517 // Fourth round of authentication, which completes successfully.
[email protected]eca50e122010-09-11 14:03:3012518 auth_handler->SetGenerateExpectation(false, OK);
bnc691fda62016-08-12 00:43:1612519 rv = trans.RestartWithAuth(AuthCredentials(), callback.callback());
[email protected]eca50e122010-09-11 14:03:3012520 if (rv == ERR_IO_PENDING)
12521 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0112522 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:1612523 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5212524 ASSERT_TRUE(response);
12525 EXPECT_FALSE(response->auth_challenge);
[email protected]ab739042011-04-07 15:22:2812526 EXPECT_EQ(0, transport_pool->IdleSocketCountInGroup(kSocketGroup));
[email protected]7ef4cbbb2011-02-06 11:19:1012527
asanka463ca4262016-11-16 02:34:3112528 // In WAIT_FOR_CHALLENGE, although in reality the auth handler is done. A real
12529 // auth handler should transition to a DONE state in concert with the remote
12530 // server. But that's not something we can test here with a mock handler.
12531 EXPECT_EQ(HttpAuthHandlerMock::State::WAIT_FOR_CHALLENGE,
12532 auth_handler->state());
12533
[email protected]7ef4cbbb2011-02-06 11:19:1012534 // Read the body since the fourth round was successful. This will also
12535 // release the socket back to the pool.
12536 scoped_refptr<IOBufferWithSize> io_buf(new IOBufferWithSize(50));
bnc691fda62016-08-12 00:43:1612537 rv = trans.Read(io_buf.get(), io_buf->size(), callback.callback());
[email protected]7ef4cbbb2011-02-06 11:19:1012538 if (rv == ERR_IO_PENDING)
12539 rv = callback.WaitForResult();
12540 EXPECT_EQ(3, rv);
bnc691fda62016-08-12 00:43:1612541 rv = trans.Read(io_buf.get(), io_buf->size(), callback.callback());
[email protected]7ef4cbbb2011-02-06 11:19:1012542 EXPECT_EQ(0, rv);
12543 // There are still 0 idle sockets, since the trans_compete transaction
12544 // will be handed it immediately after trans releases it to the group.
[email protected]ab739042011-04-07 15:22:2812545 EXPECT_EQ(0, transport_pool->IdleSocketCountInGroup(kSocketGroup));
[email protected]7ef4cbbb2011-02-06 11:19:1012546
12547 // The competing request can now finish. Wait for the headers and then
12548 // read the body.
12549 rv = callback_compete.WaitForResult();
robpercival214763f2016-07-01 23:27:0112550 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:1612551 rv = trans_compete.Read(io_buf.get(), io_buf->size(), callback.callback());
[email protected]7ef4cbbb2011-02-06 11:19:1012552 if (rv == ERR_IO_PENDING)
12553 rv = callback.WaitForResult();
12554 EXPECT_EQ(3, rv);
bnc691fda62016-08-12 00:43:1612555 rv = trans_compete.Read(io_buf.get(), io_buf->size(), callback.callback());
[email protected]7ef4cbbb2011-02-06 11:19:1012556 EXPECT_EQ(0, rv);
12557
12558 // Finally, the socket is released to the group.
[email protected]ab739042011-04-07 15:22:2812559 EXPECT_EQ(1, transport_pool->IdleSocketCountInGroup(kSocketGroup));
[email protected]c871bce92010-07-15 21:51:1412560}
12561
[email protected]65041fa2010-05-21 06:56:5312562// This tests the case that a request is issued via http instead of spdy after
12563// npn is negotiated.
bncd16676a2016-07-20 16:23:0112564TEST_F(HttpNetworkTransactionTest, NpnWithHttpOverSSL) {
[email protected]65041fa2010-05-21 06:56:5312565 HttpRequestInfo request;
12566 request.method = "GET";
bncce36dca22015-04-21 22:11:2312567 request.url = GURL("https://www.example.org/");
[email protected]65041fa2010-05-21 06:56:5312568
12569 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:2312570 MockWrite(
12571 "GET / HTTP/1.1\r\n"
12572 "Host: www.example.org\r\n"
12573 "Connection: keep-alive\r\n\r\n"),
[email protected]65041fa2010-05-21 06:56:5312574 };
12575
12576 MockRead data_reads[] = {
bncc958faa2015-07-31 18:14:5212577 MockRead("HTTP/1.1 200 OK\r\n"),
bnc2df4b522016-07-08 18:17:4312578 MockRead(kAlternativeServiceHttpHeader),
bncc958faa2015-07-31 18:14:5212579 MockRead("\r\n"),
12580 MockRead("hello world"),
12581 MockRead(SYNCHRONOUS, OK),
[email protected]65041fa2010-05-21 06:56:5312582 };
12583
[email protected]8ddf8322012-02-23 18:08:0612584 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3612585 ssl.next_proto = kProtoHTTP11;
[email protected]65041fa2010-05-21 06:56:5312586
[email protected]bb88e1d32013-05-03 23:11:0712587 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]65041fa2010-05-21 06:56:5312588
12589 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
12590 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:0712591 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]65041fa2010-05-21 06:56:5312592
[email protected]49639fa2011-12-20 23:22:4112593 TestCompletionCallback callback;
[email protected]65041fa2010-05-21 06:56:5312594
danakj1fd259a02016-04-16 03:17:0912595 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1612596 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]65041fa2010-05-21 06:56:5312597
tfarina42834112016-09-22 13:38:2012598 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
[email protected]65041fa2010-05-21 06:56:5312599
robpercival214763f2016-07-01 23:27:0112600 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
12601 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]65041fa2010-05-21 06:56:5312602
bnc691fda62016-08-12 00:43:1612603 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5212604 ASSERT_TRUE(response);
12605 ASSERT_TRUE(response->headers);
[email protected]65041fa2010-05-21 06:56:5312606 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
12607
12608 std::string response_data;
bnc691fda62016-08-12 00:43:1612609 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
[email protected]65041fa2010-05-21 06:56:5312610 EXPECT_EQ("hello world", response_data);
12611
12612 EXPECT_FALSE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5212613 EXPECT_TRUE(response->was_alpn_negotiated);
[email protected]65041fa2010-05-21 06:56:5312614}
[email protected]26ef6582010-06-24 02:30:4712615
bnc55ff9da2015-08-19 18:42:3512616// Simulate the SSL handshake completing with an NPN negotiation followed by an
12617// immediate server closing of the socket.
12618// Regression test for https://crbug.com/46369.
bncd16676a2016-07-20 16:23:0112619TEST_F(HttpNetworkTransactionTest, SpdyPostNPNServerHangup) {
[email protected]26ef6582010-06-24 02:30:4712620 HttpRequestInfo request;
12621 request.method = "GET";
bncce36dca22015-04-21 22:11:2312622 request.url = GURL("https://www.example.org/");
[email protected]26ef6582010-06-24 02:30:4712623
[email protected]8ddf8322012-02-23 18:08:0612624 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3612625 ssl.next_proto = kProtoHTTP2;
[email protected]bb88e1d32013-05-03 23:11:0712626 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]26ef6582010-06-24 02:30:4712627
bncdf80d44fd2016-07-15 20:27:4112628 SpdySerializedFrame req(
bnc38dcd392016-02-09 23:19:4912629 spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST, true));
bncdf80d44fd2016-07-15 20:27:4112630 MockWrite spdy_writes[] = {CreateMockWrite(req, 1)};
[email protected]26ef6582010-06-24 02:30:4712631
12632 MockRead spdy_reads[] = {
[email protected]8ddf8322012-02-23 18:08:0612633 MockRead(SYNCHRONOUS, 0, 0) // Not async - return 0 immediately.
[email protected]26ef6582010-06-24 02:30:4712634 };
12635
rch8e6c6c42015-05-01 14:05:1312636 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
12637 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:0712638 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]26ef6582010-06-24 02:30:4712639
[email protected]49639fa2011-12-20 23:22:4112640 TestCompletionCallback callback;
[email protected]26ef6582010-06-24 02:30:4712641
danakj1fd259a02016-04-16 03:17:0912642 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1612643 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]26ef6582010-06-24 02:30:4712644
tfarina42834112016-09-22 13:38:2012645 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0112646 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
12647 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_CONNECTION_CLOSED));
[email protected]26ef6582010-06-24 02:30:4712648}
[email protected]65d34382010-07-01 18:12:2612649
[email protected]795cbf82013-07-22 09:37:2712650// A subclass of HttpAuthHandlerMock that records the request URL when
12651// it gets it. This is needed since the auth handler may get destroyed
12652// before we get a chance to query it.
12653class UrlRecordingHttpAuthHandlerMock : public HttpAuthHandlerMock {
12654 public:
12655 explicit UrlRecordingHttpAuthHandlerMock(GURL* url) : url_(url) {}
12656
dchengb03027d2014-10-21 12:00:2012657 ~UrlRecordingHttpAuthHandlerMock() override {}
[email protected]795cbf82013-07-22 09:37:2712658
12659 protected:
dchengb03027d2014-10-21 12:00:2012660 int GenerateAuthTokenImpl(const AuthCredentials* credentials,
12661 const HttpRequestInfo* request,
12662 const CompletionCallback& callback,
12663 std::string* auth_token) override {
[email protected]795cbf82013-07-22 09:37:2712664 *url_ = request->url;
12665 return HttpAuthHandlerMock::GenerateAuthTokenImpl(
12666 credentials, request, callback, auth_token);
12667 }
12668
12669 private:
12670 GURL* url_;
12671};
12672
[email protected]8e6441ca2010-08-19 05:56:3812673// Test that if we cancel the transaction as the connection is completing, that
12674// everything tears down correctly.
bncd16676a2016-07-20 16:23:0112675TEST_F(HttpNetworkTransactionTest, SimpleCancel) {
[email protected]8e6441ca2010-08-19 05:56:3812676 // Setup everything about the connection to complete synchronously, so that
12677 // after calling HttpNetworkTransaction::Start, the only thing we're waiting
12678 // for is the callback from the HttpStreamRequest.
12679 // Then cancel the transaction.
12680 // Verify that we don't crash.
[email protected]d973e99a2012-02-17 21:02:3612681 MockConnect mock_connect(SYNCHRONOUS, OK);
[email protected]8e6441ca2010-08-19 05:56:3812682 MockRead data_reads[] = {
[email protected]8ddf8322012-02-23 18:08:0612683 MockRead(SYNCHRONOUS, "HTTP/1.0 200 OK\r\n\r\n"),
12684 MockRead(SYNCHRONOUS, "hello world"),
12685 MockRead(SYNCHRONOUS, OK),
[email protected]8e6441ca2010-08-19 05:56:3812686 };
12687
[email protected]8e6441ca2010-08-19 05:56:3812688 HttpRequestInfo request;
12689 request.method = "GET";
bncce36dca22015-04-21 22:11:2312690 request.url = GURL("http://www.example.org/");
[email protected]8e6441ca2010-08-19 05:56:3812691
[email protected]bb88e1d32013-05-03 23:11:0712692 session_deps_.host_resolver->set_synchronous_mode(true);
danakj1fd259a02016-04-16 03:17:0912693 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1612694 std::unique_ptr<HttpNetworkTransaction> trans(
dcheng48459ac22014-08-26 00:46:4112695 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:2712696
[email protected]8e6441ca2010-08-19 05:56:3812697 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
12698 data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:0712699 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]8e6441ca2010-08-19 05:56:3812700
[email protected]49639fa2011-12-20 23:22:4112701 TestCompletionCallback callback;
[email protected]8e6441ca2010-08-19 05:56:3812702
vishal.b62985ca92015-04-17 08:45:5112703 BoundTestNetLog log;
[email protected]49639fa2011-12-20 23:22:4112704 int rv = trans->Start(&request, callback.callback(), log.bound());
robpercival214763f2016-07-01 23:27:0112705 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]8e6441ca2010-08-19 05:56:3812706 trans.reset(); // Cancel the transaction here.
12707
fdoray92e35a72016-06-10 15:54:5512708 base::RunLoop().RunUntilIdle();
[email protected]f45c1ee2010-08-03 00:54:3012709}
12710
[email protected]ecab6e052014-05-16 14:58:1212711// Test that if a transaction is cancelled after receiving the headers, the
12712// stream is drained properly and added back to the socket pool. The main
12713// purpose of this test is to make sure that an HttpStreamParser can be read
12714// from after the HttpNetworkTransaction and the objects it owns have been
12715// deleted.
12716// See http://crbug.com/368418
bncd16676a2016-07-20 16:23:0112717TEST_F(HttpNetworkTransactionTest, CancelAfterHeaders) {
[email protected]ecab6e052014-05-16 14:58:1212718 MockRead data_reads[] = {
12719 MockRead(ASYNC, "HTTP/1.1 200 OK\r\n"),
12720 MockRead(ASYNC, "Content-Length: 2\r\n"),
12721 MockRead(ASYNC, "Connection: Keep-Alive\r\n\r\n"),
12722 MockRead(ASYNC, "1"),
12723 // 2 async reads are necessary to trigger a ReadResponseBody call after the
12724 // HttpNetworkTransaction has been deleted.
12725 MockRead(ASYNC, "2"),
12726 MockRead(SYNCHRONOUS, ERR_IO_PENDING), // Should never read this.
12727 };
12728 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
12729 session_deps_.socket_factory->AddSocketDataProvider(&data);
12730
danakj1fd259a02016-04-16 03:17:0912731 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]ecab6e052014-05-16 14:58:1212732
12733 {
12734 HttpRequestInfo request;
12735 request.method = "GET";
bncce36dca22015-04-21 22:11:2312736 request.url = GURL("http://www.example.org/");
[email protected]ecab6e052014-05-16 14:58:1212737
dcheng48459ac22014-08-26 00:46:4112738 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]ecab6e052014-05-16 14:58:1212739 TestCompletionCallback callback;
12740
tfarina42834112016-09-22 13:38:2012741 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0112742 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]ecab6e052014-05-16 14:58:1212743 callback.WaitForResult();
12744
12745 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5212746 ASSERT_TRUE(response);
12747 EXPECT_TRUE(response->headers);
[email protected]ecab6e052014-05-16 14:58:1212748 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
12749
12750 // The transaction and HttpRequestInfo are deleted.
12751 }
12752
12753 // Let the HttpResponseBodyDrainer drain the socket.
fdoray92e35a72016-06-10 15:54:5512754 base::RunLoop().RunUntilIdle();
[email protected]ecab6e052014-05-16 14:58:1212755
12756 // Socket should now be idle, waiting to be reused.
dcheng48459ac22014-08-26 00:46:4112757 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]ecab6e052014-05-16 14:58:1212758}
12759
[email protected]76a505b2010-08-25 06:23:0012760// Test a basic GET request through a proxy.
bncd16676a2016-07-20 16:23:0112761TEST_F(HttpNetworkTransactionTest, ProxyGet) {
rdsmith82957ad2015-09-16 19:42:0312762 session_deps_.proxy_service =
12763 ProxyService::CreateFixedFromPacResult("PROXY myproxy:70");
vishal.b62985ca92015-04-17 08:45:5112764 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:0712765 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:0912766 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]76a505b2010-08-25 06:23:0012767
[email protected]76a505b2010-08-25 06:23:0012768 HttpRequestInfo request;
12769 request.method = "GET";
bncce36dca22015-04-21 22:11:2312770 request.url = GURL("http://www.example.org/");
[email protected]76a505b2010-08-25 06:23:0012771
12772 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:2312773 MockWrite(
12774 "GET http://www.example.org/ HTTP/1.1\r\n"
12775 "Host: www.example.org\r\n"
12776 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]76a505b2010-08-25 06:23:0012777 };
12778
12779 MockRead data_reads1[] = {
12780 MockRead("HTTP/1.1 200 OK\r\n"),
12781 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
12782 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:0612783 MockRead(SYNCHRONOUS, OK),
[email protected]76a505b2010-08-25 06:23:0012784 };
12785
12786 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
12787 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:0712788 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]76a505b2010-08-25 06:23:0012789
[email protected]49639fa2011-12-20 23:22:4112790 TestCompletionCallback callback1;
[email protected]76a505b2010-08-25 06:23:0012791
bnc691fda62016-08-12 00:43:1612792 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
ryansturm49a8cb12016-06-15 16:51:0912793 BeforeHeadersSentHandler headers_handler;
bnc691fda62016-08-12 00:43:1612794 trans.SetBeforeHeadersSentCallback(
ryansturm49a8cb12016-06-15 16:51:0912795 base::Bind(&BeforeHeadersSentHandler::OnBeforeHeadersSent,
12796 base::Unretained(&headers_handler)));
[email protected]0b0bf032010-09-21 18:08:5012797
bnc691fda62016-08-12 00:43:1612798 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:0112799 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]76a505b2010-08-25 06:23:0012800
12801 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:0112802 EXPECT_THAT(rv, IsOk());
[email protected]76a505b2010-08-25 06:23:0012803
bnc691fda62016-08-12 00:43:1612804 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5212805 ASSERT_TRUE(response);
[email protected]76a505b2010-08-25 06:23:0012806
12807 EXPECT_TRUE(response->headers->IsKeepAlive());
12808 EXPECT_EQ(200, response->headers->response_code());
12809 EXPECT_EQ(100, response->headers->GetContentLength());
12810 EXPECT_TRUE(response->was_fetched_via_proxy);
tbansal2ecbbc72016-10-06 17:15:4712811 EXPECT_EQ(ProxyServer(ProxyServer::SCHEME_HTTP,
12812 HostPortPair::FromString("myproxy:70")),
12813 response->proxy_server);
ryansturm49a8cb12016-06-15 16:51:0912814 EXPECT_TRUE(headers_handler.observed_before_headers_sent());
12815 EXPECT_TRUE(headers_handler.observed_before_headers_sent_with_proxy());
12816 EXPECT_EQ("myproxy:70", headers_handler.observed_proxy_server_uri());
[email protected]76a505b2010-08-25 06:23:0012817 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
[email protected]029c83b62013-01-24 05:28:2012818
12819 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:1612820 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]029c83b62013-01-24 05:28:2012821 TestLoadTimingNotReusedWithPac(load_timing_info,
12822 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
[email protected]76a505b2010-08-25 06:23:0012823}
12824
12825// Test a basic HTTPS GET request through a proxy.
bncd16676a2016-07-20 16:23:0112826TEST_F(HttpNetworkTransactionTest, ProxyTunnelGet) {
rdsmith82957ad2015-09-16 19:42:0312827 session_deps_.proxy_service =
12828 ProxyService::CreateFixedFromPacResult("PROXY myproxy:70");
vishal.b62985ca92015-04-17 08:45:5112829 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:0712830 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:0912831 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]76a505b2010-08-25 06:23:0012832
[email protected]76a505b2010-08-25 06:23:0012833 HttpRequestInfo request;
12834 request.method = "GET";
bncce36dca22015-04-21 22:11:2312835 request.url = GURL("https://www.example.org/");
[email protected]76a505b2010-08-25 06:23:0012836
12837 // Since we have proxy, should try to establish tunnel.
12838 MockWrite data_writes1[] = {
rsleevidb16bb02015-11-12 23:47:1712839 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
12840 "Host: www.example.org:443\r\n"
12841 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]76a505b2010-08-25 06:23:0012842
rsleevidb16bb02015-11-12 23:47:1712843 MockWrite("GET / HTTP/1.1\r\n"
12844 "Host: www.example.org\r\n"
12845 "Connection: keep-alive\r\n\r\n"),
[email protected]76a505b2010-08-25 06:23:0012846 };
12847
12848 MockRead data_reads1[] = {
12849 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
12850
12851 MockRead("HTTP/1.1 200 OK\r\n"),
12852 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
12853 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:0612854 MockRead(SYNCHRONOUS, OK),
[email protected]76a505b2010-08-25 06:23:0012855 };
12856
12857 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
12858 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:0712859 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8ddf8322012-02-23 18:08:0612860 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:0712861 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]76a505b2010-08-25 06:23:0012862
[email protected]49639fa2011-12-20 23:22:4112863 TestCompletionCallback callback1;
[email protected]76a505b2010-08-25 06:23:0012864
bnc691fda62016-08-12 00:43:1612865 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
ryansturm49a8cb12016-06-15 16:51:0912866 BeforeHeadersSentHandler headers_handler;
bnc691fda62016-08-12 00:43:1612867 trans.SetBeforeHeadersSentCallback(
ryansturm49a8cb12016-06-15 16:51:0912868 base::Bind(&BeforeHeadersSentHandler::OnBeforeHeadersSent,
12869 base::Unretained(&headers_handler)));
[email protected]0b0bf032010-09-21 18:08:5012870
bnc691fda62016-08-12 00:43:1612871 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:0112872 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]76a505b2010-08-25 06:23:0012873
12874 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:0112875 EXPECT_THAT(rv, IsOk());
mmenke43758e62015-05-04 21:09:4612876 TestNetLogEntry::List entries;
[email protected]b2fcd0e2010-12-01 15:19:4012877 log.GetEntries(&entries);
[email protected]76a505b2010-08-25 06:23:0012878 size_t pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:0012879 entries, 0, NetLogEventType::HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
12880 NetLogEventPhase::NONE);
[email protected]76a505b2010-08-25 06:23:0012881 ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:4012882 entries, pos,
mikecirone8b85c432016-09-08 19:11:0012883 NetLogEventType::HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
12884 NetLogEventPhase::NONE);
[email protected]76a505b2010-08-25 06:23:0012885
bnc691fda62016-08-12 00:43:1612886 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5212887 ASSERT_TRUE(response);
[email protected]76a505b2010-08-25 06:23:0012888
12889 EXPECT_TRUE(response->headers->IsKeepAlive());
12890 EXPECT_EQ(200, response->headers->response_code());
12891 EXPECT_EQ(100, response->headers->GetContentLength());
12892 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
12893 EXPECT_TRUE(response->was_fetched_via_proxy);
tbansal2ecbbc72016-10-06 17:15:4712894 EXPECT_EQ(ProxyServer(ProxyServer::SCHEME_HTTP,
12895 HostPortPair::FromString("myproxy:70")),
12896 response->proxy_server);
ryansturm49a8cb12016-06-15 16:51:0912897 EXPECT_TRUE(headers_handler.observed_before_headers_sent());
12898 EXPECT_TRUE(headers_handler.observed_before_headers_sent_with_proxy());
12899 EXPECT_EQ("myproxy:70", headers_handler.observed_proxy_server_uri());
[email protected]029c83b62013-01-24 05:28:2012900
12901 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:1612902 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]029c83b62013-01-24 05:28:2012903 TestLoadTimingNotReusedWithPac(load_timing_info,
12904 CONNECT_TIMING_HAS_SSL_TIMES);
[email protected]76a505b2010-08-25 06:23:0012905}
12906
rsleevidb16bb02015-11-12 23:47:1712907// Test a basic HTTPS GET request through a proxy, connecting to an IPv6
12908// literal host.
bncd16676a2016-07-20 16:23:0112909TEST_F(HttpNetworkTransactionTest, ProxyTunnelGetIPv6) {
rsleevidb16bb02015-11-12 23:47:1712910 session_deps_.proxy_service =
12911 ProxyService::CreateFixedFromPacResult("PROXY myproxy:70");
12912 BoundTestNetLog log;
12913 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:0912914 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
rsleevidb16bb02015-11-12 23:47:1712915
12916 HttpRequestInfo request;
12917 request.method = "GET";
12918 request.url = GURL("https://[::1]:443/");
12919
12920 // Since we have proxy, should try to establish tunnel.
12921 MockWrite data_writes1[] = {
12922 MockWrite("CONNECT [::1]:443 HTTP/1.1\r\n"
12923 "Host: [::1]:443\r\n"
12924 "Proxy-Connection: keep-alive\r\n\r\n"),
12925
12926 MockWrite("GET / HTTP/1.1\r\n"
12927 "Host: [::1]\r\n"
12928 "Connection: keep-alive\r\n\r\n"),
12929 };
12930
12931 MockRead data_reads1[] = {
12932 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
12933
12934 MockRead("HTTP/1.1 200 OK\r\n"),
12935 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
12936 MockRead("Content-Length: 100\r\n\r\n"),
12937 MockRead(SYNCHRONOUS, OK),
12938 };
12939
12940 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
12941 data_writes1, arraysize(data_writes1));
12942 session_deps_.socket_factory->AddSocketDataProvider(&data1);
12943 SSLSocketDataProvider ssl(ASYNC, OK);
12944 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
12945
12946 TestCompletionCallback callback1;
12947
bnc691fda62016-08-12 00:43:1612948 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
rsleevidb16bb02015-11-12 23:47:1712949
bnc691fda62016-08-12 00:43:1612950 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:0112951 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
rsleevidb16bb02015-11-12 23:47:1712952
12953 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:0112954 EXPECT_THAT(rv, IsOk());
rsleevidb16bb02015-11-12 23:47:1712955 TestNetLogEntry::List entries;
12956 log.GetEntries(&entries);
12957 size_t pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:0012958 entries, 0, NetLogEventType::HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
12959 NetLogEventPhase::NONE);
rsleevidb16bb02015-11-12 23:47:1712960 ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:0012961 entries, pos,
12962 NetLogEventType::HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
12963 NetLogEventPhase::NONE);
rsleevidb16bb02015-11-12 23:47:1712964
bnc691fda62016-08-12 00:43:1612965 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5212966 ASSERT_TRUE(response);
rsleevidb16bb02015-11-12 23:47:1712967
12968 EXPECT_TRUE(response->headers->IsKeepAlive());
12969 EXPECT_EQ(200, response->headers->response_code());
12970 EXPECT_EQ(100, response->headers->GetContentLength());
12971 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
12972 EXPECT_TRUE(response->was_fetched_via_proxy);
tbansal2ecbbc72016-10-06 17:15:4712973 EXPECT_EQ(ProxyServer(ProxyServer::SCHEME_HTTP,
12974 HostPortPair::FromString("myproxy:70")),
12975 response->proxy_server);
rsleevidb16bb02015-11-12 23:47:1712976
12977 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:1612978 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
rsleevidb16bb02015-11-12 23:47:1712979 TestLoadTimingNotReusedWithPac(load_timing_info,
12980 CONNECT_TIMING_HAS_SSL_TIMES);
12981}
12982
[email protected]76a505b2010-08-25 06:23:0012983// Test a basic HTTPS GET request through a proxy, but the server hangs up
12984// while establishing the tunnel.
bncd16676a2016-07-20 16:23:0112985TEST_F(HttpNetworkTransactionTest, ProxyTunnelGetHangup) {
rdsmith82957ad2015-09-16 19:42:0312986 session_deps_.proxy_service = ProxyService::CreateFixed("myproxy:70");
vishal.b62985ca92015-04-17 08:45:5112987 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:0712988 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:0912989 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]76a505b2010-08-25 06:23:0012990
[email protected]76a505b2010-08-25 06:23:0012991 HttpRequestInfo request;
12992 request.method = "GET";
bncce36dca22015-04-21 22:11:2312993 request.url = GURL("https://www.example.org/");
[email protected]76a505b2010-08-25 06:23:0012994
12995 // Since we have proxy, should try to establish tunnel.
12996 MockWrite data_writes1[] = {
rsleevidb16bb02015-11-12 23:47:1712997 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
12998 "Host: www.example.org:443\r\n"
12999 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]76a505b2010-08-25 06:23:0013000
rsleevidb16bb02015-11-12 23:47:1713001 MockWrite("GET / HTTP/1.1\r\n"
13002 "Host: www.example.org\r\n"
13003 "Connection: keep-alive\r\n\r\n"),
[email protected]76a505b2010-08-25 06:23:0013004 };
13005
13006 MockRead data_reads1[] = {
[email protected]8ddf8322012-02-23 18:08:0613007 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
[email protected]76a505b2010-08-25 06:23:0013008 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:0613009 MockRead(ASYNC, 0, 0), // EOF
[email protected]76a505b2010-08-25 06:23:0013010 };
13011
13012 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
13013 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:0713014 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8ddf8322012-02-23 18:08:0613015 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:0713016 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]76a505b2010-08-25 06:23:0013017
[email protected]49639fa2011-12-20 23:22:4113018 TestCompletionCallback callback1;
[email protected]76a505b2010-08-25 06:23:0013019
bnc691fda62016-08-12 00:43:1613020 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]0b0bf032010-09-21 18:08:5013021
bnc691fda62016-08-12 00:43:1613022 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:0113023 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]76a505b2010-08-25 06:23:0013024
13025 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:0113026 EXPECT_THAT(rv, IsError(ERR_EMPTY_RESPONSE));
mmenke43758e62015-05-04 21:09:4613027 TestNetLogEntry::List entries;
[email protected]b2fcd0e2010-12-01 15:19:4013028 log.GetEntries(&entries);
[email protected]76a505b2010-08-25 06:23:0013029 size_t pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:0013030 entries, 0, NetLogEventType::HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
13031 NetLogEventPhase::NONE);
[email protected]76a505b2010-08-25 06:23:0013032 ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:4013033 entries, pos,
mikecirone8b85c432016-09-08 19:11:0013034 NetLogEventType::HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
13035 NetLogEventPhase::NONE);
[email protected]76a505b2010-08-25 06:23:0013036}
13037
[email protected]749eefa82010-09-13 22:14:0313038// Test for crbug.com/55424.
bncd16676a2016-07-20 16:23:0113039TEST_F(HttpNetworkTransactionTest, PreconnectWithExistingSpdySession) {
bncdf80d44fd2016-07-15 20:27:4113040 SpdySerializedFrame req(
bnc38dcd392016-02-09 23:19:4913041 spdy_util_.ConstructSpdyGet("https://www.example.org", 1, LOWEST));
bncdf80d44fd2016-07-15 20:27:4113042 MockWrite spdy_writes[] = {CreateMockWrite(req, 0)};
[email protected]749eefa82010-09-13 22:14:0313043
bnc42331402016-07-25 13:36:1513044 SpdySerializedFrame resp(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
bncdf80d44fd2016-07-15 20:27:4113045 SpdySerializedFrame data(spdy_util_.ConstructSpdyDataFrame(1, true));
[email protected]749eefa82010-09-13 22:14:0313046 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:4113047 CreateMockRead(resp, 1), CreateMockRead(data, 2), MockRead(ASYNC, 0, 3),
[email protected]749eefa82010-09-13 22:14:0313048 };
13049
rch8e6c6c42015-05-01 14:05:1313050 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
13051 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:0713052 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]749eefa82010-09-13 22:14:0313053
[email protected]8ddf8322012-02-23 18:08:0613054 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3613055 ssl.next_proto = kProtoHTTP2;
[email protected]bb88e1d32013-05-03 23:11:0713056 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]749eefa82010-09-13 22:14:0313057
danakj1fd259a02016-04-16 03:17:0913058 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]749eefa82010-09-13 22:14:0313059
13060 // Set up an initial SpdySession in the pool to reuse.
bncce36dca22015-04-21 22:11:2313061 HostPortPair host_port_pair("www.example.org", 443);
[email protected]e6d017652013-05-17 18:01:4013062 SpdySessionKey key(host_port_pair, ProxyServer::Direct(),
[email protected]314b03992014-04-01 01:28:5313063 PRIVACY_MODE_DISABLED);
[email protected]795cbf82013-07-22 09:37:2713064 base::WeakPtr<SpdySession> spdy_session =
bnc032658ba2016-09-26 18:17:1513065 CreateSecureSpdySession(session.get(), key, NetLogWithSource());
[email protected]749eefa82010-09-13 22:14:0313066
13067 HttpRequestInfo request;
13068 request.method = "GET";
bncce36dca22015-04-21 22:11:2313069 request.url = GURL("https://www.example.org/");
[email protected]749eefa82010-09-13 22:14:0313070
13071 // This is the important line that marks this as a preconnect.
13072 request.motivation = HttpRequestInfo::PRECONNECT_MOTIVATED;
13073
bnc691fda62016-08-12 00:43:1613074 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]749eefa82010-09-13 22:14:0313075
[email protected]41d64e82013-07-03 22:44:2613076 TestCompletionCallback callback;
tfarina42834112016-09-22 13:38:2013077 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0113078 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
13079 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]749eefa82010-09-13 22:14:0313080}
13081
[email protected]73b8dd222010-11-11 19:55:2413082// Given a net error, cause that error to be returned from the first Write()
bnc691fda62016-08-12 00:43:1613083// call and verify that the HttpNetworkTransaction fails with that error.
[email protected]23e482282013-06-14 16:08:0213084void HttpNetworkTransactionTest::CheckErrorIsPassedBack(
[email protected]bb88e1d32013-05-03 23:11:0713085 int error, IoMode mode) {
ttuttle859dc7a2015-04-23 19:42:2913086 HttpRequestInfo request_info;
[email protected]cb9bf6ca2011-01-28 13:15:2713087 request_info.url = GURL("https://www.example.com/");
13088 request_info.method = "GET";
ttuttle859dc7a2015-04-23 19:42:2913089 request_info.load_flags = LOAD_NORMAL;
[email protected]cb9bf6ca2011-01-28 13:15:2713090
[email protected]8ddf8322012-02-23 18:08:0613091 SSLSocketDataProvider ssl_data(mode, OK);
ttuttle859dc7a2015-04-23 19:42:2913092 MockWrite data_writes[] = {
13093 MockWrite(mode, error),
[email protected]73b8dd222010-11-11 19:55:2413094 };
ttuttle859dc7a2015-04-23 19:42:2913095 StaticSocketDataProvider data(NULL, 0, data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:0713096 session_deps_.socket_factory->AddSocketDataProvider(&data);
13097 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data);
[email protected]73b8dd222010-11-11 19:55:2413098
danakj1fd259a02016-04-16 03:17:0913099 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1613100 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]73b8dd222010-11-11 19:55:2413101
[email protected]49639fa2011-12-20 23:22:4113102 TestCompletionCallback callback;
tfarina42834112016-09-22 13:38:2013103 int rv = trans.Start(&request_info, callback.callback(), NetLogWithSource());
ttuttle859dc7a2015-04-23 19:42:2913104 if (rv == ERR_IO_PENDING)
[email protected]73b8dd222010-11-11 19:55:2413105 rv = callback.WaitForResult();
13106 ASSERT_EQ(error, rv);
13107}
13108
bncd16676a2016-07-20 16:23:0113109TEST_F(HttpNetworkTransactionTest, SSLWriteCertError) {
[email protected]73b8dd222010-11-11 19:55:2413110 // Just check a grab bag of cert errors.
13111 static const int kErrors[] = {
13112 ERR_CERT_COMMON_NAME_INVALID,
13113 ERR_CERT_AUTHORITY_INVALID,
13114 ERR_CERT_DATE_INVALID,
13115 };
13116 for (size_t i = 0; i < arraysize(kErrors); i++) {
[email protected]8ddf8322012-02-23 18:08:0613117 CheckErrorIsPassedBack(kErrors[i], ASYNC);
13118 CheckErrorIsPassedBack(kErrors[i], SYNCHRONOUS);
[email protected]73b8dd222010-11-11 19:55:2413119 }
13120}
13121
[email protected]bd0b6772011-01-11 19:59:3013122// Ensure that a client certificate is removed from the SSL client auth
13123// cache when:
13124// 1) No proxy is involved.
13125// 2) TLS False Start is disabled.
13126// 3) The initial TLS handshake requests a client certificate.
13127// 4) The client supplies an invalid/unacceptable certificate.
bncd16676a2016-07-20 16:23:0113128TEST_F(HttpNetworkTransactionTest, ClientAuthCertCache_Direct_NoFalseStart) {
ttuttle859dc7a2015-04-23 19:42:2913129 HttpRequestInfo request_info;
[email protected]cb9bf6ca2011-01-28 13:15:2713130 request_info.url = GURL("https://www.example.com/");
13131 request_info.method = "GET";
ttuttle859dc7a2015-04-23 19:42:2913132 request_info.load_flags = LOAD_NORMAL;
[email protected]cb9bf6ca2011-01-28 13:15:2713133
[email protected]bd0b6772011-01-11 19:59:3013134 scoped_refptr<SSLCertRequestInfo> cert_request(new SSLCertRequestInfo());
[email protected]791879c2013-12-17 07:22:4113135 cert_request->host_and_port = HostPortPair("www.example.com", 443);
[email protected]bd0b6772011-01-11 19:59:3013136
13137 // [ssl_]data1 contains the data for the first SSL handshake. When a
13138 // CertificateRequest is received for the first time, the handshake will
13139 // be aborted to allow the caller to provide a certificate.
ttuttle859dc7a2015-04-23 19:42:2913140 SSLSocketDataProvider ssl_data1(ASYNC, ERR_SSL_CLIENT_AUTH_CERT_NEEDED);
[email protected]bd0b6772011-01-11 19:59:3013141 ssl_data1.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0713142 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data1);
ttuttle859dc7a2015-04-23 19:42:2913143 StaticSocketDataProvider data1(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0713144 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]bd0b6772011-01-11 19:59:3013145
13146 // [ssl_]data2 contains the data for the second SSL handshake. When TLS
13147 // False Start is not being used, the result of the SSL handshake will be
13148 // returned as part of the SSLClientSocket::Connect() call. This test
13149 // matches the result of a server sending a handshake_failure alert,
13150 // rather than a Finished message, because it requires a client
13151 // certificate and none was supplied.
ttuttle859dc7a2015-04-23 19:42:2913152 SSLSocketDataProvider ssl_data2(ASYNC, ERR_SSL_PROTOCOL_ERROR);
[email protected]bd0b6772011-01-11 19:59:3013153 ssl_data2.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0713154 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data2);
ttuttle859dc7a2015-04-23 19:42:2913155 StaticSocketDataProvider data2(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0713156 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]bd0b6772011-01-11 19:59:3013157
13158 // [ssl_]data3 contains the data for the third SSL handshake. When a
13159 // connection to a server fails during an SSL handshake,
davidbenb937d6c2015-05-14 04:53:4213160 // HttpNetworkTransaction will attempt to fallback to TLSv1.1 if the previous
13161 // connection was attempted with TLSv1.2. This is transparent to the caller
[email protected]bd0b6772011-01-11 19:59:3013162 // of the HttpNetworkTransaction. Because this test failure is due to
13163 // requiring a client certificate, this fallback handshake should also
13164 // fail.
ttuttle859dc7a2015-04-23 19:42:2913165 SSLSocketDataProvider ssl_data3(ASYNC, ERR_SSL_PROTOCOL_ERROR);
[email protected]bd0b6772011-01-11 19:59:3013166 ssl_data3.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0713167 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data3);
ttuttle859dc7a2015-04-23 19:42:2913168 StaticSocketDataProvider data3(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0713169 session_deps_.socket_factory->AddSocketDataProvider(&data3);
[email protected]bd0b6772011-01-11 19:59:3013170
[email protected]80c75f682012-05-26 16:22:1713171 // [ssl_]data4 contains the data for the fourth SSL handshake. When a
13172 // connection to a server fails during an SSL handshake,
davidbenb937d6c2015-05-14 04:53:4213173 // HttpNetworkTransaction will attempt to fallback to TLSv1 if the previous
13174 // connection was attempted with TLSv1.1. This is transparent to the caller
[email protected]80c75f682012-05-26 16:22:1713175 // of the HttpNetworkTransaction. Because this test failure is due to
13176 // requiring a client certificate, this fallback handshake should also
13177 // fail.
ttuttle859dc7a2015-04-23 19:42:2913178 SSLSocketDataProvider ssl_data4(ASYNC, ERR_SSL_PROTOCOL_ERROR);
[email protected]80c75f682012-05-26 16:22:1713179 ssl_data4.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0713180 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data4);
ttuttle859dc7a2015-04-23 19:42:2913181 StaticSocketDataProvider data4(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0713182 session_deps_.socket_factory->AddSocketDataProvider(&data4);
[email protected]80c75f682012-05-26 16:22:1713183
danakj1fd259a02016-04-16 03:17:0913184 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1613185 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]bd0b6772011-01-11 19:59:3013186
[email protected]bd0b6772011-01-11 19:59:3013187 // Begin the SSL handshake with the peer. This consumes ssl_data1.
[email protected]49639fa2011-12-20 23:22:4113188 TestCompletionCallback callback;
tfarina42834112016-09-22 13:38:2013189 int rv = trans.Start(&request_info, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0113190 ASSERT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]bd0b6772011-01-11 19:59:3013191
13192 // Complete the SSL handshake, which should abort due to requiring a
13193 // client certificate.
13194 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0113195 ASSERT_THAT(rv, IsError(ERR_SSL_CLIENT_AUTH_CERT_NEEDED));
[email protected]bd0b6772011-01-11 19:59:3013196
13197 // Indicate that no certificate should be supplied. From the perspective
13198 // of SSLClientCertCache, NULL is just as meaningful as a real
13199 // certificate, so this is the same as supply a
13200 // legitimate-but-unacceptable certificate.
bnc691fda62016-08-12 00:43:1613201 rv = trans.RestartWithCertificate(NULL, NULL, callback.callback());
robpercival214763f2016-07-01 23:27:0113202 ASSERT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]bd0b6772011-01-11 19:59:3013203
13204 // Ensure the certificate was added to the client auth cache before
13205 // allowing the connection to continue restarting.
13206 scoped_refptr<X509Certificate> client_cert;
svaldez7872fd02015-11-19 21:10:5413207 scoped_refptr<SSLPrivateKey> client_private_key;
[email protected]791879c2013-12-17 07:22:4113208 ASSERT_TRUE(session->ssl_client_auth_cache()->Lookup(
svaldez7872fd02015-11-19 21:10:5413209 HostPortPair("www.example.com", 443), &client_cert, &client_private_key));
wezca1070932016-05-26 20:30:5213210 ASSERT_FALSE(client_cert);
[email protected]bd0b6772011-01-11 19:59:3013211
13212 // Restart the handshake. This will consume ssl_data2, which fails, and
[email protected]80c75f682012-05-26 16:22:1713213 // then consume ssl_data3 and ssl_data4, both of which should also fail.
13214 // The result code is checked against what ssl_data4 should return.
[email protected]bd0b6772011-01-11 19:59:3013215 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0113216 ASSERT_THAT(rv, IsError(ERR_SSL_PROTOCOL_ERROR));
[email protected]bd0b6772011-01-11 19:59:3013217
13218 // Ensure that the client certificate is removed from the cache on a
13219 // handshake failure.
[email protected]791879c2013-12-17 07:22:4113220 ASSERT_FALSE(session->ssl_client_auth_cache()->Lookup(
svaldez7872fd02015-11-19 21:10:5413221 HostPortPair("www.example.com", 443), &client_cert, &client_private_key));
[email protected]bd0b6772011-01-11 19:59:3013222}
13223
13224// Ensure that a client certificate is removed from the SSL client auth
13225// cache when:
13226// 1) No proxy is involved.
13227// 2) TLS False Start is enabled.
13228// 3) The initial TLS handshake requests a client certificate.
13229// 4) The client supplies an invalid/unacceptable certificate.
bncd16676a2016-07-20 16:23:0113230TEST_F(HttpNetworkTransactionTest, ClientAuthCertCache_Direct_FalseStart) {
ttuttle859dc7a2015-04-23 19:42:2913231 HttpRequestInfo request_info;
[email protected]cb9bf6ca2011-01-28 13:15:2713232 request_info.url = GURL("https://www.example.com/");
13233 request_info.method = "GET";
ttuttle859dc7a2015-04-23 19:42:2913234 request_info.load_flags = LOAD_NORMAL;
[email protected]cb9bf6ca2011-01-28 13:15:2713235
[email protected]bd0b6772011-01-11 19:59:3013236 scoped_refptr<SSLCertRequestInfo> cert_request(new SSLCertRequestInfo());
[email protected]791879c2013-12-17 07:22:4113237 cert_request->host_and_port = HostPortPair("www.example.com", 443);
[email protected]bd0b6772011-01-11 19:59:3013238
13239 // When TLS False Start is used, SSLClientSocket::Connect() calls will
13240 // return successfully after reading up to the peer's Certificate message.
13241 // This is to allow the caller to call SSLClientSocket::Write(), which can
13242 // enqueue application data to be sent in the same packet as the
13243 // ChangeCipherSpec and Finished messages.
13244 // The actual handshake will be finished when SSLClientSocket::Read() is
13245 // called, which expects to process the peer's ChangeCipherSpec and
13246 // Finished messages. If there was an error negotiating with the peer,
13247 // such as due to the peer requiring a client certificate when none was
13248 // supplied, the alert sent by the peer won't be processed until Read() is
13249 // called.
13250
13251 // Like the non-False Start case, when a client certificate is requested by
13252 // the peer, the handshake is aborted during the Connect() call.
13253 // [ssl_]data1 represents the initial SSL handshake with the peer.
ttuttle859dc7a2015-04-23 19:42:2913254 SSLSocketDataProvider ssl_data1(ASYNC, ERR_SSL_CLIENT_AUTH_CERT_NEEDED);
[email protected]bd0b6772011-01-11 19:59:3013255 ssl_data1.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0713256 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data1);
ttuttle859dc7a2015-04-23 19:42:2913257 StaticSocketDataProvider data1(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0713258 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]bd0b6772011-01-11 19:59:3013259
13260 // When a client certificate is supplied, Connect() will not be aborted
13261 // when the peer requests the certificate. Instead, the handshake will
13262 // artificially succeed, allowing the caller to write the HTTP request to
13263 // the socket. The handshake messages are not processed until Read() is
13264 // called, which then detects that the handshake was aborted, due to the
13265 // peer sending a handshake_failure because it requires a client
13266 // certificate.
ttuttle859dc7a2015-04-23 19:42:2913267 SSLSocketDataProvider ssl_data2(ASYNC, OK);
[email protected]bd0b6772011-01-11 19:59:3013268 ssl_data2.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0713269 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data2);
ttuttle859dc7a2015-04-23 19:42:2913270 MockRead data2_reads[] = {
13271 MockRead(ASYNC /* async */, ERR_SSL_PROTOCOL_ERROR),
[email protected]bd0b6772011-01-11 19:59:3013272 };
ttuttle859dc7a2015-04-23 19:42:2913273 StaticSocketDataProvider data2(data2_reads, arraysize(data2_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0713274 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]bd0b6772011-01-11 19:59:3013275
13276 // As described in ClientAuthCertCache_Direct_NoFalseStart, [ssl_]data3 is
[email protected]80c75f682012-05-26 16:22:1713277 // the data for the SSL handshake once the TLSv1.1 connection falls back to
13278 // TLSv1. It has the same behaviour as [ssl_]data2.
ttuttle859dc7a2015-04-23 19:42:2913279 SSLSocketDataProvider ssl_data3(ASYNC, OK);
[email protected]bd0b6772011-01-11 19:59:3013280 ssl_data3.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0713281 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data3);
ttuttle859dc7a2015-04-23 19:42:2913282 StaticSocketDataProvider data3(data2_reads, arraysize(data2_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0713283 session_deps_.socket_factory->AddSocketDataProvider(&data3);
[email protected]bd0b6772011-01-11 19:59:3013284
[email protected]80c75f682012-05-26 16:22:1713285 // [ssl_]data4 is the data for the SSL handshake once the TLSv1 connection
13286 // falls back to SSLv3. It has the same behaviour as [ssl_]data2.
ttuttle859dc7a2015-04-23 19:42:2913287 SSLSocketDataProvider ssl_data4(ASYNC, OK);
[email protected]80c75f682012-05-26 16:22:1713288 ssl_data4.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0713289 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data4);
ttuttle859dc7a2015-04-23 19:42:2913290 StaticSocketDataProvider data4(data2_reads, arraysize(data2_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0713291 session_deps_.socket_factory->AddSocketDataProvider(&data4);
[email protected]80c75f682012-05-26 16:22:1713292
[email protected]7799de12013-05-30 05:52:5113293 // Need one more if TLSv1.2 is enabled.
ttuttle859dc7a2015-04-23 19:42:2913294 SSLSocketDataProvider ssl_data5(ASYNC, OK);
[email protected]7799de12013-05-30 05:52:5113295 ssl_data5.cert_request_info = cert_request.get();
13296 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data5);
ttuttle859dc7a2015-04-23 19:42:2913297 StaticSocketDataProvider data5(data2_reads, arraysize(data2_reads), NULL, 0);
[email protected]7799de12013-05-30 05:52:5113298 session_deps_.socket_factory->AddSocketDataProvider(&data5);
13299
danakj1fd259a02016-04-16 03:17:0913300 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1613301 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]bd0b6772011-01-11 19:59:3013302
[email protected]bd0b6772011-01-11 19:59:3013303 // Begin the initial SSL handshake.
[email protected]49639fa2011-12-20 23:22:4113304 TestCompletionCallback callback;
tfarina42834112016-09-22 13:38:2013305 int rv = trans.Start(&request_info, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0113306 ASSERT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]bd0b6772011-01-11 19:59:3013307
13308 // Complete the SSL handshake, which should abort due to requiring a
13309 // client certificate.
13310 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0113311 ASSERT_THAT(rv, IsError(ERR_SSL_CLIENT_AUTH_CERT_NEEDED));
[email protected]bd0b6772011-01-11 19:59:3013312
13313 // Indicate that no certificate should be supplied. From the perspective
13314 // of SSLClientCertCache, NULL is just as meaningful as a real
13315 // certificate, so this is the same as supply a
13316 // legitimate-but-unacceptable certificate.
bnc691fda62016-08-12 00:43:1613317 rv = trans.RestartWithCertificate(NULL, NULL, callback.callback());
robpercival214763f2016-07-01 23:27:0113318 ASSERT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]bd0b6772011-01-11 19:59:3013319
13320 // Ensure the certificate was added to the client auth cache before
13321 // allowing the connection to continue restarting.
13322 scoped_refptr<X509Certificate> client_cert;
svaldez7872fd02015-11-19 21:10:5413323 scoped_refptr<SSLPrivateKey> client_private_key;
[email protected]791879c2013-12-17 07:22:4113324 ASSERT_TRUE(session->ssl_client_auth_cache()->Lookup(
svaldez7872fd02015-11-19 21:10:5413325 HostPortPair("www.example.com", 443), &client_cert, &client_private_key));
wezca1070932016-05-26 20:30:5213326 ASSERT_FALSE(client_cert);
[email protected]bd0b6772011-01-11 19:59:3013327
[email protected]bd0b6772011-01-11 19:59:3013328 // Restart the handshake. This will consume ssl_data2, which fails, and
[email protected]80c75f682012-05-26 16:22:1713329 // then consume ssl_data3 and ssl_data4, both of which should also fail.
13330 // The result code is checked against what ssl_data4 should return.
[email protected]bd0b6772011-01-11 19:59:3013331 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0113332 ASSERT_THAT(rv, IsError(ERR_SSL_PROTOCOL_ERROR));
[email protected]bd0b6772011-01-11 19:59:3013333
13334 // Ensure that the client certificate is removed from the cache on a
13335 // handshake failure.
[email protected]791879c2013-12-17 07:22:4113336 ASSERT_FALSE(session->ssl_client_auth_cache()->Lookup(
svaldez7872fd02015-11-19 21:10:5413337 HostPortPair("www.example.com", 443), &client_cert, &client_private_key));
[email protected]bd0b6772011-01-11 19:59:3013338}
13339
[email protected]8c405132011-01-11 22:03:1813340// Ensure that a client certificate is removed from the SSL client auth
13341// cache when:
13342// 1) An HTTPS proxy is involved.
13343// 3) The HTTPS proxy requests a client certificate.
13344// 4) The client supplies an invalid/unacceptable certificate for the
13345// proxy.
13346// The test is repeated twice, first for connecting to an HTTPS endpoint,
13347// then for connecting to an HTTP endpoint.
bncd16676a2016-07-20 16:23:0113348TEST_F(HttpNetworkTransactionTest, ClientAuthCertCache_Proxy_Fail) {
rdsmith82957ad2015-09-16 19:42:0313349 session_deps_.proxy_service = ProxyService::CreateFixed("https://proxy:70");
vishal.b62985ca92015-04-17 08:45:5113350 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:0713351 session_deps_.net_log = log.bound().net_log();
[email protected]8c405132011-01-11 22:03:1813352
13353 scoped_refptr<SSLCertRequestInfo> cert_request(new SSLCertRequestInfo());
[email protected]791879c2013-12-17 07:22:4113354 cert_request->host_and_port = HostPortPair("proxy", 70);
[email protected]8c405132011-01-11 22:03:1813355
13356 // See ClientAuthCertCache_Direct_NoFalseStart for the explanation of
13357 // [ssl_]data[1-3]. Rather than represending the endpoint
13358 // (www.example.com:443), they represent failures with the HTTPS proxy
13359 // (proxy:70).
ttuttle859dc7a2015-04-23 19:42:2913360 SSLSocketDataProvider ssl_data1(ASYNC, ERR_SSL_CLIENT_AUTH_CERT_NEEDED);
[email protected]8c405132011-01-11 22:03:1813361 ssl_data1.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0713362 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data1);
ttuttle859dc7a2015-04-23 19:42:2913363 StaticSocketDataProvider data1(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0713364 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8c405132011-01-11 22:03:1813365
ttuttle859dc7a2015-04-23 19:42:2913366 SSLSocketDataProvider ssl_data2(ASYNC, ERR_SSL_PROTOCOL_ERROR);
[email protected]8c405132011-01-11 22:03:1813367 ssl_data2.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0713368 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data2);
ttuttle859dc7a2015-04-23 19:42:2913369 StaticSocketDataProvider data2(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0713370 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]8c405132011-01-11 22:03:1813371
[email protected]80c75f682012-05-26 16:22:1713372 // TODO(wtc): find out why this unit test doesn't need [ssl_]data3.
13373#if 0
ttuttle859dc7a2015-04-23 19:42:2913374 SSLSocketDataProvider ssl_data3(ASYNC, ERR_SSL_PROTOCOL_ERROR);
[email protected]8c405132011-01-11 22:03:1813375 ssl_data3.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0713376 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data3);
ttuttle859dc7a2015-04-23 19:42:2913377 StaticSocketDataProvider data3(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0713378 session_deps_.socket_factory->AddSocketDataProvider(&data3);
[email protected]80c75f682012-05-26 16:22:1713379#endif
[email protected]8c405132011-01-11 22:03:1813380
ttuttle859dc7a2015-04-23 19:42:2913381 HttpRequestInfo requests[2];
[email protected]8c405132011-01-11 22:03:1813382 requests[0].url = GURL("https://www.example.com/");
13383 requests[0].method = "GET";
ttuttle859dc7a2015-04-23 19:42:2913384 requests[0].load_flags = LOAD_NORMAL;
[email protected]8c405132011-01-11 22:03:1813385
13386 requests[1].url = GURL("http://www.example.com/");
13387 requests[1].method = "GET";
ttuttle859dc7a2015-04-23 19:42:2913388 requests[1].load_flags = LOAD_NORMAL;
[email protected]8c405132011-01-11 22:03:1813389
13390 for (size_t i = 0; i < arraysize(requests); ++i) {
[email protected]bb88e1d32013-05-03 23:11:0713391 session_deps_.socket_factory->ResetNextMockIndexes();
danakj1fd259a02016-04-16 03:17:0913392 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1613393 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]8c405132011-01-11 22:03:1813394
13395 // Begin the SSL handshake with the proxy.
[email protected]49639fa2011-12-20 23:22:4113396 TestCompletionCallback callback;
tfarina42834112016-09-22 13:38:2013397 int rv = trans.Start(&requests[i], callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0113398 ASSERT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]8c405132011-01-11 22:03:1813399
13400 // Complete the SSL handshake, which should abort due to requiring a
13401 // client certificate.
13402 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0113403 ASSERT_THAT(rv, IsError(ERR_SSL_CLIENT_AUTH_CERT_NEEDED));
[email protected]8c405132011-01-11 22:03:1813404
13405 // Indicate that no certificate should be supplied. From the perspective
13406 // of SSLClientCertCache, NULL is just as meaningful as a real
13407 // certificate, so this is the same as supply a
13408 // legitimate-but-unacceptable certificate.
bnc691fda62016-08-12 00:43:1613409 rv = trans.RestartWithCertificate(NULL, NULL, callback.callback());
robpercival214763f2016-07-01 23:27:0113410 ASSERT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]8c405132011-01-11 22:03:1813411
13412 // Ensure the certificate was added to the client auth cache before
13413 // allowing the connection to continue restarting.
13414 scoped_refptr<X509Certificate> client_cert;
svaldez7872fd02015-11-19 21:10:5413415 scoped_refptr<SSLPrivateKey> client_private_key;
[email protected]791879c2013-12-17 07:22:4113416 ASSERT_TRUE(session->ssl_client_auth_cache()->Lookup(
svaldez7872fd02015-11-19 21:10:5413417 HostPortPair("proxy", 70), &client_cert, &client_private_key));
wezca1070932016-05-26 20:30:5213418 ASSERT_FALSE(client_cert);
[email protected]8c405132011-01-11 22:03:1813419 // Ensure the certificate was NOT cached for the endpoint. This only
13420 // applies to HTTPS requests, but is fine to check for HTTP requests.
[email protected]791879c2013-12-17 07:22:4113421 ASSERT_FALSE(session->ssl_client_auth_cache()->Lookup(
svaldez7872fd02015-11-19 21:10:5413422 HostPortPair("www.example.com", 443), &client_cert,
13423 &client_private_key));
[email protected]8c405132011-01-11 22:03:1813424
13425 // Restart the handshake. This will consume ssl_data2, which fails, and
13426 // then consume ssl_data3, which should also fail. The result code is
13427 // checked against what ssl_data3 should return.
13428 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0113429 ASSERT_THAT(rv, IsError(ERR_PROXY_CONNECTION_FAILED));
[email protected]8c405132011-01-11 22:03:1813430
13431 // Now that the new handshake has failed, ensure that the client
13432 // certificate was removed from the client auth cache.
[email protected]791879c2013-12-17 07:22:4113433 ASSERT_FALSE(session->ssl_client_auth_cache()->Lookup(
svaldez7872fd02015-11-19 21:10:5413434 HostPortPair("proxy", 70), &client_cert, &client_private_key));
[email protected]791879c2013-12-17 07:22:4113435 ASSERT_FALSE(session->ssl_client_auth_cache()->Lookup(
svaldez7872fd02015-11-19 21:10:5413436 HostPortPair("www.example.com", 443), &client_cert,
13437 &client_private_key));
[email protected]8c405132011-01-11 22:03:1813438 }
13439}
13440
bncd16676a2016-07-20 16:23:0113441TEST_F(HttpNetworkTransactionTest, UseIPConnectionPooling) {
[email protected]e3ceb682011-06-28 23:55:4613442 // Set up a special HttpNetworkSession with a MockCachingHostResolver.
[email protected]bb88e1d32013-05-03 23:11:0713443 session_deps_.host_resolver.reset(new MockCachingHostResolver());
danakj1fd259a02016-04-16 03:17:0913444 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]e3ceb682011-06-28 23:55:4613445
bnc032658ba2016-09-26 18:17:1513446 AddSSLSocketData();
[email protected]e3ceb682011-06-28 23:55:4613447
bncdf80d44fd2016-07-15 20:27:4113448 SpdySerializedFrame host1_req(
bnc38dcd392016-02-09 23:19:4913449 spdy_util_.ConstructSpdyGet("https://www.example.org", 1, LOWEST));
rdsmithebb50aa2015-11-12 03:44:3813450 spdy_util_.UpdateWithStreamDestruction(1);
bncdf80d44fd2016-07-15 20:27:4113451 SpdySerializedFrame host2_req(
bnca4d611d2016-09-22 19:55:3713452 spdy_util_.ConstructSpdyGet("https://mail.example.com", 3, LOWEST));
[email protected]e3ceb682011-06-28 23:55:4613453 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:4113454 CreateMockWrite(host1_req, 0), CreateMockWrite(host2_req, 3),
[email protected]e3ceb682011-06-28 23:55:4613455 };
bnc42331402016-07-25 13:36:1513456 SpdySerializedFrame host1_resp(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
bncdf80d44fd2016-07-15 20:27:4113457 SpdySerializedFrame host1_resp_body(
13458 spdy_util_.ConstructSpdyDataFrame(1, true));
bnc42331402016-07-25 13:36:1513459 SpdySerializedFrame host2_resp(spdy_util_.ConstructSpdyGetReply(NULL, 0, 3));
bncdf80d44fd2016-07-15 20:27:4113460 SpdySerializedFrame host2_resp_body(
13461 spdy_util_.ConstructSpdyDataFrame(3, true));
[email protected]e3ceb682011-06-28 23:55:4613462 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:4113463 CreateMockRead(host1_resp, 1), CreateMockRead(host1_resp_body, 2),
13464 CreateMockRead(host2_resp, 4), CreateMockRead(host2_resp_body, 5),
rch8e6c6c42015-05-01 14:05:1313465 MockRead(ASYNC, 0, 6),
[email protected]e3ceb682011-06-28 23:55:4613466 };
13467
eroman36d84e54432016-03-17 03:23:0213468 IPEndPoint peer_addr(IPAddress::IPv4Localhost(), 443);
[email protected]d2b5f092012-06-08 23:55:0213469 MockConnect connect(ASYNC, OK, peer_addr);
rch8e6c6c42015-05-01 14:05:1313470 SequencedSocketData spdy_data(connect, spdy_reads, arraysize(spdy_reads),
13471 spdy_writes, arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:0713472 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]e3ceb682011-06-28 23:55:4613473
[email protected]aa22b242011-11-16 18:58:2913474 TestCompletionCallback callback;
[email protected]e3ceb682011-06-28 23:55:4613475 HttpRequestInfo request1;
13476 request1.method = "GET";
bncce36dca22015-04-21 22:11:2313477 request1.url = GURL("https://www.example.org/");
[email protected]e3ceb682011-06-28 23:55:4613478 request1.load_flags = 0;
[email protected]90499482013-06-01 00:39:5013479 HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
[email protected]e3ceb682011-06-28 23:55:4613480
tfarina42834112016-09-22 13:38:2013481 int rv = trans1.Start(&request1, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0113482 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
13483 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]e3ceb682011-06-28 23:55:4613484
13485 const HttpResponseInfo* response = trans1.GetResponseInfo();
wezca1070932016-05-26 20:30:5213486 ASSERT_TRUE(response);
13487 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0213488 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]e3ceb682011-06-28 23:55:4613489
13490 std::string response_data;
robpercival214763f2016-07-01 23:27:0113491 ASSERT_THAT(ReadTransaction(&trans1, &response_data), IsOk());
[email protected]e3ceb682011-06-28 23:55:4613492 EXPECT_EQ("hello!", response_data);
13493
bnca4d611d2016-09-22 19:55:3713494 // Preload mail.example.com into HostCache.
13495 HostPortPair host_port("mail.example.com", 443);
[email protected]5109c1952013-08-20 18:44:1013496 HostResolver::RequestInfo resolve_info(host_port);
[email protected]e3ceb682011-06-28 23:55:4613497 AddressList ignored;
maksim.sisov31452af2016-07-27 06:38:1013498 std::unique_ptr<HostResolver::Request> request;
13499 rv = session_deps_.host_resolver->Resolve(resolve_info, DEFAULT_PRIORITY,
13500 &ignored, callback.callback(),
tfarina42834112016-09-22 13:38:2013501 &request, NetLogWithSource());
robpercival214763f2016-07-01 23:27:0113502 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]6e78dfb2011-07-28 21:34:4713503 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0113504 EXPECT_THAT(rv, IsOk());
[email protected]e3ceb682011-06-28 23:55:4613505
13506 HttpRequestInfo request2;
13507 request2.method = "GET";
bnca4d611d2016-09-22 19:55:3713508 request2.url = GURL("https://mail.example.com/");
[email protected]e3ceb682011-06-28 23:55:4613509 request2.load_flags = 0;
[email protected]90499482013-06-01 00:39:5013510 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
[email protected]e3ceb682011-06-28 23:55:4613511
tfarina42834112016-09-22 13:38:2013512 rv = trans2.Start(&request2, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0113513 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
13514 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]e3ceb682011-06-28 23:55:4613515
13516 response = trans2.GetResponseInfo();
wezca1070932016-05-26 20:30:5213517 ASSERT_TRUE(response);
13518 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0213519 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]e3ceb682011-06-28 23:55:4613520 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5213521 EXPECT_TRUE(response->was_alpn_negotiated);
robpercival214763f2016-07-01 23:27:0113522 ASSERT_THAT(ReadTransaction(&trans2, &response_data), IsOk());
[email protected]e3ceb682011-06-28 23:55:4613523 EXPECT_EQ("hello!", response_data);
[email protected]e3ceb682011-06-28 23:55:4613524}
13525
bncd16676a2016-07-20 16:23:0113526TEST_F(HttpNetworkTransactionTest, UseIPConnectionPoolingAfterResolution) {
[email protected]d2b5f092012-06-08 23:55:0213527 // Set up a special HttpNetworkSession with a MockCachingHostResolver.
[email protected]bb88e1d32013-05-03 23:11:0713528 session_deps_.host_resolver.reset(new MockCachingHostResolver());
danakj1fd259a02016-04-16 03:17:0913529 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]d2b5f092012-06-08 23:55:0213530
bnc032658ba2016-09-26 18:17:1513531 AddSSLSocketData();
[email protected]d2b5f092012-06-08 23:55:0213532
bncdf80d44fd2016-07-15 20:27:4113533 SpdySerializedFrame host1_req(
bnc38dcd392016-02-09 23:19:4913534 spdy_util_.ConstructSpdyGet("https://www.example.org", 1, LOWEST));
rdsmithebb50aa2015-11-12 03:44:3813535 spdy_util_.UpdateWithStreamDestruction(1);
bncdf80d44fd2016-07-15 20:27:4113536 SpdySerializedFrame host2_req(
bnca4d611d2016-09-22 19:55:3713537 spdy_util_.ConstructSpdyGet("https://mail.example.com", 3, LOWEST));
[email protected]d2b5f092012-06-08 23:55:0213538 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:4113539 CreateMockWrite(host1_req, 0), CreateMockWrite(host2_req, 3),
[email protected]d2b5f092012-06-08 23:55:0213540 };
bnc42331402016-07-25 13:36:1513541 SpdySerializedFrame host1_resp(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
bncdf80d44fd2016-07-15 20:27:4113542 SpdySerializedFrame host1_resp_body(
13543 spdy_util_.ConstructSpdyDataFrame(1, true));
bnc42331402016-07-25 13:36:1513544 SpdySerializedFrame host2_resp(spdy_util_.ConstructSpdyGetReply(NULL, 0, 3));
bncdf80d44fd2016-07-15 20:27:4113545 SpdySerializedFrame host2_resp_body(
13546 spdy_util_.ConstructSpdyDataFrame(3, true));
[email protected]d2b5f092012-06-08 23:55:0213547 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:4113548 CreateMockRead(host1_resp, 1), CreateMockRead(host1_resp_body, 2),
13549 CreateMockRead(host2_resp, 4), CreateMockRead(host2_resp_body, 5),
rch8e6c6c42015-05-01 14:05:1313550 MockRead(ASYNC, 0, 6),
[email protected]d2b5f092012-06-08 23:55:0213551 };
13552
eroman36d84e54432016-03-17 03:23:0213553 IPEndPoint peer_addr(IPAddress::IPv4Localhost(), 443);
[email protected]d2b5f092012-06-08 23:55:0213554 MockConnect connect(ASYNC, OK, peer_addr);
rch8e6c6c42015-05-01 14:05:1313555 SequencedSocketData spdy_data(connect, spdy_reads, arraysize(spdy_reads),
13556 spdy_writes, arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:0713557 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]d2b5f092012-06-08 23:55:0213558
13559 TestCompletionCallback callback;
13560 HttpRequestInfo request1;
13561 request1.method = "GET";
bncce36dca22015-04-21 22:11:2313562 request1.url = GURL("https://www.example.org/");
[email protected]d2b5f092012-06-08 23:55:0213563 request1.load_flags = 0;
[email protected]90499482013-06-01 00:39:5013564 HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
[email protected]d2b5f092012-06-08 23:55:0213565
tfarina42834112016-09-22 13:38:2013566 int rv = trans1.Start(&request1, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0113567 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
13568 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]d2b5f092012-06-08 23:55:0213569
13570 const HttpResponseInfo* response = trans1.GetResponseInfo();
wezca1070932016-05-26 20:30:5213571 ASSERT_TRUE(response);
13572 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0213573 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]d2b5f092012-06-08 23:55:0213574
13575 std::string response_data;
robpercival214763f2016-07-01 23:27:0113576 ASSERT_THAT(ReadTransaction(&trans1, &response_data), IsOk());
[email protected]d2b5f092012-06-08 23:55:0213577 EXPECT_EQ("hello!", response_data);
13578
13579 HttpRequestInfo request2;
13580 request2.method = "GET";
bnca4d611d2016-09-22 19:55:3713581 request2.url = GURL("https://mail.example.com/");
[email protected]d2b5f092012-06-08 23:55:0213582 request2.load_flags = 0;
[email protected]90499482013-06-01 00:39:5013583 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
[email protected]d2b5f092012-06-08 23:55:0213584
tfarina42834112016-09-22 13:38:2013585 rv = trans2.Start(&request2, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0113586 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
13587 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]d2b5f092012-06-08 23:55:0213588
13589 response = trans2.GetResponseInfo();
wezca1070932016-05-26 20:30:5213590 ASSERT_TRUE(response);
13591 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0213592 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]d2b5f092012-06-08 23:55:0213593 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5213594 EXPECT_TRUE(response->was_alpn_negotiated);
robpercival214763f2016-07-01 23:27:0113595 ASSERT_THAT(ReadTransaction(&trans2, &response_data), IsOk());
[email protected]d2b5f092012-06-08 23:55:0213596 EXPECT_EQ("hello!", response_data);
[email protected]d2b5f092012-06-08 23:55:0213597}
13598
bnc8016c1f2017-03-31 02:11:2913599// Regression test for https://crbug.com/546991.
13600// The server might not be able to serve an IP pooled request, and might send a
13601// 421 Misdirected Request response status to indicate this.
13602// HttpNetworkTransaction should reset the request and retry without IP pooling.
13603TEST_F(HttpNetworkTransactionTest, RetryWithoutConnectionPooling) {
13604 // Two hosts resolve to the same IP address.
13605 const std::string ip_addr = "1.2.3.4";
13606 IPAddress ip;
13607 ASSERT_TRUE(ip.AssignFromIPLiteral(ip_addr));
13608 IPEndPoint peer_addr = IPEndPoint(ip, 443);
13609
13610 session_deps_.host_resolver.reset(new MockCachingHostResolver());
13611 session_deps_.host_resolver->rules()->AddRule("www.example.org", ip_addr);
13612 session_deps_.host_resolver->rules()->AddRule("mail.example.org", ip_addr);
13613
13614 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
13615
13616 // Two requests on the first connection.
13617 SpdySerializedFrame req1(
13618 spdy_util_.ConstructSpdyGet("https://www.example.org", 1, LOWEST));
13619 spdy_util_.UpdateWithStreamDestruction(1);
13620 SpdySerializedFrame req2(
13621 spdy_util_.ConstructSpdyGet("https://mail.example.org", 3, LOWEST));
13622 SpdySerializedFrame rst(
13623 spdy_util_.ConstructSpdyRstStream(3, ERROR_CODE_CANCEL));
13624 MockWrite writes1[] = {
13625 CreateMockWrite(req1, 0), CreateMockWrite(req2, 3),
13626 CreateMockWrite(rst, 6),
13627 };
13628
13629 // The first one succeeds, the second gets error 421 Misdirected Request.
13630 SpdySerializedFrame resp1(spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
13631 SpdySerializedFrame body1(spdy_util_.ConstructSpdyDataFrame(1, true));
13632 SpdyHeaderBlock response_headers;
13633 response_headers[SpdyTestUtil::GetStatusKey()] = "421";
13634 SpdySerializedFrame resp2(
13635 spdy_util_.ConstructSpdyReply(3, std::move(response_headers)));
13636 MockRead reads1[] = {CreateMockRead(resp1, 1), CreateMockRead(body1, 2),
13637 CreateMockRead(resp2, 4), MockRead(ASYNC, 0, 5)};
13638
13639 MockConnect connect1(ASYNC, OK, peer_addr);
13640 SequencedSocketData data1(connect1, reads1, arraysize(reads1), writes1,
13641 arraysize(writes1));
13642 session_deps_.socket_factory->AddSocketDataProvider(&data1);
13643
13644 AddSSLSocketData();
13645
13646 // Retry the second request on a second connection.
13647 SpdyTestUtil spdy_util2;
13648 SpdySerializedFrame req3(
13649 spdy_util2.ConstructSpdyGet("https://mail.example.org", 1, LOWEST));
13650 MockWrite writes2[] = {
13651 CreateMockWrite(req3, 0),
13652 };
13653
13654 SpdySerializedFrame resp3(spdy_util2.ConstructSpdyGetReply(nullptr, 0, 1));
13655 SpdySerializedFrame body3(spdy_util2.ConstructSpdyDataFrame(1, true));
13656 MockRead reads2[] = {CreateMockRead(resp3, 1), CreateMockRead(body3, 2),
13657 MockRead(ASYNC, 0, 3)};
13658
13659 MockConnect connect2(ASYNC, OK, peer_addr);
13660 SequencedSocketData data2(connect2, reads2, arraysize(reads2), writes2,
13661 arraysize(writes2));
13662 session_deps_.socket_factory->AddSocketDataProvider(&data2);
13663
13664 AddSSLSocketData();
13665
13666 // Preload mail.example.org into HostCache.
13667 HostPortPair host_port("mail.example.org", 443);
13668 HostResolver::RequestInfo resolve_info(host_port);
13669 AddressList ignored;
13670 std::unique_ptr<HostResolver::Request> request;
13671 TestCompletionCallback callback;
13672 int rv = session_deps_.host_resolver->Resolve(resolve_info, DEFAULT_PRIORITY,
13673 &ignored, callback.callback(),
13674 &request, NetLogWithSource());
13675 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
13676 rv = callback.WaitForResult();
13677 EXPECT_THAT(rv, IsOk());
13678
13679 HttpRequestInfo request1;
13680 request1.method = "GET";
13681 request1.url = GURL("https://www.example.org/");
13682 request1.load_flags = 0;
13683 HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
13684
13685 rv = trans1.Start(&request1, callback.callback(), NetLogWithSource());
13686 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
13687 rv = callback.WaitForResult();
13688 EXPECT_THAT(rv, IsOk());
13689
13690 const HttpResponseInfo* response = trans1.GetResponseInfo();
13691 ASSERT_TRUE(response);
13692 ASSERT_TRUE(response->headers);
13693 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
13694 EXPECT_TRUE(response->was_fetched_via_spdy);
13695 EXPECT_TRUE(response->was_alpn_negotiated);
13696 std::string response_data;
13697 ASSERT_THAT(ReadTransaction(&trans1, &response_data), IsOk());
13698 EXPECT_EQ("hello!", response_data);
13699
13700 HttpRequestInfo request2;
13701 request2.method = "GET";
13702 request2.url = GURL("https://mail.example.org/");
13703 request2.load_flags = 0;
13704 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
13705
13706 BoundTestNetLog log;
13707 rv = trans2.Start(&request2, callback.callback(), log.bound());
13708 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
13709 rv = callback.WaitForResult();
13710 EXPECT_THAT(rv, IsOk());
13711
13712 response = trans2.GetResponseInfo();
13713 ASSERT_TRUE(response);
13714 ASSERT_TRUE(response->headers);
13715 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
13716 EXPECT_TRUE(response->was_fetched_via_spdy);
13717 EXPECT_TRUE(response->was_alpn_negotiated);
13718 ASSERT_THAT(ReadTransaction(&trans2, &response_data), IsOk());
13719 EXPECT_EQ("hello!", response_data);
13720
13721 TestNetLogEntry::List entries;
13722 log.GetEntries(&entries);
davidbence688ae2017-05-04 15:12:5913723 ExpectLogContainsSomewhere(
13724 entries, 0, NetLogEventType::HTTP_TRANSACTION_RESTART_MISDIRECTED_REQUEST,
bnc8016c1f2017-03-31 02:11:2913725 NetLogEventPhase::NONE);
davidbence688ae2017-05-04 15:12:5913726}
13727
13728// Test that HTTP 421 responses are properly returned to the caller if received
13729// on the retry as well. HttpNetworkTransaction should not infinite loop or lose
13730// portions of the response.
13731TEST_F(HttpNetworkTransactionTest, ReturnHTTP421OnRetry) {
13732 // Two hosts resolve to the same IP address.
13733 const std::string ip_addr = "1.2.3.4";
13734 IPAddress ip;
13735 ASSERT_TRUE(ip.AssignFromIPLiteral(ip_addr));
13736 IPEndPoint peer_addr = IPEndPoint(ip, 443);
13737
13738 session_deps_.host_resolver.reset(new MockCachingHostResolver());
13739 session_deps_.host_resolver->rules()->AddRule("www.example.org", ip_addr);
13740 session_deps_.host_resolver->rules()->AddRule("mail.example.org", ip_addr);
13741
13742 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
13743
13744 // Two requests on the first connection.
13745 SpdySerializedFrame req1(
13746 spdy_util_.ConstructSpdyGet("https://www.example.org", 1, LOWEST));
13747 spdy_util_.UpdateWithStreamDestruction(1);
13748 SpdySerializedFrame req2(
13749 spdy_util_.ConstructSpdyGet("https://mail.example.org", 3, LOWEST));
13750 SpdySerializedFrame rst(
13751 spdy_util_.ConstructSpdyRstStream(3, ERROR_CODE_CANCEL));
13752 MockWrite writes1[] = {
13753 CreateMockWrite(req1, 0), CreateMockWrite(req2, 3),
13754 CreateMockWrite(rst, 6),
13755 };
13756
13757 // The first one succeeds, the second gets error 421 Misdirected Request.
13758 SpdySerializedFrame resp1(spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
13759 SpdySerializedFrame body1(spdy_util_.ConstructSpdyDataFrame(1, true));
13760 SpdyHeaderBlock response_headers;
13761 response_headers[SpdyTestUtil::GetStatusKey()] = "421";
13762 SpdySerializedFrame resp2(
13763 spdy_util_.ConstructSpdyReply(3, response_headers.Clone()));
13764 MockRead reads1[] = {CreateMockRead(resp1, 1), CreateMockRead(body1, 2),
13765 CreateMockRead(resp2, 4), MockRead(ASYNC, 0, 5)};
13766
13767 MockConnect connect1(ASYNC, OK, peer_addr);
13768 SequencedSocketData data1(connect1, reads1, arraysize(reads1), writes1,
13769 arraysize(writes1));
13770 session_deps_.socket_factory->AddSocketDataProvider(&data1);
13771
13772 AddSSLSocketData();
13773
13774 // Retry the second request on a second connection. It returns 421 Misdirected
13775 // Retry again.
13776 SpdyTestUtil spdy_util2;
13777 SpdySerializedFrame req3(
13778 spdy_util2.ConstructSpdyGet("https://mail.example.org", 1, LOWEST));
13779 MockWrite writes2[] = {
13780 CreateMockWrite(req3, 0),
13781 };
13782
13783 SpdySerializedFrame resp3(
13784 spdy_util2.ConstructSpdyReply(1, std::move(response_headers)));
13785 SpdySerializedFrame body3(spdy_util2.ConstructSpdyDataFrame(1, true));
13786 MockRead reads2[] = {CreateMockRead(resp3, 1), CreateMockRead(body3, 2),
13787 MockRead(ASYNC, 0, 3)};
13788
13789 MockConnect connect2(ASYNC, OK, peer_addr);
13790 SequencedSocketData data2(connect2, reads2, arraysize(reads2), writes2,
13791 arraysize(writes2));
13792 session_deps_.socket_factory->AddSocketDataProvider(&data2);
13793
13794 AddSSLSocketData();
13795
13796 // Preload mail.example.org into HostCache.
13797 HostPortPair host_port("mail.example.org", 443);
13798 HostResolver::RequestInfo resolve_info(host_port);
13799 AddressList ignored;
13800 std::unique_ptr<HostResolver::Request> request;
13801 TestCompletionCallback callback;
13802 int rv = session_deps_.host_resolver->Resolve(resolve_info, DEFAULT_PRIORITY,
13803 &ignored, callback.callback(),
13804 &request, NetLogWithSource());
13805 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
13806 rv = callback.WaitForResult();
13807 EXPECT_THAT(rv, IsOk());
13808
13809 HttpRequestInfo request1;
13810 request1.method = "GET";
13811 request1.url = GURL("https://www.example.org/");
13812 request1.load_flags = 0;
13813 HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
13814
13815 rv = trans1.Start(&request1, callback.callback(), NetLogWithSource());
13816 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
13817 rv = callback.WaitForResult();
13818 EXPECT_THAT(rv, IsOk());
13819
13820 const HttpResponseInfo* response = trans1.GetResponseInfo();
13821 ASSERT_TRUE(response);
13822 ASSERT_TRUE(response->headers);
13823 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
13824 EXPECT_TRUE(response->was_fetched_via_spdy);
13825 EXPECT_TRUE(response->was_alpn_negotiated);
13826 std::string response_data;
13827 ASSERT_THAT(ReadTransaction(&trans1, &response_data), IsOk());
13828 EXPECT_EQ("hello!", response_data);
13829
13830 HttpRequestInfo request2;
13831 request2.method = "GET";
13832 request2.url = GURL("https://mail.example.org/");
13833 request2.load_flags = 0;
13834 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
13835
13836 BoundTestNetLog log;
13837 rv = trans2.Start(&request2, callback.callback(), log.bound());
13838 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
13839 rv = callback.WaitForResult();
13840 EXPECT_THAT(rv, IsOk());
13841
13842 // After a retry, the 421 Misdirected Request is reported back up to the
13843 // caller.
13844 response = trans2.GetResponseInfo();
13845 ASSERT_TRUE(response);
13846 ASSERT_TRUE(response->headers);
13847 EXPECT_EQ("HTTP/1.1 421", response->headers->GetStatusLine());
13848 EXPECT_TRUE(response->was_fetched_via_spdy);
13849 EXPECT_TRUE(response->was_alpn_negotiated);
13850 EXPECT_TRUE(response->ssl_info.cert);
13851 ASSERT_THAT(ReadTransaction(&trans2, &response_data), IsOk());
13852 EXPECT_EQ("hello!", response_data);
bnc8016c1f2017-03-31 02:11:2913853}
13854
ttuttle859dc7a2015-04-23 19:42:2913855class OneTimeCachingHostResolver : public HostResolver {
[email protected]e3ceb682011-06-28 23:55:4613856 public:
13857 explicit OneTimeCachingHostResolver(const HostPortPair& host_port)
13858 : host_port_(host_port) {}
dchengb03027d2014-10-21 12:00:2013859 ~OneTimeCachingHostResolver() override {}
[email protected]e3ceb682011-06-28 23:55:4613860
13861 RuleBasedHostResolverProc* rules() { return host_resolver_.rules(); }
13862
13863 // HostResolver methods:
dchengb03027d2014-10-21 12:00:2013864 int Resolve(const RequestInfo& info,
13865 RequestPriority priority,
13866 AddressList* addresses,
13867 const CompletionCallback& callback,
maksim.sisov31452af2016-07-27 06:38:1013868 std::unique_ptr<Request>* out_req,
tfarina42834112016-09-22 13:38:2013869 const NetLogWithSource& net_log) override {
[email protected]95a214c2011-08-04 21:50:4013870 return host_resolver_.Resolve(
[email protected]5109c1952013-08-20 18:44:1013871 info, priority, addresses, callback, out_req, net_log);
[email protected]95a214c2011-08-04 21:50:4013872 }
13873
dchengb03027d2014-10-21 12:00:2013874 int ResolveFromCache(const RequestInfo& info,
13875 AddressList* addresses,
tfarina42834112016-09-22 13:38:2013876 const NetLogWithSource& net_log) override {
[email protected]95a214c2011-08-04 21:50:4013877 int rv = host_resolver_.ResolveFromCache(info, addresses, net_log);
13878 if (rv == OK && info.host_port_pair().Equals(host_port_))
[email protected]98e1cd012011-11-08 15:33:0913879 host_resolver_.GetHostCache()->clear();
[email protected]e3ceb682011-06-28 23:55:4613880 return rv;
13881 }
13882
[email protected]46da33be2011-07-19 21:58:0413883 MockCachingHostResolver* GetMockHostResolver() {
13884 return &host_resolver_;
13885 }
13886
[email protected]e3ceb682011-06-28 23:55:4613887 private:
13888 MockCachingHostResolver host_resolver_;
13889 const HostPortPair host_port_;
13890};
13891
bncd16676a2016-07-20 16:23:0113892TEST_F(HttpNetworkTransactionTest,
mmenke5c642132015-06-02 16:05:1313893 UseIPConnectionPoolingWithHostCacheExpiration) {
[email protected]e3ceb682011-06-28 23:55:4613894 // Set up a special HttpNetworkSession with a OneTimeCachingHostResolver.
bnca4d611d2016-09-22 19:55:3713895 OneTimeCachingHostResolver host_resolver(
13896 HostPortPair("mail.example.com", 443));
[email protected]c6bf8152012-12-02 07:43:3413897 HttpNetworkSession::Params params =
[email protected]bb88e1d32013-05-03 23:11:0713898 SpdySessionDependencies::CreateSessionParams(&session_deps_);
[email protected]e3ceb682011-06-28 23:55:4613899 params.host_resolver = &host_resolver;
danakj1fd259a02016-04-16 03:17:0913900 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]e3ceb682011-06-28 23:55:4613901
bnc032658ba2016-09-26 18:17:1513902 AddSSLSocketData();
[email protected]e3ceb682011-06-28 23:55:4613903
bncdf80d44fd2016-07-15 20:27:4113904 SpdySerializedFrame host1_req(
bnc38dcd392016-02-09 23:19:4913905 spdy_util_.ConstructSpdyGet("https://www.example.org", 1, LOWEST));
rdsmithebb50aa2015-11-12 03:44:3813906 spdy_util_.UpdateWithStreamDestruction(1);
bncdf80d44fd2016-07-15 20:27:4113907 SpdySerializedFrame host2_req(
bnca4d611d2016-09-22 19:55:3713908 spdy_util_.ConstructSpdyGet("https://mail.example.com", 3, LOWEST));
[email protected]e3ceb682011-06-28 23:55:4613909 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:4113910 CreateMockWrite(host1_req, 0), CreateMockWrite(host2_req, 3),
[email protected]e3ceb682011-06-28 23:55:4613911 };
bnc42331402016-07-25 13:36:1513912 SpdySerializedFrame host1_resp(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
bncdf80d44fd2016-07-15 20:27:4113913 SpdySerializedFrame host1_resp_body(
13914 spdy_util_.ConstructSpdyDataFrame(1, true));
bnc42331402016-07-25 13:36:1513915 SpdySerializedFrame host2_resp(spdy_util_.ConstructSpdyGetReply(NULL, 0, 3));
bncdf80d44fd2016-07-15 20:27:4113916 SpdySerializedFrame host2_resp_body(
13917 spdy_util_.ConstructSpdyDataFrame(3, true));
[email protected]e3ceb682011-06-28 23:55:4613918 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:4113919 CreateMockRead(host1_resp, 1), CreateMockRead(host1_resp_body, 2),
13920 CreateMockRead(host2_resp, 4), CreateMockRead(host2_resp_body, 5),
rch8e6c6c42015-05-01 14:05:1313921 MockRead(ASYNC, 0, 6),
[email protected]e3ceb682011-06-28 23:55:4613922 };
13923
eroman36d84e54432016-03-17 03:23:0213924 IPEndPoint peer_addr(IPAddress::IPv4Localhost(), 443);
[email protected]d2b5f092012-06-08 23:55:0213925 MockConnect connect(ASYNC, OK, peer_addr);
rch8e6c6c42015-05-01 14:05:1313926 SequencedSocketData spdy_data(connect, spdy_reads, arraysize(spdy_reads),
13927 spdy_writes, arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:0713928 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]e3ceb682011-06-28 23:55:4613929
[email protected]aa22b242011-11-16 18:58:2913930 TestCompletionCallback callback;
[email protected]e3ceb682011-06-28 23:55:4613931 HttpRequestInfo request1;
13932 request1.method = "GET";
bncce36dca22015-04-21 22:11:2313933 request1.url = GURL("https://www.example.org/");
[email protected]e3ceb682011-06-28 23:55:4613934 request1.load_flags = 0;
[email protected]90499482013-06-01 00:39:5013935 HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
[email protected]e3ceb682011-06-28 23:55:4613936
tfarina42834112016-09-22 13:38:2013937 int rv = trans1.Start(&request1, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0113938 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
13939 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]e3ceb682011-06-28 23:55:4613940
13941 const HttpResponseInfo* response = trans1.GetResponseInfo();
wezca1070932016-05-26 20:30:5213942 ASSERT_TRUE(response);
13943 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0213944 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]e3ceb682011-06-28 23:55:4613945
13946 std::string response_data;
robpercival214763f2016-07-01 23:27:0113947 ASSERT_THAT(ReadTransaction(&trans1, &response_data), IsOk());
[email protected]e3ceb682011-06-28 23:55:4613948 EXPECT_EQ("hello!", response_data);
13949
13950 // Preload cache entries into HostCache.
bnca4d611d2016-09-22 19:55:3713951 HostResolver::RequestInfo resolve_info(HostPortPair("mail.example.com", 443));
[email protected]e3ceb682011-06-28 23:55:4613952 AddressList ignored;
maksim.sisov31452af2016-07-27 06:38:1013953 std::unique_ptr<HostResolver::Request> request;
13954 rv = host_resolver.Resolve(resolve_info, DEFAULT_PRIORITY, &ignored,
tfarina42834112016-09-22 13:38:2013955 callback.callback(), &request, NetLogWithSource());
robpercival214763f2016-07-01 23:27:0113956 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]6e78dfb2011-07-28 21:34:4713957 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0113958 EXPECT_THAT(rv, IsOk());
[email protected]e3ceb682011-06-28 23:55:4613959
13960 HttpRequestInfo request2;
13961 request2.method = "GET";
bnca4d611d2016-09-22 19:55:3713962 request2.url = GURL("https://mail.example.com/");
[email protected]e3ceb682011-06-28 23:55:4613963 request2.load_flags = 0;
[email protected]90499482013-06-01 00:39:5013964 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
[email protected]e3ceb682011-06-28 23:55:4613965
tfarina42834112016-09-22 13:38:2013966 rv = trans2.Start(&request2, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0113967 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
13968 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]e3ceb682011-06-28 23:55:4613969
13970 response = trans2.GetResponseInfo();
wezca1070932016-05-26 20:30:5213971 ASSERT_TRUE(response);
13972 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0213973 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]e3ceb682011-06-28 23:55:4613974 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5213975 EXPECT_TRUE(response->was_alpn_negotiated);
robpercival214763f2016-07-01 23:27:0113976 ASSERT_THAT(ReadTransaction(&trans2, &response_data), IsOk());
[email protected]e3ceb682011-06-28 23:55:4613977 EXPECT_EQ("hello!", response_data);
[email protected]e3ceb682011-06-28 23:55:4613978}
13979
bncd16676a2016-07-20 16:23:0113980TEST_F(HttpNetworkTransactionTest, DoNotUseSpdySessionForHttp) {
bncce36dca22015-04-21 22:11:2313981 const std::string https_url = "https://www.example.org:8080/";
13982 const std::string http_url = "http://www.example.org:8080/";
[email protected]8450d722012-07-02 19:14:0413983
13984 // SPDY GET for HTTPS URL
bncdf80d44fd2016-07-15 20:27:4113985 SpdySerializedFrame req1(
bnc38dcd392016-02-09 23:19:4913986 spdy_util_.ConstructSpdyGet(https_url.c_str(), 1, LOWEST));
[email protected]8450d722012-07-02 19:14:0413987
13988 MockWrite writes1[] = {
bncdf80d44fd2016-07-15 20:27:4113989 CreateMockWrite(req1, 0),
[email protected]8450d722012-07-02 19:14:0413990 };
13991
bnc42331402016-07-25 13:36:1513992 SpdySerializedFrame resp1(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
bncdf80d44fd2016-07-15 20:27:4113993 SpdySerializedFrame body1(spdy_util_.ConstructSpdyDataFrame(1, true));
13994 MockRead reads1[] = {CreateMockRead(resp1, 1), CreateMockRead(body1, 2),
mmenkee24011922015-12-17 22:12:5913995 MockRead(SYNCHRONOUS, ERR_IO_PENDING, 3)};
[email protected]8450d722012-07-02 19:14:0413996
rch8e6c6c42015-05-01 14:05:1313997 SequencedSocketData data1(reads1, arraysize(reads1), writes1,
13998 arraysize(writes1));
[email protected]8450d722012-07-02 19:14:0413999 MockConnect connect_data1(ASYNC, OK);
[email protected]dd54bd82012-07-19 23:44:5714000 data1.set_connect_data(connect_data1);
[email protected]8450d722012-07-02 19:14:0414001
14002 // HTTP GET for the HTTP URL
14003 MockWrite writes2[] = {
rch8e6c6c42015-05-01 14:05:1314004 MockWrite(ASYNC, 0,
lgarrona91df87f2014-12-05 00:51:3414005 "GET / HTTP/1.1\r\n"
bncce36dca22015-04-21 22:11:2314006 "Host: www.example.org:8080\r\n"
lgarrona91df87f2014-12-05 00:51:3414007 "Connection: keep-alive\r\n\r\n"),
[email protected]8450d722012-07-02 19:14:0414008 };
14009
14010 MockRead reads2[] = {
rch8e6c6c42015-05-01 14:05:1314011 MockRead(ASYNC, 1, "HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
14012 MockRead(ASYNC, 2, "hello"),
14013 MockRead(ASYNC, OK, 3),
[email protected]8450d722012-07-02 19:14:0414014 };
14015
rch8e6c6c42015-05-01 14:05:1314016 SequencedSocketData data2(reads2, arraysize(reads2), writes2,
14017 arraysize(writes2));
[email protected]8450d722012-07-02 19:14:0414018
[email protected]8450d722012-07-02 19:14:0414019 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3614020 ssl.next_proto = kProtoHTTP2;
[email protected]bb88e1d32013-05-03 23:11:0714021 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
14022 session_deps_.socket_factory->AddSocketDataProvider(&data1);
14023 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]8450d722012-07-02 19:14:0414024
danakj1fd259a02016-04-16 03:17:0914025 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]8450d722012-07-02 19:14:0414026
14027 // Start the first transaction to set up the SpdySession
14028 HttpRequestInfo request1;
14029 request1.method = "GET";
14030 request1.url = GURL(https_url);
[email protected]8450d722012-07-02 19:14:0414031 request1.load_flags = 0;
[email protected]90499482013-06-01 00:39:5014032 HttpNetworkTransaction trans1(LOWEST, session.get());
[email protected]8450d722012-07-02 19:14:0414033 TestCompletionCallback callback1;
14034 EXPECT_EQ(ERR_IO_PENDING,
tfarina42834112016-09-22 13:38:2014035 trans1.Start(&request1, callback1.callback(), NetLogWithSource()));
fdoray92e35a72016-06-10 15:54:5514036 base::RunLoop().RunUntilIdle();
[email protected]8450d722012-07-02 19:14:0414037
robpercival214763f2016-07-01 23:27:0114038 EXPECT_THAT(callback1.WaitForResult(), IsOk());
[email protected]8450d722012-07-02 19:14:0414039 EXPECT_TRUE(trans1.GetResponseInfo()->was_fetched_via_spdy);
14040
14041 // Now, start the HTTP request
14042 HttpRequestInfo request2;
14043 request2.method = "GET";
14044 request2.url = GURL(http_url);
[email protected]8450d722012-07-02 19:14:0414045 request2.load_flags = 0;
[email protected]90499482013-06-01 00:39:5014046 HttpNetworkTransaction trans2(MEDIUM, session.get());
[email protected]8450d722012-07-02 19:14:0414047 TestCompletionCallback callback2;
14048 EXPECT_EQ(ERR_IO_PENDING,
tfarina42834112016-09-22 13:38:2014049 trans2.Start(&request2, callback2.callback(), NetLogWithSource()));
fdoray92e35a72016-06-10 15:54:5514050 base::RunLoop().RunUntilIdle();
[email protected]8450d722012-07-02 19:14:0414051
robpercival214763f2016-07-01 23:27:0114052 EXPECT_THAT(callback2.WaitForResult(), IsOk());
[email protected]8450d722012-07-02 19:14:0414053 EXPECT_FALSE(trans2.GetResponseInfo()->was_fetched_via_spdy);
14054}
14055
bnc5452e2a2015-05-08 16:27:4214056// Alternative service requires HTTP/2 (or SPDY), but HTTP/1.1 is negotiated
14057// with the alternative server. That connection should not be used.
bncd16676a2016-07-20 16:23:0114058TEST_F(HttpNetworkTransactionTest, AlternativeServiceNotOnHttp11) {
bnc8bef8da22016-05-30 01:28:2514059 url::SchemeHostPort server("https", "www.example.org", 443);
14060 HostPortPair alternative("www.example.org", 444);
bnc5452e2a2015-05-08 16:27:4214061
bnc8bef8da22016-05-30 01:28:2514062 // Negotiate HTTP/1.1 with alternative.
bnc5452e2a2015-05-08 16:27:4214063 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3614064 ssl.next_proto = kProtoHTTP11;
bnc5452e2a2015-05-08 16:27:4214065 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
14066
14067 // No data should be read from the alternative, because HTTP/1.1 is
14068 // negotiated.
14069 StaticSocketDataProvider data;
14070 session_deps_.socket_factory->AddSocketDataProvider(&data);
14071
14072 // This test documents that an alternate Job should not be used if HTTP/1.1 is
zhongyi3d4a55e72016-04-22 20:36:4614073 // negotiated. In order to test this, a failed connection to the server is
bnc5452e2a2015-05-08 16:27:4214074 // mocked. This way the request relies on the alternate Job.
14075 StaticSocketDataProvider data_refused;
14076 data_refused.set_connect_data(MockConnect(ASYNC, ERR_CONNECTION_REFUSED));
14077 session_deps_.socket_factory->AddSocketDataProvider(&data_refused);
14078
zhongyi3d4a55e72016-04-22 20:36:4614079 // Set up alternative service for server.
danakj1fd259a02016-04-16 03:17:0914080 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc525e175a2016-06-20 12:36:4014081 HttpServerProperties* http_server_properties =
bnc5452e2a2015-05-08 16:27:4214082 session->http_server_properties();
bnc3472afd2016-11-17 15:27:2114083 AlternativeService alternative_service(kProtoHTTP2, alternative);
bnc7dc7e1b42015-07-28 14:43:1214084 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyi3d4a55e72016-04-22 20:36:4614085 http_server_properties->SetAlternativeService(server, alternative_service,
rchdc7b9052016-03-17 20:51:5014086 expiration);
bnc5452e2a2015-05-08 16:27:4214087
bnc5452e2a2015-05-08 16:27:4214088 HttpRequestInfo request;
krasinc06a72a2016-12-21 03:42:4614089 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
bnc5452e2a2015-05-08 16:27:4214090 request.method = "GET";
bnc8bef8da22016-05-30 01:28:2514091 request.url = GURL("https://www.example.org:443");
bnc5452e2a2015-05-08 16:27:4214092 TestCompletionCallback callback;
14093
14094 // HTTP/2 (or SPDY) is required for alternative service, if HTTP/1.1 is
bnc94c92842016-09-21 15:22:5214095 // negotiated, the alternate Job should fail with ERR_ALPN_NEGOTIATION_FAILED.
tfarina42834112016-09-22 13:38:2014096 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
bnc94c92842016-09-21 15:22:5214097 EXPECT_THAT(callback.GetResult(rv), IsError(ERR_ALPN_NEGOTIATION_FAILED));
bnc5452e2a2015-05-08 16:27:4214098}
14099
bnc40448a532015-05-11 19:13:1414100// A request to a server with an alternative service fires two Jobs: one to the
zhongyi3d4a55e72016-04-22 20:36:4614101// server, and an alternate one to the alternative server. If the former
bnc40448a532015-05-11 19:13:1414102// succeeds, the request should succeed, even if the latter fails because
14103// HTTP/1.1 is negotiated which is insufficient for alternative service.
bncd16676a2016-07-20 16:23:0114104TEST_F(HttpNetworkTransactionTest, FailedAlternativeServiceIsNotUserVisible) {
bnc8bef8da22016-05-30 01:28:2514105 url::SchemeHostPort server("https", "www.example.org", 443);
14106 HostPortPair alternative("www.example.org", 444);
bnc40448a532015-05-11 19:13:1414107
14108 // Negotiate HTTP/1.1 with alternative.
14109 SSLSocketDataProvider alternative_ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3614110 alternative_ssl.next_proto = kProtoHTTP11;
bnc40448a532015-05-11 19:13:1414111 session_deps_.socket_factory->AddSSLSocketDataProvider(&alternative_ssl);
14112
14113 // No data should be read from the alternative, because HTTP/1.1 is
14114 // negotiated.
14115 StaticSocketDataProvider data;
14116 session_deps_.socket_factory->AddSocketDataProvider(&data);
14117
zhongyi3d4a55e72016-04-22 20:36:4614118 // Negotiate HTTP/1.1 with server.
bnc40448a532015-05-11 19:13:1414119 SSLSocketDataProvider origin_ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3614120 origin_ssl.next_proto = kProtoHTTP11;
bnc40448a532015-05-11 19:13:1414121 session_deps_.socket_factory->AddSSLSocketDataProvider(&origin_ssl);
14122
14123 MockWrite http_writes[] = {
bnc8bef8da22016-05-30 01:28:2514124 MockWrite("GET / HTTP/1.1\r\n"
14125 "Host: www.example.org\r\n"
14126 "Connection: keep-alive\r\n\r\n"),
14127 MockWrite("GET /second HTTP/1.1\r\n"
14128 "Host: www.example.org\r\n"
14129 "Connection: keep-alive\r\n\r\n"),
bnc40448a532015-05-11 19:13:1414130 };
14131
14132 MockRead http_reads[] = {
14133 MockRead("HTTP/1.1 200 OK\r\n"),
14134 MockRead("Content-Type: text/html\r\n"),
14135 MockRead("Content-Length: 6\r\n\r\n"),
14136 MockRead("foobar"),
14137 MockRead("HTTP/1.1 200 OK\r\n"),
14138 MockRead("Content-Type: text/html\r\n"),
14139 MockRead("Content-Length: 7\r\n\r\n"),
14140 MockRead("another"),
14141 };
14142 StaticSocketDataProvider http_data(http_reads, arraysize(http_reads),
14143 http_writes, arraysize(http_writes));
14144 session_deps_.socket_factory->AddSocketDataProvider(&http_data);
14145
zhongyi3d4a55e72016-04-22 20:36:4614146 // Set up alternative service for server.
danakj1fd259a02016-04-16 03:17:0914147 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc525e175a2016-06-20 12:36:4014148 HttpServerProperties* http_server_properties =
bnc40448a532015-05-11 19:13:1414149 session->http_server_properties();
bnc3472afd2016-11-17 15:27:2114150 AlternativeService alternative_service(kProtoHTTP2, alternative);
bnc7dc7e1b42015-07-28 14:43:1214151 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyi3d4a55e72016-04-22 20:36:4614152 http_server_properties->SetAlternativeService(server, alternative_service,
rchdc7b9052016-03-17 20:51:5014153 expiration);
bnc40448a532015-05-11 19:13:1414154
14155 HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
14156 HttpRequestInfo request1;
14157 request1.method = "GET";
bnc8bef8da22016-05-30 01:28:2514158 request1.url = GURL("https://www.example.org:443");
bnc40448a532015-05-11 19:13:1414159 request1.load_flags = 0;
14160 TestCompletionCallback callback1;
14161
tfarina42834112016-09-22 13:38:2014162 int rv = trans1.Start(&request1, callback1.callback(), NetLogWithSource());
bnc40448a532015-05-11 19:13:1414163 rv = callback1.GetResult(rv);
robpercival214763f2016-07-01 23:27:0114164 EXPECT_THAT(rv, IsOk());
bnc40448a532015-05-11 19:13:1414165
14166 const HttpResponseInfo* response1 = trans1.GetResponseInfo();
wezca1070932016-05-26 20:30:5214167 ASSERT_TRUE(response1);
14168 ASSERT_TRUE(response1->headers);
bnc40448a532015-05-11 19:13:1414169 EXPECT_EQ("HTTP/1.1 200 OK", response1->headers->GetStatusLine());
14170
14171 std::string response_data1;
robpercival214763f2016-07-01 23:27:0114172 ASSERT_THAT(ReadTransaction(&trans1, &response_data1), IsOk());
bnc40448a532015-05-11 19:13:1414173 EXPECT_EQ("foobar", response_data1);
14174
14175 // Alternative should be marked as broken, because HTTP/1.1 is not sufficient
14176 // for alternative service.
14177 EXPECT_TRUE(
14178 http_server_properties->IsAlternativeServiceBroken(alternative_service));
14179
zhongyi3d4a55e72016-04-22 20:36:4614180 // Since |alternative_service| is broken, a second transaction to server
bnc40448a532015-05-11 19:13:1414181 // should not start an alternate Job. It should pool to existing connection
zhongyi3d4a55e72016-04-22 20:36:4614182 // to server.
bnc40448a532015-05-11 19:13:1414183 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
14184 HttpRequestInfo request2;
14185 request2.method = "GET";
bnc8bef8da22016-05-30 01:28:2514186 request2.url = GURL("https://www.example.org:443/second");
bnc40448a532015-05-11 19:13:1414187 request2.load_flags = 0;
14188 TestCompletionCallback callback2;
14189
tfarina42834112016-09-22 13:38:2014190 rv = trans2.Start(&request2, callback2.callback(), NetLogWithSource());
bnc40448a532015-05-11 19:13:1414191 rv = callback2.GetResult(rv);
robpercival214763f2016-07-01 23:27:0114192 EXPECT_THAT(rv, IsOk());
bnc40448a532015-05-11 19:13:1414193
14194 const HttpResponseInfo* response2 = trans2.GetResponseInfo();
wezca1070932016-05-26 20:30:5214195 ASSERT_TRUE(response2);
14196 ASSERT_TRUE(response2->headers);
bnc40448a532015-05-11 19:13:1414197 EXPECT_EQ("HTTP/1.1 200 OK", response2->headers->GetStatusLine());
14198
14199 std::string response_data2;
robpercival214763f2016-07-01 23:27:0114200 ASSERT_THAT(ReadTransaction(&trans2, &response_data2), IsOk());
bnc40448a532015-05-11 19:13:1414201 EXPECT_EQ("another", response_data2);
14202}
14203
bnc5452e2a2015-05-08 16:27:4214204// Alternative service requires HTTP/2 (or SPDY), but there is already a
14205// HTTP/1.1 socket open to the alternative server. That socket should not be
14206// used.
bncd16676a2016-07-20 16:23:0114207TEST_F(HttpNetworkTransactionTest, AlternativeServiceShouldNotPoolToHttp11) {
zhongyi3d4a55e72016-04-22 20:36:4614208 url::SchemeHostPort server("https", "origin.example.org", 443);
bnc5452e2a2015-05-08 16:27:4214209 HostPortPair alternative("alternative.example.org", 443);
14210 std::string origin_url = "https://origin.example.org:443";
14211 std::string alternative_url = "https://alternative.example.org:443";
14212
14213 // Negotiate HTTP/1.1 with alternative.example.org.
14214 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3614215 ssl.next_proto = kProtoHTTP11;
bnc5452e2a2015-05-08 16:27:4214216 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
14217
14218 // HTTP/1.1 data for |request1| and |request2|.
14219 MockWrite http_writes[] = {
14220 MockWrite(
14221 "GET / HTTP/1.1\r\n"
14222 "Host: alternative.example.org\r\n"
14223 "Connection: keep-alive\r\n\r\n"),
14224 MockWrite(
14225 "GET / HTTP/1.1\r\n"
14226 "Host: alternative.example.org\r\n"
14227 "Connection: keep-alive\r\n\r\n"),
14228 };
14229
14230 MockRead http_reads[] = {
14231 MockRead(
14232 "HTTP/1.1 200 OK\r\n"
14233 "Content-Type: text/html; charset=iso-8859-1\r\n"
14234 "Content-Length: 40\r\n\r\n"
14235 "first HTTP/1.1 response from alternative"),
14236 MockRead(
14237 "HTTP/1.1 200 OK\r\n"
14238 "Content-Type: text/html; charset=iso-8859-1\r\n"
14239 "Content-Length: 41\r\n\r\n"
14240 "second HTTP/1.1 response from alternative"),
14241 };
14242 StaticSocketDataProvider http_data(http_reads, arraysize(http_reads),
14243 http_writes, arraysize(http_writes));
14244 session_deps_.socket_factory->AddSocketDataProvider(&http_data);
14245
14246 // This test documents that an alternate Job should not pool to an already
14247 // existing HTTP/1.1 connection. In order to test this, a failed connection
zhongyi3d4a55e72016-04-22 20:36:4614248 // to the server is mocked. This way |request2| relies on the alternate Job.
bnc5452e2a2015-05-08 16:27:4214249 StaticSocketDataProvider data_refused;
14250 data_refused.set_connect_data(MockConnect(ASYNC, ERR_CONNECTION_REFUSED));
14251 session_deps_.socket_factory->AddSocketDataProvider(&data_refused);
14252
zhongyi3d4a55e72016-04-22 20:36:4614253 // Set up alternative service for server.
danakj1fd259a02016-04-16 03:17:0914254 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc525e175a2016-06-20 12:36:4014255 HttpServerProperties* http_server_properties =
bnc5452e2a2015-05-08 16:27:4214256 session->http_server_properties();
bnc3472afd2016-11-17 15:27:2114257 AlternativeService alternative_service(kProtoHTTP2, alternative);
bnc7dc7e1b42015-07-28 14:43:1214258 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyi3d4a55e72016-04-22 20:36:4614259 http_server_properties->SetAlternativeService(server, alternative_service,
rchdc7b9052016-03-17 20:51:5014260 expiration);
bnc5452e2a2015-05-08 16:27:4214261
14262 // First transaction to alternative to open an HTTP/1.1 socket.
bnc5452e2a2015-05-08 16:27:4214263 HttpRequestInfo request1;
krasinc06a72a2016-12-21 03:42:4614264 HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
bnc5452e2a2015-05-08 16:27:4214265 request1.method = "GET";
14266 request1.url = GURL(alternative_url);
14267 request1.load_flags = 0;
14268 TestCompletionCallback callback1;
14269
tfarina42834112016-09-22 13:38:2014270 int rv = trans1.Start(&request1, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0114271 EXPECT_THAT(callback1.GetResult(rv), IsOk());
bnc691fda62016-08-12 00:43:1614272 const HttpResponseInfo* response1 = trans1.GetResponseInfo();
bnc5452e2a2015-05-08 16:27:4214273 ASSERT_TRUE(response1);
wezca1070932016-05-26 20:30:5214274 ASSERT_TRUE(response1->headers);
bnc5452e2a2015-05-08 16:27:4214275 EXPECT_EQ("HTTP/1.1 200 OK", response1->headers->GetStatusLine());
bnc94c92842016-09-21 15:22:5214276 EXPECT_TRUE(response1->was_alpn_negotiated);
bnc5452e2a2015-05-08 16:27:4214277 EXPECT_FALSE(response1->was_fetched_via_spdy);
14278 std::string response_data1;
bnc691fda62016-08-12 00:43:1614279 ASSERT_THAT(ReadTransaction(&trans1, &response_data1), IsOk());
bnc5452e2a2015-05-08 16:27:4214280 EXPECT_EQ("first HTTP/1.1 response from alternative", response_data1);
14281
14282 // Request for origin.example.org, which has an alternative service. This
14283 // will start two Jobs: the alternative looks for connections to pool to,
14284 // finds one which is HTTP/1.1, and should ignore it, and should not try to
zhongyi3d4a55e72016-04-22 20:36:4614285 // open other connections to alternative server. The Job to server fails, so
bnc5452e2a2015-05-08 16:27:4214286 // this request fails.
bnc5452e2a2015-05-08 16:27:4214287 HttpRequestInfo request2;
krasinc06a72a2016-12-21 03:42:4614288 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
bnc5452e2a2015-05-08 16:27:4214289 request2.method = "GET";
14290 request2.url = GURL(origin_url);
14291 request2.load_flags = 0;
14292 TestCompletionCallback callback2;
14293
tfarina42834112016-09-22 13:38:2014294 rv = trans2.Start(&request2, callback2.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0114295 EXPECT_THAT(callback2.GetResult(rv), IsError(ERR_CONNECTION_REFUSED));
bnc5452e2a2015-05-08 16:27:4214296
14297 // Another transaction to alternative. This is to test that the HTTP/1.1
14298 // socket is still open and in the pool.
bnc5452e2a2015-05-08 16:27:4214299 HttpRequestInfo request3;
krasinc06a72a2016-12-21 03:42:4614300 HttpNetworkTransaction trans3(DEFAULT_PRIORITY, session.get());
bnc5452e2a2015-05-08 16:27:4214301 request3.method = "GET";
14302 request3.url = GURL(alternative_url);
14303 request3.load_flags = 0;
14304 TestCompletionCallback callback3;
14305
tfarina42834112016-09-22 13:38:2014306 rv = trans3.Start(&request3, callback3.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0114307 EXPECT_THAT(callback3.GetResult(rv), IsOk());
bnc691fda62016-08-12 00:43:1614308 const HttpResponseInfo* response3 = trans3.GetResponseInfo();
bnc5452e2a2015-05-08 16:27:4214309 ASSERT_TRUE(response3);
wezca1070932016-05-26 20:30:5214310 ASSERT_TRUE(response3->headers);
bnc5452e2a2015-05-08 16:27:4214311 EXPECT_EQ("HTTP/1.1 200 OK", response3->headers->GetStatusLine());
bnc94c92842016-09-21 15:22:5214312 EXPECT_TRUE(response3->was_alpn_negotiated);
bnc5452e2a2015-05-08 16:27:4214313 EXPECT_FALSE(response3->was_fetched_via_spdy);
14314 std::string response_data3;
bnc691fda62016-08-12 00:43:1614315 ASSERT_THAT(ReadTransaction(&trans3, &response_data3), IsOk());
bnc5452e2a2015-05-08 16:27:4214316 EXPECT_EQ("second HTTP/1.1 response from alternative", response_data3);
14317}
14318
bncd16676a2016-07-20 16:23:0114319TEST_F(HttpNetworkTransactionTest, DoNotUseSpdySessionForHttpOverTunnel) {
bncce36dca22015-04-21 22:11:2314320 const std::string https_url = "https://www.example.org:8080/";
14321 const std::string http_url = "http://www.example.org:8080/";
[email protected]8450d722012-07-02 19:14:0414322
rdsmithebb50aa2015-11-12 03:44:3814323 // Separate SPDY util instance for naked and wrapped requests.
bncd16676a2016-07-20 16:23:0114324 SpdyTestUtil spdy_util_wrapped;
rdsmithebb50aa2015-11-12 03:44:3814325
[email protected]8450d722012-07-02 19:14:0414326 // SPDY GET for HTTPS URL (through CONNECT tunnel)
bncce36dca22015-04-21 22:11:2314327 const HostPortPair host_port_pair("www.example.org", 8080);
bncdf80d44fd2016-07-15 20:27:4114328 SpdySerializedFrame connect(
lgarrona91df87f2014-12-05 00:51:3414329 spdy_util_.ConstructSpdyConnect(NULL, 0, 1, LOWEST, host_port_pair));
bncdf80d44fd2016-07-15 20:27:4114330 SpdySerializedFrame req1(
bnc38dcd392016-02-09 23:19:4914331 spdy_util_wrapped.ConstructSpdyGet(https_url.c_str(), 1, LOWEST));
bncdf80d44fd2016-07-15 20:27:4114332 SpdySerializedFrame wrapped_req1(
[email protected]23e482282013-06-14 16:08:0214333 spdy_util_.ConstructWrappedSpdyFrame(req1, 1));
[email protected]601e03f12014-04-06 16:26:3914334
14335 // SPDY GET for HTTP URL (through the proxy, but not the tunnel).
[email protected]745aa9c2014-06-27 02:21:2914336 SpdyHeaderBlock req2_block;
14337 req2_block[spdy_util_.GetMethodKey()] = "GET";
bncce36dca22015-04-21 22:11:2314338 req2_block[spdy_util_.GetHostKey()] = "www.example.org:8080";
[email protected]745aa9c2014-06-27 02:21:2914339 req2_block[spdy_util_.GetSchemeKey()] = "http";
bnc7ecc1122015-09-28 13:22:4914340 req2_block[spdy_util_.GetPathKey()] = "/";
bncdf80d44fd2016-07-15 20:27:4114341 SpdySerializedFrame req2(
bnc42331402016-07-25 13:36:1514342 spdy_util_.ConstructSpdyHeaders(3, std::move(req2_block), MEDIUM, true));
[email protected]8450d722012-07-02 19:14:0414343
14344 MockWrite writes1[] = {
bncdf80d44fd2016-07-15 20:27:4114345 CreateMockWrite(connect, 0), CreateMockWrite(wrapped_req1, 2),
14346 CreateMockWrite(req2, 6),
[email protected]8450d722012-07-02 19:14:0414347 };
14348
bncdf80d44fd2016-07-15 20:27:4114349 SpdySerializedFrame conn_resp(
bnc42331402016-07-25 13:36:1514350 spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
bncdf80d44fd2016-07-15 20:27:4114351 SpdySerializedFrame resp1(
bnc42331402016-07-25 13:36:1514352 spdy_util_wrapped.ConstructSpdyGetReply(nullptr, 0, 1));
bncdf80d44fd2016-07-15 20:27:4114353 SpdySerializedFrame body1(spdy_util_wrapped.ConstructSpdyDataFrame(1, true));
14354 SpdySerializedFrame wrapped_resp1(
rdsmithebb50aa2015-11-12 03:44:3814355 spdy_util_wrapped.ConstructWrappedSpdyFrame(resp1, 1));
bncdf80d44fd2016-07-15 20:27:4114356 SpdySerializedFrame wrapped_body1(
rdsmithebb50aa2015-11-12 03:44:3814357 spdy_util_wrapped.ConstructWrappedSpdyFrame(body1, 1));
bnc42331402016-07-25 13:36:1514358 SpdySerializedFrame resp2(spdy_util_.ConstructSpdyGetReply(NULL, 0, 3));
bncdf80d44fd2016-07-15 20:27:4114359 SpdySerializedFrame body2(spdy_util_.ConstructSpdyDataFrame(3, true));
mmenke666a6fea2015-12-19 04:16:3314360 MockRead reads1[] = {
bncdf80d44fd2016-07-15 20:27:4114361 CreateMockRead(conn_resp, 1),
mmenke666a6fea2015-12-19 04:16:3314362 MockRead(ASYNC, ERR_IO_PENDING, 3),
bncdf80d44fd2016-07-15 20:27:4114363 CreateMockRead(wrapped_resp1, 4),
14364 CreateMockRead(wrapped_body1, 5),
mmenke666a6fea2015-12-19 04:16:3314365 MockRead(ASYNC, ERR_IO_PENDING, 7),
bncdf80d44fd2016-07-15 20:27:4114366 CreateMockRead(resp2, 8),
14367 CreateMockRead(body2, 9),
mmenke666a6fea2015-12-19 04:16:3314368 MockRead(SYNCHRONOUS, ERR_IO_PENDING, 10),
14369 };
[email protected]8450d722012-07-02 19:14:0414370
mmenke666a6fea2015-12-19 04:16:3314371 SequencedSocketData data1(reads1, arraysize(reads1), writes1,
14372 arraysize(writes1));
[email protected]8450d722012-07-02 19:14:0414373 MockConnect connect_data1(ASYNC, OK);
[email protected]dd54bd82012-07-19 23:44:5714374 data1.set_connect_data(connect_data1);
[email protected]8450d722012-07-02 19:14:0414375
rdsmith82957ad2015-09-16 19:42:0314376 session_deps_.proxy_service =
14377 ProxyService::CreateFixedFromPacResult("HTTPS proxy:70");
vishal.b62985ca92015-04-17 08:45:5114378 TestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:0714379 session_deps_.net_log = &log;
[email protected]8450d722012-07-02 19:14:0414380 SSLSocketDataProvider ssl1(ASYNC, OK); // to the proxy
bnc3cf2a592016-08-11 14:48:3614381 ssl1.next_proto = kProtoHTTP2;
mmenke666a6fea2015-12-19 04:16:3314382 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl1);
[email protected]8450d722012-07-02 19:14:0414383 SSLSocketDataProvider ssl2(ASYNC, OK); // to the server
bnc3cf2a592016-08-11 14:48:3614384 ssl2.next_proto = kProtoHTTP2;
mmenke666a6fea2015-12-19 04:16:3314385 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
14386 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8450d722012-07-02 19:14:0414387
danakj1fd259a02016-04-16 03:17:0914388 std::unique_ptr<HttpNetworkSession> session = CreateSession(&session_deps_);
[email protected]8450d722012-07-02 19:14:0414389
14390 // Start the first transaction to set up the SpdySession
14391 HttpRequestInfo request1;
14392 request1.method = "GET";
14393 request1.url = GURL(https_url);
[email protected]8450d722012-07-02 19:14:0414394 request1.load_flags = 0;
[email protected]90499482013-06-01 00:39:5014395 HttpNetworkTransaction trans1(LOWEST, session.get());
[email protected]8450d722012-07-02 19:14:0414396 TestCompletionCallback callback1;
tfarina42834112016-09-22 13:38:2014397 int rv = trans1.Start(&request1, callback1.callback(), NetLogWithSource());
[email protected]8450d722012-07-02 19:14:0414398
mmenke666a6fea2015-12-19 04:16:3314399 // This pause is a hack to avoid running into https://crbug.com/497228.
14400 data1.RunUntilPaused();
14401 base::RunLoop().RunUntilIdle();
14402 data1.Resume();
robpercival214763f2016-07-01 23:27:0114403 EXPECT_THAT(callback1.GetResult(rv), IsOk());
[email protected]8450d722012-07-02 19:14:0414404 EXPECT_TRUE(trans1.GetResponseInfo()->was_fetched_via_spdy);
14405
[email protected]f6c63db52013-02-02 00:35:2214406 LoadTimingInfo load_timing_info1;
14407 EXPECT_TRUE(trans1.GetLoadTimingInfo(&load_timing_info1));
14408 TestLoadTimingNotReusedWithPac(load_timing_info1,
14409 CONNECT_TIMING_HAS_SSL_TIMES);
14410
mmenke666a6fea2015-12-19 04:16:3314411 // Now, start the HTTP request.
[email protected]8450d722012-07-02 19:14:0414412 HttpRequestInfo request2;
14413 request2.method = "GET";
14414 request2.url = GURL(http_url);
[email protected]8450d722012-07-02 19:14:0414415 request2.load_flags = 0;
[email protected]90499482013-06-01 00:39:5014416 HttpNetworkTransaction trans2(MEDIUM, session.get());
[email protected]8450d722012-07-02 19:14:0414417 TestCompletionCallback callback2;
tfarina42834112016-09-22 13:38:2014418 rv = trans2.Start(&request2, callback2.callback(), NetLogWithSource());
[email protected]8450d722012-07-02 19:14:0414419
mmenke666a6fea2015-12-19 04:16:3314420 // This pause is a hack to avoid running into https://crbug.com/497228.
14421 data1.RunUntilPaused();
14422 base::RunLoop().RunUntilIdle();
14423 data1.Resume();
robpercival214763f2016-07-01 23:27:0114424 EXPECT_THAT(callback2.GetResult(rv), IsOk());
mmenke666a6fea2015-12-19 04:16:3314425
[email protected]8450d722012-07-02 19:14:0414426 EXPECT_TRUE(trans2.GetResponseInfo()->was_fetched_via_spdy);
[email protected]f6c63db52013-02-02 00:35:2214427
14428 LoadTimingInfo load_timing_info2;
14429 EXPECT_TRUE(trans2.GetLoadTimingInfo(&load_timing_info2));
14430 // The established SPDY sessions is considered reused by the HTTP request.
14431 TestLoadTimingReusedWithPac(load_timing_info2);
14432 // HTTP requests over a SPDY session should have a different connection
14433 // socket_log_id than requests over a tunnel.
14434 EXPECT_NE(load_timing_info1.socket_log_id, load_timing_info2.socket_log_id);
[email protected]8450d722012-07-02 19:14:0414435}
14436
[email protected]2d88e7d2012-07-19 17:55:1714437// Test that in the case where we have a SPDY session to a SPDY proxy
14438// that we do not pool other origins that resolve to the same IP when
14439// the certificate does not match the new origin.
14440// http://crbug.com/134690
bncd16676a2016-07-20 16:23:0114441TEST_F(HttpNetworkTransactionTest, DoNotUseSpdySessionIfCertDoesNotMatch) {
bncce36dca22015-04-21 22:11:2314442 const std::string url1 = "http://www.example.org/";
14443 const std::string url2 = "https://news.example.org/";
[email protected]2d88e7d2012-07-19 17:55:1714444 const std::string ip_addr = "1.2.3.4";
14445
rdsmithebb50aa2015-11-12 03:44:3814446 // Second SpdyTestUtil instance for the second socket.
bncd16676a2016-07-20 16:23:0114447 SpdyTestUtil spdy_util_secure;
rdsmithebb50aa2015-11-12 03:44:3814448
[email protected]2d88e7d2012-07-19 17:55:1714449 // SPDY GET for HTTP URL (through SPDY proxy)
bnc086b39e12016-06-24 13:05:2614450 SpdyHeaderBlock headers(
bncce36dca22015-04-21 22:11:2314451 spdy_util_.ConstructGetHeaderBlockForProxy("http://www.example.org/"));
bncdf80d44fd2016-07-15 20:27:4114452 SpdySerializedFrame req1(
bnc42331402016-07-25 13:36:1514453 spdy_util_.ConstructSpdyHeaders(1, std::move(headers), LOWEST, true));
[email protected]2d88e7d2012-07-19 17:55:1714454
14455 MockWrite writes1[] = {
bncdf80d44fd2016-07-15 20:27:4114456 CreateMockWrite(req1, 0),
[email protected]2d88e7d2012-07-19 17:55:1714457 };
14458
bnc42331402016-07-25 13:36:1514459 SpdySerializedFrame resp1(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
bncdf80d44fd2016-07-15 20:27:4114460 SpdySerializedFrame body1(spdy_util_.ConstructSpdyDataFrame(1, true));
[email protected]2d88e7d2012-07-19 17:55:1714461 MockRead reads1[] = {
bncdf80d44fd2016-07-15 20:27:4114462 MockRead(ASYNC, ERR_IO_PENDING, 1), CreateMockRead(resp1, 2),
14463 CreateMockRead(body1, 3), MockRead(ASYNC, OK, 4), // EOF
[email protected]2d88e7d2012-07-19 17:55:1714464 };
14465
mmenke666a6fea2015-12-19 04:16:3314466 SequencedSocketData data1(reads1, arraysize(reads1), writes1,
14467 arraysize(writes1));
martijnfe9636e2016-02-06 14:33:3214468 IPAddress ip;
martijn654c8c42016-02-10 22:10:5914469 ASSERT_TRUE(ip.AssignFromIPLiteral(ip_addr));
[email protected]2d88e7d2012-07-19 17:55:1714470 IPEndPoint peer_addr = IPEndPoint(ip, 443);
14471 MockConnect connect_data1(ASYNC, OK, peer_addr);
mmenke666a6fea2015-12-19 04:16:3314472 data1.set_connect_data(connect_data1);
[email protected]2d88e7d2012-07-19 17:55:1714473
14474 // SPDY GET for HTTPS URL (direct)
bncdf80d44fd2016-07-15 20:27:4114475 SpdySerializedFrame req2(
bnc38dcd392016-02-09 23:19:4914476 spdy_util_secure.ConstructSpdyGet(url2.c_str(), 1, MEDIUM));
[email protected]2d88e7d2012-07-19 17:55:1714477
14478 MockWrite writes2[] = {
bncdf80d44fd2016-07-15 20:27:4114479 CreateMockWrite(req2, 0),
[email protected]2d88e7d2012-07-19 17:55:1714480 };
14481
bnc42331402016-07-25 13:36:1514482 SpdySerializedFrame resp2(spdy_util_secure.ConstructSpdyGetReply(NULL, 0, 1));
bncdf80d44fd2016-07-15 20:27:4114483 SpdySerializedFrame body2(spdy_util_secure.ConstructSpdyDataFrame(1, true));
14484 MockRead reads2[] = {CreateMockRead(resp2, 1), CreateMockRead(body2, 2),
mmenke666a6fea2015-12-19 04:16:3314485 MockRead(ASYNC, OK, 3)};
[email protected]2d88e7d2012-07-19 17:55:1714486
mmenke666a6fea2015-12-19 04:16:3314487 SequencedSocketData data2(reads2, arraysize(reads2), writes2,
14488 arraysize(writes2));
[email protected]2d88e7d2012-07-19 17:55:1714489 MockConnect connect_data2(ASYNC, OK);
mmenke666a6fea2015-12-19 04:16:3314490 data2.set_connect_data(connect_data2);
[email protected]2d88e7d2012-07-19 17:55:1714491
14492 // Set up a proxy config that sends HTTP requests to a proxy, and
14493 // all others direct.
14494 ProxyConfig proxy_config;
14495 proxy_config.proxy_rules().ParseFromString("http=https://proxy:443");
[email protected]bb88e1d32013-05-03 23:11:0714496 session_deps_.proxy_service.reset(new ProxyService(
danakj1fd259a02016-04-16 03:17:0914497 base::WrapUnique(new ProxyConfigServiceFixed(proxy_config)), nullptr,
csharrisonb7e3a082015-09-22 19:13:0414498 NULL));
[email protected]2d88e7d2012-07-19 17:55:1714499
bncce36dca22015-04-21 22:11:2314500 SSLSocketDataProvider ssl1(ASYNC, OK); // to the proxy
bnc3cf2a592016-08-11 14:48:3614501 ssl1.next_proto = kProtoHTTP2;
[email protected]2d88e7d2012-07-19 17:55:1714502 // Load a valid cert. Note, that this does not need to
14503 // be valid for proxy because the MockSSLClientSocket does
14504 // not actually verify it. But SpdySession will use this
14505 // to see if it is valid for the new origin
bncce36dca22015-04-21 22:11:2314506 ssl1.cert = ImportCertFromFile(GetTestCertsDirectory(), "ok_cert.pem");
wezca1070932016-05-26 20:30:5214507 ASSERT_TRUE(ssl1.cert);
mmenke666a6fea2015-12-19 04:16:3314508 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl1);
14509 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]2d88e7d2012-07-19 17:55:1714510
14511 SSLSocketDataProvider ssl2(ASYNC, OK); // to the server
bnc3cf2a592016-08-11 14:48:3614512 ssl2.next_proto = kProtoHTTP2;
mmenke666a6fea2015-12-19 04:16:3314513 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
14514 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]2d88e7d2012-07-19 17:55:1714515
[email protected]bb88e1d32013-05-03 23:11:0714516 session_deps_.host_resolver.reset(new MockCachingHostResolver());
bncce36dca22015-04-21 22:11:2314517 session_deps_.host_resolver->rules()->AddRule("news.example.org", ip_addr);
[email protected]bb88e1d32013-05-03 23:11:0714518 session_deps_.host_resolver->rules()->AddRule("proxy", ip_addr);
[email protected]2d88e7d2012-07-19 17:55:1714519
danakj1fd259a02016-04-16 03:17:0914520 std::unique_ptr<HttpNetworkSession> session = CreateSession(&session_deps_);
[email protected]2d88e7d2012-07-19 17:55:1714521
14522 // Start the first transaction to set up the SpdySession
14523 HttpRequestInfo request1;
14524 request1.method = "GET";
14525 request1.url = GURL(url1);
[email protected]2d88e7d2012-07-19 17:55:1714526 request1.load_flags = 0;
[email protected]90499482013-06-01 00:39:5014527 HttpNetworkTransaction trans1(LOWEST, session.get());
[email protected]2d88e7d2012-07-19 17:55:1714528 TestCompletionCallback callback1;
14529 ASSERT_EQ(ERR_IO_PENDING,
tfarina42834112016-09-22 13:38:2014530 trans1.Start(&request1, callback1.callback(), NetLogWithSource()));
mmenke666a6fea2015-12-19 04:16:3314531 // This pause is a hack to avoid running into https://crbug.com/497228.
14532 data1.RunUntilPaused();
14533 base::RunLoop().RunUntilIdle();
14534 data1.Resume();
[email protected]2d88e7d2012-07-19 17:55:1714535
robpercival214763f2016-07-01 23:27:0114536 EXPECT_THAT(callback1.WaitForResult(), IsOk());
[email protected]2d88e7d2012-07-19 17:55:1714537 EXPECT_TRUE(trans1.GetResponseInfo()->was_fetched_via_spdy);
14538
14539 // Now, start the HTTP request
14540 HttpRequestInfo request2;
14541 request2.method = "GET";
14542 request2.url = GURL(url2);
[email protected]2d88e7d2012-07-19 17:55:1714543 request2.load_flags = 0;
[email protected]90499482013-06-01 00:39:5014544 HttpNetworkTransaction trans2(MEDIUM, session.get());
[email protected]2d88e7d2012-07-19 17:55:1714545 TestCompletionCallback callback2;
14546 EXPECT_EQ(ERR_IO_PENDING,
tfarina42834112016-09-22 13:38:2014547 trans2.Start(&request2, callback2.callback(), NetLogWithSource()));
fdoray92e35a72016-06-10 15:54:5514548 base::RunLoop().RunUntilIdle();
[email protected]2d88e7d2012-07-19 17:55:1714549
14550 ASSERT_TRUE(callback2.have_result());
robpercival214763f2016-07-01 23:27:0114551 EXPECT_THAT(callback2.WaitForResult(), IsOk());
[email protected]2d88e7d2012-07-19 17:55:1714552 EXPECT_TRUE(trans2.GetResponseInfo()->was_fetched_via_spdy);
14553}
14554
[email protected]85f97342013-04-17 06:12:2414555// Test to verify that a failed socket read (due to an ERR_CONNECTION_CLOSED
14556// error) in SPDY session, removes the socket from pool and closes the SPDY
14557// session. Verify that new url's from the same HttpNetworkSession (and a new
14558// SpdySession) do work. http://crbug.com/224701
bncd16676a2016-07-20 16:23:0114559TEST_F(HttpNetworkTransactionTest, ErrorSocketNotConnected) {
bncce36dca22015-04-21 22:11:2314560 const std::string https_url = "https://www.example.org/";
[email protected]85f97342013-04-17 06:12:2414561
14562 MockRead reads1[] = {
14563 MockRead(SYNCHRONOUS, ERR_CONNECTION_CLOSED, 0)
14564 };
14565
mmenke11eb5152015-06-09 14:50:5014566 SequencedSocketData data1(reads1, arraysize(reads1), NULL, 0);
[email protected]85f97342013-04-17 06:12:2414567
bncdf80d44fd2016-07-15 20:27:4114568 SpdySerializedFrame req2(
bnc38dcd392016-02-09 23:19:4914569 spdy_util_.ConstructSpdyGet(https_url.c_str(), 1, MEDIUM));
[email protected]85f97342013-04-17 06:12:2414570 MockWrite writes2[] = {
bncdf80d44fd2016-07-15 20:27:4114571 CreateMockWrite(req2, 0),
[email protected]85f97342013-04-17 06:12:2414572 };
14573
bnc42331402016-07-25 13:36:1514574 SpdySerializedFrame resp2(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
bncdf80d44fd2016-07-15 20:27:4114575 SpdySerializedFrame body2(spdy_util_.ConstructSpdyDataFrame(1, true));
[email protected]85f97342013-04-17 06:12:2414576 MockRead reads2[] = {
bncdf80d44fd2016-07-15 20:27:4114577 CreateMockRead(resp2, 1), CreateMockRead(body2, 2),
14578 MockRead(ASYNC, OK, 3) // EOF
[email protected]85f97342013-04-17 06:12:2414579 };
14580
mmenke11eb5152015-06-09 14:50:5014581 SequencedSocketData data2(reads2, arraysize(reads2), writes2,
14582 arraysize(writes2));
[email protected]85f97342013-04-17 06:12:2414583
[email protected]85f97342013-04-17 06:12:2414584 SSLSocketDataProvider ssl1(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3614585 ssl1.next_proto = kProtoHTTP2;
mmenke11eb5152015-06-09 14:50:5014586 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl1);
14587 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]85f97342013-04-17 06:12:2414588
14589 SSLSocketDataProvider ssl2(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3614590 ssl2.next_proto = kProtoHTTP2;
mmenke11eb5152015-06-09 14:50:5014591 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
14592 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]85f97342013-04-17 06:12:2414593
danakj1fd259a02016-04-16 03:17:0914594 std::unique_ptr<HttpNetworkSession> session(
mmenke11eb5152015-06-09 14:50:5014595 SpdySessionDependencies::SpdyCreateSession(&session_deps_));
[email protected]85f97342013-04-17 06:12:2414596
14597 // Start the first transaction to set up the SpdySession and verify that
14598 // connection was closed.
14599 HttpRequestInfo request1;
14600 request1.method = "GET";
14601 request1.url = GURL(https_url);
14602 request1.load_flags = 0;
[email protected]90499482013-06-01 00:39:5014603 HttpNetworkTransaction trans1(MEDIUM, session.get());
[email protected]85f97342013-04-17 06:12:2414604 TestCompletionCallback callback1;
14605 EXPECT_EQ(ERR_IO_PENDING,
tfarina42834112016-09-22 13:38:2014606 trans1.Start(&request1, callback1.callback(), NetLogWithSource()));
robpercival214763f2016-07-01 23:27:0114607 EXPECT_THAT(callback1.WaitForResult(), IsError(ERR_CONNECTION_CLOSED));
[email protected]85f97342013-04-17 06:12:2414608
14609 // Now, start the second request and make sure it succeeds.
14610 HttpRequestInfo request2;
14611 request2.method = "GET";
14612 request2.url = GURL(https_url);
14613 request2.load_flags = 0;
[email protected]90499482013-06-01 00:39:5014614 HttpNetworkTransaction trans2(MEDIUM, session.get());
[email protected]85f97342013-04-17 06:12:2414615 TestCompletionCallback callback2;
14616 EXPECT_EQ(ERR_IO_PENDING,
tfarina42834112016-09-22 13:38:2014617 trans2.Start(&request2, callback2.callback(), NetLogWithSource()));
[email protected]85f97342013-04-17 06:12:2414618
robpercival214763f2016-07-01 23:27:0114619 ASSERT_THAT(callback2.WaitForResult(), IsOk());
[email protected]85f97342013-04-17 06:12:2414620 EXPECT_TRUE(trans2.GetResponseInfo()->was_fetched_via_spdy);
14621}
14622
bncd16676a2016-07-20 16:23:0114623TEST_F(HttpNetworkTransactionTest, CloseIdleSpdySessionToOpenNewOne) {
[email protected]483fa202013-05-14 01:07:0314624 ClientSocketPoolManager::set_max_sockets_per_group(
14625 HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
14626 ClientSocketPoolManager::set_max_sockets_per_pool(
14627 HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
14628
14629 // Use two different hosts with different IPs so they don't get pooled.
14630 session_deps_.host_resolver->rules()->AddRule("www.a.com", "10.0.0.1");
14631 session_deps_.host_resolver->rules()->AddRule("www.b.com", "10.0.0.2");
danakj1fd259a02016-04-16 03:17:0914632 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]483fa202013-05-14 01:07:0314633
14634 SSLSocketDataProvider ssl1(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3614635 ssl1.next_proto = kProtoHTTP2;
[email protected]483fa202013-05-14 01:07:0314636 SSLSocketDataProvider ssl2(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3614637 ssl2.next_proto = kProtoHTTP2;
[email protected]483fa202013-05-14 01:07:0314638 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl1);
14639 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
14640
bncdf80d44fd2016-07-15 20:27:4114641 SpdySerializedFrame host1_req(
bnc38dcd392016-02-09 23:19:4914642 spdy_util_.ConstructSpdyGet("https://www.a.com", 1, DEFAULT_PRIORITY));
[email protected]483fa202013-05-14 01:07:0314643 MockWrite spdy1_writes[] = {
bncdf80d44fd2016-07-15 20:27:4114644 CreateMockWrite(host1_req, 0),
[email protected]483fa202013-05-14 01:07:0314645 };
bnc42331402016-07-25 13:36:1514646 SpdySerializedFrame host1_resp(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
bncdf80d44fd2016-07-15 20:27:4114647 SpdySerializedFrame host1_resp_body(
14648 spdy_util_.ConstructSpdyDataFrame(1, true));
[email protected]483fa202013-05-14 01:07:0314649 MockRead spdy1_reads[] = {
bncdf80d44fd2016-07-15 20:27:4114650 CreateMockRead(host1_resp, 1), CreateMockRead(host1_resp_body, 2),
mmenkee24011922015-12-17 22:12:5914651 MockRead(SYNCHRONOUS, ERR_IO_PENDING, 3),
[email protected]483fa202013-05-14 01:07:0314652 };
14653
rdsmithebb50aa2015-11-12 03:44:3814654 // Use a separate test instance for the separate SpdySession that will be
14655 // created.
bncd16676a2016-07-20 16:23:0114656 SpdyTestUtil spdy_util_2;
danakj1fd259a02016-04-16 03:17:0914657 std::unique_ptr<SequencedSocketData> spdy1_data(
rch8e6c6c42015-05-01 14:05:1314658 new SequencedSocketData(spdy1_reads, arraysize(spdy1_reads), spdy1_writes,
14659 arraysize(spdy1_writes)));
[email protected]483fa202013-05-14 01:07:0314660 session_deps_.socket_factory->AddSocketDataProvider(spdy1_data.get());
14661
bncdf80d44fd2016-07-15 20:27:4114662 SpdySerializedFrame host2_req(
bnc38dcd392016-02-09 23:19:4914663 spdy_util_2.ConstructSpdyGet("https://www.b.com", 1, DEFAULT_PRIORITY));
[email protected]483fa202013-05-14 01:07:0314664 MockWrite spdy2_writes[] = {
bncdf80d44fd2016-07-15 20:27:4114665 CreateMockWrite(host2_req, 0),
[email protected]483fa202013-05-14 01:07:0314666 };
bnc42331402016-07-25 13:36:1514667 SpdySerializedFrame host2_resp(spdy_util_2.ConstructSpdyGetReply(NULL, 0, 1));
bncdf80d44fd2016-07-15 20:27:4114668 SpdySerializedFrame host2_resp_body(
14669 spdy_util_2.ConstructSpdyDataFrame(1, true));
[email protected]483fa202013-05-14 01:07:0314670 MockRead spdy2_reads[] = {
bncdf80d44fd2016-07-15 20:27:4114671 CreateMockRead(host2_resp, 1), CreateMockRead(host2_resp_body, 2),
mmenkee24011922015-12-17 22:12:5914672 MockRead(SYNCHRONOUS, ERR_IO_PENDING, 3),
[email protected]483fa202013-05-14 01:07:0314673 };
14674
danakj1fd259a02016-04-16 03:17:0914675 std::unique_ptr<SequencedSocketData> spdy2_data(
rch8e6c6c42015-05-01 14:05:1314676 new SequencedSocketData(spdy2_reads, arraysize(spdy2_reads), spdy2_writes,
14677 arraysize(spdy2_writes)));
[email protected]483fa202013-05-14 01:07:0314678 session_deps_.socket_factory->AddSocketDataProvider(spdy2_data.get());
14679
14680 MockWrite http_write[] = {
14681 MockWrite("GET / HTTP/1.1\r\n"
14682 "Host: www.a.com\r\n"
14683 "Connection: keep-alive\r\n\r\n"),
14684 };
14685
14686 MockRead http_read[] = {
14687 MockRead("HTTP/1.1 200 OK\r\n"),
14688 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
14689 MockRead("Content-Length: 6\r\n\r\n"),
14690 MockRead("hello!"),
14691 };
14692 StaticSocketDataProvider http_data(http_read, arraysize(http_read),
14693 http_write, arraysize(http_write));
14694 session_deps_.socket_factory->AddSocketDataProvider(&http_data);
14695
14696 HostPortPair host_port_pair_a("www.a.com", 443);
[email protected]e6d017652013-05-17 18:01:4014697 SpdySessionKey spdy_session_key_a(
[email protected]314b03992014-04-01 01:28:5314698 host_port_pair_a, ProxyServer::Direct(), PRIVACY_MODE_DISABLED);
[email protected]483fa202013-05-14 01:07:0314699 EXPECT_FALSE(
[email protected]41d64e82013-07-03 22:44:2614700 HasSpdySession(session->spdy_session_pool(), spdy_session_key_a));
[email protected]483fa202013-05-14 01:07:0314701
14702 TestCompletionCallback callback;
14703 HttpRequestInfo request1;
14704 request1.method = "GET";
14705 request1.url = GURL("https://www.a.com/");
14706 request1.load_flags = 0;
danakj1fd259a02016-04-16 03:17:0914707 std::unique_ptr<HttpNetworkTransaction> trans(
[email protected]90499482013-06-01 00:39:5014708 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]483fa202013-05-14 01:07:0314709
tfarina42834112016-09-22 13:38:2014710 int rv = trans->Start(&request1, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0114711 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
14712 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]483fa202013-05-14 01:07:0314713
14714 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5214715 ASSERT_TRUE(response);
14716 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0214717 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]483fa202013-05-14 01:07:0314718 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5214719 EXPECT_TRUE(response->was_alpn_negotiated);
[email protected]483fa202013-05-14 01:07:0314720
14721 std::string response_data;
robpercival214763f2016-07-01 23:27:0114722 ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
[email protected]483fa202013-05-14 01:07:0314723 EXPECT_EQ("hello!", response_data);
14724 trans.reset();
14725 EXPECT_TRUE(
[email protected]41d64e82013-07-03 22:44:2614726 HasSpdySession(session->spdy_session_pool(), spdy_session_key_a));
[email protected]483fa202013-05-14 01:07:0314727
14728 HostPortPair host_port_pair_b("www.b.com", 443);
[email protected]e6d017652013-05-17 18:01:4014729 SpdySessionKey spdy_session_key_b(
[email protected]314b03992014-04-01 01:28:5314730 host_port_pair_b, ProxyServer::Direct(), PRIVACY_MODE_DISABLED);
[email protected]483fa202013-05-14 01:07:0314731 EXPECT_FALSE(
[email protected]41d64e82013-07-03 22:44:2614732 HasSpdySession(session->spdy_session_pool(), spdy_session_key_b));
[email protected]483fa202013-05-14 01:07:0314733 HttpRequestInfo request2;
14734 request2.method = "GET";
14735 request2.url = GURL("https://www.b.com/");
14736 request2.load_flags = 0;
[email protected]90499482013-06-01 00:39:5014737 trans.reset(new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]483fa202013-05-14 01:07:0314738
tfarina42834112016-09-22 13:38:2014739 rv = trans->Start(&request2, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0114740 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
14741 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]483fa202013-05-14 01:07:0314742
14743 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5214744 ASSERT_TRUE(response);
14745 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0214746 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]483fa202013-05-14 01:07:0314747 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5214748 EXPECT_TRUE(response->was_alpn_negotiated);
robpercival214763f2016-07-01 23:27:0114749 ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
[email protected]483fa202013-05-14 01:07:0314750 EXPECT_EQ("hello!", response_data);
14751 EXPECT_FALSE(
[email protected]41d64e82013-07-03 22:44:2614752 HasSpdySession(session->spdy_session_pool(), spdy_session_key_a));
[email protected]483fa202013-05-14 01:07:0314753 EXPECT_TRUE(
[email protected]41d64e82013-07-03 22:44:2614754 HasSpdySession(session->spdy_session_pool(), spdy_session_key_b));
[email protected]483fa202013-05-14 01:07:0314755
14756 HostPortPair host_port_pair_a1("www.a.com", 80);
[email protected]e6d017652013-05-17 18:01:4014757 SpdySessionKey spdy_session_key_a1(
[email protected]314b03992014-04-01 01:28:5314758 host_port_pair_a1, ProxyServer::Direct(), PRIVACY_MODE_DISABLED);
[email protected]483fa202013-05-14 01:07:0314759 EXPECT_FALSE(
[email protected]41d64e82013-07-03 22:44:2614760 HasSpdySession(session->spdy_session_pool(), spdy_session_key_a1));
[email protected]483fa202013-05-14 01:07:0314761 HttpRequestInfo request3;
14762 request3.method = "GET";
14763 request3.url = GURL("http://www.a.com/");
14764 request3.load_flags = 0;
[email protected]90499482013-06-01 00:39:5014765 trans.reset(new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]483fa202013-05-14 01:07:0314766
tfarina42834112016-09-22 13:38:2014767 rv = trans->Start(&request3, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0114768 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
14769 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]483fa202013-05-14 01:07:0314770
14771 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5214772 ASSERT_TRUE(response);
14773 ASSERT_TRUE(response->headers);
[email protected]483fa202013-05-14 01:07:0314774 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
14775 EXPECT_FALSE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5214776 EXPECT_FALSE(response->was_alpn_negotiated);
robpercival214763f2016-07-01 23:27:0114777 ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
[email protected]483fa202013-05-14 01:07:0314778 EXPECT_EQ("hello!", response_data);
14779 EXPECT_FALSE(
[email protected]41d64e82013-07-03 22:44:2614780 HasSpdySession(session->spdy_session_pool(), spdy_session_key_a));
[email protected]483fa202013-05-14 01:07:0314781 EXPECT_FALSE(
[email protected]41d64e82013-07-03 22:44:2614782 HasSpdySession(session->spdy_session_pool(), spdy_session_key_b));
[email protected]483fa202013-05-14 01:07:0314783}
14784
bncd16676a2016-07-20 16:23:0114785TEST_F(HttpNetworkTransactionTest, HttpSyncConnectError) {
[email protected]79e1fd62013-06-20 06:50:0414786 HttpRequestInfo request;
14787 request.method = "GET";
bncce36dca22015-04-21 22:11:2314788 request.url = GURL("http://www.example.org/");
[email protected]79e1fd62013-06-20 06:50:0414789
danakj1fd259a02016-04-16 03:17:0914790 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1614791 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]79e1fd62013-06-20 06:50:0414792
ttuttled9dbc652015-09-29 20:00:5914793 MockConnect mock_connect(SYNCHRONOUS, ERR_NAME_NOT_RESOLVED);
[email protected]79e1fd62013-06-20 06:50:0414794 StaticSocketDataProvider data;
14795 data.set_connect_data(mock_connect);
14796 session_deps_.socket_factory->AddSocketDataProvider(&data);
14797
14798 TestCompletionCallback callback;
14799
tfarina42834112016-09-22 13:38:2014800 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0114801 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]79e1fd62013-06-20 06:50:0414802
14803 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0114804 EXPECT_THAT(rv, IsError(ERR_NAME_NOT_RESOLVED));
[email protected]79e1fd62013-06-20 06:50:0414805
[email protected]79e1fd62013-06-20 06:50:0414806 // We don't care whether this succeeds or fails, but it shouldn't crash.
14807 HttpRequestHeaders request_headers;
bnc691fda62016-08-12 00:43:1614808 trans.GetFullRequestHeaders(&request_headers);
ttuttle1f2d7e92015-04-28 16:17:4714809
14810 ConnectionAttempts attempts;
bnc691fda62016-08-12 00:43:1614811 trans.GetConnectionAttempts(&attempts);
ttuttle1f2d7e92015-04-28 16:17:4714812 ASSERT_EQ(1u, attempts.size());
robpercival214763f2016-07-01 23:27:0114813 EXPECT_THAT(attempts[0].result, IsError(ERR_NAME_NOT_RESOLVED));
ttuttled9dbc652015-09-29 20:00:5914814
14815 IPEndPoint endpoint;
bnc691fda62016-08-12 00:43:1614816 EXPECT_FALSE(trans.GetRemoteEndpoint(&endpoint));
ttuttled9dbc652015-09-29 20:00:5914817 EXPECT_TRUE(endpoint.address().empty());
[email protected]79e1fd62013-06-20 06:50:0414818}
14819
bncd16676a2016-07-20 16:23:0114820TEST_F(HttpNetworkTransactionTest, HttpAsyncConnectError) {
[email protected]79e1fd62013-06-20 06:50:0414821 HttpRequestInfo request;
14822 request.method = "GET";
bncce36dca22015-04-21 22:11:2314823 request.url = GURL("http://www.example.org/");
[email protected]79e1fd62013-06-20 06:50:0414824
danakj1fd259a02016-04-16 03:17:0914825 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1614826 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]79e1fd62013-06-20 06:50:0414827
ttuttled9dbc652015-09-29 20:00:5914828 MockConnect mock_connect(ASYNC, ERR_NAME_NOT_RESOLVED);
[email protected]79e1fd62013-06-20 06:50:0414829 StaticSocketDataProvider data;
14830 data.set_connect_data(mock_connect);
14831 session_deps_.socket_factory->AddSocketDataProvider(&data);
14832
14833 TestCompletionCallback callback;
14834
tfarina42834112016-09-22 13:38:2014835 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0114836 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]79e1fd62013-06-20 06:50:0414837
14838 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0114839 EXPECT_THAT(rv, IsError(ERR_NAME_NOT_RESOLVED));
[email protected]79e1fd62013-06-20 06:50:0414840
[email protected]79e1fd62013-06-20 06:50:0414841 // We don't care whether this succeeds or fails, but it shouldn't crash.
14842 HttpRequestHeaders request_headers;
bnc691fda62016-08-12 00:43:1614843 trans.GetFullRequestHeaders(&request_headers);
ttuttle1f2d7e92015-04-28 16:17:4714844
14845 ConnectionAttempts attempts;
bnc691fda62016-08-12 00:43:1614846 trans.GetConnectionAttempts(&attempts);
ttuttle1f2d7e92015-04-28 16:17:4714847 ASSERT_EQ(1u, attempts.size());
robpercival214763f2016-07-01 23:27:0114848 EXPECT_THAT(attempts[0].result, IsError(ERR_NAME_NOT_RESOLVED));
ttuttled9dbc652015-09-29 20:00:5914849
14850 IPEndPoint endpoint;
bnc691fda62016-08-12 00:43:1614851 EXPECT_FALSE(trans.GetRemoteEndpoint(&endpoint));
ttuttled9dbc652015-09-29 20:00:5914852 EXPECT_TRUE(endpoint.address().empty());
[email protected]79e1fd62013-06-20 06:50:0414853}
14854
bncd16676a2016-07-20 16:23:0114855TEST_F(HttpNetworkTransactionTest, HttpSyncWriteError) {
[email protected]79e1fd62013-06-20 06:50:0414856 HttpRequestInfo request;
14857 request.method = "GET";
bncce36dca22015-04-21 22:11:2314858 request.url = GURL("http://www.example.org/");
[email protected]79e1fd62013-06-20 06:50:0414859
danakj1fd259a02016-04-16 03:17:0914860 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1614861 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]79e1fd62013-06-20 06:50:0414862
14863 MockWrite data_writes[] = {
14864 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
14865 };
14866 MockRead data_reads[] = {
14867 MockRead(SYNCHRONOUS, ERR_UNEXPECTED), // Should not be reached.
14868 };
14869
14870 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
14871 data_writes, arraysize(data_writes));
14872 session_deps_.socket_factory->AddSocketDataProvider(&data);
14873
14874 TestCompletionCallback callback;
14875
tfarina42834112016-09-22 13:38:2014876 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0114877 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]79e1fd62013-06-20 06:50:0414878
14879 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0114880 EXPECT_THAT(rv, IsError(ERR_CONNECTION_RESET));
[email protected]79e1fd62013-06-20 06:50:0414881
[email protected]79e1fd62013-06-20 06:50:0414882 HttpRequestHeaders request_headers;
bnc691fda62016-08-12 00:43:1614883 EXPECT_TRUE(trans.GetFullRequestHeaders(&request_headers));
[email protected]79e1fd62013-06-20 06:50:0414884 EXPECT_TRUE(request_headers.HasHeader("Host"));
14885}
14886
bncd16676a2016-07-20 16:23:0114887TEST_F(HttpNetworkTransactionTest, HttpAsyncWriteError) {
[email protected]79e1fd62013-06-20 06:50:0414888 HttpRequestInfo request;
14889 request.method = "GET";
bncce36dca22015-04-21 22:11:2314890 request.url = GURL("http://www.example.org/");
[email protected]79e1fd62013-06-20 06:50:0414891
danakj1fd259a02016-04-16 03:17:0914892 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1614893 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]79e1fd62013-06-20 06:50:0414894
14895 MockWrite data_writes[] = {
14896 MockWrite(ASYNC, ERR_CONNECTION_RESET),
14897 };
14898 MockRead data_reads[] = {
14899 MockRead(SYNCHRONOUS, ERR_UNEXPECTED), // Should not be reached.
14900 };
14901
14902 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
14903 data_writes, arraysize(data_writes));
14904 session_deps_.socket_factory->AddSocketDataProvider(&data);
14905
14906 TestCompletionCallback callback;
14907
tfarina42834112016-09-22 13:38:2014908 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0114909 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]79e1fd62013-06-20 06:50:0414910
14911 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0114912 EXPECT_THAT(rv, IsError(ERR_CONNECTION_RESET));
[email protected]79e1fd62013-06-20 06:50:0414913
[email protected]79e1fd62013-06-20 06:50:0414914 HttpRequestHeaders request_headers;
bnc691fda62016-08-12 00:43:1614915 EXPECT_TRUE(trans.GetFullRequestHeaders(&request_headers));
[email protected]79e1fd62013-06-20 06:50:0414916 EXPECT_TRUE(request_headers.HasHeader("Host"));
14917}
14918
bncd16676a2016-07-20 16:23:0114919TEST_F(HttpNetworkTransactionTest, HttpSyncReadError) {
[email protected]79e1fd62013-06-20 06:50:0414920 HttpRequestInfo request;
14921 request.method = "GET";
bncce36dca22015-04-21 22:11:2314922 request.url = GURL("http://www.example.org/");
[email protected]79e1fd62013-06-20 06:50:0414923
danakj1fd259a02016-04-16 03:17:0914924 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1614925 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]79e1fd62013-06-20 06:50:0414926
14927 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:2314928 MockWrite(
14929 "GET / HTTP/1.1\r\n"
14930 "Host: www.example.org\r\n"
14931 "Connection: keep-alive\r\n\r\n"),
[email protected]79e1fd62013-06-20 06:50:0414932 };
14933 MockRead data_reads[] = {
14934 MockRead(SYNCHRONOUS, ERR_CONNECTION_RESET),
14935 };
14936
14937 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
14938 data_writes, arraysize(data_writes));
14939 session_deps_.socket_factory->AddSocketDataProvider(&data);
14940
14941 TestCompletionCallback callback;
14942
tfarina42834112016-09-22 13:38:2014943 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0114944 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]79e1fd62013-06-20 06:50:0414945
14946 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0114947 EXPECT_THAT(rv, IsError(ERR_CONNECTION_RESET));
[email protected]79e1fd62013-06-20 06:50:0414948
[email protected]79e1fd62013-06-20 06:50:0414949 HttpRequestHeaders request_headers;
bnc691fda62016-08-12 00:43:1614950 EXPECT_TRUE(trans.GetFullRequestHeaders(&request_headers));
[email protected]79e1fd62013-06-20 06:50:0414951 EXPECT_TRUE(request_headers.HasHeader("Host"));
14952}
14953
bncd16676a2016-07-20 16:23:0114954TEST_F(HttpNetworkTransactionTest, HttpAsyncReadError) {
[email protected]79e1fd62013-06-20 06:50:0414955 HttpRequestInfo request;
14956 request.method = "GET";
bncce36dca22015-04-21 22:11:2314957 request.url = GURL("http://www.example.org/");
[email protected]79e1fd62013-06-20 06:50:0414958
danakj1fd259a02016-04-16 03:17:0914959 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1614960 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]79e1fd62013-06-20 06:50:0414961
14962 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:2314963 MockWrite(
14964 "GET / HTTP/1.1\r\n"
14965 "Host: www.example.org\r\n"
14966 "Connection: keep-alive\r\n\r\n"),
[email protected]79e1fd62013-06-20 06:50:0414967 };
14968 MockRead data_reads[] = {
14969 MockRead(ASYNC, ERR_CONNECTION_RESET),
14970 };
14971
14972 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
14973 data_writes, arraysize(data_writes));
14974 session_deps_.socket_factory->AddSocketDataProvider(&data);
14975
14976 TestCompletionCallback callback;
14977
tfarina42834112016-09-22 13:38:2014978 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0114979 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]79e1fd62013-06-20 06:50:0414980
14981 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0114982 EXPECT_THAT(rv, IsError(ERR_CONNECTION_RESET));
[email protected]79e1fd62013-06-20 06:50:0414983
[email protected]79e1fd62013-06-20 06:50:0414984 HttpRequestHeaders request_headers;
bnc691fda62016-08-12 00:43:1614985 EXPECT_TRUE(trans.GetFullRequestHeaders(&request_headers));
[email protected]79e1fd62013-06-20 06:50:0414986 EXPECT_TRUE(request_headers.HasHeader("Host"));
14987}
14988
bncd16676a2016-07-20 16:23:0114989TEST_F(HttpNetworkTransactionTest, GetFullRequestHeadersIncludesExtraHeader) {
[email protected]79e1fd62013-06-20 06:50:0414990 HttpRequestInfo request;
14991 request.method = "GET";
bncce36dca22015-04-21 22:11:2314992 request.url = GURL("http://www.example.org/");
[email protected]79e1fd62013-06-20 06:50:0414993 request.extra_headers.SetHeader("X-Foo", "bar");
14994
danakj1fd259a02016-04-16 03:17:0914995 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1614996 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]79e1fd62013-06-20 06:50:0414997
14998 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:2314999 MockWrite(
15000 "GET / HTTP/1.1\r\n"
15001 "Host: www.example.org\r\n"
15002 "Connection: keep-alive\r\n"
15003 "X-Foo: bar\r\n\r\n"),
[email protected]79e1fd62013-06-20 06:50:0415004 };
15005 MockRead data_reads[] = {
15006 MockRead("HTTP/1.1 200 OK\r\n"
15007 "Content-Length: 5\r\n\r\n"
15008 "hello"),
15009 MockRead(ASYNC, ERR_UNEXPECTED),
15010 };
15011
15012 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
15013 data_writes, arraysize(data_writes));
15014 session_deps_.socket_factory->AddSocketDataProvider(&data);
15015
15016 TestCompletionCallback callback;
15017
tfarina42834112016-09-22 13:38:2015018 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0115019 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]79e1fd62013-06-20 06:50:0415020
15021 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0115022 EXPECT_THAT(rv, IsOk());
[email protected]79e1fd62013-06-20 06:50:0415023
15024 HttpRequestHeaders request_headers;
bnc691fda62016-08-12 00:43:1615025 EXPECT_TRUE(trans.GetFullRequestHeaders(&request_headers));
[email protected]79e1fd62013-06-20 06:50:0415026 std::string foo;
15027 EXPECT_TRUE(request_headers.GetHeader("X-Foo", &foo));
15028 EXPECT_EQ("bar", foo);
15029}
15030
[email protected]bf828982013-08-14 18:01:4715031namespace {
15032
yhiranoa7e05bb2014-11-06 05:40:3915033// Fake HttpStream that simply records calls to SetPriority().
15034class FakeStream : public HttpStream,
[email protected]e86839fd2013-08-14 18:29:0315035 public base::SupportsWeakPtr<FakeStream> {
15036 public:
15037 explicit FakeStream(RequestPriority priority) : priority_(priority) {}
dchengb03027d2014-10-21 12:00:2015038 ~FakeStream() override {}
[email protected]e86839fd2013-08-14 18:29:0315039
15040 RequestPriority priority() const { return priority_; }
15041
dchengb03027d2014-10-21 12:00:2015042 int InitializeStream(const HttpRequestInfo* request_info,
15043 RequestPriority priority,
tfarina42834112016-09-22 13:38:2015044 const NetLogWithSource& net_log,
dchengb03027d2014-10-21 12:00:2015045 const CompletionCallback& callback) override {
[email protected]e86839fd2013-08-14 18:29:0315046 return ERR_IO_PENDING;
15047 }
15048
dchengb03027d2014-10-21 12:00:2015049 int SendRequest(const HttpRequestHeaders& request_headers,
15050 HttpResponseInfo* response,
15051 const CompletionCallback& callback) override {
[email protected]e86839fd2013-08-14 18:29:0315052 ADD_FAILURE();
15053 return ERR_UNEXPECTED;
15054 }
15055
dchengb03027d2014-10-21 12:00:2015056 int ReadResponseHeaders(const CompletionCallback& callback) override {
[email protected]e86839fd2013-08-14 18:29:0315057 ADD_FAILURE();
15058 return ERR_UNEXPECTED;
15059 }
15060
dchengb03027d2014-10-21 12:00:2015061 int ReadResponseBody(IOBuffer* buf,
15062 int buf_len,
15063 const CompletionCallback& callback) override {
[email protected]e86839fd2013-08-14 18:29:0315064 ADD_FAILURE();
15065 return ERR_UNEXPECTED;
15066 }
15067
dchengb03027d2014-10-21 12:00:2015068 void Close(bool not_reusable) override {}
[email protected]e86839fd2013-08-14 18:29:0315069
dchengb03027d2014-10-21 12:00:2015070 bool IsResponseBodyComplete() const override {
[email protected]e86839fd2013-08-14 18:29:0315071 ADD_FAILURE();
15072 return false;
15073 }
15074
dchengb03027d2014-10-21 12:00:2015075 bool IsConnectionReused() const override {
[email protected]e86839fd2013-08-14 18:29:0315076 ADD_FAILURE();
15077 return false;
15078 }
15079
dchengb03027d2014-10-21 12:00:2015080 void SetConnectionReused() override { ADD_FAILURE(); }
[email protected]e86839fd2013-08-14 18:29:0315081
mmenkebd84c392015-09-02 14:12:3415082 bool CanReuseConnection() const override { return false; }
[email protected]e86839fd2013-08-14 18:29:0315083
sclittle4de1bab92015-09-22 21:28:2415084 int64_t GetTotalReceivedBytes() const override {
[email protected]bc92bc972013-12-13 08:32:5915085 ADD_FAILURE();
15086 return 0;
15087 }
15088
sclittlebe1ccf62015-09-02 19:40:3615089 int64_t GetTotalSentBytes() const override {
15090 ADD_FAILURE();
15091 return 0;
15092 }
15093
dchengb03027d2014-10-21 12:00:2015094 bool GetLoadTimingInfo(LoadTimingInfo* load_timing_info) const override {
[email protected]e86839fd2013-08-14 18:29:0315095 ADD_FAILURE();
15096 return false;
15097 }
15098
rchcd379012017-04-12 21:53:3215099 bool GetAlternativeService(
15100 AlternativeService* alternative_service) const override {
15101 ADD_FAILURE();
15102 return false;
15103 }
15104
dchengb03027d2014-10-21 12:00:2015105 void GetSSLInfo(SSLInfo* ssl_info) override { ADD_FAILURE(); }
15106
15107 void GetSSLCertRequestInfo(SSLCertRequestInfo* cert_request_info) override {
[email protected]e86839fd2013-08-14 18:29:0315108 ADD_FAILURE();
15109 }
15110
ttuttled9dbc652015-09-29 20:00:5915111 bool GetRemoteEndpoint(IPEndPoint* endpoint) override { return false; }
15112
nharper78e6d2b2016-09-21 05:42:3515113 Error GetTokenBindingSignature(crypto::ECPrivateKey* key,
15114 TokenBindingType tb_type,
15115 std::vector<uint8_t>* out) override {
nharperb7441ef2016-01-25 23:54:1415116 ADD_FAILURE();
15117 return ERR_NOT_IMPLEMENTED;
15118 }
15119
dchengb03027d2014-10-21 12:00:2015120 void Drain(HttpNetworkSession* session) override { ADD_FAILURE(); }
[email protected]e86839fd2013-08-14 18:29:0315121
zhongyica364fbb2015-12-12 03:39:1215122 void PopulateNetErrorDetails(NetErrorDetails* details) override { return; }
15123
dchengb03027d2014-10-21 12:00:2015124 void SetPriority(RequestPriority priority) override { priority_ = priority; }
[email protected]e86839fd2013-08-14 18:29:0315125
yhiranoa7e05bb2014-11-06 05:40:3915126 HttpStream* RenewStreamForAuth() override { return NULL; }
15127
[email protected]e86839fd2013-08-14 18:29:0315128 private:
15129 RequestPriority priority_;
15130
15131 DISALLOW_COPY_AND_ASSIGN(FakeStream);
15132};
15133
15134// Fake HttpStreamRequest that simply records calls to SetPriority()
15135// and vends FakeStreams with its current priority.
[email protected]bf828982013-08-14 18:01:4715136class FakeStreamRequest : public HttpStreamRequest,
15137 public base::SupportsWeakPtr<FakeStreamRequest> {
15138 public:
[email protected]e86839fd2013-08-14 18:29:0315139 FakeStreamRequest(RequestPriority priority,
15140 HttpStreamRequest::Delegate* delegate)
15141 : priority_(priority),
[email protected]831e4a32013-11-14 02:14:4415142 delegate_(delegate),
15143 websocket_stream_create_helper_(NULL) {}
15144
15145 FakeStreamRequest(RequestPriority priority,
15146 HttpStreamRequest::Delegate* delegate,
15147 WebSocketHandshakeStreamBase::CreateHelper* create_helper)
15148 : priority_(priority),
15149 delegate_(delegate),
15150 websocket_stream_create_helper_(create_helper) {}
[email protected]e86839fd2013-08-14 18:29:0315151
dchengb03027d2014-10-21 12:00:2015152 ~FakeStreamRequest() override {}
[email protected]bf828982013-08-14 18:01:4715153
15154 RequestPriority priority() const { return priority_; }
15155
[email protected]831e4a32013-11-14 02:14:4415156 const WebSocketHandshakeStreamBase::CreateHelper*
15157 websocket_stream_create_helper() const {
15158 return websocket_stream_create_helper_;
15159 }
15160
[email protected]e86839fd2013-08-14 18:29:0315161 // Create a new FakeStream and pass it to the request's
15162 // delegate. Returns a weak pointer to the FakeStream.
15163 base::WeakPtr<FakeStream> FinishStreamRequest() {
15164 FakeStream* fake_stream = new FakeStream(priority_);
15165 // Do this before calling OnStreamReady() as OnStreamReady() may
15166 // immediately delete |fake_stream|.
15167 base::WeakPtr<FakeStream> weak_stream = fake_stream->AsWeakPtr();
15168 delegate_->OnStreamReady(SSLConfig(), ProxyInfo(), fake_stream);
15169 return weak_stream;
15170 }
15171
asanka681f02d2017-02-22 17:06:3915172 int RestartTunnelWithProxyAuth() override {
[email protected]bf828982013-08-14 18:01:4715173 ADD_FAILURE();
15174 return ERR_UNEXPECTED;
15175 }
15176
dchengb03027d2014-10-21 12:00:2015177 LoadState GetLoadState() const override {
[email protected]bf828982013-08-14 18:01:4715178 ADD_FAILURE();
15179 return LoadState();
15180 }
15181
dchengb03027d2014-10-21 12:00:2015182 void SetPriority(RequestPriority priority) override { priority_ = priority; }
[email protected]bf828982013-08-14 18:01:4715183
bnc94c92842016-09-21 15:22:5215184 bool was_alpn_negotiated() const override { return false; }
[email protected]bf828982013-08-14 18:01:4715185
bnc6227b26e2016-08-12 02:00:4315186 NextProto negotiated_protocol() const override { return kProtoUnknown; }
[email protected]bf828982013-08-14 18:01:4715187
dchengb03027d2014-10-21 12:00:2015188 bool using_spdy() const override { return false; }
[email protected]bf828982013-08-14 18:01:4715189
ttuttle1f2d7e92015-04-28 16:17:4715190 const ConnectionAttempts& connection_attempts() const override {
15191 static ConnectionAttempts no_attempts;
15192 return no_attempts;
15193 }
15194
[email protected]bf828982013-08-14 18:01:4715195 private:
15196 RequestPriority priority_;
[email protected]e86839fd2013-08-14 18:29:0315197 HttpStreamRequest::Delegate* const delegate_;
[email protected]831e4a32013-11-14 02:14:4415198 WebSocketHandshakeStreamBase::CreateHelper* websocket_stream_create_helper_;
[email protected]bf828982013-08-14 18:01:4715199
15200 DISALLOW_COPY_AND_ASSIGN(FakeStreamRequest);
15201};
15202
15203// Fake HttpStreamFactory that vends FakeStreamRequests.
15204class FakeStreamFactory : public HttpStreamFactory {
15205 public:
15206 FakeStreamFactory() {}
dchengb03027d2014-10-21 12:00:2015207 ~FakeStreamFactory() override {}
[email protected]bf828982013-08-14 18:01:4715208
15209 // Returns a WeakPtr<> to the last HttpStreamRequest returned by
15210 // RequestStream() (which may be NULL if it was destroyed already).
15211 base::WeakPtr<FakeStreamRequest> last_stream_request() {
15212 return last_stream_request_;
15213 }
15214
dchengb03027d2014-10-21 12:00:2015215 HttpStreamRequest* RequestStream(const HttpRequestInfo& info,
15216 RequestPriority priority,
15217 const SSLConfig& server_ssl_config,
15218 const SSLConfig& proxy_ssl_config,
15219 HttpStreamRequest::Delegate* delegate,
bnc8016c1f2017-03-31 02:11:2915220 bool enable_ip_based_pooling,
bncaccd4962017-04-06 21:00:2615221 bool enable_alternative_services,
tfarina42834112016-09-22 13:38:2015222 const NetLogWithSource& net_log) override {
[email protected]e86839fd2013-08-14 18:29:0315223 FakeStreamRequest* fake_request = new FakeStreamRequest(priority, delegate);
[email protected]bf828982013-08-14 18:01:4715224 last_stream_request_ = fake_request->AsWeakPtr();
15225 return fake_request;
15226 }
15227
xunjieli5749218c2016-03-22 16:43:0615228 HttpStreamRequest* RequestBidirectionalStreamImpl(
xunjieli11834f02015-12-22 04:27:0815229 const HttpRequestInfo& info,
15230 RequestPriority priority,
15231 const SSLConfig& server_ssl_config,
15232 const SSLConfig& proxy_ssl_config,
15233 HttpStreamRequest::Delegate* delegate,
bnc8016c1f2017-03-31 02:11:2915234 bool enable_ip_based_pooling,
bncaccd4962017-04-06 21:00:2615235 bool enable_alternative_services,
tfarina42834112016-09-22 13:38:2015236 const NetLogWithSource& net_log) override {
xunjieli11834f02015-12-22 04:27:0815237 NOTREACHED();
15238 return nullptr;
15239 }
15240
dchengb03027d2014-10-21 12:00:2015241 HttpStreamRequest* RequestWebSocketHandshakeStream(
[email protected]bf828982013-08-14 18:01:4715242 const HttpRequestInfo& info,
15243 RequestPriority priority,
15244 const SSLConfig& server_ssl_config,
15245 const SSLConfig& proxy_ssl_config,
15246 HttpStreamRequest::Delegate* delegate,
[email protected]467086b2013-11-12 08:19:4615247 WebSocketHandshakeStreamBase::CreateHelper* create_helper,
bnc8016c1f2017-03-31 02:11:2915248 bool enable_ip_based_pooling,
bncaccd4962017-04-06 21:00:2615249 bool enable_alternative_services,
tfarina42834112016-09-22 13:38:2015250 const NetLogWithSource& net_log) override {
[email protected]831e4a32013-11-14 02:14:4415251 FakeStreamRequest* fake_request =
15252 new FakeStreamRequest(priority, delegate, create_helper);
15253 last_stream_request_ = fake_request->AsWeakPtr();
15254 return fake_request;
[email protected]bf828982013-08-14 18:01:4715255 }
15256
dchengb03027d2014-10-21 12:00:2015257 void PreconnectStreams(int num_streams,
nharper8cdb0fb2016-04-22 21:34:5915258 const HttpRequestInfo& info) override {
[email protected]bf828982013-08-14 18:01:4715259 ADD_FAILURE();
15260 }
15261
dchengb03027d2014-10-21 12:00:2015262 const HostMappingRules* GetHostMappingRules() const override {
[email protected]bf828982013-08-14 18:01:4715263 ADD_FAILURE();
15264 return NULL;
15265 }
15266
xunjielif5267de2017-01-20 21:18:5715267 void DumpMemoryStats(base::trace_event::ProcessMemoryDump* pmd,
15268 const std::string& parent_absolute_name) const override {
15269 ADD_FAILURE();
15270 }
15271
[email protected]bf828982013-08-14 18:01:4715272 private:
15273 base::WeakPtr<FakeStreamRequest> last_stream_request_;
15274
15275 DISALLOW_COPY_AND_ASSIGN(FakeStreamFactory);
15276};
15277
Adam Rice425cf122015-01-19 06:18:2415278// TODO(ricea): Maybe unify this with the one in
15279// url_request_http_job_unittest.cc ?
15280class FakeWebSocketBasicHandshakeStream : public WebSocketHandshakeStreamBase {
15281 public:
danakj1fd259a02016-04-16 03:17:0915282 FakeWebSocketBasicHandshakeStream(
15283 std::unique_ptr<ClientSocketHandle> connection,
15284 bool using_proxy)
mmenkea7da6da2016-09-01 21:56:5215285 : state_(std::move(connection), using_proxy, false) {}
Adam Rice425cf122015-01-19 06:18:2415286
15287 // Fake implementation of HttpStreamBase methods.
15288 // This ends up being quite "real" because this object has to really send data
15289 // on the mock socket. It might be easier to use the real implementation, but
15290 // the fact that the WebSocket code is not compiled on iOS makes that
15291 // difficult.
15292 int InitializeStream(const HttpRequestInfo* request_info,
15293 RequestPriority priority,
tfarina42834112016-09-22 13:38:2015294 const NetLogWithSource& net_log,
Adam Rice425cf122015-01-19 06:18:2415295 const CompletionCallback& callback) override {
15296 state_.Initialize(request_info, priority, net_log, callback);
15297 return OK;
15298 }
15299
15300 int SendRequest(const HttpRequestHeaders& request_headers,
15301 HttpResponseInfo* response,
15302 const CompletionCallback& callback) override {
15303 return parser()->SendRequest(state_.GenerateRequestLine(), request_headers,
15304 response, callback);
15305 }
15306
15307 int ReadResponseHeaders(const CompletionCallback& callback) override {
15308 return parser()->ReadResponseHeaders(callback);
15309 }
15310
15311 int ReadResponseBody(IOBuffer* buf,
15312 int buf_len,
15313 const CompletionCallback& callback) override {
15314 NOTREACHED();
15315 return ERR_IO_PENDING;
15316 }
15317
15318 void Close(bool not_reusable) override {
15319 if (parser())
15320 parser()->Close(true);
15321 }
15322
15323 bool IsResponseBodyComplete() const override {
15324 NOTREACHED();
15325 return false;
15326 }
15327
Adam Rice425cf122015-01-19 06:18:2415328 bool IsConnectionReused() const override {
15329 NOTREACHED();
15330 return false;
15331 }
15332 void SetConnectionReused() override { NOTREACHED(); }
15333
mmenkebd84c392015-09-02 14:12:3415334 bool CanReuseConnection() const override { return false; }
Adam Rice425cf122015-01-19 06:18:2415335
sclittle4de1bab92015-09-22 21:28:2415336 int64_t GetTotalReceivedBytes() const override {
Adam Rice425cf122015-01-19 06:18:2415337 NOTREACHED();
15338 return 0;
15339 }
15340
sclittlebe1ccf62015-09-02 19:40:3615341 int64_t GetTotalSentBytes() const override {
15342 NOTREACHED();
15343 return 0;
15344 }
15345
Adam Rice425cf122015-01-19 06:18:2415346 bool GetLoadTimingInfo(LoadTimingInfo* load_timing_info) const override {
15347 NOTREACHED();
15348 return false;
15349 }
15350
rchcd379012017-04-12 21:53:3215351 bool GetAlternativeService(
15352 AlternativeService* alternative_service) const override {
15353 ADD_FAILURE();
15354 return false;
15355 }
15356
Adam Ricecb76ac62015-02-20 05:33:2515357 void GetSSLInfo(SSLInfo* ssl_info) override {}
Adam Rice425cf122015-01-19 06:18:2415358
15359 void GetSSLCertRequestInfo(SSLCertRequestInfo* cert_request_info) override {
15360 NOTREACHED();
15361 }
15362
ttuttled9dbc652015-09-29 20:00:5915363 bool GetRemoteEndpoint(IPEndPoint* endpoint) override { return false; }
15364
nharper78e6d2b2016-09-21 05:42:3515365 Error GetTokenBindingSignature(crypto::ECPrivateKey* key,
15366 TokenBindingType tb_type,
15367 std::vector<uint8_t>* out) override {
nharperb7441ef2016-01-25 23:54:1415368 ADD_FAILURE();
15369 return ERR_NOT_IMPLEMENTED;
15370 }
15371
Adam Rice425cf122015-01-19 06:18:2415372 void Drain(HttpNetworkSession* session) override { NOTREACHED(); }
15373
zhongyica364fbb2015-12-12 03:39:1215374 void PopulateNetErrorDetails(NetErrorDetails* details) override { return; }
15375
Adam Rice425cf122015-01-19 06:18:2415376 void SetPriority(RequestPriority priority) override { NOTREACHED(); }
15377
Adam Rice425cf122015-01-19 06:18:2415378 HttpStream* RenewStreamForAuth() override {
15379 NOTREACHED();
15380 return nullptr;
15381 }
15382
15383 // Fake implementation of WebSocketHandshakeStreamBase method(s)
danakj1fd259a02016-04-16 03:17:0915384 std::unique_ptr<WebSocketStream> Upgrade() override {
Adam Rice425cf122015-01-19 06:18:2415385 NOTREACHED();
danakj1fd259a02016-04-16 03:17:0915386 return std::unique_ptr<WebSocketStream>();
Adam Rice425cf122015-01-19 06:18:2415387 }
15388
15389 private:
15390 HttpStreamParser* parser() const { return state_.parser(); }
15391 HttpBasicState state_;
15392
15393 DISALLOW_COPY_AND_ASSIGN(FakeWebSocketBasicHandshakeStream);
15394};
15395
[email protected]831e4a32013-11-14 02:14:4415396// TODO(yhirano): Split this class out into a net/websockets file, if it is
15397// worth doing.
15398class FakeWebSocketStreamCreateHelper :
15399 public WebSocketHandshakeStreamBase::CreateHelper {
15400 public:
dchengb03027d2014-10-21 12:00:2015401 WebSocketHandshakeStreamBase* CreateBasicStream(
danakj1fd259a02016-04-16 03:17:0915402 std::unique_ptr<ClientSocketHandle> connection,
mostynbba063d6032014-10-09 11:01:1315403 bool using_proxy) override {
dchengc7eeda422015-12-26 03:56:4815404 return new FakeWebSocketBasicHandshakeStream(std::move(connection),
Adam Rice425cf122015-01-19 06:18:2415405 using_proxy);
[email protected]831e4a32013-11-14 02:14:4415406 }
15407
dchengb03027d2014-10-21 12:00:2015408 WebSocketHandshakeStreamBase* CreateSpdyStream(
[email protected]831e4a32013-11-14 02:14:4415409 const base::WeakPtr<SpdySession>& session,
mostynbba063d6032014-10-09 11:01:1315410 bool use_relative_url) override {
[email protected]831e4a32013-11-14 02:14:4415411 NOTREACHED();
15412 return NULL;
15413 };
15414
dchengb03027d2014-10-21 12:00:2015415 ~FakeWebSocketStreamCreateHelper() override {}
[email protected]831e4a32013-11-14 02:14:4415416
danakj1fd259a02016-04-16 03:17:0915417 virtual std::unique_ptr<WebSocketStream> Upgrade() {
[email protected]831e4a32013-11-14 02:14:4415418 NOTREACHED();
danakj1fd259a02016-04-16 03:17:0915419 return std::unique_ptr<WebSocketStream>();
[email protected]831e4a32013-11-14 02:14:4415420 }
15421};
15422
[email protected]bf828982013-08-14 18:01:4715423} // namespace
15424
15425// Make sure that HttpNetworkTransaction passes on its priority to its
15426// stream request on start.
bncd16676a2016-07-20 16:23:0115427TEST_F(HttpNetworkTransactionTest, SetStreamRequestPriorityOnStart) {
danakj1fd259a02016-04-16 03:17:0915428 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
mmenkee65e7af2015-10-13 17:16:4215429 HttpNetworkSessionPeer peer(session.get());
[email protected]bf828982013-08-14 18:01:4715430 FakeStreamFactory* fake_factory = new FakeStreamFactory();
danakj1fd259a02016-04-16 03:17:0915431 peer.SetHttpStreamFactory(std::unique_ptr<HttpStreamFactory>(fake_factory));
[email protected]bf828982013-08-14 18:01:4715432
krasinc06a72a2016-12-21 03:42:4615433 HttpRequestInfo request;
dcheng48459ac22014-08-26 00:46:4115434 HttpNetworkTransaction trans(LOW, session.get());
[email protected]bf828982013-08-14 18:01:4715435
wezca1070932016-05-26 20:30:5215436 ASSERT_FALSE(fake_factory->last_stream_request());
[email protected]bf828982013-08-14 18:01:4715437
[email protected]bf828982013-08-14 18:01:4715438 TestCompletionCallback callback;
15439 EXPECT_EQ(ERR_IO_PENDING,
tfarina42834112016-09-22 13:38:2015440 trans.Start(&request, callback.callback(), NetLogWithSource()));
[email protected]bf828982013-08-14 18:01:4715441
15442 base::WeakPtr<FakeStreamRequest> fake_request =
15443 fake_factory->last_stream_request();
wezca1070932016-05-26 20:30:5215444 ASSERT_TRUE(fake_request);
[email protected]bf828982013-08-14 18:01:4715445 EXPECT_EQ(LOW, fake_request->priority());
15446}
15447
15448// Make sure that HttpNetworkTransaction passes on its priority
15449// updates to its stream request.
bncd16676a2016-07-20 16:23:0115450TEST_F(HttpNetworkTransactionTest, SetStreamRequestPriority) {
danakj1fd259a02016-04-16 03:17:0915451 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
mmenkee65e7af2015-10-13 17:16:4215452 HttpNetworkSessionPeer peer(session.get());
[email protected]bf828982013-08-14 18:01:4715453 FakeStreamFactory* fake_factory = new FakeStreamFactory();
danakj1fd259a02016-04-16 03:17:0915454 peer.SetHttpStreamFactory(std::unique_ptr<HttpStreamFactory>(fake_factory));
[email protected]bf828982013-08-14 18:01:4715455
krasinc06a72a2016-12-21 03:42:4615456 HttpRequestInfo request;
dcheng48459ac22014-08-26 00:46:4115457 HttpNetworkTransaction trans(LOW, session.get());
[email protected]bf828982013-08-14 18:01:4715458
[email protected]bf828982013-08-14 18:01:4715459 TestCompletionCallback callback;
15460 EXPECT_EQ(ERR_IO_PENDING,
tfarina42834112016-09-22 13:38:2015461 trans.Start(&request, callback.callback(), NetLogWithSource()));
[email protected]bf828982013-08-14 18:01:4715462
15463 base::WeakPtr<FakeStreamRequest> fake_request =
15464 fake_factory->last_stream_request();
wezca1070932016-05-26 20:30:5215465 ASSERT_TRUE(fake_request);
[email protected]bf828982013-08-14 18:01:4715466 EXPECT_EQ(LOW, fake_request->priority());
15467
15468 trans.SetPriority(LOWEST);
wezca1070932016-05-26 20:30:5215469 ASSERT_TRUE(fake_request);
[email protected]bf828982013-08-14 18:01:4715470 EXPECT_EQ(LOWEST, fake_request->priority());
15471}
15472
[email protected]e86839fd2013-08-14 18:29:0315473// Make sure that HttpNetworkTransaction passes on its priority
15474// updates to its stream.
bncd16676a2016-07-20 16:23:0115475TEST_F(HttpNetworkTransactionTest, SetStreamPriority) {
danakj1fd259a02016-04-16 03:17:0915476 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
mmenkee65e7af2015-10-13 17:16:4215477 HttpNetworkSessionPeer peer(session.get());
[email protected]e86839fd2013-08-14 18:29:0315478 FakeStreamFactory* fake_factory = new FakeStreamFactory();
danakj1fd259a02016-04-16 03:17:0915479 peer.SetHttpStreamFactory(std::unique_ptr<HttpStreamFactory>(fake_factory));
[email protected]e86839fd2013-08-14 18:29:0315480
krasinc06a72a2016-12-21 03:42:4615481 HttpRequestInfo request;
dcheng48459ac22014-08-26 00:46:4115482 HttpNetworkTransaction trans(LOW, session.get());
[email protected]e86839fd2013-08-14 18:29:0315483
[email protected]e86839fd2013-08-14 18:29:0315484 TestCompletionCallback callback;
15485 EXPECT_EQ(ERR_IO_PENDING,
tfarina42834112016-09-22 13:38:2015486 trans.Start(&request, callback.callback(), NetLogWithSource()));
[email protected]e86839fd2013-08-14 18:29:0315487
15488 base::WeakPtr<FakeStreamRequest> fake_request =
15489 fake_factory->last_stream_request();
wezca1070932016-05-26 20:30:5215490 ASSERT_TRUE(fake_request);
[email protected]e86839fd2013-08-14 18:29:0315491 base::WeakPtr<FakeStream> fake_stream = fake_request->FinishStreamRequest();
wezca1070932016-05-26 20:30:5215492 ASSERT_TRUE(fake_stream);
[email protected]e86839fd2013-08-14 18:29:0315493 EXPECT_EQ(LOW, fake_stream->priority());
15494
15495 trans.SetPriority(LOWEST);
15496 EXPECT_EQ(LOWEST, fake_stream->priority());
15497}
15498
bncd16676a2016-07-20 16:23:0115499TEST_F(HttpNetworkTransactionTest, CreateWebSocketHandshakeStream) {
[email protected]831e4a32013-11-14 02:14:4415500 // The same logic needs to be tested for both ws: and wss: schemes, but this
15501 // test is already parameterised on NextProto, so it uses a loop to verify
15502 // that the different schemes work.
bncce36dca22015-04-21 22:11:2315503 std::string test_cases[] = {"ws://www.example.org/",
15504 "wss://www.example.org/"};
[email protected]831e4a32013-11-14 02:14:4415505 for (size_t i = 0; i < arraysize(test_cases); ++i) {
danakj1fd259a02016-04-16 03:17:0915506 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
mmenkee65e7af2015-10-13 17:16:4215507 HttpNetworkSessionPeer peer(session.get());
[email protected]831e4a32013-11-14 02:14:4415508 FakeStreamFactory* fake_factory = new FakeStreamFactory();
15509 FakeWebSocketStreamCreateHelper websocket_stream_create_helper;
[email protected]0191b51c2013-11-18 10:55:2315510 peer.SetHttpStreamFactoryForWebSocket(
danakj1fd259a02016-04-16 03:17:0915511 std::unique_ptr<HttpStreamFactory>(fake_factory));
[email protected]831e4a32013-11-14 02:14:4415512
krasinc06a72a2016-12-21 03:42:4615513 HttpRequestInfo request;
dcheng48459ac22014-08-26 00:46:4115514 HttpNetworkTransaction trans(LOW, session.get());
[email protected]831e4a32013-11-14 02:14:4415515 trans.SetWebSocketHandshakeStreamCreateHelper(
15516 &websocket_stream_create_helper);
15517
[email protected]831e4a32013-11-14 02:14:4415518 TestCompletionCallback callback;
15519 request.method = "GET";
15520 request.url = GURL(test_cases[i]);
15521
15522 EXPECT_EQ(ERR_IO_PENDING,
tfarina42834112016-09-22 13:38:2015523 trans.Start(&request, callback.callback(), NetLogWithSource()));
[email protected]831e4a32013-11-14 02:14:4415524
15525 base::WeakPtr<FakeStreamRequest> fake_request =
15526 fake_factory->last_stream_request();
wezca1070932016-05-26 20:30:5215527 ASSERT_TRUE(fake_request);
[email protected]831e4a32013-11-14 02:14:4415528 EXPECT_EQ(&websocket_stream_create_helper,
15529 fake_request->websocket_stream_create_helper());
15530 }
15531}
15532
[email protected]043b68c82013-08-22 23:41:5215533// Tests that when a used socket is returned to the SSL socket pool, it's closed
15534// if the transport socket pool is stalled on the global socket limit.
bncd16676a2016-07-20 16:23:0115535TEST_F(HttpNetworkTransactionTest, CloseSSLSocketOnIdleForHttpRequest) {
[email protected]043b68c82013-08-22 23:41:5215536 ClientSocketPoolManager::set_max_sockets_per_group(
15537 HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
15538 ClientSocketPoolManager::set_max_sockets_per_pool(
15539 HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
15540
15541 // Set up SSL request.
15542
15543 HttpRequestInfo ssl_request;
15544 ssl_request.method = "GET";
bncce36dca22015-04-21 22:11:2315545 ssl_request.url = GURL("https://www.example.org/");
[email protected]043b68c82013-08-22 23:41:5215546
15547 MockWrite ssl_writes[] = {
bncce36dca22015-04-21 22:11:2315548 MockWrite(
15549 "GET / HTTP/1.1\r\n"
15550 "Host: www.example.org\r\n"
15551 "Connection: keep-alive\r\n\r\n"),
[email protected]043b68c82013-08-22 23:41:5215552 };
15553 MockRead ssl_reads[] = {
15554 MockRead("HTTP/1.1 200 OK\r\n"),
15555 MockRead("Content-Length: 11\r\n\r\n"),
15556 MockRead("hello world"),
15557 MockRead(SYNCHRONOUS, OK),
15558 };
15559 StaticSocketDataProvider ssl_data(ssl_reads, arraysize(ssl_reads),
15560 ssl_writes, arraysize(ssl_writes));
15561 session_deps_.socket_factory->AddSocketDataProvider(&ssl_data);
15562
15563 SSLSocketDataProvider ssl(ASYNC, OK);
15564 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
15565
15566 // Set up HTTP request.
15567
15568 HttpRequestInfo http_request;
15569 http_request.method = "GET";
bncce36dca22015-04-21 22:11:2315570 http_request.url = GURL("http://www.example.org/");
[email protected]043b68c82013-08-22 23:41:5215571
15572 MockWrite http_writes[] = {
bncce36dca22015-04-21 22:11:2315573 MockWrite(
15574 "GET / HTTP/1.1\r\n"
15575 "Host: www.example.org\r\n"
15576 "Connection: keep-alive\r\n\r\n"),
[email protected]043b68c82013-08-22 23:41:5215577 };
15578 MockRead http_reads[] = {
15579 MockRead("HTTP/1.1 200 OK\r\n"),
15580 MockRead("Content-Length: 7\r\n\r\n"),
15581 MockRead("falafel"),
15582 MockRead(SYNCHRONOUS, OK),
15583 };
15584 StaticSocketDataProvider http_data(http_reads, arraysize(http_reads),
15585 http_writes, arraysize(http_writes));
15586 session_deps_.socket_factory->AddSocketDataProvider(&http_data);
15587
danakj1fd259a02016-04-16 03:17:0915588 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]043b68c82013-08-22 23:41:5215589
15590 // Start the SSL request.
15591 TestCompletionCallback ssl_callback;
bnc691fda62016-08-12 00:43:1615592 HttpNetworkTransaction ssl_trans(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:2015593 ASSERT_EQ(ERR_IO_PENDING,
15594 ssl_trans.Start(&ssl_request, ssl_callback.callback(),
15595 NetLogWithSource()));
[email protected]043b68c82013-08-22 23:41:5215596
15597 // Start the HTTP request. Pool should stall.
15598 TestCompletionCallback http_callback;
bnc691fda62016-08-12 00:43:1615599 HttpNetworkTransaction http_trans(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:2015600 ASSERT_EQ(ERR_IO_PENDING,
15601 http_trans.Start(&http_request, http_callback.callback(),
15602 NetLogWithSource()));
dcheng48459ac22014-08-26 00:46:4115603 EXPECT_TRUE(IsTransportSocketPoolStalled(session.get()));
[email protected]043b68c82013-08-22 23:41:5215604
15605 // Wait for response from SSL request.
robpercival214763f2016-07-01 23:27:0115606 ASSERT_THAT(ssl_callback.WaitForResult(), IsOk());
[email protected]043b68c82013-08-22 23:41:5215607 std::string response_data;
bnc691fda62016-08-12 00:43:1615608 ASSERT_THAT(ReadTransaction(&ssl_trans, &response_data), IsOk());
[email protected]043b68c82013-08-22 23:41:5215609 EXPECT_EQ("hello world", response_data);
15610
15611 // The SSL socket should automatically be closed, so the HTTP request can
15612 // start.
dcheng48459ac22014-08-26 00:46:4115613 EXPECT_EQ(0, GetIdleSocketCountInSSLSocketPool(session.get()));
15614 ASSERT_FALSE(IsTransportSocketPoolStalled(session.get()));
[email protected]043b68c82013-08-22 23:41:5215615
15616 // The HTTP request can now complete.
robpercival214763f2016-07-01 23:27:0115617 ASSERT_THAT(http_callback.WaitForResult(), IsOk());
bnc691fda62016-08-12 00:43:1615618 ASSERT_THAT(ReadTransaction(&http_trans, &response_data), IsOk());
[email protected]043b68c82013-08-22 23:41:5215619 EXPECT_EQ("falafel", response_data);
15620
dcheng48459ac22014-08-26 00:46:4115621 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]043b68c82013-08-22 23:41:5215622}
15623
15624// Tests that when a SSL connection is established but there's no corresponding
15625// request that needs it, the new socket is closed if the transport socket pool
15626// is stalled on the global socket limit.
bncd16676a2016-07-20 16:23:0115627TEST_F(HttpNetworkTransactionTest, CloseSSLSocketOnIdleForHttpRequest2) {
[email protected]043b68c82013-08-22 23:41:5215628 ClientSocketPoolManager::set_max_sockets_per_group(
15629 HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
15630 ClientSocketPoolManager::set_max_sockets_per_pool(
15631 HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
15632
15633 // Set up an ssl request.
15634
15635 HttpRequestInfo ssl_request;
15636 ssl_request.method = "GET";
15637 ssl_request.url = GURL("https://www.foopy.com/");
15638
15639 // No data will be sent on the SSL socket.
15640 StaticSocketDataProvider ssl_data;
15641 session_deps_.socket_factory->AddSocketDataProvider(&ssl_data);
15642
15643 SSLSocketDataProvider ssl(ASYNC, OK);
15644 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
15645
15646 // Set up HTTP request.
15647
15648 HttpRequestInfo http_request;
15649 http_request.method = "GET";
bncce36dca22015-04-21 22:11:2315650 http_request.url = GURL("http://www.example.org/");
[email protected]043b68c82013-08-22 23:41:5215651
15652 MockWrite http_writes[] = {
bncce36dca22015-04-21 22:11:2315653 MockWrite(
15654 "GET / HTTP/1.1\r\n"
15655 "Host: www.example.org\r\n"
15656 "Connection: keep-alive\r\n\r\n"),
[email protected]043b68c82013-08-22 23:41:5215657 };
15658 MockRead http_reads[] = {
15659 MockRead("HTTP/1.1 200 OK\r\n"),
15660 MockRead("Content-Length: 7\r\n\r\n"),
15661 MockRead("falafel"),
15662 MockRead(SYNCHRONOUS, OK),
15663 };
15664 StaticSocketDataProvider http_data(http_reads, arraysize(http_reads),
15665 http_writes, arraysize(http_writes));
15666 session_deps_.socket_factory->AddSocketDataProvider(&http_data);
15667
danakj1fd259a02016-04-16 03:17:0915668 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]043b68c82013-08-22 23:41:5215669
15670 // Preconnect an SSL socket. A preconnect is needed because connect jobs are
15671 // cancelled when a normal transaction is cancelled.
ttuttle859dc7a2015-04-23 19:42:2915672 HttpStreamFactory* http_stream_factory = session->http_stream_factory();
nharper8cdb0fb2016-04-22 21:34:5915673 http_stream_factory->PreconnectStreams(1, ssl_request);
dcheng48459ac22014-08-26 00:46:4115674 EXPECT_EQ(0, GetIdleSocketCountInSSLSocketPool(session.get()));
[email protected]043b68c82013-08-22 23:41:5215675
15676 // Start the HTTP request. Pool should stall.
15677 TestCompletionCallback http_callback;
bnc691fda62016-08-12 00:43:1615678 HttpNetworkTransaction http_trans(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:2015679 ASSERT_EQ(ERR_IO_PENDING,
15680 http_trans.Start(&http_request, http_callback.callback(),
15681 NetLogWithSource()));
dcheng48459ac22014-08-26 00:46:4115682 EXPECT_TRUE(IsTransportSocketPoolStalled(session.get()));
[email protected]043b68c82013-08-22 23:41:5215683
15684 // The SSL connection will automatically be closed once the connection is
15685 // established, to let the HTTP request start.
robpercival214763f2016-07-01 23:27:0115686 ASSERT_THAT(http_callback.WaitForResult(), IsOk());
[email protected]043b68c82013-08-22 23:41:5215687 std::string response_data;
bnc691fda62016-08-12 00:43:1615688 ASSERT_THAT(ReadTransaction(&http_trans, &response_data), IsOk());
[email protected]043b68c82013-08-22 23:41:5215689 EXPECT_EQ("falafel", response_data);
15690
dcheng48459ac22014-08-26 00:46:4115691 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]043b68c82013-08-22 23:41:5215692}
15693
bncd16676a2016-07-20 16:23:0115694TEST_F(HttpNetworkTransactionTest, PostReadsErrorResponseAfterReset) {
danakj1fd259a02016-04-16 03:17:0915695 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:2215696 element_readers.push_back(
ricea2deef682016-09-09 08:04:0715697 base::MakeUnique<UploadBytesElementReader>("foo", 3));
olli.raula6df48b2a2015-11-26 07:40:2215698 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]02d74a02014-04-23 18:10:5415699
15700 HttpRequestInfo request;
15701 request.method = "POST";
15702 request.url = GURL("http://www.foo.com/");
15703 request.upload_data_stream = &upload_data_stream;
[email protected]02d74a02014-04-23 18:10:5415704
danakj1fd259a02016-04-16 03:17:0915705 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1615706 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]02d74a02014-04-23 18:10:5415707 // Send headers successfully, but get an error while sending the body.
15708 MockWrite data_writes[] = {
15709 MockWrite("POST / HTTP/1.1\r\n"
15710 "Host: www.foo.com\r\n"
15711 "Connection: keep-alive\r\n"
15712 "Content-Length: 3\r\n\r\n"),
15713 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
15714 };
15715
15716 MockRead data_reads[] = {
15717 MockRead("HTTP/1.0 400 Not OK\r\n\r\n"),
15718 MockRead("hello world"),
15719 MockRead(SYNCHRONOUS, OK),
15720 };
15721 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
15722 arraysize(data_writes));
15723 session_deps_.socket_factory->AddSocketDataProvider(&data);
15724
15725 TestCompletionCallback callback;
15726
tfarina42834112016-09-22 13:38:2015727 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0115728 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]02d74a02014-04-23 18:10:5415729
15730 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0115731 EXPECT_THAT(rv, IsOk());
[email protected]02d74a02014-04-23 18:10:5415732
bnc691fda62016-08-12 00:43:1615733 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5215734 ASSERT_TRUE(response);
[email protected]02d74a02014-04-23 18:10:5415735
wezca1070932016-05-26 20:30:5215736 EXPECT_TRUE(response->headers);
[email protected]02d74a02014-04-23 18:10:5415737 EXPECT_EQ("HTTP/1.0 400 Not OK", response->headers->GetStatusLine());
15738
15739 std::string response_data;
bnc691fda62016-08-12 00:43:1615740 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:0115741 EXPECT_THAT(rv, IsOk());
[email protected]02d74a02014-04-23 18:10:5415742 EXPECT_EQ("hello world", response_data);
15743}
15744
15745// This test makes sure the retry logic doesn't trigger when reading an error
15746// response from a server that rejected a POST with a CONNECTION_RESET.
bncd16676a2016-07-20 16:23:0115747TEST_F(HttpNetworkTransactionTest,
[email protected]02d74a02014-04-23 18:10:5415748 PostReadsErrorResponseAfterResetOnReusedSocket) {
danakj1fd259a02016-04-16 03:17:0915749 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]02d74a02014-04-23 18:10:5415750 MockWrite data_writes[] = {
15751 MockWrite("GET / HTTP/1.1\r\n"
15752 "Host: www.foo.com\r\n"
15753 "Connection: keep-alive\r\n\r\n"),
15754 MockWrite("POST / HTTP/1.1\r\n"
15755 "Host: www.foo.com\r\n"
15756 "Connection: keep-alive\r\n"
15757 "Content-Length: 3\r\n\r\n"),
15758 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
15759 };
15760
15761 MockRead data_reads[] = {
15762 MockRead("HTTP/1.1 200 Peachy\r\n"
15763 "Content-Length: 14\r\n\r\n"),
15764 MockRead("first response"),
15765 MockRead("HTTP/1.1 400 Not OK\r\n"
15766 "Content-Length: 15\r\n\r\n"),
15767 MockRead("second response"),
15768 MockRead(SYNCHRONOUS, OK),
15769 };
15770 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
15771 arraysize(data_writes));
15772 session_deps_.socket_factory->AddSocketDataProvider(&data);
15773
15774 TestCompletionCallback callback;
15775 HttpRequestInfo request1;
15776 request1.method = "GET";
15777 request1.url = GURL("http://www.foo.com/");
15778 request1.load_flags = 0;
15779
bnc691fda62016-08-12 00:43:1615780 std::unique_ptr<HttpNetworkTransaction> trans1(
dcheng48459ac22014-08-26 00:46:4115781 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
tfarina42834112016-09-22 13:38:2015782 int rv = trans1->Start(&request1, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0115783 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]02d74a02014-04-23 18:10:5415784
15785 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0115786 EXPECT_THAT(rv, IsOk());
[email protected]02d74a02014-04-23 18:10:5415787
15788 const HttpResponseInfo* response1 = trans1->GetResponseInfo();
wezca1070932016-05-26 20:30:5215789 ASSERT_TRUE(response1);
[email protected]02d74a02014-04-23 18:10:5415790
wezca1070932016-05-26 20:30:5215791 EXPECT_TRUE(response1->headers);
[email protected]02d74a02014-04-23 18:10:5415792 EXPECT_EQ("HTTP/1.1 200 Peachy", response1->headers->GetStatusLine());
15793
15794 std::string response_data1;
15795 rv = ReadTransaction(trans1.get(), &response_data1);
robpercival214763f2016-07-01 23:27:0115796 EXPECT_THAT(rv, IsOk());
[email protected]02d74a02014-04-23 18:10:5415797 EXPECT_EQ("first response", response_data1);
15798 // Delete the transaction to release the socket back into the socket pool.
15799 trans1.reset();
15800
danakj1fd259a02016-04-16 03:17:0915801 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:2215802 element_readers.push_back(
danakj1fd259a02016-04-16 03:17:0915803 base::WrapUnique(new UploadBytesElementReader("foo", 3)));
olli.raula6df48b2a2015-11-26 07:40:2215804 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]02d74a02014-04-23 18:10:5415805
15806 HttpRequestInfo request2;
15807 request2.method = "POST";
15808 request2.url = GURL("http://www.foo.com/");
15809 request2.upload_data_stream = &upload_data_stream;
15810 request2.load_flags = 0;
15811
bnc691fda62016-08-12 00:43:1615812 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:2015813 rv = trans2.Start(&request2, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0115814 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]02d74a02014-04-23 18:10:5415815
15816 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0115817 EXPECT_THAT(rv, IsOk());
[email protected]02d74a02014-04-23 18:10:5415818
bnc691fda62016-08-12 00:43:1615819 const HttpResponseInfo* response2 = trans2.GetResponseInfo();
wezca1070932016-05-26 20:30:5215820 ASSERT_TRUE(response2);
[email protected]02d74a02014-04-23 18:10:5415821
wezca1070932016-05-26 20:30:5215822 EXPECT_TRUE(response2->headers);
[email protected]02d74a02014-04-23 18:10:5415823 EXPECT_EQ("HTTP/1.1 400 Not OK", response2->headers->GetStatusLine());
15824
15825 std::string response_data2;
bnc691fda62016-08-12 00:43:1615826 rv = ReadTransaction(&trans2, &response_data2);
robpercival214763f2016-07-01 23:27:0115827 EXPECT_THAT(rv, IsOk());
[email protected]02d74a02014-04-23 18:10:5415828 EXPECT_EQ("second response", response_data2);
15829}
15830
bncd16676a2016-07-20 16:23:0115831TEST_F(HttpNetworkTransactionTest,
[email protected]02d74a02014-04-23 18:10:5415832 PostReadsErrorResponseAfterResetPartialBodySent) {
danakj1fd259a02016-04-16 03:17:0915833 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:2215834 element_readers.push_back(
ricea2deef682016-09-09 08:04:0715835 base::MakeUnique<UploadBytesElementReader>("foo", 3));
olli.raula6df48b2a2015-11-26 07:40:2215836 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]02d74a02014-04-23 18:10:5415837
15838 HttpRequestInfo request;
15839 request.method = "POST";
15840 request.url = GURL("http://www.foo.com/");
15841 request.upload_data_stream = &upload_data_stream;
[email protected]02d74a02014-04-23 18:10:5415842
danakj1fd259a02016-04-16 03:17:0915843 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1615844 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]02d74a02014-04-23 18:10:5415845 // Send headers successfully, but get an error while sending the body.
15846 MockWrite data_writes[] = {
15847 MockWrite("POST / HTTP/1.1\r\n"
15848 "Host: www.foo.com\r\n"
15849 "Connection: keep-alive\r\n"
15850 "Content-Length: 3\r\n\r\n"
15851 "fo"),
15852 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
15853 };
15854
15855 MockRead data_reads[] = {
15856 MockRead("HTTP/1.0 400 Not OK\r\n\r\n"),
15857 MockRead("hello world"),
15858 MockRead(SYNCHRONOUS, OK),
15859 };
15860 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
15861 arraysize(data_writes));
15862 session_deps_.socket_factory->AddSocketDataProvider(&data);
15863
15864 TestCompletionCallback callback;
15865
tfarina42834112016-09-22 13:38:2015866 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0115867 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]02d74a02014-04-23 18:10:5415868
15869 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0115870 EXPECT_THAT(rv, IsOk());
[email protected]02d74a02014-04-23 18:10:5415871
bnc691fda62016-08-12 00:43:1615872 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5215873 ASSERT_TRUE(response);
[email protected]02d74a02014-04-23 18:10:5415874
wezca1070932016-05-26 20:30:5215875 EXPECT_TRUE(response->headers);
[email protected]02d74a02014-04-23 18:10:5415876 EXPECT_EQ("HTTP/1.0 400 Not OK", response->headers->GetStatusLine());
15877
15878 std::string response_data;
bnc691fda62016-08-12 00:43:1615879 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:0115880 EXPECT_THAT(rv, IsOk());
[email protected]02d74a02014-04-23 18:10:5415881 EXPECT_EQ("hello world", response_data);
15882}
15883
15884// This tests the more common case than the previous test, where headers and
15885// body are not merged into a single request.
bncd16676a2016-07-20 16:23:0115886TEST_F(HttpNetworkTransactionTest, ChunkedPostReadsErrorResponseAfterReset) {
mmenkecbc2b712014-10-09 20:29:0715887 ChunkedUploadDataStream upload_data_stream(0);
[email protected]02d74a02014-04-23 18:10:5415888
15889 HttpRequestInfo request;
15890 request.method = "POST";
15891 request.url = GURL("http://www.foo.com/");
15892 request.upload_data_stream = &upload_data_stream;
[email protected]02d74a02014-04-23 18:10:5415893
danakj1fd259a02016-04-16 03:17:0915894 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1615895 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]02d74a02014-04-23 18:10:5415896 // Send headers successfully, but get an error while sending the body.
15897 MockWrite data_writes[] = {
15898 MockWrite("POST / HTTP/1.1\r\n"
15899 "Host: www.foo.com\r\n"
15900 "Connection: keep-alive\r\n"
15901 "Transfer-Encoding: chunked\r\n\r\n"),
15902 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
15903 };
15904
15905 MockRead data_reads[] = {
15906 MockRead("HTTP/1.0 400 Not OK\r\n\r\n"),
15907 MockRead("hello world"),
15908 MockRead(SYNCHRONOUS, OK),
15909 };
15910 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
15911 arraysize(data_writes));
15912 session_deps_.socket_factory->AddSocketDataProvider(&data);
15913
15914 TestCompletionCallback callback;
15915
tfarina42834112016-09-22 13:38:2015916 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0115917 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]02d74a02014-04-23 18:10:5415918 // Make sure the headers are sent before adding a chunk. This ensures that
15919 // they can't be merged with the body in a single send. Not currently
15920 // necessary since a chunked body is never merged with headers, but this makes
15921 // the test more future proof.
15922 base::RunLoop().RunUntilIdle();
15923
mmenkecbc2b712014-10-09 20:29:0715924 upload_data_stream.AppendData("last chunk", 10, true);
[email protected]02d74a02014-04-23 18:10:5415925
15926 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0115927 EXPECT_THAT(rv, IsOk());
[email protected]02d74a02014-04-23 18:10:5415928
bnc691fda62016-08-12 00:43:1615929 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5215930 ASSERT_TRUE(response);
[email protected]02d74a02014-04-23 18:10:5415931
wezca1070932016-05-26 20:30:5215932 EXPECT_TRUE(response->headers);
[email protected]02d74a02014-04-23 18:10:5415933 EXPECT_EQ("HTTP/1.0 400 Not OK", response->headers->GetStatusLine());
15934
15935 std::string response_data;
bnc691fda62016-08-12 00:43:1615936 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:0115937 EXPECT_THAT(rv, IsOk());
[email protected]02d74a02014-04-23 18:10:5415938 EXPECT_EQ("hello world", response_data);
15939}
15940
bncd16676a2016-07-20 16:23:0115941TEST_F(HttpNetworkTransactionTest, PostReadsErrorResponseAfterResetAnd100) {
danakj1fd259a02016-04-16 03:17:0915942 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:2215943 element_readers.push_back(
ricea2deef682016-09-09 08:04:0715944 base::MakeUnique<UploadBytesElementReader>("foo", 3));
olli.raula6df48b2a2015-11-26 07:40:2215945 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]02d74a02014-04-23 18:10:5415946
15947 HttpRequestInfo request;
15948 request.method = "POST";
15949 request.url = GURL("http://www.foo.com/");
15950 request.upload_data_stream = &upload_data_stream;
[email protected]02d74a02014-04-23 18:10:5415951
danakj1fd259a02016-04-16 03:17:0915952 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1615953 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]02d74a02014-04-23 18:10:5415954
15955 MockWrite data_writes[] = {
15956 MockWrite("POST / HTTP/1.1\r\n"
15957 "Host: www.foo.com\r\n"
15958 "Connection: keep-alive\r\n"
15959 "Content-Length: 3\r\n\r\n"),
15960 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
15961 };
15962
15963 MockRead data_reads[] = {
15964 MockRead("HTTP/1.0 100 Continue\r\n\r\n"),
15965 MockRead("HTTP/1.0 400 Not OK\r\n\r\n"),
15966 MockRead("hello world"),
15967 MockRead(SYNCHRONOUS, OK),
15968 };
15969 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
15970 arraysize(data_writes));
15971 session_deps_.socket_factory->AddSocketDataProvider(&data);
15972
15973 TestCompletionCallback callback;
15974
tfarina42834112016-09-22 13:38:2015975 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0115976 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]02d74a02014-04-23 18:10:5415977
15978 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0115979 EXPECT_THAT(rv, IsOk());
[email protected]02d74a02014-04-23 18:10:5415980
bnc691fda62016-08-12 00:43:1615981 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5215982 ASSERT_TRUE(response);
[email protected]02d74a02014-04-23 18:10:5415983
wezca1070932016-05-26 20:30:5215984 EXPECT_TRUE(response->headers);
[email protected]02d74a02014-04-23 18:10:5415985 EXPECT_EQ("HTTP/1.0 400 Not OK", response->headers->GetStatusLine());
15986
15987 std::string response_data;
bnc691fda62016-08-12 00:43:1615988 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:0115989 EXPECT_THAT(rv, IsOk());
[email protected]02d74a02014-04-23 18:10:5415990 EXPECT_EQ("hello world", response_data);
15991}
15992
bncd16676a2016-07-20 16:23:0115993TEST_F(HttpNetworkTransactionTest, PostIgnoresNonErrorResponseAfterReset) {
danakj1fd259a02016-04-16 03:17:0915994 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:2215995 element_readers.push_back(
ricea2deef682016-09-09 08:04:0715996 base::MakeUnique<UploadBytesElementReader>("foo", 3));
olli.raula6df48b2a2015-11-26 07:40:2215997 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]02d74a02014-04-23 18:10:5415998
15999 HttpRequestInfo request;
16000 request.method = "POST";
16001 request.url = GURL("http://www.foo.com/");
16002 request.upload_data_stream = &upload_data_stream;
[email protected]02d74a02014-04-23 18:10:5416003
danakj1fd259a02016-04-16 03:17:0916004 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1616005 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]02d74a02014-04-23 18:10:5416006 // Send headers successfully, but get an error while sending the body.
16007 MockWrite data_writes[] = {
16008 MockWrite("POST / HTTP/1.1\r\n"
16009 "Host: www.foo.com\r\n"
16010 "Connection: keep-alive\r\n"
16011 "Content-Length: 3\r\n\r\n"),
16012 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
16013 };
16014
16015 MockRead data_reads[] = {
16016 MockRead("HTTP/1.0 200 Just Dandy\r\n\r\n"),
16017 MockRead("hello world"),
16018 MockRead(SYNCHRONOUS, OK),
16019 };
16020 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
16021 arraysize(data_writes));
16022 session_deps_.socket_factory->AddSocketDataProvider(&data);
16023
16024 TestCompletionCallback callback;
16025
tfarina42834112016-09-22 13:38:2016026 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0116027 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]02d74a02014-04-23 18:10:5416028
16029 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0116030 EXPECT_THAT(rv, IsError(ERR_CONNECTION_RESET));
[email protected]02d74a02014-04-23 18:10:5416031}
16032
bncd16676a2016-07-20 16:23:0116033TEST_F(HttpNetworkTransactionTest,
[email protected]02d74a02014-04-23 18:10:5416034 PostIgnoresNonErrorResponseAfterResetAnd100) {
danakj1fd259a02016-04-16 03:17:0916035 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:2216036 element_readers.push_back(
ricea2deef682016-09-09 08:04:0716037 base::MakeUnique<UploadBytesElementReader>("foo", 3));
olli.raula6df48b2a2015-11-26 07:40:2216038 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]02d74a02014-04-23 18:10:5416039
16040 HttpRequestInfo request;
16041 request.method = "POST";
16042 request.url = GURL("http://www.foo.com/");
16043 request.upload_data_stream = &upload_data_stream;
[email protected]02d74a02014-04-23 18:10:5416044
danakj1fd259a02016-04-16 03:17:0916045 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1616046 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]02d74a02014-04-23 18:10:5416047 // Send headers successfully, but get an error while sending the body.
16048 MockWrite data_writes[] = {
16049 MockWrite("POST / HTTP/1.1\r\n"
16050 "Host: www.foo.com\r\n"
16051 "Connection: keep-alive\r\n"
16052 "Content-Length: 3\r\n\r\n"),
16053 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
16054 };
16055
16056 MockRead data_reads[] = {
16057 MockRead("HTTP/1.0 100 Continue\r\n\r\n"),
16058 MockRead("HTTP/1.0 302 Redirect\r\n"),
16059 MockRead("Location: http://somewhere-else.com/\r\n"),
16060 MockRead("Content-Length: 0\r\n\r\n"),
16061 MockRead(SYNCHRONOUS, OK),
16062 };
16063 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
16064 arraysize(data_writes));
16065 session_deps_.socket_factory->AddSocketDataProvider(&data);
16066
16067 TestCompletionCallback callback;
16068
tfarina42834112016-09-22 13:38:2016069 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0116070 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]02d74a02014-04-23 18:10:5416071
16072 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0116073 EXPECT_THAT(rv, IsError(ERR_CONNECTION_RESET));
[email protected]02d74a02014-04-23 18:10:5416074}
16075
bncd16676a2016-07-20 16:23:0116076TEST_F(HttpNetworkTransactionTest, PostIgnoresHttp09ResponseAfterReset) {
danakj1fd259a02016-04-16 03:17:0916077 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:2216078 element_readers.push_back(
ricea2deef682016-09-09 08:04:0716079 base::MakeUnique<UploadBytesElementReader>("foo", 3));
olli.raula6df48b2a2015-11-26 07:40:2216080 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]02d74a02014-04-23 18:10:5416081
16082 HttpRequestInfo request;
16083 request.method = "POST";
16084 request.url = GURL("http://www.foo.com/");
16085 request.upload_data_stream = &upload_data_stream;
[email protected]02d74a02014-04-23 18:10:5416086
danakj1fd259a02016-04-16 03:17:0916087 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1616088 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]02d74a02014-04-23 18:10:5416089 // Send headers successfully, but get an error while sending the body.
16090 MockWrite data_writes[] = {
16091 MockWrite("POST / HTTP/1.1\r\n"
16092 "Host: www.foo.com\r\n"
16093 "Connection: keep-alive\r\n"
16094 "Content-Length: 3\r\n\r\n"),
16095 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
16096 };
16097
16098 MockRead data_reads[] = {
16099 MockRead("HTTP 0.9 rocks!"),
16100 MockRead(SYNCHRONOUS, OK),
16101 };
16102 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
16103 arraysize(data_writes));
16104 session_deps_.socket_factory->AddSocketDataProvider(&data);
16105
16106 TestCompletionCallback callback;
16107
tfarina42834112016-09-22 13:38:2016108 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0116109 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]02d74a02014-04-23 18:10:5416110
16111 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0116112 EXPECT_THAT(rv, IsError(ERR_CONNECTION_RESET));
[email protected]02d74a02014-04-23 18:10:5416113}
16114
bncd16676a2016-07-20 16:23:0116115TEST_F(HttpNetworkTransactionTest, PostIgnoresPartial400HeadersAfterReset) {
danakj1fd259a02016-04-16 03:17:0916116 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:2216117 element_readers.push_back(
ricea2deef682016-09-09 08:04:0716118 base::MakeUnique<UploadBytesElementReader>("foo", 3));
olli.raula6df48b2a2015-11-26 07:40:2216119 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]02d74a02014-04-23 18:10:5416120
16121 HttpRequestInfo request;
16122 request.method = "POST";
16123 request.url = GURL("http://www.foo.com/");
16124 request.upload_data_stream = &upload_data_stream;
[email protected]02d74a02014-04-23 18:10:5416125
danakj1fd259a02016-04-16 03:17:0916126 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1616127 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]02d74a02014-04-23 18:10:5416128 // Send headers successfully, but get an error while sending the body.
16129 MockWrite data_writes[] = {
16130 MockWrite("POST / HTTP/1.1\r\n"
16131 "Host: www.foo.com\r\n"
16132 "Connection: keep-alive\r\n"
16133 "Content-Length: 3\r\n\r\n"),
16134 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
16135 };
16136
16137 MockRead data_reads[] = {
16138 MockRead("HTTP/1.0 400 Not a Full Response\r\n"),
16139 MockRead(SYNCHRONOUS, OK),
16140 };
16141 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
16142 arraysize(data_writes));
16143 session_deps_.socket_factory->AddSocketDataProvider(&data);
16144
16145 TestCompletionCallback callback;
16146
tfarina42834112016-09-22 13:38:2016147 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0116148 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]02d74a02014-04-23 18:10:5416149
16150 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0116151 EXPECT_THAT(rv, IsError(ERR_CONNECTION_RESET));
[email protected]02d74a02014-04-23 18:10:5416152}
16153
Adam Rice425cf122015-01-19 06:18:2416154// Verify that proxy headers are not sent to the destination server when
16155// establishing a tunnel for a secure WebSocket connection.
bncd16676a2016-07-20 16:23:0116156TEST_F(HttpNetworkTransactionTest, ProxyHeadersNotSentOverWssTunnel) {
Adam Rice425cf122015-01-19 06:18:2416157 HttpRequestInfo request;
16158 request.method = "GET";
bncce36dca22015-04-21 22:11:2316159 request.url = GURL("wss://www.example.org/");
Adam Rice425cf122015-01-19 06:18:2416160 AddWebSocketHeaders(&request.extra_headers);
16161
16162 // Configure against proxy server "myproxy:70".
rdsmith82957ad2015-09-16 19:42:0316163 session_deps_.proxy_service =
16164 ProxyService::CreateFixedFromPacResult("PROXY myproxy:70");
Adam Rice425cf122015-01-19 06:18:2416165
danakj1fd259a02016-04-16 03:17:0916166 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
Adam Rice425cf122015-01-19 06:18:2416167
16168 // Since a proxy is configured, try to establish a tunnel.
16169 MockWrite data_writes[] = {
rsleevidb16bb02015-11-12 23:47:1716170 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
16171 "Host: www.example.org:443\r\n"
16172 "Proxy-Connection: keep-alive\r\n\r\n"),
Adam Rice425cf122015-01-19 06:18:2416173
16174 // After calling trans->RestartWithAuth(), this is the request we should
16175 // be issuing -- the final header line contains the credentials.
rsleevidb16bb02015-11-12 23:47:1716176 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
16177 "Host: www.example.org:443\r\n"
16178 "Proxy-Connection: keep-alive\r\n"
16179 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
Adam Rice425cf122015-01-19 06:18:2416180
rsleevidb16bb02015-11-12 23:47:1716181 MockWrite("GET / HTTP/1.1\r\n"
16182 "Host: www.example.org\r\n"
16183 "Connection: Upgrade\r\n"
16184 "Upgrade: websocket\r\n"
16185 "Origin: http://www.example.org\r\n"
16186 "Sec-WebSocket-Version: 13\r\n"
16187 "Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==\r\n\r\n"),
Adam Rice425cf122015-01-19 06:18:2416188 };
16189
16190 // The proxy responds to the connect with a 407, using a persistent
16191 // connection.
16192 MockRead data_reads[] = {
16193 // No credentials.
16194 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
16195 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
mmenkee71e15332015-10-07 16:39:5416196 MockRead("Content-Length: 0\r\n"),
16197 MockRead("Proxy-Connection: keep-alive\r\n\r\n"),
Adam Rice425cf122015-01-19 06:18:2416198
16199 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
16200
16201 MockRead("HTTP/1.1 101 Switching Protocols\r\n"),
16202 MockRead("Upgrade: websocket\r\n"),
16203 MockRead("Connection: Upgrade\r\n"),
16204 MockRead("Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=\r\n\r\n"),
16205 };
16206
16207 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
16208 arraysize(data_writes));
16209 session_deps_.socket_factory->AddSocketDataProvider(&data);
16210 SSLSocketDataProvider ssl(ASYNC, OK);
16211 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
16212
bnc691fda62016-08-12 00:43:1616213 std::unique_ptr<HttpNetworkTransaction> trans(
Adam Rice425cf122015-01-19 06:18:2416214 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
16215 FakeWebSocketStreamCreateHelper websocket_stream_create_helper;
16216 trans->SetWebSocketHandshakeStreamCreateHelper(
16217 &websocket_stream_create_helper);
16218
16219 {
16220 TestCompletionCallback callback;
16221
tfarina42834112016-09-22 13:38:2016222 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0116223 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
Adam Rice425cf122015-01-19 06:18:2416224
16225 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0116226 EXPECT_THAT(rv, IsOk());
Adam Rice425cf122015-01-19 06:18:2416227 }
16228
16229 const HttpResponseInfo* response = trans->GetResponseInfo();
16230 ASSERT_TRUE(response);
wezca1070932016-05-26 20:30:5216231 ASSERT_TRUE(response->headers);
Adam Rice425cf122015-01-19 06:18:2416232 EXPECT_EQ(407, response->headers->response_code());
16233
16234 {
16235 TestCompletionCallback callback;
16236
16237 int rv = trans->RestartWithAuth(AuthCredentials(kFoo, kBar),
16238 callback.callback());
robpercival214763f2016-07-01 23:27:0116239 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
Adam Rice425cf122015-01-19 06:18:2416240
16241 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0116242 EXPECT_THAT(rv, IsOk());
Adam Rice425cf122015-01-19 06:18:2416243 }
16244
16245 response = trans->GetResponseInfo();
16246 ASSERT_TRUE(response);
wezca1070932016-05-26 20:30:5216247 ASSERT_TRUE(response->headers);
Adam Rice425cf122015-01-19 06:18:2416248
16249 EXPECT_EQ(101, response->headers->response_code());
16250
16251 trans.reset();
16252 session->CloseAllConnections();
16253}
16254
16255// Verify that proxy headers are not sent to the destination server when
16256// establishing a tunnel for an insecure WebSocket connection.
16257// This requires the authentication info to be injected into the auth cache
16258// due to crbug.com/395064
16259// TODO(ricea): Change to use a 407 response once issue 395064 is fixed.
bncd16676a2016-07-20 16:23:0116260TEST_F(HttpNetworkTransactionTest, ProxyHeadersNotSentOverWsTunnel) {
Adam Rice425cf122015-01-19 06:18:2416261 HttpRequestInfo request;
16262 request.method = "GET";
bncce36dca22015-04-21 22:11:2316263 request.url = GURL("ws://www.example.org/");
Adam Rice425cf122015-01-19 06:18:2416264 AddWebSocketHeaders(&request.extra_headers);
16265
16266 // Configure against proxy server "myproxy:70".
rdsmith82957ad2015-09-16 19:42:0316267 session_deps_.proxy_service =
16268 ProxyService::CreateFixedFromPacResult("PROXY myproxy:70");
Adam Rice425cf122015-01-19 06:18:2416269
danakj1fd259a02016-04-16 03:17:0916270 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
Adam Rice425cf122015-01-19 06:18:2416271
16272 MockWrite data_writes[] = {
16273 // Try to establish a tunnel for the WebSocket connection, with
16274 // credentials. Because WebSockets have a separate set of socket pools,
16275 // they cannot and will not use the same TCP/IP connection as the
16276 // preflight HTTP request.
16277 MockWrite(
bncce36dca22015-04-21 22:11:2316278 "CONNECT www.example.org:80 HTTP/1.1\r\n"
16279 "Host: www.example.org:80\r\n"
Adam Rice425cf122015-01-19 06:18:2416280 "Proxy-Connection: keep-alive\r\n"
16281 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
16282
16283 MockWrite(
16284 "GET / HTTP/1.1\r\n"
bncce36dca22015-04-21 22:11:2316285 "Host: www.example.org\r\n"
Adam Rice425cf122015-01-19 06:18:2416286 "Connection: Upgrade\r\n"
16287 "Upgrade: websocket\r\n"
bncce36dca22015-04-21 22:11:2316288 "Origin: http://www.example.org\r\n"
Adam Rice425cf122015-01-19 06:18:2416289 "Sec-WebSocket-Version: 13\r\n"
16290 "Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==\r\n\r\n"),
16291 };
16292
16293 MockRead data_reads[] = {
16294 // HTTP CONNECT with credentials.
16295 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
16296
16297 // WebSocket connection established inside tunnel.
16298 MockRead("HTTP/1.1 101 Switching Protocols\r\n"),
16299 MockRead("Upgrade: websocket\r\n"),
16300 MockRead("Connection: Upgrade\r\n"),
16301 MockRead("Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=\r\n\r\n"),
16302 };
16303
16304 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
16305 arraysize(data_writes));
16306 session_deps_.socket_factory->AddSocketDataProvider(&data);
16307
16308 session->http_auth_cache()->Add(
16309 GURL("http://myproxy:70/"), "MyRealm1", HttpAuth::AUTH_SCHEME_BASIC,
16310 "Basic realm=MyRealm1", AuthCredentials(kFoo, kBar), "/");
16311
bnc691fda62016-08-12 00:43:1616312 std::unique_ptr<HttpNetworkTransaction> trans(
Adam Rice425cf122015-01-19 06:18:2416313 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
16314 FakeWebSocketStreamCreateHelper websocket_stream_create_helper;
16315 trans->SetWebSocketHandshakeStreamCreateHelper(
16316 &websocket_stream_create_helper);
16317
16318 TestCompletionCallback callback;
16319
tfarina42834112016-09-22 13:38:2016320 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0116321 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
Adam Rice425cf122015-01-19 06:18:2416322
16323 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0116324 EXPECT_THAT(rv, IsOk());
Adam Rice425cf122015-01-19 06:18:2416325
16326 const HttpResponseInfo* response = trans->GetResponseInfo();
16327 ASSERT_TRUE(response);
wezca1070932016-05-26 20:30:5216328 ASSERT_TRUE(response->headers);
Adam Rice425cf122015-01-19 06:18:2416329
16330 EXPECT_EQ(101, response->headers->response_code());
16331
16332 trans.reset();
16333 session->CloseAllConnections();
16334}
16335
bncd16676a2016-07-20 16:23:0116336TEST_F(HttpNetworkTransactionTest, TotalNetworkBytesPost) {
danakj1fd259a02016-04-16 03:17:0916337 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:2216338 element_readers.push_back(
ricea2deef682016-09-09 08:04:0716339 base::MakeUnique<UploadBytesElementReader>("foo", 3));
olli.raula6df48b2a2015-11-26 07:40:2216340 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
sclittlefb249892015-09-10 21:33:2216341
16342 HttpRequestInfo request;
16343 request.method = "POST";
16344 request.url = GURL("http://www.foo.com/");
16345 request.upload_data_stream = &upload_data_stream;
16346
danakj1fd259a02016-04-16 03:17:0916347 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1616348 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
sclittlefb249892015-09-10 21:33:2216349 MockWrite data_writes[] = {
16350 MockWrite("POST / HTTP/1.1\r\n"
16351 "Host: www.foo.com\r\n"
16352 "Connection: keep-alive\r\n"
16353 "Content-Length: 3\r\n\r\n"),
16354 MockWrite("foo"),
16355 };
16356
16357 MockRead data_reads[] = {
16358 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello world"),
16359 MockRead(SYNCHRONOUS, OK),
16360 };
16361 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
16362 arraysize(data_writes));
16363 session_deps_.socket_factory->AddSocketDataProvider(&data);
16364
16365 TestCompletionCallback callback;
16366
16367 EXPECT_EQ(ERR_IO_PENDING,
tfarina42834112016-09-22 13:38:2016368 trans.Start(&request, callback.callback(), NetLogWithSource()));
robpercival214763f2016-07-01 23:27:0116369 EXPECT_THAT(callback.WaitForResult(), IsOk());
sclittlefb249892015-09-10 21:33:2216370
16371 std::string response_data;
bnc691fda62016-08-12 00:43:1616372 EXPECT_THAT(ReadTransaction(&trans, &response_data), IsOk());
sclittlefb249892015-09-10 21:33:2216373
16374 EXPECT_EQ(CountWriteBytes(data_writes, arraysize(data_writes)),
bnc691fda62016-08-12 00:43:1616375 trans.GetTotalSentBytes());
sclittlefb249892015-09-10 21:33:2216376 EXPECT_EQ(CountReadBytes(data_reads, arraysize(data_reads)),
bnc691fda62016-08-12 00:43:1616377 trans.GetTotalReceivedBytes());
sclittlefb249892015-09-10 21:33:2216378}
16379
bncd16676a2016-07-20 16:23:0116380TEST_F(HttpNetworkTransactionTest, TotalNetworkBytesPost100Continue) {
danakj1fd259a02016-04-16 03:17:0916381 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:2216382 element_readers.push_back(
ricea2deef682016-09-09 08:04:0716383 base::MakeUnique<UploadBytesElementReader>("foo", 3));
olli.raula6df48b2a2015-11-26 07:40:2216384 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
sclittlefb249892015-09-10 21:33:2216385
16386 HttpRequestInfo request;
16387 request.method = "POST";
16388 request.url = GURL("http://www.foo.com/");
16389 request.upload_data_stream = &upload_data_stream;
16390
danakj1fd259a02016-04-16 03:17:0916391 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1616392 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
sclittlefb249892015-09-10 21:33:2216393 MockWrite data_writes[] = {
16394 MockWrite("POST / HTTP/1.1\r\n"
16395 "Host: www.foo.com\r\n"
16396 "Connection: keep-alive\r\n"
16397 "Content-Length: 3\r\n\r\n"),
16398 MockWrite("foo"),
16399 };
16400
16401 MockRead data_reads[] = {
16402 MockRead("HTTP/1.1 100 Continue\r\n\r\n"),
16403 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello world"),
16404 MockRead(SYNCHRONOUS, OK),
16405 };
16406 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
16407 arraysize(data_writes));
16408 session_deps_.socket_factory->AddSocketDataProvider(&data);
16409
16410 TestCompletionCallback callback;
16411
16412 EXPECT_EQ(ERR_IO_PENDING,
tfarina42834112016-09-22 13:38:2016413 trans.Start(&request, callback.callback(), NetLogWithSource()));
robpercival214763f2016-07-01 23:27:0116414 EXPECT_THAT(callback.WaitForResult(), IsOk());
sclittlefb249892015-09-10 21:33:2216415
16416 std::string response_data;
bnc691fda62016-08-12 00:43:1616417 EXPECT_THAT(ReadTransaction(&trans, &response_data), IsOk());
sclittlefb249892015-09-10 21:33:2216418
16419 EXPECT_EQ(CountWriteBytes(data_writes, arraysize(data_writes)),
bnc691fda62016-08-12 00:43:1616420 trans.GetTotalSentBytes());
sclittlefb249892015-09-10 21:33:2216421 EXPECT_EQ(CountReadBytes(data_reads, arraysize(data_reads)),
bnc691fda62016-08-12 00:43:1616422 trans.GetTotalReceivedBytes());
sclittlefb249892015-09-10 21:33:2216423}
16424
bncd16676a2016-07-20 16:23:0116425TEST_F(HttpNetworkTransactionTest, TotalNetworkBytesChunkedPost) {
sclittlefb249892015-09-10 21:33:2216426 ChunkedUploadDataStream upload_data_stream(0);
16427
16428 HttpRequestInfo request;
16429 request.method = "POST";
16430 request.url = GURL("http://www.foo.com/");
16431 request.upload_data_stream = &upload_data_stream;
16432
danakj1fd259a02016-04-16 03:17:0916433 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1616434 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
sclittlefb249892015-09-10 21:33:2216435 // Send headers successfully, but get an error while sending the body.
16436 MockWrite data_writes[] = {
16437 MockWrite("POST / HTTP/1.1\r\n"
16438 "Host: www.foo.com\r\n"
16439 "Connection: keep-alive\r\n"
16440 "Transfer-Encoding: chunked\r\n\r\n"),
16441 MockWrite("1\r\nf\r\n"), MockWrite("2\r\noo\r\n"), MockWrite("0\r\n\r\n"),
16442 };
16443
16444 MockRead data_reads[] = {
16445 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello world"),
16446 MockRead(SYNCHRONOUS, OK),
16447 };
16448 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
16449 arraysize(data_writes));
16450 session_deps_.socket_factory->AddSocketDataProvider(&data);
16451
16452 TestCompletionCallback callback;
16453
16454 EXPECT_EQ(ERR_IO_PENDING,
tfarina42834112016-09-22 13:38:2016455 trans.Start(&request, callback.callback(), NetLogWithSource()));
sclittlefb249892015-09-10 21:33:2216456
16457 base::RunLoop().RunUntilIdle();
16458 upload_data_stream.AppendData("f", 1, false);
16459
16460 base::RunLoop().RunUntilIdle();
16461 upload_data_stream.AppendData("oo", 2, true);
16462
robpercival214763f2016-07-01 23:27:0116463 EXPECT_THAT(callback.WaitForResult(), IsOk());
sclittlefb249892015-09-10 21:33:2216464
16465 std::string response_data;
bnc691fda62016-08-12 00:43:1616466 EXPECT_THAT(ReadTransaction(&trans, &response_data), IsOk());
sclittlefb249892015-09-10 21:33:2216467
16468 EXPECT_EQ(CountWriteBytes(data_writes, arraysize(data_writes)),
bnc691fda62016-08-12 00:43:1616469 trans.GetTotalSentBytes());
sclittlefb249892015-09-10 21:33:2216470 EXPECT_EQ(CountReadBytes(data_reads, arraysize(data_reads)),
bnc691fda62016-08-12 00:43:1616471 trans.GetTotalReceivedBytes());
sclittlefb249892015-09-10 21:33:2216472}
16473
rdsmith1d343be52016-10-21 20:37:5016474// Confirm that transactions whose throttle is created in (and stays in)
16475// the unthrottled state are not blocked.
16476TEST_F(HttpNetworkTransactionTest, ThrottlingUnthrottled) {
16477 TestNetworkStreamThrottler* throttler(nullptr);
16478 std::unique_ptr<HttpNetworkSession> session(
16479 CreateSessionWithThrottler(&session_deps_, &throttler));
16480
16481 // Send a simple request and make sure it goes through.
16482 HttpRequestInfo request;
16483 request.method = "GET";
16484 request.url = GURL("http://www.example.org/");
16485
16486 std::unique_ptr<HttpTransaction> trans(
16487 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
16488
16489 MockWrite data_writes[] = {
16490 MockWrite("GET / HTTP/1.1\r\n"
16491 "Host: www.example.org\r\n"
16492 "Connection: keep-alive\r\n\r\n"),
16493 };
16494 MockRead data_reads[] = {
16495 MockRead("HTTP/1.0 200 OK\r\n\r\n"), MockRead("hello world"),
16496 MockRead(SYNCHRONOUS, OK),
16497 };
16498 StaticSocketDataProvider reads(data_reads, arraysize(data_reads), data_writes,
16499 arraysize(data_writes));
16500 session_deps_.socket_factory->AddSocketDataProvider(&reads);
16501
16502 TestCompletionCallback callback;
16503 trans->Start(&request, callback.callback(), NetLogWithSource());
16504 EXPECT_EQ(OK, callback.WaitForResult());
16505}
16506
16507// Confirm requests can be blocked by a throttler, and are resumed
16508// when the throttle is unblocked.
16509TEST_F(HttpNetworkTransactionTest, ThrottlingBasic) {
16510 TestNetworkStreamThrottler* throttler(nullptr);
16511 std::unique_ptr<HttpNetworkSession> session(
16512 CreateSessionWithThrottler(&session_deps_, &throttler));
16513
16514 // Send a simple request and make sure it goes through.
16515 HttpRequestInfo request;
16516 request.method = "GET";
16517 request.url = GURL("http://www.example.org/");
16518
16519 MockWrite data_writes[] = {
16520 MockWrite("GET / HTTP/1.1\r\n"
16521 "Host: www.example.org\r\n"
16522 "Connection: keep-alive\r\n\r\n"),
16523 };
16524 MockRead data_reads[] = {
16525 MockRead("HTTP/1.0 200 OK\r\n\r\n"), MockRead("hello world"),
16526 MockRead(SYNCHRONOUS, OK),
16527 };
16528 StaticSocketDataProvider reads(data_reads, arraysize(data_reads), data_writes,
16529 arraysize(data_writes));
16530 session_deps_.socket_factory->AddSocketDataProvider(&reads);
16531
16532 // Start a request that will be throttled at start; confirm it
16533 // doesn't complete.
16534 throttler->set_throttle_new_requests(true);
16535 std::unique_ptr<HttpTransaction> trans(
16536 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
16537
16538 TestCompletionCallback callback;
16539 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
16540 EXPECT_EQ(ERR_IO_PENDING, rv);
16541
16542 base::RunLoop().RunUntilIdle();
16543 EXPECT_EQ(LOAD_STATE_THROTTLED, trans->GetLoadState());
16544 EXPECT_FALSE(callback.have_result());
16545
16546 // Confirm the request goes on to complete when unthrottled.
16547 throttler->UnthrottleAllRequests();
16548 base::RunLoop().RunUntilIdle();
16549 ASSERT_TRUE(callback.have_result());
16550 EXPECT_EQ(OK, callback.WaitForResult());
16551}
16552
16553// Destroy a request while it's throttled.
16554TEST_F(HttpNetworkTransactionTest, ThrottlingDestruction) {
16555 TestNetworkStreamThrottler* throttler(nullptr);
16556 std::unique_ptr<HttpNetworkSession> session(
16557 CreateSessionWithThrottler(&session_deps_, &throttler));
16558
16559 // Send a simple request and make sure it goes through.
16560 HttpRequestInfo request;
16561 request.method = "GET";
16562 request.url = GURL("http://www.example.org/");
16563
16564 MockWrite data_writes[] = {
16565 MockWrite("GET / HTTP/1.1\r\n"
16566 "Host: www.example.org\r\n"
16567 "Connection: keep-alive\r\n\r\n"),
16568 };
16569 MockRead data_reads[] = {
16570 MockRead("HTTP/1.0 200 OK\r\n\r\n"), MockRead("hello world"),
16571 MockRead(SYNCHRONOUS, OK),
16572 };
16573 StaticSocketDataProvider reads(data_reads, arraysize(data_reads), data_writes,
16574 arraysize(data_writes));
16575 session_deps_.socket_factory->AddSocketDataProvider(&reads);
16576
16577 // Start a request that will be throttled at start; confirm it
16578 // doesn't complete.
16579 throttler->set_throttle_new_requests(true);
16580 std::unique_ptr<HttpTransaction> trans(
16581 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
16582
16583 TestCompletionCallback callback;
16584 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
16585 EXPECT_EQ(ERR_IO_PENDING, rv);
16586
16587 base::RunLoop().RunUntilIdle();
16588 EXPECT_EQ(LOAD_STATE_THROTTLED, trans->GetLoadState());
16589 EXPECT_FALSE(callback.have_result());
16590
16591 EXPECT_EQ(1u, throttler->num_outstanding_requests());
16592 trans.reset();
16593 EXPECT_EQ(0u, throttler->num_outstanding_requests());
16594}
16595
16596// Confirm the throttler receives SetPriority calls.
16597TEST_F(HttpNetworkTransactionTest, ThrottlingPrioritySet) {
16598 TestNetworkStreamThrottler* throttler(nullptr);
16599 std::unique_ptr<HttpNetworkSession> session(
16600 CreateSessionWithThrottler(&session_deps_, &throttler));
16601
16602 // Send a simple request and make sure it goes through.
16603 HttpRequestInfo request;
16604 request.method = "GET";
16605 request.url = GURL("http://www.example.org/");
16606
16607 MockWrite data_writes[] = {
16608 MockWrite("GET / HTTP/1.1\r\n"
16609 "Host: www.example.org\r\n"
16610 "Connection: keep-alive\r\n\r\n"),
16611 };
16612 MockRead data_reads[] = {
16613 MockRead("HTTP/1.0 200 OK\r\n\r\n"), MockRead("hello world"),
16614 MockRead(SYNCHRONOUS, OK),
16615 };
16616 StaticSocketDataProvider reads(data_reads, arraysize(data_reads), data_writes,
16617 arraysize(data_writes));
16618 session_deps_.socket_factory->AddSocketDataProvider(&reads);
16619
16620 throttler->set_throttle_new_requests(true);
16621 std::unique_ptr<HttpTransaction> trans(
16622 new HttpNetworkTransaction(IDLE, session.get()));
16623 // Start the transaction to associate a throttle with it.
16624 TestCompletionCallback callback;
16625 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
16626 EXPECT_EQ(ERR_IO_PENDING, rv);
16627
16628 EXPECT_EQ(0, throttler->num_set_priority_calls());
16629 trans->SetPriority(LOW);
16630 EXPECT_EQ(1, throttler->num_set_priority_calls());
16631 EXPECT_EQ(LOW, throttler->last_priority_set());
16632
16633 throttler->UnthrottleAllRequests();
16634 base::RunLoop().RunUntilIdle();
16635 ASSERT_TRUE(callback.have_result());
16636 EXPECT_EQ(OK, callback.WaitForResult());
16637}
16638
16639// Confirm that unthrottling from a SetPriority call by the
16640// throttler works properly.
16641TEST_F(HttpNetworkTransactionTest, ThrottlingPrioritySetUnthrottle) {
16642 TestNetworkStreamThrottler* throttler(nullptr);
16643 std::unique_ptr<HttpNetworkSession> session(
16644 CreateSessionWithThrottler(&session_deps_, &throttler));
16645
16646 // Send a simple request and make sure it goes through.
16647 HttpRequestInfo request;
16648 request.method = "GET";
16649 request.url = GURL("http://www.example.org/");
16650
16651 MockWrite data_writes[] = {
16652 MockWrite("GET / HTTP/1.1\r\n"
16653 "Host: www.example.org\r\n"
16654 "Connection: keep-alive\r\n\r\n"),
16655 };
16656 MockRead data_reads[] = {
16657 MockRead("HTTP/1.0 200 OK\r\n\r\n"), MockRead("hello world"),
16658 MockRead(SYNCHRONOUS, OK),
16659 };
16660 StaticSocketDataProvider reads(data_reads, arraysize(data_reads), data_writes,
16661 arraysize(data_writes));
16662 session_deps_.socket_factory->AddSocketDataProvider(&reads);
16663
16664 StaticSocketDataProvider reads1(data_reads, arraysize(data_reads),
16665 data_writes, arraysize(data_writes));
16666 session_deps_.socket_factory->AddSocketDataProvider(&reads1);
16667
16668 // Start a request that will be throttled at start; confirm it
16669 // doesn't complete.
16670 throttler->set_throttle_new_requests(true);
16671 std::unique_ptr<HttpTransaction> trans(
16672 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
16673
16674 TestCompletionCallback callback;
16675 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
16676 EXPECT_EQ(ERR_IO_PENDING, rv);
16677
16678 base::RunLoop().RunUntilIdle();
16679 EXPECT_EQ(LOAD_STATE_THROTTLED, trans->GetLoadState());
16680 EXPECT_FALSE(callback.have_result());
16681
16682 // Create a new request, call SetPriority on it to unthrottle,
16683 // and make sure that allows the original request to complete.
16684 std::unique_ptr<HttpTransaction> trans1(
16685 new HttpNetworkTransaction(LOW, session.get()));
16686 throttler->set_priority_change_closure(
16687 base::Bind(&TestNetworkStreamThrottler::UnthrottleAllRequests,
16688 base::Unretained(throttler)));
16689
16690 // Start the transaction to associate a throttle with it.
16691 TestCompletionCallback callback1;
16692 rv = trans1->Start(&request, callback1.callback(), NetLogWithSource());
16693 EXPECT_EQ(ERR_IO_PENDING, rv);
16694
16695 trans1->SetPriority(IDLE);
16696
16697 base::RunLoop().RunUntilIdle();
16698 ASSERT_TRUE(callback.have_result());
16699 EXPECT_EQ(OK, callback.WaitForResult());
16700 ASSERT_TRUE(callback1.have_result());
16701 EXPECT_EQ(OK, callback1.WaitForResult());
16702}
16703
16704// Transaction will be destroyed when the unique_ptr goes out of scope.
16705void DestroyTransaction(std::unique_ptr<HttpTransaction> transaction) {}
16706
16707// Confirm that destroying a transaction from a SetPriority call by the
16708// throttler works properly.
16709TEST_F(HttpNetworkTransactionTest, ThrottlingPrioritySetDestroy) {
16710 TestNetworkStreamThrottler* throttler(nullptr);
16711 std::unique_ptr<HttpNetworkSession> session(
16712 CreateSessionWithThrottler(&session_deps_, &throttler));
16713
16714 // Send a simple request and make sure it goes through.
16715 HttpRequestInfo request;
16716 request.method = "GET";
16717 request.url = GURL("http://www.example.org/");
16718
16719 MockWrite data_writes[] = {
16720 MockWrite("GET / HTTP/1.1\r\n"
16721 "Host: www.example.org\r\n"
16722 "Connection: keep-alive\r\n\r\n"),
16723 };
16724 MockRead data_reads[] = {
16725 MockRead("HTTP/1.0 200 OK\r\n\r\n"), MockRead("hello world"),
16726 MockRead(SYNCHRONOUS, OK),
16727 };
16728 StaticSocketDataProvider reads(data_reads, arraysize(data_reads), data_writes,
16729 arraysize(data_writes));
16730 session_deps_.socket_factory->AddSocketDataProvider(&reads);
16731
16732 StaticSocketDataProvider reads1(data_reads, arraysize(data_reads),
16733 data_writes, arraysize(data_writes));
16734 session_deps_.socket_factory->AddSocketDataProvider(&reads1);
16735
16736 // Start a request that will be throttled at start; confirm it
16737 // doesn't complete.
16738 throttler->set_throttle_new_requests(true);
16739 std::unique_ptr<HttpTransaction> trans(
16740 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
16741
16742 TestCompletionCallback callback;
16743 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
16744 EXPECT_EQ(ERR_IO_PENDING, rv);
16745
16746 base::RunLoop().RunUntilIdle();
16747 EXPECT_EQ(LOAD_STATE_THROTTLED, trans->GetLoadState());
16748 EXPECT_FALSE(callback.have_result());
16749
16750 // Arrange for the set priority call on the above transaction to delete
16751 // the transaction.
16752 HttpTransaction* trans_ptr(trans.get());
16753 throttler->set_priority_change_closure(
16754 base::Bind(&DestroyTransaction, base::Passed(&trans)));
16755
16756 // Call it and check results (partially a "doesn't crash" test).
16757 trans_ptr->SetPriority(IDLE);
16758 trans_ptr = nullptr; // No longer a valid pointer.
16759
16760 base::RunLoop().RunUntilIdle();
16761 ASSERT_FALSE(callback.have_result());
16762}
16763
nharperb7441ef2016-01-25 23:54:1416764#if !defined(OS_IOS)
bncd16676a2016-07-20 16:23:0116765TEST_F(HttpNetworkTransactionTest, TokenBindingSpdy) {
fdoraya89e673c2017-01-31 21:44:2116766 // Required by ChannelIDService.
16767 base::test::ScopedTaskScheduler scoped_task_scheduler(
16768 base::MessageLoop::current());
16769
nharperb7441ef2016-01-25 23:54:1416770 const std::string https_url = "https://www.example.com";
16771 HttpRequestInfo request;
16772 request.url = GURL(https_url);
16773 request.method = "GET";
16774
16775 SSLSocketDataProvider ssl(ASYNC, OK);
16776 ssl.token_binding_negotiated = true;
16777 ssl.token_binding_key_param = TB_PARAM_ECDSAP256;
bnc3cf2a592016-08-11 14:48:3616778 ssl.next_proto = kProtoHTTP2;
nharperb7441ef2016-01-25 23:54:1416779 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
16780
bnc42331402016-07-25 13:36:1516781 SpdySerializedFrame resp(spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
bncdf80d44fd2016-07-15 20:27:4116782 SpdySerializedFrame body(spdy_util_.ConstructSpdyDataFrame(1, true));
16783 MockRead reads[] = {CreateMockRead(resp), CreateMockRead(body),
nharperb7441ef2016-01-25 23:54:1416784 MockRead(ASYNC, ERR_IO_PENDING)};
16785 StaticSocketDataProvider data(reads, arraysize(reads), nullptr, 0);
16786 session_deps_.socket_factory->AddSocketDataProvider(&data);
fdoraya89e673c2017-01-31 21:44:2116787 session_deps_.channel_id_service.reset(
16788 new ChannelIDService(new DefaultChannelIDStore(nullptr)));
danakj1fd259a02016-04-16 03:17:0916789 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
nharperb7441ef2016-01-25 23:54:1416790
16791 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
16792 TestCompletionCallback callback;
16793 EXPECT_EQ(ERR_IO_PENDING,
tfarina42834112016-09-22 13:38:2016794 trans.Start(&request, callback.callback(), NetLogWithSource()));
fdoray92e35a72016-06-10 15:54:5516795 base::RunLoop().RunUntilIdle();
nharperb7441ef2016-01-25 23:54:1416796
16797 EXPECT_TRUE(trans.GetResponseInfo()->was_fetched_via_spdy);
16798 HttpRequestHeaders headers;
16799 ASSERT_TRUE(trans.GetFullRequestHeaders(&headers));
16800 EXPECT_TRUE(headers.HasHeader(HttpRequestHeaders::kTokenBinding));
16801}
16802#endif // !defined(OS_IOS)
16803
eustasc7d27da2017-04-06 10:33:2016804void CheckContentEncodingMatching(SpdySessionDependencies* session_deps,
16805 const std::string& accept_encoding,
16806 const std::string& content_encoding,
sky50576f32017-05-01 19:28:0316807 const std::string& location,
eustasc7d27da2017-04-06 10:33:2016808 bool should_match) {
16809 HttpRequestInfo request;
16810 request.method = "GET";
16811 request.url = GURL("http://www.foo.com/");
16812 request.extra_headers.SetHeader(HttpRequestHeaders::kAcceptEncoding,
16813 accept_encoding);
16814
16815 std::unique_ptr<HttpNetworkSession> session(CreateSession(session_deps));
16816 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
16817 // Send headers successfully, but get an error while sending the body.
16818 MockWrite data_writes[] = {
16819 MockWrite("GET / HTTP/1.1\r\n"
16820 "Host: www.foo.com\r\n"
16821 "Connection: keep-alive\r\n"
16822 "Accept-Encoding: "),
16823 MockWrite(accept_encoding.data()), MockWrite("\r\n\r\n"),
16824 };
16825
sky50576f32017-05-01 19:28:0316826 std::string response_code = "200 OK";
16827 std::string extra;
16828 if (!location.empty()) {
16829 response_code = "301 Redirect\r\nLocation: ";
16830 response_code.append(location);
16831 }
16832
eustasc7d27da2017-04-06 10:33:2016833 MockRead data_reads[] = {
sky50576f32017-05-01 19:28:0316834 MockRead("HTTP/1.0 "),
16835 MockRead(response_code.data()),
16836 MockRead("\r\nContent-Encoding: "),
16837 MockRead(content_encoding.data()),
16838 MockRead("\r\n\r\n"),
eustasc7d27da2017-04-06 10:33:2016839 MockRead(SYNCHRONOUS, OK),
16840 };
16841 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
16842 arraysize(data_writes));
16843 session_deps->socket_factory->AddSocketDataProvider(&data);
16844
16845 TestCompletionCallback callback;
16846
16847 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
16848 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
16849
16850 rv = callback.WaitForResult();
16851 if (should_match) {
16852 EXPECT_THAT(rv, IsOk());
16853 } else {
16854 EXPECT_THAT(rv, IsError(ERR_CONTENT_DECODING_FAILED));
16855 }
16856}
16857
16858TEST_F(HttpNetworkTransactionTest, MatchContentEncoding1) {
sky50576f32017-05-01 19:28:0316859 CheckContentEncodingMatching(&session_deps_, "gzip,sdch", "br", "", false);
eustasc7d27da2017-04-06 10:33:2016860}
16861
16862TEST_F(HttpNetworkTransactionTest, MatchContentEncoding2) {
sky50576f32017-05-01 19:28:0316863 CheckContentEncodingMatching(&session_deps_, "identity;q=1, *;q=0", "", "",
16864 true);
eustasc7d27da2017-04-06 10:33:2016865}
16866
16867TEST_F(HttpNetworkTransactionTest, MatchContentEncoding3) {
16868 CheckContentEncodingMatching(&session_deps_, "identity;q=1, *;q=0", "gzip",
sky50576f32017-05-01 19:28:0316869 "", false);
16870}
16871
16872TEST_F(HttpNetworkTransactionTest, MatchContentEncoding4) {
16873 CheckContentEncodingMatching(&session_deps_, "identity;q=1, *;q=0", "gzip",
16874 "www.foo.com/other", true);
eustasc7d27da2017-04-06 10:33:2016875}
16876
[email protected]89ceba9a2009-03-21 03:46:0616877} // namespace net