blob: e95ab37faf515ae8e47324e982447d4dc341c9ca [file] [log] [blame]
[email protected]23e482282013-06-14 16:08:021// Copyright 2013 The Chromium Authors. All rights reserved.
license.botbf09a502008-08-24 00:55:552// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
initial.commit586acc5fe2008-07-26 22:42:524
[email protected]2d731a32010-04-29 01:04:065#include "net/http/http_network_transaction.h"
6
[email protected]77848d12008-11-14 00:00:227#include <math.h> // ceil
[email protected]5285d972011-10-18 18:56:348#include <stdarg.h>
sclittlebe1ccf62015-09-02 19:40:369#include <stdint.h>
danakj1fd259a02016-04-16 03:17:0910
avibf0746c2015-12-09 19:53:1411#include <limits>
danakj1fd259a02016-04-16 03:17:0912#include <memory>
rdsmith1d343be52016-10-21 20:37:5013#include <set>
[email protected]5285d972011-10-18 18:56:3414#include <string>
dchengc7eeda422015-12-26 03:56:4815#include <utility>
[email protected]95d88ffe2010-02-04 21:25:3316#include <vector>
[email protected]77848d12008-11-14 00:00:2217
[email protected]68bf9152008-09-25 19:47:3018#include "base/compiler_specific.h"
[email protected]57999812013-02-24 05:40:5219#include "base/files/file_path.h"
thestigd8df0332014-09-04 06:33:2920#include "base/files/file_util.h"
[email protected]f3da152d2012-06-02 01:00:5721#include "base/json/json_writer.h"
Adam Rice425cf122015-01-19 06:18:2422#include "base/logging.h"
Avi Drissman13fc8932015-12-20 04:40:4623#include "base/macros.h"
danakj1fd259a02016-04-16 03:17:0924#include "base/memory/ptr_util.h"
[email protected]bf828982013-08-14 18:01:4725#include "base/memory/weak_ptr.h"
fdoraya89e673c2017-01-31 21:44:2126#include "base/message_loop/message_loop.h"
[email protected]a34f61ee2014-03-18 20:59:4927#include "base/run_loop.h"
[email protected]125ef482013-06-11 18:32:4728#include "base/strings/string_util.h"
[email protected]750b2f3c2013-06-07 18:41:0529#include "base/strings/utf_string_conversions.h"
fdoraya89e673c2017-01-31 21:44:2130#include "base/test/scoped_task_scheduler.h"
[email protected]f36a8132011-09-02 18:36:3331#include "base/test/test_file_util.h"
gabf767595f2016-05-11 18:50:3532#include "base/threading/thread_task_runner_handle.h"
[email protected]277d5942010-08-11 21:02:3533#include "net/base/auth.h"
mmenkecbc2b712014-10-09 20:29:0734#include "net/base/chunked_upload_data_stream.h"
[email protected]bacff652009-03-31 17:50:3335#include "net/base/completion_callback.h"
mmenkecbc2b712014-10-09 20:29:0736#include "net/base/elements_upload_data_stream.h"
[email protected]58e32bb2013-01-21 18:23:2537#include "net/base/load_timing_info.h"
38#include "net/base/load_timing_info_test_util.h"
Adam Rice425cf122015-01-19 06:18:2439#include "net/base/net_errors.h"
rdsmith1d343be52016-10-21 20:37:5040#include "net/base/network_throttle_manager.h"
tbansal28e68f82016-02-04 02:56:1541#include "net/base/proxy_delegate.h"
[email protected]ac790b42009-12-02 04:31:3142#include "net/base/request_priority.h"
initial.commit586acc5fe2008-07-26 22:42:5243#include "net/base/test_completion_callback.h"
tbansal28e68f82016-02-04 02:56:1544#include "net/base/test_proxy_delegate.h"
[email protected]b2d26cfd2012-12-11 10:36:0645#include "net/base/upload_bytes_element_reader.h"
[email protected]d98961652012-09-11 20:27:2146#include "net/base/upload_file_element_reader.h"
[email protected]6e7845ae2013-03-29 21:48:1147#include "net/cert/mock_cert_verifier.h"
[email protected]bc71b8772013-04-10 20:55:1648#include "net/dns/host_cache.h"
[email protected]f2cb3cf2013-03-21 01:40:5349#include "net/dns/mock_host_resolver.h"
[email protected]df41d0d82014-03-13 00:43:2450#include "net/http/http_auth_challenge_tokenizer.h"
[email protected]3c32c5f2010-05-18 15:18:1251#include "net/http/http_auth_handler_digest.h"
[email protected]3fd9dae2010-06-21 11:39:0052#include "net/http/http_auth_handler_mock.h"
[email protected]385a4672009-03-11 22:21:2953#include "net/http/http_auth_handler_ntlm.h"
aberentbba302d2015-12-03 10:20:1954#include "net/http/http_auth_scheme.h"
Adam Rice425cf122015-01-19 06:18:2455#include "net/http/http_basic_state.h"
[email protected]0877e3d2009-10-17 22:29:5756#include "net/http/http_basic_stream.h"
initial.commit586acc5fe2008-07-26 22:42:5257#include "net/http/http_network_session.h"
[email protected]87bfa3f2010-09-30 14:54:5658#include "net/http/http_network_session_peer.h"
Adam Rice425cf122015-01-19 06:18:2459#include "net/http/http_request_headers.h"
mmenke5f94fda2016-06-02 20:54:1360#include "net/http/http_response_info.h"
[email protected]17291a022011-10-10 07:32:5361#include "net/http/http_server_properties_impl.h"
[email protected]0877e3d2009-10-17 22:29:5762#include "net/http/http_stream.h"
[email protected]8e6441ca2010-08-19 05:56:3863#include "net/http/http_stream_factory.h"
Adam Rice425cf122015-01-19 06:18:2464#include "net/http/http_stream_parser.h"
[email protected]c41737d2014-05-14 07:47:1965#include "net/http/http_transaction_test_util.h"
eroman87c53d62015-04-02 06:51:0766#include "net/log/net_log.h"
mikecirone8b85c432016-09-08 19:11:0067#include "net/log/net_log_event_type.h"
mikecironef22f9812016-10-04 03:40:1968#include "net/log/net_log_source.h"
vishal.b62985ca92015-04-17 08:45:5169#include "net/log/test_net_log.h"
mmenke43758e62015-05-04 21:09:4670#include "net/log/test_net_log_entry.h"
71#include "net/log/test_net_log_util.h"
sammc5dd160c2015-04-02 02:43:1372#include "net/proxy/mock_proxy_resolver.h"
[email protected]51fff29d2008-12-19 22:17:5373#include "net/proxy/proxy_config_service_fixed.h"
[email protected]e86839fd2013-08-14 18:29:0374#include "net/proxy/proxy_info.h"
[email protected]631f1322010-04-30 17:59:1175#include "net/proxy/proxy_resolver.h"
tbansal28e68f82016-02-04 02:56:1576#include "net/proxy/proxy_server.h"
[email protected]631f1322010-04-30 17:59:1177#include "net/proxy/proxy_service.h"
[email protected]f7984fc62009-06-22 23:26:4478#include "net/socket/client_socket_factory.h"
mmenked3641e12016-01-28 16:06:1579#include "net/socket/client_socket_pool.h"
[email protected]483fa202013-05-14 01:07:0380#include "net/socket/client_socket_pool_manager.h"
ttuttle1f2d7e92015-04-28 16:17:4781#include "net/socket/connection_attempts.h"
[email protected]a42dbd142011-11-17 16:42:0282#include "net/socket/mock_client_socket_pool_manager.h"
[email protected]bb88e1d32013-05-03 23:11:0783#include "net/socket/next_proto.h"
[email protected]f7984fc62009-06-22 23:26:4484#include "net/socket/socket_test_util.h"
85#include "net/socket/ssl_client_socket.h"
[email protected]2ff8b312010-04-26 22:20:5486#include "net/spdy/spdy_framer.h"
87#include "net/spdy/spdy_session.h"
88#include "net/spdy/spdy_session_pool.h"
[email protected]23e482282013-06-14 16:08:0289#include "net/spdy/spdy_test_util_common.h"
nharperb7441ef2016-01-25 23:54:1490#include "net/ssl/default_channel_id_store.h"
[email protected]536fd0b2013-03-14 17:41:5791#include "net/ssl/ssl_cert_request_info.h"
[email protected]e86839fd2013-08-14 18:29:0392#include "net/ssl/ssl_config_service.h"
[email protected]536fd0b2013-03-14 17:41:5793#include "net/ssl/ssl_config_service_defaults.h"
94#include "net/ssl/ssl_info.h"
svaldez7872fd02015-11-19 21:10:5495#include "net/ssl/ssl_private_key.h"
[email protected]6e7845ae2013-03-29 21:48:1196#include "net/test/cert_test_util.h"
robpercival214763f2016-07-01 23:27:0197#include "net/test/gtest_util.h"
rsleevia69c79a2016-06-22 03:28:4398#include "net/test/test_data_directory.h"
[email protected]831e4a32013-11-14 02:14:4499#include "net/websockets/websocket_handshake_stream_base.h"
bncf4588402015-11-24 13:33:18100#include "testing/gmock/include/gmock/gmock.h"
initial.commit586acc5fe2008-07-26 22:42:52101#include "testing/gtest/include/gtest/gtest.h"
[email protected]23887f04f2008-12-02 19:20:15102#include "testing/platform_test.h"
[email protected]795cbf82013-07-22 09:37:27103#include "url/gurl.h"
initial.commit586acc5fe2008-07-26 22:42:52104
robpercival214763f2016-07-01 23:27:01105using net::test::IsError;
106using net::test::IsOk;
107
[email protected]ad65a3e2013-12-25 18:18:01108using base::ASCIIToUTF16;
109
initial.commit586acc5fe2008-07-26 22:42:52110//-----------------------------------------------------------------------------
111
ttuttle859dc7a2015-04-23 19:42:29112namespace net {
113
[email protected]13c8a092010-07-29 06:15:44114namespace {
115
rdsmith1d343be52016-10-21 20:37:50116class TestNetworkStreamThrottler : public NetworkThrottleManager {
117 public:
118 TestNetworkStreamThrottler()
119 : throttle_new_requests_(false),
120 num_set_priority_calls_(0),
121 last_priority_set_(IDLE) {}
122
123 ~TestNetworkStreamThrottler() override {
124 EXPECT_TRUE(outstanding_throttles_.empty());
125 }
126
127 // NetworkThrottleManager
128 std::unique_ptr<Throttle> CreateThrottle(ThrottleDelegate* delegate,
129 RequestPriority priority,
130 bool ignore_limits) override {
131 std::unique_ptr<TestThrottle> test_throttle(
132 new TestThrottle(throttle_new_requests_, delegate, this));
133 outstanding_throttles_.insert(test_throttle.get());
134 return std::move(test_throttle);
135 }
136
137 void UnthrottleAllRequests() {
138 std::set<TestThrottle*> outstanding_throttles_copy(outstanding_throttles_);
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)) {
bncb26024382016-06-29 02:39:45401 session_deps_.enable_http2_alternative_service_with_different_host = true;
[email protected]483fa202013-05-14 01:07:03402 }
[email protected]bb88e1d32013-05-03 23:11:07403
[email protected]e3ceb682011-06-28 23:55:46404 struct SimpleGetHelperResult {
405 int rv;
406 std::string status_line;
407 std::string response_data;
sclittlefb249892015-09-10 21:33:22408 int64_t total_received_bytes;
409 int64_t total_sent_bytes;
[email protected]58e32bb2013-01-21 18:23:25410 LoadTimingInfo load_timing_info;
ttuttle1f2d7e92015-04-28 16:17:47411 ConnectionAttempts connection_attempts;
ttuttled9dbc652015-09-29 20:00:59412 IPEndPoint remote_endpoint_after_start;
[email protected]e3ceb682011-06-28 23:55:46413 };
414
dcheng67be2b1f2014-10-27 21:47:29415 void SetUp() override {
[email protected]0b0bf032010-09-21 18:08:50416 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
fdoray92e35a72016-06-10 15:54:55417 base::RunLoop().RunUntilIdle();
[email protected]2ff8b312010-04-26 22:20:54418 }
419
dcheng67be2b1f2014-10-27 21:47:29420 void TearDown() override {
[email protected]0b0bf032010-09-21 18:08:50421 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
fdoray92e35a72016-06-10 15:54:55422 base::RunLoop().RunUntilIdle();
[email protected]0e75a732008-10-16 20:36:09423 // Empty the current queue.
fdoray92e35a72016-06-10 15:54:55424 base::RunLoop().RunUntilIdle();
[email protected]0e75a732008-10-16 20:36:09425 PlatformTest::TearDown();
[email protected]0b0bf032010-09-21 18:08:50426 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
fdoray92e35a72016-06-10 15:54:55427 base::RunLoop().RunUntilIdle();
[email protected]0e75a732008-10-16 20:36:09428 }
429
[email protected]202965992011-12-07 23:04:51430 // Either |write_failure| specifies a write failure or |read_failure|
431 // specifies a read failure when using a reused socket. In either case, the
432 // failure should cause the network transaction to resend the request, and the
433 // other argument should be NULL.
434 void KeepAliveConnectionResendRequestTest(const MockWrite* write_failure,
435 const MockRead* read_failure);
initial.commit586acc5fe2008-07-26 22:42:52436
[email protected]a34f61ee2014-03-18 20:59:49437 // Either |write_failure| specifies a write failure or |read_failure|
438 // specifies a read failure when using a reused socket. In either case, the
439 // failure should cause the network transaction to resend the request, and the
440 // other argument should be NULL.
441 void PreconnectErrorResendRequestTest(const MockWrite* write_failure,
[email protected]09356c652014-03-25 15:36:10442 const MockRead* read_failure,
443 bool use_spdy);
[email protected]a34f61ee2014-03-18 20:59:49444
[email protected]5a60c8b2011-10-19 20:14:29445 SimpleGetHelperResult SimpleGetHelperForData(StaticSocketDataProvider* data[],
446 size_t data_count) {
[email protected]ff007e162009-05-23 09:13:15447 SimpleGetHelperResult out;
initial.commit586acc5fe2008-07-26 22:42:52448
[email protected]ff007e162009-05-23 09:13:15449 HttpRequestInfo request;
450 request.method = "GET";
bncce36dca22015-04-21 22:11:23451 request.url = GURL("http://www.example.org/");
initial.commit586acc5fe2008-07-26 22:42:52452
vishal.b62985ca92015-04-17 08:45:51453 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:07454 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:09455 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:16456 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:27457
[email protected]5a60c8b2011-10-19 20:14:29458 for (size_t i = 0; i < data_count; ++i) {
[email protected]bb88e1d32013-05-03 23:11:07459 session_deps_.socket_factory->AddSocketDataProvider(data[i]);
[email protected]5a60c8b2011-10-19 20:14:29460 }
initial.commit586acc5fe2008-07-26 22:42:52461
[email protected]49639fa2011-12-20 23:22:41462 TestCompletionCallback callback;
initial.commit586acc5fe2008-07-26 22:42:52463
eroman24bc6a12015-05-06 19:55:48464 EXPECT_TRUE(log.bound().IsCapturing());
bnc691fda62016-08-12 00:43:16465 int rv = trans.Start(&request, callback.callback(), log.bound());
robpercival214763f2016-07-01 23:27:01466 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
initial.commit586acc5fe2008-07-26 22:42:52467
[email protected]ff007e162009-05-23 09:13:15468 out.rv = callback.WaitForResult();
bnc691fda62016-08-12 00:43:16469 out.total_received_bytes = trans.GetTotalReceivedBytes();
470 out.total_sent_bytes = trans.GetTotalSentBytes();
[email protected]58e32bb2013-01-21 18:23:25471
472 // Even in the failure cases that use this function, connections are always
473 // successfully established before the error.
bnc691fda62016-08-12 00:43:16474 EXPECT_TRUE(trans.GetLoadTimingInfo(&out.load_timing_info));
[email protected]58e32bb2013-01-21 18:23:25475 TestLoadTimingNotReused(out.load_timing_info, CONNECT_TIMING_HAS_DNS_TIMES);
476
[email protected]ff007e162009-05-23 09:13:15477 if (out.rv != OK)
478 return out;
479
bnc691fda62016-08-12 00:43:16480 const HttpResponseInfo* response = trans.GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:50481 // Can't use ASSERT_* inside helper functions like this, so
482 // return an error.
wezca1070932016-05-26 20:30:52483 if (!response || !response->headers) {
[email protected]fe2255a2011-09-20 19:37:50484 out.rv = ERR_UNEXPECTED;
485 return out;
486 }
[email protected]ff007e162009-05-23 09:13:15487 out.status_line = response->headers->GetStatusLine();
488
[email protected]80a09a82012-11-16 17:40:06489 EXPECT_EQ("127.0.0.1", response->socket_address.host());
490 EXPECT_EQ(80, response->socket_address.port());
[email protected]6d81b482011-02-22 19:47:19491
ttuttled9dbc652015-09-29 20:00:59492 bool got_endpoint =
bnc691fda62016-08-12 00:43:16493 trans.GetRemoteEndpoint(&out.remote_endpoint_after_start);
ttuttled9dbc652015-09-29 20:00:59494 EXPECT_EQ(got_endpoint,
495 out.remote_endpoint_after_start.address().size() > 0);
496
bnc691fda62016-08-12 00:43:16497 rv = ReadTransaction(&trans, &out.response_data);
robpercival214763f2016-07-01 23:27:01498 EXPECT_THAT(rv, IsOk());
[email protected]b2fcd0e2010-12-01 15:19:40499
mmenke43758e62015-05-04 21:09:46500 TestNetLogEntry::List entries;
[email protected]b2fcd0e2010-12-01 15:19:40501 log.GetEntries(&entries);
[email protected]dbb83db2010-05-11 18:13:39502 size_t pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:00503 entries, 0, NetLogEventType::HTTP_TRANSACTION_SEND_REQUEST_HEADERS,
504 NetLogEventPhase::NONE);
[email protected]dbb83db2010-05-11 18:13:39505 ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:00506 entries, pos, NetLogEventType::HTTP_TRANSACTION_READ_RESPONSE_HEADERS,
507 NetLogEventPhase::NONE);
[email protected]ff007e162009-05-23 09:13:15508
[email protected]f3da152d2012-06-02 01:00:57509 std::string line;
510 EXPECT_TRUE(entries[pos].GetStringValue("line", &line));
511 EXPECT_EQ("GET / HTTP/1.1\r\n", line);
512
[email protected]79e1fd62013-06-20 06:50:04513 HttpRequestHeaders request_headers;
bnc691fda62016-08-12 00:43:16514 EXPECT_TRUE(trans.GetFullRequestHeaders(&request_headers));
[email protected]79e1fd62013-06-20 06:50:04515 std::string value;
516 EXPECT_TRUE(request_headers.GetHeader("Host", &value));
bncce36dca22015-04-21 22:11:23517 EXPECT_EQ("www.example.org", value);
[email protected]79e1fd62013-06-20 06:50:04518 EXPECT_TRUE(request_headers.GetHeader("Connection", &value));
519 EXPECT_EQ("keep-alive", value);
520
521 std::string response_headers;
522 EXPECT_TRUE(GetHeaders(entries[pos].params.get(), &response_headers));
bncce36dca22015-04-21 22:11:23523 EXPECT_EQ("['Host: www.example.org','Connection: keep-alive']",
[email protected]79e1fd62013-06-20 06:50:04524 response_headers);
[email protected]3deb9a52010-11-11 00:24:40525
bnc691fda62016-08-12 00:43:16526 out.total_received_bytes = trans.GetTotalReceivedBytes();
sclittlefb249892015-09-10 21:33:22527 // The total number of sent bytes should not have changed.
bnc691fda62016-08-12 00:43:16528 EXPECT_EQ(out.total_sent_bytes, trans.GetTotalSentBytes());
sclittlefb249892015-09-10 21:33:22529
bnc691fda62016-08-12 00:43:16530 trans.GetConnectionAttempts(&out.connection_attempts);
[email protected]aecfbf22008-10-16 02:02:47531 return out;
[email protected]ff007e162009-05-23 09:13:15532 }
initial.commit586acc5fe2008-07-26 22:42:52533
[email protected]5a60c8b2011-10-19 20:14:29534 SimpleGetHelperResult SimpleGetHelper(MockRead data_reads[],
535 size_t reads_count) {
sclittlefb249892015-09-10 21:33:22536 MockWrite data_writes[] = {
537 MockWrite("GET / HTTP/1.1\r\n"
538 "Host: www.example.org\r\n"
539 "Connection: keep-alive\r\n\r\n"),
540 };
[email protected]5a60c8b2011-10-19 20:14:29541
sclittlefb249892015-09-10 21:33:22542 StaticSocketDataProvider reads(data_reads, reads_count, data_writes,
543 arraysize(data_writes));
544 StaticSocketDataProvider* data[] = {&reads};
545 SimpleGetHelperResult out = SimpleGetHelperForData(data, 1);
546
547 EXPECT_EQ(CountWriteBytes(data_writes, arraysize(data_writes)),
548 out.total_sent_bytes);
549 return out;
[email protected]b8015c42013-12-24 15:18:19550 }
551
bnc032658ba2016-09-26 18:17:15552 void AddSSLSocketData() {
553 ssl_.next_proto = kProtoHTTP2;
554 ssl_.cert = ImportCertFromFile(GetTestCertsDirectory(), "spdy_pooling.pem");
555 ASSERT_TRUE(ssl_.cert);
556 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_);
557 }
558
[email protected]ff007e162009-05-23 09:13:15559 void ConnectStatusHelperWithExpectedStatus(const MockRead& status,
560 int expected_status);
initial.commit586acc5fe2008-07-26 22:42:52561
[email protected]ff007e162009-05-23 09:13:15562 void ConnectStatusHelper(const MockRead& status);
[email protected]bb88e1d32013-05-03 23:11:07563
564 void BypassHostCacheOnRefreshHelper(int load_flags);
565
566 void CheckErrorIsPassedBack(int error, IoMode mode);
567
[email protected]4bd46222013-05-14 19:32:23568 SpdyTestUtil spdy_util_;
[email protected]bb88e1d32013-05-03 23:11:07569 SpdySessionDependencies session_deps_;
bnc032658ba2016-09-26 18:17:15570 SSLSocketDataProvider ssl_;
[email protected]483fa202013-05-14 01:07:03571
572 // Original socket limits. Some tests set these. Safest to always restore
573 // them once each test has been run.
574 int old_max_group_sockets_;
575 int old_max_pool_sockets_;
[email protected]ff007e162009-05-23 09:13:15576};
[email protected]231d5a32008-09-13 00:45:27577
[email protected]448d4ca52012-03-04 04:12:23578namespace {
579
ryansturm49a8cb12016-06-15 16:51:09580class BeforeHeadersSentHandler {
[email protected]597a1ab2014-06-26 08:12:27581 public:
ryansturm49a8cb12016-06-15 16:51:09582 BeforeHeadersSentHandler()
583 : observed_before_headers_sent_with_proxy_(false),
584 observed_before_headers_sent_(false) {}
[email protected]597a1ab2014-06-26 08:12:27585
ryansturm49a8cb12016-06-15 16:51:09586 void OnBeforeHeadersSent(const ProxyInfo& proxy_info,
587 HttpRequestHeaders* request_headers) {
588 observed_before_headers_sent_ = true;
589 if (!proxy_info.is_http() && !proxy_info.is_https() &&
590 !proxy_info.is_quic()) {
591 return;
592 }
593 observed_before_headers_sent_with_proxy_ = true;
[email protected]597a1ab2014-06-26 08:12:27594 observed_proxy_server_uri_ = proxy_info.proxy_server().ToURI();
595 }
596
ryansturm49a8cb12016-06-15 16:51:09597 bool observed_before_headers_sent_with_proxy() const {
598 return observed_before_headers_sent_with_proxy_;
599 }
600
601 bool observed_before_headers_sent() const {
602 return observed_before_headers_sent_;
[email protected]597a1ab2014-06-26 08:12:27603 }
604
605 std::string observed_proxy_server_uri() const {
606 return observed_proxy_server_uri_;
607 }
608
609 private:
ryansturm49a8cb12016-06-15 16:51:09610 bool observed_before_headers_sent_with_proxy_;
611 bool observed_before_headers_sent_;
[email protected]597a1ab2014-06-26 08:12:27612 std::string observed_proxy_server_uri_;
613
ryansturm49a8cb12016-06-15 16:51:09614 DISALLOW_COPY_AND_ASSIGN(BeforeHeadersSentHandler);
[email protected]597a1ab2014-06-26 08:12:27615};
616
[email protected]15a5ccf82008-10-23 19:57:43617// Fill |str| with a long header list that consumes >= |size| bytes.
618void FillLargeHeadersString(std::string* str, int size) {
thestig9d3bb0c2015-01-24 00:49:51619 const char row[] =
[email protected]4ddaf2502008-10-23 18:26:19620 "SomeHeaderName: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx\r\n";
621 const int sizeof_row = strlen(row);
622 const int num_rows = static_cast<int>(
623 ceil(static_cast<float>(size) / sizeof_row));
624 const int sizeof_data = num_rows * sizeof_row;
625 DCHECK(sizeof_data >= size);
[email protected]15a5ccf82008-10-23 19:57:43626 str->reserve(sizeof_data);
[email protected]372d34a2008-11-05 21:30:51627
[email protected]4ddaf2502008-10-23 18:26:19628 for (int i = 0; i < num_rows; ++i)
[email protected]15a5ccf82008-10-23 19:57:43629 str->append(row, sizeof_row);
[email protected]4ddaf2502008-10-23 18:26:19630}
631
thakis84dff942015-07-28 20:47:38632#if defined(NTLM_PORTABLE)
[email protected]385a4672009-03-11 22:21:29633// Alternative functions that eliminate randomness and dependency on the local
634// host name so that the generated NTLM messages are reproducible.
avibf0746c2015-12-09 19:53:14635void MockGenerateRandom1(uint8_t* output, size_t n) {
636 static const uint8_t bytes[] = {0x55, 0x29, 0x66, 0x26,
637 0x6b, 0x9c, 0x73, 0x54};
[email protected]385a4672009-03-11 22:21:29638 static size_t current_byte = 0;
639 for (size_t i = 0; i < n; ++i) {
640 output[i] = bytes[current_byte++];
641 current_byte %= arraysize(bytes);
642 }
643}
644
avibf0746c2015-12-09 19:53:14645void MockGenerateRandom2(uint8_t* output, size_t n) {
646 static const uint8_t bytes[] = {0x96, 0x79, 0x85, 0xe7, 0x49, 0x93,
647 0x70, 0xa1, 0x4e, 0xe7, 0x87, 0x45,
648 0x31, 0x5b, 0xd3, 0x1f};
[email protected]385a4672009-03-11 22:21:29649 static size_t current_byte = 0;
650 for (size_t i = 0; i < n; ++i) {
651 output[i] = bytes[current_byte++];
652 current_byte %= arraysize(bytes);
653 }
654}
655
[email protected]fe2bc6a2009-03-23 16:52:20656std::string MockGetHostName() {
657 return "WTC-WIN7";
[email protected]385a4672009-03-11 22:21:29658}
thakis84dff942015-07-28 20:47:38659#endif // defined(NTLM_PORTABLE)
[email protected]385a4672009-03-11 22:21:29660
[email protected]e60e47a2010-07-14 03:37:18661template<typename ParentPool>
662class CaptureGroupNameSocketPool : public ParentPool {
[email protected]04e5be32009-06-26 20:00:31663 public:
[email protected]9e1bdd32011-02-03 21:48:34664 CaptureGroupNameSocketPool(HostResolver* host_resolver,
665 CertVerifier* cert_verifier);
[email protected]e60e47a2010-07-14 03:37:18666
[email protected]d80a4322009-08-14 07:07:49667 const std::string last_group_name_received() const {
668 return last_group_name_;
669 }
670
dmichaeld6e570d2014-12-18 22:30:57671 int RequestSocket(const std::string& group_name,
672 const void* socket_params,
673 RequestPriority priority,
mmenked3641e12016-01-28 16:06:15674 ClientSocketPool::RespectLimits respect_limits,
dmichaeld6e570d2014-12-18 22:30:57675 ClientSocketHandle* handle,
676 const CompletionCallback& callback,
tfarina42834112016-09-22 13:38:20677 const NetLogWithSource& net_log) override {
[email protected]04e5be32009-06-26 20:00:31678 last_group_name_ = group_name;
679 return ERR_IO_PENDING;
680 }
dmichaeld6e570d2014-12-18 22:30:57681 void CancelRequest(const std::string& group_name,
682 ClientSocketHandle* handle) override {}
683 void ReleaseSocket(const std::string& group_name,
danakj1fd259a02016-04-16 03:17:09684 std::unique_ptr<StreamSocket> socket,
dmichaeld6e570d2014-12-18 22:30:57685 int id) override {}
686 void CloseIdleSockets() override {}
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
bnc8bef8da22016-05-30 01:28:2510165// HTTP/2 Alternative Services should be disabled if alternative service
10166// hostname is different from that of origin.
10167// TODO(bnc): Remove when https://crbug.com/615413 is fixed.
bncd16676a2016-07-20 16:23:0110168TEST_F(HttpNetworkTransactionTest,
bnc8bef8da22016-05-30 01:28:2510169 DisableHTTP2AlternativeServicesWithDifferentHost) {
bncb26024382016-06-29 02:39:4510170 session_deps_.enable_http2_alternative_service_with_different_host = false;
10171
bnc8bef8da22016-05-30 01:28:2510172 HttpRequestInfo request;
10173 request.method = "GET";
bncb26024382016-06-29 02:39:4510174 request.url = GURL("https://www.example.org/");
bnc8bef8da22016-05-30 01:28:2510175 request.load_flags = 0;
10176
10177 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
10178 StaticSocketDataProvider first_data;
10179 first_data.set_connect_data(mock_connect);
10180 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
bncb26024382016-06-29 02:39:4510181 SSLSocketDataProvider ssl_http11(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3610182 ssl_http11.next_proto = kProtoHTTP11;
bncb26024382016-06-29 02:39:4510183 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_http11);
bnc8bef8da22016-05-30 01:28:2510184
10185 MockRead data_reads[] = {
10186 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello world"),
10187 MockRead(ASYNC, OK),
10188 };
10189 StaticSocketDataProvider second_data(data_reads, arraysize(data_reads), NULL,
10190 0);
10191 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
10192
10193 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
10194
bnc525e175a2016-06-20 12:36:4010195 HttpServerProperties* http_server_properties =
bnc8bef8da22016-05-30 01:28:2510196 session->http_server_properties();
bnc3472afd2016-11-17 15:27:2110197 AlternativeService alternative_service(kProtoHTTP2, "different.example.org",
10198 444);
bnc8bef8da22016-05-30 01:28:2510199 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
10200 http_server_properties->SetAlternativeService(
10201 url::SchemeHostPort(request.url), alternative_service, expiration);
10202
bnc691fda62016-08-12 00:43:1610203 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
bnc8bef8da22016-05-30 01:28:2510204 TestCompletionCallback callback;
10205
tfarina42834112016-09-22 13:38:2010206 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
bnc8bef8da22016-05-30 01:28:2510207 // Alternative service is not used, request fails.
robpercival214763f2016-07-01 23:27:0110208 EXPECT_THAT(callback.GetResult(rv), IsError(ERR_CONNECTION_REFUSED));
bnc8bef8da22016-05-30 01:28:2510209}
10210
bnce3dd56f2016-06-01 10:37:1110211// Regression test for https://crbug.com/615497:
10212// Alternative Services should be disabled for http origin.
bncd16676a2016-07-20 16:23:0110213TEST_F(HttpNetworkTransactionTest,
bnce3dd56f2016-06-01 10:37:1110214 DisableAlternativeServicesForInsecureOrigin) {
bnce3dd56f2016-06-01 10:37:1110215 HttpRequestInfo request;
10216 request.method = "GET";
10217 request.url = GURL("http://www.example.org/");
10218 request.load_flags = 0;
10219
10220 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
10221 StaticSocketDataProvider first_data;
10222 first_data.set_connect_data(mock_connect);
10223 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
10224
10225 MockRead data_reads[] = {
10226 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello world"),
10227 MockRead(ASYNC, OK),
10228 };
10229 StaticSocketDataProvider second_data(data_reads, arraysize(data_reads), NULL,
10230 0);
10231 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
10232
10233 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
10234
bnc525e175a2016-06-20 12:36:4010235 HttpServerProperties* http_server_properties =
bnce3dd56f2016-06-01 10:37:1110236 session->http_server_properties();
bnc3472afd2016-11-17 15:27:2110237 AlternativeService alternative_service(kProtoHTTP2, "", 444);
bnce3dd56f2016-06-01 10:37:1110238 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
10239 http_server_properties->SetAlternativeService(
10240 url::SchemeHostPort(request.url), alternative_service, expiration);
10241
bnc691fda62016-08-12 00:43:1610242 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
bnce3dd56f2016-06-01 10:37:1110243 TestCompletionCallback callback;
10244
tfarina42834112016-09-22 13:38:2010245 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
bnce3dd56f2016-06-01 10:37:1110246 // Alternative service is not used, request fails.
robpercival214763f2016-07-01 23:27:0110247 EXPECT_THAT(callback.GetResult(rv), IsError(ERR_CONNECTION_REFUSED));
bnce3dd56f2016-06-01 10:37:1110248}
10249
bncd16676a2016-07-20 16:23:0110250TEST_F(HttpNetworkTransactionTest, ClearAlternativeServices) {
bnc4f575852015-10-14 18:35:0810251 // Set an alternative service for origin.
danakj1fd259a02016-04-16 03:17:0910252 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc525e175a2016-06-20 12:36:4010253 HttpServerProperties* http_server_properties =
10254 session->http_server_properties();
bncb26024382016-06-29 02:39:4510255 url::SchemeHostPort test_server("https", "www.example.org", 443);
bnc3472afd2016-11-17 15:27:2110256 AlternativeService alternative_service(kProtoQUIC, "", 80);
bnc4f575852015-10-14 18:35:0810257 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
bnc525e175a2016-06-20 12:36:4010258 http_server_properties->SetAlternativeService(
10259 test_server, alternative_service, expiration);
bnc4f575852015-10-14 18:35:0810260 AlternativeServiceVector alternative_service_vector =
bnc525e175a2016-06-20 12:36:4010261 http_server_properties->GetAlternativeServices(test_server);
bnc4f575852015-10-14 18:35:0810262 EXPECT_EQ(1u, alternative_service_vector.size());
10263
10264 // Send a clear header.
10265 MockRead data_reads[] = {
10266 MockRead("HTTP/1.1 200 OK\r\n"),
10267 MockRead("Alt-Svc: clear\r\n"),
10268 MockRead("\r\n"),
10269 MockRead("hello world"),
10270 MockRead(SYNCHRONOUS, OK),
10271 };
10272 StaticSocketDataProvider data(data_reads, arraysize(data_reads), nullptr, 0);
10273 session_deps_.socket_factory->AddSocketDataProvider(&data);
10274
bncb26024382016-06-29 02:39:4510275 SSLSocketDataProvider ssl(ASYNC, OK);
10276 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
10277
bnc4f575852015-10-14 18:35:0810278 HttpRequestInfo request;
10279 request.method = "GET";
bncb26024382016-06-29 02:39:4510280 request.url = GURL("https://www.example.org/");
bnc4f575852015-10-14 18:35:0810281
10282 TestCompletionCallback callback;
10283
bnc691fda62016-08-12 00:43:1610284 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
bnc4f575852015-10-14 18:35:0810285
tfarina42834112016-09-22 13:38:2010286 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110287 EXPECT_THAT(callback.GetResult(rv), IsOk());
bnc4f575852015-10-14 18:35:0810288
bnc691fda62016-08-12 00:43:1610289 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5210290 ASSERT_TRUE(response);
10291 ASSERT_TRUE(response->headers);
bnc4f575852015-10-14 18:35:0810292 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
10293 EXPECT_FALSE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5210294 EXPECT_FALSE(response->was_alpn_negotiated);
bnc4f575852015-10-14 18:35:0810295
10296 std::string response_data;
bnc691fda62016-08-12 00:43:1610297 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
bnc4f575852015-10-14 18:35:0810298 EXPECT_EQ("hello world", response_data);
10299
10300 alternative_service_vector =
bnc525e175a2016-06-20 12:36:4010301 http_server_properties->GetAlternativeServices(test_server);
bnc4f575852015-10-14 18:35:0810302 EXPECT_TRUE(alternative_service_vector.empty());
10303}
10304
bncd16676a2016-07-20 16:23:0110305TEST_F(HttpNetworkTransactionTest, HonorMultipleAlternativeServiceHeaders) {
bncc958faa2015-07-31 18:14:5210306 MockRead data_reads[] = {
10307 MockRead("HTTP/1.1 200 OK\r\n"),
bnc2df4b522016-07-08 18:17:4310308 MockRead("Alt-Svc: h2=\"www.example.com:443\","),
10309 MockRead("h2=\":1234\"\r\n\r\n"),
bncc958faa2015-07-31 18:14:5210310 MockRead("hello world"),
10311 MockRead(SYNCHRONOUS, OK),
10312 };
10313
10314 HttpRequestInfo request;
10315 request.method = "GET";
bncb26024382016-06-29 02:39:4510316 request.url = GURL("https://www.example.org/");
bncc958faa2015-07-31 18:14:5210317
10318 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
bncc958faa2015-07-31 18:14:5210319 session_deps_.socket_factory->AddSocketDataProvider(&data);
10320
bncb26024382016-06-29 02:39:4510321 SSLSocketDataProvider ssl(ASYNC, OK);
10322 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
10323
bncc958faa2015-07-31 18:14:5210324 TestCompletionCallback callback;
10325
danakj1fd259a02016-04-16 03:17:0910326 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1610327 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
bncc958faa2015-07-31 18:14:5210328
tfarina42834112016-09-22 13:38:2010329 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110330 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
bncc958faa2015-07-31 18:14:5210331
bncb26024382016-06-29 02:39:4510332 url::SchemeHostPort test_server("https", "www.example.org", 443);
bnc525e175a2016-06-20 12:36:4010333 HttpServerProperties* http_server_properties =
10334 session->http_server_properties();
bncc958faa2015-07-31 18:14:5210335 AlternativeServiceVector alternative_service_vector =
bnc525e175a2016-06-20 12:36:4010336 http_server_properties->GetAlternativeServices(test_server);
bncc958faa2015-07-31 18:14:5210337 EXPECT_TRUE(alternative_service_vector.empty());
10338
robpercival214763f2016-07-01 23:27:0110339 EXPECT_THAT(callback.WaitForResult(), IsOk());
bncc958faa2015-07-31 18:14:5210340
bnc691fda62016-08-12 00:43:1610341 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5210342 ASSERT_TRUE(response);
10343 ASSERT_TRUE(response->headers);
bncc958faa2015-07-31 18:14:5210344 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
10345 EXPECT_FALSE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5210346 EXPECT_FALSE(response->was_alpn_negotiated);
bncc958faa2015-07-31 18:14:5210347
10348 std::string response_data;
bnc691fda62016-08-12 00:43:1610349 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
bncc958faa2015-07-31 18:14:5210350 EXPECT_EQ("hello world", response_data);
10351
10352 alternative_service_vector =
bnc525e175a2016-06-20 12:36:4010353 http_server_properties->GetAlternativeServices(test_server);
bncc958faa2015-07-31 18:14:5210354 ASSERT_EQ(2u, alternative_service_vector.size());
bnc3472afd2016-11-17 15:27:2110355 EXPECT_EQ(kProtoHTTP2, alternative_service_vector[0].protocol);
bncc958faa2015-07-31 18:14:5210356 EXPECT_EQ("www.example.com", alternative_service_vector[0].host);
10357 EXPECT_EQ(443, alternative_service_vector[0].port);
bnc3472afd2016-11-17 15:27:2110358 EXPECT_EQ(kProtoHTTP2, alternative_service_vector[1].protocol);
bncc958faa2015-07-31 18:14:5210359 EXPECT_EQ("www.example.org", alternative_service_vector[1].host);
10360 EXPECT_EQ(1234, alternative_service_vector[1].port);
10361}
10362
bncd16676a2016-07-20 16:23:0110363TEST_F(HttpNetworkTransactionTest, IdentifyQuicBroken) {
zhongyi3d4a55e72016-04-22 20:36:4610364 url::SchemeHostPort server("https", "origin.example.org", 443);
zhongyi48704c182015-12-07 07:52:0210365 HostPortPair alternative("alternative.example.org", 443);
10366 std::string origin_url = "https://origin.example.org:443";
10367 std::string alternative_url = "https://alternative.example.org:443";
10368
10369 // Negotiate HTTP/1.1 with alternative.example.org.
10370 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3610371 ssl.next_proto = kProtoHTTP11;
zhongyi48704c182015-12-07 07:52:0210372 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
10373
10374 // HTTP/1.1 data for request.
10375 MockWrite http_writes[] = {
10376 MockWrite("GET / HTTP/1.1\r\n"
10377 "Host: alternative.example.org\r\n"
10378 "Connection: keep-alive\r\n\r\n"),
10379 };
10380
10381 MockRead http_reads[] = {
10382 MockRead("HTTP/1.1 200 OK\r\n"
10383 "Content-Type: text/html; charset=iso-8859-1\r\n"
10384 "Content-Length: 40\r\n\r\n"
10385 "first HTTP/1.1 response from alternative"),
10386 };
10387 StaticSocketDataProvider http_data(http_reads, arraysize(http_reads),
10388 http_writes, arraysize(http_writes));
10389 session_deps_.socket_factory->AddSocketDataProvider(&http_data);
10390
10391 StaticSocketDataProvider data_refused;
10392 data_refused.set_connect_data(MockConnect(ASYNC, ERR_CONNECTION_REFUSED));
10393 session_deps_.socket_factory->AddSocketDataProvider(&data_refused);
10394
zhongyi3d4a55e72016-04-22 20:36:4610395 // Set up a QUIC alternative service for server.
danakj1fd259a02016-04-16 03:17:0910396 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc525e175a2016-06-20 12:36:4010397 HttpServerProperties* http_server_properties =
zhongyi48704c182015-12-07 07:52:0210398 session->http_server_properties();
bnc3472afd2016-11-17 15:27:2110399 AlternativeService alternative_service(kProtoQUIC, alternative);
zhongyi48704c182015-12-07 07:52:0210400 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyi3d4a55e72016-04-22 20:36:4610401 http_server_properties->SetAlternativeService(server, alternative_service,
rchdc7b9052016-03-17 20:51:5010402 expiration);
zhongyi48704c182015-12-07 07:52:0210403 // Mark the QUIC alternative service as broken.
10404 http_server_properties->MarkAlternativeServiceBroken(alternative_service);
10405
zhongyi48704c182015-12-07 07:52:0210406 HttpRequestInfo request;
krasinc06a72a2016-12-21 03:42:4610407 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
zhongyi48704c182015-12-07 07:52:0210408 request.method = "GET";
10409 request.url = GURL(origin_url);
zhongyi48704c182015-12-07 07:52:0210410 TestCompletionCallback callback;
10411 NetErrorDetails details;
10412 EXPECT_FALSE(details.quic_broken);
10413
tfarina42834112016-09-22 13:38:2010414 trans.Start(&request, callback.callback(), NetLogWithSource());
bnc691fda62016-08-12 00:43:1610415 trans.PopulateNetErrorDetails(&details);
zhongyi48704c182015-12-07 07:52:0210416 EXPECT_TRUE(details.quic_broken);
10417}
10418
bncd16676a2016-07-20 16:23:0110419TEST_F(HttpNetworkTransactionTest, IdentifyQuicNotBroken) {
zhongyi3d4a55e72016-04-22 20:36:4610420 url::SchemeHostPort server("https", "origin.example.org", 443);
zhongyi48704c182015-12-07 07:52:0210421 HostPortPair alternative1("alternative1.example.org", 443);
10422 HostPortPair alternative2("alternative2.example.org", 443);
10423 std::string origin_url = "https://origin.example.org:443";
10424 std::string alternative_url1 = "https://alternative1.example.org:443";
10425 std::string alternative_url2 = "https://alternative2.example.org:443";
10426
10427 // Negotiate HTTP/1.1 with alternative1.example.org.
10428 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3610429 ssl.next_proto = kProtoHTTP11;
zhongyi48704c182015-12-07 07:52:0210430 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
10431
10432 // HTTP/1.1 data for request.
10433 MockWrite http_writes[] = {
10434 MockWrite("GET / HTTP/1.1\r\n"
10435 "Host: alternative1.example.org\r\n"
10436 "Connection: keep-alive\r\n\r\n"),
10437 };
10438
10439 MockRead http_reads[] = {
10440 MockRead("HTTP/1.1 200 OK\r\n"
10441 "Content-Type: text/html; charset=iso-8859-1\r\n"
10442 "Content-Length: 40\r\n\r\n"
10443 "first HTTP/1.1 response from alternative1"),
10444 };
10445 StaticSocketDataProvider http_data(http_reads, arraysize(http_reads),
10446 http_writes, arraysize(http_writes));
10447 session_deps_.socket_factory->AddSocketDataProvider(&http_data);
10448
10449 StaticSocketDataProvider data_refused;
10450 data_refused.set_connect_data(MockConnect(ASYNC, ERR_CONNECTION_REFUSED));
10451 session_deps_.socket_factory->AddSocketDataProvider(&data_refused);
10452
danakj1fd259a02016-04-16 03:17:0910453 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc525e175a2016-06-20 12:36:4010454 HttpServerProperties* http_server_properties =
zhongyi48704c182015-12-07 07:52:0210455 session->http_server_properties();
10456
zhongyi3d4a55e72016-04-22 20:36:4610457 // Set up two QUIC alternative services for server.
zhongyi48704c182015-12-07 07:52:0210458 AlternativeServiceInfoVector alternative_service_info_vector;
10459 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
10460
bnc3472afd2016-11-17 15:27:2110461 AlternativeService alternative_service1(kProtoQUIC, alternative1);
rchdc7b9052016-03-17 20:51:5010462 AlternativeServiceInfo alternative_service_info1(alternative_service1,
zhongyi48704c182015-12-07 07:52:0210463 expiration);
10464 alternative_service_info_vector.push_back(alternative_service_info1);
bnc3472afd2016-11-17 15:27:2110465 AlternativeService alternative_service2(kProtoQUIC, alternative2);
rchdc7b9052016-03-17 20:51:5010466 AlternativeServiceInfo alternative_service_info2(alternative_service2,
zhongyi48704c182015-12-07 07:52:0210467 expiration);
10468 alternative_service_info_vector.push_back(alternative_service_info2);
10469
10470 http_server_properties->SetAlternativeServices(
zhongyi3d4a55e72016-04-22 20:36:4610471 server, alternative_service_info_vector);
zhongyi48704c182015-12-07 07:52:0210472
10473 // Mark one of the QUIC alternative service as broken.
10474 http_server_properties->MarkAlternativeServiceBroken(alternative_service1);
10475
10476 const AlternativeServiceVector alternative_service_vector =
zhongyi3d4a55e72016-04-22 20:36:4610477 http_server_properties->GetAlternativeServices(server);
zhongyi48704c182015-12-07 07:52:0210478
zhongyi48704c182015-12-07 07:52:0210479 HttpRequestInfo request;
krasinc06a72a2016-12-21 03:42:4610480 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
zhongyi48704c182015-12-07 07:52:0210481 request.method = "GET";
10482 request.url = GURL(origin_url);
zhongyi48704c182015-12-07 07:52:0210483 TestCompletionCallback callback;
10484 NetErrorDetails details;
10485 EXPECT_FALSE(details.quic_broken);
10486
tfarina42834112016-09-22 13:38:2010487 trans.Start(&request, callback.callback(), NetLogWithSource());
bnc691fda62016-08-12 00:43:1610488 trans.PopulateNetErrorDetails(&details);
zhongyi48704c182015-12-07 07:52:0210489 EXPECT_FALSE(details.quic_broken);
10490}
10491
bncd16676a2016-07-20 16:23:0110492TEST_F(HttpNetworkTransactionTest, MarkBrokenAlternateProtocolAndFallback) {
[email protected]564b4912010-03-09 16:30:4210493 HttpRequestInfo request;
10494 request.method = "GET";
bncb26024382016-06-29 02:39:4510495 request.url = GURL("https://www.example.org/");
[email protected]564b4912010-03-09 16:30:4210496
[email protected]d973e99a2012-02-17 21:02:3610497 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
[email protected]564b4912010-03-09 16:30:4210498 StaticSocketDataProvider first_data;
10499 first_data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:0710500 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
bncb26024382016-06-29 02:39:4510501 SSLSocketDataProvider ssl_http11(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3610502 ssl_http11.next_proto = kProtoHTTP11;
bncb26024382016-06-29 02:39:4510503 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_http11);
[email protected]564b4912010-03-09 16:30:4210504
10505 MockRead data_reads[] = {
10506 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
10507 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:0610508 MockRead(ASYNC, OK),
[email protected]564b4912010-03-09 16:30:4210509 };
10510 StaticSocketDataProvider second_data(
10511 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0710512 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
[email protected]564b4912010-03-09 16:30:4210513
danakj1fd259a02016-04-16 03:17:0910514 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]564b4912010-03-09 16:30:4210515
bnc525e175a2016-06-20 12:36:4010516 HttpServerProperties* http_server_properties =
[email protected]17291a022011-10-10 07:32:5310517 session->http_server_properties();
zhongyi3d4a55e72016-04-22 20:36:4610518 const url::SchemeHostPort server(request.url);
[email protected]3912662a32011-10-04 00:51:1110519 // Port must be < 1024, or the header will be ignored (since initial port was
10520 // port 80 (another restricted port).
bncd9b132e2015-07-08 05:16:1010521 const AlternativeService alternative_service(
bnc3472afd2016-11-17 15:27:2110522 kProtoHTTP2, "www.example.org",
bncd9b132e2015-07-08 05:16:1010523 666); // Port is ignored by MockConnect anyway.
bnc7dc7e1b42015-07-28 14:43:1210524 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyi3d4a55e72016-04-22 20:36:4610525 http_server_properties->SetAlternativeService(server, alternative_service,
10526 expiration);
[email protected]564b4912010-03-09 16:30:4210527
bnc691fda62016-08-12 00:43:1610528 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]49639fa2011-12-20 23:22:4110529 TestCompletionCallback callback;
[email protected]564b4912010-03-09 16:30:4210530
tfarina42834112016-09-22 13:38:2010531 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110532 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
10533 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]564b4912010-03-09 16:30:4210534
bnc691fda62016-08-12 00:43:1610535 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5210536 ASSERT_TRUE(response);
10537 ASSERT_TRUE(response->headers);
[email protected]564b4912010-03-09 16:30:4210538 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
10539
10540 std::string response_data;
bnc691fda62016-08-12 00:43:1610541 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
[email protected]564b4912010-03-09 16:30:4210542 EXPECT_EQ("hello world", response_data);
10543
bncd9b132e2015-07-08 05:16:1010544 const AlternativeServiceVector alternative_service_vector =
zhongyi3d4a55e72016-04-22 20:36:4610545 http_server_properties->GetAlternativeServices(server);
bncd9b132e2015-07-08 05:16:1010546 ASSERT_EQ(1u, alternative_service_vector.size());
10547 EXPECT_EQ(alternative_service, alternative_service_vector[0]);
10548 EXPECT_TRUE(http_server_properties->IsAlternativeServiceBroken(
10549 alternative_service_vector[0]));
[email protected]564b4912010-03-09 16:30:4210550}
10551
bnc55ff9da2015-08-19 18:42:3510552// Ensure that we are not allowed to redirect traffic via an alternate protocol
10553// to an unrestricted (port >= 1024) when the original traffic was on a
10554// restricted port (port < 1024). Ensure that we can redirect in all other
10555// cases.
bncd16676a2016-07-20 16:23:0110556TEST_F(HttpNetworkTransactionTest, AlternateProtocolPortRestrictedBlocked) {
[email protected]3912662a32011-10-04 00:51:1110557 HttpRequestInfo restricted_port_request;
10558 restricted_port_request.method = "GET";
bncb26024382016-06-29 02:39:4510559 restricted_port_request.url = GURL("https://www.example.org:1023/");
[email protected]3912662a32011-10-04 00:51:1110560 restricted_port_request.load_flags = 0;
10561
[email protected]d973e99a2012-02-17 21:02:3610562 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
[email protected]3912662a32011-10-04 00:51:1110563 StaticSocketDataProvider first_data;
10564 first_data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:0710565 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
[email protected]3912662a32011-10-04 00:51:1110566
10567 MockRead data_reads[] = {
10568 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
10569 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:0610570 MockRead(ASYNC, OK),
[email protected]3912662a32011-10-04 00:51:1110571 };
10572 StaticSocketDataProvider second_data(
10573 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0710574 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
bncb26024382016-06-29 02:39:4510575 SSLSocketDataProvider ssl_http11(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3610576 ssl_http11.next_proto = kProtoHTTP11;
bncb26024382016-06-29 02:39:4510577 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_http11);
[email protected]3912662a32011-10-04 00:51:1110578
danakj1fd259a02016-04-16 03:17:0910579 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]3912662a32011-10-04 00:51:1110580
bnc525e175a2016-06-20 12:36:4010581 HttpServerProperties* http_server_properties =
[email protected]17291a022011-10-10 07:32:5310582 session->http_server_properties();
[email protected]3912662a32011-10-04 00:51:1110583 const int kUnrestrictedAlternatePort = 1024;
bnc3472afd2016-11-17 15:27:2110584 AlternativeService alternative_service(kProtoHTTP2, "www.example.org",
10585 kUnrestrictedAlternatePort);
bnc7dc7e1b42015-07-28 14:43:1210586 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
bnccacc0992015-03-20 20:22:2210587 http_server_properties->SetAlternativeService(
zhongyi3d4a55e72016-04-22 20:36:4610588 url::SchemeHostPort(restricted_port_request.url), alternative_service,
rchdc7b9052016-03-17 20:51:5010589 expiration);
[email protected]3912662a32011-10-04 00:51:1110590
bnc691fda62016-08-12 00:43:1610591 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]49639fa2011-12-20 23:22:4110592 TestCompletionCallback callback;
[email protected]3912662a32011-10-04 00:51:1110593
tfarina42834112016-09-22 13:38:2010594 int rv = trans.Start(&restricted_port_request, callback.callback(),
10595 NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110596 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]3912662a32011-10-04 00:51:1110597 // Invalid change to unrestricted port should fail.
robpercival214763f2016-07-01 23:27:0110598 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_CONNECTION_REFUSED));
[email protected]c54c6962013-02-01 04:53:1910599}
[email protected]3912662a32011-10-04 00:51:1110600
bnc55ff9da2015-08-19 18:42:3510601// Ensure that we are allowed to redirect traffic via an alternate protocol to
10602// an unrestricted (port >= 1024) when the original traffic was on a restricted
10603// port (port < 1024) if we set |enable_user_alternate_protocol_ports|.
bncd16676a2016-07-20 16:23:0110604TEST_F(HttpNetworkTransactionTest, AlternateProtocolPortRestrictedPermitted) {
[email protected]bb88e1d32013-05-03 23:11:0710605 session_deps_.enable_user_alternate_protocol_ports = true;
[email protected]c54c6962013-02-01 04:53:1910606
10607 HttpRequestInfo restricted_port_request;
10608 restricted_port_request.method = "GET";
bncb26024382016-06-29 02:39:4510609 restricted_port_request.url = GURL("https://www.example.org:1023/");
[email protected]c54c6962013-02-01 04:53:1910610 restricted_port_request.load_flags = 0;
10611
10612 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
10613 StaticSocketDataProvider first_data;
10614 first_data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:0710615 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
[email protected]c54c6962013-02-01 04:53:1910616
10617 MockRead data_reads[] = {
10618 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
10619 MockRead("hello world"),
10620 MockRead(ASYNC, OK),
10621 };
10622 StaticSocketDataProvider second_data(
10623 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0710624 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
bncb26024382016-06-29 02:39:4510625 SSLSocketDataProvider ssl_http11(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3610626 ssl_http11.next_proto = kProtoHTTP11;
bncb26024382016-06-29 02:39:4510627 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_http11);
[email protected]c54c6962013-02-01 04:53:1910628
danakj1fd259a02016-04-16 03:17:0910629 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]c54c6962013-02-01 04:53:1910630
bnc525e175a2016-06-20 12:36:4010631 HttpServerProperties* http_server_properties =
[email protected]c54c6962013-02-01 04:53:1910632 session->http_server_properties();
10633 const int kUnrestrictedAlternatePort = 1024;
bnc3472afd2016-11-17 15:27:2110634 AlternativeService alternative_service(kProtoHTTP2, "www.example.org",
10635 kUnrestrictedAlternatePort);
bnc7dc7e1b42015-07-28 14:43:1210636 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
bnccacc0992015-03-20 20:22:2210637 http_server_properties->SetAlternativeService(
zhongyi3d4a55e72016-04-22 20:36:4610638 url::SchemeHostPort(restricted_port_request.url), alternative_service,
rchdc7b9052016-03-17 20:51:5010639 expiration);
[email protected]c54c6962013-02-01 04:53:1910640
bnc691fda62016-08-12 00:43:1610641 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]c54c6962013-02-01 04:53:1910642 TestCompletionCallback callback;
10643
tfarina42834112016-09-22 13:38:2010644 EXPECT_EQ(ERR_IO_PENDING,
10645 trans.Start(&restricted_port_request, callback.callback(),
10646 NetLogWithSource()));
[email protected]c54c6962013-02-01 04:53:1910647 // Change to unrestricted port should succeed.
robpercival214763f2016-07-01 23:27:0110648 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]3912662a32011-10-04 00:51:1110649}
10650
bnc55ff9da2015-08-19 18:42:3510651// Ensure that we are not allowed to redirect traffic via an alternate protocol
10652// to an unrestricted (port >= 1024) when the original traffic was on a
10653// restricted port (port < 1024). Ensure that we can redirect in all other
10654// cases.
bncd16676a2016-07-20 16:23:0110655TEST_F(HttpNetworkTransactionTest, AlternateProtocolPortRestrictedAllowed) {
[email protected]3912662a32011-10-04 00:51:1110656 HttpRequestInfo restricted_port_request;
10657 restricted_port_request.method = "GET";
bncb26024382016-06-29 02:39:4510658 restricted_port_request.url = GURL("https://www.example.org:1023/");
[email protected]3912662a32011-10-04 00:51:1110659 restricted_port_request.load_flags = 0;
10660
[email protected]d973e99a2012-02-17 21:02:3610661 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
[email protected]3912662a32011-10-04 00:51:1110662 StaticSocketDataProvider first_data;
10663 first_data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:0710664 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
[email protected]3912662a32011-10-04 00:51:1110665
10666 MockRead data_reads[] = {
10667 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
10668 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:0610669 MockRead(ASYNC, OK),
[email protected]3912662a32011-10-04 00:51:1110670 };
10671 StaticSocketDataProvider second_data(
10672 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0710673 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
[email protected]3912662a32011-10-04 00:51:1110674
bncb26024382016-06-29 02:39:4510675 SSLSocketDataProvider ssl(ASYNC, OK);
10676 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
10677
danakj1fd259a02016-04-16 03:17:0910678 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]3912662a32011-10-04 00:51:1110679
bnc525e175a2016-06-20 12:36:4010680 HttpServerProperties* http_server_properties =
[email protected]17291a022011-10-10 07:32:5310681 session->http_server_properties();
[email protected]3912662a32011-10-04 00:51:1110682 const int kRestrictedAlternatePort = 80;
bnc3472afd2016-11-17 15:27:2110683 AlternativeService alternative_service(kProtoHTTP2, "www.example.org",
10684 kRestrictedAlternatePort);
bnc7dc7e1b42015-07-28 14:43:1210685 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
bnccacc0992015-03-20 20:22:2210686 http_server_properties->SetAlternativeService(
zhongyi3d4a55e72016-04-22 20:36:4610687 url::SchemeHostPort(restricted_port_request.url), alternative_service,
rchdc7b9052016-03-17 20:51:5010688 expiration);
[email protected]3912662a32011-10-04 00:51:1110689
bnc691fda62016-08-12 00:43:1610690 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]49639fa2011-12-20 23:22:4110691 TestCompletionCallback callback;
[email protected]3912662a32011-10-04 00:51:1110692
tfarina42834112016-09-22 13:38:2010693 int rv = trans.Start(&restricted_port_request, callback.callback(),
10694 NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110695 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]3912662a32011-10-04 00:51:1110696 // Valid change to restricted port should pass.
robpercival214763f2016-07-01 23:27:0110697 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]3912662a32011-10-04 00:51:1110698}
10699
bnc55ff9da2015-08-19 18:42:3510700// Ensure that we are not allowed to redirect traffic via an alternate protocol
10701// to an unrestricted (port >= 1024) when the original traffic was on a
10702// restricted port (port < 1024). Ensure that we can redirect in all other
10703// cases.
bncd16676a2016-07-20 16:23:0110704TEST_F(HttpNetworkTransactionTest, AlternateProtocolPortUnrestrictedAllowed1) {
[email protected]3912662a32011-10-04 00:51:1110705 HttpRequestInfo unrestricted_port_request;
10706 unrestricted_port_request.method = "GET";
bncb26024382016-06-29 02:39:4510707 unrestricted_port_request.url = GURL("https://www.example.org:1024/");
[email protected]3912662a32011-10-04 00:51:1110708 unrestricted_port_request.load_flags = 0;
10709
[email protected]d973e99a2012-02-17 21:02:3610710 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
[email protected]3912662a32011-10-04 00:51:1110711 StaticSocketDataProvider first_data;
10712 first_data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:0710713 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
[email protected]3912662a32011-10-04 00:51:1110714
10715 MockRead data_reads[] = {
10716 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
10717 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:0610718 MockRead(ASYNC, OK),
[email protected]3912662a32011-10-04 00:51:1110719 };
10720 StaticSocketDataProvider second_data(
10721 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0710722 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
bncb26024382016-06-29 02:39:4510723 SSLSocketDataProvider ssl_http11(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3610724 ssl_http11.next_proto = kProtoHTTP11;
bncb26024382016-06-29 02:39:4510725 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_http11);
[email protected]3912662a32011-10-04 00:51:1110726
danakj1fd259a02016-04-16 03:17:0910727 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]3912662a32011-10-04 00:51:1110728
bnc525e175a2016-06-20 12:36:4010729 HttpServerProperties* http_server_properties =
[email protected]17291a022011-10-10 07:32:5310730 session->http_server_properties();
[email protected]3912662a32011-10-04 00:51:1110731 const int kRestrictedAlternatePort = 80;
bnc3472afd2016-11-17 15:27:2110732 AlternativeService alternative_service(kProtoHTTP2, "www.example.org",
10733 kRestrictedAlternatePort);
bnc7dc7e1b42015-07-28 14:43:1210734 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
bnccacc0992015-03-20 20:22:2210735 http_server_properties->SetAlternativeService(
zhongyi3d4a55e72016-04-22 20:36:4610736 url::SchemeHostPort(unrestricted_port_request.url), alternative_service,
rchdc7b9052016-03-17 20:51:5010737 expiration);
[email protected]3912662a32011-10-04 00:51:1110738
bnc691fda62016-08-12 00:43:1610739 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]49639fa2011-12-20 23:22:4110740 TestCompletionCallback callback;
[email protected]3912662a32011-10-04 00:51:1110741
bnc691fda62016-08-12 00:43:1610742 int rv = trans.Start(&unrestricted_port_request, callback.callback(),
tfarina42834112016-09-22 13:38:2010743 NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110744 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]3912662a32011-10-04 00:51:1110745 // Valid change to restricted port should pass.
robpercival214763f2016-07-01 23:27:0110746 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]3912662a32011-10-04 00:51:1110747}
10748
bnc55ff9da2015-08-19 18:42:3510749// Ensure that we are not allowed to redirect traffic via an alternate protocol
10750// to an unrestricted (port >= 1024) when the original traffic was on a
10751// restricted port (port < 1024). Ensure that we can redirect in all other
10752// cases.
bncd16676a2016-07-20 16:23:0110753TEST_F(HttpNetworkTransactionTest, AlternateProtocolPortUnrestrictedAllowed2) {
[email protected]3912662a32011-10-04 00:51:1110754 HttpRequestInfo unrestricted_port_request;
10755 unrestricted_port_request.method = "GET";
bncb26024382016-06-29 02:39:4510756 unrestricted_port_request.url = GURL("https://www.example.org:1024/");
[email protected]3912662a32011-10-04 00:51:1110757 unrestricted_port_request.load_flags = 0;
10758
[email protected]d973e99a2012-02-17 21:02:3610759 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
[email protected]3912662a32011-10-04 00:51:1110760 StaticSocketDataProvider first_data;
10761 first_data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:0710762 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
[email protected]3912662a32011-10-04 00:51:1110763
10764 MockRead data_reads[] = {
10765 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
10766 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:0610767 MockRead(ASYNC, OK),
[email protected]3912662a32011-10-04 00:51:1110768 };
10769 StaticSocketDataProvider second_data(
10770 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0710771 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
[email protected]3912662a32011-10-04 00:51:1110772
bncb26024382016-06-29 02:39:4510773 SSLSocketDataProvider ssl(ASYNC, OK);
10774 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
10775
danakj1fd259a02016-04-16 03:17:0910776 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]3912662a32011-10-04 00:51:1110777
bnc525e175a2016-06-20 12:36:4010778 HttpServerProperties* http_server_properties =
[email protected]17291a022011-10-10 07:32:5310779 session->http_server_properties();
bnc0bbb02622015-07-23 10:06:2210780 const int kUnrestrictedAlternatePort = 1025;
bnc3472afd2016-11-17 15:27:2110781 AlternativeService alternative_service(kProtoHTTP2, "www.example.org",
10782 kUnrestrictedAlternatePort);
bnc7dc7e1b42015-07-28 14:43:1210783 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
bnccacc0992015-03-20 20:22:2210784 http_server_properties->SetAlternativeService(
zhongyi3d4a55e72016-04-22 20:36:4610785 url::SchemeHostPort(unrestricted_port_request.url), alternative_service,
rchdc7b9052016-03-17 20:51:5010786 expiration);
[email protected]3912662a32011-10-04 00:51:1110787
bnc691fda62016-08-12 00:43:1610788 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]49639fa2011-12-20 23:22:4110789 TestCompletionCallback callback;
[email protected]3912662a32011-10-04 00:51:1110790
bnc691fda62016-08-12 00:43:1610791 int rv = trans.Start(&unrestricted_port_request, callback.callback(),
tfarina42834112016-09-22 13:38:2010792 NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110793 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]3912662a32011-10-04 00:51:1110794 // Valid change to an unrestricted port should pass.
robpercival214763f2016-07-01 23:27:0110795 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]3912662a32011-10-04 00:51:1110796}
10797
bnc55ff9da2015-08-19 18:42:3510798// Ensure that we are not allowed to redirect traffic via an alternate protocol
10799// to an unsafe port, and that we resume the second HttpStreamFactoryImpl::Job
10800// once the alternate protocol request fails.
bncd16676a2016-07-20 16:23:0110801TEST_F(HttpNetworkTransactionTest, AlternateProtocolUnsafeBlocked) {
[email protected]eb6234e2012-01-19 01:50:0210802 HttpRequestInfo request;
10803 request.method = "GET";
bncce36dca22015-04-21 22:11:2310804 request.url = GURL("http://www.example.org/");
[email protected]eb6234e2012-01-19 01:50:0210805
10806 // The alternate protocol request will error out before we attempt to connect,
10807 // so only the standard HTTP request will try to connect.
10808 MockRead data_reads[] = {
10809 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
10810 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:0610811 MockRead(ASYNC, OK),
[email protected]eb6234e2012-01-19 01:50:0210812 };
10813 StaticSocketDataProvider data(
10814 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0710815 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]eb6234e2012-01-19 01:50:0210816
danakj1fd259a02016-04-16 03:17:0910817 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]eb6234e2012-01-19 01:50:0210818
bnc525e175a2016-06-20 12:36:4010819 HttpServerProperties* http_server_properties =
[email protected]eb6234e2012-01-19 01:50:0210820 session->http_server_properties();
10821 const int kUnsafePort = 7;
bnc3472afd2016-11-17 15:27:2110822 AlternativeService alternative_service(kProtoHTTP2, "www.example.org",
10823 kUnsafePort);
bnc7dc7e1b42015-07-28 14:43:1210824 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
bnccacc0992015-03-20 20:22:2210825 http_server_properties->SetAlternativeService(
zhongyi3d4a55e72016-04-22 20:36:4610826 url::SchemeHostPort(request.url), alternative_service, expiration);
[email protected]eb6234e2012-01-19 01:50:0210827
bnc691fda62016-08-12 00:43:1610828 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]eb6234e2012-01-19 01:50:0210829 TestCompletionCallback callback;
10830
tfarina42834112016-09-22 13:38:2010831 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110832 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]eb6234e2012-01-19 01:50:0210833 // The HTTP request should succeed.
robpercival214763f2016-07-01 23:27:0110834 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]eb6234e2012-01-19 01:50:0210835
bnc691fda62016-08-12 00:43:1610836 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5210837 ASSERT_TRUE(response);
10838 ASSERT_TRUE(response->headers);
[email protected]eb6234e2012-01-19 01:50:0210839 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
10840
10841 std::string response_data;
bnc691fda62016-08-12 00:43:1610842 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
[email protected]eb6234e2012-01-19 01:50:0210843 EXPECT_EQ("hello world", response_data);
10844}
10845
bncd16676a2016-07-20 16:23:0110846TEST_F(HttpNetworkTransactionTest, UseAlternateProtocolForNpnSpdy) {
[email protected]2ff8b312010-04-26 22:20:5410847 HttpRequestInfo request;
10848 request.method = "GET";
bncb26024382016-06-29 02:39:4510849 request.url = GURL("https://www.example.org/");
[email protected]2ff8b312010-04-26 22:20:5410850
10851 MockRead data_reads[] = {
bncc958faa2015-07-31 18:14:5210852 MockRead("HTTP/1.1 200 OK\r\n"),
bnc2df4b522016-07-08 18:17:4310853 MockRead(kAlternativeServiceHttpHeader),
bncc958faa2015-07-31 18:14:5210854 MockRead("\r\n"),
10855 MockRead("hello world"),
10856 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
10857 MockRead(ASYNC, OK)};
[email protected]2ff8b312010-04-26 22:20:5410858
10859 StaticSocketDataProvider first_transaction(
10860 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0710861 session_deps_.socket_factory->AddSocketDataProvider(&first_transaction);
bncb26024382016-06-29 02:39:4510862 SSLSocketDataProvider ssl_http11(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3610863 ssl_http11.next_proto = kProtoHTTP11;
bncb26024382016-06-29 02:39:4510864 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_http11);
[email protected]2ff8b312010-04-26 22:20:5410865
bnc032658ba2016-09-26 18:17:1510866 AddSSLSocketData();
[email protected]2ff8b312010-04-26 22:20:5410867
bncdf80d44fd2016-07-15 20:27:4110868 SpdySerializedFrame req(
bncb26024382016-06-29 02:39:4510869 spdy_util_.ConstructSpdyGet("https://www.example.org/", 1, LOWEST));
bncdf80d44fd2016-07-15 20:27:4110870 MockWrite spdy_writes[] = {CreateMockWrite(req, 0)};
[email protected]2ff8b312010-04-26 22:20:5410871
bnc42331402016-07-25 13:36:1510872 SpdySerializedFrame resp(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
bncdf80d44fd2016-07-15 20:27:4110873 SpdySerializedFrame data(spdy_util_.ConstructSpdyDataFrame(1, true));
[email protected]2ff8b312010-04-26 22:20:5410874 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:4110875 CreateMockRead(resp, 1), CreateMockRead(data, 2), MockRead(ASYNC, 0, 3),
[email protected]2ff8b312010-04-26 22:20:5410876 };
10877
rch8e6c6c42015-05-01 14:05:1310878 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
10879 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:0710880 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]2ff8b312010-04-26 22:20:5410881
[email protected]d973e99a2012-02-17 21:02:3610882 MockConnect never_finishing_connect(SYNCHRONOUS, ERR_IO_PENDING);
[email protected]2d6728692011-03-12 01:39:5510883 StaticSocketDataProvider hanging_non_alternate_protocol_socket(
10884 NULL, 0, NULL, 0);
10885 hanging_non_alternate_protocol_socket.set_connect_data(
10886 never_finishing_connect);
[email protected]bb88e1d32013-05-03 23:11:0710887 session_deps_.socket_factory->AddSocketDataProvider(
[email protected]2d6728692011-03-12 01:39:5510888 &hanging_non_alternate_protocol_socket);
10889
[email protected]49639fa2011-12-20 23:22:4110890 TestCompletionCallback callback;
[email protected]2ff8b312010-04-26 22:20:5410891
danakj1fd259a02016-04-16 03:17:0910892 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1610893 std::unique_ptr<HttpNetworkTransaction> trans(
[email protected]90499482013-06-01 00:39:5010894 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]2ff8b312010-04-26 22:20:5410895
tfarina42834112016-09-22 13:38:2010896 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110897 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
10898 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]2ff8b312010-04-26 22:20:5410899
10900 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5210901 ASSERT_TRUE(response);
10902 ASSERT_TRUE(response->headers);
[email protected]2ff8b312010-04-26 22:20:5410903 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
10904
10905 std::string response_data;
robpercival214763f2016-07-01 23:27:0110906 ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
[email protected]2ff8b312010-04-26 22:20:5410907 EXPECT_EQ("hello world", response_data);
10908
[email protected]90499482013-06-01 00:39:5010909 trans.reset(new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]2ff8b312010-04-26 22:20:5410910
tfarina42834112016-09-22 13:38:2010911 rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110912 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
10913 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]2ff8b312010-04-26 22:20:5410914
10915 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5210916 ASSERT_TRUE(response);
10917 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0210918 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]65041fa2010-05-21 06:56:5310919 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5210920 EXPECT_TRUE(response->was_alpn_negotiated);
[email protected]2ff8b312010-04-26 22:20:5410921
robpercival214763f2016-07-01 23:27:0110922 ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
[email protected]2ff8b312010-04-26 22:20:5410923 EXPECT_EQ("hello!", response_data);
[email protected]2ff8b312010-04-26 22:20:5410924}
10925
bncd16676a2016-07-20 16:23:0110926TEST_F(HttpNetworkTransactionTest, AlternateProtocolWithSpdyLateBinding) {
[email protected]2d6728692011-03-12 01:39:5510927 HttpRequestInfo request;
10928 request.method = "GET";
bncb26024382016-06-29 02:39:4510929 request.url = GURL("https://www.example.org/");
[email protected]2d6728692011-03-12 01:39:5510930
bncb26024382016-06-29 02:39:4510931 // First transaction receives Alt-Svc header over HTTP/1.1.
[email protected]2d6728692011-03-12 01:39:5510932 MockRead data_reads[] = {
bncc958faa2015-07-31 18:14:5210933 MockRead("HTTP/1.1 200 OK\r\n"),
bnc2df4b522016-07-08 18:17:4310934 MockRead(kAlternativeServiceHttpHeader),
bncc958faa2015-07-31 18:14:5210935 MockRead("\r\n"),
10936 MockRead("hello world"),
10937 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
10938 MockRead(ASYNC, OK),
[email protected]2d6728692011-03-12 01:39:5510939 };
10940
bncb26024382016-06-29 02:39:4510941 StaticSocketDataProvider http11_data(data_reads, arraysize(data_reads), NULL,
10942 0);
10943 session_deps_.socket_factory->AddSocketDataProvider(&http11_data);
[email protected]2d6728692011-03-12 01:39:5510944
bncb26024382016-06-29 02:39:4510945 SSLSocketDataProvider ssl_http11(ASYNC, OK);
10946 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_http11);
10947
10948 // Second transaction starts an alternative and a non-alternative Job.
10949 // Both sockets hang.
[email protected]d973e99a2012-02-17 21:02:3610950 MockConnect never_finishing_connect(SYNCHRONOUS, ERR_IO_PENDING);
mmenkecc2298e2015-12-07 18:20:1810951 StaticSocketDataProvider hanging_socket1(NULL, 0, NULL, 0);
10952 hanging_socket1.set_connect_data(never_finishing_connect);
mmenkecc2298e2015-12-07 18:20:1810953 session_deps_.socket_factory->AddSocketDataProvider(&hanging_socket1);
10954
10955 StaticSocketDataProvider hanging_socket2(NULL, 0, NULL, 0);
10956 hanging_socket2.set_connect_data(never_finishing_connect);
10957 session_deps_.socket_factory->AddSocketDataProvider(&hanging_socket2);
[email protected]2d6728692011-03-12 01:39:5510958
bncb26024382016-06-29 02:39:4510959 // Third transaction starts an alternative and a non-alternative job.
10960 // The non-alternative job hangs, but the alternative one succeeds.
10961 // The second transaction, still pending, binds to this socket.
bncdf80d44fd2016-07-15 20:27:4110962 SpdySerializedFrame req1(
bncb26024382016-06-29 02:39:4510963 spdy_util_.ConstructSpdyGet("https://www.example.org/", 1, LOWEST));
bncdf80d44fd2016-07-15 20:27:4110964 SpdySerializedFrame req2(
bncb26024382016-06-29 02:39:4510965 spdy_util_.ConstructSpdyGet("https://www.example.org/", 3, LOWEST));
[email protected]2d6728692011-03-12 01:39:5510966 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:4110967 CreateMockWrite(req1, 0), CreateMockWrite(req2, 1),
[email protected]2d6728692011-03-12 01:39:5510968 };
bnc42331402016-07-25 13:36:1510969 SpdySerializedFrame resp1(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
bncdf80d44fd2016-07-15 20:27:4110970 SpdySerializedFrame data1(spdy_util_.ConstructSpdyDataFrame(1, true));
bnc42331402016-07-25 13:36:1510971 SpdySerializedFrame resp2(spdy_util_.ConstructSpdyGetReply(NULL, 0, 3));
bncdf80d44fd2016-07-15 20:27:4110972 SpdySerializedFrame data2(spdy_util_.ConstructSpdyDataFrame(3, true));
[email protected]2d6728692011-03-12 01:39:5510973 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:4110974 CreateMockRead(resp1, 2), CreateMockRead(data1, 3),
10975 CreateMockRead(resp2, 4), CreateMockRead(data2, 5),
rch8e6c6c42015-05-01 14:05:1310976 MockRead(ASYNC, 0, 6),
[email protected]2d6728692011-03-12 01:39:5510977 };
10978
rch8e6c6c42015-05-01 14:05:1310979 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
10980 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:0710981 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]2d6728692011-03-12 01:39:5510982
bnc032658ba2016-09-26 18:17:1510983 AddSSLSocketData();
bncb26024382016-06-29 02:39:4510984
mmenkecc2298e2015-12-07 18:20:1810985 StaticSocketDataProvider hanging_socket3(NULL, 0, NULL, 0);
10986 hanging_socket3.set_connect_data(never_finishing_connect);
10987 session_deps_.socket_factory->AddSocketDataProvider(&hanging_socket3);
[email protected]2d6728692011-03-12 01:39:5510988
danakj1fd259a02016-04-16 03:17:0910989 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]49639fa2011-12-20 23:22:4110990 TestCompletionCallback callback1;
[email protected]90499482013-06-01 00:39:5010991 HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
[email protected]2d6728692011-03-12 01:39:5510992
tfarina42834112016-09-22 13:38:2010993 int rv = trans1.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110994 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
10995 EXPECT_THAT(callback1.WaitForResult(), IsOk());
[email protected]2d6728692011-03-12 01:39:5510996
10997 const HttpResponseInfo* response = trans1.GetResponseInfo();
wezca1070932016-05-26 20:30:5210998 ASSERT_TRUE(response);
10999 ASSERT_TRUE(response->headers);
[email protected]2d6728692011-03-12 01:39:5511000 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
11001
11002 std::string response_data;
robpercival214763f2016-07-01 23:27:0111003 ASSERT_THAT(ReadTransaction(&trans1, &response_data), IsOk());
[email protected]2d6728692011-03-12 01:39:5511004 EXPECT_EQ("hello world", response_data);
11005
[email protected]49639fa2011-12-20 23:22:4111006 TestCompletionCallback callback2;
[email protected]90499482013-06-01 00:39:5011007 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:2011008 rv = trans2.Start(&request, callback2.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0111009 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2d6728692011-03-12 01:39:5511010
[email protected]49639fa2011-12-20 23:22:4111011 TestCompletionCallback callback3;
[email protected]90499482013-06-01 00:39:5011012 HttpNetworkTransaction trans3(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:2011013 rv = trans3.Start(&request, callback3.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0111014 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2d6728692011-03-12 01:39:5511015
robpercival214763f2016-07-01 23:27:0111016 EXPECT_THAT(callback2.WaitForResult(), IsOk());
11017 EXPECT_THAT(callback3.WaitForResult(), IsOk());
[email protected]2d6728692011-03-12 01:39:5511018
11019 response = trans2.GetResponseInfo();
wezca1070932016-05-26 20:30:5211020 ASSERT_TRUE(response);
11021 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0211022 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]2d6728692011-03-12 01:39:5511023 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5211024 EXPECT_TRUE(response->was_alpn_negotiated);
robpercival214763f2016-07-01 23:27:0111025 ASSERT_THAT(ReadTransaction(&trans2, &response_data), IsOk());
[email protected]2d6728692011-03-12 01:39:5511026 EXPECT_EQ("hello!", response_data);
11027
11028 response = trans3.GetResponseInfo();
wezca1070932016-05-26 20:30:5211029 ASSERT_TRUE(response);
11030 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0211031 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]2d6728692011-03-12 01:39:5511032 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5211033 EXPECT_TRUE(response->was_alpn_negotiated);
robpercival214763f2016-07-01 23:27:0111034 ASSERT_THAT(ReadTransaction(&trans3, &response_data), IsOk());
[email protected]2d6728692011-03-12 01:39:5511035 EXPECT_EQ("hello!", response_data);
[email protected]2d6728692011-03-12 01:39:5511036}
11037
bncd16676a2016-07-20 16:23:0111038TEST_F(HttpNetworkTransactionTest, StallAlternativeServiceForNpnSpdy) {
[email protected]2d6728692011-03-12 01:39:5511039 HttpRequestInfo request;
11040 request.method = "GET";
bncb26024382016-06-29 02:39:4511041 request.url = GURL("https://www.example.org/");
[email protected]2d6728692011-03-12 01:39:5511042
11043 MockRead data_reads[] = {
bncc958faa2015-07-31 18:14:5211044 MockRead("HTTP/1.1 200 OK\r\n"),
bnc2df4b522016-07-08 18:17:4311045 MockRead(kAlternativeServiceHttpHeader),
bncc958faa2015-07-31 18:14:5211046 MockRead("\r\n"),
11047 MockRead("hello world"),
11048 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
11049 MockRead(ASYNC, OK),
[email protected]2d6728692011-03-12 01:39:5511050 };
11051
11052 StaticSocketDataProvider first_transaction(
11053 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0711054 session_deps_.socket_factory->AddSocketDataProvider(&first_transaction);
[email protected]2d6728692011-03-12 01:39:5511055
[email protected]8ddf8322012-02-23 18:08:0611056 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:0711057 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]2d6728692011-03-12 01:39:5511058
[email protected]d973e99a2012-02-17 21:02:3611059 MockConnect never_finishing_connect(SYNCHRONOUS, ERR_IO_PENDING);
[email protected]2d6728692011-03-12 01:39:5511060 StaticSocketDataProvider hanging_alternate_protocol_socket(
11061 NULL, 0, NULL, 0);
11062 hanging_alternate_protocol_socket.set_connect_data(
11063 never_finishing_connect);
[email protected]bb88e1d32013-05-03 23:11:0711064 session_deps_.socket_factory->AddSocketDataProvider(
[email protected]2d6728692011-03-12 01:39:5511065 &hanging_alternate_protocol_socket);
11066
bncb26024382016-06-29 02:39:4511067 // 2nd request is just a copy of the first one, over HTTP/1.1 again.
mmenkecc2298e2015-12-07 18:20:1811068 StaticSocketDataProvider second_transaction(data_reads, arraysize(data_reads),
11069 NULL, 0);
11070 session_deps_.socket_factory->AddSocketDataProvider(&second_transaction);
bncb26024382016-06-29 02:39:4511071 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]2d6728692011-03-12 01:39:5511072
[email protected]49639fa2011-12-20 23:22:4111073 TestCompletionCallback callback;
[email protected]2d6728692011-03-12 01:39:5511074
danakj1fd259a02016-04-16 03:17:0911075 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1611076 std::unique_ptr<HttpNetworkTransaction> trans(
[email protected]90499482013-06-01 00:39:5011077 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]2d6728692011-03-12 01:39:5511078
tfarina42834112016-09-22 13:38:2011079 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0111080 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
11081 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]2d6728692011-03-12 01:39:5511082
11083 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5211084 ASSERT_TRUE(response);
11085 ASSERT_TRUE(response->headers);
[email protected]2d6728692011-03-12 01:39:5511086 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
11087
11088 std::string response_data;
robpercival214763f2016-07-01 23:27:0111089 ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
[email protected]2d6728692011-03-12 01:39:5511090 EXPECT_EQ("hello world", response_data);
11091
[email protected]90499482013-06-01 00:39:5011092 trans.reset(new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]2d6728692011-03-12 01:39:5511093
tfarina42834112016-09-22 13:38:2011094 rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0111095 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
11096 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]2d6728692011-03-12 01:39:5511097
11098 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5211099 ASSERT_TRUE(response);
11100 ASSERT_TRUE(response->headers);
[email protected]2d6728692011-03-12 01:39:5511101 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
11102 EXPECT_FALSE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5211103 EXPECT_FALSE(response->was_alpn_negotiated);
[email protected]2d6728692011-03-12 01:39:5511104
robpercival214763f2016-07-01 23:27:0111105 ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
[email protected]2d6728692011-03-12 01:39:5511106 EXPECT_EQ("hello world", response_data);
[email protected]2d6728692011-03-12 01:39:5511107}
11108
[email protected]631f1322010-04-30 17:59:1111109class CapturingProxyResolver : public ProxyResolver {
11110 public:
sammce90c9212015-05-27 23:43:3511111 CapturingProxyResolver() {}
dchengb03027d2014-10-21 12:00:2011112 ~CapturingProxyResolver() override {}
[email protected]631f1322010-04-30 17:59:1111113
dchengb03027d2014-10-21 12:00:2011114 int GetProxyForURL(const GURL& url,
11115 ProxyInfo* results,
11116 const CompletionCallback& callback,
maksim.sisov7e157262016-10-20 11:19:5511117 std::unique_ptr<Request>* request,
tfarina42834112016-09-22 13:38:2011118 const NetLogWithSource& net_log) override {
[email protected]fae7669f2010-08-02 21:49:4011119 ProxyServer proxy_server(ProxyServer::SCHEME_HTTP,
11120 HostPortPair("myproxy", 80));
[email protected]d911f1b2010-05-05 22:39:4211121 results->UseProxyServer(proxy_server);
[email protected]631f1322010-04-30 17:59:1111122 resolved_.push_back(url);
[email protected]d911f1b2010-05-05 22:39:4211123 return OK;
[email protected]631f1322010-04-30 17:59:1111124 }
11125
[email protected]24476402010-07-20 20:55:1711126 const std::vector<GURL>& resolved() const { return resolved_; }
11127
11128 private:
[email protected]631f1322010-04-30 17:59:1111129 std::vector<GURL> resolved_;
11130
11131 DISALLOW_COPY_AND_ASSIGN(CapturingProxyResolver);
11132};
11133
sammce64b2362015-04-29 03:50:2311134class CapturingProxyResolverFactory : public ProxyResolverFactory {
11135 public:
11136 explicit CapturingProxyResolverFactory(CapturingProxyResolver* resolver)
11137 : ProxyResolverFactory(false), resolver_(resolver) {}
11138
11139 int CreateProxyResolver(
11140 const scoped_refptr<ProxyResolverScriptData>& pac_script,
danakj1fd259a02016-04-16 03:17:0911141 std::unique_ptr<ProxyResolver>* resolver,
sammce64b2362015-04-29 03:50:2311142 const net::CompletionCallback& callback,
danakj1fd259a02016-04-16 03:17:0911143 std::unique_ptr<Request>* request) override {
sammce64b2362015-04-29 03:50:2311144 resolver->reset(new ForwardingProxyResolver(resolver_));
11145 return OK;
11146 }
11147
11148 private:
11149 ProxyResolver* resolver_;
11150};
11151
bnc2e884782016-08-11 19:45:1911152// Test that proxy is resolved using the origin url,
11153// regardless of the alternative server.
11154TEST_F(HttpNetworkTransactionTest, UseOriginNotAlternativeForProxy) {
11155 // Configure proxy to bypass www.example.org, which is the origin URL.
11156 ProxyConfig proxy_config;
11157 proxy_config.proxy_rules().ParseFromString("myproxy:70");
11158 proxy_config.proxy_rules().bypass_rules.AddRuleFromString("www.example.org");
11159 auto proxy_config_service =
11160 base::MakeUnique<ProxyConfigServiceFixed>(proxy_config);
11161
11162 CapturingProxyResolver capturing_proxy_resolver;
11163 auto proxy_resolver_factory = base::MakeUnique<CapturingProxyResolverFactory>(
11164 &capturing_proxy_resolver);
11165
11166 TestNetLog net_log;
11167
11168 session_deps_.proxy_service = base::MakeUnique<ProxyService>(
11169 std::move(proxy_config_service), std::move(proxy_resolver_factory),
11170 &net_log);
11171
11172 session_deps_.net_log = &net_log;
11173
11174 // Configure alternative service with a hostname that is not bypassed by the
11175 // proxy.
11176 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
11177 HttpServerProperties* http_server_properties =
11178 session->http_server_properties();
11179 url::SchemeHostPort server("https", "www.example.org", 443);
11180 HostPortPair alternative("www.example.com", 443);
bnc3472afd2016-11-17 15:27:2111181 AlternativeService alternative_service(kProtoHTTP2, alternative);
bnc2e884782016-08-11 19:45:1911182 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
11183 http_server_properties->SetAlternativeService(server, alternative_service,
11184 expiration);
11185
11186 // Non-alternative job should hang.
11187 MockConnect never_finishing_connect(SYNCHRONOUS, ERR_IO_PENDING);
11188 StaticSocketDataProvider hanging_alternate_protocol_socket(nullptr, 0,
11189 nullptr, 0);
11190 hanging_alternate_protocol_socket.set_connect_data(never_finishing_connect);
11191 session_deps_.socket_factory->AddSocketDataProvider(
11192 &hanging_alternate_protocol_socket);
11193
bnc032658ba2016-09-26 18:17:1511194 AddSSLSocketData();
bnc2e884782016-08-11 19:45:1911195
11196 HttpRequestInfo request;
11197 request.method = "GET";
11198 request.url = GURL("https://www.example.org/");
11199 request.load_flags = 0;
11200
11201 SpdySerializedFrame req(
11202 spdy_util_.ConstructSpdyGet("https://www.example.org/", 1, LOWEST));
11203
11204 MockWrite spdy_writes[] = {CreateMockWrite(req, 0)};
11205
11206 SpdySerializedFrame resp(spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
11207 SpdySerializedFrame data(spdy_util_.ConstructSpdyDataFrame(1, true));
11208 MockRead spdy_reads[] = {
11209 CreateMockRead(resp, 1), CreateMockRead(data, 2), MockRead(ASYNC, 0, 3),
11210 };
11211
11212 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
11213 arraysize(spdy_writes));
11214 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
11215
11216 TestCompletionCallback callback;
11217
11218 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
11219
tfarina42834112016-09-22 13:38:2011220 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
bnc2e884782016-08-11 19:45:1911221 EXPECT_THAT(callback.GetResult(rv), IsOk());
11222
11223 const HttpResponseInfo* response = trans.GetResponseInfo();
11224 ASSERT_TRUE(response);
11225 ASSERT_TRUE(response->headers);
11226 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
11227 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5211228 EXPECT_TRUE(response->was_alpn_negotiated);
bnc2e884782016-08-11 19:45:1911229
11230 std::string response_data;
11231 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
11232 EXPECT_EQ("hello!", response_data);
11233
11234 // Origin host bypasses proxy, no resolution should have happened.
11235 ASSERT_TRUE(capturing_proxy_resolver.resolved().empty());
11236}
11237
bncd16676a2016-07-20 16:23:0111238TEST_F(HttpNetworkTransactionTest, UseAlternativeServiceForTunneledNpnSpdy) {
[email protected]631f1322010-04-30 17:59:1111239 ProxyConfig proxy_config;
[email protected]d911f1b2010-05-05 22:39:4211240 proxy_config.set_auto_detect(true);
11241 proxy_config.set_pac_url(GURL("http://fooproxyurl"));
[email protected]2227c692010-05-04 15:36:1111242
sammc5dd160c2015-04-02 02:43:1311243 CapturingProxyResolver capturing_proxy_resolver;
ricea2deef682016-09-09 08:04:0711244 session_deps_.proxy_service.reset(
11245 new ProxyService(base::MakeUnique<ProxyConfigServiceFixed>(proxy_config),
11246 base::MakeUnique<CapturingProxyResolverFactory>(
11247 &capturing_proxy_resolver),
11248 NULL));
vishal.b62985ca92015-04-17 08:45:5111249 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:0711250 session_deps_.net_log = &net_log;
[email protected]631f1322010-04-30 17:59:1111251
11252 HttpRequestInfo request;
11253 request.method = "GET";
bncb26024382016-06-29 02:39:4511254 request.url = GURL("https://www.example.org/");
[email protected]631f1322010-04-30 17:59:1111255
11256 MockRead data_reads[] = {
bncc958faa2015-07-31 18:14:5211257 MockRead("HTTP/1.1 200 OK\r\n"),
bnc2df4b522016-07-08 18:17:4311258 MockRead(kAlternativeServiceHttpHeader),
bncc958faa2015-07-31 18:14:5211259 MockRead("\r\n"),
11260 MockRead("hello world"),
11261 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
11262 MockRead(ASYNC, OK),
[email protected]631f1322010-04-30 17:59:1111263 };
11264
11265 StaticSocketDataProvider first_transaction(
11266 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0711267 session_deps_.socket_factory->AddSocketDataProvider(&first_transaction);
bncb26024382016-06-29 02:39:4511268 SSLSocketDataProvider ssl_http11(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3611269 ssl_http11.next_proto = kProtoHTTP11;
bncb26024382016-06-29 02:39:4511270 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_http11);
[email protected]631f1322010-04-30 17:59:1111271
bnc032658ba2016-09-26 18:17:1511272 AddSSLSocketData();
[email protected]631f1322010-04-30 17:59:1111273
bncdf80d44fd2016-07-15 20:27:4111274 SpdySerializedFrame req(
bncb26024382016-06-29 02:39:4511275 spdy_util_.ConstructSpdyGet("https://www.example.org/", 1, LOWEST));
[email protected]631f1322010-04-30 17:59:1111276 MockWrite spdy_writes[] = {
rch8e6c6c42015-05-01 14:05:1311277 MockWrite(ASYNC, 0,
bnc8bef8da22016-05-30 01:28:2511278 "CONNECT www.example.org:443 HTTP/1.1\r\n"
11279 "Host: www.example.org:443\r\n"
rch8e6c6c42015-05-01 14:05:1311280 "Proxy-Connection: keep-alive\r\n\r\n"),
bncdf80d44fd2016-07-15 20:27:4111281 CreateMockWrite(req, 2),
[email protected]631f1322010-04-30 17:59:1111282 };
11283
[email protected]d911f1b2010-05-05 22:39:4211284 const char kCONNECTResponse[] = "HTTP/1.1 200 Connected\r\n\r\n";
11285
bnc42331402016-07-25 13:36:1511286 SpdySerializedFrame resp(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
bncdf80d44fd2016-07-15 20:27:4111287 SpdySerializedFrame data(spdy_util_.ConstructSpdyDataFrame(1, true));
[email protected]631f1322010-04-30 17:59:1111288 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:4111289 MockRead(ASYNC, 1, kCONNECTResponse), CreateMockRead(resp, 3),
11290 CreateMockRead(data, 4), MockRead(SYNCHRONOUS, ERR_IO_PENDING, 5),
[email protected]631f1322010-04-30 17:59:1111291 };
11292
rch8e6c6c42015-05-01 14:05:1311293 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
11294 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:0711295 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]631f1322010-04-30 17:59:1111296
[email protected]d973e99a2012-02-17 21:02:3611297 MockConnect never_finishing_connect(SYNCHRONOUS, ERR_IO_PENDING);
[email protected]2d6728692011-03-12 01:39:5511298 StaticSocketDataProvider hanging_non_alternate_protocol_socket(
11299 NULL, 0, NULL, 0);
11300 hanging_non_alternate_protocol_socket.set_connect_data(
11301 never_finishing_connect);
[email protected]bb88e1d32013-05-03 23:11:0711302 session_deps_.socket_factory->AddSocketDataProvider(
[email protected]2d6728692011-03-12 01:39:5511303 &hanging_non_alternate_protocol_socket);
11304
[email protected]49639fa2011-12-20 23:22:4111305 TestCompletionCallback callback;
[email protected]631f1322010-04-30 17:59:1111306
danakj1fd259a02016-04-16 03:17:0911307 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1611308 std::unique_ptr<HttpNetworkTransaction> trans(
[email protected]90499482013-06-01 00:39:5011309 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]631f1322010-04-30 17:59:1111310
tfarina42834112016-09-22 13:38:2011311 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
mmenkea2dcd3bf2016-08-16 21:49:4111312 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
11313 EXPECT_THAT(callback.WaitForResult(), IsOk());
11314
11315 const HttpResponseInfo* response = trans->GetResponseInfo();
11316 ASSERT_TRUE(response);
11317 ASSERT_TRUE(response->headers);
11318 EXPECT_EQ("HTTP/0.9 200 OK", response->headers->GetStatusLine());
11319 EXPECT_FALSE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5211320 EXPECT_TRUE(response->was_alpn_negotiated);
mmenkea2dcd3bf2016-08-16 21:49:4111321
11322 std::string response_data;
11323 ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
11324 EXPECT_EQ("hello world", response_data);
[email protected]631f1322010-04-30 17:59:1111325
[email protected]90499482013-06-01 00:39:5011326 trans.reset(new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]631f1322010-04-30 17:59:1111327
tfarina42834112016-09-22 13:38:2011328 rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0111329 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
11330 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]631f1322010-04-30 17:59:1111331
mmenkea2dcd3bf2016-08-16 21:49:4111332 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5211333 ASSERT_TRUE(response);
11334 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0211335 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]65041fa2010-05-21 06:56:5311336 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5211337 EXPECT_TRUE(response->was_alpn_negotiated);
[email protected]631f1322010-04-30 17:59:1111338
robpercival214763f2016-07-01 23:27:0111339 ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
[email protected]631f1322010-04-30 17:59:1111340 EXPECT_EQ("hello!", response_data);
bncb26024382016-06-29 02:39:4511341 ASSERT_EQ(2u, capturing_proxy_resolver.resolved().size());
11342 EXPECT_EQ("https://www.example.org/",
sammc5dd160c2015-04-02 02:43:1311343 capturing_proxy_resolver.resolved()[0].spec());
bncce36dca22015-04-21 22:11:2311344 EXPECT_EQ("https://www.example.org/",
sammc5dd160c2015-04-02 02:43:1311345 capturing_proxy_resolver.resolved()[1].spec());
[email protected]631f1322010-04-30 17:59:1111346
[email protected]029c83b62013-01-24 05:28:2011347 LoadTimingInfo load_timing_info;
11348 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
11349 TestLoadTimingNotReusedWithPac(load_timing_info,
11350 CONNECT_TIMING_HAS_SSL_TIMES);
[email protected]631f1322010-04-30 17:59:1111351}
[email protected]631f1322010-04-30 17:59:1111352
bncd16676a2016-07-20 16:23:0111353TEST_F(HttpNetworkTransactionTest,
bnc1c196c6e2016-05-28 13:51:4811354 UseAlternativeServiceForNpnSpdyWithExistingSpdySession) {
[email protected]2ff8b312010-04-26 22:20:5411355 HttpRequestInfo request;
11356 request.method = "GET";
bncb26024382016-06-29 02:39:4511357 request.url = GURL("https://www.example.org/");
[email protected]2ff8b312010-04-26 22:20:5411358
11359 MockRead data_reads[] = {
bncc958faa2015-07-31 18:14:5211360 MockRead("HTTP/1.1 200 OK\r\n"),
bnc2df4b522016-07-08 18:17:4311361 MockRead(kAlternativeServiceHttpHeader),
bncc958faa2015-07-31 18:14:5211362 MockRead("\r\n"),
11363 MockRead("hello world"),
11364 MockRead(ASYNC, OK),
[email protected]2ff8b312010-04-26 22:20:5411365 };
11366
11367 StaticSocketDataProvider first_transaction(
11368 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0711369 session_deps_.socket_factory->AddSocketDataProvider(&first_transaction);
bncb26024382016-06-29 02:39:4511370 SSLSocketDataProvider ssl_http11(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3611371 ssl_http11.next_proto = kProtoHTTP11;
bncb26024382016-06-29 02:39:4511372 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_http11);
[email protected]2ff8b312010-04-26 22:20:5411373
bnc032658ba2016-09-26 18:17:1511374 AddSSLSocketData();
[email protected]2ff8b312010-04-26 22:20:5411375
bncdf80d44fd2016-07-15 20:27:4111376 SpdySerializedFrame req(
bncb26024382016-06-29 02:39:4511377 spdy_util_.ConstructSpdyGet("https://www.example.org/", 1, LOWEST));
bncdf80d44fd2016-07-15 20:27:4111378 MockWrite spdy_writes[] = {CreateMockWrite(req, 0)};
[email protected]2ff8b312010-04-26 22:20:5411379
bnc42331402016-07-25 13:36:1511380 SpdySerializedFrame resp(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
bncdf80d44fd2016-07-15 20:27:4111381 SpdySerializedFrame data(spdy_util_.ConstructSpdyDataFrame(1, true));
[email protected]2ff8b312010-04-26 22:20:5411382 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:4111383 CreateMockRead(resp, 1), CreateMockRead(data, 2), MockRead(ASYNC, 0, 3),
[email protected]2ff8b312010-04-26 22:20:5411384 };
11385
rch8e6c6c42015-05-01 14:05:1311386 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
11387 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:0711388 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]2ff8b312010-04-26 22:20:5411389
[email protected]83039bb2011-12-09 18:43:5511390 TestCompletionCallback callback;
[email protected]2ff8b312010-04-26 22:20:5411391
danakj1fd259a02016-04-16 03:17:0911392 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]2ff8b312010-04-26 22:20:5411393
bnc691fda62016-08-12 00:43:1611394 std::unique_ptr<HttpNetworkTransaction> trans(
[email protected]90499482013-06-01 00:39:5011395 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]2ff8b312010-04-26 22:20:5411396
tfarina42834112016-09-22 13:38:2011397 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0111398 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
11399 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]2ff8b312010-04-26 22:20:5411400
11401 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5211402 ASSERT_TRUE(response);
11403 ASSERT_TRUE(response->headers);
[email protected]2ff8b312010-04-26 22:20:5411404 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
11405
11406 std::string response_data;
robpercival214763f2016-07-01 23:27:0111407 ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
[email protected]2ff8b312010-04-26 22:20:5411408 EXPECT_EQ("hello world", response_data);
11409
11410 // Set up an initial SpdySession in the pool to reuse.
bnc8bef8da22016-05-30 01:28:2511411 HostPortPair host_port_pair("www.example.org", 443);
[email protected]e6d017652013-05-17 18:01:4011412 SpdySessionKey key(host_port_pair, ProxyServer::Direct(),
[email protected]314b03992014-04-01 01:28:5311413 PRIVACY_MODE_DISABLED);
[email protected]795cbf82013-07-22 09:37:2711414 base::WeakPtr<SpdySession> spdy_session =
tfarina42834112016-09-22 13:38:2011415 CreateSecureSpdySession(session.get(), key, NetLogWithSource());
[email protected]02b0c342010-09-25 21:09:3811416
[email protected]90499482013-06-01 00:39:5011417 trans.reset(new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]2ff8b312010-04-26 22:20:5411418
tfarina42834112016-09-22 13:38:2011419 rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0111420 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
11421 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]2ff8b312010-04-26 22:20:5411422
11423 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5211424 ASSERT_TRUE(response);
11425 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0211426 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]65041fa2010-05-21 06:56:5311427 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5211428 EXPECT_TRUE(response->was_alpn_negotiated);
[email protected]2ff8b312010-04-26 22:20:5411429
robpercival214763f2016-07-01 23:27:0111430 ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
[email protected]2ff8b312010-04-26 22:20:5411431 EXPECT_EQ("hello!", response_data);
[email protected]564b4912010-03-09 16:30:4211432}
11433
[email protected]044de0642010-06-17 10:42:1511434// GenerateAuthToken is a mighty big test.
11435// It tests all permutation of GenerateAuthToken behavior:
11436// - Synchronous and Asynchronous completion.
11437// - OK or error on completion.
11438// - Direct connection, non-authenticating proxy, and authenticating proxy.
11439// - HTTP or HTTPS backend (to include proxy tunneling).
11440// - Non-authenticating and authenticating backend.
11441//
[email protected]fe3b7dc2012-02-03 19:52:0911442// In all, there are 44 reasonable permuations (for example, if there are
[email protected]044de0642010-06-17 10:42:1511443// problems generating an auth token for an authenticating proxy, we don't
11444// need to test all permutations of the backend server).
11445//
11446// The test proceeds by going over each of the configuration cases, and
11447// potentially running up to three rounds in each of the tests. The TestConfig
11448// specifies both the configuration for the test as well as the expectations
11449// for the results.
bncd16676a2016-07-20 16:23:0111450TEST_F(HttpNetworkTransactionTest, GenerateAuthToken) {
[email protected]0b0bf032010-09-21 18:08:5011451 static const char kServer[] = "http://www.example.com";
11452 static const char kSecureServer[] = "https://www.example.com";
11453 static const char kProxy[] = "myproxy:70";
[email protected]044de0642010-06-17 10:42:1511454
11455 enum AuthTiming {
11456 AUTH_NONE,
11457 AUTH_SYNC,
11458 AUTH_ASYNC,
11459 };
11460
11461 const MockWrite kGet(
11462 "GET / HTTP/1.1\r\n"
11463 "Host: www.example.com\r\n"
11464 "Connection: keep-alive\r\n\r\n");
11465 const MockWrite kGetProxy(
11466 "GET http://www.example.com/ HTTP/1.1\r\n"
11467 "Host: www.example.com\r\n"
11468 "Proxy-Connection: keep-alive\r\n\r\n");
11469 const MockWrite kGetAuth(
11470 "GET / HTTP/1.1\r\n"
11471 "Host: www.example.com\r\n"
11472 "Connection: keep-alive\r\n"
11473 "Authorization: auth_token\r\n\r\n");
11474 const MockWrite kGetProxyAuth(
11475 "GET http://www.example.com/ HTTP/1.1\r\n"
11476 "Host: www.example.com\r\n"
11477 "Proxy-Connection: keep-alive\r\n"
11478 "Proxy-Authorization: auth_token\r\n\r\n");
11479 const MockWrite kGetAuthThroughProxy(
11480 "GET http://www.example.com/ HTTP/1.1\r\n"
11481 "Host: www.example.com\r\n"
11482 "Proxy-Connection: keep-alive\r\n"
11483 "Authorization: auth_token\r\n\r\n");
11484 const MockWrite kGetAuthWithProxyAuth(
11485 "GET http://www.example.com/ HTTP/1.1\r\n"
11486 "Host: www.example.com\r\n"
11487 "Proxy-Connection: keep-alive\r\n"
11488 "Proxy-Authorization: auth_token\r\n"
11489 "Authorization: auth_token\r\n\r\n");
11490 const MockWrite kConnect(
11491 "CONNECT www.example.com:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:1711492 "Host: www.example.com:443\r\n"
[email protected]044de0642010-06-17 10:42:1511493 "Proxy-Connection: keep-alive\r\n\r\n");
11494 const MockWrite kConnectProxyAuth(
11495 "CONNECT www.example.com:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:1711496 "Host: www.example.com:443\r\n"
[email protected]044de0642010-06-17 10:42:1511497 "Proxy-Connection: keep-alive\r\n"
11498 "Proxy-Authorization: auth_token\r\n\r\n");
11499
11500 const MockRead kSuccess(
11501 "HTTP/1.1 200 OK\r\n"
11502 "Content-Type: text/html; charset=iso-8859-1\r\n"
11503 "Content-Length: 3\r\n\r\n"
11504 "Yes");
11505 const MockRead kFailure(
11506 "Should not be called.");
11507 const MockRead kServerChallenge(
11508 "HTTP/1.1 401 Unauthorized\r\n"
11509 "WWW-Authenticate: Mock realm=server\r\n"
11510 "Content-Type: text/html; charset=iso-8859-1\r\n"
11511 "Content-Length: 14\r\n\r\n"
11512 "Unauthorized\r\n");
11513 const MockRead kProxyChallenge(
11514 "HTTP/1.1 407 Unauthorized\r\n"
11515 "Proxy-Authenticate: Mock realm=proxy\r\n"
11516 "Proxy-Connection: close\r\n"
11517 "Content-Type: text/html; charset=iso-8859-1\r\n"
11518 "Content-Length: 14\r\n\r\n"
11519 "Unauthorized\r\n");
11520 const MockRead kProxyConnected(
11521 "HTTP/1.1 200 Connection Established\r\n\r\n");
11522
11523 // NOTE(cbentzel): I wanted TestReadWriteRound to be a simple struct with
11524 // no constructors, but the C++ compiler on Windows warns about
11525 // unspecified data in compound literals. So, moved to using constructors,
11526 // and TestRound's created with the default constructor should not be used.
11527 struct TestRound {
11528 TestRound()
11529 : expected_rv(ERR_UNEXPECTED),
11530 extra_write(NULL),
11531 extra_read(NULL) {
11532 }
11533 TestRound(const MockWrite& write_arg, const MockRead& read_arg,
11534 int expected_rv_arg)
11535 : write(write_arg),
11536 read(read_arg),
11537 expected_rv(expected_rv_arg),
11538 extra_write(NULL),
11539 extra_read(NULL) {
11540 }
11541 TestRound(const MockWrite& write_arg, const MockRead& read_arg,
11542 int expected_rv_arg, const MockWrite* extra_write_arg,
[email protected]f871ee152012-07-27 19:02:0111543 const MockRead* extra_read_arg)
[email protected]044de0642010-06-17 10:42:1511544 : write(write_arg),
11545 read(read_arg),
11546 expected_rv(expected_rv_arg),
11547 extra_write(extra_write_arg),
11548 extra_read(extra_read_arg) {
11549 }
11550 MockWrite write;
11551 MockRead read;
11552 int expected_rv;
11553 const MockWrite* extra_write;
11554 const MockRead* extra_read;
11555 };
11556
11557 static const int kNoSSL = 500;
11558
11559 struct TestConfig {
asanka463ca4262016-11-16 02:34:3111560 int line_number;
thestig9d3bb0c2015-01-24 00:49:5111561 const char* const proxy_url;
[email protected]044de0642010-06-17 10:42:1511562 AuthTiming proxy_auth_timing;
asanka463ca4262016-11-16 02:34:3111563 int first_generate_proxy_token_rv;
thestig9d3bb0c2015-01-24 00:49:5111564 const char* const server_url;
[email protected]044de0642010-06-17 10:42:1511565 AuthTiming server_auth_timing;
asanka463ca4262016-11-16 02:34:3111566 int first_generate_server_token_rv;
[email protected]044de0642010-06-17 10:42:1511567 int num_auth_rounds;
11568 int first_ssl_round;
asankae2257db2016-10-11 22:03:1611569 TestRound rounds[4];
[email protected]044de0642010-06-17 10:42:1511570 } test_configs[] = {
asankac93076192016-10-03 15:46:0211571 // Non-authenticating HTTP server with a direct connection.
asanka463ca4262016-11-16 02:34:3111572 {__LINE__,
11573 nullptr,
asankac93076192016-10-03 15:46:0211574 AUTH_NONE,
11575 OK,
11576 kServer,
11577 AUTH_NONE,
11578 OK,
11579 1,
11580 kNoSSL,
11581 {TestRound(kGet, kSuccess, OK)}},
11582 // Authenticating HTTP server with a direct connection.
asanka463ca4262016-11-16 02:34:3111583 {__LINE__,
11584 nullptr,
asankac93076192016-10-03 15:46:0211585 AUTH_NONE,
11586 OK,
11587 kServer,
11588 AUTH_SYNC,
11589 OK,
11590 2,
11591 kNoSSL,
11592 {TestRound(kGet, kServerChallenge, OK),
[email protected]044de0642010-06-17 10:42:1511593 TestRound(kGetAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3111594 {__LINE__,
11595 nullptr,
asankac93076192016-10-03 15:46:0211596 AUTH_NONE,
11597 OK,
11598 kServer,
11599 AUTH_SYNC,
11600 ERR_INVALID_AUTH_CREDENTIALS,
asankae2257db2016-10-11 22:03:1611601 3,
11602 kNoSSL,
11603 {TestRound(kGet, kServerChallenge, OK),
11604 TestRound(kGet, kServerChallenge, OK),
11605 TestRound(kGetAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3111606 {__LINE__,
11607 nullptr,
asankae2257db2016-10-11 22:03:1611608 AUTH_NONE,
11609 OK,
11610 kServer,
11611 AUTH_SYNC,
11612 ERR_UNSUPPORTED_AUTH_SCHEME,
11613 2,
11614 kNoSSL,
11615 {TestRound(kGet, kServerChallenge, OK), TestRound(kGet, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3111616 {__LINE__,
11617 nullptr,
asankae2257db2016-10-11 22:03:1611618 AUTH_NONE,
11619 OK,
11620 kServer,
11621 AUTH_SYNC,
11622 ERR_UNDOCUMENTED_SECURITY_LIBRARY_STATUS,
11623 2,
11624 kNoSSL,
11625 {TestRound(kGet, kServerChallenge, OK), TestRound(kGet, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3111626 {__LINE__,
11627 kProxy,
asankae2257db2016-10-11 22:03:1611628 AUTH_SYNC,
11629 ERR_FAILED,
11630 kServer,
11631 AUTH_NONE,
11632 OK,
11633 2,
11634 kNoSSL,
11635 {TestRound(kGetProxy, kProxyChallenge, OK),
11636 TestRound(kGetProxy, kFailure, ERR_FAILED)}},
asanka463ca4262016-11-16 02:34:3111637 {__LINE__,
11638 kProxy,
asankae2257db2016-10-11 22:03:1611639 AUTH_ASYNC,
11640 ERR_FAILED,
11641 kServer,
11642 AUTH_NONE,
11643 OK,
11644 2,
11645 kNoSSL,
11646 {TestRound(kGetProxy, kProxyChallenge, OK),
11647 TestRound(kGetProxy, kFailure, ERR_FAILED)}},
asanka463ca4262016-11-16 02:34:3111648 {__LINE__,
11649 nullptr,
asankae2257db2016-10-11 22:03:1611650 AUTH_NONE,
11651 OK,
11652 kServer,
11653 AUTH_SYNC,
11654 ERR_FAILED,
asankac93076192016-10-03 15:46:0211655 2,
11656 kNoSSL,
11657 {TestRound(kGet, kServerChallenge, OK),
asankae2257db2016-10-11 22:03:1611658 TestRound(kGet, kFailure, ERR_FAILED)}},
asanka463ca4262016-11-16 02:34:3111659 {__LINE__,
11660 nullptr,
asankae2257db2016-10-11 22:03:1611661 AUTH_NONE,
11662 OK,
11663 kServer,
11664 AUTH_ASYNC,
11665 ERR_FAILED,
11666 2,
11667 kNoSSL,
11668 {TestRound(kGet, kServerChallenge, OK),
11669 TestRound(kGet, kFailure, ERR_FAILED)}},
asanka463ca4262016-11-16 02:34:3111670 {__LINE__,
11671 nullptr,
asankac93076192016-10-03 15:46:0211672 AUTH_NONE,
11673 OK,
11674 kServer,
11675 AUTH_ASYNC,
11676 OK,
11677 2,
11678 kNoSSL,
11679 {TestRound(kGet, kServerChallenge, OK),
[email protected]044de0642010-06-17 10:42:1511680 TestRound(kGetAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3111681 {__LINE__,
11682 nullptr,
asankac93076192016-10-03 15:46:0211683 AUTH_NONE,
11684 OK,
11685 kServer,
11686 AUTH_ASYNC,
11687 ERR_INVALID_AUTH_CREDENTIALS,
asankae2257db2016-10-11 22:03:1611688 3,
asankac93076192016-10-03 15:46:0211689 kNoSSL,
11690 {TestRound(kGet, kServerChallenge, OK),
asankae2257db2016-10-11 22:03:1611691 // The second round uses a HttpAuthHandlerMock that always succeeds.
11692 TestRound(kGet, kServerChallenge, OK),
11693 TestRound(kGetAuth, kSuccess, OK)}},
asankac93076192016-10-03 15:46:0211694 // Non-authenticating HTTP server through a non-authenticating proxy.
asanka463ca4262016-11-16 02:34:3111695 {__LINE__,
11696 kProxy,
asankac93076192016-10-03 15:46:0211697 AUTH_NONE,
11698 OK,
11699 kServer,
11700 AUTH_NONE,
11701 OK,
11702 1,
11703 kNoSSL,
11704 {TestRound(kGetProxy, kSuccess, OK)}},
11705 // Authenticating HTTP server through a non-authenticating proxy.
asanka463ca4262016-11-16 02:34:3111706 {__LINE__,
11707 kProxy,
asankac93076192016-10-03 15:46:0211708 AUTH_NONE,
11709 OK,
11710 kServer,
11711 AUTH_SYNC,
11712 OK,
11713 2,
11714 kNoSSL,
11715 {TestRound(kGetProxy, kServerChallenge, OK),
[email protected]044de0642010-06-17 10:42:1511716 TestRound(kGetAuthThroughProxy, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3111717 {__LINE__,
11718 kProxy,
asankac93076192016-10-03 15:46:0211719 AUTH_NONE,
11720 OK,
11721 kServer,
11722 AUTH_SYNC,
11723 ERR_INVALID_AUTH_CREDENTIALS,
asankae2257db2016-10-11 22:03:1611724 3,
asankac93076192016-10-03 15:46:0211725 kNoSSL,
11726 {TestRound(kGetProxy, kServerChallenge, OK),
asankae2257db2016-10-11 22:03:1611727 TestRound(kGetProxy, kServerChallenge, OK),
11728 TestRound(kGetAuthThroughProxy, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3111729 {__LINE__,
11730 kProxy,
asankac93076192016-10-03 15:46:0211731 AUTH_NONE,
11732 OK,
11733 kServer,
11734 AUTH_ASYNC,
11735 OK,
11736 2,
11737 kNoSSL,
11738 {TestRound(kGetProxy, kServerChallenge, OK),
[email protected]044de0642010-06-17 10:42:1511739 TestRound(kGetAuthThroughProxy, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3111740 {__LINE__,
11741 kProxy,
asankac93076192016-10-03 15:46:0211742 AUTH_NONE,
11743 OK,
11744 kServer,
11745 AUTH_ASYNC,
11746 ERR_INVALID_AUTH_CREDENTIALS,
11747 2,
11748 kNoSSL,
11749 {TestRound(kGetProxy, kServerChallenge, OK),
asankae2257db2016-10-11 22:03:1611750 TestRound(kGetProxy, kSuccess, OK)}},
asankac93076192016-10-03 15:46:0211751 // Non-authenticating HTTP server through an authenticating proxy.
asanka463ca4262016-11-16 02:34:3111752 {__LINE__,
11753 kProxy,
asankac93076192016-10-03 15:46:0211754 AUTH_SYNC,
11755 OK,
11756 kServer,
11757 AUTH_NONE,
11758 OK,
11759 2,
11760 kNoSSL,
11761 {TestRound(kGetProxy, kProxyChallenge, OK),
[email protected]044de0642010-06-17 10:42:1511762 TestRound(kGetProxyAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3111763 {__LINE__,
11764 kProxy,
asankac93076192016-10-03 15:46:0211765 AUTH_SYNC,
11766 ERR_INVALID_AUTH_CREDENTIALS,
11767 kServer,
11768 AUTH_NONE,
11769 OK,
11770 2,
11771 kNoSSL,
11772 {TestRound(kGetProxy, kProxyChallenge, OK),
asankae2257db2016-10-11 22:03:1611773 TestRound(kGetProxy, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3111774 {__LINE__,
11775 kProxy,
asankac93076192016-10-03 15:46:0211776 AUTH_ASYNC,
11777 OK,
11778 kServer,
11779 AUTH_NONE,
11780 OK,
11781 2,
11782 kNoSSL,
11783 {TestRound(kGetProxy, kProxyChallenge, OK),
[email protected]044de0642010-06-17 10:42:1511784 TestRound(kGetProxyAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3111785 {__LINE__,
11786 kProxy,
asankac93076192016-10-03 15:46:0211787 AUTH_ASYNC,
11788 ERR_INVALID_AUTH_CREDENTIALS,
11789 kServer,
11790 AUTH_NONE,
11791 OK,
11792 2,
11793 kNoSSL,
11794 {TestRound(kGetProxy, kProxyChallenge, OK),
asankae2257db2016-10-11 22:03:1611795 TestRound(kGetProxy, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3111796 {__LINE__,
11797 kProxy,
11798 AUTH_ASYNC,
11799 ERR_INVALID_AUTH_CREDENTIALS,
11800 kServer,
11801 AUTH_NONE,
11802 OK,
11803 3,
11804 kNoSSL,
11805 {TestRound(kGetProxy, kProxyChallenge, OK),
11806 TestRound(kGetProxy, kProxyChallenge, OK),
11807 TestRound(kGetProxyAuth, kSuccess, OK)}},
asankac93076192016-10-03 15:46:0211808 // Authenticating HTTP server through an authenticating proxy.
asanka463ca4262016-11-16 02:34:3111809 {__LINE__,
11810 kProxy,
asankac93076192016-10-03 15:46:0211811 AUTH_SYNC,
11812 OK,
11813 kServer,
11814 AUTH_SYNC,
11815 OK,
11816 3,
11817 kNoSSL,
11818 {TestRound(kGetProxy, kProxyChallenge, OK),
[email protected]044de0642010-06-17 10:42:1511819 TestRound(kGetProxyAuth, kServerChallenge, OK),
11820 TestRound(kGetAuthWithProxyAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3111821 {__LINE__,
11822 kProxy,
asankac93076192016-10-03 15:46:0211823 AUTH_SYNC,
11824 OK,
11825 kServer,
11826 AUTH_SYNC,
11827 ERR_INVALID_AUTH_CREDENTIALS,
11828 3,
11829 kNoSSL,
11830 {TestRound(kGetProxy, kProxyChallenge, OK),
[email protected]044de0642010-06-17 10:42:1511831 TestRound(kGetProxyAuth, kServerChallenge, OK),
asankae2257db2016-10-11 22:03:1611832 TestRound(kGetProxyAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3111833 {__LINE__,
11834 kProxy,
asankac93076192016-10-03 15:46:0211835 AUTH_ASYNC,
11836 OK,
11837 kServer,
11838 AUTH_SYNC,
11839 OK,
11840 3,
11841 kNoSSL,
11842 {TestRound(kGetProxy, kProxyChallenge, OK),
[email protected]044de0642010-06-17 10:42:1511843 TestRound(kGetProxyAuth, kServerChallenge, OK),
11844 TestRound(kGetAuthWithProxyAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3111845 {__LINE__,
11846 kProxy,
asankac93076192016-10-03 15:46:0211847 AUTH_ASYNC,
11848 OK,
11849 kServer,
11850 AUTH_SYNC,
11851 ERR_INVALID_AUTH_CREDENTIALS,
11852 3,
11853 kNoSSL,
11854 {TestRound(kGetProxy, kProxyChallenge, OK),
[email protected]044de0642010-06-17 10:42:1511855 TestRound(kGetProxyAuth, kServerChallenge, OK),
asankae2257db2016-10-11 22:03:1611856 TestRound(kGetProxyAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3111857 {__LINE__,
11858 kProxy,
asankac93076192016-10-03 15:46:0211859 AUTH_SYNC,
11860 OK,
11861 kServer,
11862 AUTH_ASYNC,
11863 OK,
11864 3,
11865 kNoSSL,
11866 {TestRound(kGetProxy, kProxyChallenge, OK),
[email protected]044de0642010-06-17 10:42:1511867 TestRound(kGetProxyAuth, kServerChallenge, OK),
11868 TestRound(kGetAuthWithProxyAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3111869 {__LINE__,
11870 kProxy,
11871 AUTH_SYNC,
11872 ERR_INVALID_AUTH_CREDENTIALS,
11873 kServer,
11874 AUTH_ASYNC,
11875 OK,
11876 4,
11877 kNoSSL,
11878 {TestRound(kGetProxy, kProxyChallenge, OK),
11879 TestRound(kGetProxy, kProxyChallenge, OK),
11880 TestRound(kGetProxyAuth, kServerChallenge, OK),
11881 TestRound(kGetAuthWithProxyAuth, kSuccess, OK)}},
11882 {__LINE__,
11883 kProxy,
asankac93076192016-10-03 15:46:0211884 AUTH_SYNC,
11885 OK,
11886 kServer,
11887 AUTH_ASYNC,
11888 ERR_INVALID_AUTH_CREDENTIALS,
11889 3,
11890 kNoSSL,
11891 {TestRound(kGetProxy, kProxyChallenge, OK),
[email protected]044de0642010-06-17 10:42:1511892 TestRound(kGetProxyAuth, kServerChallenge, OK),
asankae2257db2016-10-11 22:03:1611893 TestRound(kGetProxyAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3111894 {__LINE__,
11895 kProxy,
asankac93076192016-10-03 15:46:0211896 AUTH_ASYNC,
11897 OK,
11898 kServer,
11899 AUTH_ASYNC,
11900 OK,
11901 3,
11902 kNoSSL,
11903 {TestRound(kGetProxy, kProxyChallenge, OK),
[email protected]044de0642010-06-17 10:42:1511904 TestRound(kGetProxyAuth, kServerChallenge, OK),
11905 TestRound(kGetAuthWithProxyAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3111906 {__LINE__,
11907 kProxy,
asankac93076192016-10-03 15:46:0211908 AUTH_ASYNC,
11909 OK,
11910 kServer,
11911 AUTH_ASYNC,
11912 ERR_INVALID_AUTH_CREDENTIALS,
11913 3,
11914 kNoSSL,
11915 {TestRound(kGetProxy, kProxyChallenge, OK),
[email protected]044de0642010-06-17 10:42:1511916 TestRound(kGetProxyAuth, kServerChallenge, OK),
asankae2257db2016-10-11 22:03:1611917 TestRound(kGetProxyAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3111918 {__LINE__,
11919 kProxy,
11920 AUTH_ASYNC,
11921 ERR_INVALID_AUTH_CREDENTIALS,
11922 kServer,
11923 AUTH_ASYNC,
11924 ERR_INVALID_AUTH_CREDENTIALS,
11925 4,
11926 kNoSSL,
11927 {TestRound(kGetProxy, kProxyChallenge, OK),
11928 TestRound(kGetProxy, kProxyChallenge, OK),
11929 TestRound(kGetProxyAuth, kServerChallenge, OK),
11930 TestRound(kGetProxyAuth, kSuccess, OK)}},
asankac93076192016-10-03 15:46:0211931 // Non-authenticating HTTPS server with a direct connection.
asanka463ca4262016-11-16 02:34:3111932 {__LINE__,
11933 nullptr,
asankac93076192016-10-03 15:46:0211934 AUTH_NONE,
11935 OK,
11936 kSecureServer,
11937 AUTH_NONE,
11938 OK,
11939 1,
11940 0,
11941 {TestRound(kGet, kSuccess, OK)}},
11942 // Authenticating HTTPS server with a direct connection.
asanka463ca4262016-11-16 02:34:3111943 {__LINE__,
11944 nullptr,
asankac93076192016-10-03 15:46:0211945 AUTH_NONE,
11946 OK,
11947 kSecureServer,
11948 AUTH_SYNC,
11949 OK,
11950 2,
11951 0,
11952 {TestRound(kGet, kServerChallenge, OK),
[email protected]044de0642010-06-17 10:42:1511953 TestRound(kGetAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3111954 {__LINE__,
11955 nullptr,
asankac93076192016-10-03 15:46:0211956 AUTH_NONE,
11957 OK,
11958 kSecureServer,
11959 AUTH_SYNC,
11960 ERR_INVALID_AUTH_CREDENTIALS,
11961 2,
11962 0,
asankae2257db2016-10-11 22:03:1611963 {TestRound(kGet, kServerChallenge, OK), TestRound(kGet, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3111964 {__LINE__,
11965 nullptr,
asankac93076192016-10-03 15:46:0211966 AUTH_NONE,
11967 OK,
11968 kSecureServer,
11969 AUTH_ASYNC,
11970 OK,
11971 2,
11972 0,
11973 {TestRound(kGet, kServerChallenge, OK),
[email protected]044de0642010-06-17 10:42:1511974 TestRound(kGetAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3111975 {__LINE__,
11976 nullptr,
asankac93076192016-10-03 15:46:0211977 AUTH_NONE,
11978 OK,
11979 kSecureServer,
11980 AUTH_ASYNC,
11981 ERR_INVALID_AUTH_CREDENTIALS,
11982 2,
11983 0,
asankae2257db2016-10-11 22:03:1611984 {TestRound(kGet, kServerChallenge, OK), TestRound(kGet, kSuccess, OK)}},
asankac93076192016-10-03 15:46:0211985 // Non-authenticating HTTPS server with a non-authenticating proxy.
asanka463ca4262016-11-16 02:34:3111986 {__LINE__,
11987 kProxy,
asankac93076192016-10-03 15:46:0211988 AUTH_NONE,
11989 OK,
11990 kSecureServer,
11991 AUTH_NONE,
11992 OK,
11993 1,
11994 0,
11995 {TestRound(kConnect, kProxyConnected, OK, &kGet, &kSuccess)}},
11996 // Authenticating HTTPS server through a non-authenticating proxy.
asanka463ca4262016-11-16 02:34:3111997 {__LINE__,
11998 kProxy,
asankac93076192016-10-03 15:46:0211999 AUTH_NONE,
12000 OK,
12001 kSecureServer,
12002 AUTH_SYNC,
12003 OK,
12004 2,
12005 0,
12006 {TestRound(kConnect, kProxyConnected, OK, &kGet, &kServerChallenge),
[email protected]044de0642010-06-17 10:42:1512007 TestRound(kGetAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112008 {__LINE__,
12009 kProxy,
asankac93076192016-10-03 15:46:0212010 AUTH_NONE,
12011 OK,
12012 kSecureServer,
12013 AUTH_SYNC,
12014 ERR_INVALID_AUTH_CREDENTIALS,
12015 2,
12016 0,
12017 {TestRound(kConnect, kProxyConnected, OK, &kGet, &kServerChallenge),
asankae2257db2016-10-11 22:03:1612018 TestRound(kGet, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112019 {__LINE__,
12020 kProxy,
asankac93076192016-10-03 15:46:0212021 AUTH_NONE,
12022 OK,
12023 kSecureServer,
12024 AUTH_ASYNC,
12025 OK,
12026 2,
12027 0,
12028 {TestRound(kConnect, kProxyConnected, OK, &kGet, &kServerChallenge),
[email protected]044de0642010-06-17 10:42:1512029 TestRound(kGetAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112030 {__LINE__,
12031 kProxy,
asankac93076192016-10-03 15:46:0212032 AUTH_NONE,
12033 OK,
12034 kSecureServer,
12035 AUTH_ASYNC,
12036 ERR_INVALID_AUTH_CREDENTIALS,
12037 2,
12038 0,
12039 {TestRound(kConnect, kProxyConnected, OK, &kGet, &kServerChallenge),
asankae2257db2016-10-11 22:03:1612040 TestRound(kGet, kSuccess, OK)}},
asankac93076192016-10-03 15:46:0212041 // Non-Authenticating HTTPS server through an authenticating proxy.
asanka463ca4262016-11-16 02:34:3112042 {__LINE__,
12043 kProxy,
asankac93076192016-10-03 15:46:0212044 AUTH_SYNC,
12045 OK,
12046 kSecureServer,
12047 AUTH_NONE,
12048 OK,
12049 2,
12050 1,
12051 {TestRound(kConnect, kProxyChallenge, OK),
[email protected]044de0642010-06-17 10:42:1512052 TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet, &kSuccess)}},
asanka463ca4262016-11-16 02:34:3112053 {__LINE__,
12054 kProxy,
asankac93076192016-10-03 15:46:0212055 AUTH_SYNC,
12056 ERR_INVALID_AUTH_CREDENTIALS,
12057 kSecureServer,
12058 AUTH_NONE,
12059 OK,
12060 2,
12061 kNoSSL,
12062 {TestRound(kConnect, kProxyChallenge, OK),
asankae2257db2016-10-11 22:03:1612063 TestRound(kConnect, kProxyConnected, OK, &kGet, &kSuccess)}},
asanka463ca4262016-11-16 02:34:3112064 {__LINE__,
12065 kProxy,
asankae2257db2016-10-11 22:03:1612066 AUTH_SYNC,
12067 ERR_UNSUPPORTED_AUTH_SCHEME,
12068 kSecureServer,
12069 AUTH_NONE,
12070 OK,
12071 2,
12072 kNoSSL,
12073 {TestRound(kConnect, kProxyChallenge, OK),
12074 TestRound(kConnect, kProxyConnected, OK, &kGet, &kSuccess)}},
asanka463ca4262016-11-16 02:34:3112075 {__LINE__,
12076 kProxy,
asankae2257db2016-10-11 22:03:1612077 AUTH_SYNC,
12078 ERR_UNEXPECTED,
12079 kSecureServer,
12080 AUTH_NONE,
12081 OK,
12082 2,
12083 kNoSSL,
12084 {TestRound(kConnect, kProxyChallenge, OK),
12085 TestRound(kConnect, kProxyConnected, ERR_UNEXPECTED)}},
asanka463ca4262016-11-16 02:34:3112086 {__LINE__,
12087 kProxy,
asankac93076192016-10-03 15:46:0212088 AUTH_ASYNC,
12089 OK,
12090 kSecureServer,
12091 AUTH_NONE,
12092 OK,
12093 2,
12094 1,
12095 {TestRound(kConnect, kProxyChallenge, OK),
[email protected]044de0642010-06-17 10:42:1512096 TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet, &kSuccess)}},
asanka463ca4262016-11-16 02:34:3112097 {__LINE__,
12098 kProxy,
asankac93076192016-10-03 15:46:0212099 AUTH_ASYNC,
12100 ERR_INVALID_AUTH_CREDENTIALS,
12101 kSecureServer,
12102 AUTH_NONE,
12103 OK,
12104 2,
12105 kNoSSL,
12106 {TestRound(kConnect, kProxyChallenge, OK),
asankae2257db2016-10-11 22:03:1612107 TestRound(kConnect, kProxyConnected, OK, &kGet, &kSuccess)}},
asankac93076192016-10-03 15:46:0212108 // Authenticating HTTPS server through an authenticating proxy.
asanka463ca4262016-11-16 02:34:3112109 {__LINE__,
12110 kProxy,
asankac93076192016-10-03 15:46:0212111 AUTH_SYNC,
12112 OK,
12113 kSecureServer,
12114 AUTH_SYNC,
12115 OK,
12116 3,
12117 1,
12118 {TestRound(kConnect, kProxyChallenge, OK),
12119 TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet,
12120 &kServerChallenge),
[email protected]044de0642010-06-17 10:42:1512121 TestRound(kGetAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112122 {__LINE__,
12123 kProxy,
asankac93076192016-10-03 15:46:0212124 AUTH_SYNC,
12125 OK,
12126 kSecureServer,
12127 AUTH_SYNC,
12128 ERR_INVALID_AUTH_CREDENTIALS,
12129 3,
12130 1,
12131 {TestRound(kConnect, kProxyChallenge, OK),
12132 TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet,
12133 &kServerChallenge),
asankae2257db2016-10-11 22:03:1612134 TestRound(kGet, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112135 {__LINE__,
12136 kProxy,
asankac93076192016-10-03 15:46:0212137 AUTH_ASYNC,
12138 OK,
12139 kSecureServer,
12140 AUTH_SYNC,
12141 OK,
12142 3,
12143 1,
12144 {TestRound(kConnect, kProxyChallenge, OK),
12145 TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet,
12146 &kServerChallenge),
[email protected]044de0642010-06-17 10:42:1512147 TestRound(kGetAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112148 {__LINE__,
12149 kProxy,
asankac93076192016-10-03 15:46:0212150 AUTH_ASYNC,
12151 OK,
12152 kSecureServer,
12153 AUTH_SYNC,
12154 ERR_INVALID_AUTH_CREDENTIALS,
12155 3,
12156 1,
12157 {TestRound(kConnect, kProxyChallenge, OK),
12158 TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet,
12159 &kServerChallenge),
asankae2257db2016-10-11 22:03:1612160 TestRound(kGet, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112161 {__LINE__,
12162 kProxy,
asankac93076192016-10-03 15:46:0212163 AUTH_SYNC,
12164 OK,
12165 kSecureServer,
12166 AUTH_ASYNC,
12167 OK,
12168 3,
12169 1,
12170 {TestRound(kConnect, kProxyChallenge, OK),
12171 TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet,
12172 &kServerChallenge),
[email protected]044de0642010-06-17 10:42:1512173 TestRound(kGetAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112174 {__LINE__,
12175 kProxy,
asankac93076192016-10-03 15:46:0212176 AUTH_SYNC,
12177 OK,
12178 kSecureServer,
12179 AUTH_ASYNC,
12180 ERR_INVALID_AUTH_CREDENTIALS,
12181 3,
12182 1,
12183 {TestRound(kConnect, kProxyChallenge, OK),
12184 TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet,
12185 &kServerChallenge),
asankae2257db2016-10-11 22:03:1612186 TestRound(kGet, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112187 {__LINE__,
12188 kProxy,
asankac93076192016-10-03 15:46:0212189 AUTH_ASYNC,
12190 OK,
12191 kSecureServer,
12192 AUTH_ASYNC,
12193 OK,
12194 3,
12195 1,
12196 {TestRound(kConnect, kProxyChallenge, OK),
12197 TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet,
12198 &kServerChallenge),
[email protected]044de0642010-06-17 10:42:1512199 TestRound(kGetAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112200 {__LINE__,
12201 kProxy,
asankac93076192016-10-03 15:46:0212202 AUTH_ASYNC,
12203 OK,
12204 kSecureServer,
12205 AUTH_ASYNC,
12206 ERR_INVALID_AUTH_CREDENTIALS,
12207 3,
12208 1,
12209 {TestRound(kConnect, kProxyChallenge, OK),
12210 TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet,
12211 &kServerChallenge),
asankae2257db2016-10-11 22:03:1612212 TestRound(kGet, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112213 {__LINE__,
12214 kProxy,
12215 AUTH_ASYNC,
12216 ERR_INVALID_AUTH_CREDENTIALS,
12217 kSecureServer,
12218 AUTH_ASYNC,
12219 ERR_INVALID_AUTH_CREDENTIALS,
12220 4,
12221 2,
12222 {TestRound(kConnect, kProxyChallenge, OK),
12223 TestRound(kConnect, kProxyChallenge, OK),
12224 TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet,
12225 &kServerChallenge),
12226 TestRound(kGet, kSuccess, OK)}},
[email protected]044de0642010-06-17 10:42:1512227 };
12228
asanka463ca4262016-11-16 02:34:3112229 for (const auto& test_config : test_configs) {
12230 SCOPED_TRACE(::testing::Message() << "Test config at "
12231 << test_config.line_number);
[email protected]2d01c262011-08-11 23:07:0812232 HttpAuthHandlerMock::Factory* auth_factory(
12233 new HttpAuthHandlerMock::Factory());
[email protected]bb88e1d32013-05-03 23:11:0712234 session_deps_.http_auth_handler_factory.reset(auth_factory);
asanka5ffd5d72016-03-23 16:20:4912235 SSLInfo empty_ssl_info;
[email protected]65d34382010-07-01 18:12:2612236
12237 // Set up authentication handlers as necessary.
[email protected]044de0642010-06-17 10:42:1512238 if (test_config.proxy_auth_timing != AUTH_NONE) {
asanka463ca4262016-11-16 02:34:3112239 for (int n = 0; n < 3; n++) {
[email protected]2d01c262011-08-11 23:07:0812240 HttpAuthHandlerMock* auth_handler(new HttpAuthHandlerMock());
12241 std::string auth_challenge = "Mock realm=proxy";
12242 GURL origin(test_config.proxy_url);
[email protected]df41d0d82014-03-13 00:43:2412243 HttpAuthChallengeTokenizer tokenizer(auth_challenge.begin(),
12244 auth_challenge.end());
[email protected]2d01c262011-08-11 23:07:0812245 auth_handler->InitFromChallenge(&tokenizer, HttpAuth::AUTH_PROXY,
tfarina42834112016-09-22 13:38:2012246 empty_ssl_info, origin,
12247 NetLogWithSource());
[email protected]2d01c262011-08-11 23:07:0812248 auth_handler->SetGenerateExpectation(
12249 test_config.proxy_auth_timing == AUTH_ASYNC,
asanka463ca4262016-11-16 02:34:3112250 n == 0 ? test_config.first_generate_proxy_token_rv : OK);
[email protected]2d01c262011-08-11 23:07:0812251 auth_factory->AddMockHandler(auth_handler, HttpAuth::AUTH_PROXY);
12252 }
[email protected]044de0642010-06-17 10:42:1512253 }
12254 if (test_config.server_auth_timing != AUTH_NONE) {
[email protected]3fd9dae2010-06-21 11:39:0012255 HttpAuthHandlerMock* auth_handler(new HttpAuthHandlerMock());
[email protected]044de0642010-06-17 10:42:1512256 std::string auth_challenge = "Mock realm=server";
12257 GURL origin(test_config.server_url);
[email protected]df41d0d82014-03-13 00:43:2412258 HttpAuthChallengeTokenizer tokenizer(auth_challenge.begin(),
12259 auth_challenge.end());
[email protected]044de0642010-06-17 10:42:1512260 auth_handler->InitFromChallenge(&tokenizer, HttpAuth::AUTH_SERVER,
tfarina42834112016-09-22 13:38:2012261 empty_ssl_info, origin,
12262 NetLogWithSource());
[email protected]044de0642010-06-17 10:42:1512263 auth_handler->SetGenerateExpectation(
12264 test_config.server_auth_timing == AUTH_ASYNC,
asanka463ca4262016-11-16 02:34:3112265 test_config.first_generate_server_token_rv);
[email protected]2d01c262011-08-11 23:07:0812266 auth_factory->AddMockHandler(auth_handler, HttpAuth::AUTH_SERVER);
asankae2257db2016-10-11 22:03:1612267
12268 // The second handler always succeeds. It should only be used where there
12269 // are multiple auth sessions for server auth in the same network
12270 // transaction using the same auth scheme.
12271 std::unique_ptr<HttpAuthHandlerMock> second_handler =
12272 base::MakeUnique<HttpAuthHandlerMock>();
12273 second_handler->InitFromChallenge(&tokenizer, HttpAuth::AUTH_SERVER,
12274 empty_ssl_info, origin,
12275 NetLogWithSource());
12276 second_handler->SetGenerateExpectation(true, OK);
12277 auth_factory->AddMockHandler(second_handler.release(),
12278 HttpAuth::AUTH_SERVER);
[email protected]044de0642010-06-17 10:42:1512279 }
12280 if (test_config.proxy_url) {
rdsmith82957ad2015-09-16 19:42:0312281 session_deps_.proxy_service =
12282 ProxyService::CreateFixed(test_config.proxy_url);
[email protected]044de0642010-06-17 10:42:1512283 } else {
rdsmith82957ad2015-09-16 19:42:0312284 session_deps_.proxy_service = ProxyService::CreateDirect();
[email protected]044de0642010-06-17 10:42:1512285 }
12286
12287 HttpRequestInfo request;
12288 request.method = "GET";
12289 request.url = GURL(test_config.server_url);
[email protected]044de0642010-06-17 10:42:1512290
danakj1fd259a02016-04-16 03:17:0912291 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]044de0642010-06-17 10:42:1512292
rchcb68dc62015-05-21 04:45:3612293 SSLSocketDataProvider ssl_socket_data_provider(SYNCHRONOUS, OK);
12294
12295 std::vector<std::vector<MockRead>> mock_reads(1);
12296 std::vector<std::vector<MockWrite>> mock_writes(1);
[email protected]044de0642010-06-17 10:42:1512297 for (int round = 0; round < test_config.num_auth_rounds; ++round) {
12298 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) {
12338 const TestRound& read_write_round = test_config.rounds[round];
[email protected]044de0642010-06-17 10:42:1512339 // Start or restart the transaction.
[email protected]49639fa2011-12-20 23:22:4112340 TestCompletionCallback callback;
[email protected]044de0642010-06-17 10:42:1512341 int rv;
12342 if (round == 0) {
tfarina42834112016-09-22 13:38:2012343 rv = trans.Start(&request, callback.callback(), NetLogWithSource());
[email protected]044de0642010-06-17 10:42:1512344 } else {
[email protected]49639fa2011-12-20 23:22:4112345 rv = trans.RestartWithAuth(
12346 AuthCredentials(kFoo, kBar), callback.callback());
[email protected]044de0642010-06-17 10:42:1512347 }
12348 if (rv == ERR_IO_PENDING)
12349 rv = callback.WaitForResult();
12350
12351 // Compare results with expected data.
asankae2257db2016-10-11 22:03:1612352 EXPECT_THAT(rv, IsError(read_write_round.expected_rv));
[email protected]0b0bf032010-09-21 18:08:5012353 const HttpResponseInfo* response = trans.GetResponseInfo();
ttuttlec0c828492015-05-15 01:25:5512354 if (read_write_round.expected_rv != OK) {
[email protected]044de0642010-06-17 10:42:1512355 EXPECT_EQ(round + 1, test_config.num_auth_rounds);
12356 continue;
12357 }
12358 if (round + 1 < test_config.num_auth_rounds) {
wezca1070932016-05-26 20:30:5212359 EXPECT_TRUE(response->auth_challenge);
[email protected]044de0642010-06-17 10:42:1512360 } else {
wezca1070932016-05-26 20:30:5212361 EXPECT_FALSE(response->auth_challenge);
asankae2257db2016-10-11 22:03:1612362 EXPECT_FALSE(trans.IsReadyToRestartForAuth());
[email protected]044de0642010-06-17 10:42:1512363 }
12364 }
[email protected]e5ae96a2010-04-14 20:12:4512365 }
12366}
12367
bncd16676a2016-07-20 16:23:0112368TEST_F(HttpNetworkTransactionTest, MultiRoundAuth) {
[email protected]c871bce92010-07-15 21:51:1412369 // Do multi-round authentication and make sure it works correctly.
[email protected]c871bce92010-07-15 21:51:1412370 HttpAuthHandlerMock::Factory* auth_factory(
12371 new HttpAuthHandlerMock::Factory());
[email protected]bb88e1d32013-05-03 23:11:0712372 session_deps_.http_auth_handler_factory.reset(auth_factory);
rdsmith82957ad2015-09-16 19:42:0312373 session_deps_.proxy_service = ProxyService::CreateDirect();
[email protected]bb88e1d32013-05-03 23:11:0712374 session_deps_.host_resolver->rules()->AddRule("www.example.com", "10.0.0.1");
12375 session_deps_.host_resolver->set_synchronous_mode(true);
[email protected]c871bce92010-07-15 21:51:1412376
12377 HttpAuthHandlerMock* auth_handler(new HttpAuthHandlerMock());
12378 auth_handler->set_connection_based(true);
12379 std::string auth_challenge = "Mock realm=server";
12380 GURL origin("http://www.example.com");
[email protected]df41d0d82014-03-13 00:43:2412381 HttpAuthChallengeTokenizer tokenizer(auth_challenge.begin(),
12382 auth_challenge.end());
asanka5ffd5d72016-03-23 16:20:4912383 SSLInfo empty_ssl_info;
[email protected]c871bce92010-07-15 21:51:1412384 auth_handler->InitFromChallenge(&tokenizer, HttpAuth::AUTH_SERVER,
tfarina42834112016-09-22 13:38:2012385 empty_ssl_info, origin, NetLogWithSource());
[email protected]2d01c262011-08-11 23:07:0812386 auth_factory->AddMockHandler(auth_handler, HttpAuth::AUTH_SERVER);
[email protected]c871bce92010-07-15 21:51:1412387
[email protected]c871bce92010-07-15 21:51:1412388 int rv = OK;
12389 const HttpResponseInfo* response = NULL;
12390 HttpRequestInfo request;
12391 request.method = "GET";
12392 request.url = origin;
[email protected]cb9bf6ca2011-01-28 13:15:2712393
danakj1fd259a02016-04-16 03:17:0912394 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]7ef4cbbb2011-02-06 11:19:1012395
12396 // Use a TCP Socket Pool with only one connection per group. This is used
12397 // to validate that the TCP socket is not released to the pool between
12398 // each round of multi-round authentication.
mmenkee65e7af2015-10-13 17:16:4212399 HttpNetworkSessionPeer session_peer(session.get());
[email protected]ab739042011-04-07 15:22:2812400 TransportClientSocketPool* transport_pool = new TransportClientSocketPool(
[email protected]7ef4cbbb2011-02-06 11:19:1012401 50, // Max sockets for pool
12402 1, // Max sockets per group
tbansal7b403bcc2016-04-13 22:33:2112403 session_deps_.host_resolver.get(), session_deps_.socket_factory.get(),
12404 NULL, session_deps_.net_log);
danakj1fd259a02016-04-16 03:17:0912405 std::unique_ptr<MockClientSocketPoolManager> mock_pool_manager(
[email protected]831e4a32013-11-14 02:14:4412406 new MockClientSocketPoolManager);
[email protected]a42dbd142011-11-17 16:42:0212407 mock_pool_manager->SetTransportSocketPool(transport_pool);
dchengc7eeda422015-12-26 03:56:4812408 session_peer.SetClientSocketPoolManager(std::move(mock_pool_manager));
[email protected]7ef4cbbb2011-02-06 11:19:1012409
bnc691fda62016-08-12 00:43:1612410 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]49639fa2011-12-20 23:22:4112411 TestCompletionCallback callback;
[email protected]c871bce92010-07-15 21:51:1412412
12413 const MockWrite kGet(
12414 "GET / HTTP/1.1\r\n"
12415 "Host: www.example.com\r\n"
12416 "Connection: keep-alive\r\n\r\n");
12417 const MockWrite kGetAuth(
12418 "GET / HTTP/1.1\r\n"
12419 "Host: www.example.com\r\n"
12420 "Connection: keep-alive\r\n"
12421 "Authorization: auth_token\r\n\r\n");
12422
12423 const MockRead kServerChallenge(
12424 "HTTP/1.1 401 Unauthorized\r\n"
12425 "WWW-Authenticate: Mock realm=server\r\n"
12426 "Content-Type: text/html; charset=iso-8859-1\r\n"
12427 "Content-Length: 14\r\n\r\n"
12428 "Unauthorized\r\n");
12429 const MockRead kSuccess(
12430 "HTTP/1.1 200 OK\r\n"
12431 "Content-Type: text/html; charset=iso-8859-1\r\n"
12432 "Content-Length: 3\r\n\r\n"
12433 "Yes");
12434
12435 MockWrite writes[] = {
12436 // First round
12437 kGet,
12438 // Second round
12439 kGetAuth,
12440 // Third round
12441 kGetAuth,
[email protected]eca50e122010-09-11 14:03:3012442 // Fourth round
[email protected]7ef4cbbb2011-02-06 11:19:1012443 kGetAuth,
12444 // Competing request
12445 kGet,
[email protected]c871bce92010-07-15 21:51:1412446 };
12447 MockRead reads[] = {
12448 // First round
12449 kServerChallenge,
12450 // Second round
12451 kServerChallenge,
12452 // Third round
[email protected]eca50e122010-09-11 14:03:3012453 kServerChallenge,
12454 // Fourth round
[email protected]c871bce92010-07-15 21:51:1412455 kSuccess,
[email protected]7ef4cbbb2011-02-06 11:19:1012456 // Competing response
12457 kSuccess,
[email protected]c871bce92010-07-15 21:51:1412458 };
12459 StaticSocketDataProvider data_provider(reads, arraysize(reads),
12460 writes, arraysize(writes));
[email protected]bb88e1d32013-05-03 23:11:0712461 session_deps_.socket_factory->AddSocketDataProvider(&data_provider);
[email protected]c871bce92010-07-15 21:51:1412462
thestig9d3bb0c2015-01-24 00:49:5112463 const char kSocketGroup[] = "www.example.com:80";
[email protected]7ef4cbbb2011-02-06 11:19:1012464
12465 // First round of authentication.
[email protected]c871bce92010-07-15 21:51:1412466 auth_handler->SetGenerateExpectation(false, OK);
tfarina42834112016-09-22 13:38:2012467 rv = trans.Start(&request, callback.callback(), NetLogWithSource());
[email protected]c871bce92010-07-15 21:51:1412468 if (rv == ERR_IO_PENDING)
12469 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0112470 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:1612471 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5212472 ASSERT_TRUE(response);
12473 EXPECT_TRUE(response->auth_challenge);
[email protected]ab739042011-04-07 15:22:2812474 EXPECT_EQ(0, transport_pool->IdleSocketCountInGroup(kSocketGroup));
asanka463ca4262016-11-16 02:34:3112475 EXPECT_EQ(HttpAuthHandlerMock::State::WAIT_FOR_GENERATE_AUTH_TOKEN,
12476 auth_handler->state());
[email protected]c871bce92010-07-15 21:51:1412477
[email protected]7ef4cbbb2011-02-06 11:19:1012478 // In between rounds, another request comes in for the same domain.
12479 // It should not be able to grab the TCP socket that trans has already
12480 // claimed.
bnc691fda62016-08-12 00:43:1612481 HttpNetworkTransaction trans_compete(DEFAULT_PRIORITY, session.get());
[email protected]49639fa2011-12-20 23:22:4112482 TestCompletionCallback callback_compete;
tfarina42834112016-09-22 13:38:2012483 rv = trans_compete.Start(&request, callback_compete.callback(),
12484 NetLogWithSource());
robpercival214763f2016-07-01 23:27:0112485 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]7ef4cbbb2011-02-06 11:19:1012486 // callback_compete.WaitForResult at this point would stall forever,
12487 // since the HttpNetworkTransaction does not release the request back to
12488 // the pool until after authentication completes.
12489
12490 // Second round of authentication.
[email protected]c871bce92010-07-15 21:51:1412491 auth_handler->SetGenerateExpectation(false, OK);
bnc691fda62016-08-12 00:43:1612492 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar), callback.callback());
[email protected]c871bce92010-07-15 21:51:1412493 if (rv == ERR_IO_PENDING)
12494 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0112495 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:1612496 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5212497 ASSERT_TRUE(response);
12498 EXPECT_FALSE(response->auth_challenge);
[email protected]ab739042011-04-07 15:22:2812499 EXPECT_EQ(0, transport_pool->IdleSocketCountInGroup(kSocketGroup));
asanka463ca4262016-11-16 02:34:3112500 EXPECT_EQ(HttpAuthHandlerMock::State::WAIT_FOR_GENERATE_AUTH_TOKEN,
12501 auth_handler->state());
[email protected]c871bce92010-07-15 21:51:1412502
[email protected]7ef4cbbb2011-02-06 11:19:1012503 // Third round of authentication.
[email protected]c871bce92010-07-15 21:51:1412504 auth_handler->SetGenerateExpectation(false, OK);
bnc691fda62016-08-12 00:43:1612505 rv = trans.RestartWithAuth(AuthCredentials(), callback.callback());
[email protected]c871bce92010-07-15 21:51:1412506 if (rv == ERR_IO_PENDING)
12507 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0112508 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:1612509 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5212510 ASSERT_TRUE(response);
12511 EXPECT_FALSE(response->auth_challenge);
[email protected]ab739042011-04-07 15:22:2812512 EXPECT_EQ(0, transport_pool->IdleSocketCountInGroup(kSocketGroup));
asanka463ca4262016-11-16 02:34:3112513 EXPECT_EQ(HttpAuthHandlerMock::State::WAIT_FOR_GENERATE_AUTH_TOKEN,
12514 auth_handler->state());
[email protected]eca50e122010-09-11 14:03:3012515
[email protected]7ef4cbbb2011-02-06 11:19:1012516 // Fourth round of authentication, which completes successfully.
[email protected]eca50e122010-09-11 14:03:3012517 auth_handler->SetGenerateExpectation(false, OK);
bnc691fda62016-08-12 00:43:1612518 rv = trans.RestartWithAuth(AuthCredentials(), callback.callback());
[email protected]eca50e122010-09-11 14:03:3012519 if (rv == ERR_IO_PENDING)
12520 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0112521 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:1612522 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5212523 ASSERT_TRUE(response);
12524 EXPECT_FALSE(response->auth_challenge);
[email protected]ab739042011-04-07 15:22:2812525 EXPECT_EQ(0, transport_pool->IdleSocketCountInGroup(kSocketGroup));
[email protected]7ef4cbbb2011-02-06 11:19:1012526
asanka463ca4262016-11-16 02:34:3112527 // In WAIT_FOR_CHALLENGE, although in reality the auth handler is done. A real
12528 // auth handler should transition to a DONE state in concert with the remote
12529 // server. But that's not something we can test here with a mock handler.
12530 EXPECT_EQ(HttpAuthHandlerMock::State::WAIT_FOR_CHALLENGE,
12531 auth_handler->state());
12532
[email protected]7ef4cbbb2011-02-06 11:19:1012533 // Read the body since the fourth round was successful. This will also
12534 // release the socket back to the pool.
12535 scoped_refptr<IOBufferWithSize> io_buf(new IOBufferWithSize(50));
bnc691fda62016-08-12 00:43:1612536 rv = trans.Read(io_buf.get(), io_buf->size(), callback.callback());
[email protected]7ef4cbbb2011-02-06 11:19:1012537 if (rv == ERR_IO_PENDING)
12538 rv = callback.WaitForResult();
12539 EXPECT_EQ(3, rv);
bnc691fda62016-08-12 00:43:1612540 rv = trans.Read(io_buf.get(), io_buf->size(), callback.callback());
[email protected]7ef4cbbb2011-02-06 11:19:1012541 EXPECT_EQ(0, rv);
12542 // There are still 0 idle sockets, since the trans_compete transaction
12543 // will be handed it immediately after trans releases it to the group.
[email protected]ab739042011-04-07 15:22:2812544 EXPECT_EQ(0, transport_pool->IdleSocketCountInGroup(kSocketGroup));
[email protected]7ef4cbbb2011-02-06 11:19:1012545
12546 // The competing request can now finish. Wait for the headers and then
12547 // read the body.
12548 rv = callback_compete.WaitForResult();
robpercival214763f2016-07-01 23:27:0112549 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:1612550 rv = trans_compete.Read(io_buf.get(), io_buf->size(), callback.callback());
[email protected]7ef4cbbb2011-02-06 11:19:1012551 if (rv == ERR_IO_PENDING)
12552 rv = callback.WaitForResult();
12553 EXPECT_EQ(3, rv);
bnc691fda62016-08-12 00:43:1612554 rv = trans_compete.Read(io_buf.get(), io_buf->size(), callback.callback());
[email protected]7ef4cbbb2011-02-06 11:19:1012555 EXPECT_EQ(0, rv);
12556
12557 // Finally, the socket is released to the group.
[email protected]ab739042011-04-07 15:22:2812558 EXPECT_EQ(1, transport_pool->IdleSocketCountInGroup(kSocketGroup));
[email protected]c871bce92010-07-15 21:51:1412559}
12560
[email protected]65041fa2010-05-21 06:56:5312561// This tests the case that a request is issued via http instead of spdy after
12562// npn is negotiated.
bncd16676a2016-07-20 16:23:0112563TEST_F(HttpNetworkTransactionTest, NpnWithHttpOverSSL) {
[email protected]65041fa2010-05-21 06:56:5312564 HttpRequestInfo request;
12565 request.method = "GET";
bncce36dca22015-04-21 22:11:2312566 request.url = GURL("https://www.example.org/");
[email protected]65041fa2010-05-21 06:56:5312567
12568 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:2312569 MockWrite(
12570 "GET / HTTP/1.1\r\n"
12571 "Host: www.example.org\r\n"
12572 "Connection: keep-alive\r\n\r\n"),
[email protected]65041fa2010-05-21 06:56:5312573 };
12574
12575 MockRead data_reads[] = {
bncc958faa2015-07-31 18:14:5212576 MockRead("HTTP/1.1 200 OK\r\n"),
bnc2df4b522016-07-08 18:17:4312577 MockRead(kAlternativeServiceHttpHeader),
bncc958faa2015-07-31 18:14:5212578 MockRead("\r\n"),
12579 MockRead("hello world"),
12580 MockRead(SYNCHRONOUS, OK),
[email protected]65041fa2010-05-21 06:56:5312581 };
12582
[email protected]8ddf8322012-02-23 18:08:0612583 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3612584 ssl.next_proto = kProtoHTTP11;
[email protected]65041fa2010-05-21 06:56:5312585
[email protected]bb88e1d32013-05-03 23:11:0712586 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]65041fa2010-05-21 06:56:5312587
12588 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
12589 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:0712590 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]65041fa2010-05-21 06:56:5312591
[email protected]49639fa2011-12-20 23:22:4112592 TestCompletionCallback callback;
[email protected]65041fa2010-05-21 06:56:5312593
danakj1fd259a02016-04-16 03:17:0912594 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1612595 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]65041fa2010-05-21 06:56:5312596
tfarina42834112016-09-22 13:38:2012597 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
[email protected]65041fa2010-05-21 06:56:5312598
robpercival214763f2016-07-01 23:27:0112599 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
12600 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]65041fa2010-05-21 06:56:5312601
bnc691fda62016-08-12 00:43:1612602 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5212603 ASSERT_TRUE(response);
12604 ASSERT_TRUE(response->headers);
[email protected]65041fa2010-05-21 06:56:5312605 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
12606
12607 std::string response_data;
bnc691fda62016-08-12 00:43:1612608 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
[email protected]65041fa2010-05-21 06:56:5312609 EXPECT_EQ("hello world", response_data);
12610
12611 EXPECT_FALSE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5212612 EXPECT_TRUE(response->was_alpn_negotiated);
[email protected]65041fa2010-05-21 06:56:5312613}
[email protected]26ef6582010-06-24 02:30:4712614
bnc55ff9da2015-08-19 18:42:3512615// Simulate the SSL handshake completing with an NPN negotiation followed by an
12616// immediate server closing of the socket.
12617// Regression test for https://crbug.com/46369.
bncd16676a2016-07-20 16:23:0112618TEST_F(HttpNetworkTransactionTest, SpdyPostNPNServerHangup) {
[email protected]26ef6582010-06-24 02:30:4712619 HttpRequestInfo request;
12620 request.method = "GET";
bncce36dca22015-04-21 22:11:2312621 request.url = GURL("https://www.example.org/");
[email protected]26ef6582010-06-24 02:30:4712622
[email protected]8ddf8322012-02-23 18:08:0612623 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3612624 ssl.next_proto = kProtoHTTP2;
[email protected]bb88e1d32013-05-03 23:11:0712625 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]26ef6582010-06-24 02:30:4712626
bncdf80d44fd2016-07-15 20:27:4112627 SpdySerializedFrame req(
bnc38dcd392016-02-09 23:19:4912628 spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST, true));
bncdf80d44fd2016-07-15 20:27:4112629 MockWrite spdy_writes[] = {CreateMockWrite(req, 1)};
[email protected]26ef6582010-06-24 02:30:4712630
12631 MockRead spdy_reads[] = {
[email protected]8ddf8322012-02-23 18:08:0612632 MockRead(SYNCHRONOUS, 0, 0) // Not async - return 0 immediately.
[email protected]26ef6582010-06-24 02:30:4712633 };
12634
rch8e6c6c42015-05-01 14:05:1312635 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
12636 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:0712637 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]26ef6582010-06-24 02:30:4712638
[email protected]49639fa2011-12-20 23:22:4112639 TestCompletionCallback callback;
[email protected]26ef6582010-06-24 02:30:4712640
danakj1fd259a02016-04-16 03:17:0912641 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1612642 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]26ef6582010-06-24 02:30:4712643
tfarina42834112016-09-22 13:38:2012644 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0112645 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
12646 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_CONNECTION_CLOSED));
[email protected]26ef6582010-06-24 02:30:4712647}
[email protected]65d34382010-07-01 18:12:2612648
[email protected]795cbf82013-07-22 09:37:2712649// A subclass of HttpAuthHandlerMock that records the request URL when
12650// it gets it. This is needed since the auth handler may get destroyed
12651// before we get a chance to query it.
12652class UrlRecordingHttpAuthHandlerMock : public HttpAuthHandlerMock {
12653 public:
12654 explicit UrlRecordingHttpAuthHandlerMock(GURL* url) : url_(url) {}
12655
dchengb03027d2014-10-21 12:00:2012656 ~UrlRecordingHttpAuthHandlerMock() override {}
[email protected]795cbf82013-07-22 09:37:2712657
12658 protected:
dchengb03027d2014-10-21 12:00:2012659 int GenerateAuthTokenImpl(const AuthCredentials* credentials,
12660 const HttpRequestInfo* request,
12661 const CompletionCallback& callback,
12662 std::string* auth_token) override {
[email protected]795cbf82013-07-22 09:37:2712663 *url_ = request->url;
12664 return HttpAuthHandlerMock::GenerateAuthTokenImpl(
12665 credentials, request, callback, auth_token);
12666 }
12667
12668 private:
12669 GURL* url_;
12670};
12671
[email protected]8e6441ca2010-08-19 05:56:3812672// Test that if we cancel the transaction as the connection is completing, that
12673// everything tears down correctly.
bncd16676a2016-07-20 16:23:0112674TEST_F(HttpNetworkTransactionTest, SimpleCancel) {
[email protected]8e6441ca2010-08-19 05:56:3812675 // Setup everything about the connection to complete synchronously, so that
12676 // after calling HttpNetworkTransaction::Start, the only thing we're waiting
12677 // for is the callback from the HttpStreamRequest.
12678 // Then cancel the transaction.
12679 // Verify that we don't crash.
[email protected]d973e99a2012-02-17 21:02:3612680 MockConnect mock_connect(SYNCHRONOUS, OK);
[email protected]8e6441ca2010-08-19 05:56:3812681 MockRead data_reads[] = {
[email protected]8ddf8322012-02-23 18:08:0612682 MockRead(SYNCHRONOUS, "HTTP/1.0 200 OK\r\n\r\n"),
12683 MockRead(SYNCHRONOUS, "hello world"),
12684 MockRead(SYNCHRONOUS, OK),
[email protected]8e6441ca2010-08-19 05:56:3812685 };
12686
[email protected]8e6441ca2010-08-19 05:56:3812687 HttpRequestInfo request;
12688 request.method = "GET";
bncce36dca22015-04-21 22:11:2312689 request.url = GURL("http://www.example.org/");
[email protected]8e6441ca2010-08-19 05:56:3812690
[email protected]bb88e1d32013-05-03 23:11:0712691 session_deps_.host_resolver->set_synchronous_mode(true);
danakj1fd259a02016-04-16 03:17:0912692 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1612693 std::unique_ptr<HttpNetworkTransaction> trans(
dcheng48459ac22014-08-26 00:46:4112694 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:2712695
[email protected]8e6441ca2010-08-19 05:56:3812696 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
12697 data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:0712698 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]8e6441ca2010-08-19 05:56:3812699
[email protected]49639fa2011-12-20 23:22:4112700 TestCompletionCallback callback;
[email protected]8e6441ca2010-08-19 05:56:3812701
vishal.b62985ca92015-04-17 08:45:5112702 BoundTestNetLog log;
[email protected]49639fa2011-12-20 23:22:4112703 int rv = trans->Start(&request, callback.callback(), log.bound());
robpercival214763f2016-07-01 23:27:0112704 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]8e6441ca2010-08-19 05:56:3812705 trans.reset(); // Cancel the transaction here.
12706
fdoray92e35a72016-06-10 15:54:5512707 base::RunLoop().RunUntilIdle();
[email protected]f45c1ee2010-08-03 00:54:3012708}
12709
[email protected]ecab6e052014-05-16 14:58:1212710// Test that if a transaction is cancelled after receiving the headers, the
12711// stream is drained properly and added back to the socket pool. The main
12712// purpose of this test is to make sure that an HttpStreamParser can be read
12713// from after the HttpNetworkTransaction and the objects it owns have been
12714// deleted.
12715// See http://crbug.com/368418
bncd16676a2016-07-20 16:23:0112716TEST_F(HttpNetworkTransactionTest, CancelAfterHeaders) {
[email protected]ecab6e052014-05-16 14:58:1212717 MockRead data_reads[] = {
12718 MockRead(ASYNC, "HTTP/1.1 200 OK\r\n"),
12719 MockRead(ASYNC, "Content-Length: 2\r\n"),
12720 MockRead(ASYNC, "Connection: Keep-Alive\r\n\r\n"),
12721 MockRead(ASYNC, "1"),
12722 // 2 async reads are necessary to trigger a ReadResponseBody call after the
12723 // HttpNetworkTransaction has been deleted.
12724 MockRead(ASYNC, "2"),
12725 MockRead(SYNCHRONOUS, ERR_IO_PENDING), // Should never read this.
12726 };
12727 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
12728 session_deps_.socket_factory->AddSocketDataProvider(&data);
12729
danakj1fd259a02016-04-16 03:17:0912730 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]ecab6e052014-05-16 14:58:1212731
12732 {
12733 HttpRequestInfo request;
12734 request.method = "GET";
bncce36dca22015-04-21 22:11:2312735 request.url = GURL("http://www.example.org/");
[email protected]ecab6e052014-05-16 14:58:1212736
dcheng48459ac22014-08-26 00:46:4112737 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]ecab6e052014-05-16 14:58:1212738 TestCompletionCallback callback;
12739
tfarina42834112016-09-22 13:38:2012740 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0112741 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]ecab6e052014-05-16 14:58:1212742 callback.WaitForResult();
12743
12744 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5212745 ASSERT_TRUE(response);
12746 EXPECT_TRUE(response->headers);
[email protected]ecab6e052014-05-16 14:58:1212747 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
12748
12749 // The transaction and HttpRequestInfo are deleted.
12750 }
12751
12752 // Let the HttpResponseBodyDrainer drain the socket.
fdoray92e35a72016-06-10 15:54:5512753 base::RunLoop().RunUntilIdle();
[email protected]ecab6e052014-05-16 14:58:1212754
12755 // Socket should now be idle, waiting to be reused.
dcheng48459ac22014-08-26 00:46:4112756 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]ecab6e052014-05-16 14:58:1212757}
12758
[email protected]76a505b2010-08-25 06:23:0012759// Test a basic GET request through a proxy.
bncd16676a2016-07-20 16:23:0112760TEST_F(HttpNetworkTransactionTest, ProxyGet) {
rdsmith82957ad2015-09-16 19:42:0312761 session_deps_.proxy_service =
12762 ProxyService::CreateFixedFromPacResult("PROXY myproxy:70");
vishal.b62985ca92015-04-17 08:45:5112763 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:0712764 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:0912765 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]76a505b2010-08-25 06:23:0012766
[email protected]76a505b2010-08-25 06:23:0012767 HttpRequestInfo request;
12768 request.method = "GET";
bncce36dca22015-04-21 22:11:2312769 request.url = GURL("http://www.example.org/");
[email protected]76a505b2010-08-25 06:23:0012770
12771 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:2312772 MockWrite(
12773 "GET http://www.example.org/ HTTP/1.1\r\n"
12774 "Host: www.example.org\r\n"
12775 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]76a505b2010-08-25 06:23:0012776 };
12777
12778 MockRead data_reads1[] = {
12779 MockRead("HTTP/1.1 200 OK\r\n"),
12780 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
12781 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:0612782 MockRead(SYNCHRONOUS, OK),
[email protected]76a505b2010-08-25 06:23:0012783 };
12784
12785 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
12786 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:0712787 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]76a505b2010-08-25 06:23:0012788
[email protected]49639fa2011-12-20 23:22:4112789 TestCompletionCallback callback1;
[email protected]76a505b2010-08-25 06:23:0012790
bnc691fda62016-08-12 00:43:1612791 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
ryansturm49a8cb12016-06-15 16:51:0912792 BeforeHeadersSentHandler headers_handler;
bnc691fda62016-08-12 00:43:1612793 trans.SetBeforeHeadersSentCallback(
ryansturm49a8cb12016-06-15 16:51:0912794 base::Bind(&BeforeHeadersSentHandler::OnBeforeHeadersSent,
12795 base::Unretained(&headers_handler)));
[email protected]0b0bf032010-09-21 18:08:5012796
bnc691fda62016-08-12 00:43:1612797 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:0112798 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]76a505b2010-08-25 06:23:0012799
12800 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:0112801 EXPECT_THAT(rv, IsOk());
[email protected]76a505b2010-08-25 06:23:0012802
bnc691fda62016-08-12 00:43:1612803 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5212804 ASSERT_TRUE(response);
[email protected]76a505b2010-08-25 06:23:0012805
12806 EXPECT_TRUE(response->headers->IsKeepAlive());
12807 EXPECT_EQ(200, response->headers->response_code());
12808 EXPECT_EQ(100, response->headers->GetContentLength());
12809 EXPECT_TRUE(response->was_fetched_via_proxy);
tbansal2ecbbc72016-10-06 17:15:4712810 EXPECT_EQ(ProxyServer(ProxyServer::SCHEME_HTTP,
12811 HostPortPair::FromString("myproxy:70")),
12812 response->proxy_server);
ryansturm49a8cb12016-06-15 16:51:0912813 EXPECT_TRUE(headers_handler.observed_before_headers_sent());
12814 EXPECT_TRUE(headers_handler.observed_before_headers_sent_with_proxy());
12815 EXPECT_EQ("myproxy:70", headers_handler.observed_proxy_server_uri());
[email protected]76a505b2010-08-25 06:23:0012816 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
[email protected]029c83b62013-01-24 05:28:2012817
12818 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:1612819 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]029c83b62013-01-24 05:28:2012820 TestLoadTimingNotReusedWithPac(load_timing_info,
12821 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
[email protected]76a505b2010-08-25 06:23:0012822}
12823
12824// Test a basic HTTPS GET request through a proxy.
bncd16676a2016-07-20 16:23:0112825TEST_F(HttpNetworkTransactionTest, ProxyTunnelGet) {
rdsmith82957ad2015-09-16 19:42:0312826 session_deps_.proxy_service =
12827 ProxyService::CreateFixedFromPacResult("PROXY myproxy:70");
vishal.b62985ca92015-04-17 08:45:5112828 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:0712829 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:0912830 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]76a505b2010-08-25 06:23:0012831
[email protected]76a505b2010-08-25 06:23:0012832 HttpRequestInfo request;
12833 request.method = "GET";
bncce36dca22015-04-21 22:11:2312834 request.url = GURL("https://www.example.org/");
[email protected]76a505b2010-08-25 06:23:0012835
12836 // Since we have proxy, should try to establish tunnel.
12837 MockWrite data_writes1[] = {
rsleevidb16bb02015-11-12 23:47:1712838 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
12839 "Host: www.example.org:443\r\n"
12840 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]76a505b2010-08-25 06:23:0012841
rsleevidb16bb02015-11-12 23:47:1712842 MockWrite("GET / HTTP/1.1\r\n"
12843 "Host: www.example.org\r\n"
12844 "Connection: keep-alive\r\n\r\n"),
[email protected]76a505b2010-08-25 06:23:0012845 };
12846
12847 MockRead data_reads1[] = {
12848 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
12849
12850 MockRead("HTTP/1.1 200 OK\r\n"),
12851 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
12852 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:0612853 MockRead(SYNCHRONOUS, OK),
[email protected]76a505b2010-08-25 06:23:0012854 };
12855
12856 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
12857 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:0712858 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8ddf8322012-02-23 18:08:0612859 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:0712860 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]76a505b2010-08-25 06:23:0012861
[email protected]49639fa2011-12-20 23:22:4112862 TestCompletionCallback callback1;
[email protected]76a505b2010-08-25 06:23:0012863
bnc691fda62016-08-12 00:43:1612864 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
ryansturm49a8cb12016-06-15 16:51:0912865 BeforeHeadersSentHandler headers_handler;
bnc691fda62016-08-12 00:43:1612866 trans.SetBeforeHeadersSentCallback(
ryansturm49a8cb12016-06-15 16:51:0912867 base::Bind(&BeforeHeadersSentHandler::OnBeforeHeadersSent,
12868 base::Unretained(&headers_handler)));
[email protected]0b0bf032010-09-21 18:08:5012869
bnc691fda62016-08-12 00:43:1612870 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:0112871 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]76a505b2010-08-25 06:23:0012872
12873 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:0112874 EXPECT_THAT(rv, IsOk());
mmenke43758e62015-05-04 21:09:4612875 TestNetLogEntry::List entries;
[email protected]b2fcd0e2010-12-01 15:19:4012876 log.GetEntries(&entries);
[email protected]76a505b2010-08-25 06:23:0012877 size_t pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:0012878 entries, 0, NetLogEventType::HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
12879 NetLogEventPhase::NONE);
[email protected]76a505b2010-08-25 06:23:0012880 ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:4012881 entries, pos,
mikecirone8b85c432016-09-08 19:11:0012882 NetLogEventType::HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
12883 NetLogEventPhase::NONE);
[email protected]76a505b2010-08-25 06:23:0012884
bnc691fda62016-08-12 00:43:1612885 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5212886 ASSERT_TRUE(response);
[email protected]76a505b2010-08-25 06:23:0012887
12888 EXPECT_TRUE(response->headers->IsKeepAlive());
12889 EXPECT_EQ(200, response->headers->response_code());
12890 EXPECT_EQ(100, response->headers->GetContentLength());
12891 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
12892 EXPECT_TRUE(response->was_fetched_via_proxy);
tbansal2ecbbc72016-10-06 17:15:4712893 EXPECT_EQ(ProxyServer(ProxyServer::SCHEME_HTTP,
12894 HostPortPair::FromString("myproxy:70")),
12895 response->proxy_server);
ryansturm49a8cb12016-06-15 16:51:0912896 EXPECT_TRUE(headers_handler.observed_before_headers_sent());
12897 EXPECT_TRUE(headers_handler.observed_before_headers_sent_with_proxy());
12898 EXPECT_EQ("myproxy:70", headers_handler.observed_proxy_server_uri());
[email protected]029c83b62013-01-24 05:28:2012899
12900 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:1612901 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]029c83b62013-01-24 05:28:2012902 TestLoadTimingNotReusedWithPac(load_timing_info,
12903 CONNECT_TIMING_HAS_SSL_TIMES);
[email protected]76a505b2010-08-25 06:23:0012904}
12905
rsleevidb16bb02015-11-12 23:47:1712906// Test a basic HTTPS GET request through a proxy, connecting to an IPv6
12907// literal host.
bncd16676a2016-07-20 16:23:0112908TEST_F(HttpNetworkTransactionTest, ProxyTunnelGetIPv6) {
rsleevidb16bb02015-11-12 23:47:1712909 session_deps_.proxy_service =
12910 ProxyService::CreateFixedFromPacResult("PROXY myproxy:70");
12911 BoundTestNetLog log;
12912 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:0912913 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
rsleevidb16bb02015-11-12 23:47:1712914
12915 HttpRequestInfo request;
12916 request.method = "GET";
12917 request.url = GURL("https://[::1]:443/");
12918
12919 // Since we have proxy, should try to establish tunnel.
12920 MockWrite data_writes1[] = {
12921 MockWrite("CONNECT [::1]:443 HTTP/1.1\r\n"
12922 "Host: [::1]:443\r\n"
12923 "Proxy-Connection: keep-alive\r\n\r\n"),
12924
12925 MockWrite("GET / HTTP/1.1\r\n"
12926 "Host: [::1]\r\n"
12927 "Connection: keep-alive\r\n\r\n"),
12928 };
12929
12930 MockRead data_reads1[] = {
12931 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
12932
12933 MockRead("HTTP/1.1 200 OK\r\n"),
12934 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
12935 MockRead("Content-Length: 100\r\n\r\n"),
12936 MockRead(SYNCHRONOUS, OK),
12937 };
12938
12939 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
12940 data_writes1, arraysize(data_writes1));
12941 session_deps_.socket_factory->AddSocketDataProvider(&data1);
12942 SSLSocketDataProvider ssl(ASYNC, OK);
12943 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
12944
12945 TestCompletionCallback callback1;
12946
bnc691fda62016-08-12 00:43:1612947 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
rsleevidb16bb02015-11-12 23:47:1712948
bnc691fda62016-08-12 00:43:1612949 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:0112950 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
rsleevidb16bb02015-11-12 23:47:1712951
12952 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:0112953 EXPECT_THAT(rv, IsOk());
rsleevidb16bb02015-11-12 23:47:1712954 TestNetLogEntry::List entries;
12955 log.GetEntries(&entries);
12956 size_t pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:0012957 entries, 0, NetLogEventType::HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
12958 NetLogEventPhase::NONE);
rsleevidb16bb02015-11-12 23:47:1712959 ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:0012960 entries, pos,
12961 NetLogEventType::HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
12962 NetLogEventPhase::NONE);
rsleevidb16bb02015-11-12 23:47:1712963
bnc691fda62016-08-12 00:43:1612964 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5212965 ASSERT_TRUE(response);
rsleevidb16bb02015-11-12 23:47:1712966
12967 EXPECT_TRUE(response->headers->IsKeepAlive());
12968 EXPECT_EQ(200, response->headers->response_code());
12969 EXPECT_EQ(100, response->headers->GetContentLength());
12970 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
12971 EXPECT_TRUE(response->was_fetched_via_proxy);
tbansal2ecbbc72016-10-06 17:15:4712972 EXPECT_EQ(ProxyServer(ProxyServer::SCHEME_HTTP,
12973 HostPortPair::FromString("myproxy:70")),
12974 response->proxy_server);
rsleevidb16bb02015-11-12 23:47:1712975
12976 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:1612977 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
rsleevidb16bb02015-11-12 23:47:1712978 TestLoadTimingNotReusedWithPac(load_timing_info,
12979 CONNECT_TIMING_HAS_SSL_TIMES);
12980}
12981
[email protected]76a505b2010-08-25 06:23:0012982// Test a basic HTTPS GET request through a proxy, but the server hangs up
12983// while establishing the tunnel.
bncd16676a2016-07-20 16:23:0112984TEST_F(HttpNetworkTransactionTest, ProxyTunnelGetHangup) {
rdsmith82957ad2015-09-16 19:42:0312985 session_deps_.proxy_service = ProxyService::CreateFixed("myproxy:70");
vishal.b62985ca92015-04-17 08:45:5112986 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:0712987 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:0912988 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]76a505b2010-08-25 06:23:0012989
[email protected]76a505b2010-08-25 06:23:0012990 HttpRequestInfo request;
12991 request.method = "GET";
bncce36dca22015-04-21 22:11:2312992 request.url = GURL("https://www.example.org/");
[email protected]76a505b2010-08-25 06:23:0012993
12994 // Since we have proxy, should try to establish tunnel.
12995 MockWrite data_writes1[] = {
rsleevidb16bb02015-11-12 23:47:1712996 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
12997 "Host: www.example.org:443\r\n"
12998 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]76a505b2010-08-25 06:23:0012999
rsleevidb16bb02015-11-12 23:47:1713000 MockWrite("GET / HTTP/1.1\r\n"
13001 "Host: www.example.org\r\n"
13002 "Connection: keep-alive\r\n\r\n"),
[email protected]76a505b2010-08-25 06:23:0013003 };
13004
13005 MockRead data_reads1[] = {
[email protected]8ddf8322012-02-23 18:08:0613006 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
[email protected]76a505b2010-08-25 06:23:0013007 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:0613008 MockRead(ASYNC, 0, 0), // EOF
[email protected]76a505b2010-08-25 06:23:0013009 };
13010
13011 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
13012 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:0713013 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8ddf8322012-02-23 18:08:0613014 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:0713015 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]76a505b2010-08-25 06:23:0013016
[email protected]49639fa2011-12-20 23:22:4113017 TestCompletionCallback callback1;
[email protected]76a505b2010-08-25 06:23:0013018
bnc691fda62016-08-12 00:43:1613019 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]0b0bf032010-09-21 18:08:5013020
bnc691fda62016-08-12 00:43:1613021 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:0113022 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]76a505b2010-08-25 06:23:0013023
13024 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:0113025 EXPECT_THAT(rv, IsError(ERR_EMPTY_RESPONSE));
mmenke43758e62015-05-04 21:09:4613026 TestNetLogEntry::List entries;
[email protected]b2fcd0e2010-12-01 15:19:4013027 log.GetEntries(&entries);
[email protected]76a505b2010-08-25 06:23:0013028 size_t pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:0013029 entries, 0, NetLogEventType::HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
13030 NetLogEventPhase::NONE);
[email protected]76a505b2010-08-25 06:23:0013031 ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:4013032 entries, pos,
mikecirone8b85c432016-09-08 19:11:0013033 NetLogEventType::HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
13034 NetLogEventPhase::NONE);
[email protected]76a505b2010-08-25 06:23:0013035}
13036
[email protected]749eefa82010-09-13 22:14:0313037// Test for crbug.com/55424.
bncd16676a2016-07-20 16:23:0113038TEST_F(HttpNetworkTransactionTest, PreconnectWithExistingSpdySession) {
bncdf80d44fd2016-07-15 20:27:4113039 SpdySerializedFrame req(
bnc38dcd392016-02-09 23:19:4913040 spdy_util_.ConstructSpdyGet("https://www.example.org", 1, LOWEST));
bncdf80d44fd2016-07-15 20:27:4113041 MockWrite spdy_writes[] = {CreateMockWrite(req, 0)};
[email protected]749eefa82010-09-13 22:14:0313042
bnc42331402016-07-25 13:36:1513043 SpdySerializedFrame resp(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
bncdf80d44fd2016-07-15 20:27:4113044 SpdySerializedFrame data(spdy_util_.ConstructSpdyDataFrame(1, true));
[email protected]749eefa82010-09-13 22:14:0313045 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:4113046 CreateMockRead(resp, 1), CreateMockRead(data, 2), MockRead(ASYNC, 0, 3),
[email protected]749eefa82010-09-13 22:14:0313047 };
13048
rch8e6c6c42015-05-01 14:05:1313049 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
13050 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:0713051 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]749eefa82010-09-13 22:14:0313052
[email protected]8ddf8322012-02-23 18:08:0613053 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3613054 ssl.next_proto = kProtoHTTP2;
[email protected]bb88e1d32013-05-03 23:11:0713055 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]749eefa82010-09-13 22:14:0313056
danakj1fd259a02016-04-16 03:17:0913057 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]749eefa82010-09-13 22:14:0313058
13059 // Set up an initial SpdySession in the pool to reuse.
bncce36dca22015-04-21 22:11:2313060 HostPortPair host_port_pair("www.example.org", 443);
[email protected]e6d017652013-05-17 18:01:4013061 SpdySessionKey key(host_port_pair, ProxyServer::Direct(),
[email protected]314b03992014-04-01 01:28:5313062 PRIVACY_MODE_DISABLED);
[email protected]795cbf82013-07-22 09:37:2713063 base::WeakPtr<SpdySession> spdy_session =
bnc032658ba2016-09-26 18:17:1513064 CreateSecureSpdySession(session.get(), key, NetLogWithSource());
[email protected]749eefa82010-09-13 22:14:0313065
13066 HttpRequestInfo request;
13067 request.method = "GET";
bncce36dca22015-04-21 22:11:2313068 request.url = GURL("https://www.example.org/");
[email protected]749eefa82010-09-13 22:14:0313069
13070 // This is the important line that marks this as a preconnect.
13071 request.motivation = HttpRequestInfo::PRECONNECT_MOTIVATED;
13072
bnc691fda62016-08-12 00:43:1613073 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]749eefa82010-09-13 22:14:0313074
[email protected]41d64e82013-07-03 22:44:2613075 TestCompletionCallback callback;
tfarina42834112016-09-22 13:38:2013076 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0113077 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
13078 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]749eefa82010-09-13 22:14:0313079}
13080
[email protected]73b8dd222010-11-11 19:55:2413081// Given a net error, cause that error to be returned from the first Write()
bnc691fda62016-08-12 00:43:1613082// call and verify that the HttpNetworkTransaction fails with that error.
[email protected]23e482282013-06-14 16:08:0213083void HttpNetworkTransactionTest::CheckErrorIsPassedBack(
[email protected]bb88e1d32013-05-03 23:11:0713084 int error, IoMode mode) {
ttuttle859dc7a2015-04-23 19:42:2913085 HttpRequestInfo request_info;
[email protected]cb9bf6ca2011-01-28 13:15:2713086 request_info.url = GURL("https://www.example.com/");
13087 request_info.method = "GET";
ttuttle859dc7a2015-04-23 19:42:2913088 request_info.load_flags = LOAD_NORMAL;
[email protected]cb9bf6ca2011-01-28 13:15:2713089
[email protected]8ddf8322012-02-23 18:08:0613090 SSLSocketDataProvider ssl_data(mode, OK);
ttuttle859dc7a2015-04-23 19:42:2913091 MockWrite data_writes[] = {
13092 MockWrite(mode, error),
[email protected]73b8dd222010-11-11 19:55:2413093 };
ttuttle859dc7a2015-04-23 19:42:2913094 StaticSocketDataProvider data(NULL, 0, data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:0713095 session_deps_.socket_factory->AddSocketDataProvider(&data);
13096 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data);
[email protected]73b8dd222010-11-11 19:55:2413097
danakj1fd259a02016-04-16 03:17:0913098 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1613099 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]73b8dd222010-11-11 19:55:2413100
[email protected]49639fa2011-12-20 23:22:4113101 TestCompletionCallback callback;
tfarina42834112016-09-22 13:38:2013102 int rv = trans.Start(&request_info, callback.callback(), NetLogWithSource());
ttuttle859dc7a2015-04-23 19:42:2913103 if (rv == ERR_IO_PENDING)
[email protected]73b8dd222010-11-11 19:55:2413104 rv = callback.WaitForResult();
13105 ASSERT_EQ(error, rv);
13106}
13107
bncd16676a2016-07-20 16:23:0113108TEST_F(HttpNetworkTransactionTest, SSLWriteCertError) {
[email protected]73b8dd222010-11-11 19:55:2413109 // Just check a grab bag of cert errors.
13110 static const int kErrors[] = {
13111 ERR_CERT_COMMON_NAME_INVALID,
13112 ERR_CERT_AUTHORITY_INVALID,
13113 ERR_CERT_DATE_INVALID,
13114 };
13115 for (size_t i = 0; i < arraysize(kErrors); i++) {
[email protected]8ddf8322012-02-23 18:08:0613116 CheckErrorIsPassedBack(kErrors[i], ASYNC);
13117 CheckErrorIsPassedBack(kErrors[i], SYNCHRONOUS);
[email protected]73b8dd222010-11-11 19:55:2413118 }
13119}
13120
[email protected]bd0b6772011-01-11 19:59:3013121// Ensure that a client certificate is removed from the SSL client auth
13122// cache when:
13123// 1) No proxy is involved.
13124// 2) TLS False Start is disabled.
13125// 3) The initial TLS handshake requests a client certificate.
13126// 4) The client supplies an invalid/unacceptable certificate.
bncd16676a2016-07-20 16:23:0113127TEST_F(HttpNetworkTransactionTest, ClientAuthCertCache_Direct_NoFalseStart) {
ttuttle859dc7a2015-04-23 19:42:2913128 HttpRequestInfo request_info;
[email protected]cb9bf6ca2011-01-28 13:15:2713129 request_info.url = GURL("https://www.example.com/");
13130 request_info.method = "GET";
ttuttle859dc7a2015-04-23 19:42:2913131 request_info.load_flags = LOAD_NORMAL;
[email protected]cb9bf6ca2011-01-28 13:15:2713132
[email protected]bd0b6772011-01-11 19:59:3013133 scoped_refptr<SSLCertRequestInfo> cert_request(new SSLCertRequestInfo());
[email protected]791879c2013-12-17 07:22:4113134 cert_request->host_and_port = HostPortPair("www.example.com", 443);
[email protected]bd0b6772011-01-11 19:59:3013135
13136 // [ssl_]data1 contains the data for the first SSL handshake. When a
13137 // CertificateRequest is received for the first time, the handshake will
13138 // be aborted to allow the caller to provide a certificate.
ttuttle859dc7a2015-04-23 19:42:2913139 SSLSocketDataProvider ssl_data1(ASYNC, ERR_SSL_CLIENT_AUTH_CERT_NEEDED);
[email protected]bd0b6772011-01-11 19:59:3013140 ssl_data1.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0713141 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data1);
ttuttle859dc7a2015-04-23 19:42:2913142 StaticSocketDataProvider data1(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0713143 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]bd0b6772011-01-11 19:59:3013144
13145 // [ssl_]data2 contains the data for the second SSL handshake. When TLS
13146 // False Start is not being used, the result of the SSL handshake will be
13147 // returned as part of the SSLClientSocket::Connect() call. This test
13148 // matches the result of a server sending a handshake_failure alert,
13149 // rather than a Finished message, because it requires a client
13150 // certificate and none was supplied.
ttuttle859dc7a2015-04-23 19:42:2913151 SSLSocketDataProvider ssl_data2(ASYNC, ERR_SSL_PROTOCOL_ERROR);
[email protected]bd0b6772011-01-11 19:59:3013152 ssl_data2.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0713153 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data2);
ttuttle859dc7a2015-04-23 19:42:2913154 StaticSocketDataProvider data2(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0713155 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]bd0b6772011-01-11 19:59:3013156
13157 // [ssl_]data3 contains the data for the third SSL handshake. When a
13158 // connection to a server fails during an SSL handshake,
davidbenb937d6c2015-05-14 04:53:4213159 // HttpNetworkTransaction will attempt to fallback to TLSv1.1 if the previous
13160 // connection was attempted with TLSv1.2. This is transparent to the caller
[email protected]bd0b6772011-01-11 19:59:3013161 // of the HttpNetworkTransaction. Because this test failure is due to
13162 // requiring a client certificate, this fallback handshake should also
13163 // fail.
ttuttle859dc7a2015-04-23 19:42:2913164 SSLSocketDataProvider ssl_data3(ASYNC, ERR_SSL_PROTOCOL_ERROR);
[email protected]bd0b6772011-01-11 19:59:3013165 ssl_data3.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0713166 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data3);
ttuttle859dc7a2015-04-23 19:42:2913167 StaticSocketDataProvider data3(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0713168 session_deps_.socket_factory->AddSocketDataProvider(&data3);
[email protected]bd0b6772011-01-11 19:59:3013169
[email protected]80c75f682012-05-26 16:22:1713170 // [ssl_]data4 contains the data for the fourth SSL handshake. When a
13171 // connection to a server fails during an SSL handshake,
davidbenb937d6c2015-05-14 04:53:4213172 // HttpNetworkTransaction will attempt to fallback to TLSv1 if the previous
13173 // connection was attempted with TLSv1.1. This is transparent to the caller
[email protected]80c75f682012-05-26 16:22:1713174 // of the HttpNetworkTransaction. Because this test failure is due to
13175 // requiring a client certificate, this fallback handshake should also
13176 // fail.
ttuttle859dc7a2015-04-23 19:42:2913177 SSLSocketDataProvider ssl_data4(ASYNC, ERR_SSL_PROTOCOL_ERROR);
[email protected]80c75f682012-05-26 16:22:1713178 ssl_data4.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0713179 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data4);
ttuttle859dc7a2015-04-23 19:42:2913180 StaticSocketDataProvider data4(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0713181 session_deps_.socket_factory->AddSocketDataProvider(&data4);
[email protected]80c75f682012-05-26 16:22:1713182
danakj1fd259a02016-04-16 03:17:0913183 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1613184 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]bd0b6772011-01-11 19:59:3013185
[email protected]bd0b6772011-01-11 19:59:3013186 // Begin the SSL handshake with the peer. This consumes ssl_data1.
[email protected]49639fa2011-12-20 23:22:4113187 TestCompletionCallback callback;
tfarina42834112016-09-22 13:38:2013188 int rv = trans.Start(&request_info, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0113189 ASSERT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]bd0b6772011-01-11 19:59:3013190
13191 // Complete the SSL handshake, which should abort due to requiring a
13192 // client certificate.
13193 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0113194 ASSERT_THAT(rv, IsError(ERR_SSL_CLIENT_AUTH_CERT_NEEDED));
[email protected]bd0b6772011-01-11 19:59:3013195
13196 // Indicate that no certificate should be supplied. From the perspective
13197 // of SSLClientCertCache, NULL is just as meaningful as a real
13198 // certificate, so this is the same as supply a
13199 // legitimate-but-unacceptable certificate.
bnc691fda62016-08-12 00:43:1613200 rv = trans.RestartWithCertificate(NULL, NULL, callback.callback());
robpercival214763f2016-07-01 23:27:0113201 ASSERT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]bd0b6772011-01-11 19:59:3013202
13203 // Ensure the certificate was added to the client auth cache before
13204 // allowing the connection to continue restarting.
13205 scoped_refptr<X509Certificate> client_cert;
svaldez7872fd02015-11-19 21:10:5413206 scoped_refptr<SSLPrivateKey> client_private_key;
[email protected]791879c2013-12-17 07:22:4113207 ASSERT_TRUE(session->ssl_client_auth_cache()->Lookup(
svaldez7872fd02015-11-19 21:10:5413208 HostPortPair("www.example.com", 443), &client_cert, &client_private_key));
wezca1070932016-05-26 20:30:5213209 ASSERT_FALSE(client_cert);
[email protected]bd0b6772011-01-11 19:59:3013210
13211 // Restart the handshake. This will consume ssl_data2, which fails, and
[email protected]80c75f682012-05-26 16:22:1713212 // then consume ssl_data3 and ssl_data4, both of which should also fail.
13213 // The result code is checked against what ssl_data4 should return.
[email protected]bd0b6772011-01-11 19:59:3013214 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0113215 ASSERT_THAT(rv, IsError(ERR_SSL_PROTOCOL_ERROR));
[email protected]bd0b6772011-01-11 19:59:3013216
13217 // Ensure that the client certificate is removed from the cache on a
13218 // handshake failure.
[email protected]791879c2013-12-17 07:22:4113219 ASSERT_FALSE(session->ssl_client_auth_cache()->Lookup(
svaldez7872fd02015-11-19 21:10:5413220 HostPortPair("www.example.com", 443), &client_cert, &client_private_key));
[email protected]bd0b6772011-01-11 19:59:3013221}
13222
13223// Ensure that a client certificate is removed from the SSL client auth
13224// cache when:
13225// 1) No proxy is involved.
13226// 2) TLS False Start is enabled.
13227// 3) The initial TLS handshake requests a client certificate.
13228// 4) The client supplies an invalid/unacceptable certificate.
bncd16676a2016-07-20 16:23:0113229TEST_F(HttpNetworkTransactionTest, ClientAuthCertCache_Direct_FalseStart) {
ttuttle859dc7a2015-04-23 19:42:2913230 HttpRequestInfo request_info;
[email protected]cb9bf6ca2011-01-28 13:15:2713231 request_info.url = GURL("https://www.example.com/");
13232 request_info.method = "GET";
ttuttle859dc7a2015-04-23 19:42:2913233 request_info.load_flags = LOAD_NORMAL;
[email protected]cb9bf6ca2011-01-28 13:15:2713234
[email protected]bd0b6772011-01-11 19:59:3013235 scoped_refptr<SSLCertRequestInfo> cert_request(new SSLCertRequestInfo());
[email protected]791879c2013-12-17 07:22:4113236 cert_request->host_and_port = HostPortPair("www.example.com", 443);
[email protected]bd0b6772011-01-11 19:59:3013237
13238 // When TLS False Start is used, SSLClientSocket::Connect() calls will
13239 // return successfully after reading up to the peer's Certificate message.
13240 // This is to allow the caller to call SSLClientSocket::Write(), which can
13241 // enqueue application data to be sent in the same packet as the
13242 // ChangeCipherSpec and Finished messages.
13243 // The actual handshake will be finished when SSLClientSocket::Read() is
13244 // called, which expects to process the peer's ChangeCipherSpec and
13245 // Finished messages. If there was an error negotiating with the peer,
13246 // such as due to the peer requiring a client certificate when none was
13247 // supplied, the alert sent by the peer won't be processed until Read() is
13248 // called.
13249
13250 // Like the non-False Start case, when a client certificate is requested by
13251 // the peer, the handshake is aborted during the Connect() call.
13252 // [ssl_]data1 represents the initial SSL handshake with the peer.
ttuttle859dc7a2015-04-23 19:42:2913253 SSLSocketDataProvider ssl_data1(ASYNC, ERR_SSL_CLIENT_AUTH_CERT_NEEDED);
[email protected]bd0b6772011-01-11 19:59:3013254 ssl_data1.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0713255 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data1);
ttuttle859dc7a2015-04-23 19:42:2913256 StaticSocketDataProvider data1(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0713257 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]bd0b6772011-01-11 19:59:3013258
13259 // When a client certificate is supplied, Connect() will not be aborted
13260 // when the peer requests the certificate. Instead, the handshake will
13261 // artificially succeed, allowing the caller to write the HTTP request to
13262 // the socket. The handshake messages are not processed until Read() is
13263 // called, which then detects that the handshake was aborted, due to the
13264 // peer sending a handshake_failure because it requires a client
13265 // certificate.
ttuttle859dc7a2015-04-23 19:42:2913266 SSLSocketDataProvider ssl_data2(ASYNC, OK);
[email protected]bd0b6772011-01-11 19:59:3013267 ssl_data2.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0713268 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data2);
ttuttle859dc7a2015-04-23 19:42:2913269 MockRead data2_reads[] = {
13270 MockRead(ASYNC /* async */, ERR_SSL_PROTOCOL_ERROR),
[email protected]bd0b6772011-01-11 19:59:3013271 };
ttuttle859dc7a2015-04-23 19:42:2913272 StaticSocketDataProvider data2(data2_reads, arraysize(data2_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0713273 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]bd0b6772011-01-11 19:59:3013274
13275 // As described in ClientAuthCertCache_Direct_NoFalseStart, [ssl_]data3 is
[email protected]80c75f682012-05-26 16:22:1713276 // the data for the SSL handshake once the TLSv1.1 connection falls back to
13277 // TLSv1. It has the same behaviour as [ssl_]data2.
ttuttle859dc7a2015-04-23 19:42:2913278 SSLSocketDataProvider ssl_data3(ASYNC, OK);
[email protected]bd0b6772011-01-11 19:59:3013279 ssl_data3.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0713280 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data3);
ttuttle859dc7a2015-04-23 19:42:2913281 StaticSocketDataProvider data3(data2_reads, arraysize(data2_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0713282 session_deps_.socket_factory->AddSocketDataProvider(&data3);
[email protected]bd0b6772011-01-11 19:59:3013283
[email protected]80c75f682012-05-26 16:22:1713284 // [ssl_]data4 is the data for the SSL handshake once the TLSv1 connection
13285 // falls back to SSLv3. It has the same behaviour as [ssl_]data2.
ttuttle859dc7a2015-04-23 19:42:2913286 SSLSocketDataProvider ssl_data4(ASYNC, OK);
[email protected]80c75f682012-05-26 16:22:1713287 ssl_data4.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0713288 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data4);
ttuttle859dc7a2015-04-23 19:42:2913289 StaticSocketDataProvider data4(data2_reads, arraysize(data2_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0713290 session_deps_.socket_factory->AddSocketDataProvider(&data4);
[email protected]80c75f682012-05-26 16:22:1713291
[email protected]7799de12013-05-30 05:52:5113292 // Need one more if TLSv1.2 is enabled.
ttuttle859dc7a2015-04-23 19:42:2913293 SSLSocketDataProvider ssl_data5(ASYNC, OK);
[email protected]7799de12013-05-30 05:52:5113294 ssl_data5.cert_request_info = cert_request.get();
13295 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data5);
ttuttle859dc7a2015-04-23 19:42:2913296 StaticSocketDataProvider data5(data2_reads, arraysize(data2_reads), NULL, 0);
[email protected]7799de12013-05-30 05:52:5113297 session_deps_.socket_factory->AddSocketDataProvider(&data5);
13298
danakj1fd259a02016-04-16 03:17:0913299 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1613300 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]bd0b6772011-01-11 19:59:3013301
[email protected]bd0b6772011-01-11 19:59:3013302 // Begin the initial SSL handshake.
[email protected]49639fa2011-12-20 23:22:4113303 TestCompletionCallback callback;
tfarina42834112016-09-22 13:38:2013304 int rv = trans.Start(&request_info, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0113305 ASSERT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]bd0b6772011-01-11 19:59:3013306
13307 // Complete the SSL handshake, which should abort due to requiring a
13308 // client certificate.
13309 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0113310 ASSERT_THAT(rv, IsError(ERR_SSL_CLIENT_AUTH_CERT_NEEDED));
[email protected]bd0b6772011-01-11 19:59:3013311
13312 // Indicate that no certificate should be supplied. From the perspective
13313 // of SSLClientCertCache, NULL is just as meaningful as a real
13314 // certificate, so this is the same as supply a
13315 // legitimate-but-unacceptable certificate.
bnc691fda62016-08-12 00:43:1613316 rv = trans.RestartWithCertificate(NULL, NULL, callback.callback());
robpercival214763f2016-07-01 23:27:0113317 ASSERT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]bd0b6772011-01-11 19:59:3013318
13319 // Ensure the certificate was added to the client auth cache before
13320 // allowing the connection to continue restarting.
13321 scoped_refptr<X509Certificate> client_cert;
svaldez7872fd02015-11-19 21:10:5413322 scoped_refptr<SSLPrivateKey> client_private_key;
[email protected]791879c2013-12-17 07:22:4113323 ASSERT_TRUE(session->ssl_client_auth_cache()->Lookup(
svaldez7872fd02015-11-19 21:10:5413324 HostPortPair("www.example.com", 443), &client_cert, &client_private_key));
wezca1070932016-05-26 20:30:5213325 ASSERT_FALSE(client_cert);
[email protected]bd0b6772011-01-11 19:59:3013326
[email protected]bd0b6772011-01-11 19:59:3013327 // Restart the handshake. This will consume ssl_data2, which fails, and
[email protected]80c75f682012-05-26 16:22:1713328 // then consume ssl_data3 and ssl_data4, both of which should also fail.
13329 // The result code is checked against what ssl_data4 should return.
[email protected]bd0b6772011-01-11 19:59:3013330 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0113331 ASSERT_THAT(rv, IsError(ERR_SSL_PROTOCOL_ERROR));
[email protected]bd0b6772011-01-11 19:59:3013332
13333 // Ensure that the client certificate is removed from the cache on a
13334 // handshake failure.
[email protected]791879c2013-12-17 07:22:4113335 ASSERT_FALSE(session->ssl_client_auth_cache()->Lookup(
svaldez7872fd02015-11-19 21:10:5413336 HostPortPair("www.example.com", 443), &client_cert, &client_private_key));
[email protected]bd0b6772011-01-11 19:59:3013337}
13338
[email protected]8c405132011-01-11 22:03:1813339// Ensure that a client certificate is removed from the SSL client auth
13340// cache when:
13341// 1) An HTTPS proxy is involved.
13342// 3) The HTTPS proxy requests a client certificate.
13343// 4) The client supplies an invalid/unacceptable certificate for the
13344// proxy.
13345// The test is repeated twice, first for connecting to an HTTPS endpoint,
13346// then for connecting to an HTTP endpoint.
bncd16676a2016-07-20 16:23:0113347TEST_F(HttpNetworkTransactionTest, ClientAuthCertCache_Proxy_Fail) {
rdsmith82957ad2015-09-16 19:42:0313348 session_deps_.proxy_service = ProxyService::CreateFixed("https://proxy:70");
vishal.b62985ca92015-04-17 08:45:5113349 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:0713350 session_deps_.net_log = log.bound().net_log();
[email protected]8c405132011-01-11 22:03:1813351
13352 scoped_refptr<SSLCertRequestInfo> cert_request(new SSLCertRequestInfo());
[email protected]791879c2013-12-17 07:22:4113353 cert_request->host_and_port = HostPortPair("proxy", 70);
[email protected]8c405132011-01-11 22:03:1813354
13355 // See ClientAuthCertCache_Direct_NoFalseStart for the explanation of
13356 // [ssl_]data[1-3]. Rather than represending the endpoint
13357 // (www.example.com:443), they represent failures with the HTTPS proxy
13358 // (proxy:70).
ttuttle859dc7a2015-04-23 19:42:2913359 SSLSocketDataProvider ssl_data1(ASYNC, ERR_SSL_CLIENT_AUTH_CERT_NEEDED);
[email protected]8c405132011-01-11 22:03:1813360 ssl_data1.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0713361 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data1);
ttuttle859dc7a2015-04-23 19:42:2913362 StaticSocketDataProvider data1(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0713363 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8c405132011-01-11 22:03:1813364
ttuttle859dc7a2015-04-23 19:42:2913365 SSLSocketDataProvider ssl_data2(ASYNC, ERR_SSL_PROTOCOL_ERROR);
[email protected]8c405132011-01-11 22:03:1813366 ssl_data2.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0713367 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data2);
ttuttle859dc7a2015-04-23 19:42:2913368 StaticSocketDataProvider data2(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0713369 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]8c405132011-01-11 22:03:1813370
[email protected]80c75f682012-05-26 16:22:1713371 // TODO(wtc): find out why this unit test doesn't need [ssl_]data3.
13372#if 0
ttuttle859dc7a2015-04-23 19:42:2913373 SSLSocketDataProvider ssl_data3(ASYNC, ERR_SSL_PROTOCOL_ERROR);
[email protected]8c405132011-01-11 22:03:1813374 ssl_data3.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0713375 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data3);
ttuttle859dc7a2015-04-23 19:42:2913376 StaticSocketDataProvider data3(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0713377 session_deps_.socket_factory->AddSocketDataProvider(&data3);
[email protected]80c75f682012-05-26 16:22:1713378#endif
[email protected]8c405132011-01-11 22:03:1813379
ttuttle859dc7a2015-04-23 19:42:2913380 HttpRequestInfo requests[2];
[email protected]8c405132011-01-11 22:03:1813381 requests[0].url = GURL("https://www.example.com/");
13382 requests[0].method = "GET";
ttuttle859dc7a2015-04-23 19:42:2913383 requests[0].load_flags = LOAD_NORMAL;
[email protected]8c405132011-01-11 22:03:1813384
13385 requests[1].url = GURL("http://www.example.com/");
13386 requests[1].method = "GET";
ttuttle859dc7a2015-04-23 19:42:2913387 requests[1].load_flags = LOAD_NORMAL;
[email protected]8c405132011-01-11 22:03:1813388
13389 for (size_t i = 0; i < arraysize(requests); ++i) {
[email protected]bb88e1d32013-05-03 23:11:0713390 session_deps_.socket_factory->ResetNextMockIndexes();
danakj1fd259a02016-04-16 03:17:0913391 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1613392 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]8c405132011-01-11 22:03:1813393
13394 // Begin the SSL handshake with the proxy.
[email protected]49639fa2011-12-20 23:22:4113395 TestCompletionCallback callback;
tfarina42834112016-09-22 13:38:2013396 int rv = trans.Start(&requests[i], callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0113397 ASSERT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]8c405132011-01-11 22:03:1813398
13399 // Complete the SSL handshake, which should abort due to requiring a
13400 // client certificate.
13401 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0113402 ASSERT_THAT(rv, IsError(ERR_SSL_CLIENT_AUTH_CERT_NEEDED));
[email protected]8c405132011-01-11 22:03:1813403
13404 // Indicate that no certificate should be supplied. From the perspective
13405 // of SSLClientCertCache, NULL is just as meaningful as a real
13406 // certificate, so this is the same as supply a
13407 // legitimate-but-unacceptable certificate.
bnc691fda62016-08-12 00:43:1613408 rv = trans.RestartWithCertificate(NULL, NULL, callback.callback());
robpercival214763f2016-07-01 23:27:0113409 ASSERT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]8c405132011-01-11 22:03:1813410
13411 // Ensure the certificate was added to the client auth cache before
13412 // allowing the connection to continue restarting.
13413 scoped_refptr<X509Certificate> client_cert;
svaldez7872fd02015-11-19 21:10:5413414 scoped_refptr<SSLPrivateKey> client_private_key;
[email protected]791879c2013-12-17 07:22:4113415 ASSERT_TRUE(session->ssl_client_auth_cache()->Lookup(
svaldez7872fd02015-11-19 21:10:5413416 HostPortPair("proxy", 70), &client_cert, &client_private_key));
wezca1070932016-05-26 20:30:5213417 ASSERT_FALSE(client_cert);
[email protected]8c405132011-01-11 22:03:1813418 // Ensure the certificate was NOT cached for the endpoint. This only
13419 // applies to HTTPS requests, but is fine to check for HTTP requests.
[email protected]791879c2013-12-17 07:22:4113420 ASSERT_FALSE(session->ssl_client_auth_cache()->Lookup(
svaldez7872fd02015-11-19 21:10:5413421 HostPortPair("www.example.com", 443), &client_cert,
13422 &client_private_key));
[email protected]8c405132011-01-11 22:03:1813423
13424 // Restart the handshake. This will consume ssl_data2, which fails, and
13425 // then consume ssl_data3, which should also fail. The result code is
13426 // checked against what ssl_data3 should return.
13427 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0113428 ASSERT_THAT(rv, IsError(ERR_PROXY_CONNECTION_FAILED));
[email protected]8c405132011-01-11 22:03:1813429
13430 // Now that the new handshake has failed, ensure that the client
13431 // certificate was removed from the client auth cache.
[email protected]791879c2013-12-17 07:22:4113432 ASSERT_FALSE(session->ssl_client_auth_cache()->Lookup(
svaldez7872fd02015-11-19 21:10:5413433 HostPortPair("proxy", 70), &client_cert, &client_private_key));
[email protected]791879c2013-12-17 07:22:4113434 ASSERT_FALSE(session->ssl_client_auth_cache()->Lookup(
svaldez7872fd02015-11-19 21:10:5413435 HostPortPair("www.example.com", 443), &client_cert,
13436 &client_private_key));
[email protected]8c405132011-01-11 22:03:1813437 }
13438}
13439
bncd16676a2016-07-20 16:23:0113440TEST_F(HttpNetworkTransactionTest, UseIPConnectionPooling) {
[email protected]e3ceb682011-06-28 23:55:4613441 // Set up a special HttpNetworkSession with a MockCachingHostResolver.
[email protected]bb88e1d32013-05-03 23:11:0713442 session_deps_.host_resolver.reset(new MockCachingHostResolver());
danakj1fd259a02016-04-16 03:17:0913443 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]e3ceb682011-06-28 23:55:4613444
bnc032658ba2016-09-26 18:17:1513445 AddSSLSocketData();
[email protected]e3ceb682011-06-28 23:55:4613446
bncdf80d44fd2016-07-15 20:27:4113447 SpdySerializedFrame host1_req(
bnc38dcd392016-02-09 23:19:4913448 spdy_util_.ConstructSpdyGet("https://www.example.org", 1, LOWEST));
rdsmithebb50aa2015-11-12 03:44:3813449 spdy_util_.UpdateWithStreamDestruction(1);
bncdf80d44fd2016-07-15 20:27:4113450 SpdySerializedFrame host2_req(
bnca4d611d2016-09-22 19:55:3713451 spdy_util_.ConstructSpdyGet("https://mail.example.com", 3, LOWEST));
[email protected]e3ceb682011-06-28 23:55:4613452 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:4113453 CreateMockWrite(host1_req, 0), CreateMockWrite(host2_req, 3),
[email protected]e3ceb682011-06-28 23:55:4613454 };
bnc42331402016-07-25 13:36:1513455 SpdySerializedFrame host1_resp(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
bncdf80d44fd2016-07-15 20:27:4113456 SpdySerializedFrame host1_resp_body(
13457 spdy_util_.ConstructSpdyDataFrame(1, true));
bnc42331402016-07-25 13:36:1513458 SpdySerializedFrame host2_resp(spdy_util_.ConstructSpdyGetReply(NULL, 0, 3));
bncdf80d44fd2016-07-15 20:27:4113459 SpdySerializedFrame host2_resp_body(
13460 spdy_util_.ConstructSpdyDataFrame(3, true));
[email protected]e3ceb682011-06-28 23:55:4613461 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:4113462 CreateMockRead(host1_resp, 1), CreateMockRead(host1_resp_body, 2),
13463 CreateMockRead(host2_resp, 4), CreateMockRead(host2_resp_body, 5),
rch8e6c6c42015-05-01 14:05:1313464 MockRead(ASYNC, 0, 6),
[email protected]e3ceb682011-06-28 23:55:4613465 };
13466
eroman36d84e54432016-03-17 03:23:0213467 IPEndPoint peer_addr(IPAddress::IPv4Localhost(), 443);
[email protected]d2b5f092012-06-08 23:55:0213468 MockConnect connect(ASYNC, OK, peer_addr);
rch8e6c6c42015-05-01 14:05:1313469 SequencedSocketData spdy_data(connect, spdy_reads, arraysize(spdy_reads),
13470 spdy_writes, arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:0713471 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]e3ceb682011-06-28 23:55:4613472
[email protected]aa22b242011-11-16 18:58:2913473 TestCompletionCallback callback;
[email protected]e3ceb682011-06-28 23:55:4613474 HttpRequestInfo request1;
13475 request1.method = "GET";
bncce36dca22015-04-21 22:11:2313476 request1.url = GURL("https://www.example.org/");
[email protected]e3ceb682011-06-28 23:55:4613477 request1.load_flags = 0;
[email protected]90499482013-06-01 00:39:5013478 HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
[email protected]e3ceb682011-06-28 23:55:4613479
tfarina42834112016-09-22 13:38:2013480 int rv = trans1.Start(&request1, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0113481 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
13482 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]e3ceb682011-06-28 23:55:4613483
13484 const HttpResponseInfo* response = trans1.GetResponseInfo();
wezca1070932016-05-26 20:30:5213485 ASSERT_TRUE(response);
13486 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0213487 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]e3ceb682011-06-28 23:55:4613488
13489 std::string response_data;
robpercival214763f2016-07-01 23:27:0113490 ASSERT_THAT(ReadTransaction(&trans1, &response_data), IsOk());
[email protected]e3ceb682011-06-28 23:55:4613491 EXPECT_EQ("hello!", response_data);
13492
bnca4d611d2016-09-22 19:55:3713493 // Preload mail.example.com into HostCache.
13494 HostPortPair host_port("mail.example.com", 443);
[email protected]5109c1952013-08-20 18:44:1013495 HostResolver::RequestInfo resolve_info(host_port);
[email protected]e3ceb682011-06-28 23:55:4613496 AddressList ignored;
maksim.sisov31452af2016-07-27 06:38:1013497 std::unique_ptr<HostResolver::Request> request;
13498 rv = session_deps_.host_resolver->Resolve(resolve_info, DEFAULT_PRIORITY,
13499 &ignored, callback.callback(),
tfarina42834112016-09-22 13:38:2013500 &request, NetLogWithSource());
robpercival214763f2016-07-01 23:27:0113501 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]6e78dfb2011-07-28 21:34:4713502 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0113503 EXPECT_THAT(rv, IsOk());
[email protected]e3ceb682011-06-28 23:55:4613504
13505 HttpRequestInfo request2;
13506 request2.method = "GET";
bnca4d611d2016-09-22 19:55:3713507 request2.url = GURL("https://mail.example.com/");
[email protected]e3ceb682011-06-28 23:55:4613508 request2.load_flags = 0;
[email protected]90499482013-06-01 00:39:5013509 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
[email protected]e3ceb682011-06-28 23:55:4613510
tfarina42834112016-09-22 13:38:2013511 rv = trans2.Start(&request2, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0113512 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
13513 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]e3ceb682011-06-28 23:55:4613514
13515 response = trans2.GetResponseInfo();
wezca1070932016-05-26 20:30:5213516 ASSERT_TRUE(response);
13517 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0213518 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]e3ceb682011-06-28 23:55:4613519 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5213520 EXPECT_TRUE(response->was_alpn_negotiated);
robpercival214763f2016-07-01 23:27:0113521 ASSERT_THAT(ReadTransaction(&trans2, &response_data), IsOk());
[email protected]e3ceb682011-06-28 23:55:4613522 EXPECT_EQ("hello!", response_data);
[email protected]e3ceb682011-06-28 23:55:4613523}
13524
bncd16676a2016-07-20 16:23:0113525TEST_F(HttpNetworkTransactionTest, UseIPConnectionPoolingAfterResolution) {
[email protected]d2b5f092012-06-08 23:55:0213526 // Set up a special HttpNetworkSession with a MockCachingHostResolver.
[email protected]bb88e1d32013-05-03 23:11:0713527 session_deps_.host_resolver.reset(new MockCachingHostResolver());
danakj1fd259a02016-04-16 03:17:0913528 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]d2b5f092012-06-08 23:55:0213529
bnc032658ba2016-09-26 18:17:1513530 AddSSLSocketData();
[email protected]d2b5f092012-06-08 23:55:0213531
bncdf80d44fd2016-07-15 20:27:4113532 SpdySerializedFrame host1_req(
bnc38dcd392016-02-09 23:19:4913533 spdy_util_.ConstructSpdyGet("https://www.example.org", 1, LOWEST));
rdsmithebb50aa2015-11-12 03:44:3813534 spdy_util_.UpdateWithStreamDestruction(1);
bncdf80d44fd2016-07-15 20:27:4113535 SpdySerializedFrame host2_req(
bnca4d611d2016-09-22 19:55:3713536 spdy_util_.ConstructSpdyGet("https://mail.example.com", 3, LOWEST));
[email protected]d2b5f092012-06-08 23:55:0213537 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:4113538 CreateMockWrite(host1_req, 0), CreateMockWrite(host2_req, 3),
[email protected]d2b5f092012-06-08 23:55:0213539 };
bnc42331402016-07-25 13:36:1513540 SpdySerializedFrame host1_resp(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
bncdf80d44fd2016-07-15 20:27:4113541 SpdySerializedFrame host1_resp_body(
13542 spdy_util_.ConstructSpdyDataFrame(1, true));
bnc42331402016-07-25 13:36:1513543 SpdySerializedFrame host2_resp(spdy_util_.ConstructSpdyGetReply(NULL, 0, 3));
bncdf80d44fd2016-07-15 20:27:4113544 SpdySerializedFrame host2_resp_body(
13545 spdy_util_.ConstructSpdyDataFrame(3, true));
[email protected]d2b5f092012-06-08 23:55:0213546 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:4113547 CreateMockRead(host1_resp, 1), CreateMockRead(host1_resp_body, 2),
13548 CreateMockRead(host2_resp, 4), CreateMockRead(host2_resp_body, 5),
rch8e6c6c42015-05-01 14:05:1313549 MockRead(ASYNC, 0, 6),
[email protected]d2b5f092012-06-08 23:55:0213550 };
13551
eroman36d84e54432016-03-17 03:23:0213552 IPEndPoint peer_addr(IPAddress::IPv4Localhost(), 443);
[email protected]d2b5f092012-06-08 23:55:0213553 MockConnect connect(ASYNC, OK, peer_addr);
rch8e6c6c42015-05-01 14:05:1313554 SequencedSocketData spdy_data(connect, spdy_reads, arraysize(spdy_reads),
13555 spdy_writes, arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:0713556 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]d2b5f092012-06-08 23:55:0213557
13558 TestCompletionCallback callback;
13559 HttpRequestInfo request1;
13560 request1.method = "GET";
bncce36dca22015-04-21 22:11:2313561 request1.url = GURL("https://www.example.org/");
[email protected]d2b5f092012-06-08 23:55:0213562 request1.load_flags = 0;
[email protected]90499482013-06-01 00:39:5013563 HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
[email protected]d2b5f092012-06-08 23:55:0213564
tfarina42834112016-09-22 13:38:2013565 int rv = trans1.Start(&request1, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0113566 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
13567 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]d2b5f092012-06-08 23:55:0213568
13569 const HttpResponseInfo* response = trans1.GetResponseInfo();
wezca1070932016-05-26 20:30:5213570 ASSERT_TRUE(response);
13571 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0213572 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]d2b5f092012-06-08 23:55:0213573
13574 std::string response_data;
robpercival214763f2016-07-01 23:27:0113575 ASSERT_THAT(ReadTransaction(&trans1, &response_data), IsOk());
[email protected]d2b5f092012-06-08 23:55:0213576 EXPECT_EQ("hello!", response_data);
13577
13578 HttpRequestInfo request2;
13579 request2.method = "GET";
bnca4d611d2016-09-22 19:55:3713580 request2.url = GURL("https://mail.example.com/");
[email protected]d2b5f092012-06-08 23:55:0213581 request2.load_flags = 0;
[email protected]90499482013-06-01 00:39:5013582 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
[email protected]d2b5f092012-06-08 23:55:0213583
tfarina42834112016-09-22 13:38:2013584 rv = trans2.Start(&request2, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0113585 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
13586 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]d2b5f092012-06-08 23:55:0213587
13588 response = trans2.GetResponseInfo();
wezca1070932016-05-26 20:30:5213589 ASSERT_TRUE(response);
13590 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0213591 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]d2b5f092012-06-08 23:55:0213592 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5213593 EXPECT_TRUE(response->was_alpn_negotiated);
robpercival214763f2016-07-01 23:27:0113594 ASSERT_THAT(ReadTransaction(&trans2, &response_data), IsOk());
[email protected]d2b5f092012-06-08 23:55:0213595 EXPECT_EQ("hello!", response_data);
[email protected]d2b5f092012-06-08 23:55:0213596}
13597
bnc8016c1f2017-03-31 02:11:2913598// Regression test for https://crbug.com/546991.
13599// The server might not be able to serve an IP pooled request, and might send a
13600// 421 Misdirected Request response status to indicate this.
13601// HttpNetworkTransaction should reset the request and retry without IP pooling.
13602TEST_F(HttpNetworkTransactionTest, RetryWithoutConnectionPooling) {
13603 // Two hosts resolve to the same IP address.
13604 const std::string ip_addr = "1.2.3.4";
13605 IPAddress ip;
13606 ASSERT_TRUE(ip.AssignFromIPLiteral(ip_addr));
13607 IPEndPoint peer_addr = IPEndPoint(ip, 443);
13608
13609 session_deps_.host_resolver.reset(new MockCachingHostResolver());
13610 session_deps_.host_resolver->rules()->AddRule("www.example.org", ip_addr);
13611 session_deps_.host_resolver->rules()->AddRule("mail.example.org", ip_addr);
13612
13613 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
13614
13615 // Two requests on the first connection.
13616 SpdySerializedFrame req1(
13617 spdy_util_.ConstructSpdyGet("https://www.example.org", 1, LOWEST));
13618 spdy_util_.UpdateWithStreamDestruction(1);
13619 SpdySerializedFrame req2(
13620 spdy_util_.ConstructSpdyGet("https://mail.example.org", 3, LOWEST));
13621 SpdySerializedFrame rst(
13622 spdy_util_.ConstructSpdyRstStream(3, ERROR_CODE_CANCEL));
13623 MockWrite writes1[] = {
13624 CreateMockWrite(req1, 0), CreateMockWrite(req2, 3),
13625 CreateMockWrite(rst, 6),
13626 };
13627
13628 // The first one succeeds, the second gets error 421 Misdirected Request.
13629 SpdySerializedFrame resp1(spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
13630 SpdySerializedFrame body1(spdy_util_.ConstructSpdyDataFrame(1, true));
13631 SpdyHeaderBlock response_headers;
13632 response_headers[SpdyTestUtil::GetStatusKey()] = "421";
13633 SpdySerializedFrame resp2(
13634 spdy_util_.ConstructSpdyReply(3, std::move(response_headers)));
13635 MockRead reads1[] = {CreateMockRead(resp1, 1), CreateMockRead(body1, 2),
13636 CreateMockRead(resp2, 4), MockRead(ASYNC, 0, 5)};
13637
13638 MockConnect connect1(ASYNC, OK, peer_addr);
13639 SequencedSocketData data1(connect1, reads1, arraysize(reads1), writes1,
13640 arraysize(writes1));
13641 session_deps_.socket_factory->AddSocketDataProvider(&data1);
13642
13643 AddSSLSocketData();
13644
13645 // Retry the second request on a second connection.
13646 SpdyTestUtil spdy_util2;
13647 SpdySerializedFrame req3(
13648 spdy_util2.ConstructSpdyGet("https://mail.example.org", 1, LOWEST));
13649 MockWrite writes2[] = {
13650 CreateMockWrite(req3, 0),
13651 };
13652
13653 SpdySerializedFrame resp3(spdy_util2.ConstructSpdyGetReply(nullptr, 0, 1));
13654 SpdySerializedFrame body3(spdy_util2.ConstructSpdyDataFrame(1, true));
13655 MockRead reads2[] = {CreateMockRead(resp3, 1), CreateMockRead(body3, 2),
13656 MockRead(ASYNC, 0, 3)};
13657
13658 MockConnect connect2(ASYNC, OK, peer_addr);
13659 SequencedSocketData data2(connect2, reads2, arraysize(reads2), writes2,
13660 arraysize(writes2));
13661 session_deps_.socket_factory->AddSocketDataProvider(&data2);
13662
13663 AddSSLSocketData();
13664
13665 // Preload mail.example.org into HostCache.
13666 HostPortPair host_port("mail.example.org", 443);
13667 HostResolver::RequestInfo resolve_info(host_port);
13668 AddressList ignored;
13669 std::unique_ptr<HostResolver::Request> request;
13670 TestCompletionCallback callback;
13671 int rv = session_deps_.host_resolver->Resolve(resolve_info, DEFAULT_PRIORITY,
13672 &ignored, callback.callback(),
13673 &request, NetLogWithSource());
13674 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
13675 rv = callback.WaitForResult();
13676 EXPECT_THAT(rv, IsOk());
13677
13678 HttpRequestInfo request1;
13679 request1.method = "GET";
13680 request1.url = GURL("https://www.example.org/");
13681 request1.load_flags = 0;
13682 HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
13683
13684 rv = trans1.Start(&request1, callback.callback(), NetLogWithSource());
13685 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
13686 rv = callback.WaitForResult();
13687 EXPECT_THAT(rv, IsOk());
13688
13689 const HttpResponseInfo* response = trans1.GetResponseInfo();
13690 ASSERT_TRUE(response);
13691 ASSERT_TRUE(response->headers);
13692 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
13693 EXPECT_TRUE(response->was_fetched_via_spdy);
13694 EXPECT_TRUE(response->was_alpn_negotiated);
13695 std::string response_data;
13696 ASSERT_THAT(ReadTransaction(&trans1, &response_data), IsOk());
13697 EXPECT_EQ("hello!", response_data);
13698
13699 HttpRequestInfo request2;
13700 request2.method = "GET";
13701 request2.url = GURL("https://mail.example.org/");
13702 request2.load_flags = 0;
13703 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
13704
13705 BoundTestNetLog log;
13706 rv = trans2.Start(&request2, callback.callback(), log.bound());
13707 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
13708 rv = callback.WaitForResult();
13709 EXPECT_THAT(rv, IsOk());
13710
13711 response = trans2.GetResponseInfo();
13712 ASSERT_TRUE(response);
13713 ASSERT_TRUE(response->headers);
13714 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
13715 EXPECT_TRUE(response->was_fetched_via_spdy);
13716 EXPECT_TRUE(response->was_alpn_negotiated);
13717 ASSERT_THAT(ReadTransaction(&trans2, &response_data), IsOk());
13718 EXPECT_EQ("hello!", response_data);
13719
13720 TestNetLogEntry::List entries;
13721 log.GetEntries(&entries);
13722 size_t pos = ExpectLogContainsSomewhere(
13723 entries, 0, NetLogEventType::HTTP_TRANSACTION_RESTART_AFTER_ERROR,
13724 NetLogEventPhase::NONE);
13725 EXPECT_TRUE(entries[pos].GetIntegerValue("net_error", &rv));
13726 EXPECT_THAT(rv, IsError(ERR_MISDIRECTED_REQUEST));
13727}
13728
ttuttle859dc7a2015-04-23 19:42:2913729class OneTimeCachingHostResolver : public HostResolver {
[email protected]e3ceb682011-06-28 23:55:4613730 public:
13731 explicit OneTimeCachingHostResolver(const HostPortPair& host_port)
13732 : host_port_(host_port) {}
dchengb03027d2014-10-21 12:00:2013733 ~OneTimeCachingHostResolver() override {}
[email protected]e3ceb682011-06-28 23:55:4613734
13735 RuleBasedHostResolverProc* rules() { return host_resolver_.rules(); }
13736
13737 // HostResolver methods:
dchengb03027d2014-10-21 12:00:2013738 int Resolve(const RequestInfo& info,
13739 RequestPriority priority,
13740 AddressList* addresses,
13741 const CompletionCallback& callback,
maksim.sisov31452af2016-07-27 06:38:1013742 std::unique_ptr<Request>* out_req,
tfarina42834112016-09-22 13:38:2013743 const NetLogWithSource& net_log) override {
[email protected]95a214c2011-08-04 21:50:4013744 return host_resolver_.Resolve(
[email protected]5109c1952013-08-20 18:44:1013745 info, priority, addresses, callback, out_req, net_log);
[email protected]95a214c2011-08-04 21:50:4013746 }
13747
dchengb03027d2014-10-21 12:00:2013748 int ResolveFromCache(const RequestInfo& info,
13749 AddressList* addresses,
tfarina42834112016-09-22 13:38:2013750 const NetLogWithSource& net_log) override {
[email protected]95a214c2011-08-04 21:50:4013751 int rv = host_resolver_.ResolveFromCache(info, addresses, net_log);
13752 if (rv == OK && info.host_port_pair().Equals(host_port_))
[email protected]98e1cd012011-11-08 15:33:0913753 host_resolver_.GetHostCache()->clear();
[email protected]e3ceb682011-06-28 23:55:4613754 return rv;
13755 }
13756
[email protected]46da33be2011-07-19 21:58:0413757 MockCachingHostResolver* GetMockHostResolver() {
13758 return &host_resolver_;
13759 }
13760
[email protected]e3ceb682011-06-28 23:55:4613761 private:
13762 MockCachingHostResolver host_resolver_;
13763 const HostPortPair host_port_;
13764};
13765
bncd16676a2016-07-20 16:23:0113766TEST_F(HttpNetworkTransactionTest,
mmenke5c642132015-06-02 16:05:1313767 UseIPConnectionPoolingWithHostCacheExpiration) {
[email protected]e3ceb682011-06-28 23:55:4613768 // Set up a special HttpNetworkSession with a OneTimeCachingHostResolver.
bnca4d611d2016-09-22 19:55:3713769 OneTimeCachingHostResolver host_resolver(
13770 HostPortPair("mail.example.com", 443));
[email protected]c6bf8152012-12-02 07:43:3413771 HttpNetworkSession::Params params =
[email protected]bb88e1d32013-05-03 23:11:0713772 SpdySessionDependencies::CreateSessionParams(&session_deps_);
[email protected]e3ceb682011-06-28 23:55:4613773 params.host_resolver = &host_resolver;
danakj1fd259a02016-04-16 03:17:0913774 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]e3ceb682011-06-28 23:55:4613775
bnc032658ba2016-09-26 18:17:1513776 AddSSLSocketData();
[email protected]e3ceb682011-06-28 23:55:4613777
bncdf80d44fd2016-07-15 20:27:4113778 SpdySerializedFrame host1_req(
bnc38dcd392016-02-09 23:19:4913779 spdy_util_.ConstructSpdyGet("https://www.example.org", 1, LOWEST));
rdsmithebb50aa2015-11-12 03:44:3813780 spdy_util_.UpdateWithStreamDestruction(1);
bncdf80d44fd2016-07-15 20:27:4113781 SpdySerializedFrame host2_req(
bnca4d611d2016-09-22 19:55:3713782 spdy_util_.ConstructSpdyGet("https://mail.example.com", 3, LOWEST));
[email protected]e3ceb682011-06-28 23:55:4613783 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:4113784 CreateMockWrite(host1_req, 0), CreateMockWrite(host2_req, 3),
[email protected]e3ceb682011-06-28 23:55:4613785 };
bnc42331402016-07-25 13:36:1513786 SpdySerializedFrame host1_resp(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
bncdf80d44fd2016-07-15 20:27:4113787 SpdySerializedFrame host1_resp_body(
13788 spdy_util_.ConstructSpdyDataFrame(1, true));
bnc42331402016-07-25 13:36:1513789 SpdySerializedFrame host2_resp(spdy_util_.ConstructSpdyGetReply(NULL, 0, 3));
bncdf80d44fd2016-07-15 20:27:4113790 SpdySerializedFrame host2_resp_body(
13791 spdy_util_.ConstructSpdyDataFrame(3, true));
[email protected]e3ceb682011-06-28 23:55:4613792 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:4113793 CreateMockRead(host1_resp, 1), CreateMockRead(host1_resp_body, 2),
13794 CreateMockRead(host2_resp, 4), CreateMockRead(host2_resp_body, 5),
rch8e6c6c42015-05-01 14:05:1313795 MockRead(ASYNC, 0, 6),
[email protected]e3ceb682011-06-28 23:55:4613796 };
13797
eroman36d84e54432016-03-17 03:23:0213798 IPEndPoint peer_addr(IPAddress::IPv4Localhost(), 443);
[email protected]d2b5f092012-06-08 23:55:0213799 MockConnect connect(ASYNC, OK, peer_addr);
rch8e6c6c42015-05-01 14:05:1313800 SequencedSocketData spdy_data(connect, spdy_reads, arraysize(spdy_reads),
13801 spdy_writes, arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:0713802 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]e3ceb682011-06-28 23:55:4613803
[email protected]aa22b242011-11-16 18:58:2913804 TestCompletionCallback callback;
[email protected]e3ceb682011-06-28 23:55:4613805 HttpRequestInfo request1;
13806 request1.method = "GET";
bncce36dca22015-04-21 22:11:2313807 request1.url = GURL("https://www.example.org/");
[email protected]e3ceb682011-06-28 23:55:4613808 request1.load_flags = 0;
[email protected]90499482013-06-01 00:39:5013809 HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
[email protected]e3ceb682011-06-28 23:55:4613810
tfarina42834112016-09-22 13:38:2013811 int rv = trans1.Start(&request1, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0113812 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
13813 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]e3ceb682011-06-28 23:55:4613814
13815 const HttpResponseInfo* response = trans1.GetResponseInfo();
wezca1070932016-05-26 20:30:5213816 ASSERT_TRUE(response);
13817 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0213818 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]e3ceb682011-06-28 23:55:4613819
13820 std::string response_data;
robpercival214763f2016-07-01 23:27:0113821 ASSERT_THAT(ReadTransaction(&trans1, &response_data), IsOk());
[email protected]e3ceb682011-06-28 23:55:4613822 EXPECT_EQ("hello!", response_data);
13823
13824 // Preload cache entries into HostCache.
bnca4d611d2016-09-22 19:55:3713825 HostResolver::RequestInfo resolve_info(HostPortPair("mail.example.com", 443));
[email protected]e3ceb682011-06-28 23:55:4613826 AddressList ignored;
maksim.sisov31452af2016-07-27 06:38:1013827 std::unique_ptr<HostResolver::Request> request;
13828 rv = host_resolver.Resolve(resolve_info, DEFAULT_PRIORITY, &ignored,
tfarina42834112016-09-22 13:38:2013829 callback.callback(), &request, NetLogWithSource());
robpercival214763f2016-07-01 23:27:0113830 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]6e78dfb2011-07-28 21:34:4713831 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0113832 EXPECT_THAT(rv, IsOk());
[email protected]e3ceb682011-06-28 23:55:4613833
13834 HttpRequestInfo request2;
13835 request2.method = "GET";
bnca4d611d2016-09-22 19:55:3713836 request2.url = GURL("https://mail.example.com/");
[email protected]e3ceb682011-06-28 23:55:4613837 request2.load_flags = 0;
[email protected]90499482013-06-01 00:39:5013838 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
[email protected]e3ceb682011-06-28 23:55:4613839
tfarina42834112016-09-22 13:38:2013840 rv = trans2.Start(&request2, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0113841 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
13842 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]e3ceb682011-06-28 23:55:4613843
13844 response = trans2.GetResponseInfo();
wezca1070932016-05-26 20:30:5213845 ASSERT_TRUE(response);
13846 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0213847 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]e3ceb682011-06-28 23:55:4613848 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5213849 EXPECT_TRUE(response->was_alpn_negotiated);
robpercival214763f2016-07-01 23:27:0113850 ASSERT_THAT(ReadTransaction(&trans2, &response_data), IsOk());
[email protected]e3ceb682011-06-28 23:55:4613851 EXPECT_EQ("hello!", response_data);
[email protected]e3ceb682011-06-28 23:55:4613852}
13853
bncd16676a2016-07-20 16:23:0113854TEST_F(HttpNetworkTransactionTest, DoNotUseSpdySessionForHttp) {
bncce36dca22015-04-21 22:11:2313855 const std::string https_url = "https://www.example.org:8080/";
13856 const std::string http_url = "http://www.example.org:8080/";
[email protected]8450d722012-07-02 19:14:0413857
13858 // SPDY GET for HTTPS URL
bncdf80d44fd2016-07-15 20:27:4113859 SpdySerializedFrame req1(
bnc38dcd392016-02-09 23:19:4913860 spdy_util_.ConstructSpdyGet(https_url.c_str(), 1, LOWEST));
[email protected]8450d722012-07-02 19:14:0413861
13862 MockWrite writes1[] = {
bncdf80d44fd2016-07-15 20:27:4113863 CreateMockWrite(req1, 0),
[email protected]8450d722012-07-02 19:14:0413864 };
13865
bnc42331402016-07-25 13:36:1513866 SpdySerializedFrame resp1(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
bncdf80d44fd2016-07-15 20:27:4113867 SpdySerializedFrame body1(spdy_util_.ConstructSpdyDataFrame(1, true));
13868 MockRead reads1[] = {CreateMockRead(resp1, 1), CreateMockRead(body1, 2),
mmenkee24011922015-12-17 22:12:5913869 MockRead(SYNCHRONOUS, ERR_IO_PENDING, 3)};
[email protected]8450d722012-07-02 19:14:0413870
rch8e6c6c42015-05-01 14:05:1313871 SequencedSocketData data1(reads1, arraysize(reads1), writes1,
13872 arraysize(writes1));
[email protected]8450d722012-07-02 19:14:0413873 MockConnect connect_data1(ASYNC, OK);
[email protected]dd54bd82012-07-19 23:44:5713874 data1.set_connect_data(connect_data1);
[email protected]8450d722012-07-02 19:14:0413875
13876 // HTTP GET for the HTTP URL
13877 MockWrite writes2[] = {
rch8e6c6c42015-05-01 14:05:1313878 MockWrite(ASYNC, 0,
lgarrona91df87f2014-12-05 00:51:3413879 "GET / HTTP/1.1\r\n"
bncce36dca22015-04-21 22:11:2313880 "Host: www.example.org:8080\r\n"
lgarrona91df87f2014-12-05 00:51:3413881 "Connection: keep-alive\r\n\r\n"),
[email protected]8450d722012-07-02 19:14:0413882 };
13883
13884 MockRead reads2[] = {
rch8e6c6c42015-05-01 14:05:1313885 MockRead(ASYNC, 1, "HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
13886 MockRead(ASYNC, 2, "hello"),
13887 MockRead(ASYNC, OK, 3),
[email protected]8450d722012-07-02 19:14:0413888 };
13889
rch8e6c6c42015-05-01 14:05:1313890 SequencedSocketData data2(reads2, arraysize(reads2), writes2,
13891 arraysize(writes2));
[email protected]8450d722012-07-02 19:14:0413892
[email protected]8450d722012-07-02 19:14:0413893 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3613894 ssl.next_proto = kProtoHTTP2;
[email protected]bb88e1d32013-05-03 23:11:0713895 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
13896 session_deps_.socket_factory->AddSocketDataProvider(&data1);
13897 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]8450d722012-07-02 19:14:0413898
danakj1fd259a02016-04-16 03:17:0913899 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]8450d722012-07-02 19:14:0413900
13901 // Start the first transaction to set up the SpdySession
13902 HttpRequestInfo request1;
13903 request1.method = "GET";
13904 request1.url = GURL(https_url);
[email protected]8450d722012-07-02 19:14:0413905 request1.load_flags = 0;
[email protected]90499482013-06-01 00:39:5013906 HttpNetworkTransaction trans1(LOWEST, session.get());
[email protected]8450d722012-07-02 19:14:0413907 TestCompletionCallback callback1;
13908 EXPECT_EQ(ERR_IO_PENDING,
tfarina42834112016-09-22 13:38:2013909 trans1.Start(&request1, callback1.callback(), NetLogWithSource()));
fdoray92e35a72016-06-10 15:54:5513910 base::RunLoop().RunUntilIdle();
[email protected]8450d722012-07-02 19:14:0413911
robpercival214763f2016-07-01 23:27:0113912 EXPECT_THAT(callback1.WaitForResult(), IsOk());
[email protected]8450d722012-07-02 19:14:0413913 EXPECT_TRUE(trans1.GetResponseInfo()->was_fetched_via_spdy);
13914
13915 // Now, start the HTTP request
13916 HttpRequestInfo request2;
13917 request2.method = "GET";
13918 request2.url = GURL(http_url);
[email protected]8450d722012-07-02 19:14:0413919 request2.load_flags = 0;
[email protected]90499482013-06-01 00:39:5013920 HttpNetworkTransaction trans2(MEDIUM, session.get());
[email protected]8450d722012-07-02 19:14:0413921 TestCompletionCallback callback2;
13922 EXPECT_EQ(ERR_IO_PENDING,
tfarina42834112016-09-22 13:38:2013923 trans2.Start(&request2, callback2.callback(), NetLogWithSource()));
fdoray92e35a72016-06-10 15:54:5513924 base::RunLoop().RunUntilIdle();
[email protected]8450d722012-07-02 19:14:0413925
robpercival214763f2016-07-01 23:27:0113926 EXPECT_THAT(callback2.WaitForResult(), IsOk());
[email protected]8450d722012-07-02 19:14:0413927 EXPECT_FALSE(trans2.GetResponseInfo()->was_fetched_via_spdy);
13928}
13929
bnc5452e2a2015-05-08 16:27:4213930// Alternative service requires HTTP/2 (or SPDY), but HTTP/1.1 is negotiated
13931// with the alternative server. That connection should not be used.
bncd16676a2016-07-20 16:23:0113932TEST_F(HttpNetworkTransactionTest, AlternativeServiceNotOnHttp11) {
bnc8bef8da22016-05-30 01:28:2513933 url::SchemeHostPort server("https", "www.example.org", 443);
13934 HostPortPair alternative("www.example.org", 444);
bnc5452e2a2015-05-08 16:27:4213935
bnc8bef8da22016-05-30 01:28:2513936 // Negotiate HTTP/1.1 with alternative.
bnc5452e2a2015-05-08 16:27:4213937 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3613938 ssl.next_proto = kProtoHTTP11;
bnc5452e2a2015-05-08 16:27:4213939 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
13940
13941 // No data should be read from the alternative, because HTTP/1.1 is
13942 // negotiated.
13943 StaticSocketDataProvider data;
13944 session_deps_.socket_factory->AddSocketDataProvider(&data);
13945
13946 // This test documents that an alternate Job should not be used if HTTP/1.1 is
zhongyi3d4a55e72016-04-22 20:36:4613947 // negotiated. In order to test this, a failed connection to the server is
bnc5452e2a2015-05-08 16:27:4213948 // mocked. This way the request relies on the alternate Job.
13949 StaticSocketDataProvider data_refused;
13950 data_refused.set_connect_data(MockConnect(ASYNC, ERR_CONNECTION_REFUSED));
13951 session_deps_.socket_factory->AddSocketDataProvider(&data_refused);
13952
zhongyi3d4a55e72016-04-22 20:36:4613953 // Set up alternative service for server.
danakj1fd259a02016-04-16 03:17:0913954 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc525e175a2016-06-20 12:36:4013955 HttpServerProperties* http_server_properties =
bnc5452e2a2015-05-08 16:27:4213956 session->http_server_properties();
bnc3472afd2016-11-17 15:27:2113957 AlternativeService alternative_service(kProtoHTTP2, alternative);
bnc7dc7e1b42015-07-28 14:43:1213958 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyi3d4a55e72016-04-22 20:36:4613959 http_server_properties->SetAlternativeService(server, alternative_service,
rchdc7b9052016-03-17 20:51:5013960 expiration);
bnc5452e2a2015-05-08 16:27:4213961
bnc5452e2a2015-05-08 16:27:4213962 HttpRequestInfo request;
krasinc06a72a2016-12-21 03:42:4613963 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
bnc5452e2a2015-05-08 16:27:4213964 request.method = "GET";
bnc8bef8da22016-05-30 01:28:2513965 request.url = GURL("https://www.example.org:443");
bnc5452e2a2015-05-08 16:27:4213966 TestCompletionCallback callback;
13967
13968 // HTTP/2 (or SPDY) is required for alternative service, if HTTP/1.1 is
bnc94c92842016-09-21 15:22:5213969 // negotiated, the alternate Job should fail with ERR_ALPN_NEGOTIATION_FAILED.
tfarina42834112016-09-22 13:38:2013970 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
bnc94c92842016-09-21 15:22:5213971 EXPECT_THAT(callback.GetResult(rv), IsError(ERR_ALPN_NEGOTIATION_FAILED));
bnc5452e2a2015-05-08 16:27:4213972}
13973
bnc40448a532015-05-11 19:13:1413974// A request to a server with an alternative service fires two Jobs: one to the
zhongyi3d4a55e72016-04-22 20:36:4613975// server, and an alternate one to the alternative server. If the former
bnc40448a532015-05-11 19:13:1413976// succeeds, the request should succeed, even if the latter fails because
13977// HTTP/1.1 is negotiated which is insufficient for alternative service.
bncd16676a2016-07-20 16:23:0113978TEST_F(HttpNetworkTransactionTest, FailedAlternativeServiceIsNotUserVisible) {
bnc8bef8da22016-05-30 01:28:2513979 url::SchemeHostPort server("https", "www.example.org", 443);
13980 HostPortPair alternative("www.example.org", 444);
bnc40448a532015-05-11 19:13:1413981
13982 // Negotiate HTTP/1.1 with alternative.
13983 SSLSocketDataProvider alternative_ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3613984 alternative_ssl.next_proto = kProtoHTTP11;
bnc40448a532015-05-11 19:13:1413985 session_deps_.socket_factory->AddSSLSocketDataProvider(&alternative_ssl);
13986
13987 // No data should be read from the alternative, because HTTP/1.1 is
13988 // negotiated.
13989 StaticSocketDataProvider data;
13990 session_deps_.socket_factory->AddSocketDataProvider(&data);
13991
zhongyi3d4a55e72016-04-22 20:36:4613992 // Negotiate HTTP/1.1 with server.
bnc40448a532015-05-11 19:13:1413993 SSLSocketDataProvider origin_ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3613994 origin_ssl.next_proto = kProtoHTTP11;
bnc40448a532015-05-11 19:13:1413995 session_deps_.socket_factory->AddSSLSocketDataProvider(&origin_ssl);
13996
13997 MockWrite http_writes[] = {
bnc8bef8da22016-05-30 01:28:2513998 MockWrite("GET / HTTP/1.1\r\n"
13999 "Host: www.example.org\r\n"
14000 "Connection: keep-alive\r\n\r\n"),
14001 MockWrite("GET /second HTTP/1.1\r\n"
14002 "Host: www.example.org\r\n"
14003 "Connection: keep-alive\r\n\r\n"),
bnc40448a532015-05-11 19:13:1414004 };
14005
14006 MockRead http_reads[] = {
14007 MockRead("HTTP/1.1 200 OK\r\n"),
14008 MockRead("Content-Type: text/html\r\n"),
14009 MockRead("Content-Length: 6\r\n\r\n"),
14010 MockRead("foobar"),
14011 MockRead("HTTP/1.1 200 OK\r\n"),
14012 MockRead("Content-Type: text/html\r\n"),
14013 MockRead("Content-Length: 7\r\n\r\n"),
14014 MockRead("another"),
14015 };
14016 StaticSocketDataProvider http_data(http_reads, arraysize(http_reads),
14017 http_writes, arraysize(http_writes));
14018 session_deps_.socket_factory->AddSocketDataProvider(&http_data);
14019
zhongyi3d4a55e72016-04-22 20:36:4614020 // Set up alternative service for server.
danakj1fd259a02016-04-16 03:17:0914021 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc525e175a2016-06-20 12:36:4014022 HttpServerProperties* http_server_properties =
bnc40448a532015-05-11 19:13:1414023 session->http_server_properties();
bnc3472afd2016-11-17 15:27:2114024 AlternativeService alternative_service(kProtoHTTP2, alternative);
bnc7dc7e1b42015-07-28 14:43:1214025 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyi3d4a55e72016-04-22 20:36:4614026 http_server_properties->SetAlternativeService(server, alternative_service,
rchdc7b9052016-03-17 20:51:5014027 expiration);
bnc40448a532015-05-11 19:13:1414028
14029 HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
14030 HttpRequestInfo request1;
14031 request1.method = "GET";
bnc8bef8da22016-05-30 01:28:2514032 request1.url = GURL("https://www.example.org:443");
bnc40448a532015-05-11 19:13:1414033 request1.load_flags = 0;
14034 TestCompletionCallback callback1;
14035
tfarina42834112016-09-22 13:38:2014036 int rv = trans1.Start(&request1, callback1.callback(), NetLogWithSource());
bnc40448a532015-05-11 19:13:1414037 rv = callback1.GetResult(rv);
robpercival214763f2016-07-01 23:27:0114038 EXPECT_THAT(rv, IsOk());
bnc40448a532015-05-11 19:13:1414039
14040 const HttpResponseInfo* response1 = trans1.GetResponseInfo();
wezca1070932016-05-26 20:30:5214041 ASSERT_TRUE(response1);
14042 ASSERT_TRUE(response1->headers);
bnc40448a532015-05-11 19:13:1414043 EXPECT_EQ("HTTP/1.1 200 OK", response1->headers->GetStatusLine());
14044
14045 std::string response_data1;
robpercival214763f2016-07-01 23:27:0114046 ASSERT_THAT(ReadTransaction(&trans1, &response_data1), IsOk());
bnc40448a532015-05-11 19:13:1414047 EXPECT_EQ("foobar", response_data1);
14048
14049 // Alternative should be marked as broken, because HTTP/1.1 is not sufficient
14050 // for alternative service.
14051 EXPECT_TRUE(
14052 http_server_properties->IsAlternativeServiceBroken(alternative_service));
14053
zhongyi3d4a55e72016-04-22 20:36:4614054 // Since |alternative_service| is broken, a second transaction to server
bnc40448a532015-05-11 19:13:1414055 // should not start an alternate Job. It should pool to existing connection
zhongyi3d4a55e72016-04-22 20:36:4614056 // to server.
bnc40448a532015-05-11 19:13:1414057 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
14058 HttpRequestInfo request2;
14059 request2.method = "GET";
bnc8bef8da22016-05-30 01:28:2514060 request2.url = GURL("https://www.example.org:443/second");
bnc40448a532015-05-11 19:13:1414061 request2.load_flags = 0;
14062 TestCompletionCallback callback2;
14063
tfarina42834112016-09-22 13:38:2014064 rv = trans2.Start(&request2, callback2.callback(), NetLogWithSource());
bnc40448a532015-05-11 19:13:1414065 rv = callback2.GetResult(rv);
robpercival214763f2016-07-01 23:27:0114066 EXPECT_THAT(rv, IsOk());
bnc40448a532015-05-11 19:13:1414067
14068 const HttpResponseInfo* response2 = trans2.GetResponseInfo();
wezca1070932016-05-26 20:30:5214069 ASSERT_TRUE(response2);
14070 ASSERT_TRUE(response2->headers);
bnc40448a532015-05-11 19:13:1414071 EXPECT_EQ("HTTP/1.1 200 OK", response2->headers->GetStatusLine());
14072
14073 std::string response_data2;
robpercival214763f2016-07-01 23:27:0114074 ASSERT_THAT(ReadTransaction(&trans2, &response_data2), IsOk());
bnc40448a532015-05-11 19:13:1414075 EXPECT_EQ("another", response_data2);
14076}
14077
bnc5452e2a2015-05-08 16:27:4214078// Alternative service requires HTTP/2 (or SPDY), but there is already a
14079// HTTP/1.1 socket open to the alternative server. That socket should not be
14080// used.
bncd16676a2016-07-20 16:23:0114081TEST_F(HttpNetworkTransactionTest, AlternativeServiceShouldNotPoolToHttp11) {
zhongyi3d4a55e72016-04-22 20:36:4614082 url::SchemeHostPort server("https", "origin.example.org", 443);
bnc5452e2a2015-05-08 16:27:4214083 HostPortPair alternative("alternative.example.org", 443);
14084 std::string origin_url = "https://origin.example.org:443";
14085 std::string alternative_url = "https://alternative.example.org:443";
14086
14087 // Negotiate HTTP/1.1 with alternative.example.org.
14088 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3614089 ssl.next_proto = kProtoHTTP11;
bnc5452e2a2015-05-08 16:27:4214090 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
14091
14092 // HTTP/1.1 data for |request1| and |request2|.
14093 MockWrite http_writes[] = {
14094 MockWrite(
14095 "GET / HTTP/1.1\r\n"
14096 "Host: alternative.example.org\r\n"
14097 "Connection: keep-alive\r\n\r\n"),
14098 MockWrite(
14099 "GET / HTTP/1.1\r\n"
14100 "Host: alternative.example.org\r\n"
14101 "Connection: keep-alive\r\n\r\n"),
14102 };
14103
14104 MockRead http_reads[] = {
14105 MockRead(
14106 "HTTP/1.1 200 OK\r\n"
14107 "Content-Type: text/html; charset=iso-8859-1\r\n"
14108 "Content-Length: 40\r\n\r\n"
14109 "first HTTP/1.1 response from alternative"),
14110 MockRead(
14111 "HTTP/1.1 200 OK\r\n"
14112 "Content-Type: text/html; charset=iso-8859-1\r\n"
14113 "Content-Length: 41\r\n\r\n"
14114 "second HTTP/1.1 response from alternative"),
14115 };
14116 StaticSocketDataProvider http_data(http_reads, arraysize(http_reads),
14117 http_writes, arraysize(http_writes));
14118 session_deps_.socket_factory->AddSocketDataProvider(&http_data);
14119
14120 // This test documents that an alternate Job should not pool to an already
14121 // existing HTTP/1.1 connection. In order to test this, a failed connection
zhongyi3d4a55e72016-04-22 20:36:4614122 // to the server is mocked. This way |request2| relies on the alternate Job.
bnc5452e2a2015-05-08 16:27:4214123 StaticSocketDataProvider data_refused;
14124 data_refused.set_connect_data(MockConnect(ASYNC, ERR_CONNECTION_REFUSED));
14125 session_deps_.socket_factory->AddSocketDataProvider(&data_refused);
14126
zhongyi3d4a55e72016-04-22 20:36:4614127 // Set up alternative service for server.
danakj1fd259a02016-04-16 03:17:0914128 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc525e175a2016-06-20 12:36:4014129 HttpServerProperties* http_server_properties =
bnc5452e2a2015-05-08 16:27:4214130 session->http_server_properties();
bnc3472afd2016-11-17 15:27:2114131 AlternativeService alternative_service(kProtoHTTP2, alternative);
bnc7dc7e1b42015-07-28 14:43:1214132 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyi3d4a55e72016-04-22 20:36:4614133 http_server_properties->SetAlternativeService(server, alternative_service,
rchdc7b9052016-03-17 20:51:5014134 expiration);
bnc5452e2a2015-05-08 16:27:4214135
14136 // First transaction to alternative to open an HTTP/1.1 socket.
bnc5452e2a2015-05-08 16:27:4214137 HttpRequestInfo request1;
krasinc06a72a2016-12-21 03:42:4614138 HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
bnc5452e2a2015-05-08 16:27:4214139 request1.method = "GET";
14140 request1.url = GURL(alternative_url);
14141 request1.load_flags = 0;
14142 TestCompletionCallback callback1;
14143
tfarina42834112016-09-22 13:38:2014144 int rv = trans1.Start(&request1, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0114145 EXPECT_THAT(callback1.GetResult(rv), IsOk());
bnc691fda62016-08-12 00:43:1614146 const HttpResponseInfo* response1 = trans1.GetResponseInfo();
bnc5452e2a2015-05-08 16:27:4214147 ASSERT_TRUE(response1);
wezca1070932016-05-26 20:30:5214148 ASSERT_TRUE(response1->headers);
bnc5452e2a2015-05-08 16:27:4214149 EXPECT_EQ("HTTP/1.1 200 OK", response1->headers->GetStatusLine());
bnc94c92842016-09-21 15:22:5214150 EXPECT_TRUE(response1->was_alpn_negotiated);
bnc5452e2a2015-05-08 16:27:4214151 EXPECT_FALSE(response1->was_fetched_via_spdy);
14152 std::string response_data1;
bnc691fda62016-08-12 00:43:1614153 ASSERT_THAT(ReadTransaction(&trans1, &response_data1), IsOk());
bnc5452e2a2015-05-08 16:27:4214154 EXPECT_EQ("first HTTP/1.1 response from alternative", response_data1);
14155
14156 // Request for origin.example.org, which has an alternative service. This
14157 // will start two Jobs: the alternative looks for connections to pool to,
14158 // finds one which is HTTP/1.1, and should ignore it, and should not try to
zhongyi3d4a55e72016-04-22 20:36:4614159 // open other connections to alternative server. The Job to server fails, so
bnc5452e2a2015-05-08 16:27:4214160 // this request fails.
bnc5452e2a2015-05-08 16:27:4214161 HttpRequestInfo request2;
krasinc06a72a2016-12-21 03:42:4614162 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
bnc5452e2a2015-05-08 16:27:4214163 request2.method = "GET";
14164 request2.url = GURL(origin_url);
14165 request2.load_flags = 0;
14166 TestCompletionCallback callback2;
14167
tfarina42834112016-09-22 13:38:2014168 rv = trans2.Start(&request2, callback2.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0114169 EXPECT_THAT(callback2.GetResult(rv), IsError(ERR_CONNECTION_REFUSED));
bnc5452e2a2015-05-08 16:27:4214170
14171 // Another transaction to alternative. This is to test that the HTTP/1.1
14172 // socket is still open and in the pool.
bnc5452e2a2015-05-08 16:27:4214173 HttpRequestInfo request3;
krasinc06a72a2016-12-21 03:42:4614174 HttpNetworkTransaction trans3(DEFAULT_PRIORITY, session.get());
bnc5452e2a2015-05-08 16:27:4214175 request3.method = "GET";
14176 request3.url = GURL(alternative_url);
14177 request3.load_flags = 0;
14178 TestCompletionCallback callback3;
14179
tfarina42834112016-09-22 13:38:2014180 rv = trans3.Start(&request3, callback3.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0114181 EXPECT_THAT(callback3.GetResult(rv), IsOk());
bnc691fda62016-08-12 00:43:1614182 const HttpResponseInfo* response3 = trans3.GetResponseInfo();
bnc5452e2a2015-05-08 16:27:4214183 ASSERT_TRUE(response3);
wezca1070932016-05-26 20:30:5214184 ASSERT_TRUE(response3->headers);
bnc5452e2a2015-05-08 16:27:4214185 EXPECT_EQ("HTTP/1.1 200 OK", response3->headers->GetStatusLine());
bnc94c92842016-09-21 15:22:5214186 EXPECT_TRUE(response3->was_alpn_negotiated);
bnc5452e2a2015-05-08 16:27:4214187 EXPECT_FALSE(response3->was_fetched_via_spdy);
14188 std::string response_data3;
bnc691fda62016-08-12 00:43:1614189 ASSERT_THAT(ReadTransaction(&trans3, &response_data3), IsOk());
bnc5452e2a2015-05-08 16:27:4214190 EXPECT_EQ("second HTTP/1.1 response from alternative", response_data3);
14191}
14192
bncd16676a2016-07-20 16:23:0114193TEST_F(HttpNetworkTransactionTest, DoNotUseSpdySessionForHttpOverTunnel) {
bncce36dca22015-04-21 22:11:2314194 const std::string https_url = "https://www.example.org:8080/";
14195 const std::string http_url = "http://www.example.org:8080/";
[email protected]8450d722012-07-02 19:14:0414196
rdsmithebb50aa2015-11-12 03:44:3814197 // Separate SPDY util instance for naked and wrapped requests.
bncd16676a2016-07-20 16:23:0114198 SpdyTestUtil spdy_util_wrapped;
rdsmithebb50aa2015-11-12 03:44:3814199
[email protected]8450d722012-07-02 19:14:0414200 // SPDY GET for HTTPS URL (through CONNECT tunnel)
bncce36dca22015-04-21 22:11:2314201 const HostPortPair host_port_pair("www.example.org", 8080);
bncdf80d44fd2016-07-15 20:27:4114202 SpdySerializedFrame connect(
lgarrona91df87f2014-12-05 00:51:3414203 spdy_util_.ConstructSpdyConnect(NULL, 0, 1, LOWEST, host_port_pair));
bncdf80d44fd2016-07-15 20:27:4114204 SpdySerializedFrame req1(
bnc38dcd392016-02-09 23:19:4914205 spdy_util_wrapped.ConstructSpdyGet(https_url.c_str(), 1, LOWEST));
bncdf80d44fd2016-07-15 20:27:4114206 SpdySerializedFrame wrapped_req1(
[email protected]23e482282013-06-14 16:08:0214207 spdy_util_.ConstructWrappedSpdyFrame(req1, 1));
[email protected]601e03f12014-04-06 16:26:3914208
14209 // SPDY GET for HTTP URL (through the proxy, but not the tunnel).
[email protected]745aa9c2014-06-27 02:21:2914210 SpdyHeaderBlock req2_block;
14211 req2_block[spdy_util_.GetMethodKey()] = "GET";
bncce36dca22015-04-21 22:11:2314212 req2_block[spdy_util_.GetHostKey()] = "www.example.org:8080";
[email protected]745aa9c2014-06-27 02:21:2914213 req2_block[spdy_util_.GetSchemeKey()] = "http";
bnc7ecc1122015-09-28 13:22:4914214 req2_block[spdy_util_.GetPathKey()] = "/";
bncdf80d44fd2016-07-15 20:27:4114215 SpdySerializedFrame req2(
bnc42331402016-07-25 13:36:1514216 spdy_util_.ConstructSpdyHeaders(3, std::move(req2_block), MEDIUM, true));
[email protected]8450d722012-07-02 19:14:0414217
14218 MockWrite writes1[] = {
bncdf80d44fd2016-07-15 20:27:4114219 CreateMockWrite(connect, 0), CreateMockWrite(wrapped_req1, 2),
14220 CreateMockWrite(req2, 6),
[email protected]8450d722012-07-02 19:14:0414221 };
14222
bncdf80d44fd2016-07-15 20:27:4114223 SpdySerializedFrame conn_resp(
bnc42331402016-07-25 13:36:1514224 spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
bncdf80d44fd2016-07-15 20:27:4114225 SpdySerializedFrame resp1(
bnc42331402016-07-25 13:36:1514226 spdy_util_wrapped.ConstructSpdyGetReply(nullptr, 0, 1));
bncdf80d44fd2016-07-15 20:27:4114227 SpdySerializedFrame body1(spdy_util_wrapped.ConstructSpdyDataFrame(1, true));
14228 SpdySerializedFrame wrapped_resp1(
rdsmithebb50aa2015-11-12 03:44:3814229 spdy_util_wrapped.ConstructWrappedSpdyFrame(resp1, 1));
bncdf80d44fd2016-07-15 20:27:4114230 SpdySerializedFrame wrapped_body1(
rdsmithebb50aa2015-11-12 03:44:3814231 spdy_util_wrapped.ConstructWrappedSpdyFrame(body1, 1));
bnc42331402016-07-25 13:36:1514232 SpdySerializedFrame resp2(spdy_util_.ConstructSpdyGetReply(NULL, 0, 3));
bncdf80d44fd2016-07-15 20:27:4114233 SpdySerializedFrame body2(spdy_util_.ConstructSpdyDataFrame(3, true));
mmenke666a6fea2015-12-19 04:16:3314234 MockRead reads1[] = {
bncdf80d44fd2016-07-15 20:27:4114235 CreateMockRead(conn_resp, 1),
mmenke666a6fea2015-12-19 04:16:3314236 MockRead(ASYNC, ERR_IO_PENDING, 3),
bncdf80d44fd2016-07-15 20:27:4114237 CreateMockRead(wrapped_resp1, 4),
14238 CreateMockRead(wrapped_body1, 5),
mmenke666a6fea2015-12-19 04:16:3314239 MockRead(ASYNC, ERR_IO_PENDING, 7),
bncdf80d44fd2016-07-15 20:27:4114240 CreateMockRead(resp2, 8),
14241 CreateMockRead(body2, 9),
mmenke666a6fea2015-12-19 04:16:3314242 MockRead(SYNCHRONOUS, ERR_IO_PENDING, 10),
14243 };
[email protected]8450d722012-07-02 19:14:0414244
mmenke666a6fea2015-12-19 04:16:3314245 SequencedSocketData data1(reads1, arraysize(reads1), writes1,
14246 arraysize(writes1));
[email protected]8450d722012-07-02 19:14:0414247 MockConnect connect_data1(ASYNC, OK);
[email protected]dd54bd82012-07-19 23:44:5714248 data1.set_connect_data(connect_data1);
[email protected]8450d722012-07-02 19:14:0414249
rdsmith82957ad2015-09-16 19:42:0314250 session_deps_.proxy_service =
14251 ProxyService::CreateFixedFromPacResult("HTTPS proxy:70");
vishal.b62985ca92015-04-17 08:45:5114252 TestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:0714253 session_deps_.net_log = &log;
[email protected]8450d722012-07-02 19:14:0414254 SSLSocketDataProvider ssl1(ASYNC, OK); // to the proxy
bnc3cf2a592016-08-11 14:48:3614255 ssl1.next_proto = kProtoHTTP2;
mmenke666a6fea2015-12-19 04:16:3314256 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl1);
[email protected]8450d722012-07-02 19:14:0414257 SSLSocketDataProvider ssl2(ASYNC, OK); // to the server
bnc3cf2a592016-08-11 14:48:3614258 ssl2.next_proto = kProtoHTTP2;
mmenke666a6fea2015-12-19 04:16:3314259 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
14260 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8450d722012-07-02 19:14:0414261
danakj1fd259a02016-04-16 03:17:0914262 std::unique_ptr<HttpNetworkSession> session = CreateSession(&session_deps_);
[email protected]8450d722012-07-02 19:14:0414263
14264 // Start the first transaction to set up the SpdySession
14265 HttpRequestInfo request1;
14266 request1.method = "GET";
14267 request1.url = GURL(https_url);
[email protected]8450d722012-07-02 19:14:0414268 request1.load_flags = 0;
[email protected]90499482013-06-01 00:39:5014269 HttpNetworkTransaction trans1(LOWEST, session.get());
[email protected]8450d722012-07-02 19:14:0414270 TestCompletionCallback callback1;
tfarina42834112016-09-22 13:38:2014271 int rv = trans1.Start(&request1, callback1.callback(), NetLogWithSource());
[email protected]8450d722012-07-02 19:14:0414272
mmenke666a6fea2015-12-19 04:16:3314273 // This pause is a hack to avoid running into https://crbug.com/497228.
14274 data1.RunUntilPaused();
14275 base::RunLoop().RunUntilIdle();
14276 data1.Resume();
robpercival214763f2016-07-01 23:27:0114277 EXPECT_THAT(callback1.GetResult(rv), IsOk());
[email protected]8450d722012-07-02 19:14:0414278 EXPECT_TRUE(trans1.GetResponseInfo()->was_fetched_via_spdy);
14279
[email protected]f6c63db52013-02-02 00:35:2214280 LoadTimingInfo load_timing_info1;
14281 EXPECT_TRUE(trans1.GetLoadTimingInfo(&load_timing_info1));
14282 TestLoadTimingNotReusedWithPac(load_timing_info1,
14283 CONNECT_TIMING_HAS_SSL_TIMES);
14284
mmenke666a6fea2015-12-19 04:16:3314285 // Now, start the HTTP request.
[email protected]8450d722012-07-02 19:14:0414286 HttpRequestInfo request2;
14287 request2.method = "GET";
14288 request2.url = GURL(http_url);
[email protected]8450d722012-07-02 19:14:0414289 request2.load_flags = 0;
[email protected]90499482013-06-01 00:39:5014290 HttpNetworkTransaction trans2(MEDIUM, session.get());
[email protected]8450d722012-07-02 19:14:0414291 TestCompletionCallback callback2;
tfarina42834112016-09-22 13:38:2014292 rv = trans2.Start(&request2, callback2.callback(), NetLogWithSource());
[email protected]8450d722012-07-02 19:14:0414293
mmenke666a6fea2015-12-19 04:16:3314294 // This pause is a hack to avoid running into https://crbug.com/497228.
14295 data1.RunUntilPaused();
14296 base::RunLoop().RunUntilIdle();
14297 data1.Resume();
robpercival214763f2016-07-01 23:27:0114298 EXPECT_THAT(callback2.GetResult(rv), IsOk());
mmenke666a6fea2015-12-19 04:16:3314299
[email protected]8450d722012-07-02 19:14:0414300 EXPECT_TRUE(trans2.GetResponseInfo()->was_fetched_via_spdy);
[email protected]f6c63db52013-02-02 00:35:2214301
14302 LoadTimingInfo load_timing_info2;
14303 EXPECT_TRUE(trans2.GetLoadTimingInfo(&load_timing_info2));
14304 // The established SPDY sessions is considered reused by the HTTP request.
14305 TestLoadTimingReusedWithPac(load_timing_info2);
14306 // HTTP requests over a SPDY session should have a different connection
14307 // socket_log_id than requests over a tunnel.
14308 EXPECT_NE(load_timing_info1.socket_log_id, load_timing_info2.socket_log_id);
[email protected]8450d722012-07-02 19:14:0414309}
14310
[email protected]2d88e7d2012-07-19 17:55:1714311// Test that in the case where we have a SPDY session to a SPDY proxy
14312// that we do not pool other origins that resolve to the same IP when
14313// the certificate does not match the new origin.
14314// http://crbug.com/134690
bncd16676a2016-07-20 16:23:0114315TEST_F(HttpNetworkTransactionTest, DoNotUseSpdySessionIfCertDoesNotMatch) {
bncce36dca22015-04-21 22:11:2314316 const std::string url1 = "http://www.example.org/";
14317 const std::string url2 = "https://news.example.org/";
[email protected]2d88e7d2012-07-19 17:55:1714318 const std::string ip_addr = "1.2.3.4";
14319
rdsmithebb50aa2015-11-12 03:44:3814320 // Second SpdyTestUtil instance for the second socket.
bncd16676a2016-07-20 16:23:0114321 SpdyTestUtil spdy_util_secure;
rdsmithebb50aa2015-11-12 03:44:3814322
[email protected]2d88e7d2012-07-19 17:55:1714323 // SPDY GET for HTTP URL (through SPDY proxy)
bnc086b39e12016-06-24 13:05:2614324 SpdyHeaderBlock headers(
bncce36dca22015-04-21 22:11:2314325 spdy_util_.ConstructGetHeaderBlockForProxy("http://www.example.org/"));
bncdf80d44fd2016-07-15 20:27:4114326 SpdySerializedFrame req1(
bnc42331402016-07-25 13:36:1514327 spdy_util_.ConstructSpdyHeaders(1, std::move(headers), LOWEST, true));
[email protected]2d88e7d2012-07-19 17:55:1714328
14329 MockWrite writes1[] = {
bncdf80d44fd2016-07-15 20:27:4114330 CreateMockWrite(req1, 0),
[email protected]2d88e7d2012-07-19 17:55:1714331 };
14332
bnc42331402016-07-25 13:36:1514333 SpdySerializedFrame resp1(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
bncdf80d44fd2016-07-15 20:27:4114334 SpdySerializedFrame body1(spdy_util_.ConstructSpdyDataFrame(1, true));
[email protected]2d88e7d2012-07-19 17:55:1714335 MockRead reads1[] = {
bncdf80d44fd2016-07-15 20:27:4114336 MockRead(ASYNC, ERR_IO_PENDING, 1), CreateMockRead(resp1, 2),
14337 CreateMockRead(body1, 3), MockRead(ASYNC, OK, 4), // EOF
[email protected]2d88e7d2012-07-19 17:55:1714338 };
14339
mmenke666a6fea2015-12-19 04:16:3314340 SequencedSocketData data1(reads1, arraysize(reads1), writes1,
14341 arraysize(writes1));
martijnfe9636e2016-02-06 14:33:3214342 IPAddress ip;
martijn654c8c42016-02-10 22:10:5914343 ASSERT_TRUE(ip.AssignFromIPLiteral(ip_addr));
[email protected]2d88e7d2012-07-19 17:55:1714344 IPEndPoint peer_addr = IPEndPoint(ip, 443);
14345 MockConnect connect_data1(ASYNC, OK, peer_addr);
mmenke666a6fea2015-12-19 04:16:3314346 data1.set_connect_data(connect_data1);
[email protected]2d88e7d2012-07-19 17:55:1714347
14348 // SPDY GET for HTTPS URL (direct)
bncdf80d44fd2016-07-15 20:27:4114349 SpdySerializedFrame req2(
bnc38dcd392016-02-09 23:19:4914350 spdy_util_secure.ConstructSpdyGet(url2.c_str(), 1, MEDIUM));
[email protected]2d88e7d2012-07-19 17:55:1714351
14352 MockWrite writes2[] = {
bncdf80d44fd2016-07-15 20:27:4114353 CreateMockWrite(req2, 0),
[email protected]2d88e7d2012-07-19 17:55:1714354 };
14355
bnc42331402016-07-25 13:36:1514356 SpdySerializedFrame resp2(spdy_util_secure.ConstructSpdyGetReply(NULL, 0, 1));
bncdf80d44fd2016-07-15 20:27:4114357 SpdySerializedFrame body2(spdy_util_secure.ConstructSpdyDataFrame(1, true));
14358 MockRead reads2[] = {CreateMockRead(resp2, 1), CreateMockRead(body2, 2),
mmenke666a6fea2015-12-19 04:16:3314359 MockRead(ASYNC, OK, 3)};
[email protected]2d88e7d2012-07-19 17:55:1714360
mmenke666a6fea2015-12-19 04:16:3314361 SequencedSocketData data2(reads2, arraysize(reads2), writes2,
14362 arraysize(writes2));
[email protected]2d88e7d2012-07-19 17:55:1714363 MockConnect connect_data2(ASYNC, OK);
mmenke666a6fea2015-12-19 04:16:3314364 data2.set_connect_data(connect_data2);
[email protected]2d88e7d2012-07-19 17:55:1714365
14366 // Set up a proxy config that sends HTTP requests to a proxy, and
14367 // all others direct.
14368 ProxyConfig proxy_config;
14369 proxy_config.proxy_rules().ParseFromString("http=https://proxy:443");
[email protected]bb88e1d32013-05-03 23:11:0714370 session_deps_.proxy_service.reset(new ProxyService(
danakj1fd259a02016-04-16 03:17:0914371 base::WrapUnique(new ProxyConfigServiceFixed(proxy_config)), nullptr,
csharrisonb7e3a082015-09-22 19:13:0414372 NULL));
[email protected]2d88e7d2012-07-19 17:55:1714373
bncce36dca22015-04-21 22:11:2314374 SSLSocketDataProvider ssl1(ASYNC, OK); // to the proxy
bnc3cf2a592016-08-11 14:48:3614375 ssl1.next_proto = kProtoHTTP2;
[email protected]2d88e7d2012-07-19 17:55:1714376 // Load a valid cert. Note, that this does not need to
14377 // be valid for proxy because the MockSSLClientSocket does
14378 // not actually verify it. But SpdySession will use this
14379 // to see if it is valid for the new origin
bncce36dca22015-04-21 22:11:2314380 ssl1.cert = ImportCertFromFile(GetTestCertsDirectory(), "ok_cert.pem");
wezca1070932016-05-26 20:30:5214381 ASSERT_TRUE(ssl1.cert);
mmenke666a6fea2015-12-19 04:16:3314382 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl1);
14383 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]2d88e7d2012-07-19 17:55:1714384
14385 SSLSocketDataProvider ssl2(ASYNC, OK); // to the server
bnc3cf2a592016-08-11 14:48:3614386 ssl2.next_proto = kProtoHTTP2;
mmenke666a6fea2015-12-19 04:16:3314387 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
14388 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]2d88e7d2012-07-19 17:55:1714389
[email protected]bb88e1d32013-05-03 23:11:0714390 session_deps_.host_resolver.reset(new MockCachingHostResolver());
bncce36dca22015-04-21 22:11:2314391 session_deps_.host_resolver->rules()->AddRule("news.example.org", ip_addr);
[email protected]bb88e1d32013-05-03 23:11:0714392 session_deps_.host_resolver->rules()->AddRule("proxy", ip_addr);
[email protected]2d88e7d2012-07-19 17:55:1714393
danakj1fd259a02016-04-16 03:17:0914394 std::unique_ptr<HttpNetworkSession> session = CreateSession(&session_deps_);
[email protected]2d88e7d2012-07-19 17:55:1714395
14396 // Start the first transaction to set up the SpdySession
14397 HttpRequestInfo request1;
14398 request1.method = "GET";
14399 request1.url = GURL(url1);
[email protected]2d88e7d2012-07-19 17:55:1714400 request1.load_flags = 0;
[email protected]90499482013-06-01 00:39:5014401 HttpNetworkTransaction trans1(LOWEST, session.get());
[email protected]2d88e7d2012-07-19 17:55:1714402 TestCompletionCallback callback1;
14403 ASSERT_EQ(ERR_IO_PENDING,
tfarina42834112016-09-22 13:38:2014404 trans1.Start(&request1, callback1.callback(), NetLogWithSource()));
mmenke666a6fea2015-12-19 04:16:3314405 // This pause is a hack to avoid running into https://crbug.com/497228.
14406 data1.RunUntilPaused();
14407 base::RunLoop().RunUntilIdle();
14408 data1.Resume();
[email protected]2d88e7d2012-07-19 17:55:1714409
robpercival214763f2016-07-01 23:27:0114410 EXPECT_THAT(callback1.WaitForResult(), IsOk());
[email protected]2d88e7d2012-07-19 17:55:1714411 EXPECT_TRUE(trans1.GetResponseInfo()->was_fetched_via_spdy);
14412
14413 // Now, start the HTTP request
14414 HttpRequestInfo request2;
14415 request2.method = "GET";
14416 request2.url = GURL(url2);
[email protected]2d88e7d2012-07-19 17:55:1714417 request2.load_flags = 0;
[email protected]90499482013-06-01 00:39:5014418 HttpNetworkTransaction trans2(MEDIUM, session.get());
[email protected]2d88e7d2012-07-19 17:55:1714419 TestCompletionCallback callback2;
14420 EXPECT_EQ(ERR_IO_PENDING,
tfarina42834112016-09-22 13:38:2014421 trans2.Start(&request2, callback2.callback(), NetLogWithSource()));
fdoray92e35a72016-06-10 15:54:5514422 base::RunLoop().RunUntilIdle();
[email protected]2d88e7d2012-07-19 17:55:1714423
14424 ASSERT_TRUE(callback2.have_result());
robpercival214763f2016-07-01 23:27:0114425 EXPECT_THAT(callback2.WaitForResult(), IsOk());
[email protected]2d88e7d2012-07-19 17:55:1714426 EXPECT_TRUE(trans2.GetResponseInfo()->was_fetched_via_spdy);
14427}
14428
[email protected]85f97342013-04-17 06:12:2414429// Test to verify that a failed socket read (due to an ERR_CONNECTION_CLOSED
14430// error) in SPDY session, removes the socket from pool and closes the SPDY
14431// session. Verify that new url's from the same HttpNetworkSession (and a new
14432// SpdySession) do work. http://crbug.com/224701
bncd16676a2016-07-20 16:23:0114433TEST_F(HttpNetworkTransactionTest, ErrorSocketNotConnected) {
bncce36dca22015-04-21 22:11:2314434 const std::string https_url = "https://www.example.org/";
[email protected]85f97342013-04-17 06:12:2414435
14436 MockRead reads1[] = {
14437 MockRead(SYNCHRONOUS, ERR_CONNECTION_CLOSED, 0)
14438 };
14439
mmenke11eb5152015-06-09 14:50:5014440 SequencedSocketData data1(reads1, arraysize(reads1), NULL, 0);
[email protected]85f97342013-04-17 06:12:2414441
bncdf80d44fd2016-07-15 20:27:4114442 SpdySerializedFrame req2(
bnc38dcd392016-02-09 23:19:4914443 spdy_util_.ConstructSpdyGet(https_url.c_str(), 1, MEDIUM));
[email protected]85f97342013-04-17 06:12:2414444 MockWrite writes2[] = {
bncdf80d44fd2016-07-15 20:27:4114445 CreateMockWrite(req2, 0),
[email protected]85f97342013-04-17 06:12:2414446 };
14447
bnc42331402016-07-25 13:36:1514448 SpdySerializedFrame resp2(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
bncdf80d44fd2016-07-15 20:27:4114449 SpdySerializedFrame body2(spdy_util_.ConstructSpdyDataFrame(1, true));
[email protected]85f97342013-04-17 06:12:2414450 MockRead reads2[] = {
bncdf80d44fd2016-07-15 20:27:4114451 CreateMockRead(resp2, 1), CreateMockRead(body2, 2),
14452 MockRead(ASYNC, OK, 3) // EOF
[email protected]85f97342013-04-17 06:12:2414453 };
14454
mmenke11eb5152015-06-09 14:50:5014455 SequencedSocketData data2(reads2, arraysize(reads2), writes2,
14456 arraysize(writes2));
[email protected]85f97342013-04-17 06:12:2414457
[email protected]85f97342013-04-17 06:12:2414458 SSLSocketDataProvider ssl1(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3614459 ssl1.next_proto = kProtoHTTP2;
mmenke11eb5152015-06-09 14:50:5014460 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl1);
14461 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]85f97342013-04-17 06:12:2414462
14463 SSLSocketDataProvider ssl2(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3614464 ssl2.next_proto = kProtoHTTP2;
mmenke11eb5152015-06-09 14:50:5014465 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
14466 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]85f97342013-04-17 06:12:2414467
danakj1fd259a02016-04-16 03:17:0914468 std::unique_ptr<HttpNetworkSession> session(
mmenke11eb5152015-06-09 14:50:5014469 SpdySessionDependencies::SpdyCreateSession(&session_deps_));
[email protected]85f97342013-04-17 06:12:2414470
14471 // Start the first transaction to set up the SpdySession and verify that
14472 // connection was closed.
14473 HttpRequestInfo request1;
14474 request1.method = "GET";
14475 request1.url = GURL(https_url);
14476 request1.load_flags = 0;
[email protected]90499482013-06-01 00:39:5014477 HttpNetworkTransaction trans1(MEDIUM, session.get());
[email protected]85f97342013-04-17 06:12:2414478 TestCompletionCallback callback1;
14479 EXPECT_EQ(ERR_IO_PENDING,
tfarina42834112016-09-22 13:38:2014480 trans1.Start(&request1, callback1.callback(), NetLogWithSource()));
robpercival214763f2016-07-01 23:27:0114481 EXPECT_THAT(callback1.WaitForResult(), IsError(ERR_CONNECTION_CLOSED));
[email protected]85f97342013-04-17 06:12:2414482
14483 // Now, start the second request and make sure it succeeds.
14484 HttpRequestInfo request2;
14485 request2.method = "GET";
14486 request2.url = GURL(https_url);
14487 request2.load_flags = 0;
[email protected]90499482013-06-01 00:39:5014488 HttpNetworkTransaction trans2(MEDIUM, session.get());
[email protected]85f97342013-04-17 06:12:2414489 TestCompletionCallback callback2;
14490 EXPECT_EQ(ERR_IO_PENDING,
tfarina42834112016-09-22 13:38:2014491 trans2.Start(&request2, callback2.callback(), NetLogWithSource()));
[email protected]85f97342013-04-17 06:12:2414492
robpercival214763f2016-07-01 23:27:0114493 ASSERT_THAT(callback2.WaitForResult(), IsOk());
[email protected]85f97342013-04-17 06:12:2414494 EXPECT_TRUE(trans2.GetResponseInfo()->was_fetched_via_spdy);
14495}
14496
bncd16676a2016-07-20 16:23:0114497TEST_F(HttpNetworkTransactionTest, CloseIdleSpdySessionToOpenNewOne) {
[email protected]483fa202013-05-14 01:07:0314498 ClientSocketPoolManager::set_max_sockets_per_group(
14499 HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
14500 ClientSocketPoolManager::set_max_sockets_per_pool(
14501 HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
14502
14503 // Use two different hosts with different IPs so they don't get pooled.
14504 session_deps_.host_resolver->rules()->AddRule("www.a.com", "10.0.0.1");
14505 session_deps_.host_resolver->rules()->AddRule("www.b.com", "10.0.0.2");
danakj1fd259a02016-04-16 03:17:0914506 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]483fa202013-05-14 01:07:0314507
14508 SSLSocketDataProvider ssl1(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3614509 ssl1.next_proto = kProtoHTTP2;
[email protected]483fa202013-05-14 01:07:0314510 SSLSocketDataProvider ssl2(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3614511 ssl2.next_proto = kProtoHTTP2;
[email protected]483fa202013-05-14 01:07:0314512 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl1);
14513 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
14514
bncdf80d44fd2016-07-15 20:27:4114515 SpdySerializedFrame host1_req(
bnc38dcd392016-02-09 23:19:4914516 spdy_util_.ConstructSpdyGet("https://www.a.com", 1, DEFAULT_PRIORITY));
[email protected]483fa202013-05-14 01:07:0314517 MockWrite spdy1_writes[] = {
bncdf80d44fd2016-07-15 20:27:4114518 CreateMockWrite(host1_req, 0),
[email protected]483fa202013-05-14 01:07:0314519 };
bnc42331402016-07-25 13:36:1514520 SpdySerializedFrame host1_resp(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
bncdf80d44fd2016-07-15 20:27:4114521 SpdySerializedFrame host1_resp_body(
14522 spdy_util_.ConstructSpdyDataFrame(1, true));
[email protected]483fa202013-05-14 01:07:0314523 MockRead spdy1_reads[] = {
bncdf80d44fd2016-07-15 20:27:4114524 CreateMockRead(host1_resp, 1), CreateMockRead(host1_resp_body, 2),
mmenkee24011922015-12-17 22:12:5914525 MockRead(SYNCHRONOUS, ERR_IO_PENDING, 3),
[email protected]483fa202013-05-14 01:07:0314526 };
14527
rdsmithebb50aa2015-11-12 03:44:3814528 // Use a separate test instance for the separate SpdySession that will be
14529 // created.
bncd16676a2016-07-20 16:23:0114530 SpdyTestUtil spdy_util_2;
danakj1fd259a02016-04-16 03:17:0914531 std::unique_ptr<SequencedSocketData> spdy1_data(
rch8e6c6c42015-05-01 14:05:1314532 new SequencedSocketData(spdy1_reads, arraysize(spdy1_reads), spdy1_writes,
14533 arraysize(spdy1_writes)));
[email protected]483fa202013-05-14 01:07:0314534 session_deps_.socket_factory->AddSocketDataProvider(spdy1_data.get());
14535
bncdf80d44fd2016-07-15 20:27:4114536 SpdySerializedFrame host2_req(
bnc38dcd392016-02-09 23:19:4914537 spdy_util_2.ConstructSpdyGet("https://www.b.com", 1, DEFAULT_PRIORITY));
[email protected]483fa202013-05-14 01:07:0314538 MockWrite spdy2_writes[] = {
bncdf80d44fd2016-07-15 20:27:4114539 CreateMockWrite(host2_req, 0),
[email protected]483fa202013-05-14 01:07:0314540 };
bnc42331402016-07-25 13:36:1514541 SpdySerializedFrame host2_resp(spdy_util_2.ConstructSpdyGetReply(NULL, 0, 1));
bncdf80d44fd2016-07-15 20:27:4114542 SpdySerializedFrame host2_resp_body(
14543 spdy_util_2.ConstructSpdyDataFrame(1, true));
[email protected]483fa202013-05-14 01:07:0314544 MockRead spdy2_reads[] = {
bncdf80d44fd2016-07-15 20:27:4114545 CreateMockRead(host2_resp, 1), CreateMockRead(host2_resp_body, 2),
mmenkee24011922015-12-17 22:12:5914546 MockRead(SYNCHRONOUS, ERR_IO_PENDING, 3),
[email protected]483fa202013-05-14 01:07:0314547 };
14548
danakj1fd259a02016-04-16 03:17:0914549 std::unique_ptr<SequencedSocketData> spdy2_data(
rch8e6c6c42015-05-01 14:05:1314550 new SequencedSocketData(spdy2_reads, arraysize(spdy2_reads), spdy2_writes,
14551 arraysize(spdy2_writes)));
[email protected]483fa202013-05-14 01:07:0314552 session_deps_.socket_factory->AddSocketDataProvider(spdy2_data.get());
14553
14554 MockWrite http_write[] = {
14555 MockWrite("GET / HTTP/1.1\r\n"
14556 "Host: www.a.com\r\n"
14557 "Connection: keep-alive\r\n\r\n"),
14558 };
14559
14560 MockRead http_read[] = {
14561 MockRead("HTTP/1.1 200 OK\r\n"),
14562 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
14563 MockRead("Content-Length: 6\r\n\r\n"),
14564 MockRead("hello!"),
14565 };
14566 StaticSocketDataProvider http_data(http_read, arraysize(http_read),
14567 http_write, arraysize(http_write));
14568 session_deps_.socket_factory->AddSocketDataProvider(&http_data);
14569
14570 HostPortPair host_port_pair_a("www.a.com", 443);
[email protected]e6d017652013-05-17 18:01:4014571 SpdySessionKey spdy_session_key_a(
[email protected]314b03992014-04-01 01:28:5314572 host_port_pair_a, ProxyServer::Direct(), PRIVACY_MODE_DISABLED);
[email protected]483fa202013-05-14 01:07:0314573 EXPECT_FALSE(
[email protected]41d64e82013-07-03 22:44:2614574 HasSpdySession(session->spdy_session_pool(), spdy_session_key_a));
[email protected]483fa202013-05-14 01:07:0314575
14576 TestCompletionCallback callback;
14577 HttpRequestInfo request1;
14578 request1.method = "GET";
14579 request1.url = GURL("https://www.a.com/");
14580 request1.load_flags = 0;
danakj1fd259a02016-04-16 03:17:0914581 std::unique_ptr<HttpNetworkTransaction> trans(
[email protected]90499482013-06-01 00:39:5014582 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]483fa202013-05-14 01:07:0314583
tfarina42834112016-09-22 13:38:2014584 int rv = trans->Start(&request1, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0114585 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
14586 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]483fa202013-05-14 01:07:0314587
14588 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5214589 ASSERT_TRUE(response);
14590 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0214591 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]483fa202013-05-14 01:07:0314592 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5214593 EXPECT_TRUE(response->was_alpn_negotiated);
[email protected]483fa202013-05-14 01:07:0314594
14595 std::string response_data;
robpercival214763f2016-07-01 23:27:0114596 ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
[email protected]483fa202013-05-14 01:07:0314597 EXPECT_EQ("hello!", response_data);
14598 trans.reset();
14599 EXPECT_TRUE(
[email protected]41d64e82013-07-03 22:44:2614600 HasSpdySession(session->spdy_session_pool(), spdy_session_key_a));
[email protected]483fa202013-05-14 01:07:0314601
14602 HostPortPair host_port_pair_b("www.b.com", 443);
[email protected]e6d017652013-05-17 18:01:4014603 SpdySessionKey spdy_session_key_b(
[email protected]314b03992014-04-01 01:28:5314604 host_port_pair_b, ProxyServer::Direct(), PRIVACY_MODE_DISABLED);
[email protected]483fa202013-05-14 01:07:0314605 EXPECT_FALSE(
[email protected]41d64e82013-07-03 22:44:2614606 HasSpdySession(session->spdy_session_pool(), spdy_session_key_b));
[email protected]483fa202013-05-14 01:07:0314607 HttpRequestInfo request2;
14608 request2.method = "GET";
14609 request2.url = GURL("https://www.b.com/");
14610 request2.load_flags = 0;
[email protected]90499482013-06-01 00:39:5014611 trans.reset(new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]483fa202013-05-14 01:07:0314612
tfarina42834112016-09-22 13:38:2014613 rv = trans->Start(&request2, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0114614 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
14615 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]483fa202013-05-14 01:07:0314616
14617 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5214618 ASSERT_TRUE(response);
14619 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0214620 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]483fa202013-05-14 01:07:0314621 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5214622 EXPECT_TRUE(response->was_alpn_negotiated);
robpercival214763f2016-07-01 23:27:0114623 ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
[email protected]483fa202013-05-14 01:07:0314624 EXPECT_EQ("hello!", response_data);
14625 EXPECT_FALSE(
[email protected]41d64e82013-07-03 22:44:2614626 HasSpdySession(session->spdy_session_pool(), spdy_session_key_a));
[email protected]483fa202013-05-14 01:07:0314627 EXPECT_TRUE(
[email protected]41d64e82013-07-03 22:44:2614628 HasSpdySession(session->spdy_session_pool(), spdy_session_key_b));
[email protected]483fa202013-05-14 01:07:0314629
14630 HostPortPair host_port_pair_a1("www.a.com", 80);
[email protected]e6d017652013-05-17 18:01:4014631 SpdySessionKey spdy_session_key_a1(
[email protected]314b03992014-04-01 01:28:5314632 host_port_pair_a1, ProxyServer::Direct(), PRIVACY_MODE_DISABLED);
[email protected]483fa202013-05-14 01:07:0314633 EXPECT_FALSE(
[email protected]41d64e82013-07-03 22:44:2614634 HasSpdySession(session->spdy_session_pool(), spdy_session_key_a1));
[email protected]483fa202013-05-14 01:07:0314635 HttpRequestInfo request3;
14636 request3.method = "GET";
14637 request3.url = GURL("http://www.a.com/");
14638 request3.load_flags = 0;
[email protected]90499482013-06-01 00:39:5014639 trans.reset(new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]483fa202013-05-14 01:07:0314640
tfarina42834112016-09-22 13:38:2014641 rv = trans->Start(&request3, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0114642 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
14643 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]483fa202013-05-14 01:07:0314644
14645 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5214646 ASSERT_TRUE(response);
14647 ASSERT_TRUE(response->headers);
[email protected]483fa202013-05-14 01:07:0314648 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
14649 EXPECT_FALSE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5214650 EXPECT_FALSE(response->was_alpn_negotiated);
robpercival214763f2016-07-01 23:27:0114651 ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
[email protected]483fa202013-05-14 01:07:0314652 EXPECT_EQ("hello!", response_data);
14653 EXPECT_FALSE(
[email protected]41d64e82013-07-03 22:44:2614654 HasSpdySession(session->spdy_session_pool(), spdy_session_key_a));
[email protected]483fa202013-05-14 01:07:0314655 EXPECT_FALSE(
[email protected]41d64e82013-07-03 22:44:2614656 HasSpdySession(session->spdy_session_pool(), spdy_session_key_b));
[email protected]483fa202013-05-14 01:07:0314657}
14658
bncd16676a2016-07-20 16:23:0114659TEST_F(HttpNetworkTransactionTest, HttpSyncConnectError) {
[email protected]79e1fd62013-06-20 06:50:0414660 HttpRequestInfo request;
14661 request.method = "GET";
bncce36dca22015-04-21 22:11:2314662 request.url = GURL("http://www.example.org/");
[email protected]79e1fd62013-06-20 06:50:0414663
danakj1fd259a02016-04-16 03:17:0914664 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1614665 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]79e1fd62013-06-20 06:50:0414666
ttuttled9dbc652015-09-29 20:00:5914667 MockConnect mock_connect(SYNCHRONOUS, ERR_NAME_NOT_RESOLVED);
[email protected]79e1fd62013-06-20 06:50:0414668 StaticSocketDataProvider data;
14669 data.set_connect_data(mock_connect);
14670 session_deps_.socket_factory->AddSocketDataProvider(&data);
14671
14672 TestCompletionCallback callback;
14673
tfarina42834112016-09-22 13:38:2014674 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0114675 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]79e1fd62013-06-20 06:50:0414676
14677 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0114678 EXPECT_THAT(rv, IsError(ERR_NAME_NOT_RESOLVED));
[email protected]79e1fd62013-06-20 06:50:0414679
[email protected]79e1fd62013-06-20 06:50:0414680 // We don't care whether this succeeds or fails, but it shouldn't crash.
14681 HttpRequestHeaders request_headers;
bnc691fda62016-08-12 00:43:1614682 trans.GetFullRequestHeaders(&request_headers);
ttuttle1f2d7e92015-04-28 16:17:4714683
14684 ConnectionAttempts attempts;
bnc691fda62016-08-12 00:43:1614685 trans.GetConnectionAttempts(&attempts);
ttuttle1f2d7e92015-04-28 16:17:4714686 ASSERT_EQ(1u, attempts.size());
robpercival214763f2016-07-01 23:27:0114687 EXPECT_THAT(attempts[0].result, IsError(ERR_NAME_NOT_RESOLVED));
ttuttled9dbc652015-09-29 20:00:5914688
14689 IPEndPoint endpoint;
bnc691fda62016-08-12 00:43:1614690 EXPECT_FALSE(trans.GetRemoteEndpoint(&endpoint));
ttuttled9dbc652015-09-29 20:00:5914691 EXPECT_TRUE(endpoint.address().empty());
[email protected]79e1fd62013-06-20 06:50:0414692}
14693
bncd16676a2016-07-20 16:23:0114694TEST_F(HttpNetworkTransactionTest, HttpAsyncConnectError) {
[email protected]79e1fd62013-06-20 06:50:0414695 HttpRequestInfo request;
14696 request.method = "GET";
bncce36dca22015-04-21 22:11:2314697 request.url = GURL("http://www.example.org/");
[email protected]79e1fd62013-06-20 06:50:0414698
danakj1fd259a02016-04-16 03:17:0914699 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1614700 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]79e1fd62013-06-20 06:50:0414701
ttuttled9dbc652015-09-29 20:00:5914702 MockConnect mock_connect(ASYNC, ERR_NAME_NOT_RESOLVED);
[email protected]79e1fd62013-06-20 06:50:0414703 StaticSocketDataProvider data;
14704 data.set_connect_data(mock_connect);
14705 session_deps_.socket_factory->AddSocketDataProvider(&data);
14706
14707 TestCompletionCallback callback;
14708
tfarina42834112016-09-22 13:38:2014709 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0114710 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]79e1fd62013-06-20 06:50:0414711
14712 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0114713 EXPECT_THAT(rv, IsError(ERR_NAME_NOT_RESOLVED));
[email protected]79e1fd62013-06-20 06:50:0414714
[email protected]79e1fd62013-06-20 06:50:0414715 // We don't care whether this succeeds or fails, but it shouldn't crash.
14716 HttpRequestHeaders request_headers;
bnc691fda62016-08-12 00:43:1614717 trans.GetFullRequestHeaders(&request_headers);
ttuttle1f2d7e92015-04-28 16:17:4714718
14719 ConnectionAttempts attempts;
bnc691fda62016-08-12 00:43:1614720 trans.GetConnectionAttempts(&attempts);
ttuttle1f2d7e92015-04-28 16:17:4714721 ASSERT_EQ(1u, attempts.size());
robpercival214763f2016-07-01 23:27:0114722 EXPECT_THAT(attempts[0].result, IsError(ERR_NAME_NOT_RESOLVED));
ttuttled9dbc652015-09-29 20:00:5914723
14724 IPEndPoint endpoint;
bnc691fda62016-08-12 00:43:1614725 EXPECT_FALSE(trans.GetRemoteEndpoint(&endpoint));
ttuttled9dbc652015-09-29 20:00:5914726 EXPECT_TRUE(endpoint.address().empty());
[email protected]79e1fd62013-06-20 06:50:0414727}
14728
bncd16676a2016-07-20 16:23:0114729TEST_F(HttpNetworkTransactionTest, HttpSyncWriteError) {
[email protected]79e1fd62013-06-20 06:50:0414730 HttpRequestInfo request;
14731 request.method = "GET";
bncce36dca22015-04-21 22:11:2314732 request.url = GURL("http://www.example.org/");
[email protected]79e1fd62013-06-20 06:50:0414733
danakj1fd259a02016-04-16 03:17:0914734 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1614735 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]79e1fd62013-06-20 06:50:0414736
14737 MockWrite data_writes[] = {
14738 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
14739 };
14740 MockRead data_reads[] = {
14741 MockRead(SYNCHRONOUS, ERR_UNEXPECTED), // Should not be reached.
14742 };
14743
14744 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
14745 data_writes, arraysize(data_writes));
14746 session_deps_.socket_factory->AddSocketDataProvider(&data);
14747
14748 TestCompletionCallback callback;
14749
tfarina42834112016-09-22 13:38:2014750 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0114751 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]79e1fd62013-06-20 06:50:0414752
14753 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0114754 EXPECT_THAT(rv, IsError(ERR_CONNECTION_RESET));
[email protected]79e1fd62013-06-20 06:50:0414755
[email protected]79e1fd62013-06-20 06:50:0414756 HttpRequestHeaders request_headers;
bnc691fda62016-08-12 00:43:1614757 EXPECT_TRUE(trans.GetFullRequestHeaders(&request_headers));
[email protected]79e1fd62013-06-20 06:50:0414758 EXPECT_TRUE(request_headers.HasHeader("Host"));
14759}
14760
bncd16676a2016-07-20 16:23:0114761TEST_F(HttpNetworkTransactionTest, HttpAsyncWriteError) {
[email protected]79e1fd62013-06-20 06:50:0414762 HttpRequestInfo request;
14763 request.method = "GET";
bncce36dca22015-04-21 22:11:2314764 request.url = GURL("http://www.example.org/");
[email protected]79e1fd62013-06-20 06:50:0414765
danakj1fd259a02016-04-16 03:17:0914766 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1614767 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]79e1fd62013-06-20 06:50:0414768
14769 MockWrite data_writes[] = {
14770 MockWrite(ASYNC, ERR_CONNECTION_RESET),
14771 };
14772 MockRead data_reads[] = {
14773 MockRead(SYNCHRONOUS, ERR_UNEXPECTED), // Should not be reached.
14774 };
14775
14776 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
14777 data_writes, arraysize(data_writes));
14778 session_deps_.socket_factory->AddSocketDataProvider(&data);
14779
14780 TestCompletionCallback callback;
14781
tfarina42834112016-09-22 13:38:2014782 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0114783 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]79e1fd62013-06-20 06:50:0414784
14785 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0114786 EXPECT_THAT(rv, IsError(ERR_CONNECTION_RESET));
[email protected]79e1fd62013-06-20 06:50:0414787
[email protected]79e1fd62013-06-20 06:50:0414788 HttpRequestHeaders request_headers;
bnc691fda62016-08-12 00:43:1614789 EXPECT_TRUE(trans.GetFullRequestHeaders(&request_headers));
[email protected]79e1fd62013-06-20 06:50:0414790 EXPECT_TRUE(request_headers.HasHeader("Host"));
14791}
14792
bncd16676a2016-07-20 16:23:0114793TEST_F(HttpNetworkTransactionTest, HttpSyncReadError) {
[email protected]79e1fd62013-06-20 06:50:0414794 HttpRequestInfo request;
14795 request.method = "GET";
bncce36dca22015-04-21 22:11:2314796 request.url = GURL("http://www.example.org/");
[email protected]79e1fd62013-06-20 06:50:0414797
danakj1fd259a02016-04-16 03:17:0914798 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1614799 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]79e1fd62013-06-20 06:50:0414800
14801 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:2314802 MockWrite(
14803 "GET / HTTP/1.1\r\n"
14804 "Host: www.example.org\r\n"
14805 "Connection: keep-alive\r\n\r\n"),
[email protected]79e1fd62013-06-20 06:50:0414806 };
14807 MockRead data_reads[] = {
14808 MockRead(SYNCHRONOUS, ERR_CONNECTION_RESET),
14809 };
14810
14811 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
14812 data_writes, arraysize(data_writes));
14813 session_deps_.socket_factory->AddSocketDataProvider(&data);
14814
14815 TestCompletionCallback callback;
14816
tfarina42834112016-09-22 13:38:2014817 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0114818 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]79e1fd62013-06-20 06:50:0414819
14820 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0114821 EXPECT_THAT(rv, IsError(ERR_CONNECTION_RESET));
[email protected]79e1fd62013-06-20 06:50:0414822
[email protected]79e1fd62013-06-20 06:50:0414823 HttpRequestHeaders request_headers;
bnc691fda62016-08-12 00:43:1614824 EXPECT_TRUE(trans.GetFullRequestHeaders(&request_headers));
[email protected]79e1fd62013-06-20 06:50:0414825 EXPECT_TRUE(request_headers.HasHeader("Host"));
14826}
14827
bncd16676a2016-07-20 16:23:0114828TEST_F(HttpNetworkTransactionTest, HttpAsyncReadError) {
[email protected]79e1fd62013-06-20 06:50:0414829 HttpRequestInfo request;
14830 request.method = "GET";
bncce36dca22015-04-21 22:11:2314831 request.url = GURL("http://www.example.org/");
[email protected]79e1fd62013-06-20 06:50:0414832
danakj1fd259a02016-04-16 03:17:0914833 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1614834 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]79e1fd62013-06-20 06:50:0414835
14836 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:2314837 MockWrite(
14838 "GET / HTTP/1.1\r\n"
14839 "Host: www.example.org\r\n"
14840 "Connection: keep-alive\r\n\r\n"),
[email protected]79e1fd62013-06-20 06:50:0414841 };
14842 MockRead data_reads[] = {
14843 MockRead(ASYNC, ERR_CONNECTION_RESET),
14844 };
14845
14846 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
14847 data_writes, arraysize(data_writes));
14848 session_deps_.socket_factory->AddSocketDataProvider(&data);
14849
14850 TestCompletionCallback callback;
14851
tfarina42834112016-09-22 13:38:2014852 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0114853 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]79e1fd62013-06-20 06:50:0414854
14855 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0114856 EXPECT_THAT(rv, IsError(ERR_CONNECTION_RESET));
[email protected]79e1fd62013-06-20 06:50:0414857
[email protected]79e1fd62013-06-20 06:50:0414858 HttpRequestHeaders request_headers;
bnc691fda62016-08-12 00:43:1614859 EXPECT_TRUE(trans.GetFullRequestHeaders(&request_headers));
[email protected]79e1fd62013-06-20 06:50:0414860 EXPECT_TRUE(request_headers.HasHeader("Host"));
14861}
14862
bncd16676a2016-07-20 16:23:0114863TEST_F(HttpNetworkTransactionTest, GetFullRequestHeadersIncludesExtraHeader) {
[email protected]79e1fd62013-06-20 06:50:0414864 HttpRequestInfo request;
14865 request.method = "GET";
bncce36dca22015-04-21 22:11:2314866 request.url = GURL("http://www.example.org/");
[email protected]79e1fd62013-06-20 06:50:0414867 request.extra_headers.SetHeader("X-Foo", "bar");
14868
danakj1fd259a02016-04-16 03:17:0914869 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1614870 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]79e1fd62013-06-20 06:50:0414871
14872 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:2314873 MockWrite(
14874 "GET / HTTP/1.1\r\n"
14875 "Host: www.example.org\r\n"
14876 "Connection: keep-alive\r\n"
14877 "X-Foo: bar\r\n\r\n"),
[email protected]79e1fd62013-06-20 06:50:0414878 };
14879 MockRead data_reads[] = {
14880 MockRead("HTTP/1.1 200 OK\r\n"
14881 "Content-Length: 5\r\n\r\n"
14882 "hello"),
14883 MockRead(ASYNC, ERR_UNEXPECTED),
14884 };
14885
14886 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
14887 data_writes, arraysize(data_writes));
14888 session_deps_.socket_factory->AddSocketDataProvider(&data);
14889
14890 TestCompletionCallback callback;
14891
tfarina42834112016-09-22 13:38:2014892 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0114893 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]79e1fd62013-06-20 06:50:0414894
14895 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0114896 EXPECT_THAT(rv, IsOk());
[email protected]79e1fd62013-06-20 06:50:0414897
14898 HttpRequestHeaders request_headers;
bnc691fda62016-08-12 00:43:1614899 EXPECT_TRUE(trans.GetFullRequestHeaders(&request_headers));
[email protected]79e1fd62013-06-20 06:50:0414900 std::string foo;
14901 EXPECT_TRUE(request_headers.GetHeader("X-Foo", &foo));
14902 EXPECT_EQ("bar", foo);
14903}
14904
[email protected]bf828982013-08-14 18:01:4714905namespace {
14906
yhiranoa7e05bb2014-11-06 05:40:3914907// Fake HttpStream that simply records calls to SetPriority().
14908class FakeStream : public HttpStream,
[email protected]e86839fd2013-08-14 18:29:0314909 public base::SupportsWeakPtr<FakeStream> {
14910 public:
14911 explicit FakeStream(RequestPriority priority) : priority_(priority) {}
dchengb03027d2014-10-21 12:00:2014912 ~FakeStream() override {}
[email protected]e86839fd2013-08-14 18:29:0314913
14914 RequestPriority priority() const { return priority_; }
14915
dchengb03027d2014-10-21 12:00:2014916 int InitializeStream(const HttpRequestInfo* request_info,
14917 RequestPriority priority,
tfarina42834112016-09-22 13:38:2014918 const NetLogWithSource& net_log,
dchengb03027d2014-10-21 12:00:2014919 const CompletionCallback& callback) override {
[email protected]e86839fd2013-08-14 18:29:0314920 return ERR_IO_PENDING;
14921 }
14922
dchengb03027d2014-10-21 12:00:2014923 int SendRequest(const HttpRequestHeaders& request_headers,
14924 HttpResponseInfo* response,
14925 const CompletionCallback& callback) override {
[email protected]e86839fd2013-08-14 18:29:0314926 ADD_FAILURE();
14927 return ERR_UNEXPECTED;
14928 }
14929
dchengb03027d2014-10-21 12:00:2014930 int ReadResponseHeaders(const CompletionCallback& callback) override {
[email protected]e86839fd2013-08-14 18:29:0314931 ADD_FAILURE();
14932 return ERR_UNEXPECTED;
14933 }
14934
dchengb03027d2014-10-21 12:00:2014935 int ReadResponseBody(IOBuffer* buf,
14936 int buf_len,
14937 const CompletionCallback& callback) override {
[email protected]e86839fd2013-08-14 18:29:0314938 ADD_FAILURE();
14939 return ERR_UNEXPECTED;
14940 }
14941
dchengb03027d2014-10-21 12:00:2014942 void Close(bool not_reusable) override {}
[email protected]e86839fd2013-08-14 18:29:0314943
dchengb03027d2014-10-21 12:00:2014944 bool IsResponseBodyComplete() const override {
[email protected]e86839fd2013-08-14 18:29:0314945 ADD_FAILURE();
14946 return false;
14947 }
14948
dchengb03027d2014-10-21 12:00:2014949 bool IsConnectionReused() const override {
[email protected]e86839fd2013-08-14 18:29:0314950 ADD_FAILURE();
14951 return false;
14952 }
14953
dchengb03027d2014-10-21 12:00:2014954 void SetConnectionReused() override { ADD_FAILURE(); }
[email protected]e86839fd2013-08-14 18:29:0314955
mmenkebd84c392015-09-02 14:12:3414956 bool CanReuseConnection() const override { return false; }
[email protected]e86839fd2013-08-14 18:29:0314957
sclittle4de1bab92015-09-22 21:28:2414958 int64_t GetTotalReceivedBytes() const override {
[email protected]bc92bc972013-12-13 08:32:5914959 ADD_FAILURE();
14960 return 0;
14961 }
14962
sclittlebe1ccf62015-09-02 19:40:3614963 int64_t GetTotalSentBytes() const override {
14964 ADD_FAILURE();
14965 return 0;
14966 }
14967
dchengb03027d2014-10-21 12:00:2014968 bool GetLoadTimingInfo(LoadTimingInfo* load_timing_info) const override {
[email protected]e86839fd2013-08-14 18:29:0314969 ADD_FAILURE();
14970 return false;
14971 }
14972
rchcd379012017-04-12 21:53:3214973 bool GetAlternativeService(
14974 AlternativeService* alternative_service) const override {
14975 ADD_FAILURE();
14976 return false;
14977 }
14978
dchengb03027d2014-10-21 12:00:2014979 void GetSSLInfo(SSLInfo* ssl_info) override { ADD_FAILURE(); }
14980
14981 void GetSSLCertRequestInfo(SSLCertRequestInfo* cert_request_info) override {
[email protected]e86839fd2013-08-14 18:29:0314982 ADD_FAILURE();
14983 }
14984
ttuttled9dbc652015-09-29 20:00:5914985 bool GetRemoteEndpoint(IPEndPoint* endpoint) override { return false; }
14986
nharper78e6d2b2016-09-21 05:42:3514987 Error GetTokenBindingSignature(crypto::ECPrivateKey* key,
14988 TokenBindingType tb_type,
14989 std::vector<uint8_t>* out) override {
nharperb7441ef2016-01-25 23:54:1414990 ADD_FAILURE();
14991 return ERR_NOT_IMPLEMENTED;
14992 }
14993
dchengb03027d2014-10-21 12:00:2014994 void Drain(HttpNetworkSession* session) override { ADD_FAILURE(); }
[email protected]e86839fd2013-08-14 18:29:0314995
zhongyica364fbb2015-12-12 03:39:1214996 void PopulateNetErrorDetails(NetErrorDetails* details) override { return; }
14997
dchengb03027d2014-10-21 12:00:2014998 void SetPriority(RequestPriority priority) override { priority_ = priority; }
[email protected]e86839fd2013-08-14 18:29:0314999
yhiranoa7e05bb2014-11-06 05:40:3915000 HttpStream* RenewStreamForAuth() override { return NULL; }
15001
[email protected]e86839fd2013-08-14 18:29:0315002 private:
15003 RequestPriority priority_;
15004
15005 DISALLOW_COPY_AND_ASSIGN(FakeStream);
15006};
15007
15008// Fake HttpStreamRequest that simply records calls to SetPriority()
15009// and vends FakeStreams with its current priority.
[email protected]bf828982013-08-14 18:01:4715010class FakeStreamRequest : public HttpStreamRequest,
15011 public base::SupportsWeakPtr<FakeStreamRequest> {
15012 public:
[email protected]e86839fd2013-08-14 18:29:0315013 FakeStreamRequest(RequestPriority priority,
15014 HttpStreamRequest::Delegate* delegate)
15015 : priority_(priority),
[email protected]831e4a32013-11-14 02:14:4415016 delegate_(delegate),
15017 websocket_stream_create_helper_(NULL) {}
15018
15019 FakeStreamRequest(RequestPriority priority,
15020 HttpStreamRequest::Delegate* delegate,
15021 WebSocketHandshakeStreamBase::CreateHelper* create_helper)
15022 : priority_(priority),
15023 delegate_(delegate),
15024 websocket_stream_create_helper_(create_helper) {}
[email protected]e86839fd2013-08-14 18:29:0315025
dchengb03027d2014-10-21 12:00:2015026 ~FakeStreamRequest() override {}
[email protected]bf828982013-08-14 18:01:4715027
15028 RequestPriority priority() const { return priority_; }
15029
[email protected]831e4a32013-11-14 02:14:4415030 const WebSocketHandshakeStreamBase::CreateHelper*
15031 websocket_stream_create_helper() const {
15032 return websocket_stream_create_helper_;
15033 }
15034
[email protected]e86839fd2013-08-14 18:29:0315035 // Create a new FakeStream and pass it to the request's
15036 // delegate. Returns a weak pointer to the FakeStream.
15037 base::WeakPtr<FakeStream> FinishStreamRequest() {
15038 FakeStream* fake_stream = new FakeStream(priority_);
15039 // Do this before calling OnStreamReady() as OnStreamReady() may
15040 // immediately delete |fake_stream|.
15041 base::WeakPtr<FakeStream> weak_stream = fake_stream->AsWeakPtr();
15042 delegate_->OnStreamReady(SSLConfig(), ProxyInfo(), fake_stream);
15043 return weak_stream;
15044 }
15045
asanka681f02d2017-02-22 17:06:3915046 int RestartTunnelWithProxyAuth() override {
[email protected]bf828982013-08-14 18:01:4715047 ADD_FAILURE();
15048 return ERR_UNEXPECTED;
15049 }
15050
dchengb03027d2014-10-21 12:00:2015051 LoadState GetLoadState() const override {
[email protected]bf828982013-08-14 18:01:4715052 ADD_FAILURE();
15053 return LoadState();
15054 }
15055
dchengb03027d2014-10-21 12:00:2015056 void SetPriority(RequestPriority priority) override { priority_ = priority; }
[email protected]bf828982013-08-14 18:01:4715057
bnc94c92842016-09-21 15:22:5215058 bool was_alpn_negotiated() const override { return false; }
[email protected]bf828982013-08-14 18:01:4715059
bnc6227b26e2016-08-12 02:00:4315060 NextProto negotiated_protocol() const override { return kProtoUnknown; }
[email protected]bf828982013-08-14 18:01:4715061
dchengb03027d2014-10-21 12:00:2015062 bool using_spdy() const override { return false; }
[email protected]bf828982013-08-14 18:01:4715063
ttuttle1f2d7e92015-04-28 16:17:4715064 const ConnectionAttempts& connection_attempts() const override {
15065 static ConnectionAttempts no_attempts;
15066 return no_attempts;
15067 }
15068
[email protected]bf828982013-08-14 18:01:4715069 private:
15070 RequestPriority priority_;
[email protected]e86839fd2013-08-14 18:29:0315071 HttpStreamRequest::Delegate* const delegate_;
[email protected]831e4a32013-11-14 02:14:4415072 WebSocketHandshakeStreamBase::CreateHelper* websocket_stream_create_helper_;
[email protected]bf828982013-08-14 18:01:4715073
15074 DISALLOW_COPY_AND_ASSIGN(FakeStreamRequest);
15075};
15076
15077// Fake HttpStreamFactory that vends FakeStreamRequests.
15078class FakeStreamFactory : public HttpStreamFactory {
15079 public:
15080 FakeStreamFactory() {}
dchengb03027d2014-10-21 12:00:2015081 ~FakeStreamFactory() override {}
[email protected]bf828982013-08-14 18:01:4715082
15083 // Returns a WeakPtr<> to the last HttpStreamRequest returned by
15084 // RequestStream() (which may be NULL if it was destroyed already).
15085 base::WeakPtr<FakeStreamRequest> last_stream_request() {
15086 return last_stream_request_;
15087 }
15088
dchengb03027d2014-10-21 12:00:2015089 HttpStreamRequest* RequestStream(const HttpRequestInfo& info,
15090 RequestPriority priority,
15091 const SSLConfig& server_ssl_config,
15092 const SSLConfig& proxy_ssl_config,
15093 HttpStreamRequest::Delegate* delegate,
bnc8016c1f2017-03-31 02:11:2915094 bool enable_ip_based_pooling,
bncaccd4962017-04-06 21:00:2615095 bool enable_alternative_services,
tfarina42834112016-09-22 13:38:2015096 const NetLogWithSource& net_log) override {
[email protected]e86839fd2013-08-14 18:29:0315097 FakeStreamRequest* fake_request = new FakeStreamRequest(priority, delegate);
[email protected]bf828982013-08-14 18:01:4715098 last_stream_request_ = fake_request->AsWeakPtr();
15099 return fake_request;
15100 }
15101
xunjieli5749218c2016-03-22 16:43:0615102 HttpStreamRequest* RequestBidirectionalStreamImpl(
xunjieli11834f02015-12-22 04:27:0815103 const HttpRequestInfo& info,
15104 RequestPriority priority,
15105 const SSLConfig& server_ssl_config,
15106 const SSLConfig& proxy_ssl_config,
15107 HttpStreamRequest::Delegate* delegate,
bnc8016c1f2017-03-31 02:11:2915108 bool enable_ip_based_pooling,
bncaccd4962017-04-06 21:00:2615109 bool enable_alternative_services,
tfarina42834112016-09-22 13:38:2015110 const NetLogWithSource& net_log) override {
xunjieli11834f02015-12-22 04:27:0815111 NOTREACHED();
15112 return nullptr;
15113 }
15114
dchengb03027d2014-10-21 12:00:2015115 HttpStreamRequest* RequestWebSocketHandshakeStream(
[email protected]bf828982013-08-14 18:01:4715116 const HttpRequestInfo& info,
15117 RequestPriority priority,
15118 const SSLConfig& server_ssl_config,
15119 const SSLConfig& proxy_ssl_config,
15120 HttpStreamRequest::Delegate* delegate,
[email protected]467086b2013-11-12 08:19:4615121 WebSocketHandshakeStreamBase::CreateHelper* create_helper,
bnc8016c1f2017-03-31 02:11:2915122 bool enable_ip_based_pooling,
bncaccd4962017-04-06 21:00:2615123 bool enable_alternative_services,
tfarina42834112016-09-22 13:38:2015124 const NetLogWithSource& net_log) override {
[email protected]831e4a32013-11-14 02:14:4415125 FakeStreamRequest* fake_request =
15126 new FakeStreamRequest(priority, delegate, create_helper);
15127 last_stream_request_ = fake_request->AsWeakPtr();
15128 return fake_request;
[email protected]bf828982013-08-14 18:01:4715129 }
15130
dchengb03027d2014-10-21 12:00:2015131 void PreconnectStreams(int num_streams,
nharper8cdb0fb2016-04-22 21:34:5915132 const HttpRequestInfo& info) override {
[email protected]bf828982013-08-14 18:01:4715133 ADD_FAILURE();
15134 }
15135
dchengb03027d2014-10-21 12:00:2015136 const HostMappingRules* GetHostMappingRules() const override {
[email protected]bf828982013-08-14 18:01:4715137 ADD_FAILURE();
15138 return NULL;
15139 }
15140
xunjielif5267de2017-01-20 21:18:5715141 void DumpMemoryStats(base::trace_event::ProcessMemoryDump* pmd,
15142 const std::string& parent_absolute_name) const override {
15143 ADD_FAILURE();
15144 }
15145
[email protected]bf828982013-08-14 18:01:4715146 private:
15147 base::WeakPtr<FakeStreamRequest> last_stream_request_;
15148
15149 DISALLOW_COPY_AND_ASSIGN(FakeStreamFactory);
15150};
15151
Adam Rice425cf122015-01-19 06:18:2415152// TODO(ricea): Maybe unify this with the one in
15153// url_request_http_job_unittest.cc ?
15154class FakeWebSocketBasicHandshakeStream : public WebSocketHandshakeStreamBase {
15155 public:
danakj1fd259a02016-04-16 03:17:0915156 FakeWebSocketBasicHandshakeStream(
15157 std::unique_ptr<ClientSocketHandle> connection,
15158 bool using_proxy)
mmenkea7da6da2016-09-01 21:56:5215159 : state_(std::move(connection), using_proxy, false) {}
Adam Rice425cf122015-01-19 06:18:2415160
15161 // Fake implementation of HttpStreamBase methods.
15162 // This ends up being quite "real" because this object has to really send data
15163 // on the mock socket. It might be easier to use the real implementation, but
15164 // the fact that the WebSocket code is not compiled on iOS makes that
15165 // difficult.
15166 int InitializeStream(const HttpRequestInfo* request_info,
15167 RequestPriority priority,
tfarina42834112016-09-22 13:38:2015168 const NetLogWithSource& net_log,
Adam Rice425cf122015-01-19 06:18:2415169 const CompletionCallback& callback) override {
15170 state_.Initialize(request_info, priority, net_log, callback);
15171 return OK;
15172 }
15173
15174 int SendRequest(const HttpRequestHeaders& request_headers,
15175 HttpResponseInfo* response,
15176 const CompletionCallback& callback) override {
15177 return parser()->SendRequest(state_.GenerateRequestLine(), request_headers,
15178 response, callback);
15179 }
15180
15181 int ReadResponseHeaders(const CompletionCallback& callback) override {
15182 return parser()->ReadResponseHeaders(callback);
15183 }
15184
15185 int ReadResponseBody(IOBuffer* buf,
15186 int buf_len,
15187 const CompletionCallback& callback) override {
15188 NOTREACHED();
15189 return ERR_IO_PENDING;
15190 }
15191
15192 void Close(bool not_reusable) override {
15193 if (parser())
15194 parser()->Close(true);
15195 }
15196
15197 bool IsResponseBodyComplete() const override {
15198 NOTREACHED();
15199 return false;
15200 }
15201
Adam Rice425cf122015-01-19 06:18:2415202 bool IsConnectionReused() const override {
15203 NOTREACHED();
15204 return false;
15205 }
15206 void SetConnectionReused() override { NOTREACHED(); }
15207
mmenkebd84c392015-09-02 14:12:3415208 bool CanReuseConnection() const override { return false; }
Adam Rice425cf122015-01-19 06:18:2415209
sclittle4de1bab92015-09-22 21:28:2415210 int64_t GetTotalReceivedBytes() const override {
Adam Rice425cf122015-01-19 06:18:2415211 NOTREACHED();
15212 return 0;
15213 }
15214
sclittlebe1ccf62015-09-02 19:40:3615215 int64_t GetTotalSentBytes() const override {
15216 NOTREACHED();
15217 return 0;
15218 }
15219
Adam Rice425cf122015-01-19 06:18:2415220 bool GetLoadTimingInfo(LoadTimingInfo* load_timing_info) const override {
15221 NOTREACHED();
15222 return false;
15223 }
15224
rchcd379012017-04-12 21:53:3215225 bool GetAlternativeService(
15226 AlternativeService* alternative_service) const override {
15227 ADD_FAILURE();
15228 return false;
15229 }
15230
Adam Ricecb76ac62015-02-20 05:33:2515231 void GetSSLInfo(SSLInfo* ssl_info) override {}
Adam Rice425cf122015-01-19 06:18:2415232
15233 void GetSSLCertRequestInfo(SSLCertRequestInfo* cert_request_info) override {
15234 NOTREACHED();
15235 }
15236
ttuttled9dbc652015-09-29 20:00:5915237 bool GetRemoteEndpoint(IPEndPoint* endpoint) override { return false; }
15238
nharper78e6d2b2016-09-21 05:42:3515239 Error GetTokenBindingSignature(crypto::ECPrivateKey* key,
15240 TokenBindingType tb_type,
15241 std::vector<uint8_t>* out) override {
nharperb7441ef2016-01-25 23:54:1415242 ADD_FAILURE();
15243 return ERR_NOT_IMPLEMENTED;
15244 }
15245
Adam Rice425cf122015-01-19 06:18:2415246 void Drain(HttpNetworkSession* session) override { NOTREACHED(); }
15247
zhongyica364fbb2015-12-12 03:39:1215248 void PopulateNetErrorDetails(NetErrorDetails* details) override { return; }
15249
Adam Rice425cf122015-01-19 06:18:2415250 void SetPriority(RequestPriority priority) override { NOTREACHED(); }
15251
Adam Rice425cf122015-01-19 06:18:2415252 HttpStream* RenewStreamForAuth() override {
15253 NOTREACHED();
15254 return nullptr;
15255 }
15256
15257 // Fake implementation of WebSocketHandshakeStreamBase method(s)
danakj1fd259a02016-04-16 03:17:0915258 std::unique_ptr<WebSocketStream> Upgrade() override {
Adam Rice425cf122015-01-19 06:18:2415259 NOTREACHED();
danakj1fd259a02016-04-16 03:17:0915260 return std::unique_ptr<WebSocketStream>();
Adam Rice425cf122015-01-19 06:18:2415261 }
15262
15263 private:
15264 HttpStreamParser* parser() const { return state_.parser(); }
15265 HttpBasicState state_;
15266
15267 DISALLOW_COPY_AND_ASSIGN(FakeWebSocketBasicHandshakeStream);
15268};
15269
[email protected]831e4a32013-11-14 02:14:4415270// TODO(yhirano): Split this class out into a net/websockets file, if it is
15271// worth doing.
15272class FakeWebSocketStreamCreateHelper :
15273 public WebSocketHandshakeStreamBase::CreateHelper {
15274 public:
dchengb03027d2014-10-21 12:00:2015275 WebSocketHandshakeStreamBase* CreateBasicStream(
danakj1fd259a02016-04-16 03:17:0915276 std::unique_ptr<ClientSocketHandle> connection,
mostynbba063d6032014-10-09 11:01:1315277 bool using_proxy) override {
dchengc7eeda422015-12-26 03:56:4815278 return new FakeWebSocketBasicHandshakeStream(std::move(connection),
Adam Rice425cf122015-01-19 06:18:2415279 using_proxy);
[email protected]831e4a32013-11-14 02:14:4415280 }
15281
dchengb03027d2014-10-21 12:00:2015282 WebSocketHandshakeStreamBase* CreateSpdyStream(
[email protected]831e4a32013-11-14 02:14:4415283 const base::WeakPtr<SpdySession>& session,
mostynbba063d6032014-10-09 11:01:1315284 bool use_relative_url) override {
[email protected]831e4a32013-11-14 02:14:4415285 NOTREACHED();
15286 return NULL;
15287 };
15288
dchengb03027d2014-10-21 12:00:2015289 ~FakeWebSocketStreamCreateHelper() override {}
[email protected]831e4a32013-11-14 02:14:4415290
danakj1fd259a02016-04-16 03:17:0915291 virtual std::unique_ptr<WebSocketStream> Upgrade() {
[email protected]831e4a32013-11-14 02:14:4415292 NOTREACHED();
danakj1fd259a02016-04-16 03:17:0915293 return std::unique_ptr<WebSocketStream>();
[email protected]831e4a32013-11-14 02:14:4415294 }
15295};
15296
[email protected]bf828982013-08-14 18:01:4715297} // namespace
15298
15299// Make sure that HttpNetworkTransaction passes on its priority to its
15300// stream request on start.
bncd16676a2016-07-20 16:23:0115301TEST_F(HttpNetworkTransactionTest, SetStreamRequestPriorityOnStart) {
danakj1fd259a02016-04-16 03:17:0915302 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
mmenkee65e7af2015-10-13 17:16:4215303 HttpNetworkSessionPeer peer(session.get());
[email protected]bf828982013-08-14 18:01:4715304 FakeStreamFactory* fake_factory = new FakeStreamFactory();
danakj1fd259a02016-04-16 03:17:0915305 peer.SetHttpStreamFactory(std::unique_ptr<HttpStreamFactory>(fake_factory));
[email protected]bf828982013-08-14 18:01:4715306
krasinc06a72a2016-12-21 03:42:4615307 HttpRequestInfo request;
dcheng48459ac22014-08-26 00:46:4115308 HttpNetworkTransaction trans(LOW, session.get());
[email protected]bf828982013-08-14 18:01:4715309
wezca1070932016-05-26 20:30:5215310 ASSERT_FALSE(fake_factory->last_stream_request());
[email protected]bf828982013-08-14 18:01:4715311
[email protected]bf828982013-08-14 18:01:4715312 TestCompletionCallback callback;
15313 EXPECT_EQ(ERR_IO_PENDING,
tfarina42834112016-09-22 13:38:2015314 trans.Start(&request, callback.callback(), NetLogWithSource()));
[email protected]bf828982013-08-14 18:01:4715315
15316 base::WeakPtr<FakeStreamRequest> fake_request =
15317 fake_factory->last_stream_request();
wezca1070932016-05-26 20:30:5215318 ASSERT_TRUE(fake_request);
[email protected]bf828982013-08-14 18:01:4715319 EXPECT_EQ(LOW, fake_request->priority());
15320}
15321
15322// Make sure that HttpNetworkTransaction passes on its priority
15323// updates to its stream request.
bncd16676a2016-07-20 16:23:0115324TEST_F(HttpNetworkTransactionTest, SetStreamRequestPriority) {
danakj1fd259a02016-04-16 03:17:0915325 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
mmenkee65e7af2015-10-13 17:16:4215326 HttpNetworkSessionPeer peer(session.get());
[email protected]bf828982013-08-14 18:01:4715327 FakeStreamFactory* fake_factory = new FakeStreamFactory();
danakj1fd259a02016-04-16 03:17:0915328 peer.SetHttpStreamFactory(std::unique_ptr<HttpStreamFactory>(fake_factory));
[email protected]bf828982013-08-14 18:01:4715329
krasinc06a72a2016-12-21 03:42:4615330 HttpRequestInfo request;
dcheng48459ac22014-08-26 00:46:4115331 HttpNetworkTransaction trans(LOW, session.get());
[email protected]bf828982013-08-14 18:01:4715332
[email protected]bf828982013-08-14 18:01:4715333 TestCompletionCallback callback;
15334 EXPECT_EQ(ERR_IO_PENDING,
tfarina42834112016-09-22 13:38:2015335 trans.Start(&request, callback.callback(), NetLogWithSource()));
[email protected]bf828982013-08-14 18:01:4715336
15337 base::WeakPtr<FakeStreamRequest> fake_request =
15338 fake_factory->last_stream_request();
wezca1070932016-05-26 20:30:5215339 ASSERT_TRUE(fake_request);
[email protected]bf828982013-08-14 18:01:4715340 EXPECT_EQ(LOW, fake_request->priority());
15341
15342 trans.SetPriority(LOWEST);
wezca1070932016-05-26 20:30:5215343 ASSERT_TRUE(fake_request);
[email protected]bf828982013-08-14 18:01:4715344 EXPECT_EQ(LOWEST, fake_request->priority());
15345}
15346
[email protected]e86839fd2013-08-14 18:29:0315347// Make sure that HttpNetworkTransaction passes on its priority
15348// updates to its stream.
bncd16676a2016-07-20 16:23:0115349TEST_F(HttpNetworkTransactionTest, SetStreamPriority) {
danakj1fd259a02016-04-16 03:17:0915350 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
mmenkee65e7af2015-10-13 17:16:4215351 HttpNetworkSessionPeer peer(session.get());
[email protected]e86839fd2013-08-14 18:29:0315352 FakeStreamFactory* fake_factory = new FakeStreamFactory();
danakj1fd259a02016-04-16 03:17:0915353 peer.SetHttpStreamFactory(std::unique_ptr<HttpStreamFactory>(fake_factory));
[email protected]e86839fd2013-08-14 18:29:0315354
krasinc06a72a2016-12-21 03:42:4615355 HttpRequestInfo request;
dcheng48459ac22014-08-26 00:46:4115356 HttpNetworkTransaction trans(LOW, session.get());
[email protected]e86839fd2013-08-14 18:29:0315357
[email protected]e86839fd2013-08-14 18:29:0315358 TestCompletionCallback callback;
15359 EXPECT_EQ(ERR_IO_PENDING,
tfarina42834112016-09-22 13:38:2015360 trans.Start(&request, callback.callback(), NetLogWithSource()));
[email protected]e86839fd2013-08-14 18:29:0315361
15362 base::WeakPtr<FakeStreamRequest> fake_request =
15363 fake_factory->last_stream_request();
wezca1070932016-05-26 20:30:5215364 ASSERT_TRUE(fake_request);
[email protected]e86839fd2013-08-14 18:29:0315365 base::WeakPtr<FakeStream> fake_stream = fake_request->FinishStreamRequest();
wezca1070932016-05-26 20:30:5215366 ASSERT_TRUE(fake_stream);
[email protected]e86839fd2013-08-14 18:29:0315367 EXPECT_EQ(LOW, fake_stream->priority());
15368
15369 trans.SetPriority(LOWEST);
15370 EXPECT_EQ(LOWEST, fake_stream->priority());
15371}
15372
bncd16676a2016-07-20 16:23:0115373TEST_F(HttpNetworkTransactionTest, CreateWebSocketHandshakeStream) {
[email protected]831e4a32013-11-14 02:14:4415374 // The same logic needs to be tested for both ws: and wss: schemes, but this
15375 // test is already parameterised on NextProto, so it uses a loop to verify
15376 // that the different schemes work.
bncce36dca22015-04-21 22:11:2315377 std::string test_cases[] = {"ws://www.example.org/",
15378 "wss://www.example.org/"};
[email protected]831e4a32013-11-14 02:14:4415379 for (size_t i = 0; i < arraysize(test_cases); ++i) {
danakj1fd259a02016-04-16 03:17:0915380 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
mmenkee65e7af2015-10-13 17:16:4215381 HttpNetworkSessionPeer peer(session.get());
[email protected]831e4a32013-11-14 02:14:4415382 FakeStreamFactory* fake_factory = new FakeStreamFactory();
15383 FakeWebSocketStreamCreateHelper websocket_stream_create_helper;
[email protected]0191b51c2013-11-18 10:55:2315384 peer.SetHttpStreamFactoryForWebSocket(
danakj1fd259a02016-04-16 03:17:0915385 std::unique_ptr<HttpStreamFactory>(fake_factory));
[email protected]831e4a32013-11-14 02:14:4415386
krasinc06a72a2016-12-21 03:42:4615387 HttpRequestInfo request;
dcheng48459ac22014-08-26 00:46:4115388 HttpNetworkTransaction trans(LOW, session.get());
[email protected]831e4a32013-11-14 02:14:4415389 trans.SetWebSocketHandshakeStreamCreateHelper(
15390 &websocket_stream_create_helper);
15391
[email protected]831e4a32013-11-14 02:14:4415392 TestCompletionCallback callback;
15393 request.method = "GET";
15394 request.url = GURL(test_cases[i]);
15395
15396 EXPECT_EQ(ERR_IO_PENDING,
tfarina42834112016-09-22 13:38:2015397 trans.Start(&request, callback.callback(), NetLogWithSource()));
[email protected]831e4a32013-11-14 02:14:4415398
15399 base::WeakPtr<FakeStreamRequest> fake_request =
15400 fake_factory->last_stream_request();
wezca1070932016-05-26 20:30:5215401 ASSERT_TRUE(fake_request);
[email protected]831e4a32013-11-14 02:14:4415402 EXPECT_EQ(&websocket_stream_create_helper,
15403 fake_request->websocket_stream_create_helper());
15404 }
15405}
15406
[email protected]043b68c82013-08-22 23:41:5215407// Tests that when a used socket is returned to the SSL socket pool, it's closed
15408// if the transport socket pool is stalled on the global socket limit.
bncd16676a2016-07-20 16:23:0115409TEST_F(HttpNetworkTransactionTest, CloseSSLSocketOnIdleForHttpRequest) {
[email protected]043b68c82013-08-22 23:41:5215410 ClientSocketPoolManager::set_max_sockets_per_group(
15411 HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
15412 ClientSocketPoolManager::set_max_sockets_per_pool(
15413 HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
15414
15415 // Set up SSL request.
15416
15417 HttpRequestInfo ssl_request;
15418 ssl_request.method = "GET";
bncce36dca22015-04-21 22:11:2315419 ssl_request.url = GURL("https://www.example.org/");
[email protected]043b68c82013-08-22 23:41:5215420
15421 MockWrite ssl_writes[] = {
bncce36dca22015-04-21 22:11:2315422 MockWrite(
15423 "GET / HTTP/1.1\r\n"
15424 "Host: www.example.org\r\n"
15425 "Connection: keep-alive\r\n\r\n"),
[email protected]043b68c82013-08-22 23:41:5215426 };
15427 MockRead ssl_reads[] = {
15428 MockRead("HTTP/1.1 200 OK\r\n"),
15429 MockRead("Content-Length: 11\r\n\r\n"),
15430 MockRead("hello world"),
15431 MockRead(SYNCHRONOUS, OK),
15432 };
15433 StaticSocketDataProvider ssl_data(ssl_reads, arraysize(ssl_reads),
15434 ssl_writes, arraysize(ssl_writes));
15435 session_deps_.socket_factory->AddSocketDataProvider(&ssl_data);
15436
15437 SSLSocketDataProvider ssl(ASYNC, OK);
15438 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
15439
15440 // Set up HTTP request.
15441
15442 HttpRequestInfo http_request;
15443 http_request.method = "GET";
bncce36dca22015-04-21 22:11:2315444 http_request.url = GURL("http://www.example.org/");
[email protected]043b68c82013-08-22 23:41:5215445
15446 MockWrite http_writes[] = {
bncce36dca22015-04-21 22:11:2315447 MockWrite(
15448 "GET / HTTP/1.1\r\n"
15449 "Host: www.example.org\r\n"
15450 "Connection: keep-alive\r\n\r\n"),
[email protected]043b68c82013-08-22 23:41:5215451 };
15452 MockRead http_reads[] = {
15453 MockRead("HTTP/1.1 200 OK\r\n"),
15454 MockRead("Content-Length: 7\r\n\r\n"),
15455 MockRead("falafel"),
15456 MockRead(SYNCHRONOUS, OK),
15457 };
15458 StaticSocketDataProvider http_data(http_reads, arraysize(http_reads),
15459 http_writes, arraysize(http_writes));
15460 session_deps_.socket_factory->AddSocketDataProvider(&http_data);
15461
danakj1fd259a02016-04-16 03:17:0915462 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]043b68c82013-08-22 23:41:5215463
15464 // Start the SSL request.
15465 TestCompletionCallback ssl_callback;
bnc691fda62016-08-12 00:43:1615466 HttpNetworkTransaction ssl_trans(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:2015467 ASSERT_EQ(ERR_IO_PENDING,
15468 ssl_trans.Start(&ssl_request, ssl_callback.callback(),
15469 NetLogWithSource()));
[email protected]043b68c82013-08-22 23:41:5215470
15471 // Start the HTTP request. Pool should stall.
15472 TestCompletionCallback http_callback;
bnc691fda62016-08-12 00:43:1615473 HttpNetworkTransaction http_trans(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:2015474 ASSERT_EQ(ERR_IO_PENDING,
15475 http_trans.Start(&http_request, http_callback.callback(),
15476 NetLogWithSource()));
dcheng48459ac22014-08-26 00:46:4115477 EXPECT_TRUE(IsTransportSocketPoolStalled(session.get()));
[email protected]043b68c82013-08-22 23:41:5215478
15479 // Wait for response from SSL request.
robpercival214763f2016-07-01 23:27:0115480 ASSERT_THAT(ssl_callback.WaitForResult(), IsOk());
[email protected]043b68c82013-08-22 23:41:5215481 std::string response_data;
bnc691fda62016-08-12 00:43:1615482 ASSERT_THAT(ReadTransaction(&ssl_trans, &response_data), IsOk());
[email protected]043b68c82013-08-22 23:41:5215483 EXPECT_EQ("hello world", response_data);
15484
15485 // The SSL socket should automatically be closed, so the HTTP request can
15486 // start.
dcheng48459ac22014-08-26 00:46:4115487 EXPECT_EQ(0, GetIdleSocketCountInSSLSocketPool(session.get()));
15488 ASSERT_FALSE(IsTransportSocketPoolStalled(session.get()));
[email protected]043b68c82013-08-22 23:41:5215489
15490 // The HTTP request can now complete.
robpercival214763f2016-07-01 23:27:0115491 ASSERT_THAT(http_callback.WaitForResult(), IsOk());
bnc691fda62016-08-12 00:43:1615492 ASSERT_THAT(ReadTransaction(&http_trans, &response_data), IsOk());
[email protected]043b68c82013-08-22 23:41:5215493 EXPECT_EQ("falafel", response_data);
15494
dcheng48459ac22014-08-26 00:46:4115495 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]043b68c82013-08-22 23:41:5215496}
15497
15498// Tests that when a SSL connection is established but there's no corresponding
15499// request that needs it, the new socket is closed if the transport socket pool
15500// is stalled on the global socket limit.
bncd16676a2016-07-20 16:23:0115501TEST_F(HttpNetworkTransactionTest, CloseSSLSocketOnIdleForHttpRequest2) {
[email protected]043b68c82013-08-22 23:41:5215502 ClientSocketPoolManager::set_max_sockets_per_group(
15503 HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
15504 ClientSocketPoolManager::set_max_sockets_per_pool(
15505 HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
15506
15507 // Set up an ssl request.
15508
15509 HttpRequestInfo ssl_request;
15510 ssl_request.method = "GET";
15511 ssl_request.url = GURL("https://www.foopy.com/");
15512
15513 // No data will be sent on the SSL socket.
15514 StaticSocketDataProvider ssl_data;
15515 session_deps_.socket_factory->AddSocketDataProvider(&ssl_data);
15516
15517 SSLSocketDataProvider ssl(ASYNC, OK);
15518 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
15519
15520 // Set up HTTP request.
15521
15522 HttpRequestInfo http_request;
15523 http_request.method = "GET";
bncce36dca22015-04-21 22:11:2315524 http_request.url = GURL("http://www.example.org/");
[email protected]043b68c82013-08-22 23:41:5215525
15526 MockWrite http_writes[] = {
bncce36dca22015-04-21 22:11:2315527 MockWrite(
15528 "GET / HTTP/1.1\r\n"
15529 "Host: www.example.org\r\n"
15530 "Connection: keep-alive\r\n\r\n"),
[email protected]043b68c82013-08-22 23:41:5215531 };
15532 MockRead http_reads[] = {
15533 MockRead("HTTP/1.1 200 OK\r\n"),
15534 MockRead("Content-Length: 7\r\n\r\n"),
15535 MockRead("falafel"),
15536 MockRead(SYNCHRONOUS, OK),
15537 };
15538 StaticSocketDataProvider http_data(http_reads, arraysize(http_reads),
15539 http_writes, arraysize(http_writes));
15540 session_deps_.socket_factory->AddSocketDataProvider(&http_data);
15541
danakj1fd259a02016-04-16 03:17:0915542 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]043b68c82013-08-22 23:41:5215543
15544 // Preconnect an SSL socket. A preconnect is needed because connect jobs are
15545 // cancelled when a normal transaction is cancelled.
ttuttle859dc7a2015-04-23 19:42:2915546 HttpStreamFactory* http_stream_factory = session->http_stream_factory();
nharper8cdb0fb2016-04-22 21:34:5915547 http_stream_factory->PreconnectStreams(1, ssl_request);
dcheng48459ac22014-08-26 00:46:4115548 EXPECT_EQ(0, GetIdleSocketCountInSSLSocketPool(session.get()));
[email protected]043b68c82013-08-22 23:41:5215549
15550 // Start the HTTP request. Pool should stall.
15551 TestCompletionCallback http_callback;
bnc691fda62016-08-12 00:43:1615552 HttpNetworkTransaction http_trans(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:2015553 ASSERT_EQ(ERR_IO_PENDING,
15554 http_trans.Start(&http_request, http_callback.callback(),
15555 NetLogWithSource()));
dcheng48459ac22014-08-26 00:46:4115556 EXPECT_TRUE(IsTransportSocketPoolStalled(session.get()));
[email protected]043b68c82013-08-22 23:41:5215557
15558 // The SSL connection will automatically be closed once the connection is
15559 // established, to let the HTTP request start.
robpercival214763f2016-07-01 23:27:0115560 ASSERT_THAT(http_callback.WaitForResult(), IsOk());
[email protected]043b68c82013-08-22 23:41:5215561 std::string response_data;
bnc691fda62016-08-12 00:43:1615562 ASSERT_THAT(ReadTransaction(&http_trans, &response_data), IsOk());
[email protected]043b68c82013-08-22 23:41:5215563 EXPECT_EQ("falafel", response_data);
15564
dcheng48459ac22014-08-26 00:46:4115565 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]043b68c82013-08-22 23:41:5215566}
15567
bncd16676a2016-07-20 16:23:0115568TEST_F(HttpNetworkTransactionTest, PostReadsErrorResponseAfterReset) {
danakj1fd259a02016-04-16 03:17:0915569 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:2215570 element_readers.push_back(
ricea2deef682016-09-09 08:04:0715571 base::MakeUnique<UploadBytesElementReader>("foo", 3));
olli.raula6df48b2a2015-11-26 07:40:2215572 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]02d74a02014-04-23 18:10:5415573
15574 HttpRequestInfo request;
15575 request.method = "POST";
15576 request.url = GURL("http://www.foo.com/");
15577 request.upload_data_stream = &upload_data_stream;
[email protected]02d74a02014-04-23 18:10:5415578
danakj1fd259a02016-04-16 03:17:0915579 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1615580 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]02d74a02014-04-23 18:10:5415581 // Send headers successfully, but get an error while sending the body.
15582 MockWrite data_writes[] = {
15583 MockWrite("POST / HTTP/1.1\r\n"
15584 "Host: www.foo.com\r\n"
15585 "Connection: keep-alive\r\n"
15586 "Content-Length: 3\r\n\r\n"),
15587 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
15588 };
15589
15590 MockRead data_reads[] = {
15591 MockRead("HTTP/1.0 400 Not OK\r\n\r\n"),
15592 MockRead("hello world"),
15593 MockRead(SYNCHRONOUS, OK),
15594 };
15595 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
15596 arraysize(data_writes));
15597 session_deps_.socket_factory->AddSocketDataProvider(&data);
15598
15599 TestCompletionCallback callback;
15600
tfarina42834112016-09-22 13:38:2015601 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0115602 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]02d74a02014-04-23 18:10:5415603
15604 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0115605 EXPECT_THAT(rv, IsOk());
[email protected]02d74a02014-04-23 18:10:5415606
bnc691fda62016-08-12 00:43:1615607 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5215608 ASSERT_TRUE(response);
[email protected]02d74a02014-04-23 18:10:5415609
wezca1070932016-05-26 20:30:5215610 EXPECT_TRUE(response->headers);
[email protected]02d74a02014-04-23 18:10:5415611 EXPECT_EQ("HTTP/1.0 400 Not OK", response->headers->GetStatusLine());
15612
15613 std::string response_data;
bnc691fda62016-08-12 00:43:1615614 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:0115615 EXPECT_THAT(rv, IsOk());
[email protected]02d74a02014-04-23 18:10:5415616 EXPECT_EQ("hello world", response_data);
15617}
15618
15619// This test makes sure the retry logic doesn't trigger when reading an error
15620// response from a server that rejected a POST with a CONNECTION_RESET.
bncd16676a2016-07-20 16:23:0115621TEST_F(HttpNetworkTransactionTest,
[email protected]02d74a02014-04-23 18:10:5415622 PostReadsErrorResponseAfterResetOnReusedSocket) {
danakj1fd259a02016-04-16 03:17:0915623 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]02d74a02014-04-23 18:10:5415624 MockWrite data_writes[] = {
15625 MockWrite("GET / HTTP/1.1\r\n"
15626 "Host: www.foo.com\r\n"
15627 "Connection: keep-alive\r\n\r\n"),
15628 MockWrite("POST / HTTP/1.1\r\n"
15629 "Host: www.foo.com\r\n"
15630 "Connection: keep-alive\r\n"
15631 "Content-Length: 3\r\n\r\n"),
15632 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
15633 };
15634
15635 MockRead data_reads[] = {
15636 MockRead("HTTP/1.1 200 Peachy\r\n"
15637 "Content-Length: 14\r\n\r\n"),
15638 MockRead("first response"),
15639 MockRead("HTTP/1.1 400 Not OK\r\n"
15640 "Content-Length: 15\r\n\r\n"),
15641 MockRead("second response"),
15642 MockRead(SYNCHRONOUS, OK),
15643 };
15644 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
15645 arraysize(data_writes));
15646 session_deps_.socket_factory->AddSocketDataProvider(&data);
15647
15648 TestCompletionCallback callback;
15649 HttpRequestInfo request1;
15650 request1.method = "GET";
15651 request1.url = GURL("http://www.foo.com/");
15652 request1.load_flags = 0;
15653
bnc691fda62016-08-12 00:43:1615654 std::unique_ptr<HttpNetworkTransaction> trans1(
dcheng48459ac22014-08-26 00:46:4115655 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
tfarina42834112016-09-22 13:38:2015656 int rv = trans1->Start(&request1, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0115657 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]02d74a02014-04-23 18:10:5415658
15659 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0115660 EXPECT_THAT(rv, IsOk());
[email protected]02d74a02014-04-23 18:10:5415661
15662 const HttpResponseInfo* response1 = trans1->GetResponseInfo();
wezca1070932016-05-26 20:30:5215663 ASSERT_TRUE(response1);
[email protected]02d74a02014-04-23 18:10:5415664
wezca1070932016-05-26 20:30:5215665 EXPECT_TRUE(response1->headers);
[email protected]02d74a02014-04-23 18:10:5415666 EXPECT_EQ("HTTP/1.1 200 Peachy", response1->headers->GetStatusLine());
15667
15668 std::string response_data1;
15669 rv = ReadTransaction(trans1.get(), &response_data1);
robpercival214763f2016-07-01 23:27:0115670 EXPECT_THAT(rv, IsOk());
[email protected]02d74a02014-04-23 18:10:5415671 EXPECT_EQ("first response", response_data1);
15672 // Delete the transaction to release the socket back into the socket pool.
15673 trans1.reset();
15674
danakj1fd259a02016-04-16 03:17:0915675 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:2215676 element_readers.push_back(
danakj1fd259a02016-04-16 03:17:0915677 base::WrapUnique(new UploadBytesElementReader("foo", 3)));
olli.raula6df48b2a2015-11-26 07:40:2215678 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]02d74a02014-04-23 18:10:5415679
15680 HttpRequestInfo request2;
15681 request2.method = "POST";
15682 request2.url = GURL("http://www.foo.com/");
15683 request2.upload_data_stream = &upload_data_stream;
15684 request2.load_flags = 0;
15685
bnc691fda62016-08-12 00:43:1615686 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:2015687 rv = trans2.Start(&request2, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0115688 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]02d74a02014-04-23 18:10:5415689
15690 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0115691 EXPECT_THAT(rv, IsOk());
[email protected]02d74a02014-04-23 18:10:5415692
bnc691fda62016-08-12 00:43:1615693 const HttpResponseInfo* response2 = trans2.GetResponseInfo();
wezca1070932016-05-26 20:30:5215694 ASSERT_TRUE(response2);
[email protected]02d74a02014-04-23 18:10:5415695
wezca1070932016-05-26 20:30:5215696 EXPECT_TRUE(response2->headers);
[email protected]02d74a02014-04-23 18:10:5415697 EXPECT_EQ("HTTP/1.1 400 Not OK", response2->headers->GetStatusLine());
15698
15699 std::string response_data2;
bnc691fda62016-08-12 00:43:1615700 rv = ReadTransaction(&trans2, &response_data2);
robpercival214763f2016-07-01 23:27:0115701 EXPECT_THAT(rv, IsOk());
[email protected]02d74a02014-04-23 18:10:5415702 EXPECT_EQ("second response", response_data2);
15703}
15704
bncd16676a2016-07-20 16:23:0115705TEST_F(HttpNetworkTransactionTest,
[email protected]02d74a02014-04-23 18:10:5415706 PostReadsErrorResponseAfterResetPartialBodySent) {
danakj1fd259a02016-04-16 03:17:0915707 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:2215708 element_readers.push_back(
ricea2deef682016-09-09 08:04:0715709 base::MakeUnique<UploadBytesElementReader>("foo", 3));
olli.raula6df48b2a2015-11-26 07:40:2215710 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]02d74a02014-04-23 18:10:5415711
15712 HttpRequestInfo request;
15713 request.method = "POST";
15714 request.url = GURL("http://www.foo.com/");
15715 request.upload_data_stream = &upload_data_stream;
[email protected]02d74a02014-04-23 18:10:5415716
danakj1fd259a02016-04-16 03:17:0915717 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1615718 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]02d74a02014-04-23 18:10:5415719 // Send headers successfully, but get an error while sending the body.
15720 MockWrite data_writes[] = {
15721 MockWrite("POST / HTTP/1.1\r\n"
15722 "Host: www.foo.com\r\n"
15723 "Connection: keep-alive\r\n"
15724 "Content-Length: 3\r\n\r\n"
15725 "fo"),
15726 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
15727 };
15728
15729 MockRead data_reads[] = {
15730 MockRead("HTTP/1.0 400 Not OK\r\n\r\n"),
15731 MockRead("hello world"),
15732 MockRead(SYNCHRONOUS, OK),
15733 };
15734 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
15735 arraysize(data_writes));
15736 session_deps_.socket_factory->AddSocketDataProvider(&data);
15737
15738 TestCompletionCallback callback;
15739
tfarina42834112016-09-22 13:38:2015740 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0115741 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]02d74a02014-04-23 18:10:5415742
15743 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0115744 EXPECT_THAT(rv, IsOk());
[email protected]02d74a02014-04-23 18:10:5415745
bnc691fda62016-08-12 00:43:1615746 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5215747 ASSERT_TRUE(response);
[email protected]02d74a02014-04-23 18:10:5415748
wezca1070932016-05-26 20:30:5215749 EXPECT_TRUE(response->headers);
[email protected]02d74a02014-04-23 18:10:5415750 EXPECT_EQ("HTTP/1.0 400 Not OK", response->headers->GetStatusLine());
15751
15752 std::string response_data;
bnc691fda62016-08-12 00:43:1615753 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:0115754 EXPECT_THAT(rv, IsOk());
[email protected]02d74a02014-04-23 18:10:5415755 EXPECT_EQ("hello world", response_data);
15756}
15757
15758// This tests the more common case than the previous test, where headers and
15759// body are not merged into a single request.
bncd16676a2016-07-20 16:23:0115760TEST_F(HttpNetworkTransactionTest, ChunkedPostReadsErrorResponseAfterReset) {
mmenkecbc2b712014-10-09 20:29:0715761 ChunkedUploadDataStream upload_data_stream(0);
[email protected]02d74a02014-04-23 18:10:5415762
15763 HttpRequestInfo request;
15764 request.method = "POST";
15765 request.url = GURL("http://www.foo.com/");
15766 request.upload_data_stream = &upload_data_stream;
[email protected]02d74a02014-04-23 18:10:5415767
danakj1fd259a02016-04-16 03:17:0915768 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1615769 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]02d74a02014-04-23 18:10:5415770 // Send headers successfully, but get an error while sending the body.
15771 MockWrite data_writes[] = {
15772 MockWrite("POST / HTTP/1.1\r\n"
15773 "Host: www.foo.com\r\n"
15774 "Connection: keep-alive\r\n"
15775 "Transfer-Encoding: chunked\r\n\r\n"),
15776 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
15777 };
15778
15779 MockRead data_reads[] = {
15780 MockRead("HTTP/1.0 400 Not OK\r\n\r\n"),
15781 MockRead("hello world"),
15782 MockRead(SYNCHRONOUS, OK),
15783 };
15784 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
15785 arraysize(data_writes));
15786 session_deps_.socket_factory->AddSocketDataProvider(&data);
15787
15788 TestCompletionCallback callback;
15789
tfarina42834112016-09-22 13:38:2015790 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0115791 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]02d74a02014-04-23 18:10:5415792 // Make sure the headers are sent before adding a chunk. This ensures that
15793 // they can't be merged with the body in a single send. Not currently
15794 // necessary since a chunked body is never merged with headers, but this makes
15795 // the test more future proof.
15796 base::RunLoop().RunUntilIdle();
15797
mmenkecbc2b712014-10-09 20:29:0715798 upload_data_stream.AppendData("last chunk", 10, true);
[email protected]02d74a02014-04-23 18:10:5415799
15800 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0115801 EXPECT_THAT(rv, IsOk());
[email protected]02d74a02014-04-23 18:10:5415802
bnc691fda62016-08-12 00:43:1615803 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5215804 ASSERT_TRUE(response);
[email protected]02d74a02014-04-23 18:10:5415805
wezca1070932016-05-26 20:30:5215806 EXPECT_TRUE(response->headers);
[email protected]02d74a02014-04-23 18:10:5415807 EXPECT_EQ("HTTP/1.0 400 Not OK", response->headers->GetStatusLine());
15808
15809 std::string response_data;
bnc691fda62016-08-12 00:43:1615810 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:0115811 EXPECT_THAT(rv, IsOk());
[email protected]02d74a02014-04-23 18:10:5415812 EXPECT_EQ("hello world", response_data);
15813}
15814
bncd16676a2016-07-20 16:23:0115815TEST_F(HttpNetworkTransactionTest, PostReadsErrorResponseAfterResetAnd100) {
danakj1fd259a02016-04-16 03:17:0915816 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:2215817 element_readers.push_back(
ricea2deef682016-09-09 08:04:0715818 base::MakeUnique<UploadBytesElementReader>("foo", 3));
olli.raula6df48b2a2015-11-26 07:40:2215819 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]02d74a02014-04-23 18:10:5415820
15821 HttpRequestInfo request;
15822 request.method = "POST";
15823 request.url = GURL("http://www.foo.com/");
15824 request.upload_data_stream = &upload_data_stream;
[email protected]02d74a02014-04-23 18:10:5415825
danakj1fd259a02016-04-16 03:17:0915826 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1615827 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]02d74a02014-04-23 18:10:5415828
15829 MockWrite data_writes[] = {
15830 MockWrite("POST / HTTP/1.1\r\n"
15831 "Host: www.foo.com\r\n"
15832 "Connection: keep-alive\r\n"
15833 "Content-Length: 3\r\n\r\n"),
15834 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
15835 };
15836
15837 MockRead data_reads[] = {
15838 MockRead("HTTP/1.0 100 Continue\r\n\r\n"),
15839 MockRead("HTTP/1.0 400 Not OK\r\n\r\n"),
15840 MockRead("hello world"),
15841 MockRead(SYNCHRONOUS, OK),
15842 };
15843 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
15844 arraysize(data_writes));
15845 session_deps_.socket_factory->AddSocketDataProvider(&data);
15846
15847 TestCompletionCallback callback;
15848
tfarina42834112016-09-22 13:38:2015849 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0115850 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]02d74a02014-04-23 18:10:5415851
15852 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0115853 EXPECT_THAT(rv, IsOk());
[email protected]02d74a02014-04-23 18:10:5415854
bnc691fda62016-08-12 00:43:1615855 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5215856 ASSERT_TRUE(response);
[email protected]02d74a02014-04-23 18:10:5415857
wezca1070932016-05-26 20:30:5215858 EXPECT_TRUE(response->headers);
[email protected]02d74a02014-04-23 18:10:5415859 EXPECT_EQ("HTTP/1.0 400 Not OK", response->headers->GetStatusLine());
15860
15861 std::string response_data;
bnc691fda62016-08-12 00:43:1615862 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:0115863 EXPECT_THAT(rv, IsOk());
[email protected]02d74a02014-04-23 18:10:5415864 EXPECT_EQ("hello world", response_data);
15865}
15866
bncd16676a2016-07-20 16:23:0115867TEST_F(HttpNetworkTransactionTest, PostIgnoresNonErrorResponseAfterReset) {
danakj1fd259a02016-04-16 03:17:0915868 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:2215869 element_readers.push_back(
ricea2deef682016-09-09 08:04:0715870 base::MakeUnique<UploadBytesElementReader>("foo", 3));
olli.raula6df48b2a2015-11-26 07:40:2215871 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]02d74a02014-04-23 18:10:5415872
15873 HttpRequestInfo request;
15874 request.method = "POST";
15875 request.url = GURL("http://www.foo.com/");
15876 request.upload_data_stream = &upload_data_stream;
[email protected]02d74a02014-04-23 18:10:5415877
danakj1fd259a02016-04-16 03:17:0915878 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1615879 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]02d74a02014-04-23 18:10:5415880 // Send headers successfully, but get an error while sending the body.
15881 MockWrite data_writes[] = {
15882 MockWrite("POST / HTTP/1.1\r\n"
15883 "Host: www.foo.com\r\n"
15884 "Connection: keep-alive\r\n"
15885 "Content-Length: 3\r\n\r\n"),
15886 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
15887 };
15888
15889 MockRead data_reads[] = {
15890 MockRead("HTTP/1.0 200 Just Dandy\r\n\r\n"),
15891 MockRead("hello world"),
15892 MockRead(SYNCHRONOUS, OK),
15893 };
15894 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
15895 arraysize(data_writes));
15896 session_deps_.socket_factory->AddSocketDataProvider(&data);
15897
15898 TestCompletionCallback callback;
15899
tfarina42834112016-09-22 13:38:2015900 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0115901 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]02d74a02014-04-23 18:10:5415902
15903 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0115904 EXPECT_THAT(rv, IsError(ERR_CONNECTION_RESET));
[email protected]02d74a02014-04-23 18:10:5415905}
15906
bncd16676a2016-07-20 16:23:0115907TEST_F(HttpNetworkTransactionTest,
[email protected]02d74a02014-04-23 18:10:5415908 PostIgnoresNonErrorResponseAfterResetAnd100) {
danakj1fd259a02016-04-16 03:17:0915909 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:2215910 element_readers.push_back(
ricea2deef682016-09-09 08:04:0715911 base::MakeUnique<UploadBytesElementReader>("foo", 3));
olli.raula6df48b2a2015-11-26 07:40:2215912 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]02d74a02014-04-23 18:10:5415913
15914 HttpRequestInfo request;
15915 request.method = "POST";
15916 request.url = GURL("http://www.foo.com/");
15917 request.upload_data_stream = &upload_data_stream;
[email protected]02d74a02014-04-23 18:10:5415918
danakj1fd259a02016-04-16 03:17:0915919 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1615920 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]02d74a02014-04-23 18:10:5415921 // Send headers successfully, but get an error while sending the body.
15922 MockWrite data_writes[] = {
15923 MockWrite("POST / HTTP/1.1\r\n"
15924 "Host: www.foo.com\r\n"
15925 "Connection: keep-alive\r\n"
15926 "Content-Length: 3\r\n\r\n"),
15927 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
15928 };
15929
15930 MockRead data_reads[] = {
15931 MockRead("HTTP/1.0 100 Continue\r\n\r\n"),
15932 MockRead("HTTP/1.0 302 Redirect\r\n"),
15933 MockRead("Location: http://somewhere-else.com/\r\n"),
15934 MockRead("Content-Length: 0\r\n\r\n"),
15935 MockRead(SYNCHRONOUS, OK),
15936 };
15937 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
15938 arraysize(data_writes));
15939 session_deps_.socket_factory->AddSocketDataProvider(&data);
15940
15941 TestCompletionCallback callback;
15942
tfarina42834112016-09-22 13:38:2015943 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0115944 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]02d74a02014-04-23 18:10:5415945
15946 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0115947 EXPECT_THAT(rv, IsError(ERR_CONNECTION_RESET));
[email protected]02d74a02014-04-23 18:10:5415948}
15949
bncd16676a2016-07-20 16:23:0115950TEST_F(HttpNetworkTransactionTest, PostIgnoresHttp09ResponseAfterReset) {
danakj1fd259a02016-04-16 03:17:0915951 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:2215952 element_readers.push_back(
ricea2deef682016-09-09 08:04:0715953 base::MakeUnique<UploadBytesElementReader>("foo", 3));
olli.raula6df48b2a2015-11-26 07:40:2215954 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]02d74a02014-04-23 18:10:5415955
15956 HttpRequestInfo request;
15957 request.method = "POST";
15958 request.url = GURL("http://www.foo.com/");
15959 request.upload_data_stream = &upload_data_stream;
[email protected]02d74a02014-04-23 18:10:5415960
danakj1fd259a02016-04-16 03:17:0915961 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1615962 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]02d74a02014-04-23 18:10:5415963 // Send headers successfully, but get an error while sending the body.
15964 MockWrite data_writes[] = {
15965 MockWrite("POST / HTTP/1.1\r\n"
15966 "Host: www.foo.com\r\n"
15967 "Connection: keep-alive\r\n"
15968 "Content-Length: 3\r\n\r\n"),
15969 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
15970 };
15971
15972 MockRead data_reads[] = {
15973 MockRead("HTTP 0.9 rocks!"),
15974 MockRead(SYNCHRONOUS, OK),
15975 };
15976 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
15977 arraysize(data_writes));
15978 session_deps_.socket_factory->AddSocketDataProvider(&data);
15979
15980 TestCompletionCallback callback;
15981
tfarina42834112016-09-22 13:38:2015982 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0115983 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]02d74a02014-04-23 18:10:5415984
15985 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0115986 EXPECT_THAT(rv, IsError(ERR_CONNECTION_RESET));
[email protected]02d74a02014-04-23 18:10:5415987}
15988
bncd16676a2016-07-20 16:23:0115989TEST_F(HttpNetworkTransactionTest, PostIgnoresPartial400HeadersAfterReset) {
danakj1fd259a02016-04-16 03:17:0915990 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:2215991 element_readers.push_back(
ricea2deef682016-09-09 08:04:0715992 base::MakeUnique<UploadBytesElementReader>("foo", 3));
olli.raula6df48b2a2015-11-26 07:40:2215993 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]02d74a02014-04-23 18:10:5415994
15995 HttpRequestInfo request;
15996 request.method = "POST";
15997 request.url = GURL("http://www.foo.com/");
15998 request.upload_data_stream = &upload_data_stream;
[email protected]02d74a02014-04-23 18:10:5415999
danakj1fd259a02016-04-16 03:17:0916000 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1616001 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]02d74a02014-04-23 18:10:5416002 // Send headers successfully, but get an error while sending the body.
16003 MockWrite data_writes[] = {
16004 MockWrite("POST / HTTP/1.1\r\n"
16005 "Host: www.foo.com\r\n"
16006 "Connection: keep-alive\r\n"
16007 "Content-Length: 3\r\n\r\n"),
16008 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
16009 };
16010
16011 MockRead data_reads[] = {
16012 MockRead("HTTP/1.0 400 Not a Full Response\r\n"),
16013 MockRead(SYNCHRONOUS, OK),
16014 };
16015 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
16016 arraysize(data_writes));
16017 session_deps_.socket_factory->AddSocketDataProvider(&data);
16018
16019 TestCompletionCallback callback;
16020
tfarina42834112016-09-22 13:38:2016021 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0116022 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]02d74a02014-04-23 18:10:5416023
16024 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0116025 EXPECT_THAT(rv, IsError(ERR_CONNECTION_RESET));
[email protected]02d74a02014-04-23 18:10:5416026}
16027
Adam Rice425cf122015-01-19 06:18:2416028// Verify that proxy headers are not sent to the destination server when
16029// establishing a tunnel for a secure WebSocket connection.
bncd16676a2016-07-20 16:23:0116030TEST_F(HttpNetworkTransactionTest, ProxyHeadersNotSentOverWssTunnel) {
Adam Rice425cf122015-01-19 06:18:2416031 HttpRequestInfo request;
16032 request.method = "GET";
bncce36dca22015-04-21 22:11:2316033 request.url = GURL("wss://www.example.org/");
Adam Rice425cf122015-01-19 06:18:2416034 AddWebSocketHeaders(&request.extra_headers);
16035
16036 // Configure against proxy server "myproxy:70".
rdsmith82957ad2015-09-16 19:42:0316037 session_deps_.proxy_service =
16038 ProxyService::CreateFixedFromPacResult("PROXY myproxy:70");
Adam Rice425cf122015-01-19 06:18:2416039
danakj1fd259a02016-04-16 03:17:0916040 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
Adam Rice425cf122015-01-19 06:18:2416041
16042 // Since a proxy is configured, try to establish a tunnel.
16043 MockWrite data_writes[] = {
rsleevidb16bb02015-11-12 23:47:1716044 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
16045 "Host: www.example.org:443\r\n"
16046 "Proxy-Connection: keep-alive\r\n\r\n"),
Adam Rice425cf122015-01-19 06:18:2416047
16048 // After calling trans->RestartWithAuth(), this is the request we should
16049 // be issuing -- the final header line contains the credentials.
rsleevidb16bb02015-11-12 23:47:1716050 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
16051 "Host: www.example.org:443\r\n"
16052 "Proxy-Connection: keep-alive\r\n"
16053 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
Adam Rice425cf122015-01-19 06:18:2416054
rsleevidb16bb02015-11-12 23:47:1716055 MockWrite("GET / HTTP/1.1\r\n"
16056 "Host: www.example.org\r\n"
16057 "Connection: Upgrade\r\n"
16058 "Upgrade: websocket\r\n"
16059 "Origin: http://www.example.org\r\n"
16060 "Sec-WebSocket-Version: 13\r\n"
16061 "Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==\r\n\r\n"),
Adam Rice425cf122015-01-19 06:18:2416062 };
16063
16064 // The proxy responds to the connect with a 407, using a persistent
16065 // connection.
16066 MockRead data_reads[] = {
16067 // No credentials.
16068 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
16069 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
mmenkee71e15332015-10-07 16:39:5416070 MockRead("Content-Length: 0\r\n"),
16071 MockRead("Proxy-Connection: keep-alive\r\n\r\n"),
Adam Rice425cf122015-01-19 06:18:2416072
16073 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
16074
16075 MockRead("HTTP/1.1 101 Switching Protocols\r\n"),
16076 MockRead("Upgrade: websocket\r\n"),
16077 MockRead("Connection: Upgrade\r\n"),
16078 MockRead("Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=\r\n\r\n"),
16079 };
16080
16081 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
16082 arraysize(data_writes));
16083 session_deps_.socket_factory->AddSocketDataProvider(&data);
16084 SSLSocketDataProvider ssl(ASYNC, OK);
16085 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
16086
bnc691fda62016-08-12 00:43:1616087 std::unique_ptr<HttpNetworkTransaction> trans(
Adam Rice425cf122015-01-19 06:18:2416088 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
16089 FakeWebSocketStreamCreateHelper websocket_stream_create_helper;
16090 trans->SetWebSocketHandshakeStreamCreateHelper(
16091 &websocket_stream_create_helper);
16092
16093 {
16094 TestCompletionCallback callback;
16095
tfarina42834112016-09-22 13:38:2016096 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0116097 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
Adam Rice425cf122015-01-19 06:18:2416098
16099 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0116100 EXPECT_THAT(rv, IsOk());
Adam Rice425cf122015-01-19 06:18:2416101 }
16102
16103 const HttpResponseInfo* response = trans->GetResponseInfo();
16104 ASSERT_TRUE(response);
wezca1070932016-05-26 20:30:5216105 ASSERT_TRUE(response->headers);
Adam Rice425cf122015-01-19 06:18:2416106 EXPECT_EQ(407, response->headers->response_code());
16107
16108 {
16109 TestCompletionCallback callback;
16110
16111 int rv = trans->RestartWithAuth(AuthCredentials(kFoo, kBar),
16112 callback.callback());
robpercival214763f2016-07-01 23:27:0116113 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
Adam Rice425cf122015-01-19 06:18:2416114
16115 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0116116 EXPECT_THAT(rv, IsOk());
Adam Rice425cf122015-01-19 06:18:2416117 }
16118
16119 response = trans->GetResponseInfo();
16120 ASSERT_TRUE(response);
wezca1070932016-05-26 20:30:5216121 ASSERT_TRUE(response->headers);
Adam Rice425cf122015-01-19 06:18:2416122
16123 EXPECT_EQ(101, response->headers->response_code());
16124
16125 trans.reset();
16126 session->CloseAllConnections();
16127}
16128
16129// Verify that proxy headers are not sent to the destination server when
16130// establishing a tunnel for an insecure WebSocket connection.
16131// This requires the authentication info to be injected into the auth cache
16132// due to crbug.com/395064
16133// TODO(ricea): Change to use a 407 response once issue 395064 is fixed.
bncd16676a2016-07-20 16:23:0116134TEST_F(HttpNetworkTransactionTest, ProxyHeadersNotSentOverWsTunnel) {
Adam Rice425cf122015-01-19 06:18:2416135 HttpRequestInfo request;
16136 request.method = "GET";
bncce36dca22015-04-21 22:11:2316137 request.url = GURL("ws://www.example.org/");
Adam Rice425cf122015-01-19 06:18:2416138 AddWebSocketHeaders(&request.extra_headers);
16139
16140 // Configure against proxy server "myproxy:70".
rdsmith82957ad2015-09-16 19:42:0316141 session_deps_.proxy_service =
16142 ProxyService::CreateFixedFromPacResult("PROXY myproxy:70");
Adam Rice425cf122015-01-19 06:18:2416143
danakj1fd259a02016-04-16 03:17:0916144 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
Adam Rice425cf122015-01-19 06:18:2416145
16146 MockWrite data_writes[] = {
16147 // Try to establish a tunnel for the WebSocket connection, with
16148 // credentials. Because WebSockets have a separate set of socket pools,
16149 // they cannot and will not use the same TCP/IP connection as the
16150 // preflight HTTP request.
16151 MockWrite(
bncce36dca22015-04-21 22:11:2316152 "CONNECT www.example.org:80 HTTP/1.1\r\n"
16153 "Host: www.example.org:80\r\n"
Adam Rice425cf122015-01-19 06:18:2416154 "Proxy-Connection: keep-alive\r\n"
16155 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
16156
16157 MockWrite(
16158 "GET / HTTP/1.1\r\n"
bncce36dca22015-04-21 22:11:2316159 "Host: www.example.org\r\n"
Adam Rice425cf122015-01-19 06:18:2416160 "Connection: Upgrade\r\n"
16161 "Upgrade: websocket\r\n"
bncce36dca22015-04-21 22:11:2316162 "Origin: http://www.example.org\r\n"
Adam Rice425cf122015-01-19 06:18:2416163 "Sec-WebSocket-Version: 13\r\n"
16164 "Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==\r\n\r\n"),
16165 };
16166
16167 MockRead data_reads[] = {
16168 // HTTP CONNECT with credentials.
16169 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
16170
16171 // WebSocket connection established inside tunnel.
16172 MockRead("HTTP/1.1 101 Switching Protocols\r\n"),
16173 MockRead("Upgrade: websocket\r\n"),
16174 MockRead("Connection: Upgrade\r\n"),
16175 MockRead("Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=\r\n\r\n"),
16176 };
16177
16178 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
16179 arraysize(data_writes));
16180 session_deps_.socket_factory->AddSocketDataProvider(&data);
16181
16182 session->http_auth_cache()->Add(
16183 GURL("http://myproxy:70/"), "MyRealm1", HttpAuth::AUTH_SCHEME_BASIC,
16184 "Basic realm=MyRealm1", AuthCredentials(kFoo, kBar), "/");
16185
bnc691fda62016-08-12 00:43:1616186 std::unique_ptr<HttpNetworkTransaction> trans(
Adam Rice425cf122015-01-19 06:18:2416187 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
16188 FakeWebSocketStreamCreateHelper websocket_stream_create_helper;
16189 trans->SetWebSocketHandshakeStreamCreateHelper(
16190 &websocket_stream_create_helper);
16191
16192 TestCompletionCallback callback;
16193
tfarina42834112016-09-22 13:38:2016194 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0116195 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
Adam Rice425cf122015-01-19 06:18:2416196
16197 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0116198 EXPECT_THAT(rv, IsOk());
Adam Rice425cf122015-01-19 06:18:2416199
16200 const HttpResponseInfo* response = trans->GetResponseInfo();
16201 ASSERT_TRUE(response);
wezca1070932016-05-26 20:30:5216202 ASSERT_TRUE(response->headers);
Adam Rice425cf122015-01-19 06:18:2416203
16204 EXPECT_EQ(101, response->headers->response_code());
16205
16206 trans.reset();
16207 session->CloseAllConnections();
16208}
16209
bncd16676a2016-07-20 16:23:0116210TEST_F(HttpNetworkTransactionTest, TotalNetworkBytesPost) {
danakj1fd259a02016-04-16 03:17:0916211 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:2216212 element_readers.push_back(
ricea2deef682016-09-09 08:04:0716213 base::MakeUnique<UploadBytesElementReader>("foo", 3));
olli.raula6df48b2a2015-11-26 07:40:2216214 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
sclittlefb249892015-09-10 21:33:2216215
16216 HttpRequestInfo request;
16217 request.method = "POST";
16218 request.url = GURL("http://www.foo.com/");
16219 request.upload_data_stream = &upload_data_stream;
16220
danakj1fd259a02016-04-16 03:17:0916221 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1616222 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
sclittlefb249892015-09-10 21:33:2216223 MockWrite data_writes[] = {
16224 MockWrite("POST / HTTP/1.1\r\n"
16225 "Host: www.foo.com\r\n"
16226 "Connection: keep-alive\r\n"
16227 "Content-Length: 3\r\n\r\n"),
16228 MockWrite("foo"),
16229 };
16230
16231 MockRead data_reads[] = {
16232 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello world"),
16233 MockRead(SYNCHRONOUS, OK),
16234 };
16235 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
16236 arraysize(data_writes));
16237 session_deps_.socket_factory->AddSocketDataProvider(&data);
16238
16239 TestCompletionCallback callback;
16240
16241 EXPECT_EQ(ERR_IO_PENDING,
tfarina42834112016-09-22 13:38:2016242 trans.Start(&request, callback.callback(), NetLogWithSource()));
robpercival214763f2016-07-01 23:27:0116243 EXPECT_THAT(callback.WaitForResult(), IsOk());
sclittlefb249892015-09-10 21:33:2216244
16245 std::string response_data;
bnc691fda62016-08-12 00:43:1616246 EXPECT_THAT(ReadTransaction(&trans, &response_data), IsOk());
sclittlefb249892015-09-10 21:33:2216247
16248 EXPECT_EQ(CountWriteBytes(data_writes, arraysize(data_writes)),
bnc691fda62016-08-12 00:43:1616249 trans.GetTotalSentBytes());
sclittlefb249892015-09-10 21:33:2216250 EXPECT_EQ(CountReadBytes(data_reads, arraysize(data_reads)),
bnc691fda62016-08-12 00:43:1616251 trans.GetTotalReceivedBytes());
sclittlefb249892015-09-10 21:33:2216252}
16253
bncd16676a2016-07-20 16:23:0116254TEST_F(HttpNetworkTransactionTest, TotalNetworkBytesPost100Continue) {
danakj1fd259a02016-04-16 03:17:0916255 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:2216256 element_readers.push_back(
ricea2deef682016-09-09 08:04:0716257 base::MakeUnique<UploadBytesElementReader>("foo", 3));
olli.raula6df48b2a2015-11-26 07:40:2216258 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
sclittlefb249892015-09-10 21:33:2216259
16260 HttpRequestInfo request;
16261 request.method = "POST";
16262 request.url = GURL("http://www.foo.com/");
16263 request.upload_data_stream = &upload_data_stream;
16264
danakj1fd259a02016-04-16 03:17:0916265 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1616266 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
sclittlefb249892015-09-10 21:33:2216267 MockWrite data_writes[] = {
16268 MockWrite("POST / HTTP/1.1\r\n"
16269 "Host: www.foo.com\r\n"
16270 "Connection: keep-alive\r\n"
16271 "Content-Length: 3\r\n\r\n"),
16272 MockWrite("foo"),
16273 };
16274
16275 MockRead data_reads[] = {
16276 MockRead("HTTP/1.1 100 Continue\r\n\r\n"),
16277 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello world"),
16278 MockRead(SYNCHRONOUS, OK),
16279 };
16280 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
16281 arraysize(data_writes));
16282 session_deps_.socket_factory->AddSocketDataProvider(&data);
16283
16284 TestCompletionCallback callback;
16285
16286 EXPECT_EQ(ERR_IO_PENDING,
tfarina42834112016-09-22 13:38:2016287 trans.Start(&request, callback.callback(), NetLogWithSource()));
robpercival214763f2016-07-01 23:27:0116288 EXPECT_THAT(callback.WaitForResult(), IsOk());
sclittlefb249892015-09-10 21:33:2216289
16290 std::string response_data;
bnc691fda62016-08-12 00:43:1616291 EXPECT_THAT(ReadTransaction(&trans, &response_data), IsOk());
sclittlefb249892015-09-10 21:33:2216292
16293 EXPECT_EQ(CountWriteBytes(data_writes, arraysize(data_writes)),
bnc691fda62016-08-12 00:43:1616294 trans.GetTotalSentBytes());
sclittlefb249892015-09-10 21:33:2216295 EXPECT_EQ(CountReadBytes(data_reads, arraysize(data_reads)),
bnc691fda62016-08-12 00:43:1616296 trans.GetTotalReceivedBytes());
sclittlefb249892015-09-10 21:33:2216297}
16298
bncd16676a2016-07-20 16:23:0116299TEST_F(HttpNetworkTransactionTest, TotalNetworkBytesChunkedPost) {
sclittlefb249892015-09-10 21:33:2216300 ChunkedUploadDataStream upload_data_stream(0);
16301
16302 HttpRequestInfo request;
16303 request.method = "POST";
16304 request.url = GURL("http://www.foo.com/");
16305 request.upload_data_stream = &upload_data_stream;
16306
danakj1fd259a02016-04-16 03:17:0916307 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1616308 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
sclittlefb249892015-09-10 21:33:2216309 // Send headers successfully, but get an error while sending the body.
16310 MockWrite data_writes[] = {
16311 MockWrite("POST / HTTP/1.1\r\n"
16312 "Host: www.foo.com\r\n"
16313 "Connection: keep-alive\r\n"
16314 "Transfer-Encoding: chunked\r\n\r\n"),
16315 MockWrite("1\r\nf\r\n"), MockWrite("2\r\noo\r\n"), MockWrite("0\r\n\r\n"),
16316 };
16317
16318 MockRead data_reads[] = {
16319 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello world"),
16320 MockRead(SYNCHRONOUS, OK),
16321 };
16322 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
16323 arraysize(data_writes));
16324 session_deps_.socket_factory->AddSocketDataProvider(&data);
16325
16326 TestCompletionCallback callback;
16327
16328 EXPECT_EQ(ERR_IO_PENDING,
tfarina42834112016-09-22 13:38:2016329 trans.Start(&request, callback.callback(), NetLogWithSource()));
sclittlefb249892015-09-10 21:33:2216330
16331 base::RunLoop().RunUntilIdle();
16332 upload_data_stream.AppendData("f", 1, false);
16333
16334 base::RunLoop().RunUntilIdle();
16335 upload_data_stream.AppendData("oo", 2, true);
16336
robpercival214763f2016-07-01 23:27:0116337 EXPECT_THAT(callback.WaitForResult(), IsOk());
sclittlefb249892015-09-10 21:33:2216338
16339 std::string response_data;
bnc691fda62016-08-12 00:43:1616340 EXPECT_THAT(ReadTransaction(&trans, &response_data), IsOk());
sclittlefb249892015-09-10 21:33:2216341
16342 EXPECT_EQ(CountWriteBytes(data_writes, arraysize(data_writes)),
bnc691fda62016-08-12 00:43:1616343 trans.GetTotalSentBytes());
sclittlefb249892015-09-10 21:33:2216344 EXPECT_EQ(CountReadBytes(data_reads, arraysize(data_reads)),
bnc691fda62016-08-12 00:43:1616345 trans.GetTotalReceivedBytes());
sclittlefb249892015-09-10 21:33:2216346}
16347
rdsmith1d343be52016-10-21 20:37:5016348// Confirm that transactions whose throttle is created in (and stays in)
16349// the unthrottled state are not blocked.
16350TEST_F(HttpNetworkTransactionTest, ThrottlingUnthrottled) {
16351 TestNetworkStreamThrottler* throttler(nullptr);
16352 std::unique_ptr<HttpNetworkSession> session(
16353 CreateSessionWithThrottler(&session_deps_, &throttler));
16354
16355 // Send a simple request and make sure it goes through.
16356 HttpRequestInfo request;
16357 request.method = "GET";
16358 request.url = GURL("http://www.example.org/");
16359
16360 std::unique_ptr<HttpTransaction> trans(
16361 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
16362
16363 MockWrite data_writes[] = {
16364 MockWrite("GET / HTTP/1.1\r\n"
16365 "Host: www.example.org\r\n"
16366 "Connection: keep-alive\r\n\r\n"),
16367 };
16368 MockRead data_reads[] = {
16369 MockRead("HTTP/1.0 200 OK\r\n\r\n"), MockRead("hello world"),
16370 MockRead(SYNCHRONOUS, OK),
16371 };
16372 StaticSocketDataProvider reads(data_reads, arraysize(data_reads), data_writes,
16373 arraysize(data_writes));
16374 session_deps_.socket_factory->AddSocketDataProvider(&reads);
16375
16376 TestCompletionCallback callback;
16377 trans->Start(&request, callback.callback(), NetLogWithSource());
16378 EXPECT_EQ(OK, callback.WaitForResult());
16379}
16380
16381// Confirm requests can be blocked by a throttler, and are resumed
16382// when the throttle is unblocked.
16383TEST_F(HttpNetworkTransactionTest, ThrottlingBasic) {
16384 TestNetworkStreamThrottler* throttler(nullptr);
16385 std::unique_ptr<HttpNetworkSession> session(
16386 CreateSessionWithThrottler(&session_deps_, &throttler));
16387
16388 // Send a simple request and make sure it goes through.
16389 HttpRequestInfo request;
16390 request.method = "GET";
16391 request.url = GURL("http://www.example.org/");
16392
16393 MockWrite data_writes[] = {
16394 MockWrite("GET / HTTP/1.1\r\n"
16395 "Host: www.example.org\r\n"
16396 "Connection: keep-alive\r\n\r\n"),
16397 };
16398 MockRead data_reads[] = {
16399 MockRead("HTTP/1.0 200 OK\r\n\r\n"), MockRead("hello world"),
16400 MockRead(SYNCHRONOUS, OK),
16401 };
16402 StaticSocketDataProvider reads(data_reads, arraysize(data_reads), data_writes,
16403 arraysize(data_writes));
16404 session_deps_.socket_factory->AddSocketDataProvider(&reads);
16405
16406 // Start a request that will be throttled at start; confirm it
16407 // doesn't complete.
16408 throttler->set_throttle_new_requests(true);
16409 std::unique_ptr<HttpTransaction> trans(
16410 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
16411
16412 TestCompletionCallback callback;
16413 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
16414 EXPECT_EQ(ERR_IO_PENDING, rv);
16415
16416 base::RunLoop().RunUntilIdle();
16417 EXPECT_EQ(LOAD_STATE_THROTTLED, trans->GetLoadState());
16418 EXPECT_FALSE(callback.have_result());
16419
16420 // Confirm the request goes on to complete when unthrottled.
16421 throttler->UnthrottleAllRequests();
16422 base::RunLoop().RunUntilIdle();
16423 ASSERT_TRUE(callback.have_result());
16424 EXPECT_EQ(OK, callback.WaitForResult());
16425}
16426
16427// Destroy a request while it's throttled.
16428TEST_F(HttpNetworkTransactionTest, ThrottlingDestruction) {
16429 TestNetworkStreamThrottler* throttler(nullptr);
16430 std::unique_ptr<HttpNetworkSession> session(
16431 CreateSessionWithThrottler(&session_deps_, &throttler));
16432
16433 // Send a simple request and make sure it goes through.
16434 HttpRequestInfo request;
16435 request.method = "GET";
16436 request.url = GURL("http://www.example.org/");
16437
16438 MockWrite data_writes[] = {
16439 MockWrite("GET / HTTP/1.1\r\n"
16440 "Host: www.example.org\r\n"
16441 "Connection: keep-alive\r\n\r\n"),
16442 };
16443 MockRead data_reads[] = {
16444 MockRead("HTTP/1.0 200 OK\r\n\r\n"), MockRead("hello world"),
16445 MockRead(SYNCHRONOUS, OK),
16446 };
16447 StaticSocketDataProvider reads(data_reads, arraysize(data_reads), data_writes,
16448 arraysize(data_writes));
16449 session_deps_.socket_factory->AddSocketDataProvider(&reads);
16450
16451 // Start a request that will be throttled at start; confirm it
16452 // doesn't complete.
16453 throttler->set_throttle_new_requests(true);
16454 std::unique_ptr<HttpTransaction> trans(
16455 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
16456
16457 TestCompletionCallback callback;
16458 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
16459 EXPECT_EQ(ERR_IO_PENDING, rv);
16460
16461 base::RunLoop().RunUntilIdle();
16462 EXPECT_EQ(LOAD_STATE_THROTTLED, trans->GetLoadState());
16463 EXPECT_FALSE(callback.have_result());
16464
16465 EXPECT_EQ(1u, throttler->num_outstanding_requests());
16466 trans.reset();
16467 EXPECT_EQ(0u, throttler->num_outstanding_requests());
16468}
16469
16470// Confirm the throttler receives SetPriority calls.
16471TEST_F(HttpNetworkTransactionTest, ThrottlingPrioritySet) {
16472 TestNetworkStreamThrottler* throttler(nullptr);
16473 std::unique_ptr<HttpNetworkSession> session(
16474 CreateSessionWithThrottler(&session_deps_, &throttler));
16475
16476 // Send a simple request and make sure it goes through.
16477 HttpRequestInfo request;
16478 request.method = "GET";
16479 request.url = GURL("http://www.example.org/");
16480
16481 MockWrite data_writes[] = {
16482 MockWrite("GET / HTTP/1.1\r\n"
16483 "Host: www.example.org\r\n"
16484 "Connection: keep-alive\r\n\r\n"),
16485 };
16486 MockRead data_reads[] = {
16487 MockRead("HTTP/1.0 200 OK\r\n\r\n"), MockRead("hello world"),
16488 MockRead(SYNCHRONOUS, OK),
16489 };
16490 StaticSocketDataProvider reads(data_reads, arraysize(data_reads), data_writes,
16491 arraysize(data_writes));
16492 session_deps_.socket_factory->AddSocketDataProvider(&reads);
16493
16494 throttler->set_throttle_new_requests(true);
16495 std::unique_ptr<HttpTransaction> trans(
16496 new HttpNetworkTransaction(IDLE, session.get()));
16497 // Start the transaction to associate a throttle with it.
16498 TestCompletionCallback callback;
16499 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
16500 EXPECT_EQ(ERR_IO_PENDING, rv);
16501
16502 EXPECT_EQ(0, throttler->num_set_priority_calls());
16503 trans->SetPriority(LOW);
16504 EXPECT_EQ(1, throttler->num_set_priority_calls());
16505 EXPECT_EQ(LOW, throttler->last_priority_set());
16506
16507 throttler->UnthrottleAllRequests();
16508 base::RunLoop().RunUntilIdle();
16509 ASSERT_TRUE(callback.have_result());
16510 EXPECT_EQ(OK, callback.WaitForResult());
16511}
16512
16513// Confirm that unthrottling from a SetPriority call by the
16514// throttler works properly.
16515TEST_F(HttpNetworkTransactionTest, ThrottlingPrioritySetUnthrottle) {
16516 TestNetworkStreamThrottler* throttler(nullptr);
16517 std::unique_ptr<HttpNetworkSession> session(
16518 CreateSessionWithThrottler(&session_deps_, &throttler));
16519
16520 // Send a simple request and make sure it goes through.
16521 HttpRequestInfo request;
16522 request.method = "GET";
16523 request.url = GURL("http://www.example.org/");
16524
16525 MockWrite data_writes[] = {
16526 MockWrite("GET / HTTP/1.1\r\n"
16527 "Host: www.example.org\r\n"
16528 "Connection: keep-alive\r\n\r\n"),
16529 };
16530 MockRead data_reads[] = {
16531 MockRead("HTTP/1.0 200 OK\r\n\r\n"), MockRead("hello world"),
16532 MockRead(SYNCHRONOUS, OK),
16533 };
16534 StaticSocketDataProvider reads(data_reads, arraysize(data_reads), data_writes,
16535 arraysize(data_writes));
16536 session_deps_.socket_factory->AddSocketDataProvider(&reads);
16537
16538 StaticSocketDataProvider reads1(data_reads, arraysize(data_reads),
16539 data_writes, arraysize(data_writes));
16540 session_deps_.socket_factory->AddSocketDataProvider(&reads1);
16541
16542 // Start a request that will be throttled at start; confirm it
16543 // doesn't complete.
16544 throttler->set_throttle_new_requests(true);
16545 std::unique_ptr<HttpTransaction> trans(
16546 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
16547
16548 TestCompletionCallback callback;
16549 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
16550 EXPECT_EQ(ERR_IO_PENDING, rv);
16551
16552 base::RunLoop().RunUntilIdle();
16553 EXPECT_EQ(LOAD_STATE_THROTTLED, trans->GetLoadState());
16554 EXPECT_FALSE(callback.have_result());
16555
16556 // Create a new request, call SetPriority on it to unthrottle,
16557 // and make sure that allows the original request to complete.
16558 std::unique_ptr<HttpTransaction> trans1(
16559 new HttpNetworkTransaction(LOW, session.get()));
16560 throttler->set_priority_change_closure(
16561 base::Bind(&TestNetworkStreamThrottler::UnthrottleAllRequests,
16562 base::Unretained(throttler)));
16563
16564 // Start the transaction to associate a throttle with it.
16565 TestCompletionCallback callback1;
16566 rv = trans1->Start(&request, callback1.callback(), NetLogWithSource());
16567 EXPECT_EQ(ERR_IO_PENDING, rv);
16568
16569 trans1->SetPriority(IDLE);
16570
16571 base::RunLoop().RunUntilIdle();
16572 ASSERT_TRUE(callback.have_result());
16573 EXPECT_EQ(OK, callback.WaitForResult());
16574 ASSERT_TRUE(callback1.have_result());
16575 EXPECT_EQ(OK, callback1.WaitForResult());
16576}
16577
16578// Transaction will be destroyed when the unique_ptr goes out of scope.
16579void DestroyTransaction(std::unique_ptr<HttpTransaction> transaction) {}
16580
16581// Confirm that destroying a transaction from a SetPriority call by the
16582// throttler works properly.
16583TEST_F(HttpNetworkTransactionTest, ThrottlingPrioritySetDestroy) {
16584 TestNetworkStreamThrottler* throttler(nullptr);
16585 std::unique_ptr<HttpNetworkSession> session(
16586 CreateSessionWithThrottler(&session_deps_, &throttler));
16587
16588 // Send a simple request and make sure it goes through.
16589 HttpRequestInfo request;
16590 request.method = "GET";
16591 request.url = GURL("http://www.example.org/");
16592
16593 MockWrite data_writes[] = {
16594 MockWrite("GET / HTTP/1.1\r\n"
16595 "Host: www.example.org\r\n"
16596 "Connection: keep-alive\r\n\r\n"),
16597 };
16598 MockRead data_reads[] = {
16599 MockRead("HTTP/1.0 200 OK\r\n\r\n"), MockRead("hello world"),
16600 MockRead(SYNCHRONOUS, OK),
16601 };
16602 StaticSocketDataProvider reads(data_reads, arraysize(data_reads), data_writes,
16603 arraysize(data_writes));
16604 session_deps_.socket_factory->AddSocketDataProvider(&reads);
16605
16606 StaticSocketDataProvider reads1(data_reads, arraysize(data_reads),
16607 data_writes, arraysize(data_writes));
16608 session_deps_.socket_factory->AddSocketDataProvider(&reads1);
16609
16610 // Start a request that will be throttled at start; confirm it
16611 // doesn't complete.
16612 throttler->set_throttle_new_requests(true);
16613 std::unique_ptr<HttpTransaction> trans(
16614 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
16615
16616 TestCompletionCallback callback;
16617 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
16618 EXPECT_EQ(ERR_IO_PENDING, rv);
16619
16620 base::RunLoop().RunUntilIdle();
16621 EXPECT_EQ(LOAD_STATE_THROTTLED, trans->GetLoadState());
16622 EXPECT_FALSE(callback.have_result());
16623
16624 // Arrange for the set priority call on the above transaction to delete
16625 // the transaction.
16626 HttpTransaction* trans_ptr(trans.get());
16627 throttler->set_priority_change_closure(
16628 base::Bind(&DestroyTransaction, base::Passed(&trans)));
16629
16630 // Call it and check results (partially a "doesn't crash" test).
16631 trans_ptr->SetPriority(IDLE);
16632 trans_ptr = nullptr; // No longer a valid pointer.
16633
16634 base::RunLoop().RunUntilIdle();
16635 ASSERT_FALSE(callback.have_result());
16636}
16637
nharperb7441ef2016-01-25 23:54:1416638#if !defined(OS_IOS)
bncd16676a2016-07-20 16:23:0116639TEST_F(HttpNetworkTransactionTest, TokenBindingSpdy) {
fdoraya89e673c2017-01-31 21:44:2116640 // Required by ChannelIDService.
16641 base::test::ScopedTaskScheduler scoped_task_scheduler(
16642 base::MessageLoop::current());
16643
nharperb7441ef2016-01-25 23:54:1416644 const std::string https_url = "https://www.example.com";
16645 HttpRequestInfo request;
16646 request.url = GURL(https_url);
16647 request.method = "GET";
16648
16649 SSLSocketDataProvider ssl(ASYNC, OK);
16650 ssl.token_binding_negotiated = true;
16651 ssl.token_binding_key_param = TB_PARAM_ECDSAP256;
bnc3cf2a592016-08-11 14:48:3616652 ssl.next_proto = kProtoHTTP2;
nharperb7441ef2016-01-25 23:54:1416653 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
16654
bnc42331402016-07-25 13:36:1516655 SpdySerializedFrame resp(spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
bncdf80d44fd2016-07-15 20:27:4116656 SpdySerializedFrame body(spdy_util_.ConstructSpdyDataFrame(1, true));
16657 MockRead reads[] = {CreateMockRead(resp), CreateMockRead(body),
nharperb7441ef2016-01-25 23:54:1416658 MockRead(ASYNC, ERR_IO_PENDING)};
16659 StaticSocketDataProvider data(reads, arraysize(reads), nullptr, 0);
16660 session_deps_.socket_factory->AddSocketDataProvider(&data);
fdoraya89e673c2017-01-31 21:44:2116661 session_deps_.channel_id_service.reset(
16662 new ChannelIDService(new DefaultChannelIDStore(nullptr)));
danakj1fd259a02016-04-16 03:17:0916663 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
nharperb7441ef2016-01-25 23:54:1416664
16665 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
16666 TestCompletionCallback callback;
16667 EXPECT_EQ(ERR_IO_PENDING,
tfarina42834112016-09-22 13:38:2016668 trans.Start(&request, callback.callback(), NetLogWithSource()));
fdoray92e35a72016-06-10 15:54:5516669 base::RunLoop().RunUntilIdle();
nharperb7441ef2016-01-25 23:54:1416670
16671 EXPECT_TRUE(trans.GetResponseInfo()->was_fetched_via_spdy);
16672 HttpRequestHeaders headers;
16673 ASSERT_TRUE(trans.GetFullRequestHeaders(&headers));
16674 EXPECT_TRUE(headers.HasHeader(HttpRequestHeaders::kTokenBinding));
16675}
16676#endif // !defined(OS_IOS)
16677
eustasc7d27da2017-04-06 10:33:2016678void CheckContentEncodingMatching(SpdySessionDependencies* session_deps,
16679 const std::string& accept_encoding,
16680 const std::string& content_encoding,
16681 bool should_match) {
16682 HttpRequestInfo request;
16683 request.method = "GET";
16684 request.url = GURL("http://www.foo.com/");
16685 request.extra_headers.SetHeader(HttpRequestHeaders::kAcceptEncoding,
16686 accept_encoding);
16687
16688 std::unique_ptr<HttpNetworkSession> session(CreateSession(session_deps));
16689 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
16690 // Send headers successfully, but get an error while sending the body.
16691 MockWrite data_writes[] = {
16692 MockWrite("GET / HTTP/1.1\r\n"
16693 "Host: www.foo.com\r\n"
16694 "Connection: keep-alive\r\n"
16695 "Accept-Encoding: "),
16696 MockWrite(accept_encoding.data()), MockWrite("\r\n\r\n"),
16697 };
16698
16699 MockRead data_reads[] = {
16700 MockRead("HTTP/1.0 200 OK\r\n"), MockRead("Content-Encoding: "),
16701 MockRead(content_encoding.data()), MockRead("\r\n\r\n"),
16702 MockRead(SYNCHRONOUS, OK),
16703 };
16704 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
16705 arraysize(data_writes));
16706 session_deps->socket_factory->AddSocketDataProvider(&data);
16707
16708 TestCompletionCallback callback;
16709
16710 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
16711 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
16712
16713 rv = callback.WaitForResult();
16714 if (should_match) {
16715 EXPECT_THAT(rv, IsOk());
16716 } else {
16717 EXPECT_THAT(rv, IsError(ERR_CONTENT_DECODING_FAILED));
16718 }
16719}
16720
16721TEST_F(HttpNetworkTransactionTest, MatchContentEncoding1) {
16722 CheckContentEncodingMatching(&session_deps_, "gzip,sdch", "br", false);
16723}
16724
16725TEST_F(HttpNetworkTransactionTest, MatchContentEncoding2) {
16726 CheckContentEncodingMatching(&session_deps_, "identity;q=1, *;q=0", "", true);
16727}
16728
16729TEST_F(HttpNetworkTransactionTest, MatchContentEncoding3) {
16730 CheckContentEncodingMatching(&session_deps_, "identity;q=1, *;q=0", "gzip",
16731 false);
16732}
16733
[email protected]89ceba9a2009-03-21 03:46:0616734} // namespace net