blob: 9d8e6254c36b91bb7514ed1e637373d087d044c9 [file] [log] [blame]
[email protected]23e482282013-06-14 16:08:021// Copyright 2013 The Chromium Authors. All rights reserved.
license.botbf09a502008-08-24 00:55:552// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
initial.commit586acc5fe2008-07-26 22:42:524
[email protected]2d731a32010-04-29 01:04:065#include "net/http/http_network_transaction.h"
6
[email protected]77848d12008-11-14 00:00:227#include <math.h> // ceil
[email protected]5285d972011-10-18 18:56:348#include <stdarg.h>
sclittlebe1ccf62015-09-02 19:40:369#include <stdint.h>
danakj1fd259a02016-04-16 03:17:0910
avibf0746c2015-12-09 19:53:1411#include <limits>
rdsmith1d343be52016-10-21 20:37:5012#include <set>
[email protected]5285d972011-10-18 18:56:3413#include <string>
dchengc7eeda422015-12-26 03:56:4814#include <utility>
[email protected]95d88ffe2010-02-04 21:25:3315#include <vector>
[email protected]77848d12008-11-14 00:00:2216
[email protected]68bf9152008-09-25 19:47:3017#include "base/compiler_specific.h"
[email protected]57999812013-02-24 05:40:5218#include "base/files/file_path.h"
thestigd8df0332014-09-04 06:33:2919#include "base/files/file_util.h"
[email protected]f3da152d2012-06-02 01:00:5720#include "base/json/json_writer.h"
Adam Rice425cf122015-01-19 06:18:2421#include "base/logging.h"
Avi Drissman13fc8932015-12-20 04:40:4622#include "base/macros.h"
danakj1fd259a02016-04-16 03:17:0923#include "base/memory/ptr_util.h"
[email protected]bf828982013-08-14 18:01:4724#include "base/memory/weak_ptr.h"
[email protected]a34f61ee2014-03-18 20:59:4925#include "base/run_loop.h"
[email protected]125ef482013-06-11 18:32:4726#include "base/strings/string_util.h"
[email protected]750b2f3c2013-06-07 18:41:0527#include "base/strings/utf_string_conversions.h"
fdorayf33fede2017-05-11 21:18:1028#include "base/test/scoped_task_environment.h"
[email protected]f36a8132011-09-02 18:36:3329#include "base/test/test_file_util.h"
gabf767595f2016-05-11 18:50:3530#include "base/threading/thread_task_runner_handle.h"
[email protected]277d5942010-08-11 21:02:3531#include "net/base/auth.h"
mmenkecbc2b712014-10-09 20:29:0732#include "net/base/chunked_upload_data_stream.h"
[email protected]bacff652009-03-31 17:50:3333#include "net/base/completion_callback.h"
mmenkecbc2b712014-10-09 20:29:0734#include "net/base/elements_upload_data_stream.h"
[email protected]58e32bb2013-01-21 18:23:2535#include "net/base/load_timing_info.h"
36#include "net/base/load_timing_info_test_util.h"
Adam Rice425cf122015-01-19 06:18:2437#include "net/base/net_errors.h"
rdsmith1d343be52016-10-21 20:37:5038#include "net/base/network_throttle_manager.h"
tbansal28e68f82016-02-04 02:56:1539#include "net/base/proxy_delegate.h"
[email protected]ac790b42009-12-02 04:31:3140#include "net/base/request_priority.h"
initial.commit586acc5fe2008-07-26 22:42:5241#include "net/base/test_completion_callback.h"
tbansal28e68f82016-02-04 02:56:1542#include "net/base/test_proxy_delegate.h"
[email protected]b2d26cfd2012-12-11 10:36:0643#include "net/base/upload_bytes_element_reader.h"
[email protected]d98961652012-09-11 20:27:2144#include "net/base/upload_file_element_reader.h"
Bence Béky230ac612017-08-30 19:17:0845#include "net/cert/cert_status_flags.h"
[email protected]6e7845ae2013-03-29 21:48:1146#include "net/cert/mock_cert_verifier.h"
[email protected]bc71b8772013-04-10 20:55:1647#include "net/dns/host_cache.h"
[email protected]f2cb3cf2013-03-21 01:40:5348#include "net/dns/mock_host_resolver.h"
[email protected]df41d0d82014-03-13 00:43:2449#include "net/http/http_auth_challenge_tokenizer.h"
[email protected]3c32c5f2010-05-18 15:18:1250#include "net/http/http_auth_handler_digest.h"
[email protected]3fd9dae2010-06-21 11:39:0051#include "net/http/http_auth_handler_mock.h"
[email protected]385a4672009-03-11 22:21:2952#include "net/http/http_auth_handler_ntlm.h"
aberentbba302d2015-12-03 10:20:1953#include "net/http/http_auth_scheme.h"
Adam Rice425cf122015-01-19 06:18:2454#include "net/http/http_basic_state.h"
[email protected]0877e3d2009-10-17 22:29:5755#include "net/http/http_basic_stream.h"
initial.commit586acc5fe2008-07-26 22:42:5256#include "net/http/http_network_session.h"
[email protected]87bfa3f2010-09-30 14:54:5657#include "net/http/http_network_session_peer.h"
Adam Rice425cf122015-01-19 06:18:2458#include "net/http/http_request_headers.h"
mmenke5f94fda2016-06-02 20:54:1359#include "net/http/http_response_info.h"
[email protected]17291a022011-10-10 07:32:5360#include "net/http/http_server_properties_impl.h"
[email protected]0877e3d2009-10-17 22:29:5761#include "net/http/http_stream.h"
[email protected]8e6441ca2010-08-19 05:56:3862#include "net/http/http_stream_factory.h"
Adam Rice425cf122015-01-19 06:18:2463#include "net/http/http_stream_parser.h"
[email protected]c41737d2014-05-14 07:47:1964#include "net/http/http_transaction_test_util.h"
eroman87c53d62015-04-02 06:51:0765#include "net/log/net_log.h"
mikecirone8b85c432016-09-08 19:11:0066#include "net/log/net_log_event_type.h"
mikecironef22f9812016-10-04 03:40:1967#include "net/log/net_log_source.h"
vishal.b62985ca92015-04-17 08:45:5168#include "net/log/test_net_log.h"
mmenke43758e62015-05-04 21:09:4669#include "net/log/test_net_log_entry.h"
70#include "net/log/test_net_log_util.h"
sammc5dd160c2015-04-02 02:43:1371#include "net/proxy/mock_proxy_resolver.h"
[email protected]51fff29d2008-12-19 22:17:5372#include "net/proxy/proxy_config_service_fixed.h"
[email protected]e86839fd2013-08-14 18:29:0373#include "net/proxy/proxy_info.h"
[email protected]631f1322010-04-30 17:59:1174#include "net/proxy/proxy_resolver.h"
xunjieli96f2a402017-06-05 17:24:2775#include "net/proxy/proxy_resolver_factory.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"
Paul Jensena457017a2018-01-19 23:52:0484#include "net/socket/socket_tag.h"
[email protected]f7984fc62009-06-22 23:26:4485#include "net/socket/socket_test_util.h"
86#include "net/socket/ssl_client_socket.h"
bnc8f8f7d302017-04-24 18:08:0687#include "net/spdy/chromium/spdy_session.h"
88#include "net/spdy/chromium/spdy_session_pool.h"
89#include "net/spdy/chromium/spdy_test_util_common.h"
90#include "net/spdy/core/spdy_framer.h"
nharperb7441ef2016-01-25 23:54:1491#include "net/ssl/default_channel_id_store.h"
[email protected]536fd0b2013-03-14 17:41:5792#include "net/ssl/ssl_cert_request_info.h"
[email protected]e86839fd2013-08-14 18:29:0393#include "net/ssl/ssl_config_service.h"
[email protected]536fd0b2013-03-14 17:41:5794#include "net/ssl/ssl_config_service_defaults.h"
95#include "net/ssl/ssl_info.h"
svaldez7872fd02015-11-19 21:10:5496#include "net/ssl/ssl_private_key.h"
[email protected]6e7845ae2013-03-29 21:48:1197#include "net/test/cert_test_util.h"
robpercival214763f2016-07-01 23:27:0198#include "net/test/gtest_util.h"
fdorayf33fede2017-05-11 21:18:1099#include "net/test/net_test_suite.h"
rsleevia69c79a2016-06-22 03:28:43100#include "net/test/test_data_directory.h"
[email protected]baee31a2018-01-18 06:10:23101#include "net/traffic_annotation/network_traffic_annotation_test_helper.h"
[email protected]831e4a32013-11-14 02:14:44102#include "net/websockets/websocket_handshake_stream_base.h"
bncf4588402015-11-24 13:33:18103#include "testing/gmock/include/gmock/gmock.h"
initial.commit586acc5fe2008-07-26 22:42:52104#include "testing/gtest/include/gtest/gtest.h"
[email protected]23887f04f2008-12-02 19:20:15105#include "testing/platform_test.h"
[email protected]795cbf82013-07-22 09:37:27106#include "url/gurl.h"
initial.commit586acc5fe2008-07-26 22:42:52107
Zentaro Kavanagh5b27a6e22017-09-25 23:00:37108#if defined(NTLM_PORTABLE)
109#include "base/base64.h"
110#include "net/ntlm/ntlm_test_data.h"
111#endif
112
robpercival214763f2016-07-01 23:27:01113using net::test::IsError;
114using net::test::IsOk;
115
[email protected]ad65a3e2013-12-25 18:18:01116using base::ASCIIToUTF16;
117
initial.commit586acc5fe2008-07-26 22:42:52118//-----------------------------------------------------------------------------
119
ttuttle859dc7a2015-04-23 19:42:29120namespace net {
121
[email protected]13c8a092010-07-29 06:15:44122namespace {
123
rdsmith1d343be52016-10-21 20:37:50124class TestNetworkStreamThrottler : public NetworkThrottleManager {
125 public:
126 TestNetworkStreamThrottler()
127 : throttle_new_requests_(false),
128 num_set_priority_calls_(0),
129 last_priority_set_(IDLE) {}
130
131 ~TestNetworkStreamThrottler() override {
132 EXPECT_TRUE(outstanding_throttles_.empty());
133 }
134
135 // NetworkThrottleManager
136 std::unique_ptr<Throttle> CreateThrottle(ThrottleDelegate* delegate,
137 RequestPriority priority,
138 bool ignore_limits) override {
bnc87dcefc2017-05-25 12:47:58139 auto test_throttle =
Jeremy Roman0579ed62017-08-29 15:56:19140 std::make_unique<TestThrottle>(throttle_new_requests_, delegate, this);
rdsmith1d343be52016-10-21 20:37:50141 outstanding_throttles_.insert(test_throttle.get());
142 return std::move(test_throttle);
143 }
144
145 void UnthrottleAllRequests() {
146 std::set<TestThrottle*> outstanding_throttles_copy(outstanding_throttles_);
vmpstr6d9996c82017-02-23 00:43:25147 for (auto* throttle : outstanding_throttles_copy) {
rdsmithbf8c3c12016-11-18 18:16:24148 if (throttle->IsBlocked())
rdsmith1d343be52016-10-21 20:37:50149 throttle->Unthrottle();
150 }
151 }
152
153 void set_throttle_new_requests(bool throttle_new_requests) {
154 throttle_new_requests_ = throttle_new_requests;
155 }
156
157 // Includes both throttled and unthrottled throttles.
158 size_t num_outstanding_requests() const {
159 return outstanding_throttles_.size();
160 }
161
162 int num_set_priority_calls() const { return num_set_priority_calls_; }
163 RequestPriority last_priority_set() const { return last_priority_set_; }
164 void set_priority_change_closure(
165 const base::Closure& priority_change_closure) {
166 priority_change_closure_ = priority_change_closure;
167 }
168
169 private:
170 class TestThrottle : public NetworkThrottleManager::Throttle {
171 public:
172 ~TestThrottle() override { throttler_->OnThrottleDestroyed(this); }
173
174 // Throttle
rdsmithbf8c3c12016-11-18 18:16:24175 bool IsBlocked() const override { return throttled_; }
176 RequestPriority Priority() const override {
177 NOTREACHED();
178 return IDLE;
179 }
rdsmith1d343be52016-10-21 20:37:50180 void SetPriority(RequestPriority priority) override {
181 throttler_->SetPriorityCalled(priority);
182 }
183
184 TestThrottle(bool throttled,
185 ThrottleDelegate* delegate,
186 TestNetworkStreamThrottler* throttler)
187 : throttled_(throttled), delegate_(delegate), throttler_(throttler) {}
188
189 void Unthrottle() {
190 EXPECT_TRUE(throttled_);
191
192 throttled_ = false;
rdsmithbf8c3c12016-11-18 18:16:24193 delegate_->OnThrottleUnblocked(this);
rdsmith1d343be52016-10-21 20:37:50194 }
195
196 bool throttled_;
197 ThrottleDelegate* delegate_;
198 TestNetworkStreamThrottler* throttler_;
199 };
200
201 void OnThrottleDestroyed(TestThrottle* throttle) {
202 EXPECT_NE(0u, outstanding_throttles_.count(throttle));
203 outstanding_throttles_.erase(throttle);
204 }
205
206 void SetPriorityCalled(RequestPriority priority) {
207 ++num_set_priority_calls_;
208 last_priority_set_ = priority;
209 if (!priority_change_closure_.is_null())
210 priority_change_closure_.Run();
211 }
212
213 // Includes both throttled and unthrottled throttles.
214 std::set<TestThrottle*> outstanding_throttles_;
215 bool throttle_new_requests_;
216 int num_set_priority_calls_;
217 RequestPriority last_priority_set_;
218 base::Closure priority_change_closure_;
219
220 DISALLOW_COPY_AND_ASSIGN(TestNetworkStreamThrottler);
221};
222
[email protected]42cba2fb2013-03-29 19:58:57223const base::string16 kBar(ASCIIToUTF16("bar"));
224const base::string16 kBar2(ASCIIToUTF16("bar2"));
225const base::string16 kBar3(ASCIIToUTF16("bar3"));
226const base::string16 kBaz(ASCIIToUTF16("baz"));
227const base::string16 kFirst(ASCIIToUTF16("first"));
228const base::string16 kFoo(ASCIIToUTF16("foo"));
229const base::string16 kFoo2(ASCIIToUTF16("foo2"));
230const base::string16 kFoo3(ASCIIToUTF16("foo3"));
231const base::string16 kFou(ASCIIToUTF16("fou"));
232const base::string16 kSecond(ASCIIToUTF16("second"));
[email protected]42cba2fb2013-03-29 19:58:57233const base::string16 kWrongPassword(ASCIIToUTF16("wrongpassword"));
[email protected]13c8a092010-07-29 06:15:44234
bnc2df4b522016-07-08 18:17:43235const char kAlternativeServiceHttpHeader[] =
236 "Alt-Svc: h2=\"mail.example.org:443\"\r\n";
237
ttuttle859dc7a2015-04-23 19:42:29238int GetIdleSocketCountInTransportSocketPool(HttpNetworkSession* session) {
239 return session->GetTransportSocketPool(HttpNetworkSession::NORMAL_SOCKET_POOL)
240 ->IdleSocketCount();
[email protected]e5c026642012-03-17 00:14:02241}
242
ttuttle859dc7a2015-04-23 19:42:29243int GetIdleSocketCountInSSLSocketPool(HttpNetworkSession* session) {
244 return session->GetSSLSocketPool(HttpNetworkSession::NORMAL_SOCKET_POOL)
245 ->IdleSocketCount();
[email protected]e5c026642012-03-17 00:14:02246}
247
ttuttle859dc7a2015-04-23 19:42:29248bool IsTransportSocketPoolStalled(HttpNetworkSession* session) {
249 return session->GetTransportSocketPool(HttpNetworkSession::NORMAL_SOCKET_POOL)
250 ->IsStalled();
[email protected]043b68c82013-08-22 23:41:52251}
252
[email protected]f3da152d2012-06-02 01:00:57253// Takes in a Value created from a NetLogHttpResponseParameter, and returns
254// a JSONified list of headers as a single string. Uses single quotes instead
255// of double quotes for easier comparison. Returns false on failure.
[email protected]ea5ef4c2013-06-13 22:50:27256bool GetHeaders(base::DictionaryValue* params, std::string* headers) {
[email protected]f3da152d2012-06-02 01:00:57257 if (!params)
258 return false;
[email protected]ea5ef4c2013-06-13 22:50:27259 base::ListValue* header_list;
[email protected]f3da152d2012-06-02 01:00:57260 if (!params->GetList("headers", &header_list))
261 return false;
262 std::string double_quote_headers;
estade8d046462015-05-16 01:02:34263 base::JSONWriter::Write(*header_list, &double_quote_headers);
[email protected]466c9862013-12-03 22:05:28264 base::ReplaceChars(double_quote_headers, "\"", "'", headers);
[email protected]f3da152d2012-06-02 01:00:57265 return true;
266}
267
[email protected]029c83b62013-01-24 05:28:20268// Tests LoadTimingInfo in the case a socket is reused and no PAC script is
269// used.
ttuttle859dc7a2015-04-23 19:42:29270void TestLoadTimingReused(const LoadTimingInfo& load_timing_info) {
[email protected]029c83b62013-01-24 05:28:20271 EXPECT_TRUE(load_timing_info.socket_reused);
mikecironef22f9812016-10-04 03:40:19272 EXPECT_NE(NetLogSource::kInvalidId, load_timing_info.socket_log_id);
[email protected]58e32bb2013-01-21 18:23:25273
[email protected]029c83b62013-01-24 05:28:20274 EXPECT_TRUE(load_timing_info.proxy_resolve_start.is_null());
275 EXPECT_TRUE(load_timing_info.proxy_resolve_end.is_null());
276
ttuttle859dc7a2015-04-23 19:42:29277 ExpectConnectTimingHasNoTimes(load_timing_info.connect_timing);
[email protected]029c83b62013-01-24 05:28:20278 EXPECT_FALSE(load_timing_info.send_start.is_null());
[email protected]58e32bb2013-01-21 18:23:25279
280 EXPECT_LE(load_timing_info.send_start, load_timing_info.send_end);
[email protected]58e32bb2013-01-21 18:23:25281
[email protected]3b23a222013-05-15 21:33:25282 // Set at a higher level.
[email protected]58e32bb2013-01-21 18:23:25283 EXPECT_TRUE(load_timing_info.request_start_time.is_null());
284 EXPECT_TRUE(load_timing_info.request_start.is_null());
[email protected]3b23a222013-05-15 21:33:25285 EXPECT_TRUE(load_timing_info.receive_headers_end.is_null());
[email protected]58e32bb2013-01-21 18:23:25286}
287
[email protected]029c83b62013-01-24 05:28:20288// Tests LoadTimingInfo in the case a new socket is used and no PAC script is
289// used.
ttuttle859dc7a2015-04-23 19:42:29290void TestLoadTimingNotReused(const LoadTimingInfo& load_timing_info,
[email protected]58e32bb2013-01-21 18:23:25291 int connect_timing_flags) {
[email protected]029c83b62013-01-24 05:28:20292 EXPECT_FALSE(load_timing_info.socket_reused);
mikecironef22f9812016-10-04 03:40:19293 EXPECT_NE(NetLogSource::kInvalidId, load_timing_info.socket_log_id);
[email protected]029c83b62013-01-24 05:28:20294
295 EXPECT_TRUE(load_timing_info.proxy_resolve_start.is_null());
296 EXPECT_TRUE(load_timing_info.proxy_resolve_end.is_null());
297
ttuttle859dc7a2015-04-23 19:42:29298 ExpectConnectTimingHasTimes(load_timing_info.connect_timing,
299 connect_timing_flags);
[email protected]029c83b62013-01-24 05:28:20300 EXPECT_LE(load_timing_info.connect_timing.connect_end,
301 load_timing_info.send_start);
302
303 EXPECT_LE(load_timing_info.send_start, load_timing_info.send_end);
[email protected]029c83b62013-01-24 05:28:20304
[email protected]3b23a222013-05-15 21:33:25305 // Set at a higher level.
[email protected]029c83b62013-01-24 05:28:20306 EXPECT_TRUE(load_timing_info.request_start_time.is_null());
307 EXPECT_TRUE(load_timing_info.request_start.is_null());
[email protected]3b23a222013-05-15 21:33:25308 EXPECT_TRUE(load_timing_info.receive_headers_end.is_null());
[email protected]029c83b62013-01-24 05:28:20309}
310
311// Tests LoadTimingInfo in the case a socket is reused and a PAC script is
312// used.
ttuttle859dc7a2015-04-23 19:42:29313void TestLoadTimingReusedWithPac(const LoadTimingInfo& load_timing_info) {
[email protected]029c83b62013-01-24 05:28:20314 EXPECT_TRUE(load_timing_info.socket_reused);
mikecironef22f9812016-10-04 03:40:19315 EXPECT_NE(NetLogSource::kInvalidId, load_timing_info.socket_log_id);
[email protected]029c83b62013-01-24 05:28:20316
ttuttle859dc7a2015-04-23 19:42:29317 ExpectConnectTimingHasNoTimes(load_timing_info.connect_timing);
[email protected]029c83b62013-01-24 05:28:20318
319 EXPECT_FALSE(load_timing_info.proxy_resolve_start.is_null());
320 EXPECT_LE(load_timing_info.proxy_resolve_start,
321 load_timing_info.proxy_resolve_end);
322 EXPECT_LE(load_timing_info.proxy_resolve_end,
323 load_timing_info.send_start);
324 EXPECT_LE(load_timing_info.send_start, load_timing_info.send_end);
[email protected]029c83b62013-01-24 05:28:20325
[email protected]3b23a222013-05-15 21:33:25326 // Set at a higher level.
[email protected]029c83b62013-01-24 05:28:20327 EXPECT_TRUE(load_timing_info.request_start_time.is_null());
328 EXPECT_TRUE(load_timing_info.request_start.is_null());
[email protected]3b23a222013-05-15 21:33:25329 EXPECT_TRUE(load_timing_info.receive_headers_end.is_null());
[email protected]029c83b62013-01-24 05:28:20330}
331
332// Tests LoadTimingInfo in the case a new socket is used and a PAC script is
333// used.
ttuttle859dc7a2015-04-23 19:42:29334void TestLoadTimingNotReusedWithPac(const LoadTimingInfo& load_timing_info,
[email protected]029c83b62013-01-24 05:28:20335 int connect_timing_flags) {
336 EXPECT_FALSE(load_timing_info.socket_reused);
mikecironef22f9812016-10-04 03:40:19337 EXPECT_NE(NetLogSource::kInvalidId, load_timing_info.socket_log_id);
[email protected]029c83b62013-01-24 05:28:20338
339 EXPECT_FALSE(load_timing_info.proxy_resolve_start.is_null());
340 EXPECT_LE(load_timing_info.proxy_resolve_start,
341 load_timing_info.proxy_resolve_end);
342 EXPECT_LE(load_timing_info.proxy_resolve_end,
343 load_timing_info.connect_timing.connect_start);
ttuttle859dc7a2015-04-23 19:42:29344 ExpectConnectTimingHasTimes(load_timing_info.connect_timing,
345 connect_timing_flags);
[email protected]029c83b62013-01-24 05:28:20346 EXPECT_LE(load_timing_info.connect_timing.connect_end,
347 load_timing_info.send_start);
348
349 EXPECT_LE(load_timing_info.send_start, load_timing_info.send_end);
[email protected]029c83b62013-01-24 05:28:20350
[email protected]3b23a222013-05-15 21:33:25351 // Set at a higher level.
[email protected]029c83b62013-01-24 05:28:20352 EXPECT_TRUE(load_timing_info.request_start_time.is_null());
353 EXPECT_TRUE(load_timing_info.request_start.is_null());
[email protected]3b23a222013-05-15 21:33:25354 EXPECT_TRUE(load_timing_info.receive_headers_end.is_null());
[email protected]58e32bb2013-01-21 18:23:25355}
356
ttuttle859dc7a2015-04-23 19:42:29357void AddWebSocketHeaders(HttpRequestHeaders* headers) {
Adam Rice425cf122015-01-19 06:18:24358 headers->SetHeader("Connection", "Upgrade");
359 headers->SetHeader("Upgrade", "websocket");
bncce36dca22015-04-21 22:11:23360 headers->SetHeader("Origin", "http://www.example.org");
Adam Rice425cf122015-01-19 06:18:24361 headers->SetHeader("Sec-WebSocket-Version", "13");
362 headers->SetHeader("Sec-WebSocket-Key", "dGhlIHNhbXBsZSBub25jZQ==");
363}
364
danakj1fd259a02016-04-16 03:17:09365std::unique_ptr<HttpNetworkSession> CreateSession(
mmenkee65e7af2015-10-13 17:16:42366 SpdySessionDependencies* session_deps) {
[email protected]c6bf8152012-12-02 07:43:34367 return SpdySessionDependencies::SpdyCreateSession(session_deps);
[email protected]e8d536192008-10-17 22:21:14368}
369
rdsmith1d343be52016-10-21 20:37:50370// Note that the pointer written into |*throttler| will only be valid
371// for the lifetime of the returned HttpNetworkSession.
372std::unique_ptr<HttpNetworkSession> CreateSessionWithThrottler(
373 SpdySessionDependencies* session_deps,
374 TestNetworkStreamThrottler** throttler) {
375 std::unique_ptr<HttpNetworkSession> session(
376 SpdySessionDependencies::SpdyCreateSession(session_deps));
377
Jeremy Roman0579ed62017-08-29 15:56:19378 auto owned_throttler = std::make_unique<TestNetworkStreamThrottler>();
rdsmith1d343be52016-10-21 20:37:50379 *throttler = owned_throttler.get();
380
381 HttpNetworkSessionPeer peer(session.get());
382 peer.SetNetworkStreamThrottler(std::move(owned_throttler));
383
384 return session;
385}
386
xunjieli96f2a402017-06-05 17:24:27387class FailingProxyResolverFactory : public ProxyResolverFactory {
388 public:
389 FailingProxyResolverFactory() : ProxyResolverFactory(false) {}
390
391 // ProxyResolverFactory override.
392 int CreateProxyResolver(
393 const scoped_refptr<ProxyResolverScriptData>& script_data,
394 std::unique_ptr<ProxyResolver>* result,
395 const CompletionCallback& callback,
396 std::unique_ptr<Request>* request) override {
397 return ERR_PAC_SCRIPT_FAILED;
398 }
399};
400
[email protected]448d4ca52012-03-04 04:12:23401} // namespace
402
bncd16676a2016-07-20 16:23:01403class HttpNetworkTransactionTest : public PlatformTest {
[email protected]483fa202013-05-14 01:07:03404 public:
bncd16676a2016-07-20 16:23:01405 ~HttpNetworkTransactionTest() override {
[email protected]483fa202013-05-14 01:07:03406 // Important to restore the per-pool limit first, since the pool limit must
407 // always be greater than group limit, and the tests reduce both limits.
408 ClientSocketPoolManager::set_max_sockets_per_pool(
409 HttpNetworkSession::NORMAL_SOCKET_POOL, old_max_pool_sockets_);
410 ClientSocketPoolManager::set_max_sockets_per_group(
411 HttpNetworkSession::NORMAL_SOCKET_POOL, old_max_group_sockets_);
412 }
413
[email protected]e3ceb682011-06-28 23:55:46414 protected:
[email protected]23e482282013-06-14 16:08:02415 HttpNetworkTransactionTest()
bnc032658ba2016-09-26 18:17:15416 : ssl_(ASYNC, OK),
417 old_max_group_sockets_(ClientSocketPoolManager::max_sockets_per_group(
[email protected]483fa202013-05-14 01:07:03418 HttpNetworkSession::NORMAL_SOCKET_POOL)),
419 old_max_pool_sockets_(ClientSocketPoolManager::max_sockets_per_pool(
420 HttpNetworkSession::NORMAL_SOCKET_POOL)) {
bnca86731e2017-04-17 12:31:28421 session_deps_.enable_http2_alternative_service = true;
[email protected]483fa202013-05-14 01:07:03422 }
[email protected]bb88e1d32013-05-03 23:11:07423
[email protected]e3ceb682011-06-28 23:55:46424 struct SimpleGetHelperResult {
425 int rv;
426 std::string status_line;
427 std::string response_data;
sclittlefb249892015-09-10 21:33:22428 int64_t total_received_bytes;
429 int64_t total_sent_bytes;
[email protected]58e32bb2013-01-21 18:23:25430 LoadTimingInfo load_timing_info;
ttuttle1f2d7e92015-04-28 16:17:47431 ConnectionAttempts connection_attempts;
ttuttled9dbc652015-09-29 20:00:59432 IPEndPoint remote_endpoint_after_start;
[email protected]e3ceb682011-06-28 23:55:46433 };
434
dcheng67be2b1f2014-10-27 21:47:29435 void SetUp() override {
[email protected]0b0bf032010-09-21 18:08:50436 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
fdoray92e35a72016-06-10 15:54:55437 base::RunLoop().RunUntilIdle();
[email protected]2ff8b312010-04-26 22:20:54438 }
439
dcheng67be2b1f2014-10-27 21:47:29440 void TearDown() override {
[email protected]0b0bf032010-09-21 18:08:50441 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
fdoray92e35a72016-06-10 15:54:55442 base::RunLoop().RunUntilIdle();
[email protected]0e75a732008-10-16 20:36:09443 // Empty the current queue.
fdoray92e35a72016-06-10 15:54:55444 base::RunLoop().RunUntilIdle();
[email protected]0e75a732008-10-16 20:36:09445 PlatformTest::TearDown();
[email protected]0b0bf032010-09-21 18:08:50446 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
fdoray92e35a72016-06-10 15:54:55447 base::RunLoop().RunUntilIdle();
[email protected]0e75a732008-10-16 20:36:09448 }
449
[email protected]202965992011-12-07 23:04:51450 // Either |write_failure| specifies a write failure or |read_failure|
451 // specifies a read failure when using a reused socket. In either case, the
452 // failure should cause the network transaction to resend the request, and the
453 // other argument should be NULL.
454 void KeepAliveConnectionResendRequestTest(const MockWrite* write_failure,
455 const MockRead* read_failure);
initial.commit586acc5fe2008-07-26 22:42:52456
[email protected]a34f61ee2014-03-18 20:59:49457 // Either |write_failure| specifies a write failure or |read_failure|
458 // specifies a read failure when using a reused socket. In either case, the
459 // failure should cause the network transaction to resend the request, and the
460 // other argument should be NULL.
461 void PreconnectErrorResendRequestTest(const MockWrite* write_failure,
[email protected]09356c652014-03-25 15:36:10462 const MockRead* read_failure,
463 bool use_spdy);
[email protected]a34f61ee2014-03-18 20:59:49464
[email protected]5a60c8b2011-10-19 20:14:29465 SimpleGetHelperResult SimpleGetHelperForData(StaticSocketDataProvider* data[],
466 size_t data_count) {
[email protected]ff007e162009-05-23 09:13:15467 SimpleGetHelperResult out;
initial.commit586acc5fe2008-07-26 22:42:52468
[email protected]ff007e162009-05-23 09:13:15469 HttpRequestInfo request;
470 request.method = "GET";
bncce36dca22015-04-21 22:11:23471 request.url = GURL("http://www.example.org/");
initial.commit586acc5fe2008-07-26 22:42:52472
vishal.b62985ca92015-04-17 08:45:51473 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:07474 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:09475 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:16476 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:27477
[email protected]5a60c8b2011-10-19 20:14:29478 for (size_t i = 0; i < data_count; ++i) {
[email protected]bb88e1d32013-05-03 23:11:07479 session_deps_.socket_factory->AddSocketDataProvider(data[i]);
[email protected]5a60c8b2011-10-19 20:14:29480 }
initial.commit586acc5fe2008-07-26 22:42:52481
[email protected]49639fa2011-12-20 23:22:41482 TestCompletionCallback callback;
initial.commit586acc5fe2008-07-26 22:42:52483
eroman24bc6a12015-05-06 19:55:48484 EXPECT_TRUE(log.bound().IsCapturing());
bnc691fda62016-08-12 00:43:16485 int rv = trans.Start(&request, callback.callback(), log.bound());
robpercival214763f2016-07-01 23:27:01486 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
initial.commit586acc5fe2008-07-26 22:42:52487
[email protected]ff007e162009-05-23 09:13:15488 out.rv = callback.WaitForResult();
bnc691fda62016-08-12 00:43:16489 out.total_received_bytes = trans.GetTotalReceivedBytes();
490 out.total_sent_bytes = trans.GetTotalSentBytes();
[email protected]58e32bb2013-01-21 18:23:25491
492 // Even in the failure cases that use this function, connections are always
493 // successfully established before the error.
bnc691fda62016-08-12 00:43:16494 EXPECT_TRUE(trans.GetLoadTimingInfo(&out.load_timing_info));
[email protected]58e32bb2013-01-21 18:23:25495 TestLoadTimingNotReused(out.load_timing_info, CONNECT_TIMING_HAS_DNS_TIMES);
496
[email protected]ff007e162009-05-23 09:13:15497 if (out.rv != OK)
498 return out;
499
bnc691fda62016-08-12 00:43:16500 const HttpResponseInfo* response = trans.GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:50501 // Can't use ASSERT_* inside helper functions like this, so
502 // return an error.
wezca1070932016-05-26 20:30:52503 if (!response || !response->headers) {
[email protected]fe2255a2011-09-20 19:37:50504 out.rv = ERR_UNEXPECTED;
505 return out;
506 }
[email protected]ff007e162009-05-23 09:13:15507 out.status_line = response->headers->GetStatusLine();
508
[email protected]80a09a82012-11-16 17:40:06509 EXPECT_EQ("127.0.0.1", response->socket_address.host());
510 EXPECT_EQ(80, response->socket_address.port());
[email protected]6d81b482011-02-22 19:47:19511
ttuttled9dbc652015-09-29 20:00:59512 bool got_endpoint =
bnc691fda62016-08-12 00:43:16513 trans.GetRemoteEndpoint(&out.remote_endpoint_after_start);
ttuttled9dbc652015-09-29 20:00:59514 EXPECT_EQ(got_endpoint,
515 out.remote_endpoint_after_start.address().size() > 0);
516
bnc691fda62016-08-12 00:43:16517 rv = ReadTransaction(&trans, &out.response_data);
robpercival214763f2016-07-01 23:27:01518 EXPECT_THAT(rv, IsOk());
[email protected]b2fcd0e2010-12-01 15:19:40519
mmenke43758e62015-05-04 21:09:46520 TestNetLogEntry::List entries;
[email protected]b2fcd0e2010-12-01 15:19:40521 log.GetEntries(&entries);
[email protected]dbb83db2010-05-11 18:13:39522 size_t pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:00523 entries, 0, NetLogEventType::HTTP_TRANSACTION_SEND_REQUEST_HEADERS,
524 NetLogEventPhase::NONE);
[email protected]dbb83db2010-05-11 18:13:39525 ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:00526 entries, pos, NetLogEventType::HTTP_TRANSACTION_READ_RESPONSE_HEADERS,
527 NetLogEventPhase::NONE);
[email protected]ff007e162009-05-23 09:13:15528
[email protected]f3da152d2012-06-02 01:00:57529 std::string line;
530 EXPECT_TRUE(entries[pos].GetStringValue("line", &line));
531 EXPECT_EQ("GET / HTTP/1.1\r\n", line);
532
[email protected]79e1fd62013-06-20 06:50:04533 HttpRequestHeaders request_headers;
bnc691fda62016-08-12 00:43:16534 EXPECT_TRUE(trans.GetFullRequestHeaders(&request_headers));
[email protected]79e1fd62013-06-20 06:50:04535 std::string value;
536 EXPECT_TRUE(request_headers.GetHeader("Host", &value));
bncce36dca22015-04-21 22:11:23537 EXPECT_EQ("www.example.org", value);
[email protected]79e1fd62013-06-20 06:50:04538 EXPECT_TRUE(request_headers.GetHeader("Connection", &value));
539 EXPECT_EQ("keep-alive", value);
540
541 std::string response_headers;
542 EXPECT_TRUE(GetHeaders(entries[pos].params.get(), &response_headers));
bncce36dca22015-04-21 22:11:23543 EXPECT_EQ("['Host: www.example.org','Connection: keep-alive']",
[email protected]79e1fd62013-06-20 06:50:04544 response_headers);
[email protected]3deb9a52010-11-11 00:24:40545
bnc691fda62016-08-12 00:43:16546 out.total_received_bytes = trans.GetTotalReceivedBytes();
sclittlefb249892015-09-10 21:33:22547 // The total number of sent bytes should not have changed.
bnc691fda62016-08-12 00:43:16548 EXPECT_EQ(out.total_sent_bytes, trans.GetTotalSentBytes());
sclittlefb249892015-09-10 21:33:22549
bnc691fda62016-08-12 00:43:16550 trans.GetConnectionAttempts(&out.connection_attempts);
[email protected]aecfbf22008-10-16 02:02:47551 return out;
[email protected]ff007e162009-05-23 09:13:15552 }
initial.commit586acc5fe2008-07-26 22:42:52553
[email protected]5a60c8b2011-10-19 20:14:29554 SimpleGetHelperResult SimpleGetHelper(MockRead data_reads[],
555 size_t reads_count) {
sclittlefb249892015-09-10 21:33:22556 MockWrite data_writes[] = {
557 MockWrite("GET / HTTP/1.1\r\n"
558 "Host: www.example.org\r\n"
559 "Connection: keep-alive\r\n\r\n"),
560 };
[email protected]5a60c8b2011-10-19 20:14:29561
sclittlefb249892015-09-10 21:33:22562 StaticSocketDataProvider reads(data_reads, reads_count, data_writes,
563 arraysize(data_writes));
564 StaticSocketDataProvider* data[] = {&reads};
565 SimpleGetHelperResult out = SimpleGetHelperForData(data, 1);
566
567 EXPECT_EQ(CountWriteBytes(data_writes, arraysize(data_writes)),
568 out.total_sent_bytes);
569 return out;
[email protected]b8015c42013-12-24 15:18:19570 }
571
bnc032658ba2016-09-26 18:17:15572 void AddSSLSocketData() {
573 ssl_.next_proto = kProtoHTTP2;
Ryan Sleevi4f832092017-11-21 23:25:49574 ssl_.ssl_info.cert =
575 ImportCertFromFile(GetTestCertsDirectory(), "spdy_pooling.pem");
576 ASSERT_TRUE(ssl_.ssl_info.cert);
bnc032658ba2016-09-26 18:17:15577 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_);
578 }
579
[email protected]ff007e162009-05-23 09:13:15580 void ConnectStatusHelperWithExpectedStatus(const MockRead& status,
581 int expected_status);
initial.commit586acc5fe2008-07-26 22:42:52582
[email protected]ff007e162009-05-23 09:13:15583 void ConnectStatusHelper(const MockRead& status);
[email protected]bb88e1d32013-05-03 23:11:07584
585 void BypassHostCacheOnRefreshHelper(int load_flags);
586
587 void CheckErrorIsPassedBack(int error, IoMode mode);
588
[email protected]4bd46222013-05-14 19:32:23589 SpdyTestUtil spdy_util_;
[email protected]bb88e1d32013-05-03 23:11:07590 SpdySessionDependencies session_deps_;
bnc032658ba2016-09-26 18:17:15591 SSLSocketDataProvider ssl_;
[email protected]483fa202013-05-14 01:07:03592
593 // Original socket limits. Some tests set these. Safest to always restore
594 // them once each test has been run.
595 int old_max_group_sockets_;
596 int old_max_pool_sockets_;
[email protected]ff007e162009-05-23 09:13:15597};
[email protected]231d5a32008-09-13 00:45:27598
[email protected]448d4ca52012-03-04 04:12:23599namespace {
600
ryansturm49a8cb12016-06-15 16:51:09601class BeforeHeadersSentHandler {
[email protected]597a1ab2014-06-26 08:12:27602 public:
ryansturm49a8cb12016-06-15 16:51:09603 BeforeHeadersSentHandler()
604 : observed_before_headers_sent_with_proxy_(false),
605 observed_before_headers_sent_(false) {}
[email protected]597a1ab2014-06-26 08:12:27606
ryansturm49a8cb12016-06-15 16:51:09607 void OnBeforeHeadersSent(const ProxyInfo& proxy_info,
608 HttpRequestHeaders* request_headers) {
609 observed_before_headers_sent_ = true;
610 if (!proxy_info.is_http() && !proxy_info.is_https() &&
611 !proxy_info.is_quic()) {
612 return;
613 }
614 observed_before_headers_sent_with_proxy_ = true;
[email protected]597a1ab2014-06-26 08:12:27615 observed_proxy_server_uri_ = proxy_info.proxy_server().ToURI();
616 }
617
ryansturm49a8cb12016-06-15 16:51:09618 bool observed_before_headers_sent_with_proxy() const {
619 return observed_before_headers_sent_with_proxy_;
620 }
621
622 bool observed_before_headers_sent() const {
623 return observed_before_headers_sent_;
[email protected]597a1ab2014-06-26 08:12:27624 }
625
626 std::string observed_proxy_server_uri() const {
627 return observed_proxy_server_uri_;
628 }
629
630 private:
ryansturm49a8cb12016-06-15 16:51:09631 bool observed_before_headers_sent_with_proxy_;
632 bool observed_before_headers_sent_;
[email protected]597a1ab2014-06-26 08:12:27633 std::string observed_proxy_server_uri_;
634
ryansturm49a8cb12016-06-15 16:51:09635 DISALLOW_COPY_AND_ASSIGN(BeforeHeadersSentHandler);
[email protected]597a1ab2014-06-26 08:12:27636};
637
[email protected]15a5ccf82008-10-23 19:57:43638// Fill |str| with a long header list that consumes >= |size| bytes.
639void FillLargeHeadersString(std::string* str, int size) {
thestig9d3bb0c2015-01-24 00:49:51640 const char row[] =
[email protected]4ddaf2502008-10-23 18:26:19641 "SomeHeaderName: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx\r\n";
642 const int sizeof_row = strlen(row);
643 const int num_rows = static_cast<int>(
644 ceil(static_cast<float>(size) / sizeof_row));
645 const int sizeof_data = num_rows * sizeof_row;
646 DCHECK(sizeof_data >= size);
[email protected]15a5ccf82008-10-23 19:57:43647 str->reserve(sizeof_data);
[email protected]372d34a2008-11-05 21:30:51648
[email protected]4ddaf2502008-10-23 18:26:19649 for (int i = 0; i < num_rows; ++i)
[email protected]15a5ccf82008-10-23 19:57:43650 str->append(row, sizeof_row);
[email protected]4ddaf2502008-10-23 18:26:19651}
652
thakis84dff942015-07-28 20:47:38653#if defined(NTLM_PORTABLE)
Zentaro Kavanagh6ccee512017-09-28 18:34:09654uint64_t MockGetMSTime() {
655 // Tue, 23 May 2017 20:13:07 +0000
656 return 131400439870000000;
657}
658
[email protected]385a4672009-03-11 22:21:29659// Alternative functions that eliminate randomness and dependency on the local
660// host name so that the generated NTLM messages are reproducible.
Zentaro Kavanagh5b27a6e22017-09-25 23:00:37661void MockGenerateRandom(uint8_t* output, size_t n) {
662 // This is set to 0xaa because the client challenge for testing in
663 // [MS-NLMP] Section 4.2.1 is 8 bytes of 0xaa.
664 memset(output, 0xaa, n);
[email protected]385a4672009-03-11 22:21:29665}
666
[email protected]fe2bc6a2009-03-23 16:52:20667std::string MockGetHostName() {
Zentaro Kavanagh5b27a6e22017-09-25 23:00:37668 return ntlm::test::kHostnameAscii;
[email protected]385a4672009-03-11 22:21:29669}
thakis84dff942015-07-28 20:47:38670#endif // defined(NTLM_PORTABLE)
[email protected]385a4672009-03-11 22:21:29671
[email protected]e60e47a2010-07-14 03:37:18672template<typename ParentPool>
673class CaptureGroupNameSocketPool : public ParentPool {
[email protected]04e5be32009-06-26 20:00:31674 public:
[email protected]9e1bdd32011-02-03 21:48:34675 CaptureGroupNameSocketPool(HostResolver* host_resolver,
676 CertVerifier* cert_verifier);
[email protected]e60e47a2010-07-14 03:37:18677
[email protected]d80a4322009-08-14 07:07:49678 const std::string last_group_name_received() const {
679 return last_group_name_;
680 }
681
Tarun Bansal162eabe52018-01-20 01:16:39682 bool socket_requested() const { return socket_requested_; }
683
dmichaeld6e570d2014-12-18 22:30:57684 int RequestSocket(const std::string& group_name,
685 const void* socket_params,
686 RequestPriority priority,
Paul Jensen8d6f87ec2018-01-13 00:46:54687 const SocketTag& socket_tag,
mmenked3641e12016-01-28 16:06:15688 ClientSocketPool::RespectLimits respect_limits,
dmichaeld6e570d2014-12-18 22:30:57689 ClientSocketHandle* handle,
690 const CompletionCallback& callback,
tfarina42834112016-09-22 13:38:20691 const NetLogWithSource& net_log) override {
[email protected]04e5be32009-06-26 20:00:31692 last_group_name_ = group_name;
Tarun Bansal162eabe52018-01-20 01:16:39693 socket_requested_ = true;
[email protected]04e5be32009-06-26 20:00:31694 return ERR_IO_PENDING;
695 }
dmichaeld6e570d2014-12-18 22:30:57696 void CancelRequest(const std::string& group_name,
697 ClientSocketHandle* handle) override {}
698 void ReleaseSocket(const std::string& group_name,
danakj1fd259a02016-04-16 03:17:09699 std::unique_ptr<StreamSocket> socket,
dmichaeld6e570d2014-12-18 22:30:57700 int id) override {}
701 void CloseIdleSockets() override {}
xunjieli92feb332017-03-03 17:19:23702 void CloseIdleSocketsInGroup(const std::string& group_name) override {}
dmichaeld6e570d2014-12-18 22:30:57703 int IdleSocketCount() const override { return 0; }
704 int IdleSocketCountInGroup(const std::string& group_name) const override {
[email protected]04e5be32009-06-26 20:00:31705 return 0;
706 }
dmichaeld6e570d2014-12-18 22:30:57707 LoadState GetLoadState(const std::string& group_name,
708 const ClientSocketHandle* handle) const override {
[email protected]04e5be32009-06-26 20:00:31709 return LOAD_STATE_IDLE;
710 }
dmichaeld6e570d2014-12-18 22:30:57711 base::TimeDelta ConnectionTimeout() const override {
[email protected]a796bcec2010-03-22 17:17:26712 return base::TimeDelta();
713 }
[email protected]d80a4322009-08-14 07:07:49714
715 private:
[email protected]04e5be32009-06-26 20:00:31716 std::string last_group_name_;
Tarun Bansal162eabe52018-01-20 01:16:39717 bool socket_requested_ = false;
[email protected]04e5be32009-06-26 20:00:31718};
719
[email protected]ab739042011-04-07 15:22:28720typedef CaptureGroupNameSocketPool<TransportClientSocketPool>
721CaptureGroupNameTransportSocketPool;
[email protected]e772db3f2010-07-12 18:11:13722typedef CaptureGroupNameSocketPool<HttpProxyClientSocketPool>
723CaptureGroupNameHttpProxySocketPool;
[email protected]2d731a32010-04-29 01:04:06724typedef CaptureGroupNameSocketPool<SOCKSClientSocketPool>
[email protected]2227c692010-05-04 15:36:11725CaptureGroupNameSOCKSSocketPool;
[email protected]e60e47a2010-07-14 03:37:18726typedef CaptureGroupNameSocketPool<SSLClientSocketPool>
727CaptureGroupNameSSLSocketPool;
728
rkaplowd90695c2015-03-25 22:12:41729template <typename ParentPool>
[email protected]e60e47a2010-07-14 03:37:18730CaptureGroupNameSocketPool<ParentPool>::CaptureGroupNameSocketPool(
[email protected]9e1bdd32011-02-03 21:48:34731 HostResolver* host_resolver,
732 CertVerifier* /* cert_verifier */)
tbansal7b403bcc2016-04-13 22:33:21733 : ParentPool(0, 0, host_resolver, NULL, NULL, NULL) {}
[email protected]e60e47a2010-07-14 03:37:18734
hashimoto0d3e4fb2015-01-09 05:02:50735template <>
[email protected]2df19bb2010-08-25 20:13:46736CaptureGroupNameHttpProxySocketPool::CaptureGroupNameSocketPool(
hashimotodae13b02015-01-15 04:28:21737 HostResolver* /* host_resolver */,
[email protected]9e1bdd32011-02-03 21:48:34738 CertVerifier* /* cert_verifier */)
tbansal16196a1e2017-06-09 01:50:09739 : HttpProxyClientSocketPool(0, 0, NULL, NULL, NULL, NULL) {}
[email protected]2df19bb2010-08-25 20:13:46740
[email protected]007b3f82013-04-09 08:46:45741template <>
[email protected]e60e47a2010-07-14 03:37:18742CaptureGroupNameSSLSocketPool::CaptureGroupNameSocketPool(
hashimotodae13b02015-01-15 04:28:21743 HostResolver* /* host_resolver */,
[email protected]9e1bdd32011-02-03 21:48:34744 CertVerifier* cert_verifier)
[email protected]007b3f82013-04-09 08:46:45745 : SSLClientSocketPool(0,
746 0,
[email protected]007b3f82013-04-09 08:46:45747 cert_verifier,
748 NULL,
749 NULL,
[email protected]284303b62013-11-28 15:11:54750 NULL,
eranm6571b2b2014-12-03 15:53:23751 NULL,
[email protected]007b3f82013-04-09 08:46:45752 std::string(),
753 NULL,
754 NULL,
755 NULL,
756 NULL,
757 NULL,
[email protected]8e458552014-08-05 00:02:15758 NULL) {
759}
[email protected]2227c692010-05-04 15:36:11760
[email protected]231d5a32008-09-13 00:45:27761//-----------------------------------------------------------------------------
762
[email protected]79cb5c12011-09-12 13:12:04763// Helper functions for validating that AuthChallengeInfo's are correctly
764// configured for common cases.
765bool CheckBasicServerAuth(const AuthChallengeInfo* auth_challenge) {
766 if (!auth_challenge)
767 return false;
768 EXPECT_FALSE(auth_challenge->is_proxy);
asanka098c0092016-06-16 20:18:43769 EXPECT_EQ("http://www.example.org", auth_challenge->challenger.Serialize());
[email protected]79cb5c12011-09-12 13:12:04770 EXPECT_EQ("MyRealm1", auth_challenge->realm);
aberentbba302d2015-12-03 10:20:19771 EXPECT_EQ(kBasicAuthScheme, auth_challenge->scheme);
[email protected]79cb5c12011-09-12 13:12:04772 return true;
773}
774
775bool CheckBasicProxyAuth(const AuthChallengeInfo* auth_challenge) {
776 if (!auth_challenge)
777 return false;
778 EXPECT_TRUE(auth_challenge->is_proxy);
asanka098c0092016-06-16 20:18:43779 EXPECT_EQ("http://myproxy:70", auth_challenge->challenger.Serialize());
780 EXPECT_EQ("MyRealm1", auth_challenge->realm);
781 EXPECT_EQ(kBasicAuthScheme, auth_challenge->scheme);
782 return true;
783}
784
785bool CheckBasicSecureProxyAuth(const AuthChallengeInfo* auth_challenge) {
786 if (!auth_challenge)
787 return false;
788 EXPECT_TRUE(auth_challenge->is_proxy);
789 EXPECT_EQ("https://myproxy:70", auth_challenge->challenger.Serialize());
[email protected]79cb5c12011-09-12 13:12:04790 EXPECT_EQ("MyRealm1", auth_challenge->realm);
aberentbba302d2015-12-03 10:20:19791 EXPECT_EQ(kBasicAuthScheme, auth_challenge->scheme);
[email protected]79cb5c12011-09-12 13:12:04792 return true;
793}
794
795bool CheckDigestServerAuth(const AuthChallengeInfo* auth_challenge) {
796 if (!auth_challenge)
797 return false;
798 EXPECT_FALSE(auth_challenge->is_proxy);
asanka098c0092016-06-16 20:18:43799 EXPECT_EQ("http://www.example.org", auth_challenge->challenger.Serialize());
[email protected]79cb5c12011-09-12 13:12:04800 EXPECT_EQ("digestive", auth_challenge->realm);
aberentbba302d2015-12-03 10:20:19801 EXPECT_EQ(kDigestAuthScheme, auth_challenge->scheme);
[email protected]79cb5c12011-09-12 13:12:04802 return true;
803}
804
thakis84dff942015-07-28 20:47:38805#if defined(NTLM_PORTABLE)
[email protected]79cb5c12011-09-12 13:12:04806bool CheckNTLMServerAuth(const AuthChallengeInfo* auth_challenge) {
807 if (!auth_challenge)
808 return false;
809 EXPECT_FALSE(auth_challenge->is_proxy);
Bence Béky83eb3512017-09-05 12:56:09810 EXPECT_EQ("https://172.22.68.17", auth_challenge->challenger.Serialize());
[email protected]79cb5c12011-09-12 13:12:04811 EXPECT_EQ(std::string(), auth_challenge->realm);
aberentbba302d2015-12-03 10:20:19812 EXPECT_EQ(kNtlmAuthScheme, auth_challenge->scheme);
[email protected]79cb5c12011-09-12 13:12:04813 return true;
814}
thakis84dff942015-07-28 20:47:38815#endif // defined(NTLM_PORTABLE)
[email protected]79cb5c12011-09-12 13:12:04816
[email protected]448d4ca52012-03-04 04:12:23817} // namespace
818
bncd16676a2016-07-20 16:23:01819TEST_F(HttpNetworkTransactionTest, Basic) {
danakj1fd259a02016-04-16 03:17:09820 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:16821 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]231d5a32008-09-13 00:45:27822}
823
bncd16676a2016-07-20 16:23:01824TEST_F(HttpNetworkTransactionTest, SimpleGET) {
[email protected]231d5a32008-09-13 00:45:27825 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:35826 MockRead("HTTP/1.0 200 OK\r\n\r\n"),
827 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:06828 MockRead(SYNCHRONOUS, OK),
[email protected]231d5a32008-09-13 00:45:27829 };
[email protected]31a2bfe2010-02-09 08:03:39830 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
831 arraysize(data_reads));
robpercival214763f2016-07-01 23:27:01832 EXPECT_THAT(out.rv, IsOk());
[email protected]231d5a32008-09-13 00:45:27833 EXPECT_EQ("HTTP/1.0 200 OK", out.status_line);
834 EXPECT_EQ("hello world", out.response_data);
sclittlefb249892015-09-10 21:33:22835 int64_t reads_size = CountReadBytes(data_reads, arraysize(data_reads));
836 EXPECT_EQ(reads_size, out.total_received_bytes);
ttuttle1f2d7e92015-04-28 16:17:47837 EXPECT_EQ(0u, out.connection_attempts.size());
ttuttled9dbc652015-09-29 20:00:59838
839 EXPECT_FALSE(out.remote_endpoint_after_start.address().empty());
[email protected]231d5a32008-09-13 00:45:27840}
841
842// Response with no status line.
bncd16676a2016-07-20 16:23:01843TEST_F(HttpNetworkTransactionTest, SimpleGETNoHeaders) {
[email protected]231d5a32008-09-13 00:45:27844 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:35845 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:06846 MockRead(SYNCHRONOUS, OK),
[email protected]231d5a32008-09-13 00:45:27847 };
[email protected]31a2bfe2010-02-09 08:03:39848 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
849 arraysize(data_reads));
mmenkea2dcd3bf2016-08-16 21:49:41850 EXPECT_THAT(out.rv, IsOk());
851 EXPECT_EQ("HTTP/0.9 200 OK", out.status_line);
852 EXPECT_EQ("hello world", out.response_data);
853 int64_t reads_size = CountReadBytes(data_reads, arraysize(data_reads));
854 EXPECT_EQ(reads_size, out.total_received_bytes);
[email protected]231d5a32008-09-13 00:45:27855}
856
mmenkea7da6da2016-09-01 21:56:52857// Response with no status line, and a weird port. Should fail by default.
858TEST_F(HttpNetworkTransactionTest, SimpleGETNoHeadersWeirdPort) {
859 MockRead data_reads[] = {
860 MockRead("hello world"), MockRead(SYNCHRONOUS, OK),
861 };
862
863 StaticSocketDataProvider data(data_reads, arraysize(data_reads), nullptr, 0);
864 session_deps_.socket_factory->AddSocketDataProvider(&data);
865
866 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
867
krasinc06a72a2016-12-21 03:42:46868 HttpRequestInfo request;
bnc87dcefc2017-05-25 12:47:58869 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:19870 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
mmenkea7da6da2016-09-01 21:56:52871
mmenkea7da6da2016-09-01 21:56:52872 request.method = "GET";
873 request.url = GURL("http://www.example.com:2000/");
874 TestCompletionCallback callback;
tfarina42834112016-09-22 13:38:20875 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
mmenkea7da6da2016-09-01 21:56:52876 EXPECT_THAT(callback.GetResult(rv), IsError(ERR_INVALID_HTTP_RESPONSE));
877}
878
Shivani Sharmafdcaefd2017-11-02 00:12:26879// Tests that request info can be destroyed after the headers phase is complete.
880TEST_F(HttpNetworkTransactionTest, SimpleGETNoReadDestroyRequestInfo) {
881 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
882 auto trans =
883 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
884
885 MockRead data_reads[] = {
886 MockRead("HTTP/1.0 200 OK\r\n"), MockRead("Connection: keep-alive\r\n"),
887 MockRead("Content-Length: 100\r\n\r\n"), MockRead(SYNCHRONOUS, 0),
888 };
889 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
890 session_deps_.socket_factory->AddSocketDataProvider(&data);
891
892 TestCompletionCallback callback;
893
894 {
895 auto request = std::make_unique<HttpRequestInfo>();
896 request->method = "GET";
897 request->url = GURL("http://www.example.org/");
898
899 int rv =
900 trans->Start(request.get(), callback.callback(), NetLogWithSource());
901
902 EXPECT_THAT(callback.GetResult(rv), IsOk());
903 } // Let request info be destroyed.
904
905 trans.reset();
906}
907
mmenkea7da6da2016-09-01 21:56:52908// Response with no status line, and a weird port. Option to allow weird ports
909// enabled.
910TEST_F(HttpNetworkTransactionTest, SimpleGETNoHeadersWeirdPortAllowed) {
911 MockRead data_reads[] = {
912 MockRead("hello world"), MockRead(SYNCHRONOUS, OK),
913 };
914
915 StaticSocketDataProvider data(data_reads, arraysize(data_reads), nullptr, 0);
916 session_deps_.socket_factory->AddSocketDataProvider(&data);
917 session_deps_.http_09_on_non_default_ports_enabled = true;
918 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
919
krasinc06a72a2016-12-21 03:42:46920 HttpRequestInfo request;
bnc87dcefc2017-05-25 12:47:58921 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:19922 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
mmenkea7da6da2016-09-01 21:56:52923
mmenkea7da6da2016-09-01 21:56:52924 request.method = "GET";
925 request.url = GURL("http://www.example.com:2000/");
926 TestCompletionCallback callback;
tfarina42834112016-09-22 13:38:20927 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
mmenkea7da6da2016-09-01 21:56:52928 EXPECT_THAT(callback.GetResult(rv), IsOk());
929
930 const HttpResponseInfo* info = trans->GetResponseInfo();
931 ASSERT_TRUE(info->headers);
932 EXPECT_EQ("HTTP/0.9 200 OK", info->headers->GetStatusLine());
933
934 // Don't bother to read the body - that's verified elsewhere, important thing
935 // is that the option to allow HTTP/0.9 on non-default ports is respected.
936}
937
[email protected]231d5a32008-09-13 00:45:27938// Allow up to 4 bytes of junk to precede status line.
bncd16676a2016-07-20 16:23:01939TEST_F(HttpNetworkTransactionTest, StatusLineJunk3Bytes) {
[email protected]231d5a32008-09-13 00:45:27940 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:35941 MockRead("xxxHTTP/1.0 404 Not Found\nServer: blah\n\nDATA"),
[email protected]8ddf8322012-02-23 18:08:06942 MockRead(SYNCHRONOUS, OK),
[email protected]231d5a32008-09-13 00:45:27943 };
[email protected]31a2bfe2010-02-09 08:03:39944 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
945 arraysize(data_reads));
robpercival214763f2016-07-01 23:27:01946 EXPECT_THAT(out.rv, IsOk());
[email protected]231d5a32008-09-13 00:45:27947 EXPECT_EQ("HTTP/1.0 404 Not Found", out.status_line);
948 EXPECT_EQ("DATA", out.response_data);
sclittlefb249892015-09-10 21:33:22949 int64_t reads_size = CountReadBytes(data_reads, arraysize(data_reads));
950 EXPECT_EQ(reads_size, out.total_received_bytes);
[email protected]231d5a32008-09-13 00:45:27951}
952
953// Allow up to 4 bytes of junk to precede status line.
bncd16676a2016-07-20 16:23:01954TEST_F(HttpNetworkTransactionTest, StatusLineJunk4Bytes) {
[email protected]231d5a32008-09-13 00:45:27955 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:35956 MockRead("\n\nQJHTTP/1.0 404 Not Found\nServer: blah\n\nDATA"),
[email protected]8ddf8322012-02-23 18:08:06957 MockRead(SYNCHRONOUS, OK),
[email protected]231d5a32008-09-13 00:45:27958 };
[email protected]31a2bfe2010-02-09 08:03:39959 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
960 arraysize(data_reads));
robpercival214763f2016-07-01 23:27:01961 EXPECT_THAT(out.rv, IsOk());
[email protected]231d5a32008-09-13 00:45:27962 EXPECT_EQ("HTTP/1.0 404 Not Found", out.status_line);
963 EXPECT_EQ("DATA", out.response_data);
sclittlefb249892015-09-10 21:33:22964 int64_t reads_size = CountReadBytes(data_reads, arraysize(data_reads));
965 EXPECT_EQ(reads_size, out.total_received_bytes);
[email protected]231d5a32008-09-13 00:45:27966}
967
968// Beyond 4 bytes of slop and it should fail to find a status line.
bncd16676a2016-07-20 16:23:01969TEST_F(HttpNetworkTransactionTest, StatusLineJunk5Bytes) {
[email protected]231d5a32008-09-13 00:45:27970 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:35971 MockRead("xxxxxHTTP/1.1 404 Not Found\nServer: blah"),
[email protected]8ddf8322012-02-23 18:08:06972 MockRead(SYNCHRONOUS, OK),
[email protected]231d5a32008-09-13 00:45:27973 };
[email protected]31a2bfe2010-02-09 08:03:39974 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
975 arraysize(data_reads));
mmenkea2dcd3bf2016-08-16 21:49:41976 EXPECT_THAT(out.rv, IsOk());
977 EXPECT_EQ("HTTP/0.9 200 OK", out.status_line);
978 EXPECT_EQ("xxxxxHTTP/1.1 404 Not Found\nServer: blah", out.response_data);
979 int64_t reads_size = CountReadBytes(data_reads, arraysize(data_reads));
980 EXPECT_EQ(reads_size, out.total_received_bytes);
[email protected]231d5a32008-09-13 00:45:27981}
982
983// Same as StatusLineJunk4Bytes, except the read chunks are smaller.
bncd16676a2016-07-20 16:23:01984TEST_F(HttpNetworkTransactionTest, StatusLineJunk4Bytes_Slow) {
[email protected]231d5a32008-09-13 00:45:27985 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:35986 MockRead("\n"),
987 MockRead("\n"),
988 MockRead("Q"),
989 MockRead("J"),
990 MockRead("HTTP/1.0 404 Not Found\nServer: blah\n\nDATA"),
[email protected]8ddf8322012-02-23 18:08:06991 MockRead(SYNCHRONOUS, OK),
[email protected]231d5a32008-09-13 00:45:27992 };
[email protected]31a2bfe2010-02-09 08:03:39993 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
994 arraysize(data_reads));
robpercival214763f2016-07-01 23:27:01995 EXPECT_THAT(out.rv, IsOk());
[email protected]231d5a32008-09-13 00:45:27996 EXPECT_EQ("HTTP/1.0 404 Not Found", out.status_line);
997 EXPECT_EQ("DATA", out.response_data);
sclittlefb249892015-09-10 21:33:22998 int64_t reads_size = CountReadBytes(data_reads, arraysize(data_reads));
999 EXPECT_EQ(reads_size, out.total_received_bytes);
[email protected]231d5a32008-09-13 00:45:271000}
1001
1002// Close the connection before enough bytes to have a status line.
bncd16676a2016-07-20 16:23:011003TEST_F(HttpNetworkTransactionTest, StatusLinePartial) {
[email protected]231d5a32008-09-13 00:45:271004 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:351005 MockRead("HTT"),
[email protected]8ddf8322012-02-23 18:08:061006 MockRead(SYNCHRONOUS, OK),
[email protected]231d5a32008-09-13 00:45:271007 };
[email protected]31a2bfe2010-02-09 08:03:391008 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
1009 arraysize(data_reads));
mmenkea2dcd3bf2016-08-16 21:49:411010 EXPECT_THAT(out.rv, IsOk());
1011 EXPECT_EQ("HTTP/0.9 200 OK", out.status_line);
1012 EXPECT_EQ("HTT", out.response_data);
1013 int64_t reads_size = CountReadBytes(data_reads, arraysize(data_reads));
1014 EXPECT_EQ(reads_size, out.total_received_bytes);
initial.commit586acc5fe2008-07-26 22:42:521015}
1016
[email protected]f9d44aa2008-09-23 23:57:171017// Simulate a 204 response, lacking a Content-Length header, sent over a
1018// persistent connection. The response should still terminate since a 204
1019// cannot have a response body.
bncd16676a2016-07-20 16:23:011020TEST_F(HttpNetworkTransactionTest, StopsReading204) {
[email protected]b8015c42013-12-24 15:18:191021 char junk[] = "junk";
[email protected]f9d44aa2008-09-23 23:57:171022 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:351023 MockRead("HTTP/1.1 204 No Content\r\n\r\n"),
[email protected]b8015c42013-12-24 15:18:191024 MockRead(junk), // Should not be read!!
[email protected]8ddf8322012-02-23 18:08:061025 MockRead(SYNCHRONOUS, OK),
[email protected]f9d44aa2008-09-23 23:57:171026 };
[email protected]31a2bfe2010-02-09 08:03:391027 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
1028 arraysize(data_reads));
robpercival214763f2016-07-01 23:27:011029 EXPECT_THAT(out.rv, IsOk());
[email protected]f9d44aa2008-09-23 23:57:171030 EXPECT_EQ("HTTP/1.1 204 No Content", out.status_line);
1031 EXPECT_EQ("", out.response_data);
sclittlefb249892015-09-10 21:33:221032 int64_t reads_size = CountReadBytes(data_reads, arraysize(data_reads));
1033 int64_t response_size = reads_size - strlen(junk);
1034 EXPECT_EQ(response_size, out.total_received_bytes);
[email protected]f9d44aa2008-09-23 23:57:171035}
1036
[email protected]0877e3d2009-10-17 22:29:571037// A simple request using chunked encoding with some extra data after.
bncd16676a2016-07-20 16:23:011038TEST_F(HttpNetworkTransactionTest, ChunkedEncoding) {
[email protected]b8015c42013-12-24 15:18:191039 std::string final_chunk = "0\r\n\r\n";
1040 std::string extra_data = "HTTP/1.1 200 OK\r\n";
1041 std::string last_read = final_chunk + extra_data;
[email protected]0877e3d2009-10-17 22:29:571042 MockRead data_reads[] = {
1043 MockRead("HTTP/1.1 200 OK\r\nTransfer-Encoding: chunked\r\n\r\n"),
1044 MockRead("5\r\nHello\r\n"),
1045 MockRead("1\r\n"),
1046 MockRead(" \r\n"),
1047 MockRead("5\r\nworld\r\n"),
[email protected]b8015c42013-12-24 15:18:191048 MockRead(last_read.data()),
[email protected]8ddf8322012-02-23 18:08:061049 MockRead(SYNCHRONOUS, OK),
[email protected]0877e3d2009-10-17 22:29:571050 };
[email protected]31a2bfe2010-02-09 08:03:391051 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
1052 arraysize(data_reads));
robpercival214763f2016-07-01 23:27:011053 EXPECT_THAT(out.rv, IsOk());
[email protected]0877e3d2009-10-17 22:29:571054 EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
1055 EXPECT_EQ("Hello world", out.response_data);
sclittlefb249892015-09-10 21:33:221056 int64_t reads_size = CountReadBytes(data_reads, arraysize(data_reads));
1057 int64_t response_size = reads_size - extra_data.size();
1058 EXPECT_EQ(response_size, out.total_received_bytes);
[email protected]0877e3d2009-10-17 22:29:571059}
1060
[email protected]9fe44f52010-09-23 18:36:001061// Next tests deal with http://crbug.com/56344.
1062
bncd16676a2016-07-20 16:23:011063TEST_F(HttpNetworkTransactionTest,
[email protected]9fe44f52010-09-23 18:36:001064 MultipleContentLengthHeadersNoTransferEncoding) {
1065 MockRead data_reads[] = {
1066 MockRead("HTTP/1.1 200 OK\r\n"),
1067 MockRead("Content-Length: 10\r\n"),
1068 MockRead("Content-Length: 5\r\n\r\n"),
1069 };
1070 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
1071 arraysize(data_reads));
robpercival214763f2016-07-01 23:27:011072 EXPECT_THAT(out.rv, IsError(ERR_RESPONSE_HEADERS_MULTIPLE_CONTENT_LENGTH));
[email protected]9fe44f52010-09-23 18:36:001073}
1074
bncd16676a2016-07-20 16:23:011075TEST_F(HttpNetworkTransactionTest,
[email protected]44b52042010-10-29 22:48:041076 DuplicateContentLengthHeadersNoTransferEncoding) {
1077 MockRead data_reads[] = {
1078 MockRead("HTTP/1.1 200 OK\r\n"),
1079 MockRead("Content-Length: 5\r\n"),
1080 MockRead("Content-Length: 5\r\n\r\n"),
1081 MockRead("Hello"),
1082 };
1083 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
1084 arraysize(data_reads));
robpercival214763f2016-07-01 23:27:011085 EXPECT_THAT(out.rv, IsOk());
[email protected]44b52042010-10-29 22:48:041086 EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
1087 EXPECT_EQ("Hello", out.response_data);
1088}
1089
bncd16676a2016-07-20 16:23:011090TEST_F(HttpNetworkTransactionTest,
[email protected]44b52042010-10-29 22:48:041091 ComplexContentLengthHeadersNoTransferEncoding) {
1092 // More than 2 dupes.
1093 {
1094 MockRead data_reads[] = {
1095 MockRead("HTTP/1.1 200 OK\r\n"),
1096 MockRead("Content-Length: 5\r\n"),
1097 MockRead("Content-Length: 5\r\n"),
1098 MockRead("Content-Length: 5\r\n\r\n"),
1099 MockRead("Hello"),
1100 };
1101 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
1102 arraysize(data_reads));
robpercival214763f2016-07-01 23:27:011103 EXPECT_THAT(out.rv, IsOk());
[email protected]44b52042010-10-29 22:48:041104 EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
1105 EXPECT_EQ("Hello", out.response_data);
1106 }
1107 // HTTP/1.0
1108 {
1109 MockRead data_reads[] = {
1110 MockRead("HTTP/1.0 200 OK\r\n"),
1111 MockRead("Content-Length: 5\r\n"),
1112 MockRead("Content-Length: 5\r\n"),
1113 MockRead("Content-Length: 5\r\n\r\n"),
1114 MockRead("Hello"),
1115 };
1116 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
1117 arraysize(data_reads));
robpercival214763f2016-07-01 23:27:011118 EXPECT_THAT(out.rv, IsOk());
[email protected]44b52042010-10-29 22:48:041119 EXPECT_EQ("HTTP/1.0 200 OK", out.status_line);
1120 EXPECT_EQ("Hello", out.response_data);
1121 }
1122 // 2 dupes and one mismatched.
1123 {
1124 MockRead data_reads[] = {
1125 MockRead("HTTP/1.1 200 OK\r\n"),
1126 MockRead("Content-Length: 10\r\n"),
1127 MockRead("Content-Length: 10\r\n"),
1128 MockRead("Content-Length: 5\r\n\r\n"),
1129 };
1130 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
1131 arraysize(data_reads));
robpercival214763f2016-07-01 23:27:011132 EXPECT_THAT(out.rv, IsError(ERR_RESPONSE_HEADERS_MULTIPLE_CONTENT_LENGTH));
[email protected]44b52042010-10-29 22:48:041133 }
1134}
1135
bncd16676a2016-07-20 16:23:011136TEST_F(HttpNetworkTransactionTest,
[email protected]9fe44f52010-09-23 18:36:001137 MultipleContentLengthHeadersTransferEncoding) {
1138 MockRead data_reads[] = {
1139 MockRead("HTTP/1.1 200 OK\r\n"),
1140 MockRead("Content-Length: 666\r\n"),
1141 MockRead("Content-Length: 1337\r\n"),
1142 MockRead("Transfer-Encoding: chunked\r\n\r\n"),
1143 MockRead("5\r\nHello\r\n"),
1144 MockRead("1\r\n"),
1145 MockRead(" \r\n"),
1146 MockRead("5\r\nworld\r\n"),
1147 MockRead("0\r\n\r\nHTTP/1.1 200 OK\r\n"),
[email protected]8ddf8322012-02-23 18:08:061148 MockRead(SYNCHRONOUS, OK),
[email protected]9fe44f52010-09-23 18:36:001149 };
1150 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
1151 arraysize(data_reads));
robpercival214763f2016-07-01 23:27:011152 EXPECT_THAT(out.rv, IsOk());
[email protected]9fe44f52010-09-23 18:36:001153 EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
1154 EXPECT_EQ("Hello world", out.response_data);
1155}
1156
[email protected]1628fe92011-10-04 23:04:551157// Next tests deal with http://crbug.com/98895.
1158
1159// Checks that a single Content-Disposition header results in no error.
bncd16676a2016-07-20 16:23:011160TEST_F(HttpNetworkTransactionTest, SingleContentDispositionHeader) {
[email protected]1628fe92011-10-04 23:04:551161 MockRead data_reads[] = {
1162 MockRead("HTTP/1.1 200 OK\r\n"),
1163 MockRead("Content-Disposition: attachment;filename=\"salutations.txt\"r\n"),
1164 MockRead("Content-Length: 5\r\n\r\n"),
1165 MockRead("Hello"),
1166 };
1167 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
1168 arraysize(data_reads));
robpercival214763f2016-07-01 23:27:011169 EXPECT_THAT(out.rv, IsOk());
[email protected]1628fe92011-10-04 23:04:551170 EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
1171 EXPECT_EQ("Hello", out.response_data);
1172}
1173
[email protected]54a9c6e52012-03-21 20:10:591174// Checks that two identical Content-Disposition headers result in no error.
bncd16676a2016-07-20 16:23:011175TEST_F(HttpNetworkTransactionTest, TwoIdenticalContentDispositionHeaders) {
[email protected]1628fe92011-10-04 23:04:551176 MockRead data_reads[] = {
1177 MockRead("HTTP/1.1 200 OK\r\n"),
1178 MockRead("Content-Disposition: attachment;filename=\"greetings.txt\"r\n"),
1179 MockRead("Content-Disposition: attachment;filename=\"greetings.txt\"r\n"),
1180 MockRead("Content-Length: 5\r\n\r\n"),
1181 MockRead("Hello"),
1182 };
1183 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
1184 arraysize(data_reads));
robpercival214763f2016-07-01 23:27:011185 EXPECT_THAT(out.rv, IsOk());
[email protected]54a9c6e52012-03-21 20:10:591186 EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
1187 EXPECT_EQ("Hello", out.response_data);
[email protected]1628fe92011-10-04 23:04:551188}
1189
1190// Checks that two distinct Content-Disposition headers result in an error.
bncd16676a2016-07-20 16:23:011191TEST_F(HttpNetworkTransactionTest, TwoDistinctContentDispositionHeaders) {
[email protected]1628fe92011-10-04 23:04:551192 MockRead data_reads[] = {
1193 MockRead("HTTP/1.1 200 OK\r\n"),
1194 MockRead("Content-Disposition: attachment;filename=\"greetings.txt\"r\n"),
1195 MockRead("Content-Disposition: attachment;filename=\"hi.txt\"r\n"),
1196 MockRead("Content-Length: 5\r\n\r\n"),
1197 MockRead("Hello"),
1198 };
1199 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
1200 arraysize(data_reads));
robpercival214763f2016-07-01 23:27:011201 EXPECT_THAT(out.rv,
1202 IsError(ERR_RESPONSE_HEADERS_MULTIPLE_CONTENT_DISPOSITION));
[email protected]1628fe92011-10-04 23:04:551203}
1204
[email protected]54a9c6e52012-03-21 20:10:591205// Checks that two identical Location headers result in no error.
1206// Also tests Location header behavior.
bncd16676a2016-07-20 16:23:011207TEST_F(HttpNetworkTransactionTest, TwoIdenticalLocationHeaders) {
[email protected]1628fe92011-10-04 23:04:551208 MockRead data_reads[] = {
1209 MockRead("HTTP/1.1 302 Redirect\r\n"),
1210 MockRead("Location: http://good.com/\r\n"),
[email protected]54a9c6e52012-03-21 20:10:591211 MockRead("Location: http://good.com/\r\n"),
[email protected]1628fe92011-10-04 23:04:551212 MockRead("Content-Length: 0\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:061213 MockRead(SYNCHRONOUS, OK),
[email protected]1628fe92011-10-04 23:04:551214 };
1215
1216 HttpRequestInfo request;
1217 request.method = "GET";
1218 request.url = GURL("http://redirect.com/");
[email protected]1628fe92011-10-04 23:04:551219
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());
[email protected]1628fe92011-10-04 23:04:551222
1223 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:071224 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1628fe92011-10-04 23:04:551225
[email protected]49639fa2011-12-20 23:22:411226 TestCompletionCallback callback;
[email protected]1628fe92011-10-04 23:04:551227
tfarina42834112016-09-22 13:38:201228 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:011229 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]1628fe92011-10-04 23:04:551230
robpercival214763f2016-07-01 23:27:011231 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]1628fe92011-10-04 23:04:551232
bnc691fda62016-08-12 00:43:161233 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:521234 ASSERT_TRUE(response);
1235 ASSERT_TRUE(response->headers);
[email protected]1628fe92011-10-04 23:04:551236 EXPECT_EQ("HTTP/1.1 302 Redirect", response->headers->GetStatusLine());
1237 std::string url;
1238 EXPECT_TRUE(response->headers->IsRedirect(&url));
1239 EXPECT_EQ("http://good.com/", url);
tbansal2ecbbc72016-10-06 17:15:471240 EXPECT_TRUE(response->proxy_server.is_direct());
[email protected]1628fe92011-10-04 23:04:551241}
1242
[email protected]1628fe92011-10-04 23:04:551243// Checks that two distinct Location headers result in an error.
bncd16676a2016-07-20 16:23:011244TEST_F(HttpNetworkTransactionTest, TwoDistinctLocationHeaders) {
[email protected]1628fe92011-10-04 23:04:551245 MockRead data_reads[] = {
1246 MockRead("HTTP/1.1 302 Redirect\r\n"),
1247 MockRead("Location: http://good.com/\r\n"),
1248 MockRead("Location: http://evil.com/\r\n"),
1249 MockRead("Content-Length: 0\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:061250 MockRead(SYNCHRONOUS, OK),
[email protected]1628fe92011-10-04 23:04:551251 };
1252 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
1253 arraysize(data_reads));
robpercival214763f2016-07-01 23:27:011254 EXPECT_THAT(out.rv, IsError(ERR_RESPONSE_HEADERS_MULTIPLE_LOCATION));
[email protected]1628fe92011-10-04 23:04:551255}
1256
[email protected]ef0faf2e72009-03-05 23:27:231257// Do a request using the HEAD method. Verify that we don't try to read the
1258// message body (since HEAD has none).
bncd16676a2016-07-20 16:23:011259TEST_F(HttpNetworkTransactionTest, Head) {
[email protected]1c773ea12009-04-28 19:58:421260 HttpRequestInfo request;
[email protected]ef0faf2e72009-03-05 23:27:231261 request.method = "HEAD";
bncce36dca22015-04-21 22:11:231262 request.url = GURL("http://www.example.org/");
[email protected]ef0faf2e72009-03-05 23:27:231263
danakj1fd259a02016-04-16 03:17:091264 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:161265 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
ryansturm49a8cb12016-06-15 16:51:091266 BeforeHeadersSentHandler headers_handler;
bnc691fda62016-08-12 00:43:161267 trans.SetBeforeHeadersSentCallback(
ryansturm49a8cb12016-06-15 16:51:091268 base::Bind(&BeforeHeadersSentHandler::OnBeforeHeadersSent,
1269 base::Unretained(&headers_handler)));
[email protected]cb9bf6ca2011-01-28 13:15:271270
[email protected]ef0faf2e72009-03-05 23:27:231271 MockWrite data_writes1[] = {
csharrisonf473dd192015-08-18 13:54:131272 MockWrite("HEAD / HTTP/1.1\r\n"
1273 "Host: www.example.org\r\n"
1274 "Connection: keep-alive\r\n\r\n"),
[email protected]ef0faf2e72009-03-05 23:27:231275 };
1276 MockRead data_reads1[] = {
mmenked39192ee2015-12-09 00:57:231277 MockRead("HTTP/1.1 404 Not Found\r\n"), MockRead("Server: Blah\r\n"),
1278 MockRead("Content-Length: 1234\r\n\r\n"),
[email protected]ef0faf2e72009-03-05 23:27:231279
mmenked39192ee2015-12-09 00:57:231280 // No response body because the test stops reading here.
1281 MockRead(SYNCHRONOUS, ERR_UNEXPECTED),
[email protected]ef0faf2e72009-03-05 23:27:231282 };
1283
[email protected]31a2bfe2010-02-09 08:03:391284 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
1285 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:071286 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]ef0faf2e72009-03-05 23:27:231287
[email protected]49639fa2011-12-20 23:22:411288 TestCompletionCallback callback1;
[email protected]ef0faf2e72009-03-05 23:27:231289
tfarina42834112016-09-22 13:38:201290 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:011291 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]ef0faf2e72009-03-05 23:27:231292
1293 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:011294 EXPECT_THAT(rv, IsOk());
[email protected]ef0faf2e72009-03-05 23:27:231295
bnc691fda62016-08-12 00:43:161296 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:521297 ASSERT_TRUE(response);
[email protected]ef0faf2e72009-03-05 23:27:231298
1299 // Check that the headers got parsed.
wezca1070932016-05-26 20:30:521300 EXPECT_TRUE(response->headers);
[email protected]ef0faf2e72009-03-05 23:27:231301 EXPECT_EQ(1234, response->headers->GetContentLength());
1302 EXPECT_EQ("HTTP/1.1 404 Not Found", response->headers->GetStatusLine());
tbansal2ecbbc72016-10-06 17:15:471303 EXPECT_TRUE(response->proxy_server.is_direct());
ryansturm49a8cb12016-06-15 16:51:091304 EXPECT_TRUE(headers_handler.observed_before_headers_sent());
1305 EXPECT_FALSE(headers_handler.observed_before_headers_sent_with_proxy());
[email protected]ef0faf2e72009-03-05 23:27:231306
1307 std::string server_header;
olli.raulaee489a52016-01-25 08:37:101308 size_t iter = 0;
[email protected]ef0faf2e72009-03-05 23:27:231309 bool has_server_header = response->headers->EnumerateHeader(
1310 &iter, "Server", &server_header);
1311 EXPECT_TRUE(has_server_header);
1312 EXPECT_EQ("Blah", server_header);
1313
1314 // Reading should give EOF right away, since there is no message body
1315 // (despite non-zero content-length).
1316 std::string response_data;
bnc691fda62016-08-12 00:43:161317 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:011318 EXPECT_THAT(rv, IsOk());
[email protected]ef0faf2e72009-03-05 23:27:231319 EXPECT_EQ("", response_data);
1320}
1321
bncd16676a2016-07-20 16:23:011322TEST_F(HttpNetworkTransactionTest, ReuseConnection) {
danakj1fd259a02016-04-16 03:17:091323 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
initial.commit586acc5fe2008-07-26 22:42:521324
1325 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:351326 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
1327 MockRead("hello"),
1328 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
1329 MockRead("world"),
[email protected]8ddf8322012-02-23 18:08:061330 MockRead(SYNCHRONOUS, OK),
initial.commit586acc5fe2008-07-26 22:42:521331 };
[email protected]31a2bfe2010-02-09 08:03:391332 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:071333 session_deps_.socket_factory->AddSocketDataProvider(&data);
initial.commit586acc5fe2008-07-26 22:42:521334
[email protected]0b0bf032010-09-21 18:08:501335 const char* const kExpectedResponseData[] = {
initial.commit586acc5fe2008-07-26 22:42:521336 "hello", "world"
1337 };
1338
1339 for (int i = 0; i < 2; ++i) {
[email protected]1c773ea12009-04-28 19:58:421340 HttpRequestInfo request;
initial.commit586acc5fe2008-07-26 22:42:521341 request.method = "GET";
bncce36dca22015-04-21 22:11:231342 request.url = GURL("http://www.example.org/");
initial.commit586acc5fe2008-07-26 22:42:521343
bnc691fda62016-08-12 00:43:161344 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:271345
[email protected]49639fa2011-12-20 23:22:411346 TestCompletionCallback callback;
initial.commit586acc5fe2008-07-26 22:42:521347
tfarina42834112016-09-22 13:38:201348 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:011349 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
initial.commit586acc5fe2008-07-26 22:42:521350
1351 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:011352 EXPECT_THAT(rv, IsOk());
initial.commit586acc5fe2008-07-26 22:42:521353
bnc691fda62016-08-12 00:43:161354 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:521355 ASSERT_TRUE(response);
initial.commit586acc5fe2008-07-26 22:42:521356
wezca1070932016-05-26 20:30:521357 EXPECT_TRUE(response->headers);
[email protected]3d2a59b2008-09-26 19:44:251358 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
tbansal2ecbbc72016-10-06 17:15:471359 EXPECT_TRUE(response->proxy_server.is_direct());
initial.commit586acc5fe2008-07-26 22:42:521360
1361 std::string response_data;
bnc691fda62016-08-12 00:43:161362 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:011363 EXPECT_THAT(rv, IsOk());
[email protected]3d2a59b2008-09-26 19:44:251364 EXPECT_EQ(kExpectedResponseData[i], response_data);
initial.commit586acc5fe2008-07-26 22:42:521365 }
1366}
1367
bncd16676a2016-07-20 16:23:011368TEST_F(HttpNetworkTransactionTest, Ignores100) {
danakj1fd259a02016-04-16 03:17:091369 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:221370 element_readers.push_back(
Jeremy Roman0579ed62017-08-29 15:56:191371 std::make_unique<UploadBytesElementReader>("foo", 3));
olli.raula6df48b2a2015-11-26 07:40:221372 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]329b68b2012-11-14 17:54:271373
[email protected]1c773ea12009-04-28 19:58:421374 HttpRequestInfo request;
initial.commit586acc5fe2008-07-26 22:42:521375 request.method = "POST";
1376 request.url = GURL("http://www.foo.com/");
[email protected]329b68b2012-11-14 17:54:271377 request.upload_data_stream = &upload_data_stream;
initial.commit586acc5fe2008-07-26 22:42:521378
shivanishab9a143952016-09-19 17:23:411379 // Check the upload progress returned before initialization is correct.
1380 UploadProgress progress = request.upload_data_stream->GetUploadProgress();
1381 EXPECT_EQ(0u, progress.size());
1382 EXPECT_EQ(0u, progress.position());
1383
danakj1fd259a02016-04-16 03:17:091384 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:161385 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:271386
initial.commit586acc5fe2008-07-26 22:42:521387 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:351388 MockRead("HTTP/1.0 100 Continue\r\n\r\n"),
1389 MockRead("HTTP/1.0 200 OK\r\n\r\n"),
1390 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:061391 MockRead(SYNCHRONOUS, OK),
initial.commit586acc5fe2008-07-26 22:42:521392 };
[email protected]31a2bfe2010-02-09 08:03:391393 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:071394 session_deps_.socket_factory->AddSocketDataProvider(&data);
initial.commit586acc5fe2008-07-26 22:42:521395
[email protected]49639fa2011-12-20 23:22:411396 TestCompletionCallback callback;
initial.commit586acc5fe2008-07-26 22:42:521397
tfarina42834112016-09-22 13:38:201398 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:011399 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
initial.commit586acc5fe2008-07-26 22:42:521400
1401 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:011402 EXPECT_THAT(rv, IsOk());
initial.commit586acc5fe2008-07-26 22:42:521403
bnc691fda62016-08-12 00:43:161404 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:521405 ASSERT_TRUE(response);
initial.commit586acc5fe2008-07-26 22:42:521406
wezca1070932016-05-26 20:30:521407 EXPECT_TRUE(response->headers);
[email protected]3d2a59b2008-09-26 19:44:251408 EXPECT_EQ("HTTP/1.0 200 OK", response->headers->GetStatusLine());
initial.commit586acc5fe2008-07-26 22:42:521409
1410 std::string response_data;
bnc691fda62016-08-12 00:43:161411 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:011412 EXPECT_THAT(rv, IsOk());
[email protected]3d2a59b2008-09-26 19:44:251413 EXPECT_EQ("hello world", response_data);
initial.commit586acc5fe2008-07-26 22:42:521414}
1415
[email protected]3a2d3662009-03-27 03:49:141416// This test is almost the same as Ignores100 above, but the response contains
1417// a 102 instead of a 100. Also, instead of HTTP/1.0 the response is
[email protected]0877e3d2009-10-17 22:29:571418// HTTP/1.1 and the two status headers are read in one read.
bncd16676a2016-07-20 16:23:011419TEST_F(HttpNetworkTransactionTest, Ignores1xx) {
[email protected]1c773ea12009-04-28 19:58:421420 HttpRequestInfo request;
[email protected]3a2d3662009-03-27 03:49:141421 request.method = "GET";
1422 request.url = GURL("http://www.foo.com/");
[email protected]3a2d3662009-03-27 03:49:141423
danakj1fd259a02016-04-16 03:17:091424 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:161425 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:271426
[email protected]3a2d3662009-03-27 03:49:141427 MockRead data_reads[] = {
[email protected]0877e3d2009-10-17 22:29:571428 MockRead("HTTP/1.1 102 Unspecified status code\r\n\r\n"
1429 "HTTP/1.1 200 OK\r\n\r\n"),
[email protected]3a2d3662009-03-27 03:49:141430 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:061431 MockRead(SYNCHRONOUS, OK),
[email protected]3a2d3662009-03-27 03:49:141432 };
[email protected]31a2bfe2010-02-09 08:03:391433 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:071434 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]3a2d3662009-03-27 03:49:141435
[email protected]49639fa2011-12-20 23:22:411436 TestCompletionCallback callback;
[email protected]3a2d3662009-03-27 03:49:141437
tfarina42834112016-09-22 13:38:201438 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:011439 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]3a2d3662009-03-27 03:49:141440
1441 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:011442 EXPECT_THAT(rv, IsOk());
[email protected]3a2d3662009-03-27 03:49:141443
bnc691fda62016-08-12 00:43:161444 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:521445 ASSERT_TRUE(response);
[email protected]3a2d3662009-03-27 03:49:141446
wezca1070932016-05-26 20:30:521447 EXPECT_TRUE(response->headers);
[email protected]3a2d3662009-03-27 03:49:141448 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
1449
1450 std::string response_data;
bnc691fda62016-08-12 00:43:161451 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:011452 EXPECT_THAT(rv, IsOk());
[email protected]3a2d3662009-03-27 03:49:141453 EXPECT_EQ("hello world", response_data);
1454}
1455
bncd16676a2016-07-20 16:23:011456TEST_F(HttpNetworkTransactionTest, Incomplete100ThenEOF) {
zmo9528c9f42015-08-04 22:12:081457 HttpRequestInfo request;
1458 request.method = "POST";
1459 request.url = GURL("http://www.foo.com/");
zmo9528c9f42015-08-04 22:12:081460
danakj1fd259a02016-04-16 03:17:091461 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:161462 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
zmo9528c9f42015-08-04 22:12:081463
1464 MockRead data_reads[] = {
1465 MockRead(SYNCHRONOUS, "HTTP/1.0 100 Continue\r\n"),
1466 MockRead(ASYNC, 0),
[email protected]ee9410e72010-01-07 01:42:381467 };
zmo9528c9f42015-08-04 22:12:081468 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
1469 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]ee9410e72010-01-07 01:42:381470
zmo9528c9f42015-08-04 22:12:081471 TestCompletionCallback callback;
[email protected]ee9410e72010-01-07 01:42:381472
tfarina42834112016-09-22 13:38:201473 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:011474 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]ee9410e72010-01-07 01:42:381475
zmo9528c9f42015-08-04 22:12:081476 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:011477 EXPECT_THAT(rv, IsOk());
[email protected]ee9410e72010-01-07 01:42:381478
zmo9528c9f42015-08-04 22:12:081479 std::string response_data;
bnc691fda62016-08-12 00:43:161480 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:011481 EXPECT_THAT(rv, IsOk());
zmo9528c9f42015-08-04 22:12:081482 EXPECT_EQ("", response_data);
[email protected]ee9410e72010-01-07 01:42:381483}
1484
bncd16676a2016-07-20 16:23:011485TEST_F(HttpNetworkTransactionTest, EmptyResponse) {
[email protected]ee9410e72010-01-07 01:42:381486 HttpRequestInfo request;
1487 request.method = "POST";
1488 request.url = GURL("http://www.foo.com/");
[email protected]ee9410e72010-01-07 01:42:381489
danakj1fd259a02016-04-16 03:17:091490 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:161491 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:271492
[email protected]ee9410e72010-01-07 01:42:381493 MockRead data_reads[] = {
[email protected]8ddf8322012-02-23 18:08:061494 MockRead(ASYNC, 0),
[email protected]ee9410e72010-01-07 01:42:381495 };
[email protected]31a2bfe2010-02-09 08:03:391496 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:071497 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]ee9410e72010-01-07 01:42:381498
[email protected]49639fa2011-12-20 23:22:411499 TestCompletionCallback callback;
[email protected]ee9410e72010-01-07 01:42:381500
tfarina42834112016-09-22 13:38:201501 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:011502 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]ee9410e72010-01-07 01:42:381503
1504 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:011505 EXPECT_THAT(rv, IsError(ERR_EMPTY_RESPONSE));
[email protected]ee9410e72010-01-07 01:42:381506}
1507
[email protected]23e482282013-06-14 16:08:021508void HttpNetworkTransactionTest::KeepAliveConnectionResendRequestTest(
[email protected]202965992011-12-07 23:04:511509 const MockWrite* write_failure,
1510 const MockRead* read_failure) {
[email protected]1c773ea12009-04-28 19:58:421511 HttpRequestInfo request;
initial.commit586acc5fe2008-07-26 22:42:521512 request.method = "GET";
1513 request.url = GURL("http://www.foo.com/");
initial.commit586acc5fe2008-07-26 22:42:521514
vishal.b62985ca92015-04-17 08:45:511515 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:071516 session_deps_.net_log = &net_log;
danakj1fd259a02016-04-16 03:17:091517 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:271518
[email protected]202965992011-12-07 23:04:511519 // Written data for successfully sending both requests.
1520 MockWrite data1_writes[] = {
1521 MockWrite("GET / HTTP/1.1\r\n"
1522 "Host: www.foo.com\r\n"
1523 "Connection: keep-alive\r\n\r\n"),
1524 MockWrite("GET / HTTP/1.1\r\n"
1525 "Host: www.foo.com\r\n"
1526 "Connection: keep-alive\r\n\r\n")
1527 };
1528
1529 // Read results for the first request.
initial.commit586acc5fe2008-07-26 22:42:521530 MockRead data1_reads[] = {
[email protected]217e6022008-09-29 18:18:351531 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
1532 MockRead("hello"),
[email protected]8ddf8322012-02-23 18:08:061533 MockRead(ASYNC, OK),
initial.commit586acc5fe2008-07-26 22:42:521534 };
[email protected]202965992011-12-07 23:04:511535
1536 if (write_failure) {
[email protected]a34f61ee2014-03-18 20:59:491537 ASSERT_FALSE(read_failure);
[email protected]202965992011-12-07 23:04:511538 data1_writes[1] = *write_failure;
1539 } else {
1540 ASSERT_TRUE(read_failure);
1541 data1_reads[2] = *read_failure;
1542 }
1543
1544 StaticSocketDataProvider data1(data1_reads, arraysize(data1_reads),
1545 data1_writes, arraysize(data1_writes));
[email protected]bb88e1d32013-05-03 23:11:071546 session_deps_.socket_factory->AddSocketDataProvider(&data1);
initial.commit586acc5fe2008-07-26 22:42:521547
1548 MockRead data2_reads[] = {
[email protected]217e6022008-09-29 18:18:351549 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
1550 MockRead("world"),
[email protected]8ddf8322012-02-23 18:08:061551 MockRead(ASYNC, OK),
initial.commit586acc5fe2008-07-26 22:42:521552 };
[email protected]31a2bfe2010-02-09 08:03:391553 StaticSocketDataProvider data2(data2_reads, arraysize(data2_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:071554 session_deps_.socket_factory->AddSocketDataProvider(&data2);
initial.commit586acc5fe2008-07-26 22:42:521555
thestig9d3bb0c2015-01-24 00:49:511556 const char* const kExpectedResponseData[] = {
initial.commit586acc5fe2008-07-26 22:42:521557 "hello", "world"
1558 };
1559
mikecironef22f9812016-10-04 03:40:191560 uint32_t first_socket_log_id = NetLogSource::kInvalidId;
initial.commit586acc5fe2008-07-26 22:42:521561 for (int i = 0; i < 2; ++i) {
[email protected]49639fa2011-12-20 23:22:411562 TestCompletionCallback callback;
initial.commit586acc5fe2008-07-26 22:42:521563
bnc691fda62016-08-12 00:43:161564 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
initial.commit586acc5fe2008-07-26 22:42:521565
tfarina42834112016-09-22 13:38:201566 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:011567 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
initial.commit586acc5fe2008-07-26 22:42:521568
1569 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:011570 EXPECT_THAT(rv, IsOk());
initial.commit586acc5fe2008-07-26 22:42:521571
[email protected]58e32bb2013-01-21 18:23:251572 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:161573 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]58e32bb2013-01-21 18:23:251574 TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_DNS_TIMES);
1575 if (i == 0) {
1576 first_socket_log_id = load_timing_info.socket_log_id;
1577 } else {
1578 // The second request should be using a new socket.
1579 EXPECT_NE(first_socket_log_id, load_timing_info.socket_log_id);
1580 }
1581
bnc691fda62016-08-12 00:43:161582 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:521583 ASSERT_TRUE(response);
initial.commit586acc5fe2008-07-26 22:42:521584
wezca1070932016-05-26 20:30:521585 EXPECT_TRUE(response->headers);
tbansal2ecbbc72016-10-06 17:15:471586 EXPECT_TRUE(response->proxy_server.is_direct());
[email protected]3d2a59b2008-09-26 19:44:251587 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
initial.commit586acc5fe2008-07-26 22:42:521588
1589 std::string response_data;
bnc691fda62016-08-12 00:43:161590 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:011591 EXPECT_THAT(rv, IsOk());
[email protected]3d2a59b2008-09-26 19:44:251592 EXPECT_EQ(kExpectedResponseData[i], response_data);
initial.commit586acc5fe2008-07-26 22:42:521593 }
1594}
[email protected]3d2a59b2008-09-26 19:44:251595
[email protected]a34f61ee2014-03-18 20:59:491596void HttpNetworkTransactionTest::PreconnectErrorResendRequestTest(
1597 const MockWrite* write_failure,
[email protected]09356c652014-03-25 15:36:101598 const MockRead* read_failure,
1599 bool use_spdy) {
[email protected]a34f61ee2014-03-18 20:59:491600 HttpRequestInfo request;
1601 request.method = "GET";
[email protected]09356c652014-03-25 15:36:101602 request.url = GURL("https://www.foo.com/");
[email protected]a34f61ee2014-03-18 20:59:491603
vishal.b62985ca92015-04-17 08:45:511604 TestNetLog net_log;
[email protected]a34f61ee2014-03-18 20:59:491605 session_deps_.net_log = &net_log;
danakj1fd259a02016-04-16 03:17:091606 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]a34f61ee2014-03-18 20:59:491607
[email protected]09356c652014-03-25 15:36:101608 SSLSocketDataProvider ssl1(ASYNC, OK);
1609 SSLSocketDataProvider ssl2(ASYNC, OK);
1610 if (use_spdy) {
bnc3cf2a592016-08-11 14:48:361611 ssl1.next_proto = kProtoHTTP2;
1612 ssl2.next_proto = kProtoHTTP2;
[email protected]09356c652014-03-25 15:36:101613 }
1614 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl1);
1615 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
[email protected]a34f61ee2014-03-18 20:59:491616
[email protected]09356c652014-03-25 15:36:101617 // SPDY versions of the request and response.
bncdf80d44fd2016-07-15 20:27:411618 SpdySerializedFrame spdy_request(spdy_util_.ConstructSpdyGet(
bnc38dcd392016-02-09 23:19:491619 request.url.spec().c_str(), 1, DEFAULT_PRIORITY));
bncdf80d44fd2016-07-15 20:27:411620 SpdySerializedFrame spdy_response(
bnc42331402016-07-25 13:36:151621 spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
bncdf80d44fd2016-07-15 20:27:411622 SpdySerializedFrame spdy_data(
1623 spdy_util_.ConstructSpdyDataFrame(1, "hello", 5, true));
[email protected]a34f61ee2014-03-18 20:59:491624
[email protected]09356c652014-03-25 15:36:101625 // HTTP/1.1 versions of the request and response.
1626 const char kHttpRequest[] = "GET / HTTP/1.1\r\n"
1627 "Host: www.foo.com\r\n"
1628 "Connection: keep-alive\r\n\r\n";
1629 const char kHttpResponse[] = "HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n";
1630 const char kHttpData[] = "hello";
1631
1632 std::vector<MockRead> data1_reads;
1633 std::vector<MockWrite> data1_writes;
[email protected]a34f61ee2014-03-18 20:59:491634 if (write_failure) {
1635 ASSERT_FALSE(read_failure);
[email protected]09356c652014-03-25 15:36:101636 data1_writes.push_back(*write_failure);
1637 data1_reads.push_back(MockRead(ASYNC, OK));
[email protected]a34f61ee2014-03-18 20:59:491638 } else {
1639 ASSERT_TRUE(read_failure);
[email protected]09356c652014-03-25 15:36:101640 if (use_spdy) {
bncdf80d44fd2016-07-15 20:27:411641 data1_writes.push_back(CreateMockWrite(spdy_request));
[email protected]09356c652014-03-25 15:36:101642 } else {
1643 data1_writes.push_back(MockWrite(kHttpRequest));
1644 }
1645 data1_reads.push_back(*read_failure);
[email protected]a34f61ee2014-03-18 20:59:491646 }
1647
[email protected]09356c652014-03-25 15:36:101648 StaticSocketDataProvider data1(&data1_reads[0], data1_reads.size(),
1649 &data1_writes[0], data1_writes.size());
[email protected]a34f61ee2014-03-18 20:59:491650 session_deps_.socket_factory->AddSocketDataProvider(&data1);
1651
[email protected]09356c652014-03-25 15:36:101652 std::vector<MockRead> data2_reads;
1653 std::vector<MockWrite> data2_writes;
1654
1655 if (use_spdy) {
bncdf80d44fd2016-07-15 20:27:411656 data2_writes.push_back(CreateMockWrite(spdy_request, 0, ASYNC));
[email protected]09356c652014-03-25 15:36:101657
bncdf80d44fd2016-07-15 20:27:411658 data2_reads.push_back(CreateMockRead(spdy_response, 1, ASYNC));
1659 data2_reads.push_back(CreateMockRead(spdy_data, 2, ASYNC));
[email protected]09356c652014-03-25 15:36:101660 data2_reads.push_back(MockRead(ASYNC, OK, 3));
1661 } else {
1662 data2_writes.push_back(
1663 MockWrite(ASYNC, kHttpRequest, strlen(kHttpRequest), 0));
1664
1665 data2_reads.push_back(
1666 MockRead(ASYNC, kHttpResponse, strlen(kHttpResponse), 1));
1667 data2_reads.push_back(MockRead(ASYNC, kHttpData, strlen(kHttpData), 2));
1668 data2_reads.push_back(MockRead(ASYNC, OK, 3));
1669 }
rch8e6c6c42015-05-01 14:05:131670 SequencedSocketData data2(&data2_reads[0], data2_reads.size(),
1671 &data2_writes[0], data2_writes.size());
[email protected]a34f61ee2014-03-18 20:59:491672 session_deps_.socket_factory->AddSocketDataProvider(&data2);
1673
1674 // Preconnect a socket.
nharper8cdb0fb2016-04-22 21:34:591675 session->http_stream_factory()->PreconnectStreams(1, request);
[email protected]a34f61ee2014-03-18 20:59:491676 // Wait for the preconnect to complete.
1677 // TODO(davidben): Some way to wait for an idle socket count might be handy.
1678 base::RunLoop().RunUntilIdle();
[email protected]09356c652014-03-25 15:36:101679 EXPECT_EQ(1, GetIdleSocketCountInSSLSocketPool(session.get()));
[email protected]a34f61ee2014-03-18 20:59:491680
1681 // Make the request.
1682 TestCompletionCallback callback;
1683
bnc691fda62016-08-12 00:43:161684 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]a34f61ee2014-03-18 20:59:491685
tfarina42834112016-09-22 13:38:201686 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:011687 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]a34f61ee2014-03-18 20:59:491688
1689 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:011690 EXPECT_THAT(rv, IsOk());
[email protected]a34f61ee2014-03-18 20:59:491691
1692 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:161693 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]09356c652014-03-25 15:36:101694 TestLoadTimingNotReused(
1695 load_timing_info,
1696 CONNECT_TIMING_HAS_DNS_TIMES|CONNECT_TIMING_HAS_SSL_TIMES);
[email protected]a34f61ee2014-03-18 20:59:491697
bnc691fda62016-08-12 00:43:161698 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:521699 ASSERT_TRUE(response);
[email protected]a34f61ee2014-03-18 20:59:491700
wezca1070932016-05-26 20:30:521701 EXPECT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:021702 if (response->was_fetched_via_spdy) {
1703 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
1704 } else {
1705 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
1706 }
[email protected]a34f61ee2014-03-18 20:59:491707
1708 std::string response_data;
bnc691fda62016-08-12 00:43:161709 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:011710 EXPECT_THAT(rv, IsOk());
[email protected]09356c652014-03-25 15:36:101711 EXPECT_EQ(kHttpData, response_data);
[email protected]a34f61ee2014-03-18 20:59:491712}
1713
Biljith Jayan45a41722017-08-16 18:43:141714// Test that we do not retry indefinitely when a server sends an error like
1715// ERR_SPDY_PING_FAILED, ERR_SPDY_SERVER_REFUSED_STREAM,
1716// ERR_QUIC_HANDSHAKE_FAILED or ERR_QUIC_PROTOCOL_ERROR.
1717TEST_F(HttpNetworkTransactionTest, FiniteRetriesOnIOError) {
1718 HttpRequestInfo request;
1719 request.method = "GET";
1720 request.url = GURL("https://www.foo.com/");
1721
1722 // Check whether we give up after the third try.
1723
1724 // Construct an HTTP2 request and a "Go away" response.
1725 SpdySerializedFrame spdy_request(spdy_util_.ConstructSpdyGet(
1726 request.url.spec().c_str(), 1, DEFAULT_PRIORITY));
1727 SpdySerializedFrame spdy_response_go_away(spdy_util_.ConstructSpdyGoAway());
1728 MockRead data_read1 = CreateMockRead(spdy_response_go_away);
1729 MockWrite data_write = CreateMockWrite(spdy_request, 0);
1730
1731 // Three go away responses.
1732 StaticSocketDataProvider data1(&data_read1, 1, &data_write, 1);
1733 StaticSocketDataProvider data2(&data_read1, 1, &data_write, 1);
1734 StaticSocketDataProvider data3(&data_read1, 1, &data_write, 1);
1735
1736 session_deps_.socket_factory->AddSocketDataProvider(&data1);
1737 AddSSLSocketData();
1738 session_deps_.socket_factory->AddSocketDataProvider(&data2);
1739 AddSSLSocketData();
1740 session_deps_.socket_factory->AddSocketDataProvider(&data3);
1741 AddSSLSocketData();
1742
1743 TestCompletionCallback callback;
1744 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
1745 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
1746
1747 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
1748 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
1749
1750 rv = callback.WaitForResult();
1751 EXPECT_THAT(rv, IsError(ERR_SPDY_SERVER_REFUSED_STREAM));
1752}
1753
1754TEST_F(HttpNetworkTransactionTest, RetryTwiceOnIOError) {
1755 HttpRequestInfo request;
1756 request.method = "GET";
1757 request.url = GURL("https://www.foo.com/");
1758
1759 // Check whether we try atleast thrice before giving up.
1760
1761 // Construct an HTTP2 request and a "Go away" response.
1762 SpdySerializedFrame spdy_request(spdy_util_.ConstructSpdyGet(
1763 request.url.spec().c_str(), 1, DEFAULT_PRIORITY));
1764 SpdySerializedFrame spdy_response_go_away(spdy_util_.ConstructSpdyGoAway());
1765 MockRead data_read1 = CreateMockRead(spdy_response_go_away);
1766 MockWrite data_write = CreateMockWrite(spdy_request, 0);
1767
1768 // Construct a non error HTTP2 response.
1769 SpdySerializedFrame spdy_response_no_error(
1770 spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
1771 SpdySerializedFrame spdy_data(spdy_util_.ConstructSpdyDataFrame(1, true));
1772 MockRead data_read2[] = {CreateMockRead(spdy_response_no_error, 1),
1773 CreateMockRead(spdy_data, 2)};
1774
1775 // Two error responses.
1776 StaticSocketDataProvider data1(&data_read1, 1, &data_write, 1);
1777 StaticSocketDataProvider data2(&data_read1, 1, &data_write, 1);
1778 // Followed by a success response.
1779 SequencedSocketData data3(data_read2, 2, &data_write, 1);
1780
1781 session_deps_.socket_factory->AddSocketDataProvider(&data1);
1782 AddSSLSocketData();
1783 session_deps_.socket_factory->AddSocketDataProvider(&data2);
1784 AddSSLSocketData();
1785 session_deps_.socket_factory->AddSocketDataProvider(&data3);
1786 AddSSLSocketData();
1787
1788 TestCompletionCallback callback;
1789 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
1790 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
1791
1792 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
1793 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
1794
1795 rv = callback.WaitForResult();
1796 EXPECT_THAT(rv, IsOk());
1797}
1798
bncd16676a2016-07-20 16:23:011799TEST_F(HttpNetworkTransactionTest, KeepAliveConnectionNotConnectedOnWrite) {
[email protected]8ddf8322012-02-23 18:08:061800 MockWrite write_failure(ASYNC, ERR_SOCKET_NOT_CONNECTED);
[email protected]202965992011-12-07 23:04:511801 KeepAliveConnectionResendRequestTest(&write_failure, NULL);
1802}
1803
bncd16676a2016-07-20 16:23:011804TEST_F(HttpNetworkTransactionTest, KeepAliveConnectionReset) {
[email protected]8ddf8322012-02-23 18:08:061805 MockRead read_failure(ASYNC, ERR_CONNECTION_RESET);
[email protected]202965992011-12-07 23:04:511806 KeepAliveConnectionResendRequestTest(NULL, &read_failure);
[email protected]3d2a59b2008-09-26 19:44:251807}
1808
bncd16676a2016-07-20 16:23:011809TEST_F(HttpNetworkTransactionTest, KeepAliveConnectionEOF) {
[email protected]8ddf8322012-02-23 18:08:061810 MockRead read_failure(SYNCHRONOUS, OK); // EOF
[email protected]202965992011-12-07 23:04:511811 KeepAliveConnectionResendRequestTest(NULL, &read_failure);
[email protected]3d2a59b2008-09-26 19:44:251812}
1813
[email protected]d58ceea82014-06-04 10:55:541814// Make sure that on a 408 response (Request Timeout), the request is retried,
1815// if the socket was a reused keep alive socket.
bncd16676a2016-07-20 16:23:011816TEST_F(HttpNetworkTransactionTest, KeepAlive408) {
[email protected]d58ceea82014-06-04 10:55:541817 MockRead read_failure(SYNCHRONOUS,
1818 "HTTP/1.1 408 Request Timeout\r\n"
1819 "Connection: Keep-Alive\r\n"
1820 "Content-Length: 6\r\n\r\n"
1821 "Pickle");
1822 KeepAliveConnectionResendRequestTest(NULL, &read_failure);
1823}
1824
bncd16676a2016-07-20 16:23:011825TEST_F(HttpNetworkTransactionTest, PreconnectErrorNotConnectedOnWrite) {
[email protected]a34f61ee2014-03-18 20:59:491826 MockWrite write_failure(ASYNC, ERR_SOCKET_NOT_CONNECTED);
[email protected]09356c652014-03-25 15:36:101827 PreconnectErrorResendRequestTest(&write_failure, NULL, false);
[email protected]a34f61ee2014-03-18 20:59:491828}
1829
bncd16676a2016-07-20 16:23:011830TEST_F(HttpNetworkTransactionTest, PreconnectErrorReset) {
[email protected]a34f61ee2014-03-18 20:59:491831 MockRead read_failure(ASYNC, ERR_CONNECTION_RESET);
[email protected]09356c652014-03-25 15:36:101832 PreconnectErrorResendRequestTest(NULL, &read_failure, false);
[email protected]a34f61ee2014-03-18 20:59:491833}
1834
bncd16676a2016-07-20 16:23:011835TEST_F(HttpNetworkTransactionTest, PreconnectErrorEOF) {
[email protected]a34f61ee2014-03-18 20:59:491836 MockRead read_failure(SYNCHRONOUS, OK); // EOF
[email protected]09356c652014-03-25 15:36:101837 PreconnectErrorResendRequestTest(NULL, &read_failure, false);
1838}
1839
bncd16676a2016-07-20 16:23:011840TEST_F(HttpNetworkTransactionTest, PreconnectErrorAsyncEOF) {
[email protected]09356c652014-03-25 15:36:101841 MockRead read_failure(ASYNC, OK); // EOF
1842 PreconnectErrorResendRequestTest(NULL, &read_failure, false);
1843}
1844
[email protected]d58ceea82014-06-04 10:55:541845// Make sure that on a 408 response (Request Timeout), the request is retried,
1846// if the socket was a preconnected (UNUSED_IDLE) socket.
bncd16676a2016-07-20 16:23:011847TEST_F(HttpNetworkTransactionTest, RetryOnIdle408) {
[email protected]d58ceea82014-06-04 10:55:541848 MockRead read_failure(SYNCHRONOUS,
1849 "HTTP/1.1 408 Request Timeout\r\n"
1850 "Connection: Keep-Alive\r\n"
1851 "Content-Length: 6\r\n\r\n"
1852 "Pickle");
1853 KeepAliveConnectionResendRequestTest(NULL, &read_failure);
1854 PreconnectErrorResendRequestTest(NULL, &read_failure, false);
1855}
1856
bncd16676a2016-07-20 16:23:011857TEST_F(HttpNetworkTransactionTest, SpdyPreconnectErrorNotConnectedOnWrite) {
[email protected]09356c652014-03-25 15:36:101858 MockWrite write_failure(ASYNC, ERR_SOCKET_NOT_CONNECTED);
1859 PreconnectErrorResendRequestTest(&write_failure, NULL, true);
1860}
1861
bncd16676a2016-07-20 16:23:011862TEST_F(HttpNetworkTransactionTest, SpdyPreconnectErrorReset) {
[email protected]09356c652014-03-25 15:36:101863 MockRead read_failure(ASYNC, ERR_CONNECTION_RESET);
1864 PreconnectErrorResendRequestTest(NULL, &read_failure, true);
1865}
1866
bncd16676a2016-07-20 16:23:011867TEST_F(HttpNetworkTransactionTest, SpdyPreconnectErrorEOF) {
[email protected]09356c652014-03-25 15:36:101868 MockRead read_failure(SYNCHRONOUS, OK); // EOF
1869 PreconnectErrorResendRequestTest(NULL, &read_failure, true);
1870}
1871
bncd16676a2016-07-20 16:23:011872TEST_F(HttpNetworkTransactionTest, SpdyPreconnectErrorAsyncEOF) {
[email protected]09356c652014-03-25 15:36:101873 MockRead read_failure(ASYNC, OK); // EOF
1874 PreconnectErrorResendRequestTest(NULL, &read_failure, true);
[email protected]a34f61ee2014-03-18 20:59:491875}
1876
bncd16676a2016-07-20 16:23:011877TEST_F(HttpNetworkTransactionTest, NonKeepAliveConnectionReset) {
[email protected]1c773ea12009-04-28 19:58:421878 HttpRequestInfo request;
[email protected]3d2a59b2008-09-26 19:44:251879 request.method = "GET";
bncce36dca22015-04-21 22:11:231880 request.url = GURL("http://www.example.org/");
[email protected]3d2a59b2008-09-26 19:44:251881
danakj1fd259a02016-04-16 03:17:091882 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:161883 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:271884
[email protected]3d2a59b2008-09-26 19:44:251885 MockRead data_reads[] = {
[email protected]8ddf8322012-02-23 18:08:061886 MockRead(ASYNC, ERR_CONNECTION_RESET),
[email protected]217e6022008-09-29 18:18:351887 MockRead("HTTP/1.0 200 OK\r\n\r\n"), // Should not be used
1888 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:061889 MockRead(SYNCHRONOUS, OK),
[email protected]3d2a59b2008-09-26 19:44:251890 };
[email protected]31a2bfe2010-02-09 08:03:391891 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:071892 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]3d2a59b2008-09-26 19:44:251893
[email protected]49639fa2011-12-20 23:22:411894 TestCompletionCallback callback;
[email protected]3d2a59b2008-09-26 19:44:251895
tfarina42834112016-09-22 13:38:201896 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:011897 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]3d2a59b2008-09-26 19:44:251898
1899 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:011900 EXPECT_THAT(rv, IsError(ERR_CONNECTION_RESET));
ttuttled9dbc652015-09-29 20:00:591901
1902 IPEndPoint endpoint;
bnc691fda62016-08-12 00:43:161903 EXPECT_TRUE(trans.GetRemoteEndpoint(&endpoint));
ttuttled9dbc652015-09-29 20:00:591904 EXPECT_LT(0u, endpoint.address().size());
[email protected]3d2a59b2008-09-26 19:44:251905}
1906
1907// What do various browsers do when the server closes a non-keepalive
1908// connection without sending any response header or body?
1909//
1910// IE7: error page
1911// Safari 3.1.2 (Windows): error page
1912// Firefox 3.0.1: blank page
1913// Opera 9.52: after five attempts, blank page
[email protected]1c773ea12009-04-28 19:58:421914// Us with WinHTTP: error page (ERR_INVALID_RESPONSE)
1915// Us: error page (EMPTY_RESPONSE)
bncd16676a2016-07-20 16:23:011916TEST_F(HttpNetworkTransactionTest, NonKeepAliveConnectionEOF) {
[email protected]3d2a59b2008-09-26 19:44:251917 MockRead data_reads[] = {
[email protected]8ddf8322012-02-23 18:08:061918 MockRead(SYNCHRONOUS, OK), // EOF
[email protected]217e6022008-09-29 18:18:351919 MockRead("HTTP/1.0 200 OK\r\n\r\n"), // Should not be used
1920 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:061921 MockRead(SYNCHRONOUS, OK),
[email protected]3d2a59b2008-09-26 19:44:251922 };
[email protected]31a2bfe2010-02-09 08:03:391923 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
1924 arraysize(data_reads));
robpercival214763f2016-07-01 23:27:011925 EXPECT_THAT(out.rv, IsError(ERR_EMPTY_RESPONSE));
[email protected]3d2a59b2008-09-26 19:44:251926}
[email protected]1826a402014-01-08 15:40:481927
[email protected]7a5378b2012-11-04 03:25:171928// Next 2 cases (KeepAliveEarlyClose and KeepAliveEarlyClose2) are regression
1929// tests. There was a bug causing HttpNetworkTransaction to hang in the
1930// destructor in such situations.
1931// See http://crbug.com/154712 and http://crbug.com/156609.
bncd16676a2016-07-20 16:23:011932TEST_F(HttpNetworkTransactionTest, KeepAliveEarlyClose) {
[email protected]7a5378b2012-11-04 03:25:171933 HttpRequestInfo request;
1934 request.method = "GET";
bncce36dca22015-04-21 22:11:231935 request.url = GURL("http://www.example.org/");
[email protected]7a5378b2012-11-04 03:25:171936
danakj1fd259a02016-04-16 03:17:091937 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc87dcefc2017-05-25 12:47:581938 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:191939 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]7a5378b2012-11-04 03:25:171940
1941 MockRead data_reads[] = {
1942 MockRead("HTTP/1.0 200 OK\r\n"),
1943 MockRead("Connection: keep-alive\r\n"),
1944 MockRead("Content-Length: 100\r\n\r\n"),
1945 MockRead("hello"),
1946 MockRead(SYNCHRONOUS, 0),
1947 };
1948 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:071949 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]7a5378b2012-11-04 03:25:171950
1951 TestCompletionCallback callback;
1952
tfarina42834112016-09-22 13:38:201953 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:011954 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]7a5378b2012-11-04 03:25:171955
1956 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:011957 EXPECT_THAT(rv, IsOk());
[email protected]7a5378b2012-11-04 03:25:171958
1959 scoped_refptr<IOBufferWithSize> io_buf(new IOBufferWithSize(100));
[email protected]90499482013-06-01 00:39:501960 rv = trans->Read(io_buf.get(), io_buf->size(), callback.callback());
[email protected]7a5378b2012-11-04 03:25:171961 if (rv == ERR_IO_PENDING)
1962 rv = callback.WaitForResult();
1963 EXPECT_EQ(5, rv);
[email protected]90499482013-06-01 00:39:501964 rv = trans->Read(io_buf.get(), io_buf->size(), callback.callback());
robpercival214763f2016-07-01 23:27:011965 EXPECT_THAT(rv, IsError(ERR_CONTENT_LENGTH_MISMATCH));
[email protected]7a5378b2012-11-04 03:25:171966
1967 trans.reset();
fdoray92e35a72016-06-10 15:54:551968 base::RunLoop().RunUntilIdle();
[email protected]7a5378b2012-11-04 03:25:171969 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
1970}
1971
bncd16676a2016-07-20 16:23:011972TEST_F(HttpNetworkTransactionTest, KeepAliveEarlyClose2) {
[email protected]7a5378b2012-11-04 03:25:171973 HttpRequestInfo request;
1974 request.method = "GET";
bncce36dca22015-04-21 22:11:231975 request.url = GURL("http://www.example.org/");
[email protected]7a5378b2012-11-04 03:25:171976
danakj1fd259a02016-04-16 03:17:091977 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc87dcefc2017-05-25 12:47:581978 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:191979 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]7a5378b2012-11-04 03:25:171980
1981 MockRead data_reads[] = {
1982 MockRead("HTTP/1.0 200 OK\r\n"),
1983 MockRead("Connection: keep-alive\r\n"),
1984 MockRead("Content-Length: 100\r\n\r\n"),
1985 MockRead(SYNCHRONOUS, 0),
1986 };
1987 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:071988 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]7a5378b2012-11-04 03:25:171989
1990 TestCompletionCallback callback;
1991
tfarina42834112016-09-22 13:38:201992 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:011993 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]7a5378b2012-11-04 03:25:171994
1995 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:011996 EXPECT_THAT(rv, IsOk());
[email protected]7a5378b2012-11-04 03:25:171997
1998 scoped_refptr<IOBufferWithSize> io_buf(new IOBufferWithSize(100));
[email protected]90499482013-06-01 00:39:501999 rv = trans->Read(io_buf.get(), io_buf->size(), callback.callback());
[email protected]7a5378b2012-11-04 03:25:172000 if (rv == ERR_IO_PENDING)
2001 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:012002 EXPECT_THAT(rv, IsError(ERR_CONTENT_LENGTH_MISMATCH));
[email protected]7a5378b2012-11-04 03:25:172003
2004 trans.reset();
fdoray92e35a72016-06-10 15:54:552005 base::RunLoop().RunUntilIdle();
[email protected]7a5378b2012-11-04 03:25:172006 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
2007}
2008
[email protected]0b0bf032010-09-21 18:08:502009// Test that we correctly reuse a keep-alive connection after not explicitly
2010// reading the body.
bncd16676a2016-07-20 16:23:012011TEST_F(HttpNetworkTransactionTest, KeepAliveAfterUnreadBody) {
[email protected]fc31d6a42010-06-24 18:05:132012 HttpRequestInfo request;
2013 request.method = "GET";
2014 request.url = GURL("http://www.foo.com/");
[email protected]fc31d6a42010-06-24 18:05:132015
vishal.b62985ca92015-04-17 08:45:512016 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:072017 session_deps_.net_log = &net_log;
danakj1fd259a02016-04-16 03:17:092018 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:272019
mmenkecc2298e2015-12-07 18:20:182020 const char* request_data =
2021 "GET / HTTP/1.1\r\n"
2022 "Host: www.foo.com\r\n"
2023 "Connection: keep-alive\r\n\r\n";
2024 MockWrite data_writes[] = {
2025 MockWrite(ASYNC, 0, request_data), MockWrite(ASYNC, 2, request_data),
2026 MockWrite(ASYNC, 4, request_data), MockWrite(ASYNC, 6, request_data),
2027 MockWrite(ASYNC, 8, request_data), MockWrite(ASYNC, 10, request_data),
2028 MockWrite(ASYNC, 12, request_data), MockWrite(ASYNC, 14, request_data),
2029 MockWrite(ASYNC, 17, request_data), MockWrite(ASYNC, 20, request_data),
2030 };
2031
[email protected]0b0bf032010-09-21 18:08:502032 // Note that because all these reads happen in the same
2033 // StaticSocketDataProvider, it shows that the same socket is being reused for
2034 // all transactions.
mmenkecc2298e2015-12-07 18:20:182035 MockRead data_reads[] = {
2036 MockRead(ASYNC, 1, "HTTP/1.1 204 No Content\r\n\r\n"),
2037 MockRead(ASYNC, 3, "HTTP/1.1 205 Reset Content\r\n\r\n"),
2038 MockRead(ASYNC, 5, "HTTP/1.1 304 Not Modified\r\n\r\n"),
2039 MockRead(ASYNC, 7,
2040 "HTTP/1.1 302 Found\r\n"
2041 "Content-Length: 0\r\n\r\n"),
2042 MockRead(ASYNC, 9,
2043 "HTTP/1.1 302 Found\r\n"
2044 "Content-Length: 5\r\n\r\n"
2045 "hello"),
2046 MockRead(ASYNC, 11,
2047 "HTTP/1.1 301 Moved Permanently\r\n"
2048 "Content-Length: 0\r\n\r\n"),
2049 MockRead(ASYNC, 13,
2050 "HTTP/1.1 301 Moved Permanently\r\n"
2051 "Content-Length: 5\r\n\r\n"
2052 "hello"),
[email protected]fc31d6a42010-06-24 18:05:132053
mmenkecc2298e2015-12-07 18:20:182054 // In the next two rounds, IsConnectedAndIdle returns false, due to
2055 // the set_busy_before_sync_reads(true) call, while the
2056 // HttpNetworkTransaction is being shut down, but the socket is still
2057 // reuseable. See http://crbug.com/544255.
2058 MockRead(ASYNC, 15,
2059 "HTTP/1.1 200 Hunky-Dory\r\n"
2060 "Content-Length: 5\r\n\r\n"),
2061 MockRead(SYNCHRONOUS, 16, "hello"),
[email protected]fc31d6a42010-06-24 18:05:132062
mmenkecc2298e2015-12-07 18:20:182063 MockRead(ASYNC, 18,
2064 "HTTP/1.1 200 Hunky-Dory\r\n"
2065 "Content-Length: 5\r\n\r\n"
2066 "he"),
2067 MockRead(SYNCHRONOUS, 19, "llo"),
2068
2069 // The body of the final request is actually read.
2070 MockRead(ASYNC, 21, "HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
2071 MockRead(ASYNC, 22, "hello"),
2072 };
2073 SequencedSocketData data(data_reads, arraysize(data_reads), data_writes,
2074 arraysize(data_writes));
2075 data.set_busy_before_sync_reads(true);
2076 session_deps_.socket_factory->AddSocketDataProvider(&data);
2077
2078 const int kNumUnreadBodies = arraysize(data_writes) - 1;
[email protected]0b0bf032010-09-21 18:08:502079 std::string response_lines[kNumUnreadBodies];
2080
mikecironef22f9812016-10-04 03:40:192081 uint32_t first_socket_log_id = NetLogSource::kInvalidId;
mmenkecc2298e2015-12-07 18:20:182082 for (size_t i = 0; i < kNumUnreadBodies; ++i) {
[email protected]49639fa2011-12-20 23:22:412083 TestCompletionCallback callback;
[email protected]fc31d6a42010-06-24 18:05:132084
Jeremy Roman0579ed62017-08-29 15:56:192085 auto trans = std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY,
bnc87dcefc2017-05-25 12:47:582086 session.get());
[email protected]fc31d6a42010-06-24 18:05:132087
tfarina42834112016-09-22 13:38:202088 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012089 EXPECT_THAT(callback.GetResult(rv), IsOk());
[email protected]fc31d6a42010-06-24 18:05:132090
[email protected]58e32bb2013-01-21 18:23:252091 LoadTimingInfo load_timing_info;
2092 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
2093 if (i == 0) {
2094 TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_DNS_TIMES);
2095 first_socket_log_id = load_timing_info.socket_log_id;
2096 } else {
2097 TestLoadTimingReused(load_timing_info);
2098 EXPECT_EQ(first_socket_log_id, load_timing_info.socket_log_id);
2099 }
2100
[email protected]fc31d6a42010-06-24 18:05:132101 const HttpResponseInfo* response = trans->GetResponseInfo();
mmenkecc2298e2015-12-07 18:20:182102 ASSERT_TRUE(response);
[email protected]fc31d6a42010-06-24 18:05:132103
mmenkecc2298e2015-12-07 18:20:182104 ASSERT_TRUE(response->headers);
[email protected]0b0bf032010-09-21 18:08:502105 response_lines[i] = response->headers->GetStatusLine();
2106
mmenkecc2298e2015-12-07 18:20:182107 // Delete the transaction without reading the response bodies. Then spin
2108 // the message loop, so the response bodies are drained.
2109 trans.reset();
2110 base::RunLoop().RunUntilIdle();
[email protected]fc31d6a42010-06-24 18:05:132111 }
[email protected]0b0bf032010-09-21 18:08:502112
2113 const char* const kStatusLines[] = {
mmenkecc2298e2015-12-07 18:20:182114 "HTTP/1.1 204 No Content",
2115 "HTTP/1.1 205 Reset Content",
2116 "HTTP/1.1 304 Not Modified",
2117 "HTTP/1.1 302 Found",
2118 "HTTP/1.1 302 Found",
2119 "HTTP/1.1 301 Moved Permanently",
2120 "HTTP/1.1 301 Moved Permanently",
2121 "HTTP/1.1 200 Hunky-Dory",
2122 "HTTP/1.1 200 Hunky-Dory",
[email protected]0b0bf032010-09-21 18:08:502123 };
2124
mostynb91e0da982015-01-20 19:17:272125 static_assert(kNumUnreadBodies == arraysize(kStatusLines),
2126 "forgot to update kStatusLines");
[email protected]0b0bf032010-09-21 18:08:502127
2128 for (int i = 0; i < kNumUnreadBodies; ++i)
2129 EXPECT_EQ(kStatusLines[i], response_lines[i]);
2130
[email protected]49639fa2011-12-20 23:22:412131 TestCompletionCallback callback;
bnc691fda62016-08-12 00:43:162132 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:202133 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012134 EXPECT_THAT(callback.GetResult(rv), IsOk());
bnc691fda62016-08-12 00:43:162135 const HttpResponseInfo* response = trans.GetResponseInfo();
mmenkecc2298e2015-12-07 18:20:182136 ASSERT_TRUE(response);
2137 ASSERT_TRUE(response->headers);
[email protected]0b0bf032010-09-21 18:08:502138 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
2139 std::string response_data;
bnc691fda62016-08-12 00:43:162140 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:012141 EXPECT_THAT(rv, IsOk());
[email protected]0b0bf032010-09-21 18:08:502142 EXPECT_EQ("hello", response_data);
[email protected]fc31d6a42010-06-24 18:05:132143}
2144
mmenke5f94fda2016-06-02 20:54:132145// Sockets that receive extra data after a response is complete should not be
2146// reused.
bncd16676a2016-07-20 16:23:012147TEST_F(HttpNetworkTransactionTest, KeepAliveWithUnusedData1) {
mmenke5f94fda2016-06-02 20:54:132148 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
2149 MockWrite data_writes1[] = {
2150 MockWrite("HEAD / HTTP/1.1\r\n"
2151 "Host: www.borked.com\r\n"
2152 "Connection: keep-alive\r\n\r\n"),
2153 };
2154
2155 MockRead data_reads1[] = {
2156 MockRead("HTTP/1.1 200 OK\r\n"
2157 "Connection: keep-alive\r\n"
2158 "Content-Length: 22\r\n\r\n"
2159 "This server is borked."),
2160 };
2161
2162 MockWrite data_writes2[] = {
2163 MockWrite("GET /foo HTTP/1.1\r\n"
2164 "Host: www.borked.com\r\n"
2165 "Connection: keep-alive\r\n\r\n"),
2166 };
2167
2168 MockRead data_reads2[] = {
2169 MockRead("HTTP/1.1 200 OK\r\n"
2170 "Content-Length: 3\r\n\r\n"
2171 "foo"),
2172 };
2173 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
2174 data_writes1, arraysize(data_writes1));
2175 session_deps_.socket_factory->AddSocketDataProvider(&data1);
2176 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
2177 data_writes2, arraysize(data_writes2));
2178 session_deps_.socket_factory->AddSocketDataProvider(&data2);
2179
2180 TestCompletionCallback callback;
2181 HttpRequestInfo request1;
2182 request1.method = "HEAD";
2183 request1.url = GURL("http://www.borked.com/");
2184
bnc87dcefc2017-05-25 12:47:582185 auto trans1 =
Jeremy Roman0579ed62017-08-29 15:56:192186 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:202187 int rv = trans1->Start(&request1, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012188 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenke5f94fda2016-06-02 20:54:132189
2190 const HttpResponseInfo* response1 = trans1->GetResponseInfo();
2191 ASSERT_TRUE(response1);
2192 ASSERT_TRUE(response1->headers);
2193 EXPECT_EQ(200, response1->headers->response_code());
2194 EXPECT_TRUE(response1->headers->IsKeepAlive());
2195
2196 std::string response_data1;
robpercival214763f2016-07-01 23:27:012197 EXPECT_THAT(ReadTransaction(trans1.get(), &response_data1), IsOk());
mmenke5f94fda2016-06-02 20:54:132198 EXPECT_EQ("", response_data1);
2199 // Deleting the transaction attempts to release the socket back into the
2200 // socket pool.
2201 trans1.reset();
2202
2203 HttpRequestInfo request2;
2204 request2.method = "GET";
2205 request2.url = GURL("http://www.borked.com/foo");
2206
bnc87dcefc2017-05-25 12:47:582207 auto trans2 =
Jeremy Roman0579ed62017-08-29 15:56:192208 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:202209 rv = trans2->Start(&request2, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012210 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenke5f94fda2016-06-02 20:54:132211
2212 const HttpResponseInfo* response2 = trans2->GetResponseInfo();
2213 ASSERT_TRUE(response2);
2214 ASSERT_TRUE(response2->headers);
2215 EXPECT_EQ(200, response2->headers->response_code());
2216
2217 std::string response_data2;
robpercival214763f2016-07-01 23:27:012218 EXPECT_THAT(ReadTransaction(trans2.get(), &response_data2), IsOk());
mmenke5f94fda2016-06-02 20:54:132219 EXPECT_EQ("foo", response_data2);
2220}
2221
bncd16676a2016-07-20 16:23:012222TEST_F(HttpNetworkTransactionTest, KeepAliveWithUnusedData2) {
mmenke5f94fda2016-06-02 20:54:132223 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
2224 MockWrite data_writes1[] = {
2225 MockWrite("GET / HTTP/1.1\r\n"
2226 "Host: www.borked.com\r\n"
2227 "Connection: keep-alive\r\n\r\n"),
2228 };
2229
2230 MockRead data_reads1[] = {
2231 MockRead("HTTP/1.1 200 OK\r\n"
2232 "Connection: keep-alive\r\n"
2233 "Content-Length: 22\r\n\r\n"
2234 "This server is borked."
2235 "Bonus data!"),
2236 };
2237
2238 MockWrite data_writes2[] = {
2239 MockWrite("GET /foo HTTP/1.1\r\n"
2240 "Host: www.borked.com\r\n"
2241 "Connection: keep-alive\r\n\r\n"),
2242 };
2243
2244 MockRead data_reads2[] = {
2245 MockRead("HTTP/1.1 200 OK\r\n"
2246 "Content-Length: 3\r\n\r\n"
2247 "foo"),
2248 };
2249 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
2250 data_writes1, arraysize(data_writes1));
2251 session_deps_.socket_factory->AddSocketDataProvider(&data1);
2252 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
2253 data_writes2, arraysize(data_writes2));
2254 session_deps_.socket_factory->AddSocketDataProvider(&data2);
2255
2256 TestCompletionCallback callback;
2257 HttpRequestInfo request1;
2258 request1.method = "GET";
2259 request1.url = GURL("http://www.borked.com/");
2260
bnc87dcefc2017-05-25 12:47:582261 auto trans1 =
Jeremy Roman0579ed62017-08-29 15:56:192262 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:202263 int rv = trans1->Start(&request1, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012264 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenke5f94fda2016-06-02 20:54:132265
2266 const HttpResponseInfo* response1 = trans1->GetResponseInfo();
2267 ASSERT_TRUE(response1);
2268 ASSERT_TRUE(response1->headers);
2269 EXPECT_EQ(200, response1->headers->response_code());
2270 EXPECT_TRUE(response1->headers->IsKeepAlive());
2271
2272 std::string response_data1;
robpercival214763f2016-07-01 23:27:012273 EXPECT_THAT(ReadTransaction(trans1.get(), &response_data1), IsOk());
mmenke5f94fda2016-06-02 20:54:132274 EXPECT_EQ("This server is borked.", response_data1);
2275 // Deleting the transaction attempts to release the socket back into the
2276 // socket pool.
2277 trans1.reset();
2278
2279 HttpRequestInfo request2;
2280 request2.method = "GET";
2281 request2.url = GURL("http://www.borked.com/foo");
2282
bnc87dcefc2017-05-25 12:47:582283 auto trans2 =
Jeremy Roman0579ed62017-08-29 15:56:192284 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:202285 rv = trans2->Start(&request2, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012286 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenke5f94fda2016-06-02 20:54:132287
2288 const HttpResponseInfo* response2 = trans2->GetResponseInfo();
2289 ASSERT_TRUE(response2);
2290 ASSERT_TRUE(response2->headers);
2291 EXPECT_EQ(200, response2->headers->response_code());
2292
2293 std::string response_data2;
robpercival214763f2016-07-01 23:27:012294 EXPECT_THAT(ReadTransaction(trans2.get(), &response_data2), IsOk());
mmenke5f94fda2016-06-02 20:54:132295 EXPECT_EQ("foo", response_data2);
2296}
2297
bncd16676a2016-07-20 16:23:012298TEST_F(HttpNetworkTransactionTest, KeepAliveWithUnusedData3) {
mmenke5f94fda2016-06-02 20:54:132299 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
2300 MockWrite data_writes1[] = {
2301 MockWrite("GET / HTTP/1.1\r\n"
2302 "Host: www.borked.com\r\n"
2303 "Connection: keep-alive\r\n\r\n"),
2304 };
2305
2306 MockRead data_reads1[] = {
2307 MockRead("HTTP/1.1 200 OK\r\n"
2308 "Connection: keep-alive\r\n"
2309 "Transfer-Encoding: chunked\r\n\r\n"),
2310 MockRead("16\r\nThis server is borked.\r\n"),
2311 MockRead("0\r\n\r\nBonus data!"),
2312 };
2313
2314 MockWrite data_writes2[] = {
2315 MockWrite("GET /foo HTTP/1.1\r\n"
2316 "Host: www.borked.com\r\n"
2317 "Connection: keep-alive\r\n\r\n"),
2318 };
2319
2320 MockRead data_reads2[] = {
2321 MockRead("HTTP/1.1 200 OK\r\n"
2322 "Content-Length: 3\r\n\r\n"
2323 "foo"),
2324 };
2325 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
2326 data_writes1, arraysize(data_writes1));
2327 session_deps_.socket_factory->AddSocketDataProvider(&data1);
2328 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
2329 data_writes2, arraysize(data_writes2));
2330 session_deps_.socket_factory->AddSocketDataProvider(&data2);
2331
2332 TestCompletionCallback callback;
2333 HttpRequestInfo request1;
2334 request1.method = "GET";
2335 request1.url = GURL("http://www.borked.com/");
2336
bnc87dcefc2017-05-25 12:47:582337 auto trans1 =
Jeremy Roman0579ed62017-08-29 15:56:192338 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:202339 int rv = trans1->Start(&request1, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012340 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenke5f94fda2016-06-02 20:54:132341
2342 const HttpResponseInfo* response1 = trans1->GetResponseInfo();
2343 ASSERT_TRUE(response1);
2344 ASSERT_TRUE(response1->headers);
2345 EXPECT_EQ(200, response1->headers->response_code());
2346 EXPECT_TRUE(response1->headers->IsKeepAlive());
2347
2348 std::string response_data1;
robpercival214763f2016-07-01 23:27:012349 EXPECT_THAT(ReadTransaction(trans1.get(), &response_data1), IsOk());
mmenke5f94fda2016-06-02 20:54:132350 EXPECT_EQ("This server is borked.", response_data1);
2351 // Deleting the transaction attempts to release the socket back into the
2352 // socket pool.
2353 trans1.reset();
2354
2355 HttpRequestInfo request2;
2356 request2.method = "GET";
2357 request2.url = GURL("http://www.borked.com/foo");
2358
bnc87dcefc2017-05-25 12:47:582359 auto trans2 =
Jeremy Roman0579ed62017-08-29 15:56:192360 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:202361 rv = trans2->Start(&request2, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012362 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenke5f94fda2016-06-02 20:54:132363
2364 const HttpResponseInfo* response2 = trans2->GetResponseInfo();
2365 ASSERT_TRUE(response2);
2366 ASSERT_TRUE(response2->headers);
2367 EXPECT_EQ(200, response2->headers->response_code());
2368
2369 std::string response_data2;
robpercival214763f2016-07-01 23:27:012370 EXPECT_THAT(ReadTransaction(trans2.get(), &response_data2), IsOk());
mmenke5f94fda2016-06-02 20:54:132371 EXPECT_EQ("foo", response_data2);
2372}
2373
2374// This is a little different from the others - it tests the case that the
2375// HttpStreamParser doesn't know if there's extra data on a socket or not when
2376// the HttpNetworkTransaction is torn down, because the response body hasn't
2377// been read from yet, but the request goes through the HttpResponseBodyDrainer.
bncd16676a2016-07-20 16:23:012378TEST_F(HttpNetworkTransactionTest, KeepAliveWithUnusedData4) {
mmenke5f94fda2016-06-02 20:54:132379 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
2380 MockWrite data_writes1[] = {
2381 MockWrite("GET / HTTP/1.1\r\n"
2382 "Host: www.borked.com\r\n"
2383 "Connection: keep-alive\r\n\r\n"),
2384 };
2385
2386 MockRead data_reads1[] = {
2387 MockRead("HTTP/1.1 200 OK\r\n"
2388 "Connection: keep-alive\r\n"
2389 "Transfer-Encoding: chunked\r\n\r\n"),
2390 MockRead("16\r\nThis server is borked.\r\n"),
2391 MockRead("0\r\n\r\nBonus data!"),
2392 };
2393 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
2394 data_writes1, arraysize(data_writes1));
2395 session_deps_.socket_factory->AddSocketDataProvider(&data1);
2396
2397 TestCompletionCallback callback;
2398 HttpRequestInfo request1;
2399 request1.method = "GET";
2400 request1.url = GURL("http://www.borked.com/");
2401
bnc87dcefc2017-05-25 12:47:582402 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:192403 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
bnc87dcefc2017-05-25 12:47:582404 int rv = trans->Start(&request1, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012405 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenke5f94fda2016-06-02 20:54:132406
bnc87dcefc2017-05-25 12:47:582407 const HttpResponseInfo* response1 = trans->GetResponseInfo();
mmenke5f94fda2016-06-02 20:54:132408 ASSERT_TRUE(response1);
2409 ASSERT_TRUE(response1->headers);
2410 EXPECT_EQ(200, response1->headers->response_code());
2411 EXPECT_TRUE(response1->headers->IsKeepAlive());
2412
2413 // Deleting the transaction creates an HttpResponseBodyDrainer to read the
2414 // response body.
bnc87dcefc2017-05-25 12:47:582415 trans.reset();
mmenke5f94fda2016-06-02 20:54:132416
2417 // Let the HttpResponseBodyDrainer drain the socket. It should determine the
2418 // socket can't be reused, rather than returning it to the socket pool.
2419 base::RunLoop().RunUntilIdle();
2420
2421 // There should be no idle sockets in the pool.
2422 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
2423}
2424
[email protected]038e9a32008-10-08 22:40:162425// Test the request-challenge-retry sequence for basic auth.
2426// (basic auth is the easiest to mock, because it has no randomness).
bncd16676a2016-07-20 16:23:012427TEST_F(HttpNetworkTransactionTest, BasicAuth) {
[email protected]1c773ea12009-04-28 19:58:422428 HttpRequestInfo request;
[email protected]038e9a32008-10-08 22:40:162429 request.method = "GET";
bncce36dca22015-04-21 22:11:232430 request.url = GURL("http://www.example.org/");
[email protected]038e9a32008-10-08 22:40:162431
vishal.b62985ca92015-04-17 08:45:512432 TestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:072433 session_deps_.net_log = &log;
danakj1fd259a02016-04-16 03:17:092434 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:162435 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:272436
[email protected]f9ee6b52008-11-08 06:46:232437 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:232438 MockWrite(
2439 "GET / HTTP/1.1\r\n"
2440 "Host: www.example.org\r\n"
2441 "Connection: keep-alive\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:232442 };
2443
[email protected]038e9a32008-10-08 22:40:162444 MockRead data_reads1[] = {
2445 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
2446 // Give a couple authenticate options (only the middle one is actually
2447 // supported).
[email protected]22927ad2009-09-21 19:56:192448 MockRead("WWW-Authenticate: Basic invalid\r\n"), // Malformed.
[email protected]038e9a32008-10-08 22:40:162449 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2450 MockRead("WWW-Authenticate: UNSUPPORTED realm=\"FOO\"\r\n"),
2451 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
2452 // Large content-length -- won't matter, as connection will be reset.
2453 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:062454 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]038e9a32008-10-08 22:40:162455 };
2456
2457 // After calling trans->RestartWithAuth(), this is the request we should
2458 // be issuing -- the final header line contains the credentials.
2459 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:232460 MockWrite(
2461 "GET / HTTP/1.1\r\n"
2462 "Host: www.example.org\r\n"
2463 "Connection: keep-alive\r\n"
2464 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]038e9a32008-10-08 22:40:162465 };
2466
2467 // Lastly, the server responds with the actual content.
2468 MockRead data_reads2[] = {
2469 MockRead("HTTP/1.0 200 OK\r\n"),
2470 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
2471 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:062472 MockRead(SYNCHRONOUS, OK),
[email protected]038e9a32008-10-08 22:40:162473 };
2474
[email protected]31a2bfe2010-02-09 08:03:392475 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
2476 data_writes1, arraysize(data_writes1));
2477 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
2478 data_writes2, arraysize(data_writes2));
[email protected]bb88e1d32013-05-03 23:11:072479 session_deps_.socket_factory->AddSocketDataProvider(&data1);
2480 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]038e9a32008-10-08 22:40:162481
[email protected]49639fa2011-12-20 23:22:412482 TestCompletionCallback callback1;
[email protected]038e9a32008-10-08 22:40:162483
tfarina42834112016-09-22 13:38:202484 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012485 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]038e9a32008-10-08 22:40:162486
2487 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:012488 EXPECT_THAT(rv, IsOk());
[email protected]038e9a32008-10-08 22:40:162489
[email protected]58e32bb2013-01-21 18:23:252490 LoadTimingInfo load_timing_info1;
bnc691fda62016-08-12 00:43:162491 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info1));
[email protected]58e32bb2013-01-21 18:23:252492 TestLoadTimingNotReused(load_timing_info1, CONNECT_TIMING_HAS_DNS_TIMES);
2493
sclittlefb249892015-09-10 21:33:222494 int64_t writes_size1 = CountWriteBytes(data_writes1, arraysize(data_writes1));
bnc691fda62016-08-12 00:43:162495 EXPECT_EQ(writes_size1, trans.GetTotalSentBytes());
sclittlefb249892015-09-10 21:33:222496 int64_t reads_size1 = CountReadBytes(data_reads1, arraysize(data_reads1));
bnc691fda62016-08-12 00:43:162497 EXPECT_EQ(reads_size1, trans.GetTotalReceivedBytes());
[email protected]b8015c42013-12-24 15:18:192498
bnc691fda62016-08-12 00:43:162499 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:522500 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:042501 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]038e9a32008-10-08 22:40:162502
[email protected]49639fa2011-12-20 23:22:412503 TestCompletionCallback callback2;
[email protected]038e9a32008-10-08 22:40:162504
bnc691fda62016-08-12 00:43:162505 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar), callback2.callback());
robpercival214763f2016-07-01 23:27:012506 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]038e9a32008-10-08 22:40:162507
2508 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:012509 EXPECT_THAT(rv, IsOk());
[email protected]038e9a32008-10-08 22:40:162510
[email protected]58e32bb2013-01-21 18:23:252511 LoadTimingInfo load_timing_info2;
bnc691fda62016-08-12 00:43:162512 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info2));
[email protected]58e32bb2013-01-21 18:23:252513 TestLoadTimingNotReused(load_timing_info2, CONNECT_TIMING_HAS_DNS_TIMES);
2514 // The load timing after restart should have a new socket ID, and times after
2515 // those of the first load timing.
2516 EXPECT_LE(load_timing_info1.receive_headers_end,
2517 load_timing_info2.connect_timing.connect_start);
2518 EXPECT_NE(load_timing_info1.socket_log_id, load_timing_info2.socket_log_id);
2519
sclittlefb249892015-09-10 21:33:222520 int64_t writes_size2 = CountWriteBytes(data_writes2, arraysize(data_writes2));
bnc691fda62016-08-12 00:43:162521 EXPECT_EQ(writes_size1 + writes_size2, trans.GetTotalSentBytes());
sclittlefb249892015-09-10 21:33:222522 int64_t reads_size2 = CountReadBytes(data_reads2, arraysize(data_reads2));
bnc691fda62016-08-12 00:43:162523 EXPECT_EQ(reads_size1 + reads_size2, trans.GetTotalReceivedBytes());
[email protected]b8015c42013-12-24 15:18:192524
bnc691fda62016-08-12 00:43:162525 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:522526 ASSERT_TRUE(response);
2527 EXPECT_FALSE(response->auth_challenge);
[email protected]038e9a32008-10-08 22:40:162528 EXPECT_EQ(100, response->headers->GetContentLength());
[email protected]038e9a32008-10-08 22:40:162529}
2530
ttuttled9dbc652015-09-29 20:00:592531// Test the request-challenge-retry sequence for basic auth.
2532// (basic auth is the easiest to mock, because it has no randomness).
bncd16676a2016-07-20 16:23:012533TEST_F(HttpNetworkTransactionTest, BasicAuthWithAddressChange) {
ttuttled9dbc652015-09-29 20:00:592534 HttpRequestInfo request;
2535 request.method = "GET";
2536 request.url = GURL("http://www.example.org/");
ttuttled9dbc652015-09-29 20:00:592537
2538 TestNetLog log;
2539 MockHostResolver* resolver = new MockHostResolver();
2540 session_deps_.net_log = &log;
2541 session_deps_.host_resolver.reset(resolver);
danakj1fd259a02016-04-16 03:17:092542 std::unique_ptr<HttpNetworkSession> session = CreateSession(&session_deps_);
bnc691fda62016-08-12 00:43:162543 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
ttuttled9dbc652015-09-29 20:00:592544
2545 resolver->rules()->ClearRules();
2546 resolver->rules()->AddRule("www.example.org", "127.0.0.1");
2547
2548 MockWrite data_writes1[] = {
2549 MockWrite("GET / HTTP/1.1\r\n"
2550 "Host: www.example.org\r\n"
2551 "Connection: keep-alive\r\n\r\n"),
2552 };
2553
2554 MockRead data_reads1[] = {
2555 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
2556 // Give a couple authenticate options (only the middle one is actually
2557 // supported).
2558 MockRead("WWW-Authenticate: Basic invalid\r\n"), // Malformed.
2559 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2560 MockRead("WWW-Authenticate: UNSUPPORTED realm=\"FOO\"\r\n"),
2561 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
2562 // Large content-length -- won't matter, as connection will be reset.
2563 MockRead("Content-Length: 10000\r\n\r\n"),
2564 MockRead(SYNCHRONOUS, ERR_FAILED),
2565 };
2566
2567 // After calling trans->RestartWithAuth(), this is the request we should
2568 // be issuing -- the final header line contains the credentials.
2569 MockWrite data_writes2[] = {
2570 MockWrite("GET / HTTP/1.1\r\n"
2571 "Host: www.example.org\r\n"
2572 "Connection: keep-alive\r\n"
2573 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
2574 };
2575
2576 // Lastly, the server responds with the actual content.
2577 MockRead data_reads2[] = {
2578 MockRead("HTTP/1.0 200 OK\r\n"),
2579 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
2580 MockRead("Content-Length: 100\r\n\r\n"), MockRead(SYNCHRONOUS, OK),
2581 };
2582
2583 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
2584 data_writes1, arraysize(data_writes1));
2585 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
2586 data_writes2, arraysize(data_writes2));
2587 session_deps_.socket_factory->AddSocketDataProvider(&data1);
2588 session_deps_.socket_factory->AddSocketDataProvider(&data2);
2589
2590 TestCompletionCallback callback1;
2591
bnc691fda62016-08-12 00:43:162592 EXPECT_EQ(OK, callback1.GetResult(trans.Start(&request, callback1.callback(),
tfarina42834112016-09-22 13:38:202593 NetLogWithSource())));
ttuttled9dbc652015-09-29 20:00:592594
2595 LoadTimingInfo load_timing_info1;
bnc691fda62016-08-12 00:43:162596 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info1));
ttuttled9dbc652015-09-29 20:00:592597 TestLoadTimingNotReused(load_timing_info1, CONNECT_TIMING_HAS_DNS_TIMES);
2598
2599 int64_t writes_size1 = CountWriteBytes(data_writes1, arraysize(data_writes1));
bnc691fda62016-08-12 00:43:162600 EXPECT_EQ(writes_size1, trans.GetTotalSentBytes());
ttuttled9dbc652015-09-29 20:00:592601 int64_t reads_size1 = CountReadBytes(data_reads1, arraysize(data_reads1));
bnc691fda62016-08-12 00:43:162602 EXPECT_EQ(reads_size1, trans.GetTotalReceivedBytes());
ttuttled9dbc652015-09-29 20:00:592603
bnc691fda62016-08-12 00:43:162604 const HttpResponseInfo* response = trans.GetResponseInfo();
ttuttled9dbc652015-09-29 20:00:592605 ASSERT_TRUE(response);
2606 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
2607
2608 IPEndPoint endpoint;
bnc691fda62016-08-12 00:43:162609 EXPECT_TRUE(trans.GetRemoteEndpoint(&endpoint));
ttuttled9dbc652015-09-29 20:00:592610 ASSERT_FALSE(endpoint.address().empty());
2611 EXPECT_EQ("127.0.0.1:80", endpoint.ToString());
2612
2613 resolver->rules()->ClearRules();
2614 resolver->rules()->AddRule("www.example.org", "127.0.0.2");
2615
2616 TestCompletionCallback callback2;
2617
bnc691fda62016-08-12 00:43:162618 EXPECT_EQ(OK, callback2.GetResult(trans.RestartWithAuth(
ttuttled9dbc652015-09-29 20:00:592619 AuthCredentials(kFoo, kBar), callback2.callback())));
2620
2621 LoadTimingInfo load_timing_info2;
bnc691fda62016-08-12 00:43:162622 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info2));
ttuttled9dbc652015-09-29 20:00:592623 TestLoadTimingNotReused(load_timing_info2, CONNECT_TIMING_HAS_DNS_TIMES);
2624 // The load timing after restart should have a new socket ID, and times after
2625 // those of the first load timing.
2626 EXPECT_LE(load_timing_info1.receive_headers_end,
2627 load_timing_info2.connect_timing.connect_start);
2628 EXPECT_NE(load_timing_info1.socket_log_id, load_timing_info2.socket_log_id);
2629
2630 int64_t writes_size2 = CountWriteBytes(data_writes2, arraysize(data_writes2));
bnc691fda62016-08-12 00:43:162631 EXPECT_EQ(writes_size1 + writes_size2, trans.GetTotalSentBytes());
ttuttled9dbc652015-09-29 20:00:592632 int64_t reads_size2 = CountReadBytes(data_reads2, arraysize(data_reads2));
bnc691fda62016-08-12 00:43:162633 EXPECT_EQ(reads_size1 + reads_size2, trans.GetTotalReceivedBytes());
ttuttled9dbc652015-09-29 20:00:592634
bnc691fda62016-08-12 00:43:162635 response = trans.GetResponseInfo();
ttuttled9dbc652015-09-29 20:00:592636 ASSERT_TRUE(response);
wezca1070932016-05-26 20:30:522637 EXPECT_FALSE(response->auth_challenge);
ttuttled9dbc652015-09-29 20:00:592638 EXPECT_EQ(100, response->headers->GetContentLength());
2639
bnc691fda62016-08-12 00:43:162640 EXPECT_TRUE(trans.GetRemoteEndpoint(&endpoint));
ttuttled9dbc652015-09-29 20:00:592641 ASSERT_FALSE(endpoint.address().empty());
2642 EXPECT_EQ("127.0.0.2:80", endpoint.ToString());
2643}
2644
bncd16676a2016-07-20 16:23:012645TEST_F(HttpNetworkTransactionTest, DoNotSendAuth) {
[email protected]861fcd52009-08-26 02:33:462646 HttpRequestInfo request;
2647 request.method = "GET";
bncce36dca22015-04-21 22:11:232648 request.url = GURL("http://www.example.org/");
ttuttle859dc7a2015-04-23 19:42:292649 request.load_flags = LOAD_DO_NOT_SEND_AUTH_DATA;
[email protected]861fcd52009-08-26 02:33:462650
danakj1fd259a02016-04-16 03:17:092651 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:162652 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:272653
[email protected]861fcd52009-08-26 02:33:462654 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:232655 MockWrite(
2656 "GET / HTTP/1.1\r\n"
2657 "Host: www.example.org\r\n"
2658 "Connection: keep-alive\r\n\r\n"),
[email protected]861fcd52009-08-26 02:33:462659 };
2660
2661 MockRead data_reads[] = {
2662 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
2663 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2664 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
2665 // Large content-length -- won't matter, as connection will be reset.
2666 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:062667 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]861fcd52009-08-26 02:33:462668 };
2669
[email protected]31a2bfe2010-02-09 08:03:392670 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
2671 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:072672 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]49639fa2011-12-20 23:22:412673 TestCompletionCallback callback;
[email protected]861fcd52009-08-26 02:33:462674
tfarina42834112016-09-22 13:38:202675 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012676 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]861fcd52009-08-26 02:33:462677
2678 rv = callback.WaitForResult();
2679 EXPECT_EQ(0, rv);
2680
sclittlefb249892015-09-10 21:33:222681 int64_t writes_size = CountWriteBytes(data_writes, arraysize(data_writes));
bnc691fda62016-08-12 00:43:162682 EXPECT_EQ(writes_size, trans.GetTotalSentBytes());
sclittlefb249892015-09-10 21:33:222683 int64_t reads_size = CountReadBytes(data_reads, arraysize(data_reads));
bnc691fda62016-08-12 00:43:162684 EXPECT_EQ(reads_size, trans.GetTotalReceivedBytes());
[email protected]b8015c42013-12-24 15:18:192685
bnc691fda62016-08-12 00:43:162686 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:522687 ASSERT_TRUE(response);
2688 EXPECT_FALSE(response->auth_challenge);
[email protected]861fcd52009-08-26 02:33:462689}
2690
[email protected]2d2697f92009-02-18 21:00:322691// Test the request-challenge-retry sequence for basic auth, over a keep-alive
2692// connection.
bncd16676a2016-07-20 16:23:012693TEST_F(HttpNetworkTransactionTest, BasicAuthKeepAlive) {
mmenkecc2298e2015-12-07 18:20:182694 // On the second pass, the body read of the auth challenge is synchronous, so
2695 // IsConnectedAndIdle returns false. The socket should still be drained and
2696 // reused. See http://crbug.com/544255.
2697 for (int i = 0; i < 2; ++i) {
2698 HttpRequestInfo request;
2699 request.method = "GET";
2700 request.url = GURL("http://www.example.org/");
[email protected]2d2697f92009-02-18 21:00:322701
mmenkecc2298e2015-12-07 18:20:182702 TestNetLog log;
2703 session_deps_.net_log = &log;
danakj1fd259a02016-04-16 03:17:092704 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:272705
mmenkecc2298e2015-12-07 18:20:182706 MockWrite data_writes[] = {
2707 MockWrite(ASYNC, 0,
2708 "GET / HTTP/1.1\r\n"
2709 "Host: www.example.org\r\n"
2710 "Connection: keep-alive\r\n\r\n"),
[email protected]2d2697f92009-02-18 21:00:322711
bnc691fda62016-08-12 00:43:162712 // After calling trans.RestartWithAuth(), this is the request we should
mmenkecc2298e2015-12-07 18:20:182713 // be issuing -- the final header line contains the credentials.
2714 MockWrite(ASYNC, 6,
2715 "GET / HTTP/1.1\r\n"
2716 "Host: www.example.org\r\n"
2717 "Connection: keep-alive\r\n"
2718 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
2719 };
[email protected]2d2697f92009-02-18 21:00:322720
mmenkecc2298e2015-12-07 18:20:182721 MockRead data_reads[] = {
2722 MockRead(ASYNC, 1, "HTTP/1.1 401 Unauthorized\r\n"),
2723 MockRead(ASYNC, 2, "WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2724 MockRead(ASYNC, 3, "Content-Type: text/html; charset=iso-8859-1\r\n"),
2725 MockRead(ASYNC, 4, "Content-Length: 14\r\n\r\n"),
2726 MockRead(i == 0 ? ASYNC : SYNCHRONOUS, 5, "Unauthorized\r\n"),
[email protected]2d2697f92009-02-18 21:00:322727
mmenkecc2298e2015-12-07 18:20:182728 // Lastly, the server responds with the actual content.
2729 MockRead(ASYNC, 7, "HTTP/1.1 200 OK\r\n"),
2730 MockRead(ASYNC, 8, "Content-Type: text/html; charset=iso-8859-1\r\n"),
2731 MockRead(ASYNC, 9, "Content-Length: 5\r\n\r\n"),
2732 MockRead(ASYNC, 10, "Hello"),
2733 };
[email protected]2d2697f92009-02-18 21:00:322734
mmenkecc2298e2015-12-07 18:20:182735 SequencedSocketData data(data_reads, arraysize(data_reads), data_writes,
2736 arraysize(data_writes));
2737 data.set_busy_before_sync_reads(true);
2738 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]2d0a4f92011-05-05 16:38:462739
mmenkecc2298e2015-12-07 18:20:182740 TestCompletionCallback callback1;
[email protected]2d2697f92009-02-18 21:00:322741
bnc691fda62016-08-12 00:43:162742 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:202743 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012744 ASSERT_THAT(callback1.GetResult(rv), IsOk());
[email protected]2d2697f92009-02-18 21:00:322745
mmenkecc2298e2015-12-07 18:20:182746 LoadTimingInfo load_timing_info1;
bnc691fda62016-08-12 00:43:162747 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info1));
mmenkecc2298e2015-12-07 18:20:182748 TestLoadTimingNotReused(load_timing_info1, CONNECT_TIMING_HAS_DNS_TIMES);
[email protected]2d2697f92009-02-18 21:00:322749
bnc691fda62016-08-12 00:43:162750 const HttpResponseInfo* response = trans.GetResponseInfo();
mmenkecc2298e2015-12-07 18:20:182751 ASSERT_TRUE(response);
2752 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]2d2697f92009-02-18 21:00:322753
mmenkecc2298e2015-12-07 18:20:182754 TestCompletionCallback callback2;
[email protected]58e32bb2013-01-21 18:23:252755
bnc691fda62016-08-12 00:43:162756 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar),
2757 callback2.callback());
robpercival214763f2016-07-01 23:27:012758 ASSERT_THAT(callback2.GetResult(rv), IsOk());
[email protected]2d2697f92009-02-18 21:00:322759
mmenkecc2298e2015-12-07 18:20:182760 LoadTimingInfo load_timing_info2;
bnc691fda62016-08-12 00:43:162761 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info2));
mmenkecc2298e2015-12-07 18:20:182762 TestLoadTimingReused(load_timing_info2);
2763 // The load timing after restart should have the same socket ID, and times
2764 // those of the first load timing.
2765 EXPECT_LE(load_timing_info1.receive_headers_end,
2766 load_timing_info2.send_start);
2767 EXPECT_EQ(load_timing_info1.socket_log_id, load_timing_info2.socket_log_id);
[email protected]2d2697f92009-02-18 21:00:322768
bnc691fda62016-08-12 00:43:162769 response = trans.GetResponseInfo();
mmenkecc2298e2015-12-07 18:20:182770 ASSERT_TRUE(response);
2771 EXPECT_FALSE(response->auth_challenge);
2772 EXPECT_EQ(5, response->headers->GetContentLength());
[email protected]2d2697f92009-02-18 21:00:322773
mmenkecc2298e2015-12-07 18:20:182774 std::string response_data;
bnc691fda62016-08-12 00:43:162775 EXPECT_THAT(ReadTransaction(&trans, &response_data), IsOk());
[email protected]2d2697f92009-02-18 21:00:322776
mmenkecc2298e2015-12-07 18:20:182777 int64_t writes_size = CountWriteBytes(data_writes, arraysize(data_writes));
bnc691fda62016-08-12 00:43:162778 EXPECT_EQ(writes_size, trans.GetTotalSentBytes());
mmenkecc2298e2015-12-07 18:20:182779 int64_t reads_size = CountReadBytes(data_reads, arraysize(data_reads));
bnc691fda62016-08-12 00:43:162780 EXPECT_EQ(reads_size, trans.GetTotalReceivedBytes());
mmenkecc2298e2015-12-07 18:20:182781 }
[email protected]2d2697f92009-02-18 21:00:322782}
2783
2784// Test the request-challenge-retry sequence for basic auth, over a keep-alive
2785// connection and with no response body to drain.
bncd16676a2016-07-20 16:23:012786TEST_F(HttpNetworkTransactionTest, BasicAuthKeepAliveNoBody) {
[email protected]1c773ea12009-04-28 19:58:422787 HttpRequestInfo request;
[email protected]2d2697f92009-02-18 21:00:322788 request.method = "GET";
bncce36dca22015-04-21 22:11:232789 request.url = GURL("http://www.example.org/");
[email protected]2d2697f92009-02-18 21:00:322790
danakj1fd259a02016-04-16 03:17:092791 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:272792
[email protected]2d2697f92009-02-18 21:00:322793 MockWrite data_writes1[] = {
bnc691fda62016-08-12 00:43:162794 MockWrite("GET / HTTP/1.1\r\n"
2795 "Host: www.example.org\r\n"
2796 "Connection: keep-alive\r\n\r\n"),
[email protected]2d2697f92009-02-18 21:00:322797
bnc691fda62016-08-12 00:43:162798 // After calling trans.RestartWithAuth(), this is the request we should
bncce36dca22015-04-21 22:11:232799 // be issuing -- the final header line contains the credentials.
bnc691fda62016-08-12 00:43:162800 MockWrite("GET / HTTP/1.1\r\n"
2801 "Host: www.example.org\r\n"
2802 "Connection: keep-alive\r\n"
2803 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]2d2697f92009-02-18 21:00:322804 };
2805
[email protected]2d2697f92009-02-18 21:00:322806 MockRead data_reads1[] = {
2807 MockRead("HTTP/1.1 401 Unauthorized\r\n"),
2808 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
[email protected]11203f012009-11-12 23:02:312809 MockRead("Content-Length: 0\r\n\r\n"), // No response body.
[email protected]2d2697f92009-02-18 21:00:322810
2811 // Lastly, the server responds with the actual content.
2812 MockRead("HTTP/1.1 200 OK\r\n"),
2813 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
[email protected]0b0bf032010-09-21 18:08:502814 MockRead("Content-Length: 5\r\n\r\n"),
2815 MockRead("hello"),
[email protected]2d2697f92009-02-18 21:00:322816 };
2817
[email protected]2d0a4f92011-05-05 16:38:462818 // An incorrect reconnect would cause this to be read.
2819 MockRead data_reads2[] = {
[email protected]8ddf8322012-02-23 18:08:062820 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]2d0a4f92011-05-05 16:38:462821 };
2822
[email protected]31a2bfe2010-02-09 08:03:392823 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
2824 data_writes1, arraysize(data_writes1));
[email protected]2d0a4f92011-05-05 16:38:462825 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
2826 NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:072827 session_deps_.socket_factory->AddSocketDataProvider(&data1);
2828 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]2d2697f92009-02-18 21:00:322829
[email protected]49639fa2011-12-20 23:22:412830 TestCompletionCallback callback1;
[email protected]2d2697f92009-02-18 21:00:322831
bnc691fda62016-08-12 00:43:162832 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:202833 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012834 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2d2697f92009-02-18 21:00:322835
2836 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:012837 EXPECT_THAT(rv, IsOk());
[email protected]2d2697f92009-02-18 21:00:322838
bnc691fda62016-08-12 00:43:162839 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:522840 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:042841 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]2d2697f92009-02-18 21:00:322842
[email protected]49639fa2011-12-20 23:22:412843 TestCompletionCallback callback2;
[email protected]2d2697f92009-02-18 21:00:322844
bnc691fda62016-08-12 00:43:162845 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar), callback2.callback());
robpercival214763f2016-07-01 23:27:012846 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2d2697f92009-02-18 21:00:322847
2848 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:012849 EXPECT_THAT(rv, IsOk());
[email protected]2d2697f92009-02-18 21:00:322850
bnc691fda62016-08-12 00:43:162851 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:522852 ASSERT_TRUE(response);
2853 EXPECT_FALSE(response->auth_challenge);
[email protected]0b0bf032010-09-21 18:08:502854 EXPECT_EQ(5, response->headers->GetContentLength());
[email protected]2d2697f92009-02-18 21:00:322855}
2856
2857// Test the request-challenge-retry sequence for basic auth, over a keep-alive
2858// connection and with a large response body to drain.
bncd16676a2016-07-20 16:23:012859TEST_F(HttpNetworkTransactionTest, BasicAuthKeepAliveLargeBody) {
[email protected]1c773ea12009-04-28 19:58:422860 HttpRequestInfo request;
[email protected]2d2697f92009-02-18 21:00:322861 request.method = "GET";
bncce36dca22015-04-21 22:11:232862 request.url = GURL("http://www.example.org/");
[email protected]2d2697f92009-02-18 21:00:322863
danakj1fd259a02016-04-16 03:17:092864 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:272865
[email protected]2d2697f92009-02-18 21:00:322866 MockWrite data_writes1[] = {
bnc691fda62016-08-12 00:43:162867 MockWrite("GET / HTTP/1.1\r\n"
2868 "Host: www.example.org\r\n"
2869 "Connection: keep-alive\r\n\r\n"),
[email protected]2d2697f92009-02-18 21:00:322870
bnc691fda62016-08-12 00:43:162871 // After calling trans.RestartWithAuth(), this is the request we should
bncce36dca22015-04-21 22:11:232872 // be issuing -- the final header line contains the credentials.
bnc691fda62016-08-12 00:43:162873 MockWrite("GET / HTTP/1.1\r\n"
2874 "Host: www.example.org\r\n"
2875 "Connection: keep-alive\r\n"
2876 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]2d2697f92009-02-18 21:00:322877 };
2878
2879 // Respond with 5 kb of response body.
2880 std::string large_body_string("Unauthorized");
2881 large_body_string.append(5 * 1024, ' ');
2882 large_body_string.append("\r\n");
2883
2884 MockRead data_reads1[] = {
2885 MockRead("HTTP/1.1 401 Unauthorized\r\n"),
2886 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2887 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
2888 // 5134 = 12 + 5 * 1024 + 2
2889 MockRead("Content-Length: 5134\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:062890 MockRead(ASYNC, large_body_string.data(), large_body_string.size()),
[email protected]2d2697f92009-02-18 21:00:322891
2892 // Lastly, the server responds with the actual content.
2893 MockRead("HTTP/1.1 200 OK\r\n"),
2894 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
[email protected]0b0bf032010-09-21 18:08:502895 MockRead("Content-Length: 5\r\n\r\n"),
2896 MockRead("hello"),
[email protected]2d2697f92009-02-18 21:00:322897 };
2898
[email protected]2d0a4f92011-05-05 16:38:462899 // An incorrect reconnect would cause this to be read.
2900 MockRead data_reads2[] = {
[email protected]8ddf8322012-02-23 18:08:062901 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]2d0a4f92011-05-05 16:38:462902 };
2903
[email protected]31a2bfe2010-02-09 08:03:392904 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
2905 data_writes1, arraysize(data_writes1));
[email protected]2d0a4f92011-05-05 16:38:462906 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
2907 NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:072908 session_deps_.socket_factory->AddSocketDataProvider(&data1);
2909 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]2d2697f92009-02-18 21:00:322910
[email protected]49639fa2011-12-20 23:22:412911 TestCompletionCallback callback1;
[email protected]2d2697f92009-02-18 21:00:322912
bnc691fda62016-08-12 00:43:162913 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:202914 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012915 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2d2697f92009-02-18 21:00:322916
2917 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:012918 EXPECT_THAT(rv, IsOk());
[email protected]2d2697f92009-02-18 21:00:322919
bnc691fda62016-08-12 00:43:162920 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:522921 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:042922 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]2d2697f92009-02-18 21:00:322923
[email protected]49639fa2011-12-20 23:22:412924 TestCompletionCallback callback2;
[email protected]2d2697f92009-02-18 21:00:322925
bnc691fda62016-08-12 00:43:162926 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar), callback2.callback());
robpercival214763f2016-07-01 23:27:012927 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2d2697f92009-02-18 21:00:322928
2929 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:012930 EXPECT_THAT(rv, IsOk());
[email protected]2d2697f92009-02-18 21:00:322931
bnc691fda62016-08-12 00:43:162932 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:522933 ASSERT_TRUE(response);
2934 EXPECT_FALSE(response->auth_challenge);
[email protected]0b0bf032010-09-21 18:08:502935 EXPECT_EQ(5, response->headers->GetContentLength());
[email protected]2d2697f92009-02-18 21:00:322936}
2937
2938// Test the request-challenge-retry sequence for basic auth, over a keep-alive
[email protected]11203f012009-11-12 23:02:312939// connection, but the server gets impatient and closes the connection.
bncd16676a2016-07-20 16:23:012940TEST_F(HttpNetworkTransactionTest, BasicAuthKeepAliveImpatientServer) {
[email protected]11203f012009-11-12 23:02:312941 HttpRequestInfo request;
2942 request.method = "GET";
bncce36dca22015-04-21 22:11:232943 request.url = GURL("http://www.example.org/");
[email protected]11203f012009-11-12 23:02:312944
danakj1fd259a02016-04-16 03:17:092945 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:272946
[email protected]11203f012009-11-12 23:02:312947 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:232948 MockWrite(
2949 "GET / HTTP/1.1\r\n"
2950 "Host: www.example.org\r\n"
2951 "Connection: keep-alive\r\n\r\n"),
2952 // This simulates the seemingly successful write to a closed connection
2953 // if the bug is not fixed.
2954 MockWrite(
2955 "GET / HTTP/1.1\r\n"
2956 "Host: www.example.org\r\n"
2957 "Connection: keep-alive\r\n"
2958 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]11203f012009-11-12 23:02:312959 };
2960
2961 MockRead data_reads1[] = {
2962 MockRead("HTTP/1.1 401 Unauthorized\r\n"),
2963 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2964 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
2965 MockRead("Content-Length: 14\r\n\r\n"),
2966 // Tell MockTCPClientSocket to simulate the server closing the connection.
[email protected]8ddf8322012-02-23 18:08:062967 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
[email protected]11203f012009-11-12 23:02:312968 MockRead("Unauthorized\r\n"),
[email protected]8ddf8322012-02-23 18:08:062969 MockRead(SYNCHRONOUS, OK), // The server closes the connection.
[email protected]11203f012009-11-12 23:02:312970 };
2971
bnc691fda62016-08-12 00:43:162972 // After calling trans.RestartWithAuth(), this is the request we should
[email protected]11203f012009-11-12 23:02:312973 // be issuing -- the final header line contains the credentials.
2974 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:232975 MockWrite(
2976 "GET / HTTP/1.1\r\n"
2977 "Host: www.example.org\r\n"
2978 "Connection: keep-alive\r\n"
2979 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]11203f012009-11-12 23:02:312980 };
2981
2982 // Lastly, the server responds with the actual content.
2983 MockRead data_reads2[] = {
2984 MockRead("HTTP/1.1 200 OK\r\n"),
2985 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
[email protected]0b0bf032010-09-21 18:08:502986 MockRead("Content-Length: 5\r\n\r\n"),
2987 MockRead("hello"),
[email protected]11203f012009-11-12 23:02:312988 };
2989
[email protected]31a2bfe2010-02-09 08:03:392990 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
2991 data_writes1, arraysize(data_writes1));
2992 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
2993 data_writes2, arraysize(data_writes2));
[email protected]bb88e1d32013-05-03 23:11:072994 session_deps_.socket_factory->AddSocketDataProvider(&data1);
2995 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]11203f012009-11-12 23:02:312996
[email protected]49639fa2011-12-20 23:22:412997 TestCompletionCallback callback1;
[email protected]11203f012009-11-12 23:02:312998
bnc691fda62016-08-12 00:43:162999 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:203000 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:013001 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]11203f012009-11-12 23:02:313002
3003 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:013004 EXPECT_THAT(rv, IsOk());
[email protected]11203f012009-11-12 23:02:313005
bnc691fda62016-08-12 00:43:163006 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:523007 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:043008 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]11203f012009-11-12 23:02:313009
[email protected]49639fa2011-12-20 23:22:413010 TestCompletionCallback callback2;
[email protected]11203f012009-11-12 23:02:313011
bnc691fda62016-08-12 00:43:163012 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar), callback2.callback());
robpercival214763f2016-07-01 23:27:013013 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]11203f012009-11-12 23:02:313014
3015 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:013016 EXPECT_THAT(rv, IsOk());
[email protected]11203f012009-11-12 23:02:313017
bnc691fda62016-08-12 00:43:163018 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:523019 ASSERT_TRUE(response);
3020 EXPECT_FALSE(response->auth_challenge);
[email protected]0b0bf032010-09-21 18:08:503021 EXPECT_EQ(5, response->headers->GetContentLength());
[email protected]11203f012009-11-12 23:02:313022}
3023
[email protected]394816e92010-08-03 07:38:593024// Test the request-challenge-retry sequence for basic auth, over a connection
3025// that requires a restart when setting up an SSL tunnel.
bncd16676a2016-07-20 16:23:013026TEST_F(HttpNetworkTransactionTest, BasicAuthProxyNoKeepAliveHttp10) {
ttuttle34f63b52015-03-05 04:33:013027 HttpRequestInfo request;
3028 request.method = "GET";
bncce36dca22015-04-21 22:11:233029 request.url = GURL("https://www.example.org/");
ttuttle34f63b52015-03-05 04:33:013030 // when the no authentication data flag is set.
ttuttle859dc7a2015-04-23 19:42:293031 request.load_flags = LOAD_DO_NOT_SEND_AUTH_DATA;
ttuttle34f63b52015-03-05 04:33:013032
3033 // Configure against proxy server "myproxy:70".
Lily Houghton8c2f97d2018-01-22 05:06:593034 session_deps_.proxy_resolution_service =
3035 ProxyResolutionService::CreateFixedFromPacResult("PROXY myproxy:70");
vishal.b62985ca92015-04-17 08:45:513036 BoundTestNetLog log;
ttuttle34f63b52015-03-05 04:33:013037 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:093038 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
ttuttle34f63b52015-03-05 04:33:013039
3040 // Since we have proxy, should try to establish tunnel.
3041 MockWrite data_writes1[] = {
mmenkee71e15332015-10-07 16:39:543042 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:173043 "Host: www.example.org:443\r\n"
mmenkee71e15332015-10-07 16:39:543044 "Proxy-Connection: keep-alive\r\n\r\n"),
ttuttle34f63b52015-03-05 04:33:013045 };
3046
mmenkee71e15332015-10-07 16:39:543047 // The proxy responds to the connect with a 407, using a non-persistent
ttuttle34f63b52015-03-05 04:33:013048 // connection.
3049 MockRead data_reads1[] = {
3050 // No credentials.
3051 MockRead("HTTP/1.0 407 Proxy Authentication Required\r\n"),
3052 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n\r\n"),
mmenkee71e15332015-10-07 16:39:543053 };
ttuttle34f63b52015-03-05 04:33:013054
mmenkee71e15332015-10-07 16:39:543055 // Since the first connection couldn't be reused, need to establish another
3056 // once given credentials.
3057 MockWrite data_writes2[] = {
3058 // After calling trans->RestartWithAuth(), this is the request we should
3059 // be issuing -- the final header line contains the credentials.
3060 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:173061 "Host: www.example.org:443\r\n"
mmenkee71e15332015-10-07 16:39:543062 "Proxy-Connection: keep-alive\r\n"
3063 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
3064
3065 MockWrite("GET / HTTP/1.1\r\n"
3066 "Host: www.example.org\r\n"
3067 "Connection: keep-alive\r\n\r\n"),
3068 };
3069
3070 MockRead data_reads2[] = {
ttuttle34f63b52015-03-05 04:33:013071 MockRead("HTTP/1.0 200 Connection Established\r\n\r\n"),
3072
3073 MockRead("HTTP/1.1 200 OK\r\n"),
3074 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
3075 MockRead("Content-Length: 5\r\n\r\n"),
3076 MockRead(SYNCHRONOUS, "hello"),
3077 };
3078
3079 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
3080 data_writes1, arraysize(data_writes1));
3081 session_deps_.socket_factory->AddSocketDataProvider(&data1);
mmenkee71e15332015-10-07 16:39:543082 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
3083 data_writes2, arraysize(data_writes2));
3084 session_deps_.socket_factory->AddSocketDataProvider(&data2);
ttuttle34f63b52015-03-05 04:33:013085 SSLSocketDataProvider ssl(ASYNC, OK);
3086 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
3087
3088 TestCompletionCallback callback1;
3089
bnc87dcefc2017-05-25 12:47:583090 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:193091 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
ttuttle34f63b52015-03-05 04:33:013092
3093 int rv = trans->Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:013094 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
ttuttle34f63b52015-03-05 04:33:013095
3096 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:013097 EXPECT_THAT(rv, IsOk());
mmenke43758e62015-05-04 21:09:463098 TestNetLogEntry::List entries;
ttuttle34f63b52015-03-05 04:33:013099 log.GetEntries(&entries);
3100 size_t pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:003101 entries, 0, NetLogEventType::HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
3102 NetLogEventPhase::NONE);
ttuttle34f63b52015-03-05 04:33:013103 ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:003104 entries, pos,
3105 NetLogEventType::HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
3106 NetLogEventPhase::NONE);
ttuttle34f63b52015-03-05 04:33:013107
3108 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:523109 ASSERT_TRUE(response);
ttuttle34f63b52015-03-05 04:33:013110 EXPECT_FALSE(response->headers->IsKeepAlive());
wezca1070932016-05-26 20:30:523111 ASSERT_TRUE(response->headers);
ttuttle34f63b52015-03-05 04:33:013112 EXPECT_EQ(407, response->headers->response_code());
3113 EXPECT_TRUE(HttpVersion(1, 0) == response->headers->GetHttpVersion());
3114 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
3115
3116 LoadTimingInfo load_timing_info;
3117 // CONNECT requests and responses are handled at the connect job level, so
3118 // the transaction does not yet have a connection.
3119 EXPECT_FALSE(trans->GetLoadTimingInfo(&load_timing_info));
3120
3121 TestCompletionCallback callback2;
3122
3123 rv =
3124 trans->RestartWithAuth(AuthCredentials(kFoo, kBar), callback2.callback());
robpercival214763f2016-07-01 23:27:013125 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
ttuttle34f63b52015-03-05 04:33:013126
3127 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:013128 EXPECT_THAT(rv, IsOk());
ttuttle34f63b52015-03-05 04:33:013129
3130 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:523131 ASSERT_TRUE(response);
ttuttle34f63b52015-03-05 04:33:013132
3133 EXPECT_TRUE(response->headers->IsKeepAlive());
3134 EXPECT_EQ(200, response->headers->response_code());
3135 EXPECT_EQ(5, response->headers->GetContentLength());
3136 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
3137
3138 // The password prompt info should not be set.
wezca1070932016-05-26 20:30:523139 EXPECT_FALSE(response->auth_challenge);
ttuttle34f63b52015-03-05 04:33:013140
3141 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
3142 TestLoadTimingNotReusedWithPac(load_timing_info,
3143 CONNECT_TIMING_HAS_SSL_TIMES);
3144
3145 trans.reset();
3146 session->CloseAllConnections();
3147}
3148
3149// Test the request-challenge-retry sequence for basic auth, over a connection
3150// that requires a restart when setting up an SSL tunnel.
bncd16676a2016-07-20 16:23:013151TEST_F(HttpNetworkTransactionTest, BasicAuthProxyNoKeepAliveHttp11) {
[email protected]394816e92010-08-03 07:38:593152 HttpRequestInfo request;
3153 request.method = "GET";
bncce36dca22015-04-21 22:11:233154 request.url = GURL("https://www.example.org/");
[email protected]394816e92010-08-03 07:38:593155 // when the no authentication data flag is set.
ttuttle859dc7a2015-04-23 19:42:293156 request.load_flags = LOAD_DO_NOT_SEND_AUTH_DATA;
[email protected]394816e92010-08-03 07:38:593157
[email protected]cb9bf6ca2011-01-28 13:15:273158 // Configure against proxy server "myproxy:70".
Lily Houghton8c2f97d2018-01-22 05:06:593159 session_deps_.proxy_resolution_service =
3160 ProxyResolutionService::CreateFixedFromPacResult("PROXY myproxy:70");
vishal.b62985ca92015-04-17 08:45:513161 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:073162 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:093163 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:273164
[email protected]394816e92010-08-03 07:38:593165 // Since we have proxy, should try to establish tunnel.
3166 MockWrite data_writes1[] = {
mmenkee71e15332015-10-07 16:39:543167 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:173168 "Host: www.example.org:443\r\n"
mmenkee71e15332015-10-07 16:39:543169 "Proxy-Connection: keep-alive\r\n\r\n"),
mmenkee0b5c882015-08-26 20:29:113170 };
3171
mmenkee71e15332015-10-07 16:39:543172 // The proxy responds to the connect with a 407, using a non-persistent
mmenke0fd148d2015-09-30 23:00:083173 // connection.
3174 MockRead data_reads1[] = {
mmenkee71e15332015-10-07 16:39:543175 // No credentials.
3176 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
3177 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
3178 MockRead("Proxy-Connection: close\r\n\r\n"),
3179 };
mmenkee0b5c882015-08-26 20:29:113180
mmenkee71e15332015-10-07 16:39:543181 MockWrite data_writes2[] = {
3182 // After calling trans->RestartWithAuth(), this is the request we should
3183 // be issuing -- the final header line contains the credentials.
3184 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:173185 "Host: www.example.org:443\r\n"
mmenkee71e15332015-10-07 16:39:543186 "Proxy-Connection: keep-alive\r\n"
3187 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
mmenke0fd148d2015-09-30 23:00:083188
mmenkee71e15332015-10-07 16:39:543189 MockWrite("GET / HTTP/1.1\r\n"
3190 "Host: www.example.org\r\n"
3191 "Connection: keep-alive\r\n\r\n"),
3192 };
3193
3194 MockRead data_reads2[] = {
3195 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
3196
3197 MockRead("HTTP/1.1 200 OK\r\n"),
3198 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
3199 MockRead("Content-Length: 5\r\n\r\n"),
3200 MockRead(SYNCHRONOUS, "hello"),
[email protected]394816e92010-08-03 07:38:593201 };
3202
3203 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
3204 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:073205 session_deps_.socket_factory->AddSocketDataProvider(&data1);
mmenkee71e15332015-10-07 16:39:543206 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
3207 data_writes2, arraysize(data_writes2));
3208 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]8ddf8322012-02-23 18:08:063209 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:073210 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]394816e92010-08-03 07:38:593211
[email protected]49639fa2011-12-20 23:22:413212 TestCompletionCallback callback1;
[email protected]394816e92010-08-03 07:38:593213
bnc87dcefc2017-05-25 12:47:583214 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:193215 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]0b0bf032010-09-21 18:08:503216
[email protected]49639fa2011-12-20 23:22:413217 int rv = trans->Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:013218 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]394816e92010-08-03 07:38:593219
3220 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:013221 EXPECT_THAT(rv, IsOk());
mmenke43758e62015-05-04 21:09:463222 TestNetLogEntry::List entries;
[email protected]b2fcd0e2010-12-01 15:19:403223 log.GetEntries(&entries);
[email protected]394816e92010-08-03 07:38:593224 size_t pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:003225 entries, 0, NetLogEventType::HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
3226 NetLogEventPhase::NONE);
[email protected]394816e92010-08-03 07:38:593227 ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:403228 entries, pos,
mikecirone8b85c432016-09-08 19:11:003229 NetLogEventType::HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
3230 NetLogEventPhase::NONE);
[email protected]394816e92010-08-03 07:38:593231
3232 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:523233 ASSERT_TRUE(response);
ttuttle34f63b52015-03-05 04:33:013234 EXPECT_FALSE(response->headers->IsKeepAlive());
wezca1070932016-05-26 20:30:523235 ASSERT_TRUE(response->headers);
[email protected]394816e92010-08-03 07:38:593236 EXPECT_EQ(407, response->headers->response_code());
3237 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
[email protected]79cb5c12011-09-12 13:12:043238 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
[email protected]394816e92010-08-03 07:38:593239
[email protected]029c83b62013-01-24 05:28:203240 LoadTimingInfo load_timing_info;
3241 // CONNECT requests and responses are handled at the connect job level, so
3242 // the transaction does not yet have a connection.
3243 EXPECT_FALSE(trans->GetLoadTimingInfo(&load_timing_info));
3244
[email protected]49639fa2011-12-20 23:22:413245 TestCompletionCallback callback2;
[email protected]394816e92010-08-03 07:38:593246
[email protected]49639fa2011-12-20 23:22:413247 rv = trans->RestartWithAuth(
3248 AuthCredentials(kFoo, kBar), callback2.callback());
robpercival214763f2016-07-01 23:27:013249 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]394816e92010-08-03 07:38:593250
3251 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:013252 EXPECT_THAT(rv, IsOk());
[email protected]394816e92010-08-03 07:38:593253
3254 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:523255 ASSERT_TRUE(response);
[email protected]394816e92010-08-03 07:38:593256
3257 EXPECT_TRUE(response->headers->IsKeepAlive());
3258 EXPECT_EQ(200, response->headers->response_code());
[email protected]0b0bf032010-09-21 18:08:503259 EXPECT_EQ(5, response->headers->GetContentLength());
[email protected]394816e92010-08-03 07:38:593260 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
3261
3262 // The password prompt info should not be set.
wezca1070932016-05-26 20:30:523263 EXPECT_FALSE(response->auth_challenge);
[email protected]0b0bf032010-09-21 18:08:503264
[email protected]029c83b62013-01-24 05:28:203265 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
3266 TestLoadTimingNotReusedWithPac(load_timing_info,
3267 CONNECT_TIMING_HAS_SSL_TIMES);
3268
[email protected]0b0bf032010-09-21 18:08:503269 trans.reset();
[email protected]102e27c2011-02-23 01:01:313270 session->CloseAllConnections();
[email protected]394816e92010-08-03 07:38:593271}
3272
[email protected]11203f012009-11-12 23:02:313273// Test the request-challenge-retry sequence for basic auth, over a keep-alive
ttuttle34f63b52015-03-05 04:33:013274// proxy connection with HTTP/1.0 responses, when setting up an SSL tunnel.
bncd16676a2016-07-20 16:23:013275TEST_F(HttpNetworkTransactionTest, BasicAuthProxyKeepAliveHttp10) {
mmenked39192ee2015-12-09 00:57:233276 // On the second pass, the body read of the auth challenge is synchronous, so
3277 // IsConnectedAndIdle returns false. The socket should still be drained and
3278 // reused. See http://crbug.com/544255.
3279 for (int i = 0; i < 2; ++i) {
3280 HttpRequestInfo request;
3281 request.method = "GET";
3282 request.url = GURL("https://www.example.org/");
3283 // Ensure that proxy authentication is attempted even
3284 // when the no authentication data flag is set.
3285 request.load_flags = LOAD_DO_NOT_SEND_AUTH_DATA;
ttuttle34f63b52015-03-05 04:33:013286
mmenked39192ee2015-12-09 00:57:233287 // Configure against proxy server "myproxy:70".
Lily Houghton8c2f97d2018-01-22 05:06:593288 session_deps_.proxy_resolution_service =
3289 ProxyResolutionService::CreateFixed("myproxy:70");
mmenked39192ee2015-12-09 00:57:233290 BoundTestNetLog log;
3291 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:093292 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
ttuttle34f63b52015-03-05 04:33:013293
bnc691fda62016-08-12 00:43:163294 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
ttuttle34f63b52015-03-05 04:33:013295
mmenked39192ee2015-12-09 00:57:233296 // Since we have proxy, should try to establish tunnel.
3297 MockWrite data_writes1[] = {
3298 MockWrite(ASYNC, 0,
3299 "CONNECT www.example.org:443 HTTP/1.1\r\n"
3300 "Host: www.example.org:443\r\n"
3301 "Proxy-Connection: keep-alive\r\n\r\n"),
ttuttle34f63b52015-03-05 04:33:013302
bnc691fda62016-08-12 00:43:163303 // After calling trans.RestartWithAuth(), this is the request we should
mmenked39192ee2015-12-09 00:57:233304 // be issuing -- the final header line contains the credentials.
3305 MockWrite(ASYNC, 3,
3306 "CONNECT www.example.org:443 HTTP/1.1\r\n"
3307 "Host: www.example.org:443\r\n"
3308 "Proxy-Connection: keep-alive\r\n"
3309 "Proxy-Authorization: Basic Zm9vOmJheg==\r\n\r\n"),
3310 };
ttuttle34f63b52015-03-05 04:33:013311
mmenked39192ee2015-12-09 00:57:233312 // The proxy responds to the connect with a 407, using a persistent
3313 // connection. (Since it's HTTP/1.0, keep-alive has to be explicit.)
3314 MockRead data_reads1[] = {
3315 // No credentials.
3316 MockRead(ASYNC, 1,
3317 "HTTP/1.0 407 Proxy Authentication Required\r\n"
3318 "Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"
3319 "Proxy-Connection: keep-alive\r\n"
3320 "Content-Length: 10\r\n\r\n"),
3321 MockRead(i == 0 ? ASYNC : SYNCHRONOUS, 2, "0123456789"),
ttuttle34f63b52015-03-05 04:33:013322
mmenked39192ee2015-12-09 00:57:233323 // Wrong credentials (wrong password).
3324 MockRead(ASYNC, 4,
3325 "HTTP/1.0 407 Proxy Authentication Required\r\n"
3326 "Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"
3327 "Proxy-Connection: keep-alive\r\n"
3328 "Content-Length: 10\r\n\r\n"),
3329 // No response body because the test stops reading here.
3330 MockRead(SYNCHRONOUS, ERR_UNEXPECTED, 5),
3331 };
ttuttle34f63b52015-03-05 04:33:013332
mmenked39192ee2015-12-09 00:57:233333 SequencedSocketData data1(data_reads1, arraysize(data_reads1), data_writes1,
3334 arraysize(data_writes1));
3335 data1.set_busy_before_sync_reads(true);
3336 session_deps_.socket_factory->AddSocketDataProvider(&data1);
ttuttle34f63b52015-03-05 04:33:013337
mmenked39192ee2015-12-09 00:57:233338 TestCompletionCallback callback1;
ttuttle34f63b52015-03-05 04:33:013339
bnc691fda62016-08-12 00:43:163340 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:013341 EXPECT_THAT(callback1.GetResult(rv), IsOk());
ttuttle34f63b52015-03-05 04:33:013342
mmenked39192ee2015-12-09 00:57:233343 TestNetLogEntry::List entries;
3344 log.GetEntries(&entries);
3345 size_t pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:003346 entries, 0, NetLogEventType::HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
3347 NetLogEventPhase::NONE);
mmenked39192ee2015-12-09 00:57:233348 ExpectLogContainsSomewhere(
3349 entries, pos,
mikecirone8b85c432016-09-08 19:11:003350 NetLogEventType::HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
3351 NetLogEventPhase::NONE);
ttuttle34f63b52015-03-05 04:33:013352
bnc691fda62016-08-12 00:43:163353 const HttpResponseInfo* response = trans.GetResponseInfo();
mmenked39192ee2015-12-09 00:57:233354 ASSERT_TRUE(response);
3355 ASSERT_TRUE(response->headers);
3356 EXPECT_TRUE(response->headers->IsKeepAlive());
3357 EXPECT_EQ(407, response->headers->response_code());
3358 EXPECT_EQ(10, response->headers->GetContentLength());
3359 EXPECT_TRUE(HttpVersion(1, 0) == response->headers->GetHttpVersion());
3360 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
ttuttle34f63b52015-03-05 04:33:013361
mmenked39192ee2015-12-09 00:57:233362 TestCompletionCallback callback2;
ttuttle34f63b52015-03-05 04:33:013363
mmenked39192ee2015-12-09 00:57:233364 // Wrong password (should be "bar").
bnc691fda62016-08-12 00:43:163365 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBaz),
3366 callback2.callback());
robpercival214763f2016-07-01 23:27:013367 EXPECT_THAT(callback2.GetResult(rv), IsOk());
ttuttle34f63b52015-03-05 04:33:013368
bnc691fda62016-08-12 00:43:163369 response = trans.GetResponseInfo();
mmenked39192ee2015-12-09 00:57:233370 ASSERT_TRUE(response);
3371 ASSERT_TRUE(response->headers);
3372 EXPECT_TRUE(response->headers->IsKeepAlive());
3373 EXPECT_EQ(407, response->headers->response_code());
3374 EXPECT_EQ(10, response->headers->GetContentLength());
3375 EXPECT_TRUE(HttpVersion(1, 0) == response->headers->GetHttpVersion());
3376 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
ttuttle34f63b52015-03-05 04:33:013377
mmenked39192ee2015-12-09 00:57:233378 // Flush the idle socket before the NetLog and HttpNetworkTransaction go
3379 // out of scope.
3380 session->CloseAllConnections();
3381 }
ttuttle34f63b52015-03-05 04:33:013382}
3383
3384// Test the request-challenge-retry sequence for basic auth, over a keep-alive
3385// proxy connection with HTTP/1.1 responses, when setting up an SSL tunnel.
bncd16676a2016-07-20 16:23:013386TEST_F(HttpNetworkTransactionTest, BasicAuthProxyKeepAliveHttp11) {
mmenked39192ee2015-12-09 00:57:233387 // On the second pass, the body read of the auth challenge is synchronous, so
3388 // IsConnectedAndIdle returns false. The socket should still be drained and
3389 // reused. See http://crbug.com/544255.
3390 for (int i = 0; i < 2; ++i) {
3391 HttpRequestInfo request;
3392 request.method = "GET";
3393 request.url = GURL("https://www.example.org/");
3394 // Ensure that proxy authentication is attempted even
3395 // when the no authentication data flag is set.
3396 request.load_flags = LOAD_DO_NOT_SEND_AUTH_DATA;
3397
3398 // Configure against proxy server "myproxy:70".
Lily Houghton8c2f97d2018-01-22 05:06:593399 session_deps_.proxy_resolution_service =
3400 ProxyResolutionService::CreateFixed("myproxy:70");
mmenked39192ee2015-12-09 00:57:233401 BoundTestNetLog log;
3402 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:093403 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
mmenked39192ee2015-12-09 00:57:233404
bnc691fda62016-08-12 00:43:163405 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
mmenked39192ee2015-12-09 00:57:233406
3407 // Since we have proxy, should try to establish tunnel.
3408 MockWrite data_writes1[] = {
3409 MockWrite(ASYNC, 0,
3410 "CONNECT www.example.org:443 HTTP/1.1\r\n"
3411 "Host: www.example.org:443\r\n"
3412 "Proxy-Connection: keep-alive\r\n\r\n"),
3413
bnc691fda62016-08-12 00:43:163414 // After calling trans.RestartWithAuth(), this is the request we should
mmenked39192ee2015-12-09 00:57:233415 // be issuing -- the final header line contains the credentials.
3416 MockWrite(ASYNC, 3,
3417 "CONNECT www.example.org:443 HTTP/1.1\r\n"
3418 "Host: www.example.org:443\r\n"
3419 "Proxy-Connection: keep-alive\r\n"
3420 "Proxy-Authorization: Basic Zm9vOmJheg==\r\n\r\n"),
3421 };
3422
3423 // The proxy responds to the connect with a 407, using a persistent
3424 // connection. (Since it's HTTP/1.0, keep-alive has to be explicit.)
3425 MockRead data_reads1[] = {
3426 // No credentials.
3427 MockRead(ASYNC, 1,
3428 "HTTP/1.1 407 Proxy Authentication Required\r\n"
3429 "Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"
3430 "Content-Length: 10\r\n\r\n"),
3431 MockRead(i == 0 ? ASYNC : SYNCHRONOUS, 2, "0123456789"),
3432
3433 // Wrong credentials (wrong password).
3434 MockRead(ASYNC, 4,
3435 "HTTP/1.1 407 Proxy Authentication Required\r\n"
3436 "Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"
3437 "Content-Length: 10\r\n\r\n"),
3438 // No response body because the test stops reading here.
3439 MockRead(SYNCHRONOUS, ERR_UNEXPECTED, 5),
3440 };
3441
3442 SequencedSocketData data1(data_reads1, arraysize(data_reads1), data_writes1,
3443 arraysize(data_writes1));
3444 data1.set_busy_before_sync_reads(true);
3445 session_deps_.socket_factory->AddSocketDataProvider(&data1);
3446
3447 TestCompletionCallback callback1;
3448
bnc691fda62016-08-12 00:43:163449 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:013450 EXPECT_THAT(callback1.GetResult(rv), IsOk());
mmenked39192ee2015-12-09 00:57:233451
3452 TestNetLogEntry::List entries;
3453 log.GetEntries(&entries);
3454 size_t pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:003455 entries, 0, NetLogEventType::HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
3456 NetLogEventPhase::NONE);
mmenked39192ee2015-12-09 00:57:233457 ExpectLogContainsSomewhere(
3458 entries, pos,
mikecirone8b85c432016-09-08 19:11:003459 NetLogEventType::HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
3460 NetLogEventPhase::NONE);
mmenked39192ee2015-12-09 00:57:233461
bnc691fda62016-08-12 00:43:163462 const HttpResponseInfo* response = trans.GetResponseInfo();
mmenked39192ee2015-12-09 00:57:233463 ASSERT_TRUE(response);
3464 ASSERT_TRUE(response->headers);
3465 EXPECT_TRUE(response->headers->IsKeepAlive());
3466 EXPECT_EQ(407, response->headers->response_code());
3467 EXPECT_EQ(10, response->headers->GetContentLength());
3468 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
3469 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
3470
3471 TestCompletionCallback callback2;
3472
3473 // Wrong password (should be "bar").
bnc691fda62016-08-12 00:43:163474 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBaz),
3475 callback2.callback());
robpercival214763f2016-07-01 23:27:013476 EXPECT_THAT(callback2.GetResult(rv), IsOk());
mmenked39192ee2015-12-09 00:57:233477
bnc691fda62016-08-12 00:43:163478 response = trans.GetResponseInfo();
mmenked39192ee2015-12-09 00:57:233479 ASSERT_TRUE(response);
3480 ASSERT_TRUE(response->headers);
3481 EXPECT_TRUE(response->headers->IsKeepAlive());
3482 EXPECT_EQ(407, response->headers->response_code());
3483 EXPECT_EQ(10, response->headers->GetContentLength());
3484 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
3485 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
3486
3487 // Flush the idle socket before the NetLog and HttpNetworkTransaction go
3488 // out of scope.
3489 session->CloseAllConnections();
3490 }
3491}
3492
3493// Test the request-challenge-retry sequence for basic auth, over a keep-alive
3494// proxy connection with HTTP/1.1 responses, when setting up an SSL tunnel, in
3495// the case the server sends extra data on the original socket, so it can't be
3496// reused.
bncd16676a2016-07-20 16:23:013497TEST_F(HttpNetworkTransactionTest, BasicAuthProxyKeepAliveExtraData) {
[email protected]cb9bf6ca2011-01-28 13:15:273498 HttpRequestInfo request;
3499 request.method = "GET";
bncce36dca22015-04-21 22:11:233500 request.url = GURL("https://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:273501 // when the no authentication data flag is set.
ttuttle859dc7a2015-04-23 19:42:293502 request.load_flags = LOAD_DO_NOT_SEND_AUTH_DATA;
[email protected]cb9bf6ca2011-01-28 13:15:273503
[email protected]2d2697f92009-02-18 21:00:323504 // Configure against proxy server "myproxy:70".
Lily Houghton8c2f97d2018-01-22 05:06:593505 session_deps_.proxy_resolution_service =
3506 ProxyResolutionService::CreateFixedFromPacResult("PROXY myproxy:70");
vishal.b62985ca92015-04-17 08:45:513507 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:073508 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:093509 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]2d2697f92009-02-18 21:00:323510
[email protected]2d2697f92009-02-18 21:00:323511 // Since we have proxy, should try to establish tunnel.
3512 MockWrite data_writes1[] = {
mmenked39192ee2015-12-09 00:57:233513 MockWrite(ASYNC, 0,
3514 "CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:173515 "Host: www.example.org:443\r\n"
3516 "Proxy-Connection: keep-alive\r\n\r\n"),
mmenked39192ee2015-12-09 00:57:233517 };
[email protected]2d2697f92009-02-18 21:00:323518
mmenked39192ee2015-12-09 00:57:233519 // The proxy responds to the connect with a 407, using a persistent, but sends
3520 // extra data, so the socket cannot be reused.
3521 MockRead data_reads1[] = {
3522 // No credentials.
3523 MockRead(ASYNC, 1,
3524 "HTTP/1.1 407 Proxy Authentication Required\r\n"
3525 "Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"
3526 "Content-Length: 10\r\n\r\n"),
3527 MockRead(SYNCHRONOUS, 2, "0123456789"),
3528 MockRead(SYNCHRONOUS, 3, "I'm broken!"),
3529 };
3530
3531 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:233532 // After calling trans->RestartWithAuth(), this is the request we should
3533 // be issuing -- the final header line contains the credentials.
mmenked39192ee2015-12-09 00:57:233534 MockWrite(ASYNC, 0,
3535 "CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:173536 "Host: www.example.org:443\r\n"
3537 "Proxy-Connection: keep-alive\r\n"
mmenked39192ee2015-12-09 00:57:233538 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
3539
3540 MockWrite(ASYNC, 2,
3541 "GET / HTTP/1.1\r\n"
3542 "Host: www.example.org\r\n"
3543 "Connection: keep-alive\r\n\r\n"),
[email protected]2d2697f92009-02-18 21:00:323544 };
3545
mmenked39192ee2015-12-09 00:57:233546 MockRead data_reads2[] = {
3547 MockRead(ASYNC, 1, "HTTP/1.1 200 Connection Established\r\n\r\n"),
[email protected]2d2697f92009-02-18 21:00:323548
mmenked39192ee2015-12-09 00:57:233549 MockRead(ASYNC, 3,
3550 "HTTP/1.1 200 OK\r\n"
3551 "Content-Type: text/html; charset=iso-8859-1\r\n"
3552 "Content-Length: 5\r\n\r\n"),
3553 // No response body because the test stops reading here.
3554 MockRead(SYNCHRONOUS, ERR_UNEXPECTED, 4),
[email protected]2d2697f92009-02-18 21:00:323555 };
3556
mmenked39192ee2015-12-09 00:57:233557 SequencedSocketData data1(data_reads1, arraysize(data_reads1), data_writes1,
3558 arraysize(data_writes1));
3559 data1.set_busy_before_sync_reads(true);
[email protected]bb88e1d32013-05-03 23:11:073560 session_deps_.socket_factory->AddSocketDataProvider(&data1);
mmenked39192ee2015-12-09 00:57:233561 SequencedSocketData data2(data_reads2, arraysize(data_reads2), data_writes2,
3562 arraysize(data_writes2));
3563 session_deps_.socket_factory->AddSocketDataProvider(&data2);
3564 SSLSocketDataProvider ssl(ASYNC, OK);
3565 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]2d2697f92009-02-18 21:00:323566
[email protected]49639fa2011-12-20 23:22:413567 TestCompletionCallback callback1;
[email protected]2d2697f92009-02-18 21:00:323568
bnc87dcefc2017-05-25 12:47:583569 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:193570 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]2d2697f92009-02-18 21:00:323571
mmenked39192ee2015-12-09 00:57:233572 int rv = trans->Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:013573 EXPECT_THAT(callback1.GetResult(rv), IsOk());
mmenked39192ee2015-12-09 00:57:233574
mmenke43758e62015-05-04 21:09:463575 TestNetLogEntry::List entries;
[email protected]b2fcd0e2010-12-01 15:19:403576 log.GetEntries(&entries);
[email protected]dbb83db2010-05-11 18:13:393577 size_t pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:003578 entries, 0, NetLogEventType::HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
3579 NetLogEventPhase::NONE);
[email protected]dbb83db2010-05-11 18:13:393580 ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:403581 entries, pos,
mikecirone8b85c432016-09-08 19:11:003582 NetLogEventType::HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
3583 NetLogEventPhase::NONE);
[email protected]2d2697f92009-02-18 21:00:323584
[email protected]1c773ea12009-04-28 19:58:423585 const HttpResponseInfo* response = trans->GetResponseInfo();
ttuttle7933c112015-01-06 00:55:243586 ASSERT_TRUE(response);
3587 ASSERT_TRUE(response->headers);
[email protected]2d2697f92009-02-18 21:00:323588 EXPECT_TRUE(response->headers->IsKeepAlive());
3589 EXPECT_EQ(407, response->headers->response_code());
[email protected]1c773ea12009-04-28 19:58:423590 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
[email protected]79cb5c12011-09-12 13:12:043591 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
[email protected]2d2697f92009-02-18 21:00:323592
mmenked39192ee2015-12-09 00:57:233593 LoadTimingInfo load_timing_info;
3594 // CONNECT requests and responses are handled at the connect job level, so
3595 // the transaction does not yet have a connection.
3596 EXPECT_FALSE(trans->GetLoadTimingInfo(&load_timing_info));
3597
[email protected]49639fa2011-12-20 23:22:413598 TestCompletionCallback callback2;
[email protected]2d2697f92009-02-18 21:00:323599
mmenked39192ee2015-12-09 00:57:233600 rv =
3601 trans->RestartWithAuth(AuthCredentials(kFoo, kBar), callback2.callback());
robpercival214763f2016-07-01 23:27:013602 EXPECT_THAT(callback2.GetResult(rv), IsOk());
[email protected]2d2697f92009-02-18 21:00:323603
[email protected]2d2697f92009-02-18 21:00:323604 EXPECT_TRUE(response->headers->IsKeepAlive());
mmenked39192ee2015-12-09 00:57:233605 EXPECT_EQ(200, response->headers->response_code());
3606 EXPECT_EQ(5, response->headers->GetContentLength());
[email protected]1c773ea12009-04-28 19:58:423607 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
[email protected]e772db3f2010-07-12 18:11:133608
mmenked39192ee2015-12-09 00:57:233609 // The password prompt info should not be set.
3610 EXPECT_FALSE(response->auth_challenge);
3611
3612 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
3613 TestLoadTimingNotReusedWithPac(load_timing_info,
3614 CONNECT_TIMING_HAS_SSL_TIMES);
3615
3616 trans.reset();
[email protected]102e27c2011-02-23 01:01:313617 session->CloseAllConnections();
[email protected]2d2697f92009-02-18 21:00:323618}
3619
mmenkee71e15332015-10-07 16:39:543620// Test the case a proxy closes a socket while the challenge body is being
3621// drained.
bncd16676a2016-07-20 16:23:013622TEST_F(HttpNetworkTransactionTest, BasicAuthProxyKeepAliveHangupDuringBody) {
mmenkee71e15332015-10-07 16:39:543623 HttpRequestInfo request;
3624 request.method = "GET";
3625 request.url = GURL("https://www.example.org/");
3626 // Ensure that proxy authentication is attempted even
3627 // when the no authentication data flag is set.
3628 request.load_flags = LOAD_DO_NOT_SEND_AUTH_DATA;
3629
3630 // Configure against proxy server "myproxy:70".
Lily Houghton8c2f97d2018-01-22 05:06:593631 session_deps_.proxy_resolution_service =
3632 ProxyResolutionService::CreateFixed("myproxy:70");
danakj1fd259a02016-04-16 03:17:093633 std::unique_ptr<HttpNetworkSession> session = CreateSession(&session_deps_);
mmenkee71e15332015-10-07 16:39:543634
bnc691fda62016-08-12 00:43:163635 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
mmenkee71e15332015-10-07 16:39:543636
3637 // Since we have proxy, should try to establish tunnel.
3638 MockWrite data_writes1[] = {
3639 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:173640 "Host: www.example.org:443\r\n"
mmenkee71e15332015-10-07 16:39:543641 "Proxy-Connection: keep-alive\r\n\r\n"),
3642 };
3643
3644 // The proxy responds to the connect with a 407, using a persistent
3645 // connection.
3646 MockRead data_reads1[] = {
3647 // No credentials.
3648 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
3649 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
3650 MockRead("Content-Length: 10\r\n\r\n"), MockRead("spam!"),
3651 // Server hands up in the middle of the body.
3652 MockRead(ASYNC, ERR_CONNECTION_CLOSED),
3653 };
3654
3655 MockWrite data_writes2[] = {
bnc691fda62016-08-12 00:43:163656 // After calling trans.RestartWithAuth(), this is the request we should
mmenkee71e15332015-10-07 16:39:543657 // be issuing -- the final header line contains the credentials.
3658 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:173659 "Host: www.example.org:443\r\n"
mmenkee71e15332015-10-07 16:39:543660 "Proxy-Connection: keep-alive\r\n"
3661 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
3662
3663 MockWrite("GET / HTTP/1.1\r\n"
3664 "Host: www.example.org\r\n"
3665 "Connection: keep-alive\r\n\r\n"),
3666 };
3667
3668 MockRead data_reads2[] = {
3669 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
3670
3671 MockRead("HTTP/1.1 200 OK\r\n"),
3672 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
3673 MockRead("Content-Length: 5\r\n\r\n"),
3674 MockRead(SYNCHRONOUS, "hello"),
3675 };
3676
3677 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
3678 data_writes1, arraysize(data_writes1));
3679 session_deps_.socket_factory->AddSocketDataProvider(&data1);
3680 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
3681 data_writes2, arraysize(data_writes2));
3682 session_deps_.socket_factory->AddSocketDataProvider(&data2);
3683 SSLSocketDataProvider ssl(ASYNC, OK);
3684 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
3685
3686 TestCompletionCallback callback;
3687
tfarina42834112016-09-22 13:38:203688 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:013689 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenkee71e15332015-10-07 16:39:543690
bnc691fda62016-08-12 00:43:163691 const HttpResponseInfo* response = trans.GetResponseInfo();
mmenkee71e15332015-10-07 16:39:543692 ASSERT_TRUE(response);
3693 ASSERT_TRUE(response->headers);
3694 EXPECT_TRUE(response->headers->IsKeepAlive());
3695 EXPECT_EQ(407, response->headers->response_code());
3696 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
3697
bnc691fda62016-08-12 00:43:163698 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar), callback.callback());
robpercival214763f2016-07-01 23:27:013699 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenkee71e15332015-10-07 16:39:543700
bnc691fda62016-08-12 00:43:163701 response = trans.GetResponseInfo();
mmenkee71e15332015-10-07 16:39:543702 ASSERT_TRUE(response);
3703 ASSERT_TRUE(response->headers);
3704 EXPECT_TRUE(response->headers->IsKeepAlive());
3705 EXPECT_EQ(200, response->headers->response_code());
3706 std::string body;
bnc691fda62016-08-12 00:43:163707 EXPECT_THAT(ReadTransaction(&trans, &body), IsOk());
mmenkee71e15332015-10-07 16:39:543708 EXPECT_EQ("hello", body);
3709}
3710
[email protected]a8e9b162009-03-12 00:06:443711// Test that we don't read the response body when we fail to establish a tunnel,
3712// even if the user cancels the proxy's auth attempt.
bncd16676a2016-07-20 16:23:013713TEST_F(HttpNetworkTransactionTest, BasicAuthProxyCancelTunnel) {
[email protected]cb9bf6ca2011-01-28 13:15:273714 HttpRequestInfo request;
3715 request.method = "GET";
bncce36dca22015-04-21 22:11:233716 request.url = GURL("https://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:273717
[email protected]a8e9b162009-03-12 00:06:443718 // Configure against proxy server "myproxy:70".
Lily Houghton8c2f97d2018-01-22 05:06:593719 session_deps_.proxy_resolution_service =
3720 ProxyResolutionService::CreateFixed("myproxy:70");
[email protected]a8e9b162009-03-12 00:06:443721
danakj1fd259a02016-04-16 03:17:093722 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]a8e9b162009-03-12 00:06:443723
bnc691fda62016-08-12 00:43:163724 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]a8e9b162009-03-12 00:06:443725
[email protected]a8e9b162009-03-12 00:06:443726 // Since we have proxy, should try to establish tunnel.
3727 MockWrite data_writes[] = {
rsleevidb16bb02015-11-12 23:47:173728 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
3729 "Host: www.example.org:443\r\n"
3730 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]a8e9b162009-03-12 00:06:443731 };
3732
3733 // The proxy responds to the connect with a 407.
3734 MockRead data_reads[] = {
ttuttle7933c112015-01-06 00:55:243735 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
3736 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
3737 MockRead("Content-Length: 10\r\n\r\n"),
mmenked39192ee2015-12-09 00:57:233738 MockRead("0123456789"),
ttuttle7933c112015-01-06 00:55:243739 MockRead(SYNCHRONOUS, ERR_UNEXPECTED),
[email protected]a8e9b162009-03-12 00:06:443740 };
3741
[email protected]31a2bfe2010-02-09 08:03:393742 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
3743 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:073744 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]a8e9b162009-03-12 00:06:443745
[email protected]49639fa2011-12-20 23:22:413746 TestCompletionCallback callback;
[email protected]a8e9b162009-03-12 00:06:443747
tfarina42834112016-09-22 13:38:203748 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:013749 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]a8e9b162009-03-12 00:06:443750
3751 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:013752 EXPECT_THAT(rv, IsOk());
[email protected]a8e9b162009-03-12 00:06:443753
bnc691fda62016-08-12 00:43:163754 const HttpResponseInfo* response = trans.GetResponseInfo();
ttuttle7933c112015-01-06 00:55:243755 ASSERT_TRUE(response);
3756 ASSERT_TRUE(response->headers);
[email protected]a8e9b162009-03-12 00:06:443757 EXPECT_TRUE(response->headers->IsKeepAlive());
3758 EXPECT_EQ(407, response->headers->response_code());
[email protected]1c773ea12009-04-28 19:58:423759 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
[email protected]a8e9b162009-03-12 00:06:443760
3761 std::string response_data;
bnc691fda62016-08-12 00:43:163762 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:013763 EXPECT_THAT(rv, IsError(ERR_TUNNEL_CONNECTION_FAILED));
[email protected]e60e47a2010-07-14 03:37:183764
3765 // Flush the idle socket before the HttpNetworkTransaction goes out of scope.
[email protected]102e27c2011-02-23 01:01:313766 session->CloseAllConnections();
[email protected]a8e9b162009-03-12 00:06:443767}
3768
ttuttle7933c112015-01-06 00:55:243769// Test that we don't pass extraneous headers from the proxy's response to the
3770// caller when the proxy responds to CONNECT with 407.
bncd16676a2016-07-20 16:23:013771TEST_F(HttpNetworkTransactionTest, SanitizeProxyAuthHeaders) {
ttuttle7933c112015-01-06 00:55:243772 HttpRequestInfo request;
3773 request.method = "GET";
bncce36dca22015-04-21 22:11:233774 request.url = GURL("https://www.example.org/");
ttuttle7933c112015-01-06 00:55:243775
3776 // Configure against proxy server "myproxy:70".
Lily Houghton8c2f97d2018-01-22 05:06:593777 session_deps_.proxy_resolution_service =
3778 ProxyResolutionService::CreateFixed("myproxy:70");
ttuttle7933c112015-01-06 00:55:243779
danakj1fd259a02016-04-16 03:17:093780 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
ttuttle7933c112015-01-06 00:55:243781
bnc691fda62016-08-12 00:43:163782 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
ttuttle7933c112015-01-06 00:55:243783
3784 // Since we have proxy, should try to establish tunnel.
3785 MockWrite data_writes[] = {
rsleevidb16bb02015-11-12 23:47:173786 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
3787 "Host: www.example.org:443\r\n"
3788 "Proxy-Connection: keep-alive\r\n\r\n"),
ttuttle7933c112015-01-06 00:55:243789 };
3790
3791 // The proxy responds to the connect with a 407.
3792 MockRead data_reads[] = {
3793 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
3794 MockRead("X-Foo: bar\r\n"),
3795 MockRead("Set-Cookie: foo=bar\r\n"),
3796 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
3797 MockRead("Content-Length: 10\r\n\r\n"),
mmenked39192ee2015-12-09 00:57:233798 MockRead(SYNCHRONOUS, ERR_UNEXPECTED),
ttuttle7933c112015-01-06 00:55:243799 };
3800
3801 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
3802 arraysize(data_writes));
3803 session_deps_.socket_factory->AddSocketDataProvider(&data);
3804
3805 TestCompletionCallback callback;
3806
tfarina42834112016-09-22 13:38:203807 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:013808 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
ttuttle7933c112015-01-06 00:55:243809
3810 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:013811 EXPECT_THAT(rv, IsOk());
ttuttle7933c112015-01-06 00:55:243812
bnc691fda62016-08-12 00:43:163813 const HttpResponseInfo* response = trans.GetResponseInfo();
ttuttle7933c112015-01-06 00:55:243814 ASSERT_TRUE(response);
3815 ASSERT_TRUE(response->headers);
3816 EXPECT_TRUE(response->headers->IsKeepAlive());
3817 EXPECT_EQ(407, response->headers->response_code());
3818 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
3819 EXPECT_FALSE(response->headers->HasHeader("X-Foo"));
3820 EXPECT_FALSE(response->headers->HasHeader("Set-Cookie"));
3821
3822 std::string response_data;
bnc691fda62016-08-12 00:43:163823 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:013824 EXPECT_THAT(rv, IsError(ERR_TUNNEL_CONNECTION_FAILED));
ttuttle7933c112015-01-06 00:55:243825
3826 // Flush the idle socket before the HttpNetworkTransaction goes out of scope.
3827 session->CloseAllConnections();
3828}
3829
[email protected]8fdbcd22010-05-05 02:54:523830// Test when a server (non-proxy) returns a 407 (proxy-authenticate).
3831// The request should fail with ERR_UNEXPECTED_PROXY_AUTH.
bncd16676a2016-07-20 16:23:013832TEST_F(HttpNetworkTransactionTest, UnexpectedProxyAuth) {
[email protected]8fdbcd22010-05-05 02:54:523833 HttpRequestInfo request;
3834 request.method = "GET";
bncce36dca22015-04-21 22:11:233835 request.url = GURL("http://www.example.org/");
[email protected]8fdbcd22010-05-05 02:54:523836
[email protected]cb9bf6ca2011-01-28 13:15:273837 // We are using a DIRECT connection (i.e. no proxy) for this session.
danakj1fd259a02016-04-16 03:17:093838 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:163839 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:273840
[email protected]8fdbcd22010-05-05 02:54:523841 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:233842 MockWrite(
3843 "GET / HTTP/1.1\r\n"
3844 "Host: www.example.org\r\n"
3845 "Connection: keep-alive\r\n\r\n"),
[email protected]8fdbcd22010-05-05 02:54:523846 };
3847
3848 MockRead data_reads1[] = {
3849 MockRead("HTTP/1.0 407 Proxy Auth required\r\n"),
3850 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
3851 // Large content-length -- won't matter, as connection will be reset.
3852 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:063853 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]8fdbcd22010-05-05 02:54:523854 };
3855
3856 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
3857 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:073858 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8fdbcd22010-05-05 02:54:523859
[email protected]49639fa2011-12-20 23:22:413860 TestCompletionCallback callback;
[email protected]8fdbcd22010-05-05 02:54:523861
tfarina42834112016-09-22 13:38:203862 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:013863 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]8fdbcd22010-05-05 02:54:523864
3865 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:013866 EXPECT_THAT(rv, IsError(ERR_UNEXPECTED_PROXY_AUTH));
[email protected]8fdbcd22010-05-05 02:54:523867}
3868
[email protected]7a67a8152010-11-05 18:31:103869// Tests when an HTTPS server (non-proxy) returns a 407 (proxy-authentication)
3870// through a non-authenticating proxy. The request should fail with
3871// ERR_UNEXPECTED_PROXY_AUTH.
3872// Note that it is impossible to detect if an HTTP server returns a 407 through
3873// a non-authenticating proxy - there is nothing to indicate whether the
3874// response came from the proxy or the server, so it is treated as if the proxy
3875// issued the challenge.
bncd16676a2016-07-20 16:23:013876TEST_F(HttpNetworkTransactionTest, HttpsServerRequestsProxyAuthThroughProxy) {
[email protected]cb9bf6ca2011-01-28 13:15:273877 HttpRequestInfo request;
3878 request.method = "GET";
bncce36dca22015-04-21 22:11:233879 request.url = GURL("https://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:273880
Lily Houghton8c2f97d2018-01-22 05:06:593881 session_deps_.proxy_resolution_service =
3882 ProxyResolutionService::CreateFixed("myproxy:70");
vishal.b62985ca92015-04-17 08:45:513883 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:073884 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:093885 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]7a67a8152010-11-05 18:31:103886
[email protected]7a67a8152010-11-05 18:31:103887 // Since we have proxy, should try to establish tunnel.
3888 MockWrite data_writes1[] = {
rsleevidb16bb02015-11-12 23:47:173889 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
3890 "Host: www.example.org:443\r\n"
3891 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]7a67a8152010-11-05 18:31:103892
rsleevidb16bb02015-11-12 23:47:173893 MockWrite("GET / HTTP/1.1\r\n"
3894 "Host: www.example.org\r\n"
3895 "Connection: keep-alive\r\n\r\n"),
[email protected]7a67a8152010-11-05 18:31:103896 };
3897
3898 MockRead data_reads1[] = {
3899 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
3900
3901 MockRead("HTTP/1.1 407 Unauthorized\r\n"),
3902 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
3903 MockRead("\r\n"),
[email protected]8ddf8322012-02-23 18:08:063904 MockRead(SYNCHRONOUS, OK),
[email protected]7a67a8152010-11-05 18:31:103905 };
3906
3907 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
3908 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:073909 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8ddf8322012-02-23 18:08:063910 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:073911 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]7a67a8152010-11-05 18:31:103912
[email protected]49639fa2011-12-20 23:22:413913 TestCompletionCallback callback1;
[email protected]7a67a8152010-11-05 18:31:103914
bnc691fda62016-08-12 00:43:163915 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]7a67a8152010-11-05 18:31:103916
bnc691fda62016-08-12 00:43:163917 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:013918 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]7a67a8152010-11-05 18:31:103919
3920 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:013921 EXPECT_THAT(rv, IsError(ERR_UNEXPECTED_PROXY_AUTH));
mmenke43758e62015-05-04 21:09:463922 TestNetLogEntry::List entries;
[email protected]b2fcd0e2010-12-01 15:19:403923 log.GetEntries(&entries);
[email protected]7a67a8152010-11-05 18:31:103924 size_t pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:003925 entries, 0, NetLogEventType::HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
3926 NetLogEventPhase::NONE);
[email protected]7a67a8152010-11-05 18:31:103927 ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:403928 entries, pos,
mikecirone8b85c432016-09-08 19:11:003929 NetLogEventType::HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
3930 NetLogEventPhase::NONE);
[email protected]7a67a8152010-11-05 18:31:103931}
[email protected]2df19bb2010-08-25 20:13:463932
mmenke2a1781d2015-10-07 19:25:333933// Test a proxy auth scheme that allows default credentials and a proxy server
3934// that uses non-persistent connections.
bncd16676a2016-07-20 16:23:013935TEST_F(HttpNetworkTransactionTest,
mmenke2a1781d2015-10-07 19:25:333936 AuthAllowsDefaultCredentialsTunnelConnectionClose) {
3937 HttpRequestInfo request;
3938 request.method = "GET";
3939 request.url = GURL("https://www.example.org/");
3940
3941 // Configure against proxy server "myproxy:70".
Lily Houghton8c2f97d2018-01-22 05:06:593942 session_deps_.proxy_resolution_service =
3943 ProxyResolutionService::CreateFixedFromPacResult("PROXY myproxy:70");
mmenke2a1781d2015-10-07 19:25:333944
Jeremy Roman0579ed62017-08-29 15:56:193945 auto auth_handler_factory = std::make_unique<HttpAuthHandlerMock::Factory>();
mmenke2a1781d2015-10-07 19:25:333946 auth_handler_factory->set_do_init_from_challenge(true);
Jeremy Roman0579ed62017-08-29 15:56:193947 auto mock_handler = std::make_unique<HttpAuthHandlerMock>();
mmenke2a1781d2015-10-07 19:25:333948 mock_handler->set_allows_default_credentials(true);
3949 auth_handler_factory->AddMockHandler(mock_handler.release(),
3950 HttpAuth::AUTH_PROXY);
dchengc7eeda422015-12-26 03:56:483951 session_deps_.http_auth_handler_factory = std::move(auth_handler_factory);
mmenke2a1781d2015-10-07 19:25:333952
3953 // Add NetLog just so can verify load timing information gets a NetLog ID.
3954 NetLog net_log;
3955 session_deps_.net_log = &net_log;
danakj1fd259a02016-04-16 03:17:093956 std::unique_ptr<HttpNetworkSession> session = CreateSession(&session_deps_);
mmenke2a1781d2015-10-07 19:25:333957
3958 // Since we have proxy, should try to establish tunnel.
3959 MockWrite data_writes1[] = {
3960 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:173961 "Host: www.example.org:443\r\n"
mmenke2a1781d2015-10-07 19:25:333962 "Proxy-Connection: keep-alive\r\n\r\n"),
3963 };
3964
3965 // The proxy responds to the connect with a 407, using a non-persistent
3966 // connection.
3967 MockRead data_reads1[] = {
3968 // No credentials.
3969 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
3970 MockRead("Proxy-Authenticate: Mock\r\n"),
3971 MockRead("Proxy-Connection: close\r\n\r\n"),
3972 };
3973
3974 // Since the first connection couldn't be reused, need to establish another
3975 // once given credentials.
3976 MockWrite data_writes2[] = {
3977 // After calling trans->RestartWithAuth(), this is the request we should
3978 // be issuing -- the final header line contains the credentials.
3979 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:173980 "Host: www.example.org:443\r\n"
mmenke2a1781d2015-10-07 19:25:333981 "Proxy-Connection: keep-alive\r\n"
3982 "Proxy-Authorization: auth_token\r\n\r\n"),
3983
3984 MockWrite("GET / HTTP/1.1\r\n"
3985 "Host: www.example.org\r\n"
3986 "Connection: keep-alive\r\n\r\n"),
3987 };
3988
3989 MockRead data_reads2[] = {
3990 MockRead("HTTP/1.0 200 Connection Established\r\n\r\n"),
3991
3992 MockRead("HTTP/1.1 200 OK\r\n"),
3993 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
3994 MockRead("Content-Length: 5\r\n\r\n"),
3995 MockRead(SYNCHRONOUS, "hello"),
3996 };
3997
3998 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
3999 data_writes1, arraysize(data_writes1));
4000 session_deps_.socket_factory->AddSocketDataProvider(&data1);
4001 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
4002 data_writes2, arraysize(data_writes2));
4003 session_deps_.socket_factory->AddSocketDataProvider(&data2);
4004 SSLSocketDataProvider ssl(ASYNC, OK);
4005 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
4006
bnc87dcefc2017-05-25 12:47:584007 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:194008 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
mmenke2a1781d2015-10-07 19:25:334009
4010 TestCompletionCallback callback;
tfarina42834112016-09-22 13:38:204011 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:014012 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenke2a1781d2015-10-07 19:25:334013
4014 const HttpResponseInfo* response = trans->GetResponseInfo();
4015 ASSERT_TRUE(response);
4016 ASSERT_TRUE(response->headers);
4017 EXPECT_FALSE(response->headers->IsKeepAlive());
4018 EXPECT_EQ(407, response->headers->response_code());
4019 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
4020 EXPECT_TRUE(trans->IsReadyToRestartForAuth());
wezca1070932016-05-26 20:30:524021 EXPECT_FALSE(response->auth_challenge);
mmenke2a1781d2015-10-07 19:25:334022
4023 LoadTimingInfo load_timing_info;
4024 // CONNECT requests and responses are handled at the connect job level, so
4025 // the transaction does not yet have a connection.
4026 EXPECT_FALSE(trans->GetLoadTimingInfo(&load_timing_info));
4027
4028 rv = trans->RestartWithAuth(AuthCredentials(), callback.callback());
robpercival214763f2016-07-01 23:27:014029 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenke2a1781d2015-10-07 19:25:334030 response = trans->GetResponseInfo();
4031 ASSERT_TRUE(response);
4032 ASSERT_TRUE(response->headers);
4033 EXPECT_TRUE(response->headers->IsKeepAlive());
4034 EXPECT_EQ(200, response->headers->response_code());
4035 EXPECT_EQ(5, response->headers->GetContentLength());
4036 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
4037
4038 // The password prompt info should not be set.
4039 EXPECT_FALSE(response->auth_challenge);
4040
4041 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
4042 TestLoadTimingNotReusedWithPac(load_timing_info,
4043 CONNECT_TIMING_HAS_SSL_TIMES);
4044
4045 trans.reset();
4046 session->CloseAllConnections();
4047}
4048
4049// Test a proxy auth scheme that allows default credentials and a proxy server
4050// that hangs up when credentials are initially sent.
bncd16676a2016-07-20 16:23:014051TEST_F(HttpNetworkTransactionTest,
mmenke2a1781d2015-10-07 19:25:334052 AuthAllowsDefaultCredentialsTunnelServerClosesConnection) {
4053 HttpRequestInfo request;
4054 request.method = "GET";
4055 request.url = GURL("https://www.example.org/");
4056
4057 // Configure against proxy server "myproxy:70".
Lily Houghton8c2f97d2018-01-22 05:06:594058 session_deps_.proxy_resolution_service =
4059 ProxyResolutionService::CreateFixedFromPacResult("PROXY myproxy:70");
mmenke2a1781d2015-10-07 19:25:334060
Jeremy Roman0579ed62017-08-29 15:56:194061 auto auth_handler_factory = std::make_unique<HttpAuthHandlerMock::Factory>();
mmenke2a1781d2015-10-07 19:25:334062 auth_handler_factory->set_do_init_from_challenge(true);
Jeremy Roman0579ed62017-08-29 15:56:194063 auto mock_handler = std::make_unique<HttpAuthHandlerMock>();
mmenke2a1781d2015-10-07 19:25:334064 mock_handler->set_allows_default_credentials(true);
4065 auth_handler_factory->AddMockHandler(mock_handler.release(),
4066 HttpAuth::AUTH_PROXY);
dchengc7eeda422015-12-26 03:56:484067 session_deps_.http_auth_handler_factory = std::move(auth_handler_factory);
mmenke2a1781d2015-10-07 19:25:334068
4069 // Add NetLog just so can verify load timing information gets a NetLog ID.
4070 NetLog net_log;
4071 session_deps_.net_log = &net_log;
danakj1fd259a02016-04-16 03:17:094072 std::unique_ptr<HttpNetworkSession> session = CreateSession(&session_deps_);
mmenke2a1781d2015-10-07 19:25:334073
4074 // Should try to establish tunnel.
4075 MockWrite data_writes1[] = {
4076 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:174077 "Host: www.example.org:443\r\n"
mmenke2a1781d2015-10-07 19:25:334078 "Proxy-Connection: keep-alive\r\n\r\n"),
4079
4080 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:174081 "Host: www.example.org:443\r\n"
mmenke2a1781d2015-10-07 19:25:334082 "Proxy-Connection: keep-alive\r\n"
4083 "Proxy-Authorization: auth_token\r\n\r\n"),
4084 };
4085
4086 // The proxy responds to the connect with a 407, using a non-persistent
4087 // connection.
4088 MockRead data_reads1[] = {
4089 // No credentials.
4090 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
4091 MockRead("Proxy-Authenticate: Mock\r\n\r\n"),
4092 MockRead(SYNCHRONOUS, ERR_CONNECTION_CLOSED),
4093 };
4094
4095 // Since the first connection was closed, need to establish another once given
4096 // credentials.
4097 MockWrite data_writes2[] = {
4098 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:174099 "Host: www.example.org:443\r\n"
mmenke2a1781d2015-10-07 19:25:334100 "Proxy-Connection: keep-alive\r\n"
4101 "Proxy-Authorization: auth_token\r\n\r\n"),
4102
4103 MockWrite("GET / HTTP/1.1\r\n"
4104 "Host: www.example.org\r\n"
4105 "Connection: keep-alive\r\n\r\n"),
4106 };
4107
4108 MockRead data_reads2[] = {
4109 MockRead("HTTP/1.0 200 Connection Established\r\n\r\n"),
4110
4111 MockRead("HTTP/1.1 200 OK\r\n"),
4112 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
4113 MockRead("Content-Length: 5\r\n\r\n"),
4114 MockRead(SYNCHRONOUS, "hello"),
4115 };
4116
4117 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
4118 data_writes1, arraysize(data_writes1));
4119 session_deps_.socket_factory->AddSocketDataProvider(&data1);
4120 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
4121 data_writes2, arraysize(data_writes2));
4122 session_deps_.socket_factory->AddSocketDataProvider(&data2);
4123 SSLSocketDataProvider ssl(ASYNC, OK);
4124 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
4125
bnc87dcefc2017-05-25 12:47:584126 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:194127 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
mmenke2a1781d2015-10-07 19:25:334128
4129 TestCompletionCallback callback;
tfarina42834112016-09-22 13:38:204130 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:014131 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenke2a1781d2015-10-07 19:25:334132
4133 const HttpResponseInfo* response = trans->GetResponseInfo();
4134 ASSERT_TRUE(response);
4135 ASSERT_TRUE(response->headers);
4136 EXPECT_TRUE(response->headers->IsKeepAlive());
4137 EXPECT_EQ(407, response->headers->response_code());
4138 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
4139 EXPECT_TRUE(trans->IsReadyToRestartForAuth());
4140 EXPECT_FALSE(response->auth_challenge);
4141
4142 LoadTimingInfo load_timing_info;
4143 // CONNECT requests and responses are handled at the connect job level, so
4144 // the transaction does not yet have a connection.
4145 EXPECT_FALSE(trans->GetLoadTimingInfo(&load_timing_info));
4146
4147 rv = trans->RestartWithAuth(AuthCredentials(), callback.callback());
robpercival214763f2016-07-01 23:27:014148 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenke2a1781d2015-10-07 19:25:334149
4150 response = trans->GetResponseInfo();
4151 ASSERT_TRUE(response);
4152 ASSERT_TRUE(response->headers);
4153 EXPECT_TRUE(response->headers->IsKeepAlive());
4154 EXPECT_EQ(200, response->headers->response_code());
4155 EXPECT_EQ(5, response->headers->GetContentLength());
4156 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
4157
4158 // The password prompt info should not be set.
wezca1070932016-05-26 20:30:524159 EXPECT_FALSE(response->auth_challenge);
mmenke2a1781d2015-10-07 19:25:334160
4161 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
4162 TestLoadTimingNotReusedWithPac(load_timing_info,
4163 CONNECT_TIMING_HAS_SSL_TIMES);
4164
4165 trans.reset();
4166 session->CloseAllConnections();
4167}
4168
4169// Test a proxy auth scheme that allows default credentials and a proxy server
4170// that hangs up when credentials are initially sent, and hangs up again when
4171// they are retried.
bncd16676a2016-07-20 16:23:014172TEST_F(HttpNetworkTransactionTest,
mmenke2a1781d2015-10-07 19:25:334173 AuthAllowsDefaultCredentialsTunnelServerClosesConnectionTwice) {
4174 HttpRequestInfo request;
4175 request.method = "GET";
4176 request.url = GURL("https://www.example.org/");
4177
4178 // Configure against proxy server "myproxy:70".
Lily Houghton8c2f97d2018-01-22 05:06:594179 session_deps_.proxy_resolution_service =
4180 ProxyResolutionService::CreateFixedFromPacResult("PROXY myproxy:70");
mmenke2a1781d2015-10-07 19:25:334181
Jeremy Roman0579ed62017-08-29 15:56:194182 auto auth_handler_factory = std::make_unique<HttpAuthHandlerMock::Factory>();
mmenke2a1781d2015-10-07 19:25:334183 auth_handler_factory->set_do_init_from_challenge(true);
Jeremy Roman0579ed62017-08-29 15:56:194184 auto mock_handler = std::make_unique<HttpAuthHandlerMock>();
mmenke2a1781d2015-10-07 19:25:334185 mock_handler->set_allows_default_credentials(true);
4186 auth_handler_factory->AddMockHandler(mock_handler.release(),
4187 HttpAuth::AUTH_PROXY);
dchengc7eeda422015-12-26 03:56:484188 session_deps_.http_auth_handler_factory = std::move(auth_handler_factory);
mmenke2a1781d2015-10-07 19:25:334189
4190 // Add NetLog just so can verify load timing information gets a NetLog ID.
4191 NetLog net_log;
4192 session_deps_.net_log = &net_log;
danakj1fd259a02016-04-16 03:17:094193 std::unique_ptr<HttpNetworkSession> session = CreateSession(&session_deps_);
mmenke2a1781d2015-10-07 19:25:334194
4195 // Should try to establish tunnel.
4196 MockWrite data_writes1[] = {
4197 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:174198 "Host: www.example.org:443\r\n"
mmenke2a1781d2015-10-07 19:25:334199 "Proxy-Connection: keep-alive\r\n\r\n"),
4200
4201 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:174202 "Host: www.example.org:443\r\n"
mmenke2a1781d2015-10-07 19:25:334203 "Proxy-Connection: keep-alive\r\n"
4204 "Proxy-Authorization: auth_token\r\n\r\n"),
4205 };
4206
4207 // The proxy responds to the connect with a 407, and then hangs up after the
4208 // second request is sent.
4209 MockRead data_reads1[] = {
4210 // No credentials.
4211 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
4212 MockRead("Content-Length: 0\r\n"),
4213 MockRead("Proxy-Connection: keep-alive\r\n"),
4214 MockRead("Proxy-Authenticate: Mock\r\n\r\n"),
4215 MockRead(SYNCHRONOUS, ERR_CONNECTION_CLOSED),
4216 };
4217
4218 // HttpNetworkTransaction sees a reused connection that was closed with
4219 // ERR_CONNECTION_CLOSED, realized it might have been a race, so retries the
4220 // request.
4221 MockWrite data_writes2[] = {
4222 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:174223 "Host: www.example.org:443\r\n"
mmenke2a1781d2015-10-07 19:25:334224 "Proxy-Connection: keep-alive\r\n\r\n"),
4225 };
4226
4227 // The proxy, having had more than enough of us, just hangs up.
4228 MockRead data_reads2[] = {
4229 // No credentials.
4230 MockRead(SYNCHRONOUS, ERR_CONNECTION_CLOSED),
4231 };
4232
4233 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
4234 data_writes1, arraysize(data_writes1));
4235 session_deps_.socket_factory->AddSocketDataProvider(&data1);
4236 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
4237 data_writes2, arraysize(data_writes2));
4238 session_deps_.socket_factory->AddSocketDataProvider(&data2);
4239
bnc87dcefc2017-05-25 12:47:584240 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:194241 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
mmenke2a1781d2015-10-07 19:25:334242
4243 TestCompletionCallback callback;
tfarina42834112016-09-22 13:38:204244 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:014245 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenke2a1781d2015-10-07 19:25:334246
4247 const HttpResponseInfo* response = trans->GetResponseInfo();
4248 ASSERT_TRUE(response);
4249 ASSERT_TRUE(response->headers);
4250 EXPECT_TRUE(response->headers->IsKeepAlive());
4251 EXPECT_EQ(407, response->headers->response_code());
4252 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
4253 EXPECT_TRUE(trans->IsReadyToRestartForAuth());
4254 EXPECT_FALSE(response->auth_challenge);
4255
4256 LoadTimingInfo load_timing_info;
4257 EXPECT_FALSE(trans->GetLoadTimingInfo(&load_timing_info));
4258
4259 rv = trans->RestartWithAuth(AuthCredentials(), callback.callback());
robpercival214763f2016-07-01 23:27:014260 EXPECT_THAT(callback.GetResult(rv), IsError(ERR_EMPTY_RESPONSE));
mmenke2a1781d2015-10-07 19:25:334261
4262 trans.reset();
4263 session->CloseAllConnections();
4264}
4265
4266// Test a proxy auth scheme that allows default credentials and a proxy server
4267// that hangs up when credentials are initially sent, and sends a challenge
4268// again they are retried.
bncd16676a2016-07-20 16:23:014269TEST_F(HttpNetworkTransactionTest,
mmenke2a1781d2015-10-07 19:25:334270 AuthAllowsDefaultCredentialsTunnelServerChallengesTwice) {
4271 HttpRequestInfo request;
4272 request.method = "GET";
4273 request.url = GURL("https://www.example.org/");
4274
4275 // Configure against proxy server "myproxy:70".
Lily Houghton8c2f97d2018-01-22 05:06:594276 session_deps_.proxy_resolution_service =
4277 ProxyResolutionService::CreateFixedFromPacResult("PROXY myproxy:70");
mmenke2a1781d2015-10-07 19:25:334278
Jeremy Roman0579ed62017-08-29 15:56:194279 auto auth_handler_factory = std::make_unique<HttpAuthHandlerMock::Factory>();
mmenke2a1781d2015-10-07 19:25:334280 auth_handler_factory->set_do_init_from_challenge(true);
Jeremy Roman0579ed62017-08-29 15:56:194281 auto mock_handler = std::make_unique<HttpAuthHandlerMock>();
mmenke2a1781d2015-10-07 19:25:334282 mock_handler->set_allows_default_credentials(true);
4283 auth_handler_factory->AddMockHandler(mock_handler.release(),
4284 HttpAuth::AUTH_PROXY);
4285 // Add another handler for the second challenge. It supports default
4286 // credentials, but they shouldn't be used, since they were already tried.
Jeremy Roman0579ed62017-08-29 15:56:194287 mock_handler = std::make_unique<HttpAuthHandlerMock>();
mmenke2a1781d2015-10-07 19:25:334288 mock_handler->set_allows_default_credentials(true);
4289 auth_handler_factory->AddMockHandler(mock_handler.release(),
4290 HttpAuth::AUTH_PROXY);
dchengc7eeda422015-12-26 03:56:484291 session_deps_.http_auth_handler_factory = std::move(auth_handler_factory);
mmenke2a1781d2015-10-07 19:25:334292
4293 // Add NetLog just so can verify load timing information gets a NetLog ID.
4294 NetLog net_log;
4295 session_deps_.net_log = &net_log;
danakj1fd259a02016-04-16 03:17:094296 std::unique_ptr<HttpNetworkSession> session = CreateSession(&session_deps_);
mmenke2a1781d2015-10-07 19:25:334297
4298 // Should try to establish tunnel.
4299 MockWrite data_writes1[] = {
4300 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:174301 "Host: www.example.org:443\r\n"
mmenke2a1781d2015-10-07 19:25:334302 "Proxy-Connection: keep-alive\r\n\r\n"),
4303 };
4304
4305 // The proxy responds to the connect with a 407, using a non-persistent
4306 // connection.
4307 MockRead data_reads1[] = {
4308 // No credentials.
4309 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
4310 MockRead("Proxy-Authenticate: Mock\r\n"),
4311 MockRead("Proxy-Connection: close\r\n\r\n"),
4312 };
4313
4314 // Since the first connection was closed, need to establish another once given
4315 // credentials.
4316 MockWrite data_writes2[] = {
4317 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:174318 "Host: www.example.org:443\r\n"
mmenke2a1781d2015-10-07 19:25:334319 "Proxy-Connection: keep-alive\r\n"
4320 "Proxy-Authorization: auth_token\r\n\r\n"),
4321 };
4322
4323 MockRead data_reads2[] = {
4324 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
4325 MockRead("Proxy-Authenticate: Mock\r\n"),
4326 MockRead("Proxy-Connection: close\r\n\r\n"),
4327 };
4328
4329 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
4330 data_writes1, arraysize(data_writes1));
4331 session_deps_.socket_factory->AddSocketDataProvider(&data1);
4332 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
4333 data_writes2, arraysize(data_writes2));
4334 session_deps_.socket_factory->AddSocketDataProvider(&data2);
4335 SSLSocketDataProvider ssl(ASYNC, OK);
4336 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
4337
bnc87dcefc2017-05-25 12:47:584338 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:194339 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
mmenke2a1781d2015-10-07 19:25:334340
4341 TestCompletionCallback callback;
tfarina42834112016-09-22 13:38:204342 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:014343 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenke2a1781d2015-10-07 19:25:334344
4345 const HttpResponseInfo* response = trans->GetResponseInfo();
4346 ASSERT_TRUE(response);
4347 ASSERT_TRUE(response->headers);
4348 EXPECT_EQ(407, response->headers->response_code());
4349 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
4350 EXPECT_TRUE(trans->IsReadyToRestartForAuth());
4351 EXPECT_FALSE(response->auth_challenge);
4352
4353 LoadTimingInfo load_timing_info;
4354 EXPECT_FALSE(trans->GetLoadTimingInfo(&load_timing_info));
4355
4356 rv = trans->RestartWithAuth(AuthCredentials(), callback.callback());
robpercival214763f2016-07-01 23:27:014357 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenke2a1781d2015-10-07 19:25:334358 response = trans->GetResponseInfo();
4359 ASSERT_TRUE(response);
4360 ASSERT_TRUE(response->headers);
4361 EXPECT_EQ(407, response->headers->response_code());
4362 EXPECT_FALSE(trans->IsReadyToRestartForAuth());
4363 EXPECT_TRUE(response->auth_challenge);
4364
4365 trans.reset();
4366 session->CloseAllConnections();
4367}
4368
asankae2257db2016-10-11 22:03:164369// A more nuanced test than GenerateAuthToken test which asserts that
4370// ERR_INVALID_AUTH_CREDENTIALS does not cause the auth scheme to be
4371// unnecessarily invalidated, and that if the server co-operates, the
4372// authentication handshake can continue with the same scheme but with a
4373// different identity.
4374TEST_F(HttpNetworkTransactionTest, NonPermanentGenerateAuthTokenError) {
4375 HttpRequestInfo request;
4376 request.method = "GET";
4377 request.url = GURL("http://www.example.org/");
4378
Jeremy Roman0579ed62017-08-29 15:56:194379 auto auth_handler_factory = std::make_unique<HttpAuthHandlerMock::Factory>();
asankae2257db2016-10-11 22:03:164380 auth_handler_factory->set_do_init_from_challenge(true);
4381
4382 // First handler. Uses default credentials, but barfs at generate auth token.
Jeremy Roman0579ed62017-08-29 15:56:194383 auto mock_handler = std::make_unique<HttpAuthHandlerMock>();
asankae2257db2016-10-11 22:03:164384 mock_handler->set_allows_default_credentials(true);
4385 mock_handler->set_allows_explicit_credentials(true);
4386 mock_handler->set_connection_based(true);
4387 mock_handler->SetGenerateExpectation(true, ERR_INVALID_AUTH_CREDENTIALS);
4388 auth_handler_factory->AddMockHandler(mock_handler.release(),
4389 HttpAuth::AUTH_SERVER);
4390
4391 // Add another handler for the second challenge. It supports default
4392 // credentials, but they shouldn't be used, since they were already tried.
Jeremy Roman0579ed62017-08-29 15:56:194393 mock_handler = std::make_unique<HttpAuthHandlerMock>();
asankae2257db2016-10-11 22:03:164394 mock_handler->set_allows_default_credentials(true);
4395 mock_handler->set_allows_explicit_credentials(true);
4396 mock_handler->set_connection_based(true);
4397 auth_handler_factory->AddMockHandler(mock_handler.release(),
4398 HttpAuth::AUTH_SERVER);
4399 session_deps_.http_auth_handler_factory = std::move(auth_handler_factory);
4400
4401 std::unique_ptr<HttpNetworkSession> session = CreateSession(&session_deps_);
4402
4403 MockWrite data_writes1[] = {
4404 MockWrite("GET / HTTP/1.1\r\n"
4405 "Host: www.example.org\r\n"
4406 "Connection: keep-alive\r\n\r\n"),
4407 };
4408
4409 MockRead data_reads1[] = {
4410 MockRead("HTTP/1.1 401 Authentication Required\r\n"
4411 "WWW-Authenticate: Mock\r\n"
4412 "Connection: keep-alive\r\n\r\n"),
4413 };
4414
4415 // Identical to data_writes1[]. The AuthHandler encounters a
4416 // ERR_INVALID_AUTH_CREDENTIALS during the GenerateAuthToken stage, so the
4417 // transaction procceds without an authorization header.
4418 MockWrite data_writes2[] = {
4419 MockWrite("GET / HTTP/1.1\r\n"
4420 "Host: www.example.org\r\n"
4421 "Connection: keep-alive\r\n\r\n"),
4422 };
4423
4424 MockRead data_reads2[] = {
4425 MockRead("HTTP/1.1 401 Authentication Required\r\n"
4426 "WWW-Authenticate: Mock\r\n"
4427 "Connection: keep-alive\r\n\r\n"),
4428 };
4429
4430 MockWrite data_writes3[] = {
4431 MockWrite("GET / HTTP/1.1\r\n"
4432 "Host: www.example.org\r\n"
4433 "Connection: keep-alive\r\n"
4434 "Authorization: auth_token\r\n\r\n"),
4435 };
4436
4437 MockRead data_reads3[] = {
4438 MockRead("HTTP/1.1 200 OK\r\n"
4439 "Content-Length: 5\r\n"
4440 "Content-Type: text/plain\r\n"
4441 "Connection: keep-alive\r\n\r\n"
4442 "Hello"),
4443 };
4444
4445 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
4446 data_writes1, arraysize(data_writes1));
4447 session_deps_.socket_factory->AddSocketDataProvider(&data1);
4448
4449 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
4450 data_writes2, arraysize(data_writes2));
4451 session_deps_.socket_factory->AddSocketDataProvider(&data2);
4452
4453 StaticSocketDataProvider data3(data_reads3, arraysize(data_reads3),
4454 data_writes3, arraysize(data_writes3));
4455 session_deps_.socket_factory->AddSocketDataProvider(&data3);
4456
bnc87dcefc2017-05-25 12:47:584457 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:194458 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
asankae2257db2016-10-11 22:03:164459
4460 TestCompletionCallback callback;
4461 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
4462 EXPECT_THAT(callback.GetResult(rv), IsOk());
4463
4464 const HttpResponseInfo* response = trans->GetResponseInfo();
4465 ASSERT_TRUE(response);
4466 ASSERT_TRUE(response->headers);
4467 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
4468
4469 // The following three tests assert that an authentication challenge was
4470 // received and that the stack is ready to respond to the challenge using
4471 // ambient credentials.
4472 EXPECT_EQ(401, response->headers->response_code());
4473 EXPECT_TRUE(trans->IsReadyToRestartForAuth());
4474 EXPECT_FALSE(response->auth_challenge);
4475
4476 rv = trans->RestartWithAuth(AuthCredentials(), callback.callback());
4477 EXPECT_THAT(callback.GetResult(rv), IsOk());
4478 response = trans->GetResponseInfo();
4479 ASSERT_TRUE(response);
4480 ASSERT_TRUE(response->headers);
4481
4482 // The following three tests assert that an authentication challenge was
4483 // received and that the stack needs explicit credentials before it is ready
4484 // to respond to the challenge.
4485 EXPECT_EQ(401, response->headers->response_code());
4486 EXPECT_FALSE(trans->IsReadyToRestartForAuth());
4487 EXPECT_TRUE(response->auth_challenge);
4488
4489 rv = trans->RestartWithAuth(AuthCredentials(), callback.callback());
4490 EXPECT_THAT(callback.GetResult(rv), IsOk());
4491 response = trans->GetResponseInfo();
4492 ASSERT_TRUE(response);
4493 ASSERT_TRUE(response->headers);
4494 EXPECT_EQ(200, response->headers->response_code());
4495
4496 trans.reset();
4497 session->CloseAllConnections();
4498}
4499
Matt Menked1eb6d42018-01-17 04:54:064500// Proxy resolver that returns a proxy with the same host and port for different
4501// schemes, based on the path of the URL being requests.
4502class SameProxyWithDifferentSchemesProxyResolver : public ProxyResolver {
4503 public:
4504 SameProxyWithDifferentSchemesProxyResolver() {}
4505 ~SameProxyWithDifferentSchemesProxyResolver() override {}
4506
4507 static std::string ProxyHostPortPairAsString() { return "proxy.test:10000"; }
4508
4509 static HostPortPair ProxyHostPortPair() {
4510 return HostPortPair::FromString(ProxyHostPortPairAsString());
4511 }
4512
4513 // ProxyResolver implementation.
4514 int GetProxyForURL(const GURL& url,
4515 ProxyInfo* results,
4516 const CompletionCallback& callback,
4517 std::unique_ptr<Request>* request,
4518 const NetLogWithSource& /*net_log*/) override {
4519 *results = ProxyInfo();
4520 if (url.path() == "/socks4") {
4521 results->UsePacString("SOCKS " + ProxyHostPortPairAsString());
4522 return OK;
4523 }
4524 if (url.path() == "/socks5") {
4525 results->UsePacString("SOCKS5 " + ProxyHostPortPairAsString());
4526 return OK;
4527 }
4528 if (url.path() == "/http") {
4529 results->UsePacString("PROXY " + ProxyHostPortPairAsString());
4530 return OK;
4531 }
4532 if (url.path() == "/https") {
4533 results->UsePacString("HTTPS " + ProxyHostPortPairAsString());
4534 return OK;
4535 }
4536 NOTREACHED();
4537 return ERR_NOT_IMPLEMENTED;
4538 }
4539
4540 private:
4541 DISALLOW_COPY_AND_ASSIGN(SameProxyWithDifferentSchemesProxyResolver);
4542};
4543
4544class SameProxyWithDifferentSchemesProxyResolverFactory
4545 : public ProxyResolverFactory {
4546 public:
4547 SameProxyWithDifferentSchemesProxyResolverFactory()
4548 : ProxyResolverFactory(false) {}
4549
4550 int CreateProxyResolver(
4551 const scoped_refptr<ProxyResolverScriptData>& pac_script,
4552 std::unique_ptr<ProxyResolver>* resolver,
4553 const CompletionCallback& callback,
4554 std::unique_ptr<Request>* request) override {
4555 *resolver = std::make_unique<SameProxyWithDifferentSchemesProxyResolver>();
4556 return OK;
4557 }
4558
4559 private:
4560 DISALLOW_COPY_AND_ASSIGN(SameProxyWithDifferentSchemesProxyResolverFactory);
4561};
4562
4563// Check that when different proxy schemes are all applied to a proxy at the
4564// same address, the sonnections are not grouped together. i.e., a request to
4565// foo.com using proxy.com as an HTTPS proxy won't use the same socket as a
4566// request to foo.com using proxy.com as an HTTP proxy.
4567TEST_F(HttpNetworkTransactionTest, SameDestinationForDifferentProxyTypes) {
Lily Houghton8c2f97d2018-01-22 05:06:594568 session_deps_.proxy_resolution_service = std::make_unique<ProxyResolutionService>(
Matt Menked1eb6d42018-01-17 04:54:064569 std::make_unique<ProxyConfigServiceFixed>(
4570 ProxyConfig::CreateAutoDetect()),
4571 std::make_unique<SameProxyWithDifferentSchemesProxyResolverFactory>(),
4572 nullptr);
4573
4574 std::unique_ptr<HttpNetworkSession> session = CreateSession(&session_deps_);
4575
4576 MockWrite socks_writes[] = {
4577 MockWrite(SYNCHRONOUS, kSOCKS4OkRequestLocalHostPort80,
4578 kSOCKS4OkRequestLocalHostPort80Length),
4579 MockWrite(SYNCHRONOUS,
4580 "GET /socks4 HTTP/1.1\r\n"
4581 "Host: test\r\n"
4582 "Connection: keep-alive\r\n\r\n"),
4583 };
4584 MockRead socks_reads[] = {
4585 MockRead(SYNCHRONOUS, kSOCKS4OkReply, kSOCKS4OkReplyLength),
4586 MockRead("HTTP/1.0 200 OK\r\n"
4587 "Connection: keep-alive\r\n"
4588 "Content-Length: 15\r\n\r\n"
4589 "SOCKS4 Response"),
4590 };
4591 StaticSocketDataProvider socks_data(socks_reads, arraysize(socks_reads),
4592 socks_writes, arraysize(socks_writes));
4593 session_deps_.socket_factory->AddSocketDataProvider(&socks_data);
4594
4595 const char kSOCKS5Request[] = {
4596 0x05, // Version
4597 0x01, // Command (CONNECT)
4598 0x00, // Reserved
4599 0x03, // Address type (DOMAINNAME)
4600 0x04, // Length of domain (4)
4601 't', 'e', 's', 't', // Domain string
4602 0x00, 0x50, // 16-bit port (80)
4603 };
4604 MockWrite socks5_writes[] = {
4605 MockWrite(ASYNC, kSOCKS5GreetRequest, kSOCKS5GreetRequestLength),
4606 MockWrite(ASYNC, kSOCKS5Request, arraysize(kSOCKS5Request)),
4607 MockWrite(SYNCHRONOUS,
4608 "GET /socks5 HTTP/1.1\r\n"
4609 "Host: test\r\n"
4610 "Connection: keep-alive\r\n\r\n"),
4611 };
4612 MockRead socks5_reads[] = {
4613 MockRead(ASYNC, kSOCKS5GreetResponse, kSOCKS5GreetResponseLength),
4614 MockRead(ASYNC, kSOCKS5OkResponse, kSOCKS5OkResponseLength),
4615 MockRead("HTTP/1.0 200 OK\r\n"
4616 "Connection: keep-alive\r\n"
4617 "Content-Length: 15\r\n\r\n"
4618 "SOCKS5 Response"),
4619 };
4620 StaticSocketDataProvider socks5_data(socks5_reads, arraysize(socks5_reads),
4621 socks5_writes, arraysize(socks5_writes));
4622 session_deps_.socket_factory->AddSocketDataProvider(&socks5_data);
4623
4624 MockWrite http_writes[] = {
4625 MockWrite(SYNCHRONOUS,
4626 "GET http://test/http HTTP/1.1\r\n"
4627 "Host: test\r\n"
4628 "Proxy-Connection: keep-alive\r\n\r\n"),
4629 };
4630 MockRead http_reads[] = {
4631 MockRead("HTTP/1.1 200 OK\r\n"
4632 "Proxy-Connection: keep-alive\r\n"
4633 "Content-Length: 13\r\n\r\n"
4634 "HTTP Response"),
4635 };
4636 StaticSocketDataProvider http_data(http_reads, arraysize(http_reads),
4637 http_writes, arraysize(http_writes));
4638 session_deps_.socket_factory->AddSocketDataProvider(&http_data);
4639
4640 MockWrite https_writes[] = {
4641 MockWrite(SYNCHRONOUS,
4642 "GET http://test/https HTTP/1.1\r\n"
4643 "Host: test\r\n"
4644 "Proxy-Connection: keep-alive\r\n\r\n"),
4645 };
4646 MockRead https_reads[] = {
4647 MockRead("HTTP/1.1 200 OK\r\n"
4648 "Proxy-Connection: keep-alive\r\n"
4649 "Content-Length: 14\r\n\r\n"
4650 "HTTPS Response"),
4651 };
4652 StaticSocketDataProvider https_data(https_reads, arraysize(https_reads),
4653 https_writes, arraysize(https_writes));
4654 session_deps_.socket_factory->AddSocketDataProvider(&https_data);
4655 SSLSocketDataProvider ssl(SYNCHRONOUS, OK);
4656 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
4657
4658 struct TestCase {
4659 GURL url;
4660 std::string expected_response;
4661 // How many idle sockets there should be in the SOCKS proxy socket pool
4662 // after the test.
4663 int expected_idle_socks_sockets;
4664 // How many idle sockets there should be in the HTTP proxy socket pool after
4665 // the test.
4666 int expected_idle_http_sockets;
4667 } const kTestCases[] = {
4668 {GURL("http://test/socks4"), "SOCKS4 Response", 1, 0},
4669 {GURL("http://test/socks5"), "SOCKS5 Response", 2, 0},
4670 {GURL("http://test/http"), "HTTP Response", 2, 1},
4671 {GURL("http://test/https"), "HTTPS Response", 2, 2},
4672 };
4673
4674 for (const auto& test_case : kTestCases) {
4675 HttpRequestInfo request;
4676 request.method = "GET";
4677 request.url = test_case.url;
4678 std::unique_ptr<HttpNetworkTransaction> trans =
4679 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY,
4680 session.get());
4681 TestCompletionCallback callback;
4682 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
4683 EXPECT_THAT(callback.GetResult(rv), IsOk());
4684
4685 const HttpResponseInfo* response = trans->GetResponseInfo();
4686 ASSERT_TRUE(response);
4687 ASSERT_TRUE(response->headers);
4688 EXPECT_EQ(200, response->headers->response_code());
4689 std::string response_data;
4690 EXPECT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
4691 EXPECT_EQ(test_case.expected_response, response_data);
4692
4693 // Return the socket to the socket pool, so can make sure it's not used for
4694 // the next requests.
4695 trans.reset();
4696 base::RunLoop().RunUntilIdle();
4697
4698 // Check the number of idle sockets in the pool, to make sure that used
4699 // sockets are indeed being returned to the socket pool. If each request
4700 // doesn't return an idle socket to the pool, the test would incorrectly
4701 // pass.
4702 EXPECT_EQ(
4703 test_case.expected_idle_socks_sockets,
4704 session
4705 ->GetSocketPoolForSOCKSProxy(
4706 HttpNetworkSession::NORMAL_SOCKET_POOL,
4707 SameProxyWithDifferentSchemesProxyResolver::ProxyHostPortPair())
4708 ->IdleSocketCount());
4709 EXPECT_EQ(
4710 test_case.expected_idle_http_sockets,
4711 session
4712 ->GetSocketPoolForHTTPProxy(
4713 HttpNetworkSession::NORMAL_SOCKET_POOL,
4714 SameProxyWithDifferentSchemesProxyResolver::ProxyHostPortPair())
4715 ->IdleSocketCount());
4716 }
4717}
4718
[email protected]029c83b62013-01-24 05:28:204719// Test the load timing for HTTPS requests with an HTTP proxy.
bncd16676a2016-07-20 16:23:014720TEST_F(HttpNetworkTransactionTest, HttpProxyLoadTimingNoPacTwoRequests) {
[email protected]029c83b62013-01-24 05:28:204721 HttpRequestInfo request1;
4722 request1.method = "GET";
bncce36dca22015-04-21 22:11:234723 request1.url = GURL("https://www.example.org/1");
[email protected]029c83b62013-01-24 05:28:204724
4725 HttpRequestInfo request2;
4726 request2.method = "GET";
bncce36dca22015-04-21 22:11:234727 request2.url = GURL("https://www.example.org/2");
[email protected]029c83b62013-01-24 05:28:204728
4729 // Configure against proxy server "myproxy:70".
Lily Houghton8c2f97d2018-01-22 05:06:594730 session_deps_.proxy_resolution_service =
4731 ProxyResolutionService::CreateFixed("myproxy:70");
vishal.b62985ca92015-04-17 08:45:514732 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:074733 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:094734 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]029c83b62013-01-24 05:28:204735
4736 // Since we have proxy, should try to establish tunnel.
4737 MockWrite data_writes1[] = {
rsleevidb16bb02015-11-12 23:47:174738 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
4739 "Host: www.example.org:443\r\n"
4740 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]029c83b62013-01-24 05:28:204741
rsleevidb16bb02015-11-12 23:47:174742 MockWrite("GET /1 HTTP/1.1\r\n"
4743 "Host: www.example.org\r\n"
4744 "Connection: keep-alive\r\n\r\n"),
[email protected]029c83b62013-01-24 05:28:204745
rsleevidb16bb02015-11-12 23:47:174746 MockWrite("GET /2 HTTP/1.1\r\n"
4747 "Host: www.example.org\r\n"
4748 "Connection: keep-alive\r\n\r\n"),
[email protected]029c83b62013-01-24 05:28:204749 };
4750
4751 // The proxy responds to the connect with a 407, using a persistent
4752 // connection.
4753 MockRead data_reads1[] = {
4754 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
4755
4756 MockRead("HTTP/1.1 200 OK\r\n"),
4757 MockRead("Content-Length: 1\r\n\r\n"),
4758 MockRead(SYNCHRONOUS, "1"),
4759
4760 MockRead("HTTP/1.1 200 OK\r\n"),
4761 MockRead("Content-Length: 2\r\n\r\n"),
4762 MockRead(SYNCHRONOUS, "22"),
4763 };
4764
4765 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
4766 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:074767 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]029c83b62013-01-24 05:28:204768 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:074769 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]029c83b62013-01-24 05:28:204770
4771 TestCompletionCallback callback1;
bnc87dcefc2017-05-25 12:47:584772 auto trans1 =
Jeremy Roman0579ed62017-08-29 15:56:194773 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]029c83b62013-01-24 05:28:204774
4775 int rv = trans1->Start(&request1, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:014776 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]029c83b62013-01-24 05:28:204777
4778 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:014779 EXPECT_THAT(rv, IsOk());
[email protected]029c83b62013-01-24 05:28:204780
4781 const HttpResponseInfo* response1 = trans1->GetResponseInfo();
wezca1070932016-05-26 20:30:524782 ASSERT_TRUE(response1);
tbansal2ecbbc72016-10-06 17:15:474783 EXPECT_TRUE(response1->proxy_server.is_http());
wezca1070932016-05-26 20:30:524784 ASSERT_TRUE(response1->headers);
[email protected]029c83b62013-01-24 05:28:204785 EXPECT_EQ(1, response1->headers->GetContentLength());
4786
4787 LoadTimingInfo load_timing_info1;
4788 EXPECT_TRUE(trans1->GetLoadTimingInfo(&load_timing_info1));
4789 TestLoadTimingNotReused(load_timing_info1, CONNECT_TIMING_HAS_SSL_TIMES);
4790
4791 trans1.reset();
4792
4793 TestCompletionCallback callback2;
bnc87dcefc2017-05-25 12:47:584794 auto trans2 =
Jeremy Roman0579ed62017-08-29 15:56:194795 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]029c83b62013-01-24 05:28:204796
4797 rv = trans2->Start(&request2, callback2.callback(), log.bound());
robpercival214763f2016-07-01 23:27:014798 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]029c83b62013-01-24 05:28:204799
4800 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:014801 EXPECT_THAT(rv, IsOk());
[email protected]029c83b62013-01-24 05:28:204802
4803 const HttpResponseInfo* response2 = trans2->GetResponseInfo();
wezca1070932016-05-26 20:30:524804 ASSERT_TRUE(response2);
tbansal2ecbbc72016-10-06 17:15:474805 EXPECT_TRUE(response2->proxy_server.is_http());
wezca1070932016-05-26 20:30:524806 ASSERT_TRUE(response2->headers);
[email protected]029c83b62013-01-24 05:28:204807 EXPECT_EQ(2, response2->headers->GetContentLength());
4808
4809 LoadTimingInfo load_timing_info2;
4810 EXPECT_TRUE(trans2->GetLoadTimingInfo(&load_timing_info2));
4811 TestLoadTimingReused(load_timing_info2);
4812
4813 EXPECT_EQ(load_timing_info1.socket_log_id, load_timing_info2.socket_log_id);
4814
4815 trans2.reset();
4816 session->CloseAllConnections();
4817}
4818
4819// Test the load timing for HTTPS requests with an HTTP proxy and a PAC script.
bncd16676a2016-07-20 16:23:014820TEST_F(HttpNetworkTransactionTest, HttpProxyLoadTimingWithPacTwoRequests) {
[email protected]029c83b62013-01-24 05:28:204821 HttpRequestInfo request1;
4822 request1.method = "GET";
bncce36dca22015-04-21 22:11:234823 request1.url = GURL("https://www.example.org/1");
[email protected]029c83b62013-01-24 05:28:204824
4825 HttpRequestInfo request2;
4826 request2.method = "GET";
bncce36dca22015-04-21 22:11:234827 request2.url = GURL("https://www.example.org/2");
[email protected]029c83b62013-01-24 05:28:204828
4829 // Configure against proxy server "myproxy:70".
Lily Houghton8c2f97d2018-01-22 05:06:594830 session_deps_.proxy_resolution_service =
4831 ProxyResolutionService::CreateFixedFromPacResult("PROXY myproxy:70");
vishal.b62985ca92015-04-17 08:45:514832 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:074833 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:094834 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]029c83b62013-01-24 05:28:204835
4836 // Since we have proxy, should try to establish tunnel.
4837 MockWrite data_writes1[] = {
rsleevidb16bb02015-11-12 23:47:174838 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
4839 "Host: www.example.org:443\r\n"
4840 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]029c83b62013-01-24 05:28:204841
rsleevidb16bb02015-11-12 23:47:174842 MockWrite("GET /1 HTTP/1.1\r\n"
4843 "Host: www.example.org\r\n"
4844 "Connection: keep-alive\r\n\r\n"),
[email protected]029c83b62013-01-24 05:28:204845
rsleevidb16bb02015-11-12 23:47:174846 MockWrite("GET /2 HTTP/1.1\r\n"
4847 "Host: www.example.org\r\n"
4848 "Connection: keep-alive\r\n\r\n"),
[email protected]029c83b62013-01-24 05:28:204849 };
4850
4851 // The proxy responds to the connect with a 407, using a persistent
4852 // connection.
4853 MockRead data_reads1[] = {
4854 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
4855
4856 MockRead("HTTP/1.1 200 OK\r\n"),
4857 MockRead("Content-Length: 1\r\n\r\n"),
4858 MockRead(SYNCHRONOUS, "1"),
4859
4860 MockRead("HTTP/1.1 200 OK\r\n"),
4861 MockRead("Content-Length: 2\r\n\r\n"),
4862 MockRead(SYNCHRONOUS, "22"),
4863 };
4864
4865 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
4866 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:074867 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]029c83b62013-01-24 05:28:204868 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:074869 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]029c83b62013-01-24 05:28:204870
4871 TestCompletionCallback callback1;
bnc87dcefc2017-05-25 12:47:584872 auto trans1 =
Jeremy Roman0579ed62017-08-29 15:56:194873 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]029c83b62013-01-24 05:28:204874
4875 int rv = trans1->Start(&request1, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:014876 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]029c83b62013-01-24 05:28:204877
4878 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:014879 EXPECT_THAT(rv, IsOk());
[email protected]029c83b62013-01-24 05:28:204880
4881 const HttpResponseInfo* response1 = trans1->GetResponseInfo();
wezca1070932016-05-26 20:30:524882 ASSERT_TRUE(response1);
4883 ASSERT_TRUE(response1->headers);
[email protected]029c83b62013-01-24 05:28:204884 EXPECT_EQ(1, response1->headers->GetContentLength());
4885
4886 LoadTimingInfo load_timing_info1;
4887 EXPECT_TRUE(trans1->GetLoadTimingInfo(&load_timing_info1));
4888 TestLoadTimingNotReusedWithPac(load_timing_info1,
4889 CONNECT_TIMING_HAS_SSL_TIMES);
4890
4891 trans1.reset();
4892
4893 TestCompletionCallback callback2;
bnc87dcefc2017-05-25 12:47:584894 auto trans2 =
Jeremy Roman0579ed62017-08-29 15:56:194895 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]029c83b62013-01-24 05:28:204896
4897 rv = trans2->Start(&request2, callback2.callback(), log.bound());
robpercival214763f2016-07-01 23:27:014898 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]029c83b62013-01-24 05:28:204899
4900 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:014901 EXPECT_THAT(rv, IsOk());
[email protected]029c83b62013-01-24 05:28:204902
4903 const HttpResponseInfo* response2 = trans2->GetResponseInfo();
wezca1070932016-05-26 20:30:524904 ASSERT_TRUE(response2);
4905 ASSERT_TRUE(response2->headers);
[email protected]029c83b62013-01-24 05:28:204906 EXPECT_EQ(2, response2->headers->GetContentLength());
4907
4908 LoadTimingInfo load_timing_info2;
4909 EXPECT_TRUE(trans2->GetLoadTimingInfo(&load_timing_info2));
4910 TestLoadTimingReusedWithPac(load_timing_info2);
4911
4912 EXPECT_EQ(load_timing_info1.socket_log_id, load_timing_info2.socket_log_id);
4913
4914 trans2.reset();
4915 session->CloseAllConnections();
4916}
4917
[email protected]2df19bb2010-08-25 20:13:464918// Test a simple get through an HTTPS Proxy.
bncd16676a2016-07-20 16:23:014919TEST_F(HttpNetworkTransactionTest, HttpsProxyGet) {
[email protected]cb9bf6ca2011-01-28 13:15:274920 HttpRequestInfo request;
4921 request.method = "GET";
bncce36dca22015-04-21 22:11:234922 request.url = GURL("http://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:274923
[email protected]2df19bb2010-08-25 20:13:464924 // Configure against https proxy server "proxy:70".
Lily Houghton8c2f97d2018-01-22 05:06:594925 session_deps_.proxy_resolution_service =
4926 ProxyResolutionService::CreateFixed("https://proxy:70");
vishal.b62985ca92015-04-17 08:45:514927 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:074928 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:094929 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]2df19bb2010-08-25 20:13:464930
[email protected]2df19bb2010-08-25 20:13:464931 // Since we have proxy, should use full url
4932 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:234933 MockWrite(
4934 "GET http://www.example.org/ HTTP/1.1\r\n"
4935 "Host: www.example.org\r\n"
4936 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]2df19bb2010-08-25 20:13:464937 };
4938
4939 MockRead data_reads1[] = {
4940 MockRead("HTTP/1.1 200 OK\r\n"),
4941 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
4942 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:064943 MockRead(SYNCHRONOUS, OK),
[email protected]2df19bb2010-08-25 20:13:464944 };
4945
4946 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
4947 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:074948 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8ddf8322012-02-23 18:08:064949 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:074950 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]2df19bb2010-08-25 20:13:464951
[email protected]49639fa2011-12-20 23:22:414952 TestCompletionCallback callback1;
[email protected]2df19bb2010-08-25 20:13:464953
bnc691fda62016-08-12 00:43:164954 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]0b0bf032010-09-21 18:08:504955
bnc691fda62016-08-12 00:43:164956 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:014957 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2df19bb2010-08-25 20:13:464958
4959 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:014960 EXPECT_THAT(rv, IsOk());
[email protected]2df19bb2010-08-25 20:13:464961
[email protected]58e32bb2013-01-21 18:23:254962 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:164963 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]58e32bb2013-01-21 18:23:254964 TestLoadTimingNotReused(load_timing_info,
4965 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
4966
bnc691fda62016-08-12 00:43:164967 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:524968 ASSERT_TRUE(response);
[email protected]2df19bb2010-08-25 20:13:464969
tbansal2ecbbc72016-10-06 17:15:474970 EXPECT_TRUE(response->proxy_server.is_https());
[email protected]2df19bb2010-08-25 20:13:464971 EXPECT_TRUE(response->headers->IsKeepAlive());
4972 EXPECT_EQ(200, response->headers->response_code());
4973 EXPECT_EQ(100, response->headers->GetContentLength());
4974 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
4975
4976 // The password prompt info should not be set.
wezca1070932016-05-26 20:30:524977 EXPECT_FALSE(response->auth_challenge);
[email protected]2df19bb2010-08-25 20:13:464978}
4979
[email protected]7642b5ae2010-09-01 20:55:174980// Test a SPDY get through an HTTPS Proxy.
bncd16676a2016-07-20 16:23:014981TEST_F(HttpNetworkTransactionTest, HttpsProxySpdyGet) {
[email protected]cb9bf6ca2011-01-28 13:15:274982 HttpRequestInfo request;
4983 request.method = "GET";
bncce36dca22015-04-21 22:11:234984 request.url = GURL("http://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:274985
[email protected]7642b5ae2010-09-01 20:55:174986 // Configure against https proxy server "proxy:70".
Lily Houghton8c2f97d2018-01-22 05:06:594987 session_deps_.proxy_resolution_service =
4988 ProxyResolutionService::CreateFixed("https://proxy:70");
vishal.b62985ca92015-04-17 08:45:514989 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:074990 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:094991 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]7642b5ae2010-09-01 20:55:174992
bncce36dca22015-04-21 22:11:234993 // fetch http://www.example.org/ via SPDY
bncdf80d44fd2016-07-15 20:27:414994 SpdySerializedFrame req(
bncb26024382016-06-29 02:39:454995 spdy_util_.ConstructSpdyGet("http://www.example.org/", 1, LOWEST));
bncdf80d44fd2016-07-15 20:27:414996 MockWrite spdy_writes[] = {CreateMockWrite(req, 0)};
[email protected]7642b5ae2010-09-01 20:55:174997
bnc42331402016-07-25 13:36:154998 SpdySerializedFrame resp(spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
bncdf80d44fd2016-07-15 20:27:414999 SpdySerializedFrame data(spdy_util_.ConstructSpdyDataFrame(1, true));
[email protected]7642b5ae2010-09-01 20:55:175000 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:415001 CreateMockRead(resp, 1), CreateMockRead(data, 2), MockRead(ASYNC, 0, 3),
[email protected]7642b5ae2010-09-01 20:55:175002 };
5003
rch8e6c6c42015-05-01 14:05:135004 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
5005 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:075006 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]7642b5ae2010-09-01 20:55:175007
[email protected]8ddf8322012-02-23 18:08:065008 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:365009 ssl.next_proto = kProtoHTTP2;
[email protected]bb88e1d32013-05-03 23:11:075010 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]7642b5ae2010-09-01 20:55:175011
[email protected]49639fa2011-12-20 23:22:415012 TestCompletionCallback callback1;
[email protected]7642b5ae2010-09-01 20:55:175013
bnc691fda62016-08-12 00:43:165014 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]0b0bf032010-09-21 18:08:505015
bnc691fda62016-08-12 00:43:165016 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:015017 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]7642b5ae2010-09-01 20:55:175018
5019 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:015020 EXPECT_THAT(rv, IsOk());
[email protected]7642b5ae2010-09-01 20:55:175021
[email protected]58e32bb2013-01-21 18:23:255022 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:165023 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]58e32bb2013-01-21 18:23:255024 TestLoadTimingNotReused(load_timing_info,
5025 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
5026
bnc691fda62016-08-12 00:43:165027 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:525028 ASSERT_TRUE(response);
tbansal2ecbbc72016-10-06 17:15:475029 EXPECT_TRUE(response->proxy_server.is_https());
wezca1070932016-05-26 20:30:525030 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:025031 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]7642b5ae2010-09-01 20:55:175032
5033 std::string response_data;
bnc691fda62016-08-12 00:43:165034 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
[email protected]448d4ca52012-03-04 04:12:235035 EXPECT_EQ(kUploadData, response_data);
[email protected]7642b5ae2010-09-01 20:55:175036}
5037
[email protected]1c173852014-06-19 12:51:505038// Verifies that a session which races and wins against the owning transaction
5039// (completing prior to host resolution), doesn't fail the transaction.
5040// Regression test for crbug.com/334413.
bncd16676a2016-07-20 16:23:015041TEST_F(HttpNetworkTransactionTest, HttpsProxySpdyGetWithSessionRace) {
[email protected]1c173852014-06-19 12:51:505042 HttpRequestInfo request;
5043 request.method = "GET";
bncce36dca22015-04-21 22:11:235044 request.url = GURL("http://www.example.org/");
[email protected]1c173852014-06-19 12:51:505045
5046 // Configure SPDY proxy server "proxy:70".
Lily Houghton8c2f97d2018-01-22 05:06:595047 session_deps_.proxy_resolution_service =
5048 ProxyResolutionService::CreateFixed("https://proxy:70");
vishal.b62985ca92015-04-17 08:45:515049 BoundTestNetLog log;
[email protected]1c173852014-06-19 12:51:505050 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:095051 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]1c173852014-06-19 12:51:505052
bncce36dca22015-04-21 22:11:235053 // Fetch http://www.example.org/ through the SPDY proxy.
bncdf80d44fd2016-07-15 20:27:415054 SpdySerializedFrame req(
bncb26024382016-06-29 02:39:455055 spdy_util_.ConstructSpdyGet("http://www.example.org/", 1, LOWEST));
bncdf80d44fd2016-07-15 20:27:415056 MockWrite spdy_writes[] = {CreateMockWrite(req, 0)};
[email protected]1c173852014-06-19 12:51:505057
bnc42331402016-07-25 13:36:155058 SpdySerializedFrame resp(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
bncdf80d44fd2016-07-15 20:27:415059 SpdySerializedFrame data(spdy_util_.ConstructSpdyDataFrame(1, true));
[email protected]1c173852014-06-19 12:51:505060 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:415061 CreateMockRead(resp, 1), CreateMockRead(data, 2), MockRead(ASYNC, 0, 3),
[email protected]1c173852014-06-19 12:51:505062 };
5063
rch8e6c6c42015-05-01 14:05:135064 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
5065 arraysize(spdy_writes));
[email protected]1c173852014-06-19 12:51:505066 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
5067
5068 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:365069 ssl.next_proto = kProtoHTTP2;
[email protected]1c173852014-06-19 12:51:505070 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
5071
5072 TestCompletionCallback callback1;
5073
bnc691fda62016-08-12 00:43:165074 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]1c173852014-06-19 12:51:505075
5076 // Stall the hostname resolution begun by the transaction.
5077 session_deps_.host_resolver->set_synchronous_mode(false);
5078 session_deps_.host_resolver->set_ondemand_mode(true);
5079
bnc691fda62016-08-12 00:43:165080 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:015081 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]1c173852014-06-19 12:51:505082
5083 // Race a session to the proxy, which completes first.
5084 session_deps_.host_resolver->set_ondemand_mode(false);
Paul Jensena457017a2018-01-19 23:52:045085 SpdySessionKey key(HostPortPair("proxy", 70), ProxyServer::Direct(),
5086 PRIVACY_MODE_DISABLED, SocketTag());
[email protected]1c173852014-06-19 12:51:505087 base::WeakPtr<SpdySession> spdy_session =
Bence Béky0ef1556e2017-06-30 19:52:525088 CreateSpdySession(session.get(), key, log.bound());
[email protected]1c173852014-06-19 12:51:505089
5090 // Unstall the resolution begun by the transaction.
5091 session_deps_.host_resolver->set_ondemand_mode(true);
5092 session_deps_.host_resolver->ResolveAllPending();
5093
5094 EXPECT_FALSE(callback1.have_result());
5095 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:015096 EXPECT_THAT(rv, IsOk());
[email protected]1c173852014-06-19 12:51:505097
bnc691fda62016-08-12 00:43:165098 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:525099 ASSERT_TRUE(response);
5100 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:025101 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]1c173852014-06-19 12:51:505102
5103 std::string response_data;
bnc691fda62016-08-12 00:43:165104 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
[email protected]1c173852014-06-19 12:51:505105 EXPECT_EQ(kUploadData, response_data);
5106}
5107
[email protected]dc7bd1c52010-11-12 00:01:135108// Test a SPDY get through an HTTPS Proxy.
bncd16676a2016-07-20 16:23:015109TEST_F(HttpNetworkTransactionTest, HttpsProxySpdyGetWithProxyAuth) {
[email protected]cb9bf6ca2011-01-28 13:15:275110 HttpRequestInfo request;
5111 request.method = "GET";
bncce36dca22015-04-21 22:11:235112 request.url = GURL("http://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:275113
[email protected]79cb5c12011-09-12 13:12:045114 // Configure against https proxy server "myproxy:70".
Lily Houghton8c2f97d2018-01-22 05:06:595115 session_deps_.proxy_resolution_service =
5116 ProxyResolutionService::CreateFixed("https://myproxy:70");
vishal.b62985ca92015-04-17 08:45:515117 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:075118 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:095119 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]dc7bd1c52010-11-12 00:01:135120
[email protected]dc7bd1c52010-11-12 00:01:135121 // The first request will be a bare GET, the second request will be a
5122 // GET with a Proxy-Authorization header.
bncb26024382016-06-29 02:39:455123 spdy_util_.set_default_url(request.url);
bncdf80d44fd2016-07-15 20:27:415124 SpdySerializedFrame req_get(
bnc38dcd392016-02-09 23:19:495125 spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST, false));
rdsmithebb50aa2015-11-12 03:44:385126 spdy_util_.UpdateWithStreamDestruction(1);
[email protected]dc7bd1c52010-11-12 00:01:135127 const char* const kExtraAuthorizationHeaders[] = {
[email protected]cdf8f7e72013-05-23 10:56:465128 "proxy-authorization", "Basic Zm9vOmJhcg=="
[email protected]dc7bd1c52010-11-12 00:01:135129 };
bncdf80d44fd2016-07-15 20:27:415130 SpdySerializedFrame req_get_authorization(spdy_util_.ConstructSpdyGet(
5131 kExtraAuthorizationHeaders, arraysize(kExtraAuthorizationHeaders) / 2, 3,
5132 LOWEST, false));
[email protected]dc7bd1c52010-11-12 00:01:135133 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:415134 CreateMockWrite(req_get, 0), CreateMockWrite(req_get_authorization, 3),
[email protected]dc7bd1c52010-11-12 00:01:135135 };
5136
5137 // The first response is a 407 proxy authentication challenge, and the second
5138 // response will be a 200 response since the second request includes a valid
5139 // Authorization header.
5140 const char* const kExtraAuthenticationHeaders[] = {
[email protected]cdf8f7e72013-05-23 10:56:465141 "proxy-authenticate", "Basic realm=\"MyRealm1\""
[email protected]dc7bd1c52010-11-12 00:01:135142 };
bnc42331402016-07-25 13:36:155143 SpdySerializedFrame resp_authentication(spdy_util_.ConstructSpdyReplyError(
bncc9f762a2016-12-06 20:38:235144 "407", kExtraAuthenticationHeaders,
bncdf80d44fd2016-07-15 20:27:415145 arraysize(kExtraAuthenticationHeaders) / 2, 1));
5146 SpdySerializedFrame body_authentication(
5147 spdy_util_.ConstructSpdyDataFrame(1, true));
bnc42331402016-07-25 13:36:155148 SpdySerializedFrame resp_data(spdy_util_.ConstructSpdyGetReply(NULL, 0, 3));
bncdf80d44fd2016-07-15 20:27:415149 SpdySerializedFrame body_data(spdy_util_.ConstructSpdyDataFrame(3, true));
[email protected]dc7bd1c52010-11-12 00:01:135150 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:415151 CreateMockRead(resp_authentication, 1),
bnceb9aa7112017-01-05 01:03:465152 CreateMockRead(body_authentication, 2, SYNCHRONOUS),
bncdf80d44fd2016-07-15 20:27:415153 CreateMockRead(resp_data, 4),
5154 CreateMockRead(body_data, 5),
rch8e6c6c42015-05-01 14:05:135155 MockRead(ASYNC, 0, 6),
[email protected]dc7bd1c52010-11-12 00:01:135156 };
5157
rch8e6c6c42015-05-01 14:05:135158 SequencedSocketData data(spdy_reads, arraysize(spdy_reads), spdy_writes,
5159 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:075160 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]dc7bd1c52010-11-12 00:01:135161
[email protected]8ddf8322012-02-23 18:08:065162 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:365163 ssl.next_proto = kProtoHTTP2;
[email protected]bb88e1d32013-05-03 23:11:075164 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]dc7bd1c52010-11-12 00:01:135165
[email protected]49639fa2011-12-20 23:22:415166 TestCompletionCallback callback1;
[email protected]dc7bd1c52010-11-12 00:01:135167
bnc691fda62016-08-12 00:43:165168 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]dc7bd1c52010-11-12 00:01:135169
bnc691fda62016-08-12 00:43:165170 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:015171 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]dc7bd1c52010-11-12 00:01:135172
5173 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:015174 EXPECT_THAT(rv, IsOk());
[email protected]dc7bd1c52010-11-12 00:01:135175
bnc691fda62016-08-12 00:43:165176 const HttpResponseInfo* const response = trans.GetResponseInfo();
[email protected]dc7bd1c52010-11-12 00:01:135177
wezca1070932016-05-26 20:30:525178 ASSERT_TRUE(response);
5179 ASSERT_TRUE(response->headers);
[email protected]dc7bd1c52010-11-12 00:01:135180 EXPECT_EQ(407, response->headers->response_code());
5181 EXPECT_TRUE(response->was_fetched_via_spdy);
asanka098c0092016-06-16 20:18:435182 EXPECT_TRUE(CheckBasicSecureProxyAuth(response->auth_challenge.get()));
[email protected]dc7bd1c52010-11-12 00:01:135183
[email protected]49639fa2011-12-20 23:22:415184 TestCompletionCallback callback2;
[email protected]dc7bd1c52010-11-12 00:01:135185
bnc691fda62016-08-12 00:43:165186 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar), callback2.callback());
robpercival214763f2016-07-01 23:27:015187 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]dc7bd1c52010-11-12 00:01:135188
5189 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:015190 EXPECT_THAT(rv, IsOk());
[email protected]dc7bd1c52010-11-12 00:01:135191
bnc691fda62016-08-12 00:43:165192 const HttpResponseInfo* const response_restart = trans.GetResponseInfo();
[email protected]dc7bd1c52010-11-12 00:01:135193
wezca1070932016-05-26 20:30:525194 ASSERT_TRUE(response_restart);
5195 ASSERT_TRUE(response_restart->headers);
[email protected]dc7bd1c52010-11-12 00:01:135196 EXPECT_EQ(200, response_restart->headers->response_code());
5197 // The password prompt info should not be set.
wezca1070932016-05-26 20:30:525198 EXPECT_FALSE(response_restart->auth_challenge);
[email protected]dc7bd1c52010-11-12 00:01:135199}
5200
[email protected]d9da5fe2010-10-13 22:37:165201// Test a SPDY CONNECT through an HTTPS Proxy to an HTTPS (non-SPDY) Server.
bncd16676a2016-07-20 16:23:015202TEST_F(HttpNetworkTransactionTest, HttpsProxySpdyConnectHttps) {
[email protected]cb9bf6ca2011-01-28 13:15:275203 HttpRequestInfo request;
5204 request.method = "GET";
bncce36dca22015-04-21 22:11:235205 request.url = GURL("https://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:275206
[email protected]d9da5fe2010-10-13 22:37:165207 // Configure against https proxy server "proxy:70".
Lily Houghton8c2f97d2018-01-22 05:06:595208 session_deps_.proxy_resolution_service =
5209 ProxyResolutionService::CreateFixed("https://proxy:70");
vishal.b62985ca92015-04-17 08:45:515210 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:075211 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:095212 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]d9da5fe2010-10-13 22:37:165213
bnc691fda62016-08-12 00:43:165214 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]d9da5fe2010-10-13 22:37:165215
bncce36dca22015-04-21 22:11:235216 // CONNECT to www.example.org:443 via SPDY
bncdf80d44fd2016-07-15 20:27:415217 SpdySerializedFrame connect(spdy_util_.ConstructSpdyConnect(
bncce36dca22015-04-21 22:11:235218 NULL, 0, 1, LOWEST, HostPortPair("www.example.org", 443)));
5219 // fetch https://www.example.org/ via HTTP
[email protected]d9da5fe2010-10-13 22:37:165220
bncce36dca22015-04-21 22:11:235221 const char get[] =
5222 "GET / HTTP/1.1\r\n"
5223 "Host: www.example.org\r\n"
5224 "Connection: keep-alive\r\n\r\n";
bncdf80d44fd2016-07-15 20:27:415225 SpdySerializedFrame wrapped_get(
5226 spdy_util_.ConstructSpdyDataFrame(1, get, strlen(get), false));
bnc42331402016-07-25 13:36:155227 SpdySerializedFrame conn_resp(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
[email protected]d9da5fe2010-10-13 22:37:165228 const char resp[] = "HTTP/1.1 200 OK\r\n"
5229 "Content-Length: 10\r\n\r\n";
bncdf80d44fd2016-07-15 20:27:415230 SpdySerializedFrame wrapped_get_resp(
5231 spdy_util_.ConstructSpdyDataFrame(1, resp, strlen(resp), false));
5232 SpdySerializedFrame wrapped_body(
5233 spdy_util_.ConstructSpdyDataFrame(1, "1234567890", 10, false));
5234 SpdySerializedFrame window_update(
5235 spdy_util_.ConstructSpdyWindowUpdate(1, wrapped_get_resp.size()));
[email protected]8d2f7012012-02-16 00:08:045236
5237 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:415238 CreateMockWrite(connect, 0), CreateMockWrite(wrapped_get, 2),
5239 CreateMockWrite(window_update, 6),
[email protected]8d2f7012012-02-16 00:08:045240 };
5241
[email protected]d9da5fe2010-10-13 22:37:165242 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:415243 CreateMockRead(conn_resp, 1, ASYNC),
5244 CreateMockRead(wrapped_get_resp, 3, ASYNC),
5245 CreateMockRead(wrapped_body, 4, ASYNC),
5246 CreateMockRead(wrapped_body, 5, ASYNC),
rch8e6c6c42015-05-01 14:05:135247 MockRead(ASYNC, 0, 7),
[email protected]d9da5fe2010-10-13 22:37:165248 };
5249
rch8e6c6c42015-05-01 14:05:135250 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
5251 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:075252 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]d9da5fe2010-10-13 22:37:165253
[email protected]8ddf8322012-02-23 18:08:065254 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:365255 ssl.next_proto = kProtoHTTP2;
[email protected]bb88e1d32013-05-03 23:11:075256 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]8ddf8322012-02-23 18:08:065257 SSLSocketDataProvider ssl2(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:075258 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
[email protected]d9da5fe2010-10-13 22:37:165259
[email protected]49639fa2011-12-20 23:22:415260 TestCompletionCallback callback1;
[email protected]d9da5fe2010-10-13 22:37:165261
bnc691fda62016-08-12 00:43:165262 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:015263 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]d9da5fe2010-10-13 22:37:165264
5265 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:015266 ASSERT_THAT(rv, IsOk());
[email protected]d9da5fe2010-10-13 22:37:165267
[email protected]58e32bb2013-01-21 18:23:255268 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:165269 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]58e32bb2013-01-21 18:23:255270 TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_SSL_TIMES);
5271
bnc691fda62016-08-12 00:43:165272 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:525273 ASSERT_TRUE(response);
5274 ASSERT_TRUE(response->headers);
[email protected]d9da5fe2010-10-13 22:37:165275 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
5276
5277 std::string response_data;
bnc691fda62016-08-12 00:43:165278 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
[email protected]d9da5fe2010-10-13 22:37:165279 EXPECT_EQ("1234567890", response_data);
5280}
5281
5282// Test a SPDY CONNECT through an HTTPS Proxy to a SPDY server.
bncd16676a2016-07-20 16:23:015283TEST_F(HttpNetworkTransactionTest, HttpsProxySpdyConnectSpdy) {
5284 SpdyTestUtil spdy_util_wrapped;
rdsmithebb50aa2015-11-12 03:44:385285
[email protected]cb9bf6ca2011-01-28 13:15:275286 HttpRequestInfo request;
5287 request.method = "GET";
bncce36dca22015-04-21 22:11:235288 request.url = GURL("https://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:275289
[email protected]d9da5fe2010-10-13 22:37:165290 // Configure against https proxy server "proxy:70".
Lily Houghton8c2f97d2018-01-22 05:06:595291 session_deps_.proxy_resolution_service =
5292 ProxyResolutionService::CreateFixed("https://proxy:70");
vishal.b62985ca92015-04-17 08:45:515293 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:075294 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:095295 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]d9da5fe2010-10-13 22:37:165296
bnc691fda62016-08-12 00:43:165297 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]d9da5fe2010-10-13 22:37:165298
bncce36dca22015-04-21 22:11:235299 // CONNECT to www.example.org:443 via SPDY
bncdf80d44fd2016-07-15 20:27:415300 SpdySerializedFrame connect(spdy_util_.ConstructSpdyConnect(
bncce36dca22015-04-21 22:11:235301 NULL, 0, 1, LOWEST, HostPortPair("www.example.org", 443)));
5302 // fetch https://www.example.org/ via SPDY
5303 const char kMyUrl[] = "https://www.example.org/";
bncdf80d44fd2016-07-15 20:27:415304 SpdySerializedFrame get(
bnc38dcd392016-02-09 23:19:495305 spdy_util_wrapped.ConstructSpdyGet(kMyUrl, 1, LOWEST));
bncdf80d44fd2016-07-15 20:27:415306 SpdySerializedFrame wrapped_get(spdy_util_.ConstructWrappedSpdyFrame(get, 1));
bnc42331402016-07-25 13:36:155307 SpdySerializedFrame conn_resp(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
bncdf80d44fd2016-07-15 20:27:415308 SpdySerializedFrame get_resp(
bnc42331402016-07-25 13:36:155309 spdy_util_wrapped.ConstructSpdyGetReply(NULL, 0, 1));
bncdf80d44fd2016-07-15 20:27:415310 SpdySerializedFrame wrapped_get_resp(
[email protected]23e482282013-06-14 16:08:025311 spdy_util_.ConstructWrappedSpdyFrame(get_resp, 1));
bncdf80d44fd2016-07-15 20:27:415312 SpdySerializedFrame body(spdy_util_wrapped.ConstructSpdyDataFrame(1, true));
5313 SpdySerializedFrame wrapped_body(
[email protected]23e482282013-06-14 16:08:025314 spdy_util_.ConstructWrappedSpdyFrame(body, 1));
bncdf80d44fd2016-07-15 20:27:415315 SpdySerializedFrame window_update_get_resp(
5316 spdy_util_.ConstructSpdyWindowUpdate(1, wrapped_get_resp.size()));
5317 SpdySerializedFrame window_update_body(
5318 spdy_util_.ConstructSpdyWindowUpdate(1, wrapped_body.size()));
[email protected]8d2f7012012-02-16 00:08:045319
5320 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:415321 CreateMockWrite(connect, 0), CreateMockWrite(wrapped_get, 2),
5322 CreateMockWrite(window_update_get_resp, 6),
5323 CreateMockWrite(window_update_body, 7),
[email protected]8d2f7012012-02-16 00:08:045324 };
5325
[email protected]d9da5fe2010-10-13 22:37:165326 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:415327 CreateMockRead(conn_resp, 1, ASYNC),
rch32320842015-05-16 15:57:095328 MockRead(ASYNC, ERR_IO_PENDING, 3),
bncdf80d44fd2016-07-15 20:27:415329 CreateMockRead(wrapped_get_resp, 4, ASYNC),
5330 CreateMockRead(wrapped_body, 5, ASYNC),
rch8e6c6c42015-05-01 14:05:135331 MockRead(ASYNC, 0, 8),
[email protected]d9da5fe2010-10-13 22:37:165332 };
5333
rch32320842015-05-16 15:57:095334 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
5335 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:075336 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]d9da5fe2010-10-13 22:37:165337
[email protected]8ddf8322012-02-23 18:08:065338 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:365339 ssl.next_proto = kProtoHTTP2;
[email protected]bb88e1d32013-05-03 23:11:075340 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]8ddf8322012-02-23 18:08:065341 SSLSocketDataProvider ssl2(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:365342 ssl2.next_proto = kProtoHTTP2;
[email protected]bb88e1d32013-05-03 23:11:075343 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
[email protected]d9da5fe2010-10-13 22:37:165344
[email protected]49639fa2011-12-20 23:22:415345 TestCompletionCallback callback1;
[email protected]d9da5fe2010-10-13 22:37:165346
bnc691fda62016-08-12 00:43:165347 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:015348 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]d9da5fe2010-10-13 22:37:165349
rch32320842015-05-16 15:57:095350 // Allow the SpdyProxyClientSocket's write callback to complete.
fdoray92e35a72016-06-10 15:54:555351 base::RunLoop().RunUntilIdle();
rch32320842015-05-16 15:57:095352 // Now allow the read of the response to complete.
mmenkee24011922015-12-17 22:12:595353 spdy_data.Resume();
[email protected]d9da5fe2010-10-13 22:37:165354 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:015355 EXPECT_THAT(rv, IsOk());
[email protected]d9da5fe2010-10-13 22:37:165356
[email protected]58e32bb2013-01-21 18:23:255357 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:165358 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]58e32bb2013-01-21 18:23:255359 TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_SSL_TIMES);
5360
bnc691fda62016-08-12 00:43:165361 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:525362 ASSERT_TRUE(response);
5363 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:025364 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]d9da5fe2010-10-13 22:37:165365
5366 std::string response_data;
bnc691fda62016-08-12 00:43:165367 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
[email protected]448d4ca52012-03-04 04:12:235368 EXPECT_EQ(kUploadData, response_data);
[email protected]d9da5fe2010-10-13 22:37:165369}
5370
5371// Test a SPDY CONNECT failure through an HTTPS Proxy.
bncd16676a2016-07-20 16:23:015372TEST_F(HttpNetworkTransactionTest, HttpsProxySpdyConnectFailure) {
[email protected]cb9bf6ca2011-01-28 13:15:275373 HttpRequestInfo request;
5374 request.method = "GET";
bncce36dca22015-04-21 22:11:235375 request.url = GURL("https://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:275376
[email protected]d9da5fe2010-10-13 22:37:165377 // Configure against https proxy server "proxy:70".
Lily Houghton8c2f97d2018-01-22 05:06:595378 session_deps_.proxy_resolution_service =
5379 ProxyResolutionService::CreateFixed("https://proxy:70");
vishal.b62985ca92015-04-17 08:45:515380 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:075381 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:095382 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]d9da5fe2010-10-13 22:37:165383
bnc691fda62016-08-12 00:43:165384 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]d9da5fe2010-10-13 22:37:165385
bncce36dca22015-04-21 22:11:235386 // CONNECT to www.example.org:443 via SPDY
bncdf80d44fd2016-07-15 20:27:415387 SpdySerializedFrame connect(spdy_util_.ConstructSpdyConnect(
bncce36dca22015-04-21 22:11:235388 NULL, 0, 1, LOWEST, HostPortPair("www.example.org", 443)));
bncdf80d44fd2016-07-15 20:27:415389 SpdySerializedFrame get(
diannahu9904e272017-02-03 14:40:085390 spdy_util_.ConstructSpdyRstStream(1, ERROR_CODE_CANCEL));
[email protected]d9da5fe2010-10-13 22:37:165391
5392 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:415393 CreateMockWrite(connect, 0), CreateMockWrite(get, 2),
[email protected]d9da5fe2010-10-13 22:37:165394 };
5395
bnc42331402016-07-25 13:36:155396 SpdySerializedFrame resp(spdy_util_.ConstructSpdyReplyError(1));
bncdf80d44fd2016-07-15 20:27:415397 SpdySerializedFrame data(spdy_util_.ConstructSpdyDataFrame(1, true));
[email protected]d9da5fe2010-10-13 22:37:165398 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:415399 CreateMockRead(resp, 1, ASYNC), MockRead(ASYNC, 0, 3),
[email protected]d9da5fe2010-10-13 22:37:165400 };
5401
rch8e6c6c42015-05-01 14:05:135402 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
5403 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:075404 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]d9da5fe2010-10-13 22:37:165405
[email protected]8ddf8322012-02-23 18:08:065406 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:365407 ssl.next_proto = kProtoHTTP2;
[email protected]bb88e1d32013-05-03 23:11:075408 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]8ddf8322012-02-23 18:08:065409 SSLSocketDataProvider ssl2(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:365410 ssl2.next_proto = kProtoHTTP2;
[email protected]bb88e1d32013-05-03 23:11:075411 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
[email protected]d9da5fe2010-10-13 22:37:165412
[email protected]49639fa2011-12-20 23:22:415413 TestCompletionCallback callback1;
[email protected]d9da5fe2010-10-13 22:37:165414
bnc691fda62016-08-12 00:43:165415 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:015416 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]d9da5fe2010-10-13 22:37:165417
5418 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:015419 EXPECT_THAT(rv, IsError(ERR_TUNNEL_CONNECTION_FAILED));
[email protected]d9da5fe2010-10-13 22:37:165420
ttuttle960fcbf2016-04-19 13:26:325421 // TODO(juliatuttle): Anything else to check here?
[email protected]d9da5fe2010-10-13 22:37:165422}
5423
[email protected]f6c63db52013-02-02 00:35:225424// Test load timing in the case of two HTTPS (non-SPDY) requests through a SPDY
5425// HTTPS Proxy to different servers.
bncd16676a2016-07-20 16:23:015426TEST_F(HttpNetworkTransactionTest,
[email protected]f6c63db52013-02-02 00:35:225427 HttpsProxySpdyConnectHttpsLoadTimingTwoRequestsTwoServers) {
5428 // Configure against https proxy server "proxy:70".
Lily Houghton8c2f97d2018-01-22 05:06:595429 session_deps_.proxy_resolution_service =
5430 ProxyResolutionService::CreateFixed("https://proxy:70");
vishal.b62985ca92015-04-17 08:45:515431 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:075432 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:095433 std::unique_ptr<HttpNetworkSession> session(
mmenke11eb5152015-06-09 14:50:505434 SpdySessionDependencies::SpdyCreateSession(&session_deps_));
[email protected]f6c63db52013-02-02 00:35:225435
5436 HttpRequestInfo request1;
5437 request1.method = "GET";
bncce36dca22015-04-21 22:11:235438 request1.url = GURL("https://www.example.org/");
[email protected]f6c63db52013-02-02 00:35:225439 request1.load_flags = 0;
5440
5441 HttpRequestInfo request2;
5442 request2.method = "GET";
bncce36dca22015-04-21 22:11:235443 request2.url = GURL("https://mail.example.org/");
[email protected]f6c63db52013-02-02 00:35:225444 request2.load_flags = 0;
5445
bncce36dca22015-04-21 22:11:235446 // CONNECT to www.example.org:443 via SPDY.
bncdf80d44fd2016-07-15 20:27:415447 SpdySerializedFrame connect1(spdy_util_.ConstructSpdyConnect(
bncce36dca22015-04-21 22:11:235448 NULL, 0, 1, LOWEST, HostPortPair("www.example.org", 443)));
bnc42331402016-07-25 13:36:155449 SpdySerializedFrame conn_resp1(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
[email protected]f6c63db52013-02-02 00:35:225450
bncce36dca22015-04-21 22:11:235451 // Fetch https://www.example.org/ via HTTP.
5452 const char get1[] =
5453 "GET / HTTP/1.1\r\n"
5454 "Host: www.example.org\r\n"
[email protected]f6c63db52013-02-02 00:35:225455 "Connection: keep-alive\r\n\r\n";
bncdf80d44fd2016-07-15 20:27:415456 SpdySerializedFrame wrapped_get1(
5457 spdy_util_.ConstructSpdyDataFrame(1, get1, strlen(get1), false));
[email protected]f6c63db52013-02-02 00:35:225458 const char resp1[] = "HTTP/1.1 200 OK\r\n"
5459 "Content-Length: 1\r\n\r\n";
bncdf80d44fd2016-07-15 20:27:415460 SpdySerializedFrame wrapped_get_resp1(
5461 spdy_util_.ConstructSpdyDataFrame(1, resp1, strlen(resp1), false));
5462 SpdySerializedFrame wrapped_body1(
5463 spdy_util_.ConstructSpdyDataFrame(1, "1", 1, false));
5464 SpdySerializedFrame window_update(
5465 spdy_util_.ConstructSpdyWindowUpdate(1, wrapped_get_resp1.size()));
[email protected]f6c63db52013-02-02 00:35:225466
bncce36dca22015-04-21 22:11:235467 // CONNECT to mail.example.org:443 via SPDY.
[email protected]745aa9c2014-06-27 02:21:295468 SpdyHeaderBlock connect2_block;
Bence Békybda82952017-10-02 17:35:275469 connect2_block[kHttp2MethodHeader] = "CONNECT";
5470 connect2_block[kHttp2AuthorityHeader] = "mail.example.org:443";
bnc42331402016-07-25 13:36:155471 SpdySerializedFrame connect2(spdy_util_.ConstructSpdyHeaders(
5472 3, std::move(connect2_block), LOWEST, false));
[email protected]601e03f12014-04-06 16:26:395473
bnc42331402016-07-25 13:36:155474 SpdySerializedFrame conn_resp2(spdy_util_.ConstructSpdyGetReply(NULL, 0, 3));
[email protected]f6c63db52013-02-02 00:35:225475
bncce36dca22015-04-21 22:11:235476 // Fetch https://mail.example.org/ via HTTP.
5477 const char get2[] =
5478 "GET / HTTP/1.1\r\n"
5479 "Host: mail.example.org\r\n"
[email protected]f6c63db52013-02-02 00:35:225480 "Connection: keep-alive\r\n\r\n";
bncdf80d44fd2016-07-15 20:27:415481 SpdySerializedFrame wrapped_get2(
5482 spdy_util_.ConstructSpdyDataFrame(3, get2, strlen(get2), false));
[email protected]f6c63db52013-02-02 00:35:225483 const char resp2[] = "HTTP/1.1 200 OK\r\n"
5484 "Content-Length: 2\r\n\r\n";
bncdf80d44fd2016-07-15 20:27:415485 SpdySerializedFrame wrapped_get_resp2(
5486 spdy_util_.ConstructSpdyDataFrame(3, resp2, strlen(resp2), false));
5487 SpdySerializedFrame wrapped_body2(
5488 spdy_util_.ConstructSpdyDataFrame(3, "22", 2, false));
[email protected]f6c63db52013-02-02 00:35:225489
5490 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:415491 CreateMockWrite(connect1, 0), CreateMockWrite(wrapped_get1, 2),
5492 CreateMockWrite(connect2, 5), CreateMockWrite(wrapped_get2, 7),
[email protected]f6c63db52013-02-02 00:35:225493 };
5494
5495 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:415496 CreateMockRead(conn_resp1, 1, ASYNC),
5497 CreateMockRead(wrapped_get_resp1, 3, ASYNC),
5498 CreateMockRead(wrapped_body1, 4, ASYNC),
5499 CreateMockRead(conn_resp2, 6, ASYNC),
5500 CreateMockRead(wrapped_get_resp2, 8, ASYNC),
5501 CreateMockRead(wrapped_body2, 9, ASYNC),
5502 MockRead(ASYNC, 0, 10),
[email protected]f6c63db52013-02-02 00:35:225503 };
5504
mmenke11eb5152015-06-09 14:50:505505 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
5506 arraysize(spdy_writes));
5507 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]f6c63db52013-02-02 00:35:225508
5509 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:365510 ssl.next_proto = kProtoHTTP2;
mmenke11eb5152015-06-09 14:50:505511 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]f6c63db52013-02-02 00:35:225512 SSLSocketDataProvider ssl2(ASYNC, OK);
mmenke11eb5152015-06-09 14:50:505513 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
[email protected]f6c63db52013-02-02 00:35:225514 SSLSocketDataProvider ssl3(ASYNC, OK);
mmenke11eb5152015-06-09 14:50:505515 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl3);
[email protected]f6c63db52013-02-02 00:35:225516
5517 TestCompletionCallback callback;
5518
bnc691fda62016-08-12 00:43:165519 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:205520 int rv = trans.Start(&request1, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:015521 EXPECT_THAT(callback.GetResult(rv), IsOk());
[email protected]f6c63db52013-02-02 00:35:225522
5523 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:165524 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]f6c63db52013-02-02 00:35:225525 TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_SSL_TIMES);
5526
bnc691fda62016-08-12 00:43:165527 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:525528 ASSERT_TRUE(response);
5529 ASSERT_TRUE(response->headers);
[email protected]f6c63db52013-02-02 00:35:225530 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
5531
5532 std::string response_data;
ttuttle859dc7a2015-04-23 19:42:295533 scoped_refptr<IOBuffer> buf(new IOBuffer(256));
bnc691fda62016-08-12 00:43:165534 rv = trans.Read(buf.get(), 256, callback.callback());
mmenke11eb5152015-06-09 14:50:505535 EXPECT_EQ(1, callback.GetResult(rv));
[email protected]f6c63db52013-02-02 00:35:225536
bnc691fda62016-08-12 00:43:165537 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:205538 rv = trans2.Start(&request2, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:015539 EXPECT_THAT(callback.GetResult(rv), IsOk());
[email protected]f6c63db52013-02-02 00:35:225540
5541 LoadTimingInfo load_timing_info2;
bnc691fda62016-08-12 00:43:165542 EXPECT_TRUE(trans2.GetLoadTimingInfo(&load_timing_info2));
[email protected]f6c63db52013-02-02 00:35:225543 // Even though the SPDY connection is reused, a new tunnelled connection has
5544 // to be created, so the socket's load timing looks like a fresh connection.
5545 TestLoadTimingNotReused(load_timing_info2, CONNECT_TIMING_HAS_SSL_TIMES);
5546
5547 // The requests should have different IDs, since they each are using their own
5548 // separate stream.
5549 EXPECT_NE(load_timing_info.socket_log_id, load_timing_info2.socket_log_id);
5550
bnc691fda62016-08-12 00:43:165551 rv = trans2.Read(buf.get(), 256, callback.callback());
mmenke11eb5152015-06-09 14:50:505552 EXPECT_EQ(2, callback.GetResult(rv));
[email protected]f6c63db52013-02-02 00:35:225553}
5554
5555// Test load timing in the case of two HTTPS (non-SPDY) requests through a SPDY
5556// HTTPS Proxy to the same server.
bncd16676a2016-07-20 16:23:015557TEST_F(HttpNetworkTransactionTest,
[email protected]f6c63db52013-02-02 00:35:225558 HttpsProxySpdyConnectHttpsLoadTimingTwoRequestsSameServer) {
5559 // Configure against https proxy server "proxy:70".
Lily Houghton8c2f97d2018-01-22 05:06:595560 session_deps_.proxy_resolution_service =
5561 ProxyResolutionService::CreateFixed("https://proxy:70");
vishal.b62985ca92015-04-17 08:45:515562 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:075563 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:095564 std::unique_ptr<HttpNetworkSession> session(
mmenke11eb5152015-06-09 14:50:505565 SpdySessionDependencies::SpdyCreateSession(&session_deps_));
[email protected]f6c63db52013-02-02 00:35:225566
5567 HttpRequestInfo request1;
5568 request1.method = "GET";
bncce36dca22015-04-21 22:11:235569 request1.url = GURL("https://www.example.org/");
[email protected]f6c63db52013-02-02 00:35:225570 request1.load_flags = 0;
5571
5572 HttpRequestInfo request2;
5573 request2.method = "GET";
bncce36dca22015-04-21 22:11:235574 request2.url = GURL("https://www.example.org/2");
[email protected]f6c63db52013-02-02 00:35:225575 request2.load_flags = 0;
5576
bncce36dca22015-04-21 22:11:235577 // CONNECT to www.example.org:443 via SPDY.
bncdf80d44fd2016-07-15 20:27:415578 SpdySerializedFrame connect1(spdy_util_.ConstructSpdyConnect(
bncce36dca22015-04-21 22:11:235579 NULL, 0, 1, LOWEST, HostPortPair("www.example.org", 443)));
bnc42331402016-07-25 13:36:155580 SpdySerializedFrame conn_resp1(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
[email protected]f6c63db52013-02-02 00:35:225581
bncce36dca22015-04-21 22:11:235582 // Fetch https://www.example.org/ via HTTP.
5583 const char get1[] =
5584 "GET / HTTP/1.1\r\n"
5585 "Host: www.example.org\r\n"
[email protected]f6c63db52013-02-02 00:35:225586 "Connection: keep-alive\r\n\r\n";
bncdf80d44fd2016-07-15 20:27:415587 SpdySerializedFrame wrapped_get1(
5588 spdy_util_.ConstructSpdyDataFrame(1, get1, strlen(get1), false));
[email protected]f6c63db52013-02-02 00:35:225589 const char resp1[] = "HTTP/1.1 200 OK\r\n"
5590 "Content-Length: 1\r\n\r\n";
bncdf80d44fd2016-07-15 20:27:415591 SpdySerializedFrame wrapped_get_resp1(
5592 spdy_util_.ConstructSpdyDataFrame(1, resp1, strlen(resp1), false));
5593 SpdySerializedFrame wrapped_body1(
5594 spdy_util_.ConstructSpdyDataFrame(1, "1", 1, false));
5595 SpdySerializedFrame window_update(
5596 spdy_util_.ConstructSpdyWindowUpdate(1, wrapped_get_resp1.size()));
[email protected]f6c63db52013-02-02 00:35:225597
bncce36dca22015-04-21 22:11:235598 // Fetch https://www.example.org/2 via HTTP.
5599 const char get2[] =
5600 "GET /2 HTTP/1.1\r\n"
5601 "Host: www.example.org\r\n"
[email protected]f6c63db52013-02-02 00:35:225602 "Connection: keep-alive\r\n\r\n";
bncdf80d44fd2016-07-15 20:27:415603 SpdySerializedFrame wrapped_get2(
5604 spdy_util_.ConstructSpdyDataFrame(1, get2, strlen(get2), false));
[email protected]f6c63db52013-02-02 00:35:225605 const char resp2[] = "HTTP/1.1 200 OK\r\n"
5606 "Content-Length: 2\r\n\r\n";
bncdf80d44fd2016-07-15 20:27:415607 SpdySerializedFrame wrapped_get_resp2(
5608 spdy_util_.ConstructSpdyDataFrame(1, resp2, strlen(resp2), false));
5609 SpdySerializedFrame wrapped_body2(
5610 spdy_util_.ConstructSpdyDataFrame(1, "22", 2, false));
[email protected]f6c63db52013-02-02 00:35:225611
5612 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:415613 CreateMockWrite(connect1, 0), CreateMockWrite(wrapped_get1, 2),
5614 CreateMockWrite(wrapped_get2, 5),
[email protected]f6c63db52013-02-02 00:35:225615 };
5616
5617 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:415618 CreateMockRead(conn_resp1, 1, ASYNC),
5619 CreateMockRead(wrapped_get_resp1, 3, ASYNC),
bnceb9aa7112017-01-05 01:03:465620 CreateMockRead(wrapped_body1, 4, SYNCHRONOUS),
bncdf80d44fd2016-07-15 20:27:415621 CreateMockRead(wrapped_get_resp2, 6, ASYNC),
bnceb9aa7112017-01-05 01:03:465622 CreateMockRead(wrapped_body2, 7, SYNCHRONOUS),
bncdf80d44fd2016-07-15 20:27:415623 MockRead(ASYNC, 0, 8),
[email protected]f6c63db52013-02-02 00:35:225624 };
5625
mmenke11eb5152015-06-09 14:50:505626 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
5627 arraysize(spdy_writes));
5628 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]f6c63db52013-02-02 00:35:225629
5630 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:365631 ssl.next_proto = kProtoHTTP2;
mmenke11eb5152015-06-09 14:50:505632 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]f6c63db52013-02-02 00:35:225633 SSLSocketDataProvider ssl2(ASYNC, OK);
mmenke11eb5152015-06-09 14:50:505634 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
[email protected]f6c63db52013-02-02 00:35:225635
5636 TestCompletionCallback callback;
5637
bnc87dcefc2017-05-25 12:47:585638 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:195639 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:205640 int rv = trans->Start(&request1, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:015641 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]f6c63db52013-02-02 00:35:225642
5643 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:015644 EXPECT_THAT(rv, IsOk());
[email protected]f6c63db52013-02-02 00:35:225645
5646 LoadTimingInfo load_timing_info;
5647 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
5648 TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_SSL_TIMES);
5649
5650 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:525651 ASSERT_TRUE(response);
5652 ASSERT_TRUE(response->headers);
[email protected]f6c63db52013-02-02 00:35:225653 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
5654
5655 std::string response_data;
ttuttle859dc7a2015-04-23 19:42:295656 scoped_refptr<IOBuffer> buf(new IOBuffer(256));
[email protected]90499482013-06-01 00:39:505657 EXPECT_EQ(1, trans->Read(buf.get(), 256, callback.callback()));
[email protected]f6c63db52013-02-02 00:35:225658 trans.reset();
5659
bnc87dcefc2017-05-25 12:47:585660 auto trans2 =
Jeremy Roman0579ed62017-08-29 15:56:195661 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:205662 rv = trans2->Start(&request2, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:015663 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]f6c63db52013-02-02 00:35:225664
[email protected]f6c63db52013-02-02 00:35:225665 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:015666 EXPECT_THAT(rv, IsOk());
[email protected]f6c63db52013-02-02 00:35:225667
5668 LoadTimingInfo load_timing_info2;
5669 EXPECT_TRUE(trans2->GetLoadTimingInfo(&load_timing_info2));
5670 TestLoadTimingReused(load_timing_info2);
5671
5672 // The requests should have the same ID.
5673 EXPECT_EQ(load_timing_info.socket_log_id, load_timing_info2.socket_log_id);
5674
[email protected]90499482013-06-01 00:39:505675 EXPECT_EQ(2, trans2->Read(buf.get(), 256, callback.callback()));
[email protected]f6c63db52013-02-02 00:35:225676}
5677
5678// Test load timing in the case of of two HTTP requests through a SPDY HTTPS
5679// Proxy to different servers.
bncd16676a2016-07-20 16:23:015680TEST_F(HttpNetworkTransactionTest, HttpsProxySpdyLoadTimingTwoHttpRequests) {
[email protected]f6c63db52013-02-02 00:35:225681 // Configure against https proxy server "proxy:70".
Lily Houghton8c2f97d2018-01-22 05:06:595682 session_deps_.proxy_resolution_service =
5683 ProxyResolutionService::CreateFixed("https://proxy:70");
vishal.b62985ca92015-04-17 08:45:515684 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:075685 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:095686 std::unique_ptr<HttpNetworkSession> session(
mmenke11eb5152015-06-09 14:50:505687 SpdySessionDependencies::SpdyCreateSession(&session_deps_));
[email protected]f6c63db52013-02-02 00:35:225688
5689 HttpRequestInfo request1;
5690 request1.method = "GET";
bncce36dca22015-04-21 22:11:235691 request1.url = GURL("http://www.example.org/");
[email protected]f6c63db52013-02-02 00:35:225692 request1.load_flags = 0;
5693
5694 HttpRequestInfo request2;
5695 request2.method = "GET";
bncce36dca22015-04-21 22:11:235696 request2.url = GURL("http://mail.example.org/");
[email protected]f6c63db52013-02-02 00:35:225697 request2.load_flags = 0;
5698
bncce36dca22015-04-21 22:11:235699 // http://www.example.org/
bnc086b39e12016-06-24 13:05:265700 SpdyHeaderBlock headers(
bncce36dca22015-04-21 22:11:235701 spdy_util_.ConstructGetHeaderBlockForProxy("http://www.example.org/"));
bncdf80d44fd2016-07-15 20:27:415702 SpdySerializedFrame get1(
bnc42331402016-07-25 13:36:155703 spdy_util_.ConstructSpdyHeaders(1, std::move(headers), LOWEST, true));
5704 SpdySerializedFrame get_resp1(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
bncdf80d44fd2016-07-15 20:27:415705 SpdySerializedFrame body1(spdy_util_.ConstructSpdyDataFrame(1, "1", 1, true));
rdsmithebb50aa2015-11-12 03:44:385706 spdy_util_.UpdateWithStreamDestruction(1);
[email protected]f6c63db52013-02-02 00:35:225707
bncce36dca22015-04-21 22:11:235708 // http://mail.example.org/
bnc086b39e12016-06-24 13:05:265709 SpdyHeaderBlock headers2(
bncce36dca22015-04-21 22:11:235710 spdy_util_.ConstructGetHeaderBlockForProxy("http://mail.example.org/"));
bncdf80d44fd2016-07-15 20:27:415711 SpdySerializedFrame get2(
bnc42331402016-07-25 13:36:155712 spdy_util_.ConstructSpdyHeaders(3, std::move(headers2), LOWEST, true));
5713 SpdySerializedFrame get_resp2(spdy_util_.ConstructSpdyGetReply(NULL, 0, 3));
bncdf80d44fd2016-07-15 20:27:415714 SpdySerializedFrame body2(
5715 spdy_util_.ConstructSpdyDataFrame(3, "22", 2, true));
[email protected]f6c63db52013-02-02 00:35:225716
5717 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:415718 CreateMockWrite(get1, 0), CreateMockWrite(get2, 3),
[email protected]f6c63db52013-02-02 00:35:225719 };
5720
5721 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:415722 CreateMockRead(get_resp1, 1, ASYNC),
5723 CreateMockRead(body1, 2, ASYNC),
5724 CreateMockRead(get_resp2, 4, ASYNC),
5725 CreateMockRead(body2, 5, ASYNC),
5726 MockRead(ASYNC, 0, 6),
[email protected]f6c63db52013-02-02 00:35:225727 };
5728
mmenke11eb5152015-06-09 14:50:505729 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
5730 arraysize(spdy_writes));
5731 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]f6c63db52013-02-02 00:35:225732
5733 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:365734 ssl.next_proto = kProtoHTTP2;
mmenke11eb5152015-06-09 14:50:505735 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]f6c63db52013-02-02 00:35:225736
5737 TestCompletionCallback callback;
5738
bnc87dcefc2017-05-25 12:47:585739 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:195740 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:205741 int rv = trans->Start(&request1, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:015742 EXPECT_THAT(callback.GetResult(rv), IsOk());
[email protected]f6c63db52013-02-02 00:35:225743
5744 LoadTimingInfo load_timing_info;
5745 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
5746 TestLoadTimingNotReused(load_timing_info,
5747 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
5748
5749 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:525750 ASSERT_TRUE(response);
5751 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:025752 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]f6c63db52013-02-02 00:35:225753
5754 std::string response_data;
ttuttle859dc7a2015-04-23 19:42:295755 scoped_refptr<IOBuffer> buf(new IOBuffer(256));
mmenke11eb5152015-06-09 14:50:505756 rv = trans->Read(buf.get(), 256, callback.callback());
5757 EXPECT_EQ(1, callback.GetResult(rv));
[email protected]f6c63db52013-02-02 00:35:225758 // Delete the first request, so the second one can reuse the socket.
5759 trans.reset();
5760
bnc691fda62016-08-12 00:43:165761 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:205762 rv = trans2.Start(&request2, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:015763 EXPECT_THAT(callback.GetResult(rv), IsOk());
[email protected]f6c63db52013-02-02 00:35:225764
5765 LoadTimingInfo load_timing_info2;
bnc691fda62016-08-12 00:43:165766 EXPECT_TRUE(trans2.GetLoadTimingInfo(&load_timing_info2));
[email protected]f6c63db52013-02-02 00:35:225767 TestLoadTimingReused(load_timing_info2);
5768
5769 // The requests should have the same ID.
5770 EXPECT_EQ(load_timing_info.socket_log_id, load_timing_info2.socket_log_id);
5771
bnc691fda62016-08-12 00:43:165772 rv = trans2.Read(buf.get(), 256, callback.callback());
mmenke11eb5152015-06-09 14:50:505773 EXPECT_EQ(2, callback.GetResult(rv));
[email protected]f6c63db52013-02-02 00:35:225774}
5775
[email protected]2df19bb2010-08-25 20:13:465776// Test the challenge-response-retry sequence through an HTTPS Proxy
bncd16676a2016-07-20 16:23:015777TEST_F(HttpNetworkTransactionTest, HttpsProxyAuthRetry) {
[email protected]2df19bb2010-08-25 20:13:465778 HttpRequestInfo request;
5779 request.method = "GET";
bncce36dca22015-04-21 22:11:235780 request.url = GURL("http://www.example.org/");
[email protected]2df19bb2010-08-25 20:13:465781 // when the no authentication data flag is set.
ttuttle859dc7a2015-04-23 19:42:295782 request.load_flags = LOAD_DO_NOT_SEND_AUTH_DATA;
[email protected]2df19bb2010-08-25 20:13:465783
[email protected]79cb5c12011-09-12 13:12:045784 // Configure against https proxy server "myproxy:70".
Lily Houghton8c2f97d2018-01-22 05:06:595785 session_deps_.proxy_resolution_service =
5786 ProxyResolutionService::CreateFixed("https://myproxy:70");
vishal.b62985ca92015-04-17 08:45:515787 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:075788 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:095789 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:275790
[email protected]2df19bb2010-08-25 20:13:465791 // Since we have proxy, should use full url
5792 MockWrite data_writes1[] = {
bnc691fda62016-08-12 00:43:165793 MockWrite("GET http://www.example.org/ HTTP/1.1\r\n"
5794 "Host: www.example.org\r\n"
5795 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]2df19bb2010-08-25 20:13:465796
bnc691fda62016-08-12 00:43:165797 // After calling trans.RestartWithAuth(), this is the request we should
bncce36dca22015-04-21 22:11:235798 // be issuing -- the final header line contains the credentials.
bnc691fda62016-08-12 00:43:165799 MockWrite("GET http://www.example.org/ HTTP/1.1\r\n"
5800 "Host: www.example.org\r\n"
5801 "Proxy-Connection: keep-alive\r\n"
5802 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]2df19bb2010-08-25 20:13:465803 };
5804
5805 // The proxy responds to the GET with a 407, using a persistent
5806 // connection.
5807 MockRead data_reads1[] = {
5808 // No credentials.
5809 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
5810 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
5811 MockRead("Proxy-Connection: keep-alive\r\n"),
5812 MockRead("Content-Length: 0\r\n\r\n"),
5813
5814 MockRead("HTTP/1.1 200 OK\r\n"),
5815 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
5816 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:065817 MockRead(SYNCHRONOUS, OK),
[email protected]2df19bb2010-08-25 20:13:465818 };
5819
5820 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
5821 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:075822 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8ddf8322012-02-23 18:08:065823 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:075824 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]2df19bb2010-08-25 20:13:465825
[email protected]49639fa2011-12-20 23:22:415826 TestCompletionCallback callback1;
[email protected]2df19bb2010-08-25 20:13:465827
bnc691fda62016-08-12 00:43:165828 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]0b0bf032010-09-21 18:08:505829
bnc691fda62016-08-12 00:43:165830 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:015831 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2df19bb2010-08-25 20:13:465832
5833 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:015834 EXPECT_THAT(rv, IsOk());
[email protected]2df19bb2010-08-25 20:13:465835
[email protected]58e32bb2013-01-21 18:23:255836 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:165837 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]58e32bb2013-01-21 18:23:255838 TestLoadTimingNotReused(load_timing_info,
5839 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
5840
bnc691fda62016-08-12 00:43:165841 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:525842 ASSERT_TRUE(response);
5843 ASSERT_TRUE(response->headers);
[email protected]2df19bb2010-08-25 20:13:465844 EXPECT_EQ(407, response->headers->response_code());
5845 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
asanka098c0092016-06-16 20:18:435846 EXPECT_TRUE(CheckBasicSecureProxyAuth(response->auth_challenge.get()));
[email protected]2df19bb2010-08-25 20:13:465847
[email protected]49639fa2011-12-20 23:22:415848 TestCompletionCallback callback2;
[email protected]2df19bb2010-08-25 20:13:465849
bnc691fda62016-08-12 00:43:165850 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar), callback2.callback());
robpercival214763f2016-07-01 23:27:015851 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2df19bb2010-08-25 20:13:465852
5853 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:015854 EXPECT_THAT(rv, IsOk());
[email protected]2df19bb2010-08-25 20:13:465855
[email protected]58e32bb2013-01-21 18:23:255856 load_timing_info = LoadTimingInfo();
bnc691fda62016-08-12 00:43:165857 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]58e32bb2013-01-21 18:23:255858 // Retrying with HTTP AUTH is considered to be reusing a socket.
5859 TestLoadTimingReused(load_timing_info);
5860
bnc691fda62016-08-12 00:43:165861 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:525862 ASSERT_TRUE(response);
[email protected]2df19bb2010-08-25 20:13:465863
5864 EXPECT_TRUE(response->headers->IsKeepAlive());
5865 EXPECT_EQ(200, response->headers->response_code());
5866 EXPECT_EQ(100, response->headers->GetContentLength());
5867 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
5868
5869 // The password prompt info should not be set.
wezca1070932016-05-26 20:30:525870 EXPECT_FALSE(response->auth_challenge);
[email protected]2df19bb2010-08-25 20:13:465871}
5872
[email protected]23e482282013-06-14 16:08:025873void HttpNetworkTransactionTest::ConnectStatusHelperWithExpectedStatus(
[email protected]c744cf22009-02-27 07:28:085874 const MockRead& status, int expected_status) {
[email protected]1c773ea12009-04-28 19:58:425875 HttpRequestInfo request;
[email protected]c744cf22009-02-27 07:28:085876 request.method = "GET";
bncce36dca22015-04-21 22:11:235877 request.url = GURL("https://www.example.org/");
[email protected]c744cf22009-02-27 07:28:085878
[email protected]cb9bf6ca2011-01-28 13:15:275879 // Configure against proxy server "myproxy:70".
Lily Houghton8c2f97d2018-01-22 05:06:595880 session_deps_.proxy_resolution_service =
5881 ProxyResolutionService::CreateFixed("myproxy:70");
danakj1fd259a02016-04-16 03:17:095882 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:275883
[email protected]c744cf22009-02-27 07:28:085884 // Since we have proxy, should try to establish tunnel.
5885 MockWrite data_writes[] = {
rsleevidb16bb02015-11-12 23:47:175886 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
5887 "Host: www.example.org:443\r\n"
5888 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]c744cf22009-02-27 07:28:085889 };
5890
5891 MockRead data_reads[] = {
mmenked39192ee2015-12-09 00:57:235892 status, MockRead("Content-Length: 10\r\n\r\n"),
5893 // No response body because the test stops reading here.
5894 MockRead(SYNCHRONOUS, ERR_UNEXPECTED),
[email protected]c744cf22009-02-27 07:28:085895 };
5896
[email protected]31a2bfe2010-02-09 08:03:395897 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
5898 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:075899 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]c744cf22009-02-27 07:28:085900
[email protected]49639fa2011-12-20 23:22:415901 TestCompletionCallback callback;
[email protected]c744cf22009-02-27 07:28:085902
bnc691fda62016-08-12 00:43:165903 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]0b0bf032010-09-21 18:08:505904
tfarina42834112016-09-22 13:38:205905 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:015906 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]c744cf22009-02-27 07:28:085907
5908 rv = callback.WaitForResult();
5909 EXPECT_EQ(expected_status, rv);
5910}
5911
[email protected]23e482282013-06-14 16:08:025912void HttpNetworkTransactionTest::ConnectStatusHelper(
[email protected]448d4ca52012-03-04 04:12:235913 const MockRead& status) {
[email protected]c744cf22009-02-27 07:28:085914 ConnectStatusHelperWithExpectedStatus(
[email protected]1c773ea12009-04-28 19:58:425915 status, ERR_TUNNEL_CONNECTION_FAILED);
[email protected]c744cf22009-02-27 07:28:085916}
5917
bncd16676a2016-07-20 16:23:015918TEST_F(HttpNetworkTransactionTest, ConnectStatus100) {
[email protected]c744cf22009-02-27 07:28:085919 ConnectStatusHelper(MockRead("HTTP/1.1 100 Continue\r\n"));
5920}
5921
bncd16676a2016-07-20 16:23:015922TEST_F(HttpNetworkTransactionTest, ConnectStatus101) {
[email protected]c744cf22009-02-27 07:28:085923 ConnectStatusHelper(MockRead("HTTP/1.1 101 Switching Protocols\r\n"));
5924}
5925
bncd16676a2016-07-20 16:23:015926TEST_F(HttpNetworkTransactionTest, ConnectStatus201) {
[email protected]c744cf22009-02-27 07:28:085927 ConnectStatusHelper(MockRead("HTTP/1.1 201 Created\r\n"));
5928}
5929
bncd16676a2016-07-20 16:23:015930TEST_F(HttpNetworkTransactionTest, ConnectStatus202) {
[email protected]c744cf22009-02-27 07:28:085931 ConnectStatusHelper(MockRead("HTTP/1.1 202 Accepted\r\n"));
5932}
5933
bncd16676a2016-07-20 16:23:015934TEST_F(HttpNetworkTransactionTest, ConnectStatus203) {
[email protected]c744cf22009-02-27 07:28:085935 ConnectStatusHelper(
5936 MockRead("HTTP/1.1 203 Non-Authoritative Information\r\n"));
5937}
5938
bncd16676a2016-07-20 16:23:015939TEST_F(HttpNetworkTransactionTest, ConnectStatus204) {
[email protected]c744cf22009-02-27 07:28:085940 ConnectStatusHelper(MockRead("HTTP/1.1 204 No Content\r\n"));
5941}
5942
bncd16676a2016-07-20 16:23:015943TEST_F(HttpNetworkTransactionTest, ConnectStatus205) {
[email protected]c744cf22009-02-27 07:28:085944 ConnectStatusHelper(MockRead("HTTP/1.1 205 Reset Content\r\n"));
5945}
5946
bncd16676a2016-07-20 16:23:015947TEST_F(HttpNetworkTransactionTest, ConnectStatus206) {
[email protected]c744cf22009-02-27 07:28:085948 ConnectStatusHelper(MockRead("HTTP/1.1 206 Partial Content\r\n"));
5949}
5950
bncd16676a2016-07-20 16:23:015951TEST_F(HttpNetworkTransactionTest, ConnectStatus300) {
[email protected]c744cf22009-02-27 07:28:085952 ConnectStatusHelper(MockRead("HTTP/1.1 300 Multiple Choices\r\n"));
5953}
5954
bncd16676a2016-07-20 16:23:015955TEST_F(HttpNetworkTransactionTest, ConnectStatus301) {
[email protected]c744cf22009-02-27 07:28:085956 ConnectStatusHelper(MockRead("HTTP/1.1 301 Moved Permanently\r\n"));
5957}
5958
bncd16676a2016-07-20 16:23:015959TEST_F(HttpNetworkTransactionTest, ConnectStatus302) {
[email protected]c744cf22009-02-27 07:28:085960 ConnectStatusHelper(MockRead("HTTP/1.1 302 Found\r\n"));
5961}
5962
bncd16676a2016-07-20 16:23:015963TEST_F(HttpNetworkTransactionTest, ConnectStatus303) {
[email protected]c744cf22009-02-27 07:28:085964 ConnectStatusHelper(MockRead("HTTP/1.1 303 See Other\r\n"));
5965}
5966
bncd16676a2016-07-20 16:23:015967TEST_F(HttpNetworkTransactionTest, ConnectStatus304) {
[email protected]c744cf22009-02-27 07:28:085968 ConnectStatusHelper(MockRead("HTTP/1.1 304 Not Modified\r\n"));
5969}
5970
bncd16676a2016-07-20 16:23:015971TEST_F(HttpNetworkTransactionTest, ConnectStatus305) {
[email protected]c744cf22009-02-27 07:28:085972 ConnectStatusHelper(MockRead("HTTP/1.1 305 Use Proxy\r\n"));
5973}
5974
bncd16676a2016-07-20 16:23:015975TEST_F(HttpNetworkTransactionTest, ConnectStatus306) {
[email protected]c744cf22009-02-27 07:28:085976 ConnectStatusHelper(MockRead("HTTP/1.1 306\r\n"));
5977}
5978
bncd16676a2016-07-20 16:23:015979TEST_F(HttpNetworkTransactionTest, ConnectStatus307) {
[email protected]c744cf22009-02-27 07:28:085980 ConnectStatusHelper(MockRead("HTTP/1.1 307 Temporary Redirect\r\n"));
5981}
5982
bncd16676a2016-07-20 16:23:015983TEST_F(HttpNetworkTransactionTest, ConnectStatus308) {
[email protected]0a17aab32014-04-24 03:32:375984 ConnectStatusHelper(MockRead("HTTP/1.1 308 Permanent Redirect\r\n"));
5985}
5986
bncd16676a2016-07-20 16:23:015987TEST_F(HttpNetworkTransactionTest, ConnectStatus400) {
[email protected]c744cf22009-02-27 07:28:085988 ConnectStatusHelper(MockRead("HTTP/1.1 400 Bad Request\r\n"));
5989}
5990
bncd16676a2016-07-20 16:23:015991TEST_F(HttpNetworkTransactionTest, ConnectStatus401) {
[email protected]c744cf22009-02-27 07:28:085992 ConnectStatusHelper(MockRead("HTTP/1.1 401 Unauthorized\r\n"));
5993}
5994
bncd16676a2016-07-20 16:23:015995TEST_F(HttpNetworkTransactionTest, ConnectStatus402) {
[email protected]c744cf22009-02-27 07:28:085996 ConnectStatusHelper(MockRead("HTTP/1.1 402 Payment Required\r\n"));
5997}
5998
bncd16676a2016-07-20 16:23:015999TEST_F(HttpNetworkTransactionTest, ConnectStatus403) {
[email protected]c744cf22009-02-27 07:28:086000 ConnectStatusHelper(MockRead("HTTP/1.1 403 Forbidden\r\n"));
6001}
6002
bncd16676a2016-07-20 16:23:016003TEST_F(HttpNetworkTransactionTest, ConnectStatus404) {
[email protected]c744cf22009-02-27 07:28:086004 ConnectStatusHelper(MockRead("HTTP/1.1 404 Not Found\r\n"));
6005}
6006
bncd16676a2016-07-20 16:23:016007TEST_F(HttpNetworkTransactionTest, ConnectStatus405) {
[email protected]c744cf22009-02-27 07:28:086008 ConnectStatusHelper(MockRead("HTTP/1.1 405 Method Not Allowed\r\n"));
6009}
6010
bncd16676a2016-07-20 16:23:016011TEST_F(HttpNetworkTransactionTest, ConnectStatus406) {
[email protected]c744cf22009-02-27 07:28:086012 ConnectStatusHelper(MockRead("HTTP/1.1 406 Not Acceptable\r\n"));
6013}
6014
bncd16676a2016-07-20 16:23:016015TEST_F(HttpNetworkTransactionTest, ConnectStatus407) {
[email protected]c744cf22009-02-27 07:28:086016 ConnectStatusHelperWithExpectedStatus(
6017 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
[email protected]a7ea8832010-07-12 17:54:546018 ERR_PROXY_AUTH_UNSUPPORTED);
[email protected]c744cf22009-02-27 07:28:086019}
6020
bncd16676a2016-07-20 16:23:016021TEST_F(HttpNetworkTransactionTest, ConnectStatus408) {
[email protected]c744cf22009-02-27 07:28:086022 ConnectStatusHelper(MockRead("HTTP/1.1 408 Request Timeout\r\n"));
6023}
6024
bncd16676a2016-07-20 16:23:016025TEST_F(HttpNetworkTransactionTest, ConnectStatus409) {
[email protected]c744cf22009-02-27 07:28:086026 ConnectStatusHelper(MockRead("HTTP/1.1 409 Conflict\r\n"));
6027}
6028
bncd16676a2016-07-20 16:23:016029TEST_F(HttpNetworkTransactionTest, ConnectStatus410) {
[email protected]c744cf22009-02-27 07:28:086030 ConnectStatusHelper(MockRead("HTTP/1.1 410 Gone\r\n"));
6031}
6032
bncd16676a2016-07-20 16:23:016033TEST_F(HttpNetworkTransactionTest, ConnectStatus411) {
[email protected]c744cf22009-02-27 07:28:086034 ConnectStatusHelper(MockRead("HTTP/1.1 411 Length Required\r\n"));
6035}
6036
bncd16676a2016-07-20 16:23:016037TEST_F(HttpNetworkTransactionTest, ConnectStatus412) {
[email protected]c744cf22009-02-27 07:28:086038 ConnectStatusHelper(MockRead("HTTP/1.1 412 Precondition Failed\r\n"));
6039}
6040
bncd16676a2016-07-20 16:23:016041TEST_F(HttpNetworkTransactionTest, ConnectStatus413) {
[email protected]c744cf22009-02-27 07:28:086042 ConnectStatusHelper(MockRead("HTTP/1.1 413 Request Entity Too Large\r\n"));
6043}
6044
bncd16676a2016-07-20 16:23:016045TEST_F(HttpNetworkTransactionTest, ConnectStatus414) {
[email protected]c744cf22009-02-27 07:28:086046 ConnectStatusHelper(MockRead("HTTP/1.1 414 Request-URI Too Long\r\n"));
6047}
6048
bncd16676a2016-07-20 16:23:016049TEST_F(HttpNetworkTransactionTest, ConnectStatus415) {
[email protected]c744cf22009-02-27 07:28:086050 ConnectStatusHelper(MockRead("HTTP/1.1 415 Unsupported Media Type\r\n"));
6051}
6052
bncd16676a2016-07-20 16:23:016053TEST_F(HttpNetworkTransactionTest, ConnectStatus416) {
[email protected]c744cf22009-02-27 07:28:086054 ConnectStatusHelper(
6055 MockRead("HTTP/1.1 416 Requested Range Not Satisfiable\r\n"));
6056}
6057
bncd16676a2016-07-20 16:23:016058TEST_F(HttpNetworkTransactionTest, ConnectStatus417) {
[email protected]c744cf22009-02-27 07:28:086059 ConnectStatusHelper(MockRead("HTTP/1.1 417 Expectation Failed\r\n"));
6060}
6061
bncd16676a2016-07-20 16:23:016062TEST_F(HttpNetworkTransactionTest, ConnectStatus500) {
[email protected]c744cf22009-02-27 07:28:086063 ConnectStatusHelper(MockRead("HTTP/1.1 500 Internal Server Error\r\n"));
6064}
6065
bncd16676a2016-07-20 16:23:016066TEST_F(HttpNetworkTransactionTest, ConnectStatus501) {
[email protected]c744cf22009-02-27 07:28:086067 ConnectStatusHelper(MockRead("HTTP/1.1 501 Not Implemented\r\n"));
6068}
6069
bncd16676a2016-07-20 16:23:016070TEST_F(HttpNetworkTransactionTest, ConnectStatus502) {
[email protected]c744cf22009-02-27 07:28:086071 ConnectStatusHelper(MockRead("HTTP/1.1 502 Bad Gateway\r\n"));
6072}
6073
bncd16676a2016-07-20 16:23:016074TEST_F(HttpNetworkTransactionTest, ConnectStatus503) {
[email protected]c744cf22009-02-27 07:28:086075 ConnectStatusHelper(MockRead("HTTP/1.1 503 Service Unavailable\r\n"));
6076}
6077
bncd16676a2016-07-20 16:23:016078TEST_F(HttpNetworkTransactionTest, ConnectStatus504) {
[email protected]c744cf22009-02-27 07:28:086079 ConnectStatusHelper(MockRead("HTTP/1.1 504 Gateway Timeout\r\n"));
6080}
6081
bncd16676a2016-07-20 16:23:016082TEST_F(HttpNetworkTransactionTest, ConnectStatus505) {
[email protected]c744cf22009-02-27 07:28:086083 ConnectStatusHelper(MockRead("HTTP/1.1 505 HTTP Version Not Supported\r\n"));
6084}
6085
[email protected]038e9a32008-10-08 22:40:166086// Test the flow when both the proxy server AND origin server require
6087// authentication. Again, this uses basic auth for both since that is
6088// the simplest to mock.
bncd16676a2016-07-20 16:23:016089TEST_F(HttpNetworkTransactionTest, BasicAuthProxyThenServer) {
[email protected]cb9bf6ca2011-01-28 13:15:276090 HttpRequestInfo request;
6091 request.method = "GET";
bncce36dca22015-04-21 22:11:236092 request.url = GURL("http://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:276093
[email protected]038e9a32008-10-08 22:40:166094 // Configure against proxy server "myproxy:70".
Lily Houghton8c2f97d2018-01-22 05:06:596095 session_deps_.proxy_resolution_service =
6096 ProxyResolutionService::CreateFixed("myproxy:70");
danakj1fd259a02016-04-16 03:17:096097 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]3fe8d2f82013-10-17 08:56:076098
bnc691fda62016-08-12 00:43:166099 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]038e9a32008-10-08 22:40:166100
[email protected]f9ee6b52008-11-08 06:46:236101 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:236102 MockWrite(
6103 "GET http://www.example.org/ HTTP/1.1\r\n"
6104 "Host: www.example.org\r\n"
6105 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:236106 };
6107
[email protected]038e9a32008-10-08 22:40:166108 MockRead data_reads1[] = {
6109 MockRead("HTTP/1.0 407 Unauthorized\r\n"),
6110 // Give a couple authenticate options (only the middle one is actually
6111 // supported).
[email protected]22927ad2009-09-21 19:56:196112 MockRead("Proxy-Authenticate: Basic invalid\r\n"), // Malformed.
[email protected]038e9a32008-10-08 22:40:166113 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
6114 MockRead("Proxy-Authenticate: UNSUPPORTED realm=\"FOO\"\r\n"),
6115 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
6116 // Large content-length -- won't matter, as connection will be reset.
6117 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:066118 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]038e9a32008-10-08 22:40:166119 };
6120
bnc691fda62016-08-12 00:43:166121 // After calling trans.RestartWithAuth() the first time, this is the
[email protected]038e9a32008-10-08 22:40:166122 // request we should be issuing -- the final header line contains the
6123 // proxy's credentials.
6124 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:236125 MockWrite(
6126 "GET http://www.example.org/ HTTP/1.1\r\n"
6127 "Host: www.example.org\r\n"
6128 "Proxy-Connection: keep-alive\r\n"
6129 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]038e9a32008-10-08 22:40:166130 };
6131
6132 // Now the proxy server lets the request pass through to origin server.
6133 // The origin server responds with a 401.
6134 MockRead data_reads2[] = {
6135 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
6136 // Note: We are using the same realm-name as the proxy server. This is
6137 // completely valid, as realms are unique across hosts.
6138 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
6139 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
6140 MockRead("Content-Length: 2000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:066141 MockRead(SYNCHRONOUS, ERR_FAILED), // Won't be reached.
[email protected]038e9a32008-10-08 22:40:166142 };
6143
bnc691fda62016-08-12 00:43:166144 // After calling trans.RestartWithAuth() the second time, we should send
[email protected]038e9a32008-10-08 22:40:166145 // the credentials for both the proxy and origin server.
6146 MockWrite data_writes3[] = {
bncce36dca22015-04-21 22:11:236147 MockWrite(
6148 "GET http://www.example.org/ HTTP/1.1\r\n"
6149 "Host: www.example.org\r\n"
6150 "Proxy-Connection: keep-alive\r\n"
6151 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n"
6152 "Authorization: Basic Zm9vMjpiYXIy\r\n\r\n"),
[email protected]038e9a32008-10-08 22:40:166153 };
6154
6155 // Lastly we get the desired content.
6156 MockRead data_reads3[] = {
6157 MockRead("HTTP/1.0 200 OK\r\n"),
6158 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
6159 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:066160 MockRead(SYNCHRONOUS, OK),
[email protected]038e9a32008-10-08 22:40:166161 };
6162
[email protected]31a2bfe2010-02-09 08:03:396163 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
6164 data_writes1, arraysize(data_writes1));
6165 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
6166 data_writes2, arraysize(data_writes2));
6167 StaticSocketDataProvider data3(data_reads3, arraysize(data_reads3),
6168 data_writes3, arraysize(data_writes3));
[email protected]bb88e1d32013-05-03 23:11:076169 session_deps_.socket_factory->AddSocketDataProvider(&data1);
6170 session_deps_.socket_factory->AddSocketDataProvider(&data2);
6171 session_deps_.socket_factory->AddSocketDataProvider(&data3);
[email protected]038e9a32008-10-08 22:40:166172
[email protected]49639fa2011-12-20 23:22:416173 TestCompletionCallback callback1;
[email protected]038e9a32008-10-08 22:40:166174
tfarina42834112016-09-22 13:38:206175 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:016176 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]038e9a32008-10-08 22:40:166177
6178 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:016179 EXPECT_THAT(rv, IsOk());
[email protected]038e9a32008-10-08 22:40:166180
bnc691fda62016-08-12 00:43:166181 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:526182 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:046183 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
[email protected]038e9a32008-10-08 22:40:166184
[email protected]49639fa2011-12-20 23:22:416185 TestCompletionCallback callback2;
[email protected]038e9a32008-10-08 22:40:166186
bnc691fda62016-08-12 00:43:166187 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar), callback2.callback());
robpercival214763f2016-07-01 23:27:016188 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]038e9a32008-10-08 22:40:166189
6190 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:016191 EXPECT_THAT(rv, IsOk());
[email protected]038e9a32008-10-08 22:40:166192
bnc691fda62016-08-12 00:43:166193 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:526194 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:046195 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]038e9a32008-10-08 22:40:166196
[email protected]49639fa2011-12-20 23:22:416197 TestCompletionCallback callback3;
[email protected]038e9a32008-10-08 22:40:166198
bnc691fda62016-08-12 00:43:166199 rv = trans.RestartWithAuth(AuthCredentials(kFoo2, kBar2),
6200 callback3.callback());
robpercival214763f2016-07-01 23:27:016201 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]038e9a32008-10-08 22:40:166202
6203 rv = callback3.WaitForResult();
robpercival214763f2016-07-01 23:27:016204 EXPECT_THAT(rv, IsOk());
[email protected]038e9a32008-10-08 22:40:166205
bnc691fda62016-08-12 00:43:166206 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:526207 EXPECT_FALSE(response->auth_challenge);
[email protected]038e9a32008-10-08 22:40:166208 EXPECT_EQ(100, response->headers->GetContentLength());
[email protected]038e9a32008-10-08 22:40:166209}
[email protected]4ddaf2502008-10-23 18:26:196210
[email protected]ea9dc9a2009-09-05 00:43:326211// For the NTLM implementation using SSPI, we skip the NTLM tests since we
6212// can't hook into its internals to cause it to generate predictable NTLM
6213// authorization headers.
6214#if defined(NTLM_PORTABLE)
Zentaro Kavanagh5b27a6e22017-09-25 23:00:376215// The NTLM authentication unit tests are based on known test data from the
6216// [MS-NLMP] Specification [1]. These tests are primarily of the authentication
6217// flow rather than the implementation of the NTLM protocol. See net/ntlm
6218// for the implementation and testing of the protocol.
6219//
6220// [1] https://msdn.microsoft.com/en-us/library/cc236621.aspx
[email protected]385a4672009-03-11 22:21:296221
6222// Enter the correct password and authenticate successfully.
Zentaro Kavanagh5b27a6e22017-09-25 23:00:376223TEST_F(HttpNetworkTransactionTest, NTLMAuthV1) {
[email protected]1c773ea12009-04-28 19:58:426224 HttpRequestInfo request;
[email protected]3f918782009-02-28 01:29:246225 request.method = "GET";
Bence Béky83eb3512017-09-05 12:56:096226 request.url = GURL("https://172.22.68.17/kids/login.aspx");
[email protected]2217aa22013-10-11 03:03:546227
6228 // Ensure load is not disrupted by flags which suppress behaviour specific
6229 // to other auth schemes.
6230 request.load_flags = LOAD_DO_NOT_USE_EMBEDDED_IDENTITY;
[email protected]3f918782009-02-28 01:29:246231
Zentaro Kavanagh6ccee512017-09-28 18:34:096232 HttpAuthHandlerNTLM::ScopedProcSetter proc_setter(
6233 MockGetMSTime, MockGenerateRandom, MockGetHostName);
danakj1fd259a02016-04-16 03:17:096234 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:276235
Zentaro Kavanagh5b27a6e22017-09-25 23:00:376236 // Generate the NTLM messages based on known test data.
6237 std::string negotiate_msg;
6238 std::string challenge_msg;
6239 std::string authenticate_msg;
6240 base::Base64Encode(
6241 base::StringPiece(
6242 reinterpret_cast<const char*>(ntlm::test::kExpectedNegotiateMsg),
6243 arraysize(ntlm::test::kExpectedNegotiateMsg)),
6244 &negotiate_msg);
6245 base::Base64Encode(base::StringPiece(reinterpret_cast<const char*>(
6246 ntlm::test::kChallengeMsgV1),
6247 arraysize(ntlm::test::kChallengeMsgV1)),
6248 &challenge_msg);
6249 base::Base64Encode(
6250 base::StringPiece(
Zentaro Kavanagh6ccee512017-09-28 18:34:096251 reinterpret_cast<const char*>(
6252 ntlm::test::kExpectedAuthenticateMsgSpecResponseV1),
6253 arraysize(ntlm::test::kExpectedAuthenticateMsgSpecResponseV1)),
Zentaro Kavanagh5b27a6e22017-09-25 23:00:376254 &authenticate_msg);
6255
[email protected]3f918782009-02-28 01:29:246256 MockWrite data_writes1[] = {
6257 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
6258 "Host: 172.22.68.17\r\n"
6259 "Connection: keep-alive\r\n\r\n"),
6260 };
6261
6262 MockRead data_reads1[] = {
6263 MockRead("HTTP/1.1 401 Access Denied\r\n"),
[email protected]aef04272010-06-28 18:03:046264 // Negotiate and NTLM are often requested together. However, we only want
6265 // to test NTLM. Since Negotiate is preferred over NTLM, we have to skip
6266 // the header that requests Negotiate for this test.
[email protected]3f918782009-02-28 01:29:246267 MockRead("WWW-Authenticate: NTLM\r\n"),
6268 MockRead("Connection: close\r\n"),
6269 MockRead("Content-Length: 42\r\n"),
[email protected]076c85082009-04-10 23:21:366270 MockRead("Content-Type: text/html\r\n\r\n"),
[email protected]3f918782009-02-28 01:29:246271 // Missing content -- won't matter, as connection will be reset.
[email protected]3f918782009-02-28 01:29:246272 };
6273
6274 MockWrite data_writes2[] = {
bnc691fda62016-08-12 00:43:166275 // After restarting with a null identity, this is the
6276 // request we should be issuing -- the final header line contains a Type
6277 // 1 message.
6278 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
6279 "Host: 172.22.68.17\r\n"
6280 "Connection: keep-alive\r\n"
Zentaro Kavanagh5b27a6e22017-09-25 23:00:376281 "Authorization: NTLM "),
6282 MockWrite(negotiate_msg.c_str()), MockWrite("\r\n\r\n"),
[email protected]3f918782009-02-28 01:29:246283
bnc691fda62016-08-12 00:43:166284 // After calling trans.RestartWithAuth(), we should send a Type 3 message
Zentaro Kavanagh5b27a6e22017-09-25 23:00:376285 // (using correct credentials). The second request continues on the
6286 // same connection.
bnc691fda62016-08-12 00:43:166287 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
6288 "Host: 172.22.68.17\r\n"
6289 "Connection: keep-alive\r\n"
Zentaro Kavanagh5b27a6e22017-09-25 23:00:376290 "Authorization: NTLM "),
6291 MockWrite(authenticate_msg.c_str()), MockWrite("\r\n\r\n"),
[email protected]3f918782009-02-28 01:29:246292 };
6293
6294 MockRead data_reads2[] = {
Bence Béky1e4ef192017-09-18 19:58:026295 // The origin server responds with a Type 2 message.
6296 MockRead("HTTP/1.1 401 Access Denied\r\n"),
Zentaro Kavanagh5b27a6e22017-09-25 23:00:376297 MockRead("WWW-Authenticate: NTLM "), MockRead(challenge_msg.c_str()),
6298 MockRead("\r\n"), MockRead("Content-Length: 42\r\n"),
Bence Béky1e4ef192017-09-18 19:58:026299 MockRead("Content-Type: text/html\r\n\r\n"),
6300 MockRead("You are not authorized to view this page\r\n"),
[email protected]3f918782009-02-28 01:29:246301
Bence Béky1e4ef192017-09-18 19:58:026302 // Lastly we get the desired content.
6303 MockRead("HTTP/1.1 200 OK\r\n"),
6304 MockRead("Content-Type: text/html; charset=utf-8\r\n"),
6305 MockRead("Content-Length: 14\r\n\r\n"), MockRead("Please Login\r\n"),
[email protected]3f918782009-02-28 01:29:246306 };
6307
[email protected]31a2bfe2010-02-09 08:03:396308 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
6309 data_writes1, arraysize(data_writes1));
6310 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
6311 data_writes2, arraysize(data_writes2));
[email protected]bb88e1d32013-05-03 23:11:076312 session_deps_.socket_factory->AddSocketDataProvider(&data1);
6313 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]3f918782009-02-28 01:29:246314
Bence Béky83eb3512017-09-05 12:56:096315 SSLSocketDataProvider ssl1(ASYNC, OK);
6316 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl1);
6317 SSLSocketDataProvider ssl2(ASYNC, OK);
6318 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
6319
[email protected]49639fa2011-12-20 23:22:416320 TestCompletionCallback callback1;
[email protected]3f918782009-02-28 01:29:246321
bnc691fda62016-08-12 00:43:166322 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]0b0bf032010-09-21 18:08:506323
tfarina42834112016-09-22 13:38:206324 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:016325 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]3f918782009-02-28 01:29:246326
6327 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:016328 EXPECT_THAT(rv, IsOk());
[email protected]3f918782009-02-28 01:29:246329
bnc691fda62016-08-12 00:43:166330 EXPECT_FALSE(trans.IsReadyToRestartForAuth());
[email protected]0757e7702009-03-27 04:00:226331
bnc691fda62016-08-12 00:43:166332 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:526333 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:046334 EXPECT_TRUE(CheckNTLMServerAuth(response->auth_challenge.get()));
[email protected]3f918782009-02-28 01:29:246335
[email protected]49639fa2011-12-20 23:22:416336 TestCompletionCallback callback2;
[email protected]10af5fe72011-01-31 16:17:256337
Zentaro Kavanagh5b27a6e22017-09-25 23:00:376338 rv = trans.RestartWithAuth(
6339 AuthCredentials(ntlm::test::kDomainUserCombined, ntlm::test::kPassword),
6340 callback2.callback());
robpercival214763f2016-07-01 23:27:016341 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]10af5fe72011-01-31 16:17:256342
6343 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:016344 EXPECT_THAT(rv, IsOk());
[email protected]10af5fe72011-01-31 16:17:256345
bnc691fda62016-08-12 00:43:166346 EXPECT_TRUE(trans.IsReadyToRestartForAuth());
[email protected]10af5fe72011-01-31 16:17:256347
bnc691fda62016-08-12 00:43:166348 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:526349 ASSERT_TRUE(response);
6350 EXPECT_FALSE(response->auth_challenge);
[email protected]10af5fe72011-01-31 16:17:256351
[email protected]49639fa2011-12-20 23:22:416352 TestCompletionCallback callback3;
[email protected]3f918782009-02-28 01:29:246353
bnc691fda62016-08-12 00:43:166354 rv = trans.RestartWithAuth(AuthCredentials(), callback3.callback());
robpercival214763f2016-07-01 23:27:016355 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]3f918782009-02-28 01:29:246356
[email protected]0757e7702009-03-27 04:00:226357 rv = callback3.WaitForResult();
robpercival214763f2016-07-01 23:27:016358 EXPECT_THAT(rv, IsOk());
[email protected]3f918782009-02-28 01:29:246359
bnc691fda62016-08-12 00:43:166360 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:526361 ASSERT_TRUE(response);
6362 EXPECT_FALSE(response->auth_challenge);
Bence Béky1e4ef192017-09-18 19:58:026363 EXPECT_EQ(14, response->headers->GetContentLength());
6364
6365 std::string response_data;
6366 rv = ReadTransaction(&trans, &response_data);
6367 EXPECT_THAT(rv, IsOk());
6368 EXPECT_EQ("Please Login\r\n", response_data);
6369
6370 EXPECT_TRUE(data1.AllReadDataConsumed());
6371 EXPECT_TRUE(data1.AllWriteDataConsumed());
6372 EXPECT_TRUE(data2.AllReadDataConsumed());
6373 EXPECT_TRUE(data2.AllWriteDataConsumed());
[email protected]3f918782009-02-28 01:29:246374}
6375
[email protected]385a4672009-03-11 22:21:296376// Enter a wrong password, and then the correct one.
Zentaro Kavanagh5b27a6e22017-09-25 23:00:376377TEST_F(HttpNetworkTransactionTest, NTLMAuthV1WrongThenRightPassword) {
[email protected]1c773ea12009-04-28 19:58:426378 HttpRequestInfo request;
[email protected]385a4672009-03-11 22:21:296379 request.method = "GET";
Bence Béky83eb3512017-09-05 12:56:096380 request.url = GURL("https://172.22.68.17/kids/login.aspx");
[email protected]385a4672009-03-11 22:21:296381
Zentaro Kavanagh6ccee512017-09-28 18:34:096382 HttpAuthHandlerNTLM::ScopedProcSetter proc_setter(
6383 MockGetMSTime, MockGenerateRandom, MockGetHostName);
danakj1fd259a02016-04-16 03:17:096384 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:276385
Zentaro Kavanagh5b27a6e22017-09-25 23:00:376386 // Generate the NTLM messages based on known test data.
6387 std::string negotiate_msg;
6388 std::string challenge_msg;
6389 std::string authenticate_msg;
6390 base::Base64Encode(
6391 base::StringPiece(
6392 reinterpret_cast<const char*>(ntlm::test::kExpectedNegotiateMsg),
6393 arraysize(ntlm::test::kExpectedNegotiateMsg)),
6394 &negotiate_msg);
6395 base::Base64Encode(base::StringPiece(reinterpret_cast<const char*>(
6396 ntlm::test::kChallengeMsgV1),
6397 arraysize(ntlm::test::kChallengeMsgV1)),
6398 &challenge_msg);
6399 base::Base64Encode(
6400 base::StringPiece(
Zentaro Kavanagh6ccee512017-09-28 18:34:096401 reinterpret_cast<const char*>(
6402 ntlm::test::kExpectedAuthenticateMsgSpecResponseV1),
6403 arraysize(ntlm::test::kExpectedAuthenticateMsgSpecResponseV1)),
Zentaro Kavanagh5b27a6e22017-09-25 23:00:376404 &authenticate_msg);
6405
6406 // The authenticate message when |kWrongPassword| is sent.
6407 std::string wrong_password_authenticate_msg(
6408 "TlRMTVNTUAADAAAAGAAYAEAAAAAYABgAWAAAAAwADABwAAAACAAIAHwAAAAQABAAhAAAAAAA"
6409 "AABAAAAAA4IIAKqqqqqqqqqqAAAAAAAAAAAAAAAAAAAAAF2npafgDxlql9qxEIhLlsuuJIEd"
6410 "NQHk7kQAbwBtAGEAaQBuAFUAcwBlAHIAQwBPAE0AUABVAFQARQBSAA==");
6411
6412 // Sanity check that this is the same as |authenticate_msg| except for the
6413 // 24 bytes (32 encoded chars) of the NTLM Response.
6414 ASSERT_EQ(authenticate_msg.length(),
6415 wrong_password_authenticate_msg.length());
Zentaro Kavanagh6ccee512017-09-28 18:34:096416 ASSERT_EQ(authenticate_msg.length(), 200u);
Zentaro Kavanagh5b27a6e22017-09-25 23:00:376417 ASSERT_EQ(base::StringPiece(authenticate_msg.data(), 117),
6418 base::StringPiece(wrong_password_authenticate_msg.data(), 117));
6419 ASSERT_EQ(
6420 base::StringPiece(authenticate_msg.data() + 149, 51),
6421 base::StringPiece(wrong_password_authenticate_msg.data() + 149, 51));
6422
[email protected]385a4672009-03-11 22:21:296423 MockWrite data_writes1[] = {
6424 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
6425 "Host: 172.22.68.17\r\n"
6426 "Connection: keep-alive\r\n\r\n"),
6427 };
6428
6429 MockRead data_reads1[] = {
6430 MockRead("HTTP/1.1 401 Access Denied\r\n"),
[email protected]aef04272010-06-28 18:03:046431 // Negotiate and NTLM are often requested together. However, we only want
6432 // to test NTLM. Since Negotiate is preferred over NTLM, we have to skip
6433 // the header that requests Negotiate for this test.
[email protected]385a4672009-03-11 22:21:296434 MockRead("WWW-Authenticate: NTLM\r\n"),
6435 MockRead("Connection: close\r\n"),
6436 MockRead("Content-Length: 42\r\n"),
[email protected]076c85082009-04-10 23:21:366437 MockRead("Content-Type: text/html\r\n\r\n"),
[email protected]385a4672009-03-11 22:21:296438 // Missing content -- won't matter, as connection will be reset.
[email protected]385a4672009-03-11 22:21:296439 };
6440
6441 MockWrite data_writes2[] = {
bnc691fda62016-08-12 00:43:166442 // After restarting with a null identity, this is the
6443 // request we should be issuing -- the final header line contains a Type
6444 // 1 message.
6445 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
6446 "Host: 172.22.68.17\r\n"
6447 "Connection: keep-alive\r\n"
Zentaro Kavanagh5b27a6e22017-09-25 23:00:376448 "Authorization: NTLM "),
6449 MockWrite(negotiate_msg.c_str()), MockWrite("\r\n\r\n"),
[email protected]385a4672009-03-11 22:21:296450
bnc691fda62016-08-12 00:43:166451 // After calling trans.RestartWithAuth(), we should send a Type 3 message
Zentaro Kavanagh5b27a6e22017-09-25 23:00:376452 // (using incorrect credentials). The second request continues on the
6453 // same connection.
bnc691fda62016-08-12 00:43:166454 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
6455 "Host: 172.22.68.17\r\n"
6456 "Connection: keep-alive\r\n"
Zentaro Kavanagh5b27a6e22017-09-25 23:00:376457 "Authorization: NTLM "),
6458 MockWrite(wrong_password_authenticate_msg.c_str()), MockWrite("\r\n\r\n"),
[email protected]385a4672009-03-11 22:21:296459 };
6460
6461 MockRead data_reads2[] = {
Zentaro Kavanagh5b27a6e22017-09-25 23:00:376462 // The origin server responds with a Type 2 message.
6463 MockRead("HTTP/1.1 401 Access Denied\r\n"),
6464 MockRead("WWW-Authenticate: NTLM "), MockRead(challenge_msg.c_str()),
6465 MockRead("\r\n"), MockRead("Content-Length: 42\r\n"),
6466 MockRead("Content-Type: text/html\r\n\r\n"),
6467 MockRead("You are not authorized to view this page\r\n"),
[email protected]385a4672009-03-11 22:21:296468
Zentaro Kavanagh5b27a6e22017-09-25 23:00:376469 // Wrong password.
6470 MockRead("HTTP/1.1 401 Access Denied\r\n"),
6471 MockRead("WWW-Authenticate: NTLM\r\n"), MockRead("Connection: close\r\n"),
6472 MockRead("Content-Length: 42\r\n"),
6473 MockRead("Content-Type: text/html\r\n\r\n"),
6474 // Missing content -- won't matter, as connection will be reset.
[email protected]385a4672009-03-11 22:21:296475 };
6476
6477 MockWrite data_writes3[] = {
bnc691fda62016-08-12 00:43:166478 // After restarting with a null identity, this is the
6479 // request we should be issuing -- the final header line contains a Type
6480 // 1 message.
6481 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
6482 "Host: 172.22.68.17\r\n"
6483 "Connection: keep-alive\r\n"
Zentaro Kavanagh5b27a6e22017-09-25 23:00:376484 "Authorization: NTLM "),
6485 MockWrite(negotiate_msg.c_str()), MockWrite("\r\n\r\n"),
[email protected]385a4672009-03-11 22:21:296486
bnc691fda62016-08-12 00:43:166487 // After calling trans.RestartWithAuth(), we should send a Type 3 message
6488 // (the credentials for the origin server). The second request continues
6489 // on the same connection.
6490 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
6491 "Host: 172.22.68.17\r\n"
6492 "Connection: keep-alive\r\n"
Zentaro Kavanagh5b27a6e22017-09-25 23:00:376493 "Authorization: NTLM "),
6494 MockWrite(authenticate_msg.c_str()), MockWrite("\r\n\r\n"),
[email protected]385a4672009-03-11 22:21:296495 };
6496
6497 MockRead data_reads3[] = {
Bence Béky1e4ef192017-09-18 19:58:026498 // The origin server responds with a Type 2 message.
6499 MockRead("HTTP/1.1 401 Access Denied\r\n"),
Zentaro Kavanagh5b27a6e22017-09-25 23:00:376500 MockRead("WWW-Authenticate: NTLM "), MockRead(challenge_msg.c_str()),
6501 MockRead("\r\n"), MockRead("Content-Length: 42\r\n"),
Bence Béky1e4ef192017-09-18 19:58:026502 MockRead("Content-Type: text/html\r\n\r\n"),
6503 MockRead("You are not authorized to view this page\r\n"),
[email protected]385a4672009-03-11 22:21:296504
Bence Béky1e4ef192017-09-18 19:58:026505 // Lastly we get the desired content.
6506 MockRead("HTTP/1.1 200 OK\r\n"),
6507 MockRead("Content-Type: text/html; charset=utf-8\r\n"),
6508 MockRead("Content-Length: 14\r\n\r\n"), MockRead("Please Login\r\n"),
[email protected]385a4672009-03-11 22:21:296509 };
6510
[email protected]31a2bfe2010-02-09 08:03:396511 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
6512 data_writes1, arraysize(data_writes1));
6513 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
6514 data_writes2, arraysize(data_writes2));
6515 StaticSocketDataProvider data3(data_reads3, arraysize(data_reads3),
6516 data_writes3, arraysize(data_writes3));
[email protected]bb88e1d32013-05-03 23:11:076517 session_deps_.socket_factory->AddSocketDataProvider(&data1);
6518 session_deps_.socket_factory->AddSocketDataProvider(&data2);
6519 session_deps_.socket_factory->AddSocketDataProvider(&data3);
[email protected]385a4672009-03-11 22:21:296520
Bence Béky83eb3512017-09-05 12:56:096521 SSLSocketDataProvider ssl1(ASYNC, OK);
6522 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl1);
6523 SSLSocketDataProvider ssl2(ASYNC, OK);
6524 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
6525 SSLSocketDataProvider ssl3(ASYNC, OK);
6526 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl3);
6527
[email protected]49639fa2011-12-20 23:22:416528 TestCompletionCallback callback1;
[email protected]385a4672009-03-11 22:21:296529
bnc691fda62016-08-12 00:43:166530 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]0b0bf032010-09-21 18:08:506531
tfarina42834112016-09-22 13:38:206532 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:016533 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]385a4672009-03-11 22:21:296534
6535 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:016536 EXPECT_THAT(rv, IsOk());
[email protected]385a4672009-03-11 22:21:296537
bnc691fda62016-08-12 00:43:166538 EXPECT_FALSE(trans.IsReadyToRestartForAuth());
[email protected]385a4672009-03-11 22:21:296539
bnc691fda62016-08-12 00:43:166540 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:526541 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:046542 EXPECT_TRUE(CheckNTLMServerAuth(response->auth_challenge.get()));
[email protected]385a4672009-03-11 22:21:296543
[email protected]49639fa2011-12-20 23:22:416544 TestCompletionCallback callback2;
[email protected]385a4672009-03-11 22:21:296545
[email protected]0757e7702009-03-27 04:00:226546 // Enter the wrong password.
Zentaro Kavanagh5b27a6e22017-09-25 23:00:376547 rv = trans.RestartWithAuth(
6548 AuthCredentials(ntlm::test::kDomainUserCombined, kWrongPassword),
6549 callback2.callback());
robpercival214763f2016-07-01 23:27:016550 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]385a4672009-03-11 22:21:296551
[email protected]10af5fe72011-01-31 16:17:256552 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:016553 EXPECT_THAT(rv, IsOk());
[email protected]385a4672009-03-11 22:21:296554
bnc691fda62016-08-12 00:43:166555 EXPECT_TRUE(trans.IsReadyToRestartForAuth());
[email protected]49639fa2011-12-20 23:22:416556 TestCompletionCallback callback3;
bnc691fda62016-08-12 00:43:166557 rv = trans.RestartWithAuth(AuthCredentials(), callback3.callback());
robpercival214763f2016-07-01 23:27:016558 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]10af5fe72011-01-31 16:17:256559 rv = callback3.WaitForResult();
robpercival214763f2016-07-01 23:27:016560 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:166561 EXPECT_FALSE(trans.IsReadyToRestartForAuth());
[email protected]0757e7702009-03-27 04:00:226562
bnc691fda62016-08-12 00:43:166563 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:526564 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:046565 EXPECT_TRUE(CheckNTLMServerAuth(response->auth_challenge.get()));
[email protected]0757e7702009-03-27 04:00:226566
[email protected]49639fa2011-12-20 23:22:416567 TestCompletionCallback callback4;
[email protected]0757e7702009-03-27 04:00:226568
6569 // Now enter the right password.
Zentaro Kavanagh5b27a6e22017-09-25 23:00:376570 rv = trans.RestartWithAuth(
6571 AuthCredentials(ntlm::test::kDomainUserCombined, ntlm::test::kPassword),
6572 callback4.callback());
robpercival214763f2016-07-01 23:27:016573 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]10af5fe72011-01-31 16:17:256574
6575 rv = callback4.WaitForResult();
robpercival214763f2016-07-01 23:27:016576 EXPECT_THAT(rv, IsOk());
[email protected]10af5fe72011-01-31 16:17:256577
bnc691fda62016-08-12 00:43:166578 EXPECT_TRUE(trans.IsReadyToRestartForAuth());
[email protected]10af5fe72011-01-31 16:17:256579
[email protected]49639fa2011-12-20 23:22:416580 TestCompletionCallback callback5;
[email protected]10af5fe72011-01-31 16:17:256581
6582 // One more roundtrip
bnc691fda62016-08-12 00:43:166583 rv = trans.RestartWithAuth(AuthCredentials(), callback5.callback());
robpercival214763f2016-07-01 23:27:016584 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]0757e7702009-03-27 04:00:226585
6586 rv = callback5.WaitForResult();
robpercival214763f2016-07-01 23:27:016587 EXPECT_THAT(rv, IsOk());
[email protected]0757e7702009-03-27 04:00:226588
bnc691fda62016-08-12 00:43:166589 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:526590 EXPECT_FALSE(response->auth_challenge);
Bence Béky1e4ef192017-09-18 19:58:026591 EXPECT_EQ(14, response->headers->GetContentLength());
6592
6593 std::string response_data;
6594 rv = ReadTransaction(&trans, &response_data);
6595 EXPECT_THAT(rv, IsOk());
6596 EXPECT_EQ("Please Login\r\n", response_data);
6597
6598 EXPECT_TRUE(data1.AllReadDataConsumed());
6599 EXPECT_TRUE(data1.AllWriteDataConsumed());
6600 EXPECT_TRUE(data2.AllReadDataConsumed());
6601 EXPECT_TRUE(data2.AllWriteDataConsumed());
6602 EXPECT_TRUE(data3.AllReadDataConsumed());
6603 EXPECT_TRUE(data3.AllWriteDataConsumed());
[email protected]385a4672009-03-11 22:21:296604}
Bence Béky83eb3512017-09-05 12:56:096605
Bence Béky3238f2e12017-09-22 22:44:496606// Server requests NTLM authentication, which is not supported over HTTP/2.
6607// Subsequent request with authorization header should be sent over HTTP/1.1.
Bence Béky83eb3512017-09-05 12:56:096608TEST_F(HttpNetworkTransactionTest, NTLMOverHttp2) {
Zentaro Kavanagh6ccee512017-09-28 18:34:096609 HttpAuthHandlerNTLM::ScopedProcSetter proc_setter(
6610 MockGetMSTime, MockGenerateRandom, MockGetHostName);
Bence Béky83eb3512017-09-05 12:56:096611
6612 const char* kUrl = "https://172.22.68.17/kids/login.aspx";
6613
6614 HttpRequestInfo request;
6615 request.method = "GET";
6616 request.url = GURL(kUrl);
6617
6618 // First request without credentials.
6619 SpdyHeaderBlock request_headers0(spdy_util_.ConstructGetHeaderBlock(kUrl));
6620 SpdySerializedFrame request0(spdy_util_.ConstructSpdyHeaders(
6621 1, std::move(request_headers0), LOWEST, true));
6622
6623 SpdyHeaderBlock response_headers0;
Bence Békybda82952017-10-02 17:35:276624 response_headers0[kHttp2StatusHeader] = "401";
Bence Béky83eb3512017-09-05 12:56:096625 response_headers0["www-authenticate"] = "NTLM";
6626 SpdySerializedFrame resp(spdy_util_.ConstructSpdyResponseHeaders(
6627 1, std::move(response_headers0), true));
6628
Zentaro Kavanagh5b27a6e22017-09-25 23:00:376629 // Stream 1 is closed.
6630 spdy_util_.UpdateWithStreamDestruction(1);
6631
6632 // Generate the NTLM messages based on known test data.
6633 std::string negotiate_msg;
6634 std::string challenge_msg;
6635 std::string authenticate_msg;
6636 base::Base64Encode(
6637 base::StringPiece(
6638 reinterpret_cast<const char*>(ntlm::test::kExpectedNegotiateMsg),
6639 arraysize(ntlm::test::kExpectedNegotiateMsg)),
6640 &negotiate_msg);
6641 base::Base64Encode(base::StringPiece(reinterpret_cast<const char*>(
6642 ntlm::test::kChallengeMsgV1),
6643 arraysize(ntlm::test::kChallengeMsgV1)),
6644 &challenge_msg);
6645 base::Base64Encode(
6646 base::StringPiece(
Zentaro Kavanagh6ccee512017-09-28 18:34:096647 reinterpret_cast<const char*>(
6648 ntlm::test::kExpectedAuthenticateMsgSpecResponseV1),
6649 arraysize(ntlm::test::kExpectedAuthenticateMsgSpecResponseV1)),
Zentaro Kavanagh5b27a6e22017-09-25 23:00:376650 &authenticate_msg);
6651
6652 // Retry with authorization header.
6653 SpdyHeaderBlock request_headers1(spdy_util_.ConstructGetHeaderBlock(kUrl));
6654 request_headers1["authorization"] = std::string("NTLM ") + negotiate_msg;
6655 SpdySerializedFrame request1(spdy_util_.ConstructSpdyHeaders(
6656 3, std::move(request_headers1), LOWEST, true));
6657
6658 SpdySerializedFrame rst(
6659 spdy_util_.ConstructSpdyRstStream(3, ERROR_CODE_HTTP_1_1_REQUIRED));
6660
Bence Béky3238f2e12017-09-22 22:44:496661 MockWrite writes0[] = {CreateMockWrite(request0, 0)};
6662 MockRead reads0[] = {CreateMockRead(resp, 1), MockRead(ASYNC, 0, 2)};
Bence Béky83eb3512017-09-05 12:56:096663
6664 // Retry yet again using HTTP/1.1.
6665 MockWrite writes1[] = {
6666 // After restarting with a null identity, this is the
6667 // request we should be issuing -- the final header line contains a Type
6668 // 1 message.
6669 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
6670 "Host: 172.22.68.17\r\n"
6671 "Connection: keep-alive\r\n"
Zentaro Kavanagh5b27a6e22017-09-25 23:00:376672 "Authorization: NTLM "),
6673 MockWrite(negotiate_msg.c_str()), MockWrite("\r\n\r\n"),
Bence Béky83eb3512017-09-05 12:56:096674
6675 // After calling trans.RestartWithAuth(), we should send a Type 3 message
6676 // (the credentials for the origin server). The second request continues
6677 // on the same connection.
6678 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
6679 "Host: 172.22.68.17\r\n"
6680 "Connection: keep-alive\r\n"
Zentaro Kavanagh5b27a6e22017-09-25 23:00:376681 "Authorization: NTLM "),
6682 MockWrite(authenticate_msg.c_str()), MockWrite("\r\n\r\n"),
Bence Béky83eb3512017-09-05 12:56:096683 };
6684
6685 MockRead reads1[] = {
6686 // The origin server responds with a Type 2 message.
6687 MockRead("HTTP/1.1 401 Access Denied\r\n"),
Zentaro Kavanagh5b27a6e22017-09-25 23:00:376688 MockRead("WWW-Authenticate: NTLM "), MockRead(challenge_msg.c_str()),
6689 MockRead("\r\n"), MockRead("Content-Length: 42\r\n"),
Bence Béky83eb3512017-09-05 12:56:096690 MockRead("Content-Type: text/html\r\n\r\n"),
6691 MockRead("You are not authorized to view this page\r\n"),
6692
6693 // Lastly we get the desired content.
6694 MockRead("HTTP/1.1 200 OK\r\n"),
6695 MockRead("Content-Type: text/html; charset=utf-8\r\n"),
Bence Béky1e4ef192017-09-18 19:58:026696 MockRead("Content-Length: 14\r\n\r\n"), MockRead("Please Login\r\n"),
Bence Béky83eb3512017-09-05 12:56:096697 };
6698 SequencedSocketData data0(reads0, arraysize(reads0), writes0,
6699 arraysize(writes0));
6700 StaticSocketDataProvider data1(reads1, arraysize(reads1), writes1,
6701 arraysize(writes1));
6702 session_deps_.socket_factory->AddSocketDataProvider(&data0);
6703 session_deps_.socket_factory->AddSocketDataProvider(&data1);
6704
6705 SSLSocketDataProvider ssl0(ASYNC, OK);
6706 ssl0.next_proto = kProtoHTTP2;
6707 SSLSocketDataProvider ssl1(ASYNC, OK);
6708 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl0);
6709 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl1);
6710
6711 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
6712 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
6713
6714 TestCompletionCallback callback1;
6715 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
6716 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
6717
6718 rv = callback1.WaitForResult();
6719 EXPECT_THAT(rv, IsOk());
6720
6721 EXPECT_FALSE(trans.IsReadyToRestartForAuth());
6722
6723 const HttpResponseInfo* response = trans.GetResponseInfo();
6724 ASSERT_TRUE(response);
6725 EXPECT_TRUE(CheckNTLMServerAuth(response->auth_challenge.get()));
6726
6727 TestCompletionCallback callback2;
6728
Zentaro Kavanagh5b27a6e22017-09-25 23:00:376729 rv = trans.RestartWithAuth(
6730 AuthCredentials(ntlm::test::kDomainUserCombined, ntlm::test::kPassword),
6731 callback2.callback());
Bence Béky83eb3512017-09-05 12:56:096732 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
6733
6734 rv = callback2.WaitForResult();
6735 EXPECT_THAT(rv, IsOk());
6736
6737 EXPECT_TRUE(trans.IsReadyToRestartForAuth());
6738
6739 response = trans.GetResponseInfo();
6740 ASSERT_TRUE(response);
6741 EXPECT_FALSE(response->auth_challenge);
6742
6743 TestCompletionCallback callback3;
6744
6745 rv = trans.RestartWithAuth(AuthCredentials(), callback3.callback());
6746 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
6747
6748 rv = callback3.WaitForResult();
6749 EXPECT_THAT(rv, IsOk());
6750
6751 response = trans.GetResponseInfo();
6752 ASSERT_TRUE(response);
6753 EXPECT_FALSE(response->auth_challenge);
Bence Béky1e4ef192017-09-18 19:58:026754 EXPECT_EQ(14, response->headers->GetContentLength());
6755
6756 std::string response_data;
6757 rv = ReadTransaction(&trans, &response_data);
6758 EXPECT_THAT(rv, IsOk());
6759 EXPECT_EQ("Please Login\r\n", response_data);
6760
6761 EXPECT_TRUE(data0.AllReadDataConsumed());
6762 EXPECT_TRUE(data0.AllWriteDataConsumed());
6763 EXPECT_TRUE(data1.AllReadDataConsumed());
6764 EXPECT_TRUE(data1.AllWriteDataConsumed());
Bence Béky83eb3512017-09-05 12:56:096765}
[email protected]ea9dc9a2009-09-05 00:43:326766#endif // NTLM_PORTABLE
[email protected]385a4672009-03-11 22:21:296767
[email protected]4ddaf2502008-10-23 18:26:196768// Test reading a server response which has only headers, and no body.
6769// After some maximum number of bytes is consumed, the transaction should
6770// fail with ERR_RESPONSE_HEADERS_TOO_BIG.
bncd16676a2016-07-20 16:23:016771TEST_F(HttpNetworkTransactionTest, LargeHeadersNoBody) {
[email protected]1c773ea12009-04-28 19:58:426772 HttpRequestInfo request;
[email protected]4ddaf2502008-10-23 18:26:196773 request.method = "GET";
bncce36dca22015-04-21 22:11:236774 request.url = GURL("http://www.example.org/");
[email protected]4ddaf2502008-10-23 18:26:196775
danakj1fd259a02016-04-16 03:17:096776 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:166777 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:276778
[email protected]b75b7b2f2009-10-06 00:54:536779 // Respond with 300 kb of headers (we should fail after 256 kb).
[email protected]15a5ccf82008-10-23 19:57:436780 std::string large_headers_string;
[email protected]b75b7b2f2009-10-06 00:54:536781 FillLargeHeadersString(&large_headers_string, 300 * 1024);
[email protected]4ddaf2502008-10-23 18:26:196782
6783 MockRead data_reads[] = {
6784 MockRead("HTTP/1.0 200 OK\r\n"),
[email protected]8ddf8322012-02-23 18:08:066785 MockRead(ASYNC, large_headers_string.data(), large_headers_string.size()),
[email protected]4ddaf2502008-10-23 18:26:196786 MockRead("\r\nBODY"),
[email protected]8ddf8322012-02-23 18:08:066787 MockRead(SYNCHRONOUS, OK),
[email protected]4ddaf2502008-10-23 18:26:196788 };
[email protected]31a2bfe2010-02-09 08:03:396789 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:076790 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]4ddaf2502008-10-23 18:26:196791
[email protected]49639fa2011-12-20 23:22:416792 TestCompletionCallback callback;
[email protected]4ddaf2502008-10-23 18:26:196793
tfarina42834112016-09-22 13:38:206794 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:016795 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]4ddaf2502008-10-23 18:26:196796
6797 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:016798 EXPECT_THAT(rv, IsError(ERR_RESPONSE_HEADERS_TOO_BIG));
[email protected]4ddaf2502008-10-23 18:26:196799}
[email protected]f4e426b2008-11-05 00:24:496800
6801// Make sure that we don't try to reuse a TCPClientSocket when failing to
6802// establish tunnel.
6803// http://code.google.com/p/chromium/issues/detail?id=3772
bncd16676a2016-07-20 16:23:016804TEST_F(HttpNetworkTransactionTest, DontRecycleTransportSocketForSSLTunnel) {
[email protected]cb9bf6ca2011-01-28 13:15:276805 HttpRequestInfo request;
6806 request.method = "GET";
bncce36dca22015-04-21 22:11:236807 request.url = GURL("https://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:276808
[email protected]f4e426b2008-11-05 00:24:496809 // Configure against proxy server "myproxy:70".
Lily Houghton8c2f97d2018-01-22 05:06:596810 session_deps_.proxy_resolution_service =
6811 ProxyResolutionService::CreateFixed("myproxy:70");
[email protected]db8f44c2008-12-13 04:52:016812
danakj1fd259a02016-04-16 03:17:096813 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]f4e426b2008-11-05 00:24:496814
bnc87dcefc2017-05-25 12:47:586815 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:196816 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]f4e426b2008-11-05 00:24:496817
[email protected]f4e426b2008-11-05 00:24:496818 // Since we have proxy, should try to establish tunnel.
6819 MockWrite data_writes1[] = {
rsleevidb16bb02015-11-12 23:47:176820 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
6821 "Host: www.example.org:443\r\n"
6822 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]f4e426b2008-11-05 00:24:496823 };
6824
[email protected]77848d12008-11-14 00:00:226825 // The proxy responds to the connect with a 404, using a persistent
[email protected]f4e426b2008-11-05 00:24:496826 // connection. Usually a proxy would return 501 (not implemented),
6827 // or 200 (tunnel established).
6828 MockRead data_reads1[] = {
mmenked39192ee2015-12-09 00:57:236829 MockRead("HTTP/1.1 404 Not Found\r\n"),
6830 MockRead("Content-Length: 10\r\n\r\n"),
6831 MockRead(SYNCHRONOUS, ERR_UNEXPECTED),
[email protected]f4e426b2008-11-05 00:24:496832 };
6833
[email protected]31a2bfe2010-02-09 08:03:396834 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
6835 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:076836 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]f4e426b2008-11-05 00:24:496837
[email protected]49639fa2011-12-20 23:22:416838 TestCompletionCallback callback1;
[email protected]f4e426b2008-11-05 00:24:496839
tfarina42834112016-09-22 13:38:206840 int rv = trans->Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:016841 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]f4e426b2008-11-05 00:24:496842
6843 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:016844 EXPECT_THAT(rv, IsError(ERR_TUNNEL_CONNECTION_FAILED));
[email protected]f4e426b2008-11-05 00:24:496845
[email protected]b4404c02009-04-10 16:38:526846 // Empty the current queue. This is necessary because idle sockets are
6847 // added to the connection pool asynchronously with a PostTask.
fdoray92e35a72016-06-10 15:54:556848 base::RunLoop().RunUntilIdle();
[email protected]b4404c02009-04-10 16:38:526849
[email protected]f4e426b2008-11-05 00:24:496850 // We now check to make sure the TCPClientSocket was not added back to
6851 // the pool.
[email protected]90499482013-06-01 00:39:506852 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]f4e426b2008-11-05 00:24:496853 trans.reset();
fdoray92e35a72016-06-10 15:54:556854 base::RunLoop().RunUntilIdle();
[email protected]f4e426b2008-11-05 00:24:496855 // Make sure that the socket didn't get recycled after calling the destructor.
[email protected]90499482013-06-01 00:39:506856 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]f4e426b2008-11-05 00:24:496857}
[email protected]372d34a2008-11-05 21:30:516858
[email protected]1b157c02009-04-21 01:55:406859// Make sure that we recycle a socket after reading all of the response body.
bncd16676a2016-07-20 16:23:016860TEST_F(HttpNetworkTransactionTest, RecycleSocket) {
[email protected]1c773ea12009-04-28 19:58:426861 HttpRequestInfo request;
[email protected]1b157c02009-04-21 01:55:406862 request.method = "GET";
bncce36dca22015-04-21 22:11:236863 request.url = GURL("http://www.example.org/");
[email protected]1b157c02009-04-21 01:55:406864
danakj1fd259a02016-04-16 03:17:096865 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:276866
bnc691fda62016-08-12 00:43:166867 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:276868
[email protected]1b157c02009-04-21 01:55:406869 MockRead data_reads[] = {
6870 // A part of the response body is received with the response headers.
6871 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 11\r\n\r\nhel"),
6872 // The rest of the response body is received in two parts.
6873 MockRead("lo"),
6874 MockRead(" world"),
6875 MockRead("junk"), // Should not be read!!
[email protected]8ddf8322012-02-23 18:08:066876 MockRead(SYNCHRONOUS, OK),
[email protected]1b157c02009-04-21 01:55:406877 };
6878
[email protected]31a2bfe2010-02-09 08:03:396879 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:076880 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1b157c02009-04-21 01:55:406881
[email protected]49639fa2011-12-20 23:22:416882 TestCompletionCallback callback;
[email protected]1b157c02009-04-21 01:55:406883
tfarina42834112016-09-22 13:38:206884 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:016885 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]1b157c02009-04-21 01:55:406886
6887 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:016888 EXPECT_THAT(rv, IsOk());
[email protected]1b157c02009-04-21 01:55:406889
bnc691fda62016-08-12 00:43:166890 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:526891 ASSERT_TRUE(response);
[email protected]1b157c02009-04-21 01:55:406892
wezca1070932016-05-26 20:30:526893 EXPECT_TRUE(response->headers);
[email protected]1b157c02009-04-21 01:55:406894 std::string status_line = response->headers->GetStatusLine();
6895 EXPECT_EQ("HTTP/1.1 200 OK", status_line);
6896
[email protected]90499482013-06-01 00:39:506897 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]1b157c02009-04-21 01:55:406898
6899 std::string response_data;
bnc691fda62016-08-12 00:43:166900 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:016901 EXPECT_THAT(rv, IsOk());
[email protected]1b157c02009-04-21 01:55:406902 EXPECT_EQ("hello world", response_data);
6903
6904 // Empty the current queue. This is necessary because idle sockets are
6905 // added to the connection pool asynchronously with a PostTask.
fdoray92e35a72016-06-10 15:54:556906 base::RunLoop().RunUntilIdle();
[email protected]1b157c02009-04-21 01:55:406907
6908 // We now check to make sure the socket was added back to the pool.
[email protected]90499482013-06-01 00:39:506909 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]1b157c02009-04-21 01:55:406910}
6911
[email protected]76a505b2010-08-25 06:23:006912// Make sure that we recycle a SSL socket after reading all of the response
6913// body.
bncd16676a2016-07-20 16:23:016914TEST_F(HttpNetworkTransactionTest, RecycleSSLSocket) {
[email protected]76a505b2010-08-25 06:23:006915 HttpRequestInfo request;
6916 request.method = "GET";
bncce36dca22015-04-21 22:11:236917 request.url = GURL("https://www.example.org/");
[email protected]76a505b2010-08-25 06:23:006918
6919 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:236920 MockWrite(
6921 "GET / HTTP/1.1\r\n"
6922 "Host: www.example.org\r\n"
6923 "Connection: keep-alive\r\n\r\n"),
[email protected]76a505b2010-08-25 06:23:006924 };
6925
6926 MockRead data_reads[] = {
6927 MockRead("HTTP/1.1 200 OK\r\n"),
6928 MockRead("Content-Length: 11\r\n\r\n"),
6929 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:066930 MockRead(SYNCHRONOUS, OK),
[email protected]76a505b2010-08-25 06:23:006931 };
6932
[email protected]8ddf8322012-02-23 18:08:066933 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:076934 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]76a505b2010-08-25 06:23:006935
6936 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
6937 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:076938 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]76a505b2010-08-25 06:23:006939
[email protected]49639fa2011-12-20 23:22:416940 TestCompletionCallback callback;
[email protected]76a505b2010-08-25 06:23:006941
danakj1fd259a02016-04-16 03:17:096942 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:166943 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]76a505b2010-08-25 06:23:006944
tfarina42834112016-09-22 13:38:206945 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
[email protected]76a505b2010-08-25 06:23:006946
robpercival214763f2016-07-01 23:27:016947 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
6948 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]76a505b2010-08-25 06:23:006949
bnc691fda62016-08-12 00:43:166950 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:526951 ASSERT_TRUE(response);
6952 ASSERT_TRUE(response->headers);
[email protected]76a505b2010-08-25 06:23:006953 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
6954
[email protected]90499482013-06-01 00:39:506955 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]76a505b2010-08-25 06:23:006956
6957 std::string response_data;
bnc691fda62016-08-12 00:43:166958 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:016959 EXPECT_THAT(rv, IsOk());
[email protected]76a505b2010-08-25 06:23:006960 EXPECT_EQ("hello world", response_data);
6961
6962 // Empty the current queue. This is necessary because idle sockets are
6963 // added to the connection pool asynchronously with a PostTask.
fdoray92e35a72016-06-10 15:54:556964 base::RunLoop().RunUntilIdle();
[email protected]76a505b2010-08-25 06:23:006965
6966 // We now check to make sure the socket was added back to the pool.
[email protected]90499482013-06-01 00:39:506967 EXPECT_EQ(1, GetIdleSocketCountInSSLSocketPool(session.get()));
[email protected]76a505b2010-08-25 06:23:006968}
6969
6970// Grab a SSL socket, use it, and put it back into the pool. Then, reuse it
6971// from the pool and make sure that we recover okay.
bncd16676a2016-07-20 16:23:016972TEST_F(HttpNetworkTransactionTest, RecycleDeadSSLSocket) {
[email protected]76a505b2010-08-25 06:23:006973 HttpRequestInfo request;
6974 request.method = "GET";
bncce36dca22015-04-21 22:11:236975 request.url = GURL("https://www.example.org/");
[email protected]76a505b2010-08-25 06:23:006976
6977 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:236978 MockWrite(
6979 "GET / HTTP/1.1\r\n"
6980 "Host: www.example.org\r\n"
6981 "Connection: keep-alive\r\n\r\n"),
6982 MockWrite(
6983 "GET / HTTP/1.1\r\n"
6984 "Host: www.example.org\r\n"
6985 "Connection: keep-alive\r\n\r\n"),
[email protected]76a505b2010-08-25 06:23:006986 };
6987
6988 MockRead data_reads[] = {
mmenke911ee0222015-12-04 03:58:426989 MockRead("HTTP/1.1 200 OK\r\n"), MockRead("Content-Length: 11\r\n\r\n"),
6990 MockRead("hello world"), MockRead(ASYNC, ERR_CONNECTION_CLOSED)};
[email protected]76a505b2010-08-25 06:23:006991
[email protected]8ddf8322012-02-23 18:08:066992 SSLSocketDataProvider ssl(ASYNC, OK);
6993 SSLSocketDataProvider ssl2(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:076994 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
6995 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
[email protected]76a505b2010-08-25 06:23:006996
6997 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
6998 data_writes, arraysize(data_writes));
6999 StaticSocketDataProvider data2(data_reads, arraysize(data_reads),
7000 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:077001 session_deps_.socket_factory->AddSocketDataProvider(&data);
7002 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]76a505b2010-08-25 06:23:007003
[email protected]49639fa2011-12-20 23:22:417004 TestCompletionCallback callback;
[email protected]76a505b2010-08-25 06:23:007005
danakj1fd259a02016-04-16 03:17:097006 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc87dcefc2017-05-25 12:47:587007 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:197008 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]76a505b2010-08-25 06:23:007009
tfarina42834112016-09-22 13:38:207010 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
[email protected]76a505b2010-08-25 06:23:007011
robpercival214763f2016-07-01 23:27:017012 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
7013 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]76a505b2010-08-25 06:23:007014
7015 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:527016 ASSERT_TRUE(response);
7017 ASSERT_TRUE(response->headers);
[email protected]76a505b2010-08-25 06:23:007018 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
7019
[email protected]90499482013-06-01 00:39:507020 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]76a505b2010-08-25 06:23:007021
7022 std::string response_data;
7023 rv = ReadTransaction(trans.get(), &response_data);
robpercival214763f2016-07-01 23:27:017024 EXPECT_THAT(rv, IsOk());
[email protected]76a505b2010-08-25 06:23:007025 EXPECT_EQ("hello world", response_data);
7026
7027 // Empty the current queue. This is necessary because idle sockets are
7028 // added to the connection pool asynchronously with a PostTask.
fdoray92e35a72016-06-10 15:54:557029 base::RunLoop().RunUntilIdle();
[email protected]76a505b2010-08-25 06:23:007030
7031 // We now check to make sure the socket was added back to the pool.
[email protected]90499482013-06-01 00:39:507032 EXPECT_EQ(1, GetIdleSocketCountInSSLSocketPool(session.get()));
[email protected]76a505b2010-08-25 06:23:007033
7034 // Now start the second transaction, which should reuse the previous socket.
7035
bnc87dcefc2017-05-25 12:47:587036 trans =
Jeremy Roman0579ed62017-08-29 15:56:197037 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]76a505b2010-08-25 06:23:007038
tfarina42834112016-09-22 13:38:207039 rv = trans->Start(&request, callback.callback(), NetLogWithSource());
[email protected]76a505b2010-08-25 06:23:007040
robpercival214763f2016-07-01 23:27:017041 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
7042 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]76a505b2010-08-25 06:23:007043
7044 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:527045 ASSERT_TRUE(response);
7046 ASSERT_TRUE(response->headers);
[email protected]76a505b2010-08-25 06:23:007047 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
7048
[email protected]90499482013-06-01 00:39:507049 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]76a505b2010-08-25 06:23:007050
7051 rv = ReadTransaction(trans.get(), &response_data);
robpercival214763f2016-07-01 23:27:017052 EXPECT_THAT(rv, IsOk());
[email protected]76a505b2010-08-25 06:23:007053 EXPECT_EQ("hello world", response_data);
7054
7055 // Empty the current queue. This is necessary because idle sockets are
7056 // added to the connection pool asynchronously with a PostTask.
fdoray92e35a72016-06-10 15:54:557057 base::RunLoop().RunUntilIdle();
[email protected]76a505b2010-08-25 06:23:007058
7059 // We now check to make sure the socket was added back to the pool.
[email protected]90499482013-06-01 00:39:507060 EXPECT_EQ(1, GetIdleSocketCountInSSLSocketPool(session.get()));
[email protected]76a505b2010-08-25 06:23:007061}
7062
maksim.sisov0adf8592016-07-15 06:25:567063// Grab a socket, use it, and put it back into the pool. Then, make
7064// low memory notification and ensure the socket pool is flushed.
bncd16676a2016-07-20 16:23:017065TEST_F(HttpNetworkTransactionTest, FlushSocketPoolOnLowMemoryNotifications) {
maksim.sisov0adf8592016-07-15 06:25:567066 HttpRequestInfo request;
7067 request.method = "GET";
7068 request.url = GURL("http://www.example.org/");
7069 request.load_flags = 0;
7070
7071 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
7072
bnc691fda62016-08-12 00:43:167073 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
maksim.sisov0adf8592016-07-15 06:25:567074
7075 MockRead data_reads[] = {
7076 // A part of the response body is received with the response headers.
7077 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 11\r\n\r\nhel"),
7078 // The rest of the response body is received in two parts.
7079 MockRead("lo"), MockRead(" world"),
7080 MockRead("junk"), // Should not be read!!
7081 MockRead(SYNCHRONOUS, OK),
7082 };
7083
7084 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
7085 session_deps_.socket_factory->AddSocketDataProvider(&data);
7086
7087 TestCompletionCallback callback;
7088
tfarina42834112016-09-22 13:38:207089 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
maksim.sisov0adf8592016-07-15 06:25:567090 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
7091
7092 EXPECT_THAT(callback.GetResult(rv), IsOk());
7093
bnc691fda62016-08-12 00:43:167094 const HttpResponseInfo* response = trans.GetResponseInfo();
maksim.sisov0adf8592016-07-15 06:25:567095 ASSERT_TRUE(response);
7096 EXPECT_TRUE(response->headers);
7097 std::string status_line = response->headers->GetStatusLine();
7098 EXPECT_EQ("HTTP/1.1 200 OK", status_line);
7099
7100 // Make memory critical notification and ensure the transaction still has been
7101 // operating right.
7102 base::MemoryPressureListener::NotifyMemoryPressure(
7103 base::MemoryPressureListener::MEMORY_PRESSURE_LEVEL_CRITICAL);
7104 base::RunLoop().RunUntilIdle();
7105
7106 // Socket should not be flushed as long as it is not idle.
7107 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
7108
7109 std::string response_data;
bnc691fda62016-08-12 00:43:167110 rv = ReadTransaction(&trans, &response_data);
maksim.sisov0adf8592016-07-15 06:25:567111 EXPECT_THAT(rv, IsOk());
7112 EXPECT_EQ("hello world", response_data);
7113
7114 // Empty the current queue. This is necessary because idle sockets are
7115 // added to the connection pool asynchronously with a PostTask.
7116 base::RunLoop().RunUntilIdle();
7117
7118 // We now check to make sure the socket was added back to the pool.
7119 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
7120
7121 // Idle sockets should be flushed now.
7122 base::MemoryPressureListener::NotifyMemoryPressure(
7123 base::MemoryPressureListener::MEMORY_PRESSURE_LEVEL_CRITICAL);
7124 base::RunLoop().RunUntilIdle();
7125
7126 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
7127}
7128
yucliu48f235d2018-01-11 00:59:557129// Disable idle socket closing on memory pressure.
7130// Grab a socket, use it, and put it back into the pool. Then, make
7131// low memory notification and ensure the socket pool is NOT flushed.
7132TEST_F(HttpNetworkTransactionTest, NoFlushSocketPoolOnLowMemoryNotifications) {
7133 HttpRequestInfo request;
7134 request.method = "GET";
7135 request.url = GURL("http://www.example.org/");
7136 request.load_flags = 0;
7137
7138 // Disable idle socket closing on memory pressure.
7139 session_deps_.disable_idle_sockets_close_on_memory_pressure = true;
7140 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
7141
7142 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
7143
7144 MockRead data_reads[] = {
7145 // A part of the response body is received with the response headers.
7146 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 11\r\n\r\nhel"),
7147 // The rest of the response body is received in two parts.
7148 MockRead("lo"), MockRead(" world"),
7149 MockRead("junk"), // Should not be read!!
7150 MockRead(SYNCHRONOUS, OK),
7151 };
7152
7153 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
7154 session_deps_.socket_factory->AddSocketDataProvider(&data);
7155
7156 TestCompletionCallback callback;
7157
7158 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
7159 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
7160
7161 EXPECT_THAT(callback.GetResult(rv), IsOk());
7162
7163 const HttpResponseInfo* response = trans.GetResponseInfo();
7164 ASSERT_TRUE(response);
7165 EXPECT_TRUE(response->headers);
7166 std::string status_line = response->headers->GetStatusLine();
7167 EXPECT_EQ("HTTP/1.1 200 OK", status_line);
7168
7169 // Make memory critical notification and ensure the transaction still has been
7170 // operating right.
7171 base::MemoryPressureListener::NotifyMemoryPressure(
7172 base::MemoryPressureListener::MEMORY_PRESSURE_LEVEL_CRITICAL);
7173 base::RunLoop().RunUntilIdle();
7174
7175 // Socket should not be flushed as long as it is not idle.
7176 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
7177
7178 std::string response_data;
7179 rv = ReadTransaction(&trans, &response_data);
7180 EXPECT_THAT(rv, IsOk());
7181 EXPECT_EQ("hello world", response_data);
7182
7183 // Empty the current queue. This is necessary because idle sockets are
7184 // added to the connection pool asynchronously with a PostTask.
7185 base::RunLoop().RunUntilIdle();
7186
7187 // We now check to make sure the socket was added back to the pool.
7188 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
7189
7190 // Idle sockets should NOT be flushed on moderate memory pressure.
7191 base::MemoryPressureListener::NotifyMemoryPressure(
7192 base::MemoryPressureListener::MEMORY_PRESSURE_LEVEL_MODERATE);
7193 base::RunLoop().RunUntilIdle();
7194
7195 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
7196
7197 // Idle sockets should NOT be flushed on critical memory pressure.
7198 base::MemoryPressureListener::NotifyMemoryPressure(
7199 base::MemoryPressureListener::MEMORY_PRESSURE_LEVEL_CRITICAL);
7200 base::RunLoop().RunUntilIdle();
7201
7202 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
7203}
7204
maksim.sisov0adf8592016-07-15 06:25:567205// Grab an SSL socket, use it, and put it back into the pool. Then, make
7206// low memory notification and ensure the socket pool is flushed.
bncd16676a2016-07-20 16:23:017207TEST_F(HttpNetworkTransactionTest, FlushSSLSocketPoolOnLowMemoryNotifications) {
maksim.sisov0adf8592016-07-15 06:25:567208 HttpRequestInfo request;
7209 request.method = "GET";
7210 request.url = GURL("https://www.example.org/");
7211 request.load_flags = 0;
7212
7213 MockWrite data_writes[] = {
7214 MockWrite("GET / HTTP/1.1\r\n"
7215 "Host: www.example.org\r\n"
7216 "Connection: keep-alive\r\n\r\n"),
7217 };
7218
7219 MockRead data_reads[] = {
7220 MockRead("HTTP/1.1 200 OK\r\n"), MockRead("Content-Length: 11\r\n\r\n"),
7221 MockRead("hello world"), MockRead(ASYNC, ERR_CONNECTION_CLOSED)};
7222
7223 SSLSocketDataProvider ssl(ASYNC, OK);
7224 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
7225
7226 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
7227 arraysize(data_writes));
7228 session_deps_.socket_factory->AddSocketDataProvider(&data);
7229
7230 TestCompletionCallback callback;
7231
7232 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:167233 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
maksim.sisov0adf8592016-07-15 06:25:567234
7235 EXPECT_EQ(0, GetIdleSocketCountInSSLSocketPool(session.get()));
tfarina42834112016-09-22 13:38:207236 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
maksim.sisov0adf8592016-07-15 06:25:567237
7238 EXPECT_THAT(callback.GetResult(rv), IsOk());
7239
bnc691fda62016-08-12 00:43:167240 const HttpResponseInfo* response = trans.GetResponseInfo();
maksim.sisov0adf8592016-07-15 06:25:567241 ASSERT_TRUE(response);
7242 ASSERT_TRUE(response->headers);
7243 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
7244
7245 // Make memory critical notification and ensure the transaction still has been
7246 // operating right.
7247 base::MemoryPressureListener::NotifyMemoryPressure(
7248 base::MemoryPressureListener::MEMORY_PRESSURE_LEVEL_CRITICAL);
7249 base::RunLoop().RunUntilIdle();
7250
7251 EXPECT_EQ(0, GetIdleSocketCountInSSLSocketPool(session.get()));
7252
7253 std::string response_data;
bnc691fda62016-08-12 00:43:167254 rv = ReadTransaction(&trans, &response_data);
maksim.sisov0adf8592016-07-15 06:25:567255 EXPECT_THAT(rv, IsOk());
7256 EXPECT_EQ("hello world", response_data);
7257
7258 // Empty the current queue. This is necessary because idle sockets are
7259 // added to the connection pool asynchronously with a PostTask.
7260 base::RunLoop().RunUntilIdle();
7261
7262 // We now check to make sure the socket was added back to the pool.
7263 EXPECT_EQ(1, GetIdleSocketCountInSSLSocketPool(session.get()));
7264
7265 // Make memory notification once again and ensure idle socket is closed.
7266 base::MemoryPressureListener::NotifyMemoryPressure(
7267 base::MemoryPressureListener::MEMORY_PRESSURE_LEVEL_CRITICAL);
7268 base::RunLoop().RunUntilIdle();
7269
7270 EXPECT_EQ(0, GetIdleSocketCountInSSLSocketPool(session.get()));
7271}
7272
[email protected]b4404c02009-04-10 16:38:527273// Make sure that we recycle a socket after a zero-length response.
7274// http://crbug.com/9880
bncd16676a2016-07-20 16:23:017275TEST_F(HttpNetworkTransactionTest, RecycleSocketAfterZeroContentLength) {
[email protected]1c773ea12009-04-28 19:58:427276 HttpRequestInfo request;
[email protected]b4404c02009-04-10 16:38:527277 request.method = "GET";
bncce36dca22015-04-21 22:11:237278 request.url = GURL(
7279 "http://www.example.org/csi?v=3&s=web&action=&"
7280 "tran=undefined&ei=mAXcSeegAo-SMurloeUN&"
7281 "e=17259,18167,19592,19773,19981,20133,20173,20233&"
7282 "rt=prt.2642,ol.2649,xjs.2951");
[email protected]b4404c02009-04-10 16:38:527283
danakj1fd259a02016-04-16 03:17:097284 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:277285
[email protected]b4404c02009-04-10 16:38:527286 MockRead data_reads[] = {
7287 MockRead("HTTP/1.1 204 No Content\r\n"
7288 "Content-Length: 0\r\n"
7289 "Content-Type: text/html\r\n\r\n"),
7290 MockRead("junk"), // Should not be read!!
[email protected]8ddf8322012-02-23 18:08:067291 MockRead(SYNCHRONOUS, OK),
[email protected]b4404c02009-04-10 16:38:527292 };
7293
[email protected]31a2bfe2010-02-09 08:03:397294 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:077295 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]b4404c02009-04-10 16:38:527296
mmenkecc2298e2015-12-07 18:20:187297 // Transaction must be created after the MockReads, so it's destroyed before
7298 // them.
bnc691fda62016-08-12 00:43:167299 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
mmenkecc2298e2015-12-07 18:20:187300
[email protected]49639fa2011-12-20 23:22:417301 TestCompletionCallback callback;
[email protected]b4404c02009-04-10 16:38:527302
tfarina42834112016-09-22 13:38:207303 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:017304 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]b4404c02009-04-10 16:38:527305
7306 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:017307 EXPECT_THAT(rv, IsOk());
[email protected]b4404c02009-04-10 16:38:527308
bnc691fda62016-08-12 00:43:167309 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:527310 ASSERT_TRUE(response);
[email protected]b4404c02009-04-10 16:38:527311
wezca1070932016-05-26 20:30:527312 EXPECT_TRUE(response->headers);
[email protected]b4404c02009-04-10 16:38:527313 std::string status_line = response->headers->GetStatusLine();
7314 EXPECT_EQ("HTTP/1.1 204 No Content", status_line);
7315
[email protected]90499482013-06-01 00:39:507316 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]b4404c02009-04-10 16:38:527317
7318 std::string response_data;
bnc691fda62016-08-12 00:43:167319 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:017320 EXPECT_THAT(rv, IsOk());
[email protected]b4404c02009-04-10 16:38:527321 EXPECT_EQ("", response_data);
7322
7323 // Empty the current queue. This is necessary because idle sockets are
7324 // added to the connection pool asynchronously with a PostTask.
fdoray92e35a72016-06-10 15:54:557325 base::RunLoop().RunUntilIdle();
[email protected]b4404c02009-04-10 16:38:527326
7327 // We now check to make sure the socket was added back to the pool.
[email protected]90499482013-06-01 00:39:507328 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]b4404c02009-04-10 16:38:527329}
7330
bncd16676a2016-07-20 16:23:017331TEST_F(HttpNetworkTransactionTest, ResendRequestOnWriteBodyError) {
danakj1fd259a02016-04-16 03:17:097332 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:227333 element_readers.push_back(
Jeremy Roman0579ed62017-08-29 15:56:197334 std::make_unique<UploadBytesElementReader>("foo", 3));
olli.raula6df48b2a2015-11-26 07:40:227335 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]329b68b2012-11-14 17:54:277336
[email protected]1c773ea12009-04-28 19:58:427337 HttpRequestInfo request[2];
[email protected]372d34a2008-11-05 21:30:517338 // Transaction 1: a GET request that succeeds. The socket is recycled
7339 // after use.
7340 request[0].method = "GET";
7341 request[0].url = GURL("http://www.google.com/");
7342 request[0].load_flags = 0;
7343 // Transaction 2: a POST request. Reuses the socket kept alive from
7344 // transaction 1. The first attempts fails when writing the POST data.
7345 // This causes the transaction to retry with a new socket. The second
7346 // attempt succeeds.
7347 request[1].method = "POST";
7348 request[1].url = GURL("http://www.google.com/login.cgi");
[email protected]329b68b2012-11-14 17:54:277349 request[1].upload_data_stream = &upload_data_stream;
[email protected]372d34a2008-11-05 21:30:517350 request[1].load_flags = 0;
7351
danakj1fd259a02016-04-16 03:17:097352 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]372d34a2008-11-05 21:30:517353
7354 // The first socket is used for transaction 1 and the first attempt of
7355 // transaction 2.
7356
7357 // The response of transaction 1.
7358 MockRead data_reads1[] = {
7359 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 11\r\n\r\n"),
7360 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:067361 MockRead(SYNCHRONOUS, OK),
[email protected]372d34a2008-11-05 21:30:517362 };
7363 // The mock write results of transaction 1 and the first attempt of
7364 // transaction 2.
7365 MockWrite data_writes1[] = {
[email protected]8ddf8322012-02-23 18:08:067366 MockWrite(SYNCHRONOUS, 64), // GET
7367 MockWrite(SYNCHRONOUS, 93), // POST
7368 MockWrite(SYNCHRONOUS, ERR_CONNECTION_ABORTED), // POST data
[email protected]372d34a2008-11-05 21:30:517369 };
[email protected]31a2bfe2010-02-09 08:03:397370 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
7371 data_writes1, arraysize(data_writes1));
[email protected]372d34a2008-11-05 21:30:517372
7373 // The second socket is used for the second attempt of transaction 2.
7374
7375 // The response of transaction 2.
7376 MockRead data_reads2[] = {
7377 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 7\r\n\r\n"),
7378 MockRead("welcome"),
[email protected]8ddf8322012-02-23 18:08:067379 MockRead(SYNCHRONOUS, OK),
[email protected]372d34a2008-11-05 21:30:517380 };
7381 // The mock write results of the second attempt of transaction 2.
7382 MockWrite data_writes2[] = {
[email protected]8ddf8322012-02-23 18:08:067383 MockWrite(SYNCHRONOUS, 93), // POST
7384 MockWrite(SYNCHRONOUS, 3), // POST data
[email protected]372d34a2008-11-05 21:30:517385 };
[email protected]31a2bfe2010-02-09 08:03:397386 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
7387 data_writes2, arraysize(data_writes2));
[email protected]372d34a2008-11-05 21:30:517388
[email protected]bb88e1d32013-05-03 23:11:077389 session_deps_.socket_factory->AddSocketDataProvider(&data1);
7390 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]372d34a2008-11-05 21:30:517391
thestig9d3bb0c2015-01-24 00:49:517392 const char* const kExpectedResponseData[] = {
[email protected]372d34a2008-11-05 21:30:517393 "hello world", "welcome"
7394 };
7395
7396 for (int i = 0; i < 2; ++i) {
bnc691fda62016-08-12 00:43:167397 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]372d34a2008-11-05 21:30:517398
[email protected]49639fa2011-12-20 23:22:417399 TestCompletionCallback callback;
[email protected]372d34a2008-11-05 21:30:517400
tfarina42834112016-09-22 13:38:207401 int rv = trans.Start(&request[i], callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:017402 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]372d34a2008-11-05 21:30:517403
7404 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:017405 EXPECT_THAT(rv, IsOk());
[email protected]372d34a2008-11-05 21:30:517406
bnc691fda62016-08-12 00:43:167407 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:527408 ASSERT_TRUE(response);
[email protected]372d34a2008-11-05 21:30:517409
wezca1070932016-05-26 20:30:527410 EXPECT_TRUE(response->headers);
[email protected]372d34a2008-11-05 21:30:517411 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
7412
7413 std::string response_data;
bnc691fda62016-08-12 00:43:167414 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:017415 EXPECT_THAT(rv, IsOk());
[email protected]372d34a2008-11-05 21:30:517416 EXPECT_EQ(kExpectedResponseData[i], response_data);
7417 }
7418}
[email protected]f9ee6b52008-11-08 06:46:237419
7420// Test the request-challenge-retry sequence for basic auth when there is
7421// an identity in the URL. The request should be sent as normal, but when
[email protected]2262e3a2012-05-22 16:08:167422// it fails the identity from the URL is used to answer the challenge.
bncd16676a2016-07-20 16:23:017423TEST_F(HttpNetworkTransactionTest, AuthIdentityInURL) {
[email protected]1c773ea12009-04-28 19:58:427424 HttpRequestInfo request;
[email protected]f9ee6b52008-11-08 06:46:237425 request.method = "GET";
bncce36dca22015-04-21 22:11:237426 request.url = GURL("http://foo:b@[email protected]/");
[email protected]7b08ba62012-02-10 20:19:417427 request.load_flags = LOAD_NORMAL;
[email protected]a97cca42009-08-14 01:00:297428
danakj1fd259a02016-04-16 03:17:097429 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:167430 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:277431
[email protected]a97cca42009-08-14 01:00:297432 // The password contains an escaped character -- for this test to pass it
7433 // will need to be unescaped by HttpNetworkTransaction.
7434 EXPECT_EQ("b%40r", request.url.password());
7435
[email protected]f9ee6b52008-11-08 06:46:237436 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:237437 MockWrite(
7438 "GET / HTTP/1.1\r\n"
7439 "Host: www.example.org\r\n"
7440 "Connection: keep-alive\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:237441 };
7442
7443 MockRead data_reads1[] = {
7444 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
7445 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
7446 MockRead("Content-Length: 10\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067447 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]f9ee6b52008-11-08 06:46:237448 };
7449
[email protected]2262e3a2012-05-22 16:08:167450 // After the challenge above, the transaction will be restarted using the
7451 // identity from the url (foo, b@r) to answer the challenge.
7452 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:237453 MockWrite(
7454 "GET / HTTP/1.1\r\n"
7455 "Host: www.example.org\r\n"
7456 "Connection: keep-alive\r\n"
7457 "Authorization: Basic Zm9vOmJAcg==\r\n\r\n"),
[email protected]2262e3a2012-05-22 16:08:167458 };
7459
7460 MockRead data_reads2[] = {
7461 MockRead("HTTP/1.0 200 OK\r\n"),
7462 MockRead("Content-Length: 100\r\n\r\n"),
7463 MockRead(SYNCHRONOUS, OK),
7464 };
7465
[email protected]31a2bfe2010-02-09 08:03:397466 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
7467 data_writes1, arraysize(data_writes1));
[email protected]2262e3a2012-05-22 16:08:167468 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
7469 data_writes2, arraysize(data_writes2));
[email protected]bb88e1d32013-05-03 23:11:077470 session_deps_.socket_factory->AddSocketDataProvider(&data1);
7471 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]f9ee6b52008-11-08 06:46:237472
[email protected]49639fa2011-12-20 23:22:417473 TestCompletionCallback callback1;
tfarina42834112016-09-22 13:38:207474 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:017475 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]f9ee6b52008-11-08 06:46:237476 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:017477 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:167478 EXPECT_TRUE(trans.IsReadyToRestartForAuth());
[email protected]2262e3a2012-05-22 16:08:167479
7480 TestCompletionCallback callback2;
bnc691fda62016-08-12 00:43:167481 rv = trans.RestartWithAuth(AuthCredentials(), callback2.callback());
robpercival214763f2016-07-01 23:27:017482 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2262e3a2012-05-22 16:08:167483 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:017484 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:167485 EXPECT_FALSE(trans.IsReadyToRestartForAuth());
[email protected]0757e7702009-03-27 04:00:227486
bnc691fda62016-08-12 00:43:167487 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:527488 ASSERT_TRUE(response);
[email protected]2262e3a2012-05-22 16:08:167489
7490 // There is no challenge info, since the identity in URL worked.
wezca1070932016-05-26 20:30:527491 EXPECT_FALSE(response->auth_challenge);
[email protected]2262e3a2012-05-22 16:08:167492
7493 EXPECT_EQ(100, response->headers->GetContentLength());
7494
7495 // Empty the current queue.
fdoray92e35a72016-06-10 15:54:557496 base::RunLoop().RunUntilIdle();
[email protected]2262e3a2012-05-22 16:08:167497}
7498
7499// Test the request-challenge-retry sequence for basic auth when there is an
7500// incorrect identity in the URL. The identity from the URL should be used only
7501// once.
bncd16676a2016-07-20 16:23:017502TEST_F(HttpNetworkTransactionTest, WrongAuthIdentityInURL) {
[email protected]2262e3a2012-05-22 16:08:167503 HttpRequestInfo request;
7504 request.method = "GET";
7505 // Note: the URL has a username:password in it. The password "baz" is
7506 // wrong (should be "bar").
bncce36dca22015-04-21 22:11:237507 request.url = GURL("http://foo:[email protected]/");
[email protected]2262e3a2012-05-22 16:08:167508
7509 request.load_flags = LOAD_NORMAL;
7510
danakj1fd259a02016-04-16 03:17:097511 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:167512 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]2262e3a2012-05-22 16:08:167513
7514 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:237515 MockWrite(
7516 "GET / HTTP/1.1\r\n"
7517 "Host: www.example.org\r\n"
7518 "Connection: keep-alive\r\n\r\n"),
[email protected]2262e3a2012-05-22 16:08:167519 };
7520
7521 MockRead data_reads1[] = {
7522 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
7523 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
7524 MockRead("Content-Length: 10\r\n\r\n"),
7525 MockRead(SYNCHRONOUS, ERR_FAILED),
7526 };
7527
7528 // After the challenge above, the transaction will be restarted using the
7529 // identity from the url (foo, baz) to answer the challenge.
7530 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:237531 MockWrite(
7532 "GET / HTTP/1.1\r\n"
7533 "Host: www.example.org\r\n"
7534 "Connection: keep-alive\r\n"
7535 "Authorization: Basic Zm9vOmJheg==\r\n\r\n"),
[email protected]2262e3a2012-05-22 16:08:167536 };
7537
7538 MockRead data_reads2[] = {
7539 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
7540 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
7541 MockRead("Content-Length: 10\r\n\r\n"),
7542 MockRead(SYNCHRONOUS, ERR_FAILED),
7543 };
7544
7545 // After the challenge above, the transaction will be restarted using the
7546 // identity supplied by the user (foo, bar) to answer the challenge.
7547 MockWrite data_writes3[] = {
bncce36dca22015-04-21 22:11:237548 MockWrite(
7549 "GET / HTTP/1.1\r\n"
7550 "Host: www.example.org\r\n"
7551 "Connection: keep-alive\r\n"
7552 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]2262e3a2012-05-22 16:08:167553 };
7554
7555 MockRead data_reads3[] = {
7556 MockRead("HTTP/1.0 200 OK\r\n"),
7557 MockRead("Content-Length: 100\r\n\r\n"),
7558 MockRead(SYNCHRONOUS, OK),
7559 };
7560
7561 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
7562 data_writes1, arraysize(data_writes1));
7563 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
7564 data_writes2, arraysize(data_writes2));
7565 StaticSocketDataProvider data3(data_reads3, arraysize(data_reads3),
7566 data_writes3, arraysize(data_writes3));
[email protected]bb88e1d32013-05-03 23:11:077567 session_deps_.socket_factory->AddSocketDataProvider(&data1);
7568 session_deps_.socket_factory->AddSocketDataProvider(&data2);
7569 session_deps_.socket_factory->AddSocketDataProvider(&data3);
[email protected]2262e3a2012-05-22 16:08:167570
7571 TestCompletionCallback callback1;
7572
tfarina42834112016-09-22 13:38:207573 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:017574 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2262e3a2012-05-22 16:08:167575
7576 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:017577 EXPECT_THAT(rv, IsOk());
[email protected]2262e3a2012-05-22 16:08:167578
bnc691fda62016-08-12 00:43:167579 EXPECT_TRUE(trans.IsReadyToRestartForAuth());
[email protected]2262e3a2012-05-22 16:08:167580 TestCompletionCallback callback2;
bnc691fda62016-08-12 00:43:167581 rv = trans.RestartWithAuth(AuthCredentials(), callback2.callback());
robpercival214763f2016-07-01 23:27:017582 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2262e3a2012-05-22 16:08:167583 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:017584 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:167585 EXPECT_FALSE(trans.IsReadyToRestartForAuth());
[email protected]2262e3a2012-05-22 16:08:167586
bnc691fda62016-08-12 00:43:167587 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:527588 ASSERT_TRUE(response);
[email protected]2262e3a2012-05-22 16:08:167589 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
7590
7591 TestCompletionCallback callback3;
bnc691fda62016-08-12 00:43:167592 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar), callback3.callback());
robpercival214763f2016-07-01 23:27:017593 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2262e3a2012-05-22 16:08:167594 rv = callback3.WaitForResult();
robpercival214763f2016-07-01 23:27:017595 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:167596 EXPECT_FALSE(trans.IsReadyToRestartForAuth());
[email protected]2262e3a2012-05-22 16:08:167597
bnc691fda62016-08-12 00:43:167598 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:527599 ASSERT_TRUE(response);
[email protected]2262e3a2012-05-22 16:08:167600
7601 // There is no challenge info, since the identity worked.
wezca1070932016-05-26 20:30:527602 EXPECT_FALSE(response->auth_challenge);
[email protected]2262e3a2012-05-22 16:08:167603
7604 EXPECT_EQ(100, response->headers->GetContentLength());
7605
[email protected]ea9dc9a2009-09-05 00:43:327606 // Empty the current queue.
fdoray92e35a72016-06-10 15:54:557607 base::RunLoop().RunUntilIdle();
[email protected]ea9dc9a2009-09-05 00:43:327608}
7609
[email protected]2217aa22013-10-11 03:03:547610
7611// Test the request-challenge-retry sequence for basic auth when there is a
7612// correct identity in the URL, but its use is being suppressed. The identity
7613// from the URL should never be used.
bncd16676a2016-07-20 16:23:017614TEST_F(HttpNetworkTransactionTest, AuthIdentityInURLSuppressed) {
[email protected]2217aa22013-10-11 03:03:547615 HttpRequestInfo request;
7616 request.method = "GET";
bncce36dca22015-04-21 22:11:237617 request.url = GURL("http://foo:[email protected]/");
[email protected]2217aa22013-10-11 03:03:547618 request.load_flags = LOAD_DO_NOT_USE_EMBEDDED_IDENTITY;
7619
danakj1fd259a02016-04-16 03:17:097620 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:167621 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]2217aa22013-10-11 03:03:547622
7623 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:237624 MockWrite(
7625 "GET / HTTP/1.1\r\n"
7626 "Host: www.example.org\r\n"
7627 "Connection: keep-alive\r\n\r\n"),
[email protected]2217aa22013-10-11 03:03:547628 };
7629
7630 MockRead data_reads1[] = {
7631 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
7632 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
7633 MockRead("Content-Length: 10\r\n\r\n"),
7634 MockRead(SYNCHRONOUS, ERR_FAILED),
7635 };
7636
7637 // After the challenge above, the transaction will be restarted using the
7638 // identity supplied by the user, not the one in the URL, to answer the
7639 // challenge.
7640 MockWrite data_writes3[] = {
bncce36dca22015-04-21 22:11:237641 MockWrite(
7642 "GET / HTTP/1.1\r\n"
7643 "Host: www.example.org\r\n"
7644 "Connection: keep-alive\r\n"
7645 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]2217aa22013-10-11 03:03:547646 };
7647
7648 MockRead data_reads3[] = {
7649 MockRead("HTTP/1.0 200 OK\r\n"),
7650 MockRead("Content-Length: 100\r\n\r\n"),
7651 MockRead(SYNCHRONOUS, OK),
7652 };
7653
7654 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
7655 data_writes1, arraysize(data_writes1));
7656 StaticSocketDataProvider data3(data_reads3, arraysize(data_reads3),
7657 data_writes3, arraysize(data_writes3));
7658 session_deps_.socket_factory->AddSocketDataProvider(&data1);
7659 session_deps_.socket_factory->AddSocketDataProvider(&data3);
7660
7661 TestCompletionCallback callback1;
tfarina42834112016-09-22 13:38:207662 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:017663 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2217aa22013-10-11 03:03:547664 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:017665 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:167666 EXPECT_FALSE(trans.IsReadyToRestartForAuth());
[email protected]2217aa22013-10-11 03:03:547667
bnc691fda62016-08-12 00:43:167668 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:527669 ASSERT_TRUE(response);
[email protected]2217aa22013-10-11 03:03:547670 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
7671
7672 TestCompletionCallback callback3;
bnc691fda62016-08-12 00:43:167673 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar), callback3.callback());
robpercival214763f2016-07-01 23:27:017674 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2217aa22013-10-11 03:03:547675 rv = callback3.WaitForResult();
robpercival214763f2016-07-01 23:27:017676 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:167677 EXPECT_FALSE(trans.IsReadyToRestartForAuth());
[email protected]2217aa22013-10-11 03:03:547678
bnc691fda62016-08-12 00:43:167679 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:527680 ASSERT_TRUE(response);
[email protected]2217aa22013-10-11 03:03:547681
7682 // There is no challenge info, since the identity worked.
wezca1070932016-05-26 20:30:527683 EXPECT_FALSE(response->auth_challenge);
[email protected]2217aa22013-10-11 03:03:547684 EXPECT_EQ(100, response->headers->GetContentLength());
7685
7686 // Empty the current queue.
fdoray92e35a72016-06-10 15:54:557687 base::RunLoop().RunUntilIdle();
[email protected]2217aa22013-10-11 03:03:547688}
7689
[email protected]f9ee6b52008-11-08 06:46:237690// Test that previously tried username/passwords for a realm get re-used.
bncd16676a2016-07-20 16:23:017691TEST_F(HttpNetworkTransactionTest, BasicAuthCacheAndPreauth) {
danakj1fd259a02016-04-16 03:17:097692 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]f9ee6b52008-11-08 06:46:237693
7694 // Transaction 1: authenticate (foo, bar) on MyRealm1
7695 {
[email protected]1c773ea12009-04-28 19:58:427696 HttpRequestInfo request;
[email protected]f9ee6b52008-11-08 06:46:237697 request.method = "GET";
bncce36dca22015-04-21 22:11:237698 request.url = GURL("http://www.example.org/x/y/z");
[email protected]f9ee6b52008-11-08 06:46:237699
bnc691fda62016-08-12 00:43:167700 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:277701
[email protected]f9ee6b52008-11-08 06:46:237702 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:237703 MockWrite(
7704 "GET /x/y/z HTTP/1.1\r\n"
7705 "Host: www.example.org\r\n"
7706 "Connection: keep-alive\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:237707 };
7708
7709 MockRead data_reads1[] = {
7710 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
7711 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
7712 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067713 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]f9ee6b52008-11-08 06:46:237714 };
7715
7716 // Resend with authorization (username=foo, password=bar)
7717 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:237718 MockWrite(
7719 "GET /x/y/z HTTP/1.1\r\n"
7720 "Host: www.example.org\r\n"
7721 "Connection: keep-alive\r\n"
7722 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:237723 };
7724
7725 // Sever accepts the authorization.
7726 MockRead data_reads2[] = {
7727 MockRead("HTTP/1.0 200 OK\r\n"),
7728 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067729 MockRead(SYNCHRONOUS, OK),
[email protected]f9ee6b52008-11-08 06:46:237730 };
7731
[email protected]31a2bfe2010-02-09 08:03:397732 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
7733 data_writes1, arraysize(data_writes1));
7734 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
7735 data_writes2, arraysize(data_writes2));
[email protected]bb88e1d32013-05-03 23:11:077736 session_deps_.socket_factory->AddSocketDataProvider(&data1);
7737 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]f9ee6b52008-11-08 06:46:237738
[email protected]49639fa2011-12-20 23:22:417739 TestCompletionCallback callback1;
[email protected]f9ee6b52008-11-08 06:46:237740
tfarina42834112016-09-22 13:38:207741 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:017742 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]f9ee6b52008-11-08 06:46:237743
7744 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:017745 EXPECT_THAT(rv, IsOk());
[email protected]f9ee6b52008-11-08 06:46:237746
bnc691fda62016-08-12 00:43:167747 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:527748 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:047749 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]f9ee6b52008-11-08 06:46:237750
[email protected]49639fa2011-12-20 23:22:417751 TestCompletionCallback callback2;
[email protected]f9ee6b52008-11-08 06:46:237752
bnc691fda62016-08-12 00:43:167753 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar),
7754 callback2.callback());
robpercival214763f2016-07-01 23:27:017755 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]f9ee6b52008-11-08 06:46:237756
7757 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:017758 EXPECT_THAT(rv, IsOk());
[email protected]f9ee6b52008-11-08 06:46:237759
bnc691fda62016-08-12 00:43:167760 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:527761 ASSERT_TRUE(response);
7762 EXPECT_FALSE(response->auth_challenge);
[email protected]f9ee6b52008-11-08 06:46:237763 EXPECT_EQ(100, response->headers->GetContentLength());
7764 }
7765
7766 // ------------------------------------------------------------------------
7767
7768 // Transaction 2: authenticate (foo2, bar2) on MyRealm2
7769 {
[email protected]1c773ea12009-04-28 19:58:427770 HttpRequestInfo request;
[email protected]f9ee6b52008-11-08 06:46:237771 request.method = "GET";
7772 // Note that Transaction 1 was at /x/y/z, so this is in the same
7773 // protection space as MyRealm1.
bncce36dca22015-04-21 22:11:237774 request.url = GURL("http://www.example.org/x/y/a/b");
[email protected]f9ee6b52008-11-08 06:46:237775
bnc691fda62016-08-12 00:43:167776 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:277777
[email protected]f9ee6b52008-11-08 06:46:237778 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:237779 MockWrite(
7780 "GET /x/y/a/b HTTP/1.1\r\n"
7781 "Host: www.example.org\r\n"
7782 "Connection: keep-alive\r\n"
7783 // Send preemptive authorization for MyRealm1
7784 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:237785 };
7786
7787 // The server didn't like the preemptive authorization, and
7788 // challenges us for a different realm (MyRealm2).
7789 MockRead data_reads1[] = {
7790 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
7791 MockRead("WWW-Authenticate: Basic realm=\"MyRealm2\"\r\n"),
7792 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067793 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]f9ee6b52008-11-08 06:46:237794 };
7795
7796 // Resend with authorization for MyRealm2 (username=foo2, password=bar2)
7797 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:237798 MockWrite(
7799 "GET /x/y/a/b HTTP/1.1\r\n"
7800 "Host: www.example.org\r\n"
7801 "Connection: keep-alive\r\n"
7802 "Authorization: Basic Zm9vMjpiYXIy\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:237803 };
7804
7805 // Sever accepts the authorization.
7806 MockRead data_reads2[] = {
7807 MockRead("HTTP/1.0 200 OK\r\n"),
7808 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067809 MockRead(SYNCHRONOUS, OK),
[email protected]f9ee6b52008-11-08 06:46:237810 };
7811
[email protected]31a2bfe2010-02-09 08:03:397812 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
7813 data_writes1, arraysize(data_writes1));
7814 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
7815 data_writes2, arraysize(data_writes2));
[email protected]bb88e1d32013-05-03 23:11:077816 session_deps_.socket_factory->AddSocketDataProvider(&data1);
7817 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]f9ee6b52008-11-08 06:46:237818
[email protected]49639fa2011-12-20 23:22:417819 TestCompletionCallback callback1;
[email protected]f9ee6b52008-11-08 06:46:237820
tfarina42834112016-09-22 13:38:207821 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:017822 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]f9ee6b52008-11-08 06:46:237823
7824 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:017825 EXPECT_THAT(rv, IsOk());
[email protected]f9ee6b52008-11-08 06:46:237826
bnc691fda62016-08-12 00:43:167827 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:527828 ASSERT_TRUE(response);
7829 ASSERT_TRUE(response->auth_challenge);
[email protected]79cb5c12011-09-12 13:12:047830 EXPECT_FALSE(response->auth_challenge->is_proxy);
asanka098c0092016-06-16 20:18:437831 EXPECT_EQ("http://www.example.org",
7832 response->auth_challenge->challenger.Serialize());
[email protected]79cb5c12011-09-12 13:12:047833 EXPECT_EQ("MyRealm2", response->auth_challenge->realm);
aberentbba302d2015-12-03 10:20:197834 EXPECT_EQ(kBasicAuthScheme, response->auth_challenge->scheme);
[email protected]f9ee6b52008-11-08 06:46:237835
[email protected]49639fa2011-12-20 23:22:417836 TestCompletionCallback callback2;
[email protected]f9ee6b52008-11-08 06:46:237837
bnc691fda62016-08-12 00:43:167838 rv = trans.RestartWithAuth(AuthCredentials(kFoo2, kBar2),
7839 callback2.callback());
robpercival214763f2016-07-01 23:27:017840 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]f9ee6b52008-11-08 06:46:237841
7842 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:017843 EXPECT_THAT(rv, IsOk());
[email protected]f9ee6b52008-11-08 06:46:237844
bnc691fda62016-08-12 00:43:167845 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:527846 ASSERT_TRUE(response);
7847 EXPECT_FALSE(response->auth_challenge);
[email protected]f9ee6b52008-11-08 06:46:237848 EXPECT_EQ(100, response->headers->GetContentLength());
7849 }
7850
7851 // ------------------------------------------------------------------------
7852
7853 // Transaction 3: Resend a request in MyRealm's protection space --
7854 // succeed with preemptive authorization.
7855 {
[email protected]1c773ea12009-04-28 19:58:427856 HttpRequestInfo request;
[email protected]f9ee6b52008-11-08 06:46:237857 request.method = "GET";
bncce36dca22015-04-21 22:11:237858 request.url = GURL("http://www.example.org/x/y/z2");
[email protected]f9ee6b52008-11-08 06:46:237859
bnc691fda62016-08-12 00:43:167860 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:277861
[email protected]f9ee6b52008-11-08 06:46:237862 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:237863 MockWrite(
7864 "GET /x/y/z2 HTTP/1.1\r\n"
7865 "Host: www.example.org\r\n"
7866 "Connection: keep-alive\r\n"
7867 // The authorization for MyRealm1 gets sent preemptively
7868 // (since the url is in the same protection space)
7869 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:237870 };
7871
7872 // Sever accepts the preemptive authorization
7873 MockRead data_reads1[] = {
7874 MockRead("HTTP/1.0 200 OK\r\n"),
7875 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067876 MockRead(SYNCHRONOUS, OK),
[email protected]f9ee6b52008-11-08 06:46:237877 };
7878
[email protected]31a2bfe2010-02-09 08:03:397879 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
7880 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:077881 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]f9ee6b52008-11-08 06:46:237882
[email protected]49639fa2011-12-20 23:22:417883 TestCompletionCallback callback1;
[email protected]f9ee6b52008-11-08 06:46:237884
tfarina42834112016-09-22 13:38:207885 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:017886 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]f9ee6b52008-11-08 06:46:237887
7888 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:017889 EXPECT_THAT(rv, IsOk());
[email protected]f9ee6b52008-11-08 06:46:237890
bnc691fda62016-08-12 00:43:167891 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:527892 ASSERT_TRUE(response);
[email protected]f9ee6b52008-11-08 06:46:237893
wezca1070932016-05-26 20:30:527894 EXPECT_FALSE(response->auth_challenge);
[email protected]f9ee6b52008-11-08 06:46:237895 EXPECT_EQ(100, response->headers->GetContentLength());
7896 }
7897
7898 // ------------------------------------------------------------------------
7899
7900 // Transaction 4: request another URL in MyRealm (however the
7901 // url is not known to belong to the protection space, so no pre-auth).
7902 {
[email protected]1c773ea12009-04-28 19:58:427903 HttpRequestInfo request;
[email protected]f9ee6b52008-11-08 06:46:237904 request.method = "GET";
bncce36dca22015-04-21 22:11:237905 request.url = GURL("http://www.example.org/x/1");
[email protected]f9ee6b52008-11-08 06:46:237906
bnc691fda62016-08-12 00:43:167907 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:277908
[email protected]f9ee6b52008-11-08 06:46:237909 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:237910 MockWrite(
7911 "GET /x/1 HTTP/1.1\r\n"
7912 "Host: www.example.org\r\n"
7913 "Connection: keep-alive\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:237914 };
7915
7916 MockRead data_reads1[] = {
7917 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
7918 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
7919 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067920 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]f9ee6b52008-11-08 06:46:237921 };
7922
7923 // Resend with authorization from MyRealm's cache.
7924 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:237925 MockWrite(
7926 "GET /x/1 HTTP/1.1\r\n"
7927 "Host: www.example.org\r\n"
7928 "Connection: keep-alive\r\n"
7929 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:237930 };
7931
7932 // Sever accepts the authorization.
7933 MockRead data_reads2[] = {
7934 MockRead("HTTP/1.0 200 OK\r\n"),
7935 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067936 MockRead(SYNCHRONOUS, OK),
[email protected]f9ee6b52008-11-08 06:46:237937 };
7938
[email protected]31a2bfe2010-02-09 08:03:397939 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
7940 data_writes1, arraysize(data_writes1));
7941 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
7942 data_writes2, arraysize(data_writes2));
[email protected]bb88e1d32013-05-03 23:11:077943 session_deps_.socket_factory->AddSocketDataProvider(&data1);
7944 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]f9ee6b52008-11-08 06:46:237945
[email protected]49639fa2011-12-20 23:22:417946 TestCompletionCallback callback1;
[email protected]f9ee6b52008-11-08 06:46:237947
tfarina42834112016-09-22 13:38:207948 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:017949 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]f9ee6b52008-11-08 06:46:237950
7951 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:017952 EXPECT_THAT(rv, IsOk());
[email protected]f9ee6b52008-11-08 06:46:237953
bnc691fda62016-08-12 00:43:167954 EXPECT_TRUE(trans.IsReadyToRestartForAuth());
[email protected]49639fa2011-12-20 23:22:417955 TestCompletionCallback callback2;
bnc691fda62016-08-12 00:43:167956 rv = trans.RestartWithAuth(AuthCredentials(), callback2.callback());
robpercival214763f2016-07-01 23:27:017957 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]0757e7702009-03-27 04:00:227958 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:017959 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:167960 EXPECT_FALSE(trans.IsReadyToRestartForAuth());
[email protected]0757e7702009-03-27 04:00:227961
bnc691fda62016-08-12 00:43:167962 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:527963 ASSERT_TRUE(response);
7964 EXPECT_FALSE(response->auth_challenge);
[email protected]f9ee6b52008-11-08 06:46:237965 EXPECT_EQ(100, response->headers->GetContentLength());
7966 }
7967
7968 // ------------------------------------------------------------------------
7969
7970 // Transaction 5: request a URL in MyRealm, but the server rejects the
7971 // cached identity. Should invalidate and re-prompt.
7972 {
[email protected]1c773ea12009-04-28 19:58:427973 HttpRequestInfo request;
[email protected]f9ee6b52008-11-08 06:46:237974 request.method = "GET";
bncce36dca22015-04-21 22:11:237975 request.url = GURL("http://www.example.org/p/q/t");
[email protected]f9ee6b52008-11-08 06:46:237976
bnc691fda62016-08-12 00:43:167977 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:277978
[email protected]f9ee6b52008-11-08 06:46:237979 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:237980 MockWrite(
7981 "GET /p/q/t HTTP/1.1\r\n"
7982 "Host: www.example.org\r\n"
7983 "Connection: keep-alive\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:237984 };
7985
7986 MockRead data_reads1[] = {
7987 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
7988 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
7989 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067990 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]f9ee6b52008-11-08 06:46:237991 };
7992
7993 // Resend with authorization from cache for MyRealm.
7994 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:237995 MockWrite(
7996 "GET /p/q/t HTTP/1.1\r\n"
7997 "Host: www.example.org\r\n"
7998 "Connection: keep-alive\r\n"
7999 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:238000 };
8001
8002 // Sever rejects the authorization.
8003 MockRead data_reads2[] = {
8004 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
8005 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
8006 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:068007 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]f9ee6b52008-11-08 06:46:238008 };
8009
8010 // At this point we should prompt for new credentials for MyRealm.
8011 // Restart with username=foo3, password=foo4.
8012 MockWrite data_writes3[] = {
bncce36dca22015-04-21 22:11:238013 MockWrite(
8014 "GET /p/q/t HTTP/1.1\r\n"
8015 "Host: www.example.org\r\n"
8016 "Connection: keep-alive\r\n"
8017 "Authorization: Basic Zm9vMzpiYXIz\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:238018 };
8019
8020 // Sever accepts the authorization.
8021 MockRead data_reads3[] = {
8022 MockRead("HTTP/1.0 200 OK\r\n"),
8023 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:068024 MockRead(SYNCHRONOUS, OK),
[email protected]f9ee6b52008-11-08 06:46:238025 };
8026
[email protected]31a2bfe2010-02-09 08:03:398027 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
8028 data_writes1, arraysize(data_writes1));
8029 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
8030 data_writes2, arraysize(data_writes2));
8031 StaticSocketDataProvider data3(data_reads3, arraysize(data_reads3),
8032 data_writes3, arraysize(data_writes3));
[email protected]bb88e1d32013-05-03 23:11:078033 session_deps_.socket_factory->AddSocketDataProvider(&data1);
8034 session_deps_.socket_factory->AddSocketDataProvider(&data2);
8035 session_deps_.socket_factory->AddSocketDataProvider(&data3);
[email protected]f9ee6b52008-11-08 06:46:238036
[email protected]49639fa2011-12-20 23:22:418037 TestCompletionCallback callback1;
[email protected]f9ee6b52008-11-08 06:46:238038
tfarina42834112016-09-22 13:38:208039 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:018040 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]f9ee6b52008-11-08 06:46:238041
8042 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:018043 EXPECT_THAT(rv, IsOk());
[email protected]f9ee6b52008-11-08 06:46:238044
bnc691fda62016-08-12 00:43:168045 EXPECT_TRUE(trans.IsReadyToRestartForAuth());
[email protected]49639fa2011-12-20 23:22:418046 TestCompletionCallback callback2;
bnc691fda62016-08-12 00:43:168047 rv = trans.RestartWithAuth(AuthCredentials(), callback2.callback());
robpercival214763f2016-07-01 23:27:018048 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]0757e7702009-03-27 04:00:228049 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:018050 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:168051 EXPECT_FALSE(trans.IsReadyToRestartForAuth());
[email protected]0757e7702009-03-27 04:00:228052
bnc691fda62016-08-12 00:43:168053 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:528054 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:048055 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]f9ee6b52008-11-08 06:46:238056
[email protected]49639fa2011-12-20 23:22:418057 TestCompletionCallback callback3;
[email protected]f9ee6b52008-11-08 06:46:238058
bnc691fda62016-08-12 00:43:168059 rv = trans.RestartWithAuth(AuthCredentials(kFoo3, kBar3),
8060 callback3.callback());
robpercival214763f2016-07-01 23:27:018061 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]f9ee6b52008-11-08 06:46:238062
[email protected]0757e7702009-03-27 04:00:228063 rv = callback3.WaitForResult();
robpercival214763f2016-07-01 23:27:018064 EXPECT_THAT(rv, IsOk());
[email protected]f9ee6b52008-11-08 06:46:238065
bnc691fda62016-08-12 00:43:168066 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:528067 ASSERT_TRUE(response);
8068 EXPECT_FALSE(response->auth_challenge);
[email protected]f9ee6b52008-11-08 06:46:238069 EXPECT_EQ(100, response->headers->GetContentLength());
8070 }
8071}
[email protected]89ceba9a2009-03-21 03:46:068072
[email protected]3c32c5f2010-05-18 15:18:128073// Tests that nonce count increments when multiple auth attempts
8074// are started with the same nonce.
bncd16676a2016-07-20 16:23:018075TEST_F(HttpNetworkTransactionTest, DigestPreAuthNonceCount) {
[email protected]54fea2562010-11-17 14:40:448076 HttpAuthHandlerDigest::Factory* digest_factory =
8077 new HttpAuthHandlerDigest::Factory();
8078 HttpAuthHandlerDigest::FixedNonceGenerator* nonce_generator =
8079 new HttpAuthHandlerDigest::FixedNonceGenerator("0123456789abcdef");
8080 digest_factory->set_nonce_generator(nonce_generator);
[email protected]bb88e1d32013-05-03 23:11:078081 session_deps_.http_auth_handler_factory.reset(digest_factory);
danakj1fd259a02016-04-16 03:17:098082 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]3c32c5f2010-05-18 15:18:128083
8084 // Transaction 1: authenticate (foo, bar) on MyRealm1
8085 {
[email protected]3c32c5f2010-05-18 15:18:128086 HttpRequestInfo request;
8087 request.method = "GET";
bncce36dca22015-04-21 22:11:238088 request.url = GURL("http://www.example.org/x/y/z");
[email protected]3c32c5f2010-05-18 15:18:128089
bnc691fda62016-08-12 00:43:168090 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:278091
[email protected]3c32c5f2010-05-18 15:18:128092 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:238093 MockWrite(
8094 "GET /x/y/z HTTP/1.1\r\n"
8095 "Host: www.example.org\r\n"
8096 "Connection: keep-alive\r\n\r\n"),
[email protected]3c32c5f2010-05-18 15:18:128097 };
8098
8099 MockRead data_reads1[] = {
8100 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
8101 MockRead("WWW-Authenticate: Digest realm=\"digestive\", nonce=\"OU812\", "
8102 "algorithm=MD5, qop=\"auth\"\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:068103 MockRead(SYNCHRONOUS, OK),
[email protected]3c32c5f2010-05-18 15:18:128104 };
8105
8106 // Resend with authorization (username=foo, password=bar)
8107 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:238108 MockWrite(
8109 "GET /x/y/z HTTP/1.1\r\n"
8110 "Host: www.example.org\r\n"
8111 "Connection: keep-alive\r\n"
8112 "Authorization: Digest username=\"foo\", realm=\"digestive\", "
8113 "nonce=\"OU812\", uri=\"/x/y/z\", algorithm=MD5, "
8114 "response=\"03ffbcd30add722589c1de345d7a927f\", qop=auth, "
8115 "nc=00000001, cnonce=\"0123456789abcdef\"\r\n\r\n"),
[email protected]3c32c5f2010-05-18 15:18:128116 };
8117
8118 // Sever accepts the authorization.
8119 MockRead data_reads2[] = {
zmo9528c9f42015-08-04 22:12:088120 MockRead("HTTP/1.0 200 OK\r\n"),
8121 MockRead(SYNCHRONOUS, OK),
[email protected]3c32c5f2010-05-18 15:18:128122 };
8123
8124 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
8125 data_writes1, arraysize(data_writes1));
8126 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
8127 data_writes2, arraysize(data_writes2));
[email protected]bb88e1d32013-05-03 23:11:078128 session_deps_.socket_factory->AddSocketDataProvider(&data1);
8129 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]3c32c5f2010-05-18 15:18:128130
[email protected]49639fa2011-12-20 23:22:418131 TestCompletionCallback callback1;
[email protected]3c32c5f2010-05-18 15:18:128132
tfarina42834112016-09-22 13:38:208133 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:018134 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]3c32c5f2010-05-18 15:18:128135
8136 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:018137 EXPECT_THAT(rv, IsOk());
[email protected]3c32c5f2010-05-18 15:18:128138
bnc691fda62016-08-12 00:43:168139 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:528140 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:048141 EXPECT_TRUE(CheckDigestServerAuth(response->auth_challenge.get()));
[email protected]3c32c5f2010-05-18 15:18:128142
[email protected]49639fa2011-12-20 23:22:418143 TestCompletionCallback callback2;
[email protected]3c32c5f2010-05-18 15:18:128144
bnc691fda62016-08-12 00:43:168145 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar),
8146 callback2.callback());
robpercival214763f2016-07-01 23:27:018147 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]3c32c5f2010-05-18 15:18:128148
8149 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:018150 EXPECT_THAT(rv, IsOk());
[email protected]3c32c5f2010-05-18 15:18:128151
bnc691fda62016-08-12 00:43:168152 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:528153 ASSERT_TRUE(response);
8154 EXPECT_FALSE(response->auth_challenge);
[email protected]3c32c5f2010-05-18 15:18:128155 }
8156
8157 // ------------------------------------------------------------------------
8158
8159 // Transaction 2: Request another resource in digestive's protection space.
8160 // This will preemptively add an Authorization header which should have an
8161 // "nc" value of 2 (as compared to 1 in the first use.
8162 {
[email protected]3c32c5f2010-05-18 15:18:128163 HttpRequestInfo request;
8164 request.method = "GET";
8165 // Note that Transaction 1 was at /x/y/z, so this is in the same
8166 // protection space as digest.
bncce36dca22015-04-21 22:11:238167 request.url = GURL("http://www.example.org/x/y/a/b");
[email protected]3c32c5f2010-05-18 15:18:128168
bnc691fda62016-08-12 00:43:168169 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:278170
[email protected]3c32c5f2010-05-18 15:18:128171 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:238172 MockWrite(
8173 "GET /x/y/a/b HTTP/1.1\r\n"
8174 "Host: www.example.org\r\n"
8175 "Connection: keep-alive\r\n"
8176 "Authorization: Digest username=\"foo\", realm=\"digestive\", "
8177 "nonce=\"OU812\", uri=\"/x/y/a/b\", algorithm=MD5, "
8178 "response=\"d6f9a2c07d1c5df7b89379dca1269b35\", qop=auth, "
8179 "nc=00000002, cnonce=\"0123456789abcdef\"\r\n\r\n"),
[email protected]3c32c5f2010-05-18 15:18:128180 };
8181
8182 // Sever accepts the authorization.
8183 MockRead data_reads1[] = {
8184 MockRead("HTTP/1.0 200 OK\r\n"),
8185 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:068186 MockRead(SYNCHRONOUS, OK),
[email protected]3c32c5f2010-05-18 15:18:128187 };
8188
8189 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
8190 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:078191 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]3c32c5f2010-05-18 15:18:128192
[email protected]49639fa2011-12-20 23:22:418193 TestCompletionCallback callback1;
[email protected]3c32c5f2010-05-18 15:18:128194
tfarina42834112016-09-22 13:38:208195 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:018196 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]3c32c5f2010-05-18 15:18:128197
8198 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:018199 EXPECT_THAT(rv, IsOk());
[email protected]3c32c5f2010-05-18 15:18:128200
bnc691fda62016-08-12 00:43:168201 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:528202 ASSERT_TRUE(response);
8203 EXPECT_FALSE(response->auth_challenge);
[email protected]3c32c5f2010-05-18 15:18:128204 }
8205}
8206
[email protected]89ceba9a2009-03-21 03:46:068207// Test the ResetStateForRestart() private method.
bncd16676a2016-07-20 16:23:018208TEST_F(HttpNetworkTransactionTest, ResetStateForRestart) {
[email protected]89ceba9a2009-03-21 03:46:068209 // Create a transaction (the dependencies aren't important).
danakj1fd259a02016-04-16 03:17:098210 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:168211 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]89ceba9a2009-03-21 03:46:068212
8213 // Setup some state (which we expect ResetStateForRestart() will clear).
bnc691fda62016-08-12 00:43:168214 trans.read_buf_ = new IOBuffer(15);
8215 trans.read_buf_len_ = 15;
8216 trans.request_headers_.SetHeader("Authorization", "NTLM");
[email protected]89ceba9a2009-03-21 03:46:068217
8218 // Setup state in response_
bnc691fda62016-08-12 00:43:168219 HttpResponseInfo* response = &trans.response_;
[email protected]0877e3d2009-10-17 22:29:578220 response->auth_challenge = new AuthChallengeInfo();
[email protected]70d66502011-09-23 00:55:088221 response->ssl_info.cert_status = static_cast<CertStatus>(-1); // Nonsensical.
[email protected]0877e3d2009-10-17 22:29:578222 response->response_time = base::Time::Now();
8223 response->was_cached = true; // (Wouldn't ever actually be true...)
[email protected]89ceba9a2009-03-21 03:46:068224
8225 { // Setup state for response_.vary_data
8226 HttpRequestInfo request;
8227 std::string temp("HTTP/1.1 200 OK\nVary: foo, bar\n\n");
8228 std::replace(temp.begin(), temp.end(), '\n', '\0');
[email protected]ad8e04a2010-11-01 04:16:278229 scoped_refptr<HttpResponseHeaders> headers(new HttpResponseHeaders(temp));
[email protected]8c76ae22010-04-20 22:15:438230 request.extra_headers.SetHeader("Foo", "1");
8231 request.extra_headers.SetHeader("bar", "23");
[email protected]90499482013-06-01 00:39:508232 EXPECT_TRUE(response->vary_data.Init(request, *headers.get()));
[email protected]89ceba9a2009-03-21 03:46:068233 }
8234
8235 // Cause the above state to be reset.
bnc691fda62016-08-12 00:43:168236 trans.ResetStateForRestart();
[email protected]89ceba9a2009-03-21 03:46:068237
8238 // Verify that the state that needed to be reset, has been reset.
bnc691fda62016-08-12 00:43:168239 EXPECT_FALSE(trans.read_buf_);
8240 EXPECT_EQ(0, trans.read_buf_len_);
8241 EXPECT_TRUE(trans.request_headers_.IsEmpty());
wezca1070932016-05-26 20:30:528242 EXPECT_FALSE(response->auth_challenge);
8243 EXPECT_FALSE(response->headers);
[email protected]34f40942010-10-04 00:34:048244 EXPECT_FALSE(response->was_cached);
[email protected]70d66502011-09-23 00:55:088245 EXPECT_EQ(0U, response->ssl_info.cert_status);
[email protected]0877e3d2009-10-17 22:29:578246 EXPECT_FALSE(response->vary_data.is_valid());
[email protected]89ceba9a2009-03-21 03:46:068247}
8248
[email protected]bacff652009-03-31 17:50:338249// Test HTTPS connections to a site with a bad certificate
bncd16676a2016-07-20 16:23:018250TEST_F(HttpNetworkTransactionTest, HTTPSBadCertificate) {
[email protected]bacff652009-03-31 17:50:338251 HttpRequestInfo request;
8252 request.method = "GET";
bncce36dca22015-04-21 22:11:238253 request.url = GURL("https://www.example.org/");
[email protected]bacff652009-03-31 17:50:338254
danakj1fd259a02016-04-16 03:17:098255 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:168256 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:278257
[email protected]bacff652009-03-31 17:50:338258 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:238259 MockWrite(
8260 "GET / HTTP/1.1\r\n"
8261 "Host: www.example.org\r\n"
8262 "Connection: keep-alive\r\n\r\n"),
[email protected]bacff652009-03-31 17:50:338263 };
8264
8265 MockRead data_reads[] = {
8266 MockRead("HTTP/1.0 200 OK\r\n"),
8267 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
8268 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:068269 MockRead(SYNCHRONOUS, OK),
[email protected]bacff652009-03-31 17:50:338270 };
8271
[email protected]5ecc992a42009-11-11 01:41:598272 StaticSocketDataProvider ssl_bad_certificate;
[email protected]31a2bfe2010-02-09 08:03:398273 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
8274 data_writes, arraysize(data_writes));
[email protected]8ddf8322012-02-23 18:08:068275 SSLSocketDataProvider ssl_bad(ASYNC, ERR_CERT_AUTHORITY_INVALID);
8276 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bacff652009-03-31 17:50:338277
[email protected]bb88e1d32013-05-03 23:11:078278 session_deps_.socket_factory->AddSocketDataProvider(&ssl_bad_certificate);
8279 session_deps_.socket_factory->AddSocketDataProvider(&data);
8280 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_bad);
8281 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]bacff652009-03-31 17:50:338282
[email protected]49639fa2011-12-20 23:22:418283 TestCompletionCallback callback;
[email protected]bacff652009-03-31 17:50:338284
tfarina42834112016-09-22 13:38:208285 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:018286 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]bacff652009-03-31 17:50:338287
8288 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:018289 EXPECT_THAT(rv, IsError(ERR_CERT_AUTHORITY_INVALID));
[email protected]bacff652009-03-31 17:50:338290
bnc691fda62016-08-12 00:43:168291 rv = trans.RestartIgnoringLastError(callback.callback());
robpercival214763f2016-07-01 23:27:018292 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]bacff652009-03-31 17:50:338293
8294 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:018295 EXPECT_THAT(rv, IsOk());
[email protected]bacff652009-03-31 17:50:338296
bnc691fda62016-08-12 00:43:168297 const HttpResponseInfo* response = trans.GetResponseInfo();
[email protected]bacff652009-03-31 17:50:338298
wezca1070932016-05-26 20:30:528299 ASSERT_TRUE(response);
[email protected]bacff652009-03-31 17:50:338300 EXPECT_EQ(100, response->headers->GetContentLength());
8301}
8302
8303// Test HTTPS connections to a site with a bad certificate, going through a
8304// proxy
bncd16676a2016-07-20 16:23:018305TEST_F(HttpNetworkTransactionTest, HTTPSBadCertificateViaProxy) {
Lily Houghton8c2f97d2018-01-22 05:06:598306 session_deps_.proxy_resolution_service =
8307 ProxyResolutionService::CreateFixed("myproxy:70");
[email protected]bacff652009-03-31 17:50:338308
8309 HttpRequestInfo request;
8310 request.method = "GET";
bncce36dca22015-04-21 22:11:238311 request.url = GURL("https://www.example.org/");
[email protected]bacff652009-03-31 17:50:338312
8313 MockWrite proxy_writes[] = {
rsleevidb16bb02015-11-12 23:47:178314 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
8315 "Host: www.example.org:443\r\n"
8316 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]bacff652009-03-31 17:50:338317 };
8318
8319 MockRead proxy_reads[] = {
8320 MockRead("HTTP/1.0 200 Connected\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:068321 MockRead(SYNCHRONOUS, OK)
[email protected]bacff652009-03-31 17:50:338322 };
8323
8324 MockWrite data_writes[] = {
rsleevidb16bb02015-11-12 23:47:178325 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
8326 "Host: www.example.org:443\r\n"
8327 "Proxy-Connection: keep-alive\r\n\r\n"),
8328 MockWrite("GET / HTTP/1.1\r\n"
8329 "Host: www.example.org\r\n"
8330 "Connection: keep-alive\r\n\r\n"),
[email protected]bacff652009-03-31 17:50:338331 };
8332
8333 MockRead data_reads[] = {
8334 MockRead("HTTP/1.0 200 Connected\r\n\r\n"),
8335 MockRead("HTTP/1.0 200 OK\r\n"),
8336 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
8337 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:068338 MockRead(SYNCHRONOUS, OK),
[email protected]bacff652009-03-31 17:50:338339 };
8340
[email protected]31a2bfe2010-02-09 08:03:398341 StaticSocketDataProvider ssl_bad_certificate(
8342 proxy_reads, arraysize(proxy_reads),
8343 proxy_writes, arraysize(proxy_writes));
8344 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
8345 data_writes, arraysize(data_writes));
[email protected]8ddf8322012-02-23 18:08:068346 SSLSocketDataProvider ssl_bad(ASYNC, ERR_CERT_AUTHORITY_INVALID);
8347 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bacff652009-03-31 17:50:338348
[email protected]bb88e1d32013-05-03 23:11:078349 session_deps_.socket_factory->AddSocketDataProvider(&ssl_bad_certificate);
8350 session_deps_.socket_factory->AddSocketDataProvider(&data);
8351 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_bad);
8352 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]bacff652009-03-31 17:50:338353
[email protected]49639fa2011-12-20 23:22:418354 TestCompletionCallback callback;
[email protected]bacff652009-03-31 17:50:338355
8356 for (int i = 0; i < 2; i++) {
[email protected]bb88e1d32013-05-03 23:11:078357 session_deps_.socket_factory->ResetNextMockIndexes();
[email protected]bacff652009-03-31 17:50:338358
danakj1fd259a02016-04-16 03:17:098359 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:168360 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]bacff652009-03-31 17:50:338361
tfarina42834112016-09-22 13:38:208362 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:018363 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]bacff652009-03-31 17:50:338364
8365 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:018366 EXPECT_THAT(rv, IsError(ERR_CERT_AUTHORITY_INVALID));
[email protected]bacff652009-03-31 17:50:338367
bnc691fda62016-08-12 00:43:168368 rv = trans.RestartIgnoringLastError(callback.callback());
robpercival214763f2016-07-01 23:27:018369 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]bacff652009-03-31 17:50:338370
8371 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:018372 EXPECT_THAT(rv, IsOk());
[email protected]bacff652009-03-31 17:50:338373
bnc691fda62016-08-12 00:43:168374 const HttpResponseInfo* response = trans.GetResponseInfo();
[email protected]bacff652009-03-31 17:50:338375
wezca1070932016-05-26 20:30:528376 ASSERT_TRUE(response);
[email protected]bacff652009-03-31 17:50:338377 EXPECT_EQ(100, response->headers->GetContentLength());
8378 }
8379}
8380
[email protected]2df19bb2010-08-25 20:13:468381
8382// Test HTTPS connections to a site, going through an HTTPS proxy
bncd16676a2016-07-20 16:23:018383TEST_F(HttpNetworkTransactionTest, HTTPSViaHttpsProxy) {
Lily Houghton8c2f97d2018-01-22 05:06:598384 session_deps_.proxy_resolution_service =
8385 ProxyResolutionService::CreateFixedFromPacResult("HTTPS proxy:70");
vishal.b62985ca92015-04-17 08:45:518386 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:078387 session_deps_.net_log = &net_log;
[email protected]2df19bb2010-08-25 20:13:468388
8389 HttpRequestInfo request;
8390 request.method = "GET";
bncce36dca22015-04-21 22:11:238391 request.url = GURL("https://www.example.org/");
[email protected]2df19bb2010-08-25 20:13:468392
8393 MockWrite data_writes[] = {
rsleevidb16bb02015-11-12 23:47:178394 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
8395 "Host: www.example.org:443\r\n"
8396 "Proxy-Connection: keep-alive\r\n\r\n"),
8397 MockWrite("GET / HTTP/1.1\r\n"
8398 "Host: www.example.org\r\n"
8399 "Connection: keep-alive\r\n\r\n"),
[email protected]2df19bb2010-08-25 20:13:468400 };
8401
8402 MockRead data_reads[] = {
8403 MockRead("HTTP/1.0 200 Connected\r\n\r\n"),
8404 MockRead("HTTP/1.1 200 OK\r\n"),
8405 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
8406 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:068407 MockRead(SYNCHRONOUS, OK),
[email protected]2df19bb2010-08-25 20:13:468408 };
8409
8410 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
8411 data_writes, arraysize(data_writes));
[email protected]8ddf8322012-02-23 18:08:068412 SSLSocketDataProvider proxy_ssl(ASYNC, OK); // SSL to the proxy
8413 SSLSocketDataProvider tunnel_ssl(ASYNC, OK); // SSL through the tunnel
[email protected]2df19bb2010-08-25 20:13:468414
[email protected]bb88e1d32013-05-03 23:11:078415 session_deps_.socket_factory->AddSocketDataProvider(&data);
8416 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy_ssl);
8417 session_deps_.socket_factory->AddSSLSocketDataProvider(&tunnel_ssl);
[email protected]2df19bb2010-08-25 20:13:468418
[email protected]49639fa2011-12-20 23:22:418419 TestCompletionCallback callback;
[email protected]2df19bb2010-08-25 20:13:468420
danakj1fd259a02016-04-16 03:17:098421 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:168422 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]2df19bb2010-08-25 20:13:468423
tfarina42834112016-09-22 13:38:208424 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:018425 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2df19bb2010-08-25 20:13:468426
8427 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:018428 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:168429 const HttpResponseInfo* response = trans.GetResponseInfo();
[email protected]2df19bb2010-08-25 20:13:468430
wezca1070932016-05-26 20:30:528431 ASSERT_TRUE(response);
[email protected]2df19bb2010-08-25 20:13:468432
tbansal2ecbbc72016-10-06 17:15:478433 EXPECT_TRUE(response->proxy_server.is_https());
[email protected]2df19bb2010-08-25 20:13:468434 EXPECT_TRUE(response->headers->IsKeepAlive());
8435 EXPECT_EQ(200, response->headers->response_code());
8436 EXPECT_EQ(100, response->headers->GetContentLength());
8437 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
[email protected]029c83b62013-01-24 05:28:208438
8439 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:168440 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]029c83b62013-01-24 05:28:208441 TestLoadTimingNotReusedWithPac(load_timing_info,
8442 CONNECT_TIMING_HAS_SSL_TIMES);
[email protected]2df19bb2010-08-25 20:13:468443}
8444
[email protected]511f6f52010-12-17 03:58:298445// Test an HTTPS Proxy's ability to redirect a CONNECT request
bncd16676a2016-07-20 16:23:018446TEST_F(HttpNetworkTransactionTest, RedirectOfHttpsConnectViaHttpsProxy) {
Lily Houghton8c2f97d2018-01-22 05:06:598447 session_deps_.proxy_resolution_service =
8448 ProxyResolutionService::CreateFixedFromPacResult("HTTPS proxy:70");
vishal.b62985ca92015-04-17 08:45:518449 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:078450 session_deps_.net_log = &net_log;
[email protected]511f6f52010-12-17 03:58:298451
8452 HttpRequestInfo request;
8453 request.method = "GET";
bncce36dca22015-04-21 22:11:238454 request.url = GURL("https://www.example.org/");
[email protected]511f6f52010-12-17 03:58:298455
8456 MockWrite data_writes[] = {
rsleevidb16bb02015-11-12 23:47:178457 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
8458 "Host: www.example.org:443\r\n"
8459 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]511f6f52010-12-17 03:58:298460 };
8461
8462 MockRead data_reads[] = {
8463 MockRead("HTTP/1.1 302 Redirect\r\n"),
8464 MockRead("Location: http://login.example.com/\r\n"),
8465 MockRead("Content-Length: 0\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:068466 MockRead(SYNCHRONOUS, OK),
[email protected]511f6f52010-12-17 03:58:298467 };
8468
8469 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
8470 data_writes, arraysize(data_writes));
[email protected]8ddf8322012-02-23 18:08:068471 SSLSocketDataProvider proxy_ssl(ASYNC, OK); // SSL to the proxy
[email protected]511f6f52010-12-17 03:58:298472
[email protected]bb88e1d32013-05-03 23:11:078473 session_deps_.socket_factory->AddSocketDataProvider(&data);
8474 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy_ssl);
[email protected]511f6f52010-12-17 03:58:298475
[email protected]49639fa2011-12-20 23:22:418476 TestCompletionCallback callback;
[email protected]511f6f52010-12-17 03:58:298477
danakj1fd259a02016-04-16 03:17:098478 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:168479 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]511f6f52010-12-17 03:58:298480
tfarina42834112016-09-22 13:38:208481 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:018482 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]511f6f52010-12-17 03:58:298483
8484 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:018485 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:168486 const HttpResponseInfo* response = trans.GetResponseInfo();
[email protected]511f6f52010-12-17 03:58:298487
wezca1070932016-05-26 20:30:528488 ASSERT_TRUE(response);
[email protected]511f6f52010-12-17 03:58:298489
8490 EXPECT_EQ(302, response->headers->response_code());
8491 std::string url;
8492 EXPECT_TRUE(response->headers->IsRedirect(&url));
8493 EXPECT_EQ("http://login.example.com/", url);
[email protected]029c83b62013-01-24 05:28:208494
8495 // In the case of redirects from proxies, HttpNetworkTransaction returns
8496 // timing for the proxy connection instead of the connection to the host,
8497 // and no send / receive times.
8498 // See HttpNetworkTransaction::OnHttpsProxyTunnelResponse.
8499 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:168500 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]029c83b62013-01-24 05:28:208501
8502 EXPECT_FALSE(load_timing_info.socket_reused);
mikecironef22f9812016-10-04 03:40:198503 EXPECT_NE(NetLogSource::kInvalidId, load_timing_info.socket_log_id);
[email protected]029c83b62013-01-24 05:28:208504
8505 EXPECT_FALSE(load_timing_info.proxy_resolve_start.is_null());
8506 EXPECT_LE(load_timing_info.proxy_resolve_start,
8507 load_timing_info.proxy_resolve_end);
8508 EXPECT_LE(load_timing_info.proxy_resolve_end,
8509 load_timing_info.connect_timing.connect_start);
8510 ExpectConnectTimingHasTimes(
8511 load_timing_info.connect_timing,
8512 CONNECT_TIMING_HAS_DNS_TIMES | CONNECT_TIMING_HAS_SSL_TIMES);
8513
8514 EXPECT_TRUE(load_timing_info.send_start.is_null());
8515 EXPECT_TRUE(load_timing_info.send_end.is_null());
8516 EXPECT_TRUE(load_timing_info.receive_headers_end.is_null());
[email protected]511f6f52010-12-17 03:58:298517}
8518
8519// Test an HTTPS (SPDY) Proxy's ability to redirect a CONNECT request
bncd16676a2016-07-20 16:23:018520TEST_F(HttpNetworkTransactionTest, RedirectOfHttpsConnectViaSpdyProxy) {
Lily Houghton8c2f97d2018-01-22 05:06:598521 session_deps_.proxy_resolution_service =
8522 ProxyResolutionService::CreateFixed("https://proxy:70");
[email protected]511f6f52010-12-17 03:58:298523
8524 HttpRequestInfo request;
8525 request.method = "GET";
bncce36dca22015-04-21 22:11:238526 request.url = GURL("https://www.example.org/");
[email protected]511f6f52010-12-17 03:58:298527
bncdf80d44fd2016-07-15 20:27:418528 SpdySerializedFrame conn(spdy_util_.ConstructSpdyConnect(
bncce36dca22015-04-21 22:11:238529 NULL, 0, 1, LOWEST, HostPortPair("www.example.org", 443)));
bncdf80d44fd2016-07-15 20:27:418530 SpdySerializedFrame goaway(
diannahu9904e272017-02-03 14:40:088531 spdy_util_.ConstructSpdyRstStream(1, ERROR_CODE_CANCEL));
[email protected]511f6f52010-12-17 03:58:298532 MockWrite data_writes[] = {
bncdf80d44fd2016-07-15 20:27:418533 CreateMockWrite(conn, 0, SYNCHRONOUS),
8534 CreateMockWrite(goaway, 2, SYNCHRONOUS),
[email protected]511f6f52010-12-17 03:58:298535 };
8536
8537 static const char* const kExtraHeaders[] = {
8538 "location",
8539 "http://login.example.com/",
8540 };
bnc42331402016-07-25 13:36:158541 SpdySerializedFrame resp(spdy_util_.ConstructSpdyReplyError(
bncc9f762a2016-12-06 20:38:238542 "302", kExtraHeaders, arraysize(kExtraHeaders) / 2, 1));
[email protected]511f6f52010-12-17 03:58:298543 MockRead data_reads[] = {
bncdf80d44fd2016-07-15 20:27:418544 CreateMockRead(resp, 1), MockRead(ASYNC, 0, 3), // EOF
[email protected]511f6f52010-12-17 03:58:298545 };
8546
rch8e6c6c42015-05-01 14:05:138547 SequencedSocketData data(data_reads, arraysize(data_reads), data_writes,
8548 arraysize(data_writes));
[email protected]8ddf8322012-02-23 18:08:068549 SSLSocketDataProvider proxy_ssl(ASYNC, OK); // SSL to the proxy
bnc3cf2a592016-08-11 14:48:368550 proxy_ssl.next_proto = kProtoHTTP2;
[email protected]511f6f52010-12-17 03:58:298551
[email protected]bb88e1d32013-05-03 23:11:078552 session_deps_.socket_factory->AddSocketDataProvider(&data);
8553 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy_ssl);
[email protected]511f6f52010-12-17 03:58:298554
[email protected]49639fa2011-12-20 23:22:418555 TestCompletionCallback callback;
[email protected]511f6f52010-12-17 03:58:298556
danakj1fd259a02016-04-16 03:17:098557 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:168558 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]511f6f52010-12-17 03:58:298559
tfarina42834112016-09-22 13:38:208560 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:018561 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]511f6f52010-12-17 03:58:298562
8563 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:018564 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:168565 const HttpResponseInfo* response = trans.GetResponseInfo();
[email protected]511f6f52010-12-17 03:58:298566
wezca1070932016-05-26 20:30:528567 ASSERT_TRUE(response);
[email protected]511f6f52010-12-17 03:58:298568
8569 EXPECT_EQ(302, response->headers->response_code());
8570 std::string url;
8571 EXPECT_TRUE(response->headers->IsRedirect(&url));
8572 EXPECT_EQ("http://login.example.com/", url);
8573}
8574
[email protected]4eddbc732012-08-09 05:40:178575// Test that an HTTPS proxy's response to a CONNECT request is filtered.
bncd16676a2016-07-20 16:23:018576TEST_F(HttpNetworkTransactionTest, ErrorResponseToHttpsConnectViaHttpsProxy) {
Lily Houghton8c2f97d2018-01-22 05:06:598577 session_deps_.proxy_resolution_service =
8578 ProxyResolutionService::CreateFixed("https://proxy:70");
[email protected]511f6f52010-12-17 03:58:298579
8580 HttpRequestInfo request;
8581 request.method = "GET";
bncce36dca22015-04-21 22:11:238582 request.url = GURL("https://www.example.org/");
[email protected]511f6f52010-12-17 03:58:298583
8584 MockWrite data_writes[] = {
rsleevidb16bb02015-11-12 23:47:178585 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
8586 "Host: www.example.org:443\r\n"
8587 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]511f6f52010-12-17 03:58:298588 };
8589
8590 MockRead data_reads[] = {
8591 MockRead("HTTP/1.1 404 Not Found\r\n"),
8592 MockRead("Content-Length: 23\r\n\r\n"),
8593 MockRead("The host does not exist"),
[email protected]8ddf8322012-02-23 18:08:068594 MockRead(SYNCHRONOUS, OK),
[email protected]511f6f52010-12-17 03:58:298595 };
8596
8597 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
8598 data_writes, arraysize(data_writes));
[email protected]8ddf8322012-02-23 18:08:068599 SSLSocketDataProvider proxy_ssl(ASYNC, OK); // SSL to the proxy
[email protected]511f6f52010-12-17 03:58:298600
[email protected]bb88e1d32013-05-03 23:11:078601 session_deps_.socket_factory->AddSocketDataProvider(&data);
8602 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy_ssl);
[email protected]511f6f52010-12-17 03:58:298603
[email protected]49639fa2011-12-20 23:22:418604 TestCompletionCallback callback;
[email protected]511f6f52010-12-17 03:58:298605
danakj1fd259a02016-04-16 03:17:098606 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:168607 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]511f6f52010-12-17 03:58:298608
tfarina42834112016-09-22 13:38:208609 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:018610 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]511f6f52010-12-17 03:58:298611
8612 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:018613 EXPECT_THAT(rv, IsError(ERR_TUNNEL_CONNECTION_FAILED));
[email protected]511f6f52010-12-17 03:58:298614
ttuttle960fcbf2016-04-19 13:26:328615 // TODO(juliatuttle): Anything else to check here?
[email protected]511f6f52010-12-17 03:58:298616}
8617
[email protected]4eddbc732012-08-09 05:40:178618// Test that a SPDY proxy's response to a CONNECT request is filtered.
bncd16676a2016-07-20 16:23:018619TEST_F(HttpNetworkTransactionTest, ErrorResponseToHttpsConnectViaSpdyProxy) {
Lily Houghton8c2f97d2018-01-22 05:06:598620 session_deps_.proxy_resolution_service =
8621 ProxyResolutionService::CreateFixed("https://proxy:70");
[email protected]511f6f52010-12-17 03:58:298622
8623 HttpRequestInfo request;
8624 request.method = "GET";
bncce36dca22015-04-21 22:11:238625 request.url = GURL("https://www.example.org/");
[email protected]511f6f52010-12-17 03:58:298626
bncdf80d44fd2016-07-15 20:27:418627 SpdySerializedFrame conn(spdy_util_.ConstructSpdyConnect(
bncce36dca22015-04-21 22:11:238628 NULL, 0, 1, LOWEST, HostPortPair("www.example.org", 443)));
bncdf80d44fd2016-07-15 20:27:418629 SpdySerializedFrame rst(
diannahu9904e272017-02-03 14:40:088630 spdy_util_.ConstructSpdyRstStream(1, ERROR_CODE_CANCEL));
[email protected]511f6f52010-12-17 03:58:298631 MockWrite data_writes[] = {
bncdf80d44fd2016-07-15 20:27:418632 CreateMockWrite(conn, 0), CreateMockWrite(rst, 3),
[email protected]511f6f52010-12-17 03:58:298633 };
8634
8635 static const char* const kExtraHeaders[] = {
8636 "location",
8637 "http://login.example.com/",
8638 };
bnc42331402016-07-25 13:36:158639 SpdySerializedFrame resp(spdy_util_.ConstructSpdyReplyError(
bncc9f762a2016-12-06 20:38:238640 "404", kExtraHeaders, arraysize(kExtraHeaders) / 2, 1));
bncdf80d44fd2016-07-15 20:27:418641 SpdySerializedFrame body(spdy_util_.ConstructSpdyDataFrame(
bncb03b1092016-04-06 11:19:558642 1, "The host does not exist", 23, true));
[email protected]511f6f52010-12-17 03:58:298643 MockRead data_reads[] = {
bncdf80d44fd2016-07-15 20:27:418644 CreateMockRead(resp, 1), CreateMockRead(body, 2),
rch8e6c6c42015-05-01 14:05:138645 MockRead(ASYNC, 0, 4), // EOF
[email protected]511f6f52010-12-17 03:58:298646 };
8647
rch8e6c6c42015-05-01 14:05:138648 SequencedSocketData data(data_reads, arraysize(data_reads), data_writes,
8649 arraysize(data_writes));
[email protected]8ddf8322012-02-23 18:08:068650 SSLSocketDataProvider proxy_ssl(ASYNC, OK); // SSL to the proxy
bnc3cf2a592016-08-11 14:48:368651 proxy_ssl.next_proto = kProtoHTTP2;
[email protected]511f6f52010-12-17 03:58:298652
[email protected]bb88e1d32013-05-03 23:11:078653 session_deps_.socket_factory->AddSocketDataProvider(&data);
8654 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy_ssl);
[email protected]511f6f52010-12-17 03:58:298655
[email protected]49639fa2011-12-20 23:22:418656 TestCompletionCallback callback;
[email protected]511f6f52010-12-17 03:58:298657
danakj1fd259a02016-04-16 03:17:098658 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:168659 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]511f6f52010-12-17 03:58:298660
tfarina42834112016-09-22 13:38:208661 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:018662 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]511f6f52010-12-17 03:58:298663
8664 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:018665 EXPECT_THAT(rv, IsError(ERR_TUNNEL_CONNECTION_FAILED));
[email protected]511f6f52010-12-17 03:58:298666
ttuttle960fcbf2016-04-19 13:26:328667 // TODO(juliatuttle): Anything else to check here?
[email protected]511f6f52010-12-17 03:58:298668}
8669
[email protected]0c5fb722012-02-28 11:50:358670// Test the request-challenge-retry sequence for basic auth, through
8671// a SPDY proxy over a single SPDY session.
bncd16676a2016-07-20 16:23:018672TEST_F(HttpNetworkTransactionTest, BasicAuthSpdyProxy) {
[email protected]0c5fb722012-02-28 11:50:358673 HttpRequestInfo request;
8674 request.method = "GET";
bncce36dca22015-04-21 22:11:238675 request.url = GURL("https://www.example.org/");
[email protected]0c5fb722012-02-28 11:50:358676 // when the no authentication data flag is set.
ttuttle859dc7a2015-04-23 19:42:298677 request.load_flags = LOAD_DO_NOT_SEND_AUTH_DATA;
[email protected]0c5fb722012-02-28 11:50:358678
8679 // Configure against https proxy server "myproxy:70".
Lily Houghton8c2f97d2018-01-22 05:06:598680 session_deps_.proxy_resolution_service =
8681 ProxyResolutionService::CreateFixedFromPacResult("HTTPS myproxy:70");
vishal.b62985ca92015-04-17 08:45:518682 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:078683 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:098684 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]0c5fb722012-02-28 11:50:358685
8686 // Since we have proxy, should try to establish tunnel.
bncdf80d44fd2016-07-15 20:27:418687 SpdySerializedFrame req(spdy_util_.ConstructSpdyConnect(
bncce36dca22015-04-21 22:11:238688 NULL, 0, 1, LOWEST, HostPortPair("www.example.org", 443)));
bncdf80d44fd2016-07-15 20:27:418689 SpdySerializedFrame rst(
diannahu9904e272017-02-03 14:40:088690 spdy_util_.ConstructSpdyRstStream(1, ERROR_CODE_CANCEL));
rdsmithebb50aa2015-11-12 03:44:388691 spdy_util_.UpdateWithStreamDestruction(1);
[email protected]0c5fb722012-02-28 11:50:358692
bnc691fda62016-08-12 00:43:168693 // After calling trans.RestartWithAuth(), this is the request we should
[email protected]0c5fb722012-02-28 11:50:358694 // be issuing -- the final header line contains the credentials.
8695 const char* const kAuthCredentials[] = {
8696 "proxy-authorization", "Basic Zm9vOmJhcg==",
8697 };
bncdf80d44fd2016-07-15 20:27:418698 SpdySerializedFrame connect2(spdy_util_.ConstructSpdyConnect(
lgarrona91df87f2014-12-05 00:51:348699 kAuthCredentials, arraysize(kAuthCredentials) / 2, 3, LOWEST,
bncce36dca22015-04-21 22:11:238700 HostPortPair("www.example.org", 443)));
8701 // fetch https://www.example.org/ via HTTP
8702 const char get[] =
8703 "GET / HTTP/1.1\r\n"
8704 "Host: www.example.org\r\n"
8705 "Connection: keep-alive\r\n\r\n";
bncdf80d44fd2016-07-15 20:27:418706 SpdySerializedFrame wrapped_get(
8707 spdy_util_.ConstructSpdyDataFrame(3, get, strlen(get), false));
[email protected]0c5fb722012-02-28 11:50:358708
8709 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:418710 CreateMockWrite(req, 0, ASYNC), CreateMockWrite(rst, 2, ASYNC),
8711 CreateMockWrite(connect2, 3), CreateMockWrite(wrapped_get, 5),
[email protected]0c5fb722012-02-28 11:50:358712 };
8713
8714 // The proxy responds to the connect with a 407, using a persistent
8715 // connection.
thestig9d3bb0c2015-01-24 00:49:518716 const char kAuthStatus[] = "407";
[email protected]0c5fb722012-02-28 11:50:358717 const char* const kAuthChallenge[] = {
[email protected]0c5fb722012-02-28 11:50:358718 "proxy-authenticate", "Basic realm=\"MyRealm1\"",
8719 };
bnc42331402016-07-25 13:36:158720 SpdySerializedFrame conn_auth_resp(spdy_util_.ConstructSpdyReplyError(
bncdf80d44fd2016-07-15 20:27:418721 kAuthStatus, kAuthChallenge, arraysize(kAuthChallenge) / 2, 1));
[email protected]0c5fb722012-02-28 11:50:358722
bnc42331402016-07-25 13:36:158723 SpdySerializedFrame conn_resp(spdy_util_.ConstructSpdyGetReply(NULL, 0, 3));
[email protected]0c5fb722012-02-28 11:50:358724 const char resp[] = "HTTP/1.1 200 OK\r\n"
8725 "Content-Length: 5\r\n\r\n";
8726
bncdf80d44fd2016-07-15 20:27:418727 SpdySerializedFrame wrapped_get_resp(
8728 spdy_util_.ConstructSpdyDataFrame(3, resp, strlen(resp), false));
8729 SpdySerializedFrame wrapped_body(
8730 spdy_util_.ConstructSpdyDataFrame(3, "hello", 5, false));
[email protected]0c5fb722012-02-28 11:50:358731 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:418732 CreateMockRead(conn_auth_resp, 1, ASYNC),
8733 CreateMockRead(conn_resp, 4, ASYNC),
8734 CreateMockRead(wrapped_get_resp, 6, ASYNC),
8735 CreateMockRead(wrapped_body, 7, ASYNC),
rch8e6c6c42015-05-01 14:05:138736 MockRead(ASYNC, OK, 8), // EOF. May or may not be read.
[email protected]0c5fb722012-02-28 11:50:358737 };
8738
rch8e6c6c42015-05-01 14:05:138739 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
8740 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:078741 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]0c5fb722012-02-28 11:50:358742 // Negotiate SPDY to the proxy
8743 SSLSocketDataProvider proxy(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:368744 proxy.next_proto = kProtoHTTP2;
[email protected]bb88e1d32013-05-03 23:11:078745 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy);
[email protected]0c5fb722012-02-28 11:50:358746 // Vanilla SSL to the server
8747 SSLSocketDataProvider server(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:078748 session_deps_.socket_factory->AddSSLSocketDataProvider(&server);
[email protected]0c5fb722012-02-28 11:50:358749
8750 TestCompletionCallback callback1;
8751
bnc87dcefc2017-05-25 12:47:588752 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:198753 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]0c5fb722012-02-28 11:50:358754
8755 int rv = trans->Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:018756 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]0c5fb722012-02-28 11:50:358757
8758 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:018759 EXPECT_THAT(rv, IsOk());
mmenke43758e62015-05-04 21:09:468760 TestNetLogEntry::List entries;
[email protected]0c5fb722012-02-28 11:50:358761 log.GetEntries(&entries);
8762 size_t pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:008763 entries, 0, NetLogEventType::HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
8764 NetLogEventPhase::NONE);
[email protected]0c5fb722012-02-28 11:50:358765 ExpectLogContainsSomewhere(
8766 entries, pos,
mikecirone8b85c432016-09-08 19:11:008767 NetLogEventType::HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
8768 NetLogEventPhase::NONE);
[email protected]0c5fb722012-02-28 11:50:358769
8770 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:528771 ASSERT_TRUE(response);
8772 ASSERT_TRUE(response->headers);
[email protected]0c5fb722012-02-28 11:50:358773 EXPECT_EQ(407, response->headers->response_code());
8774 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
wezca1070932016-05-26 20:30:528775 EXPECT_TRUE(response->auth_challenge);
asanka098c0092016-06-16 20:18:438776 EXPECT_TRUE(CheckBasicSecureProxyAuth(response->auth_challenge.get()));
[email protected]0c5fb722012-02-28 11:50:358777
8778 TestCompletionCallback callback2;
8779
8780 rv = trans->RestartWithAuth(AuthCredentials(kFoo, kBar),
8781 callback2.callback());
robpercival214763f2016-07-01 23:27:018782 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]0c5fb722012-02-28 11:50:358783
8784 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:018785 EXPECT_THAT(rv, IsOk());
[email protected]0c5fb722012-02-28 11:50:358786
8787 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:528788 ASSERT_TRUE(response);
[email protected]0c5fb722012-02-28 11:50:358789
8790 EXPECT_TRUE(response->headers->IsKeepAlive());
8791 EXPECT_EQ(200, response->headers->response_code());
8792 EXPECT_EQ(5, response->headers->GetContentLength());
8793 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
8794
8795 // The password prompt info should not be set.
wezca1070932016-05-26 20:30:528796 EXPECT_FALSE(response->auth_challenge);
[email protected]0c5fb722012-02-28 11:50:358797
[email protected]029c83b62013-01-24 05:28:208798 LoadTimingInfo load_timing_info;
8799 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
8800 TestLoadTimingNotReusedWithPac(load_timing_info,
8801 CONNECT_TIMING_HAS_SSL_TIMES);
8802
[email protected]0c5fb722012-02-28 11:50:358803 trans.reset();
8804 session->CloseAllConnections();
8805}
8806
[email protected]7c6f7ba2012-04-03 04:09:298807// Test that an explicitly trusted SPDY proxy can push a resource from an
8808// origin that is different from that of its associated resource.
bncd16676a2016-07-20 16:23:018809TEST_F(HttpNetworkTransactionTest, CrossOriginSPDYProxyPush) {
tbansal28e68f82016-02-04 02:56:158810 // Configure the proxy delegate to allow cross-origin SPDY pushes.
Jeremy Roman0579ed62017-08-29 15:56:198811 auto proxy_delegate = std::make_unique<TestProxyDelegate>();
tbansal28e68f82016-02-04 02:56:158812 proxy_delegate->set_trusted_spdy_proxy(net::ProxyServer::FromURI(
8813 "https://myproxy:443", net::ProxyServer::SCHEME_HTTP));
[email protected]7c6f7ba2012-04-03 04:09:298814 HttpRequestInfo request;
8815 HttpRequestInfo push_request;
8816
[email protected]7c6f7ba2012-04-03 04:09:298817 request.method = "GET";
bncce36dca22015-04-21 22:11:238818 request.url = GURL("http://www.example.org/");
[email protected]7c6f7ba2012-04-03 04:09:298819 push_request.method = "GET";
8820 push_request.url = GURL("http://www.another-origin.com/foo.dat");
8821
tbansal28e68f82016-02-04 02:56:158822 // Configure against https proxy server "myproxy:443".
Lily Houghton8c2f97d2018-01-22 05:06:598823 session_deps_.proxy_resolution_service =
8824 ProxyResolutionService::CreateFixedFromPacResult("HTTPS myproxy:443");
vishal.b62985ca92015-04-17 08:45:518825 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:078826 session_deps_.net_log = log.bound().net_log();
[email protected]61b4efc2012-04-27 18:12:508827
inlinechan894515af2016-12-09 02:40:108828 session_deps_.proxy_delegate = std::move(proxy_delegate);
[email protected]61b4efc2012-04-27 18:12:508829
danakj1fd259a02016-04-16 03:17:098830 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]7c6f7ba2012-04-03 04:09:298831
bncdf80d44fd2016-07-15 20:27:418832 SpdySerializedFrame stream1_syn(
bncb26024382016-06-29 02:39:458833 spdy_util_.ConstructSpdyGet("http://www.example.org/", 1, LOWEST));
tombergan5d22c182017-01-11 02:05:358834 SpdySerializedFrame stream2_priority(
8835 spdy_util_.ConstructSpdyPriority(2, 1, IDLE, true));
[email protected]7c6f7ba2012-04-03 04:09:298836
8837 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:418838 CreateMockWrite(stream1_syn, 0, ASYNC),
tombergan5d22c182017-01-11 02:05:358839 CreateMockWrite(stream2_priority, 3, ASYNC),
[email protected]7c6f7ba2012-04-03 04:09:298840 };
8841
Bence Béky7bf94362018-01-10 13:19:368842 SpdySerializedFrame stream2_syn(spdy_util_.ConstructSpdyPush(
8843 NULL, 0, 2, 1, "http://www.another-origin.com/foo.dat"));
8844
bncdf80d44fd2016-07-15 20:27:418845 SpdySerializedFrame stream1_reply(
bnc42331402016-07-25 13:36:158846 spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
[email protected]7c6f7ba2012-04-03 04:09:298847
bncdf80d44fd2016-07-15 20:27:418848 SpdySerializedFrame stream1_body(spdy_util_.ConstructSpdyDataFrame(1, true));
[email protected]7c6f7ba2012-04-03 04:09:298849
[email protected]8a0fc822013-06-27 20:52:438850 const char kPushedData[] = "pushed";
bncdf80d44fd2016-07-15 20:27:418851 SpdySerializedFrame stream2_body(spdy_util_.ConstructSpdyDataFrame(
8852 2, kPushedData, strlen(kPushedData), true));
[email protected]7c6f7ba2012-04-03 04:09:298853
8854 MockRead spdy_reads[] = {
Bence Béky7bf94362018-01-10 13:19:368855 CreateMockRead(stream2_syn, 1, ASYNC),
8856 CreateMockRead(stream1_reply, 2, ASYNC),
tombergan5d22c182017-01-11 02:05:358857 CreateMockRead(stream1_body, 4, ASYNC),
8858 CreateMockRead(stream2_body, 5, ASYNC),
8859 MockRead(SYNCHRONOUS, ERR_IO_PENDING, 6), // Force a hang
[email protected]7c6f7ba2012-04-03 04:09:298860 };
8861
rch8e6c6c42015-05-01 14:05:138862 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
8863 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:078864 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]7c6f7ba2012-04-03 04:09:298865 // Negotiate SPDY to the proxy
8866 SSLSocketDataProvider proxy(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:368867 proxy.next_proto = kProtoHTTP2;
[email protected]bb88e1d32013-05-03 23:11:078868 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy);
[email protected]7c6f7ba2012-04-03 04:09:298869
bnc87dcefc2017-05-25 12:47:588870 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:198871 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]7c6f7ba2012-04-03 04:09:298872 TestCompletionCallback callback;
8873 int rv = trans->Start(&request, callback.callback(), log.bound());
robpercival214763f2016-07-01 23:27:018874 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]7c6f7ba2012-04-03 04:09:298875
8876 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:018877 EXPECT_THAT(rv, IsOk());
[email protected]7c6f7ba2012-04-03 04:09:298878 const HttpResponseInfo* response = trans->GetResponseInfo();
8879
bnc87dcefc2017-05-25 12:47:588880 auto push_trans =
Jeremy Roman0579ed62017-08-29 15:56:198881 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]90499482013-06-01 00:39:508882 rv = push_trans->Start(&push_request, callback.callback(), log.bound());
robpercival214763f2016-07-01 23:27:018883 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]7c6f7ba2012-04-03 04:09:298884
8885 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:018886 EXPECT_THAT(rv, IsOk());
[email protected]7c6f7ba2012-04-03 04:09:298887 const HttpResponseInfo* push_response = push_trans->GetResponseInfo();
8888
wezca1070932016-05-26 20:30:528889 ASSERT_TRUE(response);
[email protected]7c6f7ba2012-04-03 04:09:298890 EXPECT_TRUE(response->headers->IsKeepAlive());
8891
8892 EXPECT_EQ(200, response->headers->response_code());
8893 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
8894
8895 std::string response_data;
8896 rv = ReadTransaction(trans.get(), &response_data);
robpercival214763f2016-07-01 23:27:018897 EXPECT_THAT(rv, IsOk());
[email protected]7c6f7ba2012-04-03 04:09:298898 EXPECT_EQ("hello!", response_data);
8899
[email protected]029c83b62013-01-24 05:28:208900 LoadTimingInfo load_timing_info;
8901 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
8902 TestLoadTimingNotReusedWithPac(load_timing_info,
8903 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
8904
[email protected]7c6f7ba2012-04-03 04:09:298905 // Verify the pushed stream.
wezca1070932016-05-26 20:30:528906 EXPECT_TRUE(push_response->headers);
[email protected]7c6f7ba2012-04-03 04:09:298907 EXPECT_EQ(200, push_response->headers->response_code());
8908
8909 rv = ReadTransaction(push_trans.get(), &response_data);
robpercival214763f2016-07-01 23:27:018910 EXPECT_THAT(rv, IsOk());
[email protected]7c6f7ba2012-04-03 04:09:298911 EXPECT_EQ("pushed", response_data);
8912
[email protected]029c83b62013-01-24 05:28:208913 LoadTimingInfo push_load_timing_info;
8914 EXPECT_TRUE(push_trans->GetLoadTimingInfo(&push_load_timing_info));
8915 TestLoadTimingReusedWithPac(push_load_timing_info);
8916 // The transactions should share a socket ID, despite being for different
8917 // origins.
8918 EXPECT_EQ(load_timing_info.socket_log_id,
8919 push_load_timing_info.socket_log_id);
8920
[email protected]7c6f7ba2012-04-03 04:09:298921 trans.reset();
8922 push_trans.reset();
8923 session->CloseAllConnections();
8924}
8925
[email protected]8c843192012-04-05 07:15:008926// Test that an explicitly trusted SPDY proxy cannot push HTTPS content.
bncd16676a2016-07-20 16:23:018927TEST_F(HttpNetworkTransactionTest, CrossOriginProxyPushCorrectness) {
tbansal28e68f82016-02-04 02:56:158928 // Configure the proxy delegate to allow cross-origin SPDY pushes.
Jeremy Roman0579ed62017-08-29 15:56:198929 auto proxy_delegate = std::make_unique<TestProxyDelegate>();
tbansal28e68f82016-02-04 02:56:158930 proxy_delegate->set_trusted_spdy_proxy(net::ProxyServer::FromURI(
8931 "https://myproxy:443", net::ProxyServer::SCHEME_HTTP));
[email protected]8c843192012-04-05 07:15:008932 HttpRequestInfo request;
8933
8934 request.method = "GET";
bncce36dca22015-04-21 22:11:238935 request.url = GURL("http://www.example.org/");
[email protected]8c843192012-04-05 07:15:008936
Lily Houghton8c2f97d2018-01-22 05:06:598937 session_deps_.proxy_resolution_service =
8938 ProxyResolutionService::CreateFixed("https://myproxy:443");
vishal.b62985ca92015-04-17 08:45:518939 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:078940 session_deps_.net_log = log.bound().net_log();
[email protected]61b4efc2012-04-27 18:12:508941
8942 // Enable cross-origin push.
inlinechan894515af2016-12-09 02:40:108943 session_deps_.proxy_delegate = std::move(proxy_delegate);
[email protected]61b4efc2012-04-27 18:12:508944
danakj1fd259a02016-04-16 03:17:098945 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]8c843192012-04-05 07:15:008946
bncdf80d44fd2016-07-15 20:27:418947 SpdySerializedFrame stream1_syn(
bncb26024382016-06-29 02:39:458948 spdy_util_.ConstructSpdyGet("http://www.example.org/", 1, LOWEST));
[email protected]8c843192012-04-05 07:15:008949
bncdf80d44fd2016-07-15 20:27:418950 SpdySerializedFrame push_rst(
diannahu9904e272017-02-03 14:40:088951 spdy_util_.ConstructSpdyRstStream(2, ERROR_CODE_REFUSED_STREAM));
[email protected]8c843192012-04-05 07:15:008952
8953 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:418954 CreateMockWrite(stream1_syn, 0, ASYNC), CreateMockWrite(push_rst, 3),
[email protected]8c843192012-04-05 07:15:008955 };
8956
bncdf80d44fd2016-07-15 20:27:418957 SpdySerializedFrame stream1_reply(
bnc42331402016-07-25 13:36:158958 spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
[email protected]8c843192012-04-05 07:15:008959
bncdf80d44fd2016-07-15 20:27:418960 SpdySerializedFrame stream1_body(spdy_util_.ConstructSpdyDataFrame(1, true));
[email protected]8c843192012-04-05 07:15:008961
bncdf80d44fd2016-07-15 20:27:418962 SpdySerializedFrame stream2_syn(spdy_util_.ConstructSpdyPush(
bncb03b1092016-04-06 11:19:558963 NULL, 0, 2, 1, "https://www.another-origin.com/foo.dat"));
[email protected]8c843192012-04-05 07:15:008964
8965 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:418966 CreateMockRead(stream1_reply, 1, ASYNC),
8967 CreateMockRead(stream2_syn, 2, ASYNC),
8968 CreateMockRead(stream1_body, 4, ASYNC),
mmenkee24011922015-12-17 22:12:598969 MockRead(SYNCHRONOUS, ERR_IO_PENDING, 5), // Force a hang
[email protected]8c843192012-04-05 07:15:008970 };
8971
rch8e6c6c42015-05-01 14:05:138972 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
8973 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:078974 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]8c843192012-04-05 07:15:008975 // Negotiate SPDY to the proxy
8976 SSLSocketDataProvider proxy(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:368977 proxy.next_proto = kProtoHTTP2;
[email protected]bb88e1d32013-05-03 23:11:078978 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy);
[email protected]8c843192012-04-05 07:15:008979
bnc87dcefc2017-05-25 12:47:588980 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:198981 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]8c843192012-04-05 07:15:008982 TestCompletionCallback callback;
8983 int rv = trans->Start(&request, callback.callback(), log.bound());
robpercival214763f2016-07-01 23:27:018984 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]8c843192012-04-05 07:15:008985
8986 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:018987 EXPECT_THAT(rv, IsOk());
[email protected]8c843192012-04-05 07:15:008988 const HttpResponseInfo* response = trans->GetResponseInfo();
8989
wezca1070932016-05-26 20:30:528990 ASSERT_TRUE(response);
[email protected]8c843192012-04-05 07:15:008991 EXPECT_TRUE(response->headers->IsKeepAlive());
8992
8993 EXPECT_EQ(200, response->headers->response_code());
8994 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
8995
8996 std::string response_data;
8997 rv = ReadTransaction(trans.get(), &response_data);
robpercival214763f2016-07-01 23:27:018998 EXPECT_THAT(rv, IsOk());
[email protected]8c843192012-04-05 07:15:008999 EXPECT_EQ("hello!", response_data);
9000
9001 trans.reset();
9002 session->CloseAllConnections();
9003}
9004
tbansal8ef1d3e2016-02-03 04:05:429005// Test that an explicitly trusted SPDY proxy can push same-origin HTTPS
9006// resources.
bncd16676a2016-07-20 16:23:019007TEST_F(HttpNetworkTransactionTest, SameOriginProxyPushCorrectness) {
tbansal28e68f82016-02-04 02:56:159008 // Configure the proxy delegate to allow cross-origin SPDY pushes.
Jeremy Roman0579ed62017-08-29 15:56:199009 auto proxy_delegate = std::make_unique<TestProxyDelegate>();
tbansal28e68f82016-02-04 02:56:159010 proxy_delegate->set_trusted_spdy_proxy(
9011 net::ProxyServer::FromURI("myproxy:70", net::ProxyServer::SCHEME_HTTP));
9012
tbansal8ef1d3e2016-02-03 04:05:429013 HttpRequestInfo request;
9014
9015 request.method = "GET";
9016 request.url = GURL("http://www.example.org/");
9017
9018 // Configure against https proxy server "myproxy:70".
Lily Houghton8c2f97d2018-01-22 05:06:599019 session_deps_.proxy_resolution_service =
9020 ProxyResolutionService::CreateFixed("https://myproxy:70");
tbansal8ef1d3e2016-02-03 04:05:429021 BoundTestNetLog log;
9022 session_deps_.net_log = log.bound().net_log();
9023
9024 // Enable cross-origin push.
inlinechan894515af2016-12-09 02:40:109025 session_deps_.proxy_delegate = std::move(proxy_delegate);
tbansal8ef1d3e2016-02-03 04:05:429026
danakj1fd259a02016-04-16 03:17:099027 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
tbansal8ef1d3e2016-02-03 04:05:429028
bncdf80d44fd2016-07-15 20:27:419029 SpdySerializedFrame stream1_syn(
bncb26024382016-06-29 02:39:459030 spdy_util_.ConstructSpdyGet("http://www.example.org/", 1, LOWEST));
tombergan5d22c182017-01-11 02:05:359031 SpdySerializedFrame stream2_priority(
9032 spdy_util_.ConstructSpdyPriority(2, 1, IDLE, true));
tbansal8ef1d3e2016-02-03 04:05:429033
9034 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:419035 CreateMockWrite(stream1_syn, 0, ASYNC),
tombergan5d22c182017-01-11 02:05:359036 CreateMockWrite(stream2_priority, 3, ASYNC),
tbansal8ef1d3e2016-02-03 04:05:429037 };
9038
bncdf80d44fd2016-07-15 20:27:419039 SpdySerializedFrame stream1_reply(
bnc42331402016-07-25 13:36:159040 spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
tbansal8ef1d3e2016-02-03 04:05:429041
bncdf80d44fd2016-07-15 20:27:419042 SpdySerializedFrame stream2_syn(spdy_util_.ConstructSpdyPush(
Bence Béky096cf052017-08-08 23:55:339043 nullptr, 0, 2, 1, "http://www.example.org/foo.dat"));
bnc38dcd392016-02-09 23:19:499044
bncdf80d44fd2016-07-15 20:27:419045 SpdySerializedFrame stream1_body(spdy_util_.ConstructSpdyDataFrame(1, true));
tbansal8ef1d3e2016-02-03 04:05:429046
bncdf80d44fd2016-07-15 20:27:419047 SpdySerializedFrame stream2_reply(
bnc42331402016-07-25 13:36:159048 spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
tbansal8ef1d3e2016-02-03 04:05:429049
bncdf80d44fd2016-07-15 20:27:419050 SpdySerializedFrame stream2_body(spdy_util_.ConstructSpdyDataFrame(1, true));
tbansal8ef1d3e2016-02-03 04:05:429051
9052 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:419053 CreateMockRead(stream1_reply, 1, ASYNC),
9054 CreateMockRead(stream2_syn, 2, ASYNC),
tombergan5d22c182017-01-11 02:05:359055 CreateMockRead(stream1_body, 4, ASYNC),
9056 CreateMockRead(stream2_body, 5, ASYNC),
9057 MockRead(SYNCHRONOUS, ERR_IO_PENDING, 6), // Force a hang
tbansal8ef1d3e2016-02-03 04:05:429058 };
9059
9060 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
9061 arraysize(spdy_writes));
9062 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
9063 // Negotiate SPDY to the proxy
9064 SSLSocketDataProvider proxy(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:369065 proxy.next_proto = kProtoHTTP2;
tbansal8ef1d3e2016-02-03 04:05:429066 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy);
9067
bnc87dcefc2017-05-25 12:47:589068 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:199069 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
tbansal8ef1d3e2016-02-03 04:05:429070 TestCompletionCallback callback;
9071 int rv = trans->Start(&request, callback.callback(), log.bound());
robpercival214763f2016-07-01 23:27:019072 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
tbansal8ef1d3e2016-02-03 04:05:429073
9074 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:019075 EXPECT_THAT(rv, IsOk());
tbansal8ef1d3e2016-02-03 04:05:429076 const HttpResponseInfo* response = trans->GetResponseInfo();
9077
wezca1070932016-05-26 20:30:529078 ASSERT_TRUE(response);
tbansal8ef1d3e2016-02-03 04:05:429079 EXPECT_TRUE(response->headers->IsKeepAlive());
9080
9081 EXPECT_EQ(200, response->headers->response_code());
9082 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
9083
9084 std::string response_data;
9085 rv = ReadTransaction(trans.get(), &response_data);
robpercival214763f2016-07-01 23:27:019086 EXPECT_THAT(rv, IsOk());
tbansal8ef1d3e2016-02-03 04:05:429087 EXPECT_EQ("hello!", response_data);
9088
9089 trans.reset();
9090 session->CloseAllConnections();
9091}
9092
[email protected]2df19bb2010-08-25 20:13:469093// Test HTTPS connections to a site with a bad certificate, going through an
9094// HTTPS proxy
bncd16676a2016-07-20 16:23:019095TEST_F(HttpNetworkTransactionTest, HTTPSBadCertificateViaHttpsProxy) {
Lily Houghton8c2f97d2018-01-22 05:06:599096 session_deps_.proxy_resolution_service =
9097 ProxyResolutionService::CreateFixed("https://proxy:70");
[email protected]2df19bb2010-08-25 20:13:469098
9099 HttpRequestInfo request;
9100 request.method = "GET";
bncce36dca22015-04-21 22:11:239101 request.url = GURL("https://www.example.org/");
[email protected]2df19bb2010-08-25 20:13:469102
9103 // Attempt to fetch the URL from a server with a bad cert
9104 MockWrite bad_cert_writes[] = {
rsleevidb16bb02015-11-12 23:47:179105 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
9106 "Host: www.example.org:443\r\n"
9107 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]2df19bb2010-08-25 20:13:469108 };
9109
9110 MockRead bad_cert_reads[] = {
9111 MockRead("HTTP/1.0 200 Connected\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:069112 MockRead(SYNCHRONOUS, OK)
[email protected]2df19bb2010-08-25 20:13:469113 };
9114
9115 // Attempt to fetch the URL with a good cert
9116 MockWrite good_data_writes[] = {
rsleevidb16bb02015-11-12 23:47:179117 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
9118 "Host: www.example.org:443\r\n"
9119 "Proxy-Connection: keep-alive\r\n\r\n"),
9120 MockWrite("GET / HTTP/1.1\r\n"
9121 "Host: www.example.org\r\n"
9122 "Connection: keep-alive\r\n\r\n"),
[email protected]2df19bb2010-08-25 20:13:469123 };
9124
9125 MockRead good_cert_reads[] = {
9126 MockRead("HTTP/1.0 200 Connected\r\n\r\n"),
9127 MockRead("HTTP/1.0 200 OK\r\n"),
9128 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
9129 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:069130 MockRead(SYNCHRONOUS, OK),
[email protected]2df19bb2010-08-25 20:13:469131 };
9132
9133 StaticSocketDataProvider ssl_bad_certificate(
9134 bad_cert_reads, arraysize(bad_cert_reads),
9135 bad_cert_writes, arraysize(bad_cert_writes));
9136 StaticSocketDataProvider data(good_cert_reads, arraysize(good_cert_reads),
9137 good_data_writes, arraysize(good_data_writes));
[email protected]8ddf8322012-02-23 18:08:069138 SSLSocketDataProvider ssl_bad(ASYNC, ERR_CERT_AUTHORITY_INVALID);
9139 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]2df19bb2010-08-25 20:13:469140
9141 // SSL to the proxy, then CONNECT request, then SSL with bad certificate
[email protected]bb88e1d32013-05-03 23:11:079142 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
9143 session_deps_.socket_factory->AddSocketDataProvider(&ssl_bad_certificate);
9144 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_bad);
[email protected]2df19bb2010-08-25 20:13:469145
9146 // SSL to the proxy, then CONNECT request, then valid SSL certificate
[email protected]bb88e1d32013-05-03 23:11:079147 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
9148 session_deps_.socket_factory->AddSocketDataProvider(&data);
9149 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]2df19bb2010-08-25 20:13:469150
[email protected]49639fa2011-12-20 23:22:419151 TestCompletionCallback callback;
[email protected]2df19bb2010-08-25 20:13:469152
danakj1fd259a02016-04-16 03:17:099153 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:169154 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]2df19bb2010-08-25 20:13:469155
tfarina42834112016-09-22 13:38:209156 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:019157 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2df19bb2010-08-25 20:13:469158
9159 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:019160 EXPECT_THAT(rv, IsError(ERR_CERT_AUTHORITY_INVALID));
[email protected]2df19bb2010-08-25 20:13:469161
bnc691fda62016-08-12 00:43:169162 rv = trans.RestartIgnoringLastError(callback.callback());
robpercival214763f2016-07-01 23:27:019163 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2df19bb2010-08-25 20:13:469164
9165 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:019166 EXPECT_THAT(rv, IsOk());
[email protected]2df19bb2010-08-25 20:13:469167
bnc691fda62016-08-12 00:43:169168 const HttpResponseInfo* response = trans.GetResponseInfo();
[email protected]2df19bb2010-08-25 20:13:469169
wezca1070932016-05-26 20:30:529170 ASSERT_TRUE(response);
[email protected]2df19bb2010-08-25 20:13:469171 EXPECT_EQ(100, response->headers->GetContentLength());
9172}
9173
bncd16676a2016-07-20 16:23:019174TEST_F(HttpNetworkTransactionTest, BuildRequest_UserAgent) {
[email protected]1c773ea12009-04-28 19:58:429175 HttpRequestInfo request;
9176 request.method = "GET";
bncce36dca22015-04-21 22:11:239177 request.url = GURL("http://www.example.org/");
[email protected]8c76ae22010-04-20 22:15:439178 request.extra_headers.SetHeader(HttpRequestHeaders::kUserAgent,
9179 "Chromium Ultra Awesome X Edition");
[email protected]1c773ea12009-04-28 19:58:429180
danakj1fd259a02016-04-16 03:17:099181 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:169182 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:279183
[email protected]1c773ea12009-04-28 19:58:429184 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:239185 MockWrite(
9186 "GET / HTTP/1.1\r\n"
9187 "Host: www.example.org\r\n"
9188 "Connection: keep-alive\r\n"
9189 "User-Agent: Chromium Ultra Awesome X Edition\r\n\r\n"),
[email protected]1c773ea12009-04-28 19:58:429190 };
9191
9192 // Lastly, the server responds with the actual content.
9193 MockRead data_reads[] = {
9194 MockRead("HTTP/1.0 200 OK\r\n"),
9195 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
9196 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:069197 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:429198 };
9199
[email protected]31a2bfe2010-02-09 08:03:399200 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
9201 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:079202 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:429203
[email protected]49639fa2011-12-20 23:22:419204 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:429205
tfarina42834112016-09-22 13:38:209206 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:019207 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]1c773ea12009-04-28 19:58:429208
9209 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:019210 EXPECT_THAT(rv, IsOk());
[email protected]1c773ea12009-04-28 19:58:429211}
9212
bncd16676a2016-07-20 16:23:019213TEST_F(HttpNetworkTransactionTest, BuildRequest_UserAgentOverTunnel) {
[email protected]da81f132010-08-18 23:39:299214 HttpRequestInfo request;
9215 request.method = "GET";
bncce36dca22015-04-21 22:11:239216 request.url = GURL("https://www.example.org/");
[email protected]da81f132010-08-18 23:39:299217 request.extra_headers.SetHeader(HttpRequestHeaders::kUserAgent,
9218 "Chromium Ultra Awesome X Edition");
9219
Lily Houghton8c2f97d2018-01-22 05:06:599220 session_deps_.proxy_resolution_service =
9221 ProxyResolutionService::CreateFixed("myproxy:70");
danakj1fd259a02016-04-16 03:17:099222 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:169223 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:279224
[email protected]da81f132010-08-18 23:39:299225 MockWrite data_writes[] = {
rsleevidb16bb02015-11-12 23:47:179226 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
9227 "Host: www.example.org:443\r\n"
9228 "Proxy-Connection: keep-alive\r\n"
9229 "User-Agent: Chromium Ultra Awesome X Edition\r\n\r\n"),
[email protected]da81f132010-08-18 23:39:299230 };
9231 MockRead data_reads[] = {
9232 // Return an error, so the transaction stops here (this test isn't
9233 // interested in the rest).
9234 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
9235 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
9236 MockRead("Proxy-Connection: close\r\n\r\n"),
9237 };
9238
9239 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
9240 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:079241 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]da81f132010-08-18 23:39:299242
[email protected]49639fa2011-12-20 23:22:419243 TestCompletionCallback callback;
[email protected]da81f132010-08-18 23:39:299244
tfarina42834112016-09-22 13:38:209245 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:019246 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]da81f132010-08-18 23:39:299247
9248 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:019249 EXPECT_THAT(rv, IsOk());
[email protected]da81f132010-08-18 23:39:299250}
9251
bncd16676a2016-07-20 16:23:019252TEST_F(HttpNetworkTransactionTest, BuildRequest_Referer) {
[email protected]1c773ea12009-04-28 19:58:429253 HttpRequestInfo request;
9254 request.method = "GET";
bncce36dca22015-04-21 22:11:239255 request.url = GURL("http://www.example.org/");
[email protected]c10450102011-06-27 09:06:169256 request.extra_headers.SetHeader(HttpRequestHeaders::kReferer,
9257 "http://the.previous.site.com/");
[email protected]1c773ea12009-04-28 19:58:429258
danakj1fd259a02016-04-16 03:17:099259 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:169260 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:279261
[email protected]1c773ea12009-04-28 19:58:429262 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:239263 MockWrite(
9264 "GET / HTTP/1.1\r\n"
9265 "Host: www.example.org\r\n"
9266 "Connection: keep-alive\r\n"
9267 "Referer: http://the.previous.site.com/\r\n\r\n"),
[email protected]1c773ea12009-04-28 19:58:429268 };
9269
9270 // Lastly, the server responds with the actual content.
9271 MockRead data_reads[] = {
9272 MockRead("HTTP/1.0 200 OK\r\n"),
9273 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
9274 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:069275 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:429276 };
9277
[email protected]31a2bfe2010-02-09 08:03:399278 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
9279 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:079280 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:429281
[email protected]49639fa2011-12-20 23:22:419282 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:429283
tfarina42834112016-09-22 13:38:209284 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:019285 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]1c773ea12009-04-28 19:58:429286
9287 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:019288 EXPECT_THAT(rv, IsOk());
[email protected]1c773ea12009-04-28 19:58:429289}
9290
bncd16676a2016-07-20 16:23:019291TEST_F(HttpNetworkTransactionTest, BuildRequest_PostContentLengthZero) {
[email protected]1c773ea12009-04-28 19:58:429292 HttpRequestInfo request;
9293 request.method = "POST";
bncce36dca22015-04-21 22:11:239294 request.url = GURL("http://www.example.org/");
[email protected]1c773ea12009-04-28 19:58:429295
danakj1fd259a02016-04-16 03:17:099296 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:169297 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:279298
[email protected]1c773ea12009-04-28 19:58:429299 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:239300 MockWrite(
9301 "POST / HTTP/1.1\r\n"
9302 "Host: www.example.org\r\n"
9303 "Connection: keep-alive\r\n"
9304 "Content-Length: 0\r\n\r\n"),
[email protected]1c773ea12009-04-28 19:58:429305 };
9306
9307 // Lastly, the server responds with the actual content.
9308 MockRead data_reads[] = {
9309 MockRead("HTTP/1.0 200 OK\r\n"),
9310 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
9311 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:069312 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:429313 };
9314
[email protected]31a2bfe2010-02-09 08:03:399315 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
9316 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:079317 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:429318
[email protected]49639fa2011-12-20 23:22:419319 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:429320
tfarina42834112016-09-22 13:38:209321 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:019322 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]1c773ea12009-04-28 19:58:429323
9324 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:019325 EXPECT_THAT(rv, IsOk());
[email protected]1c773ea12009-04-28 19:58:429326}
9327
bncd16676a2016-07-20 16:23:019328TEST_F(HttpNetworkTransactionTest, BuildRequest_PutContentLengthZero) {
[email protected]1c773ea12009-04-28 19:58:429329 HttpRequestInfo request;
9330 request.method = "PUT";
bncce36dca22015-04-21 22:11:239331 request.url = GURL("http://www.example.org/");
[email protected]1c773ea12009-04-28 19:58:429332
danakj1fd259a02016-04-16 03:17:099333 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:169334 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:279335
[email protected]1c773ea12009-04-28 19:58:429336 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:239337 MockWrite(
9338 "PUT / HTTP/1.1\r\n"
9339 "Host: www.example.org\r\n"
9340 "Connection: keep-alive\r\n"
9341 "Content-Length: 0\r\n\r\n"),
[email protected]1c773ea12009-04-28 19:58:429342 };
9343
9344 // Lastly, the server responds with the actual content.
9345 MockRead data_reads[] = {
9346 MockRead("HTTP/1.0 200 OK\r\n"),
9347 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
9348 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:069349 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:429350 };
9351
[email protected]31a2bfe2010-02-09 08:03:399352 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
9353 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:079354 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:429355
[email protected]49639fa2011-12-20 23:22:419356 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:429357
tfarina42834112016-09-22 13:38:209358 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:019359 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]1c773ea12009-04-28 19:58:429360
9361 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:019362 EXPECT_THAT(rv, IsOk());
[email protected]1c773ea12009-04-28 19:58:429363}
9364
bncd16676a2016-07-20 16:23:019365TEST_F(HttpNetworkTransactionTest, BuildRequest_HeadContentLengthZero) {
[email protected]1c773ea12009-04-28 19:58:429366 HttpRequestInfo request;
9367 request.method = "HEAD";
bncce36dca22015-04-21 22:11:239368 request.url = GURL("http://www.example.org/");
[email protected]1c773ea12009-04-28 19:58:429369
danakj1fd259a02016-04-16 03:17:099370 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:169371 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:279372
[email protected]1c773ea12009-04-28 19:58:429373 MockWrite data_writes[] = {
csharrisonf473dd192015-08-18 13:54:139374 MockWrite("HEAD / HTTP/1.1\r\n"
9375 "Host: www.example.org\r\n"
9376 "Connection: keep-alive\r\n\r\n"),
[email protected]1c773ea12009-04-28 19:58:429377 };
9378
9379 // Lastly, the server responds with the actual content.
9380 MockRead data_reads[] = {
9381 MockRead("HTTP/1.0 200 OK\r\n"),
9382 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
9383 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:069384 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:429385 };
9386
[email protected]31a2bfe2010-02-09 08:03:399387 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
9388 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:079389 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:429390
[email protected]49639fa2011-12-20 23:22:419391 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:429392
tfarina42834112016-09-22 13:38:209393 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:019394 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]1c773ea12009-04-28 19:58:429395
9396 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:019397 EXPECT_THAT(rv, IsOk());
[email protected]1c773ea12009-04-28 19:58:429398}
9399
bncd16676a2016-07-20 16:23:019400TEST_F(HttpNetworkTransactionTest, BuildRequest_CacheControlNoCache) {
[email protected]1c773ea12009-04-28 19:58:429401 HttpRequestInfo request;
9402 request.method = "GET";
bncce36dca22015-04-21 22:11:239403 request.url = GURL("http://www.example.org/");
[email protected]1c773ea12009-04-28 19:58:429404 request.load_flags = LOAD_BYPASS_CACHE;
9405
danakj1fd259a02016-04-16 03:17:099406 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:169407 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:279408
[email protected]1c773ea12009-04-28 19:58:429409 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:239410 MockWrite(
9411 "GET / HTTP/1.1\r\n"
9412 "Host: www.example.org\r\n"
9413 "Connection: keep-alive\r\n"
9414 "Pragma: no-cache\r\n"
9415 "Cache-Control: no-cache\r\n\r\n"),
[email protected]1c773ea12009-04-28 19:58:429416 };
9417
9418 // Lastly, the server responds with the actual content.
9419 MockRead data_reads[] = {
9420 MockRead("HTTP/1.0 200 OK\r\n"),
9421 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
9422 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:069423 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:429424 };
9425
[email protected]31a2bfe2010-02-09 08:03:399426 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
9427 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:079428 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:429429
[email protected]49639fa2011-12-20 23:22:419430 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:429431
tfarina42834112016-09-22 13:38:209432 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:019433 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]1c773ea12009-04-28 19:58:429434
9435 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:019436 EXPECT_THAT(rv, IsOk());
[email protected]1c773ea12009-04-28 19:58:429437}
9438
bncd16676a2016-07-20 16:23:019439TEST_F(HttpNetworkTransactionTest, BuildRequest_CacheControlValidateCache) {
[email protected]1c773ea12009-04-28 19:58:429440 HttpRequestInfo request;
9441 request.method = "GET";
bncce36dca22015-04-21 22:11:239442 request.url = GURL("http://www.example.org/");
[email protected]1c773ea12009-04-28 19:58:429443 request.load_flags = LOAD_VALIDATE_CACHE;
9444
danakj1fd259a02016-04-16 03:17:099445 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:169446 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:279447
[email protected]1c773ea12009-04-28 19:58:429448 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:239449 MockWrite(
9450 "GET / HTTP/1.1\r\n"
9451 "Host: www.example.org\r\n"
9452 "Connection: keep-alive\r\n"
9453 "Cache-Control: max-age=0\r\n\r\n"),
[email protected]1c773ea12009-04-28 19:58:429454 };
9455
9456 // Lastly, the server responds with the actual content.
9457 MockRead data_reads[] = {
9458 MockRead("HTTP/1.0 200 OK\r\n"),
9459 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
9460 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:069461 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:429462 };
9463
[email protected]31a2bfe2010-02-09 08:03:399464 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
9465 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:079466 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:429467
[email protected]49639fa2011-12-20 23:22:419468 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:429469
tfarina42834112016-09-22 13:38:209470 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:019471 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]1c773ea12009-04-28 19:58:429472
9473 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:019474 EXPECT_THAT(rv, IsOk());
[email protected]1c773ea12009-04-28 19:58:429475}
9476
bncd16676a2016-07-20 16:23:019477TEST_F(HttpNetworkTransactionTest, BuildRequest_ExtraHeaders) {
[email protected]1c773ea12009-04-28 19:58:429478 HttpRequestInfo request;
9479 request.method = "GET";
bncce36dca22015-04-21 22:11:239480 request.url = GURL("http://www.example.org/");
[email protected]8c76ae22010-04-20 22:15:439481 request.extra_headers.SetHeader("FooHeader", "Bar");
[email protected]1c773ea12009-04-28 19:58:429482
danakj1fd259a02016-04-16 03:17:099483 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:169484 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:279485
[email protected]1c773ea12009-04-28 19:58:429486 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:239487 MockWrite(
9488 "GET / HTTP/1.1\r\n"
9489 "Host: www.example.org\r\n"
9490 "Connection: keep-alive\r\n"
9491 "FooHeader: Bar\r\n\r\n"),
[email protected]1c773ea12009-04-28 19:58:429492 };
9493
9494 // Lastly, the server responds with the actual content.
9495 MockRead data_reads[] = {
9496 MockRead("HTTP/1.0 200 OK\r\n"),
9497 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
9498 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:069499 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:429500 };
9501
[email protected]31a2bfe2010-02-09 08:03:399502 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
9503 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:079504 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:429505
[email protected]49639fa2011-12-20 23:22:419506 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:429507
tfarina42834112016-09-22 13:38:209508 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:019509 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]1c773ea12009-04-28 19:58:429510
9511 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:019512 EXPECT_THAT(rv, IsOk());
[email protected]1c773ea12009-04-28 19:58:429513}
9514
bncd16676a2016-07-20 16:23:019515TEST_F(HttpNetworkTransactionTest, BuildRequest_ExtraHeadersStripped) {
[email protected]270c6412010-03-29 22:02:479516 HttpRequestInfo request;
9517 request.method = "GET";
bncce36dca22015-04-21 22:11:239518 request.url = GURL("http://www.example.org/");
[email protected]8c76ae22010-04-20 22:15:439519 request.extra_headers.SetHeader("referer", "www.foo.com");
9520 request.extra_headers.SetHeader("hEllo", "Kitty");
9521 request.extra_headers.SetHeader("FoO", "bar");
[email protected]270c6412010-03-29 22:02:479522
danakj1fd259a02016-04-16 03:17:099523 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:169524 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:279525
[email protected]270c6412010-03-29 22:02:479526 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:239527 MockWrite(
9528 "GET / HTTP/1.1\r\n"
9529 "Host: www.example.org\r\n"
9530 "Connection: keep-alive\r\n"
9531 "referer: www.foo.com\r\n"
9532 "hEllo: Kitty\r\n"
9533 "FoO: bar\r\n\r\n"),
[email protected]270c6412010-03-29 22:02:479534 };
9535
9536 // Lastly, the server responds with the actual content.
9537 MockRead data_reads[] = {
9538 MockRead("HTTP/1.0 200 OK\r\n"),
9539 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
9540 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:069541 MockRead(SYNCHRONOUS, OK),
[email protected]270c6412010-03-29 22:02:479542 };
9543
9544 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
9545 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:079546 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]270c6412010-03-29 22:02:479547
[email protected]49639fa2011-12-20 23:22:419548 TestCompletionCallback callback;
[email protected]270c6412010-03-29 22:02:479549
tfarina42834112016-09-22 13:38:209550 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:019551 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]270c6412010-03-29 22:02:479552
9553 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:019554 EXPECT_THAT(rv, IsOk());
[email protected]270c6412010-03-29 22:02:479555}
9556
bncd16676a2016-07-20 16:23:019557TEST_F(HttpNetworkTransactionTest, SOCKS4_HTTP_GET) {
[email protected]cb9bf6ca2011-01-28 13:15:279558 HttpRequestInfo request;
9559 request.method = "GET";
bncce36dca22015-04-21 22:11:239560 request.url = GURL("http://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:279561
Lily Houghton8c2f97d2018-01-22 05:06:599562 session_deps_.proxy_resolution_service =
9563 ProxyResolutionService::CreateFixedFromPacResult("SOCKS myproxy:1080");
vishal.b62985ca92015-04-17 08:45:519564 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:079565 session_deps_.net_log = &net_log;
[email protected]3cd17242009-06-23 02:59:029566
danakj1fd259a02016-04-16 03:17:099567 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:169568 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]3cd17242009-06-23 02:59:029569
[email protected]3cd17242009-06-23 02:59:029570 char write_buffer[] = { 0x04, 0x01, 0x00, 0x50, 127, 0, 0, 1, 0 };
9571 char read_buffer[] = { 0x00, 0x5A, 0x00, 0x00, 0, 0, 0, 0 };
9572
9573 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:239574 MockWrite(ASYNC, write_buffer, arraysize(write_buffer)),
9575 MockWrite(
9576 "GET / HTTP/1.1\r\n"
9577 "Host: www.example.org\r\n"
9578 "Connection: keep-alive\r\n\r\n")};
[email protected]3cd17242009-06-23 02:59:029579
9580 MockRead data_reads[] = {
[email protected]8ddf8322012-02-23 18:08:069581 MockRead(ASYNC, read_buffer, arraysize(read_buffer)),
[email protected]3cd17242009-06-23 02:59:029582 MockRead("HTTP/1.0 200 OK\r\n"),
9583 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n\r\n"),
9584 MockRead("Payload"),
[email protected]8ddf8322012-02-23 18:08:069585 MockRead(SYNCHRONOUS, OK)
[email protected]3cd17242009-06-23 02:59:029586 };
9587
[email protected]31a2bfe2010-02-09 08:03:399588 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
9589 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:079590 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]3cd17242009-06-23 02:59:029591
[email protected]49639fa2011-12-20 23:22:419592 TestCompletionCallback callback;
[email protected]3cd17242009-06-23 02:59:029593
tfarina42834112016-09-22 13:38:209594 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:019595 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]3cd17242009-06-23 02:59:029596
9597 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:019598 EXPECT_THAT(rv, IsOk());
[email protected]3cd17242009-06-23 02:59:029599
bnc691fda62016-08-12 00:43:169600 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:529601 ASSERT_TRUE(response);
[email protected]3cd17242009-06-23 02:59:029602
tbansal2ecbbc72016-10-06 17:15:479603 EXPECT_EQ(ProxyServer::SCHEME_SOCKS4, response->proxy_server.scheme());
[email protected]029c83b62013-01-24 05:28:209604 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:169605 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]029c83b62013-01-24 05:28:209606 TestLoadTimingNotReusedWithPac(load_timing_info,
9607 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
9608
[email protected]3cd17242009-06-23 02:59:029609 std::string response_text;
bnc691fda62016-08-12 00:43:169610 rv = ReadTransaction(&trans, &response_text);
robpercival214763f2016-07-01 23:27:019611 EXPECT_THAT(rv, IsOk());
[email protected]3cd17242009-06-23 02:59:029612 EXPECT_EQ("Payload", response_text);
9613}
9614
bncd16676a2016-07-20 16:23:019615TEST_F(HttpNetworkTransactionTest, SOCKS4_SSL_GET) {
[email protected]cb9bf6ca2011-01-28 13:15:279616 HttpRequestInfo request;
9617 request.method = "GET";
bncce36dca22015-04-21 22:11:239618 request.url = GURL("https://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:279619
Lily Houghton8c2f97d2018-01-22 05:06:599620 session_deps_.proxy_resolution_service =
9621 ProxyResolutionService::CreateFixedFromPacResult("SOCKS myproxy:1080");
vishal.b62985ca92015-04-17 08:45:519622 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:079623 session_deps_.net_log = &net_log;
[email protected]3cd17242009-06-23 02:59:029624
danakj1fd259a02016-04-16 03:17:099625 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:169626 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]3cd17242009-06-23 02:59:029627
[email protected]3cd17242009-06-23 02:59:029628 unsigned char write_buffer[] = { 0x04, 0x01, 0x01, 0xBB, 127, 0, 0, 1, 0 };
9629 unsigned char read_buffer[] = { 0x00, 0x5A, 0x00, 0x00, 0, 0, 0, 0 };
9630
9631 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:239632 MockWrite(ASYNC, reinterpret_cast<char*>(write_buffer),
9633 arraysize(write_buffer)),
9634 MockWrite(
9635 "GET / HTTP/1.1\r\n"
9636 "Host: www.example.org\r\n"
9637 "Connection: keep-alive\r\n\r\n")};
[email protected]3cd17242009-06-23 02:59:029638
9639 MockRead data_reads[] = {
[email protected]f871ee152012-07-27 19:02:019640 MockRead(ASYNC, reinterpret_cast<char*>(read_buffer),
9641 arraysize(read_buffer)),
[email protected]e0c27be2009-07-15 13:09:359642 MockRead("HTTP/1.0 200 OK\r\n"),
9643 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n\r\n"),
9644 MockRead("Payload"),
[email protected]8ddf8322012-02-23 18:08:069645 MockRead(SYNCHRONOUS, OK)
[email protected]e0c27be2009-07-15 13:09:359646 };
9647
[email protected]31a2bfe2010-02-09 08:03:399648 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
9649 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:079650 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]e0c27be2009-07-15 13:09:359651
[email protected]8ddf8322012-02-23 18:08:069652 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:079653 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]e0c27be2009-07-15 13:09:359654
[email protected]49639fa2011-12-20 23:22:419655 TestCompletionCallback callback;
[email protected]e0c27be2009-07-15 13:09:359656
tfarina42834112016-09-22 13:38:209657 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:019658 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]e0c27be2009-07-15 13:09:359659
9660 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:019661 EXPECT_THAT(rv, IsOk());
[email protected]e0c27be2009-07-15 13:09:359662
[email protected]029c83b62013-01-24 05:28:209663 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:169664 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]029c83b62013-01-24 05:28:209665 TestLoadTimingNotReusedWithPac(load_timing_info,
9666 CONNECT_TIMING_HAS_SSL_TIMES);
9667
bnc691fda62016-08-12 00:43:169668 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:529669 ASSERT_TRUE(response);
tbansal2ecbbc72016-10-06 17:15:479670 EXPECT_EQ(ProxyServer::SCHEME_SOCKS4, response->proxy_server.scheme());
[email protected]e0c27be2009-07-15 13:09:359671
9672 std::string response_text;
bnc691fda62016-08-12 00:43:169673 rv = ReadTransaction(&trans, &response_text);
robpercival214763f2016-07-01 23:27:019674 EXPECT_THAT(rv, IsOk());
[email protected]e0c27be2009-07-15 13:09:359675 EXPECT_EQ("Payload", response_text);
9676}
9677
bncd16676a2016-07-20 16:23:019678TEST_F(HttpNetworkTransactionTest, SOCKS4_HTTP_GET_no_PAC) {
[email protected]029c83b62013-01-24 05:28:209679 HttpRequestInfo request;
9680 request.method = "GET";
bncce36dca22015-04-21 22:11:239681 request.url = GURL("http://www.example.org/");
[email protected]029c83b62013-01-24 05:28:209682
Lily Houghton8c2f97d2018-01-22 05:06:599683 session_deps_.proxy_resolution_service =
9684 ProxyResolutionService::CreateFixed("socks4://myproxy:1080");
vishal.b62985ca92015-04-17 08:45:519685 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:079686 session_deps_.net_log = &net_log;
[email protected]029c83b62013-01-24 05:28:209687
danakj1fd259a02016-04-16 03:17:099688 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:169689 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]029c83b62013-01-24 05:28:209690
9691 char write_buffer[] = { 0x04, 0x01, 0x00, 0x50, 127, 0, 0, 1, 0 };
9692 char read_buffer[] = { 0x00, 0x5A, 0x00, 0x00, 0, 0, 0, 0 };
9693
9694 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:239695 MockWrite(ASYNC, write_buffer, arraysize(write_buffer)),
9696 MockWrite(
9697 "GET / HTTP/1.1\r\n"
9698 "Host: www.example.org\r\n"
9699 "Connection: keep-alive\r\n\r\n")};
[email protected]029c83b62013-01-24 05:28:209700
9701 MockRead data_reads[] = {
9702 MockRead(ASYNC, read_buffer, arraysize(read_buffer)),
9703 MockRead("HTTP/1.0 200 OK\r\n"),
9704 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n\r\n"),
9705 MockRead("Payload"),
9706 MockRead(SYNCHRONOUS, OK)
9707 };
9708
9709 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
9710 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:079711 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]029c83b62013-01-24 05:28:209712
9713 TestCompletionCallback callback;
9714
tfarina42834112016-09-22 13:38:209715 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:019716 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]029c83b62013-01-24 05:28:209717
9718 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:019719 EXPECT_THAT(rv, IsOk());
[email protected]029c83b62013-01-24 05:28:209720
bnc691fda62016-08-12 00:43:169721 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:529722 ASSERT_TRUE(response);
[email protected]029c83b62013-01-24 05:28:209723
9724 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:169725 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]029c83b62013-01-24 05:28:209726 TestLoadTimingNotReused(load_timing_info,
9727 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
9728
9729 std::string response_text;
bnc691fda62016-08-12 00:43:169730 rv = ReadTransaction(&trans, &response_text);
robpercival214763f2016-07-01 23:27:019731 EXPECT_THAT(rv, IsOk());
[email protected]029c83b62013-01-24 05:28:209732 EXPECT_EQ("Payload", response_text);
9733}
9734
bncd16676a2016-07-20 16:23:019735TEST_F(HttpNetworkTransactionTest, SOCKS5_HTTP_GET) {
[email protected]cb9bf6ca2011-01-28 13:15:279736 HttpRequestInfo request;
9737 request.method = "GET";
bncce36dca22015-04-21 22:11:239738 request.url = GURL("http://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:279739
Lily Houghton8c2f97d2018-01-22 05:06:599740 session_deps_.proxy_resolution_service =
9741 ProxyResolutionService::CreateFixedFromPacResult("SOCKS5 myproxy:1080");
vishal.b62985ca92015-04-17 08:45:519742 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:079743 session_deps_.net_log = &net_log;
[email protected]e0c27be2009-07-15 13:09:359744
danakj1fd259a02016-04-16 03:17:099745 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:169746 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]e0c27be2009-07-15 13:09:359747
[email protected]e0c27be2009-07-15 13:09:359748 const char kSOCKS5GreetRequest[] = { 0x05, 0x01, 0x00 };
9749 const char kSOCKS5GreetResponse[] = { 0x05, 0x00 };
[email protected]f209dba2009-12-18 00:24:379750 const char kSOCKS5OkRequest[] = {
bncce36dca22015-04-21 22:11:239751 0x05, // Version
9752 0x01, // Command (CONNECT)
9753 0x00, // Reserved.
9754 0x03, // Address type (DOMAINNAME).
9755 0x0F, // Length of domain (15)
9756 'w', 'w', 'w', '.', 'e', 'x', 'a', 'm', 'p', 'l', 'e', // Domain string
9757 '.', 'o', 'r', 'g', 0x00, 0x50, // 16-bit port (80)
[email protected]f209dba2009-12-18 00:24:379758 };
[email protected]e0c27be2009-07-15 13:09:359759 const char kSOCKS5OkResponse[] =
9760 { 0x05, 0x00, 0x00, 0x01, 127, 0, 0, 1, 0x00, 0x50 };
9761
9762 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:239763 MockWrite(ASYNC, kSOCKS5GreetRequest, arraysize(kSOCKS5GreetRequest)),
9764 MockWrite(ASYNC, kSOCKS5OkRequest, arraysize(kSOCKS5OkRequest)),
9765 MockWrite(
9766 "GET / HTTP/1.1\r\n"
9767 "Host: www.example.org\r\n"
9768 "Connection: keep-alive\r\n\r\n")};
[email protected]e0c27be2009-07-15 13:09:359769
9770 MockRead data_reads[] = {
[email protected]f871ee152012-07-27 19:02:019771 MockRead(ASYNC, kSOCKS5GreetResponse, arraysize(kSOCKS5GreetResponse)),
9772 MockRead(ASYNC, kSOCKS5OkResponse, arraysize(kSOCKS5OkResponse)),
[email protected]e0c27be2009-07-15 13:09:359773 MockRead("HTTP/1.0 200 OK\r\n"),
9774 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n\r\n"),
9775 MockRead("Payload"),
[email protected]8ddf8322012-02-23 18:08:069776 MockRead(SYNCHRONOUS, OK)
[email protected]e0c27be2009-07-15 13:09:359777 };
9778
[email protected]31a2bfe2010-02-09 08:03:399779 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
9780 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:079781 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]e0c27be2009-07-15 13:09:359782
[email protected]49639fa2011-12-20 23:22:419783 TestCompletionCallback callback;
[email protected]e0c27be2009-07-15 13:09:359784
tfarina42834112016-09-22 13:38:209785 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:019786 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]e0c27be2009-07-15 13:09:359787
9788 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:019789 EXPECT_THAT(rv, IsOk());
[email protected]e0c27be2009-07-15 13:09:359790
bnc691fda62016-08-12 00:43:169791 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:529792 ASSERT_TRUE(response);
tbansal2ecbbc72016-10-06 17:15:479793 EXPECT_EQ(ProxyServer::SCHEME_SOCKS5, response->proxy_server.scheme());
[email protected]e0c27be2009-07-15 13:09:359794
[email protected]029c83b62013-01-24 05:28:209795 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:169796 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]029c83b62013-01-24 05:28:209797 TestLoadTimingNotReusedWithPac(load_timing_info,
9798 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
9799
[email protected]e0c27be2009-07-15 13:09:359800 std::string response_text;
bnc691fda62016-08-12 00:43:169801 rv = ReadTransaction(&trans, &response_text);
robpercival214763f2016-07-01 23:27:019802 EXPECT_THAT(rv, IsOk());
[email protected]e0c27be2009-07-15 13:09:359803 EXPECT_EQ("Payload", response_text);
9804}
9805
bncd16676a2016-07-20 16:23:019806TEST_F(HttpNetworkTransactionTest, SOCKS5_SSL_GET) {
[email protected]cb9bf6ca2011-01-28 13:15:279807 HttpRequestInfo request;
9808 request.method = "GET";
bncce36dca22015-04-21 22:11:239809 request.url = GURL("https://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:279810
Lily Houghton8c2f97d2018-01-22 05:06:599811 session_deps_.proxy_resolution_service =
9812 ProxyResolutionService::CreateFixedFromPacResult("SOCKS5 myproxy:1080");
vishal.b62985ca92015-04-17 08:45:519813 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:079814 session_deps_.net_log = &net_log;
[email protected]e0c27be2009-07-15 13:09:359815
danakj1fd259a02016-04-16 03:17:099816 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:169817 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]e0c27be2009-07-15 13:09:359818
[email protected]e0c27be2009-07-15 13:09:359819 const char kSOCKS5GreetRequest[] = { 0x05, 0x01, 0x00 };
9820 const char kSOCKS5GreetResponse[] = { 0x05, 0x00 };
[email protected]f209dba2009-12-18 00:24:379821 const unsigned char kSOCKS5OkRequest[] = {
bncce36dca22015-04-21 22:11:239822 0x05, // Version
9823 0x01, // Command (CONNECT)
9824 0x00, // Reserved.
9825 0x03, // Address type (DOMAINNAME).
9826 0x0F, // Length of domain (15)
9827 'w', 'w', 'w', '.', 'e', 'x', 'a', 'm', 'p', 'l', 'e', // Domain string
9828 '.', 'o', 'r', 'g', 0x01, 0xBB, // 16-bit port (443)
[email protected]f209dba2009-12-18 00:24:379829 };
9830
[email protected]e0c27be2009-07-15 13:09:359831 const char kSOCKS5OkResponse[] =
9832 { 0x05, 0x00, 0x00, 0x01, 0, 0, 0, 0, 0x00, 0x00 };
9833
9834 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:239835 MockWrite(ASYNC, kSOCKS5GreetRequest, arraysize(kSOCKS5GreetRequest)),
9836 MockWrite(ASYNC, reinterpret_cast<const char*>(kSOCKS5OkRequest),
9837 arraysize(kSOCKS5OkRequest)),
9838 MockWrite(
9839 "GET / HTTP/1.1\r\n"
9840 "Host: www.example.org\r\n"
9841 "Connection: keep-alive\r\n\r\n")};
[email protected]e0c27be2009-07-15 13:09:359842
9843 MockRead data_reads[] = {
[email protected]f871ee152012-07-27 19:02:019844 MockRead(ASYNC, kSOCKS5GreetResponse, arraysize(kSOCKS5GreetResponse)),
9845 MockRead(ASYNC, kSOCKS5OkResponse, arraysize(kSOCKS5OkResponse)),
[email protected]3cd17242009-06-23 02:59:029846 MockRead("HTTP/1.0 200 OK\r\n"),
9847 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n\r\n"),
9848 MockRead("Payload"),
[email protected]8ddf8322012-02-23 18:08:069849 MockRead(SYNCHRONOUS, OK)
[email protected]3cd17242009-06-23 02:59:029850 };
9851
[email protected]31a2bfe2010-02-09 08:03:399852 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
9853 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:079854 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]3cd17242009-06-23 02:59:029855
[email protected]8ddf8322012-02-23 18:08:069856 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:079857 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]3cd17242009-06-23 02:59:029858
[email protected]49639fa2011-12-20 23:22:419859 TestCompletionCallback callback;
[email protected]3cd17242009-06-23 02:59:029860
tfarina42834112016-09-22 13:38:209861 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:019862 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]3cd17242009-06-23 02:59:029863
9864 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:019865 EXPECT_THAT(rv, IsOk());
[email protected]3cd17242009-06-23 02:59:029866
bnc691fda62016-08-12 00:43:169867 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:529868 ASSERT_TRUE(response);
tbansal2ecbbc72016-10-06 17:15:479869 EXPECT_EQ(ProxyServer::SCHEME_SOCKS5, response->proxy_server.scheme());
[email protected]3cd17242009-06-23 02:59:029870
[email protected]029c83b62013-01-24 05:28:209871 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:169872 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]029c83b62013-01-24 05:28:209873 TestLoadTimingNotReusedWithPac(load_timing_info,
9874 CONNECT_TIMING_HAS_SSL_TIMES);
9875
[email protected]3cd17242009-06-23 02:59:029876 std::string response_text;
bnc691fda62016-08-12 00:43:169877 rv = ReadTransaction(&trans, &response_text);
robpercival214763f2016-07-01 23:27:019878 EXPECT_THAT(rv, IsOk());
[email protected]3cd17242009-06-23 02:59:029879 EXPECT_EQ("Payload", response_text);
9880}
9881
[email protected]448d4ca52012-03-04 04:12:239882namespace {
9883
[email protected]04e5be32009-06-26 20:00:319884// Tests that for connection endpoints the group names are correctly set.
[email protected]2d731a32010-04-29 01:04:069885
9886struct GroupNameTest {
9887 std::string proxy_server;
9888 std::string url;
9889 std::string expected_group_name;
[email protected]e60e47a2010-07-14 03:37:189890 bool ssl;
[email protected]2d731a32010-04-29 01:04:069891};
9892
danakj1fd259a02016-04-16 03:17:099893std::unique_ptr<HttpNetworkSession> SetupSessionForGroupNameTests(
[email protected]bb88e1d32013-05-03 23:11:079894 SpdySessionDependencies* session_deps_) {
danakj1fd259a02016-04-16 03:17:099895 std::unique_ptr<HttpNetworkSession> session(CreateSession(session_deps_));
[email protected]2d731a32010-04-29 01:04:069896
bnc525e175a2016-06-20 12:36:409897 HttpServerProperties* http_server_properties =
[email protected]17291a022011-10-10 07:32:539898 session->http_server_properties();
bnc3472afd2016-11-17 15:27:219899 AlternativeService alternative_service(kProtoHTTP2, "", 444);
bnc7dc7e1b42015-07-28 14:43:129900 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:219901 http_server_properties->SetHttp2AlternativeService(
bncaa60ff402016-06-22 19:12:429902 url::SchemeHostPort("https", "host.with.alternate", 443),
zhongyi3d4a55e72016-04-22 20:36:469903 alternative_service, expiration);
[email protected]2d731a32010-04-29 01:04:069904
9905 return session;
9906}
9907
mmenkee65e7af2015-10-13 17:16:429908int GroupNameTransactionHelper(const std::string& url,
9909 HttpNetworkSession* session) {
[email protected]2d731a32010-04-29 01:04:069910 HttpRequestInfo request;
9911 request.method = "GET";
9912 request.url = GURL(url);
[email protected]2d731a32010-04-29 01:04:069913
bnc691fda62016-08-12 00:43:169914 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session);
[email protected]cb9bf6ca2011-01-28 13:15:279915
[email protected]49639fa2011-12-20 23:22:419916 TestCompletionCallback callback;
[email protected]2d731a32010-04-29 01:04:069917
9918 // We do not complete this request, the dtor will clean the transaction up.
tfarina42834112016-09-22 13:38:209919 return trans.Start(&request, callback.callback(), NetLogWithSource());
[email protected]2d731a32010-04-29 01:04:069920}
9921
[email protected]448d4ca52012-03-04 04:12:239922} // namespace
9923
bncd16676a2016-07-20 16:23:019924TEST_F(HttpNetworkTransactionTest, GroupNameForDirectConnections) {
[email protected]2d731a32010-04-29 01:04:069925 const GroupNameTest tests[] = {
bncce36dca22015-04-21 22:11:239926 {
9927 "", // unused
9928 "http://www.example.org/direct",
9929 "www.example.org:80",
9930 false,
9931 },
9932 {
9933 "", // unused
9934 "http://[2001:1418:13:1::25]/direct",
9935 "[2001:1418:13:1::25]:80",
9936 false,
9937 },
[email protected]04e5be32009-06-26 20:00:319938
bncce36dca22015-04-21 22:11:239939 // SSL Tests
9940 {
9941 "", // unused
9942 "https://www.example.org/direct_ssl",
9943 "ssl/www.example.org:443",
9944 true,
9945 },
9946 {
9947 "", // unused
9948 "https://[2001:1418:13:1::25]/direct",
9949 "ssl/[2001:1418:13:1::25]:443",
9950 true,
9951 },
9952 {
9953 "", // unused
bncaa60ff402016-06-22 19:12:429954 "https://host.with.alternate/direct",
bncce36dca22015-04-21 22:11:239955 "ssl/host.with.alternate:443",
9956 true,
9957 },
[email protected]2d731a32010-04-29 01:04:069958 };
[email protected]2ff8b312010-04-26 22:20:549959
viettrungluue4a8b882014-10-16 06:17:389960 for (size_t i = 0; i < arraysize(tests); ++i) {
Lily Houghton8c2f97d2018-01-22 05:06:599961 session_deps_.proxy_resolution_service =
9962 ProxyResolutionService::CreateFixed(tests[i].proxy_server);
danakj1fd259a02016-04-16 03:17:099963 std::unique_ptr<HttpNetworkSession> session(
bnca9b9e222016-07-11 20:10:409964 SetupSessionForGroupNameTests(&session_deps_));
[email protected]2d731a32010-04-29 01:04:069965
mmenkee65e7af2015-10-13 17:16:429966 HttpNetworkSessionPeer peer(session.get());
[email protected]ab739042011-04-07 15:22:289967 CaptureGroupNameTransportSocketPool* transport_conn_pool =
bnc87dcefc2017-05-25 12:47:589968 new CaptureGroupNameTransportSocketPool(nullptr, nullptr);
[email protected]2431756e2010-09-29 20:26:139969 CaptureGroupNameSSLSocketPool* ssl_conn_pool =
bnc87dcefc2017-05-25 12:47:589970 new CaptureGroupNameSSLSocketPool(nullptr, nullptr);
Jeremy Roman0579ed62017-08-29 15:56:199971 auto mock_pool_manager = std::make_unique<MockClientSocketPoolManager>();
[email protected]a42dbd142011-11-17 16:42:029972 mock_pool_manager->SetTransportSocketPool(transport_conn_pool);
9973 mock_pool_manager->SetSSLSocketPool(ssl_conn_pool);
dchengc7eeda422015-12-26 03:56:489974 peer.SetClientSocketPoolManager(std::move(mock_pool_manager));
[email protected]2d731a32010-04-29 01:04:069975
9976 EXPECT_EQ(ERR_IO_PENDING,
mmenkee65e7af2015-10-13 17:16:429977 GroupNameTransactionHelper(tests[i].url, session.get()));
Tarun Bansal162eabe52018-01-20 01:16:399978 if (tests[i].ssl) {
[email protected]e60e47a2010-07-14 03:37:189979 EXPECT_EQ(tests[i].expected_group_name,
9980 ssl_conn_pool->last_group_name_received());
Tarun Bansal162eabe52018-01-20 01:16:399981 } else {
[email protected]e60e47a2010-07-14 03:37:189982 EXPECT_EQ(tests[i].expected_group_name,
[email protected]ab739042011-04-07 15:22:289983 transport_conn_pool->last_group_name_received());
Tarun Bansal162eabe52018-01-20 01:16:399984 }
9985 // When SSL proxy is in use, socket must be requested from |ssl_conn_pool|.
9986 EXPECT_EQ(tests[i].ssl, ssl_conn_pool->socket_requested());
9987 // When SSL proxy is not in use, socket must be requested from
9988 // |transport_conn_pool|.
9989 EXPECT_EQ(!tests[i].ssl, transport_conn_pool->socket_requested());
[email protected]2d731a32010-04-29 01:04:069990 }
[email protected]2d731a32010-04-29 01:04:069991}
9992
bncd16676a2016-07-20 16:23:019993TEST_F(HttpNetworkTransactionTest, GroupNameForHTTPProxyConnections) {
[email protected]2d731a32010-04-29 01:04:069994 const GroupNameTest tests[] = {
bncce36dca22015-04-21 22:11:239995 {
Matt Menked1eb6d42018-01-17 04:54:069996 "http_proxy", "http://www.example.org/http_proxy_normal",
9997 "http_proxy/www.example.org:80", false,
bncce36dca22015-04-21 22:11:239998 },
[email protected]2d731a32010-04-29 01:04:069999
bncce36dca22015-04-21 22:11:2310000 // SSL Tests
10001 {
Matt Menked1eb6d42018-01-17 04:54:0610002 "http_proxy", "https://www.example.org/http_connect_ssl",
10003 "http_proxy/ssl/www.example.org:443", true,
bncce36dca22015-04-21 22:11:2310004 },
[email protected]af3490e2010-10-16 21:02:2910005
bncce36dca22015-04-21 22:11:2310006 {
Matt Menked1eb6d42018-01-17 04:54:0610007 "http_proxy", "https://host.with.alternate/direct",
10008 "http_proxy/ssl/host.with.alternate:443", true,
bncce36dca22015-04-21 22:11:2310009 },
[email protected]45499252013-01-23 17:12:5610010
bncce36dca22015-04-21 22:11:2310011 {
Matt Menked1eb6d42018-01-17 04:54:0610012 "http_proxy", "ftp://ftp.google.com/http_proxy_normal",
10013 "http_proxy/ftp/ftp.google.com:21", false,
bncce36dca22015-04-21 22:11:2310014 },
[email protected]2d731a32010-04-29 01:04:0610015 };
10016
viettrungluue4a8b882014-10-16 06:17:3810017 for (size_t i = 0; i < arraysize(tests); ++i) {
Lily Houghton8c2f97d2018-01-22 05:06:5910018 session_deps_.proxy_resolution_service =
10019 ProxyResolutionService::CreateFixed(tests[i].proxy_server);
danakj1fd259a02016-04-16 03:17:0910020 std::unique_ptr<HttpNetworkSession> session(
bnca9b9e222016-07-11 20:10:4010021 SetupSessionForGroupNameTests(&session_deps_));
[email protected]2d731a32010-04-29 01:04:0610022
mmenkee65e7af2015-10-13 17:16:4210023 HttpNetworkSessionPeer peer(session.get());
[email protected]2d731a32010-04-29 01:04:0610024
[email protected]e60e47a2010-07-14 03:37:1810025 HostPortPair proxy_host("http_proxy", 80);
[email protected]2431756e2010-09-29 20:26:1310026 CaptureGroupNameHttpProxySocketPool* http_proxy_pool =
[email protected]9e1bdd32011-02-03 21:48:3410027 new CaptureGroupNameHttpProxySocketPool(NULL, NULL);
[email protected]2431756e2010-09-29 20:26:1310028 CaptureGroupNameSSLSocketPool* ssl_conn_pool =
[email protected]9e1bdd32011-02-03 21:48:3410029 new CaptureGroupNameSSLSocketPool(NULL, NULL);
Jeremy Roman0579ed62017-08-29 15:56:1910030 auto mock_pool_manager = std::make_unique<MockClientSocketPoolManager>();
aviadef3442016-10-03 18:50:3910031 mock_pool_manager->SetSocketPoolForHTTPProxy(
10032 proxy_host, base::WrapUnique(http_proxy_pool));
10033 mock_pool_manager->SetSocketPoolForSSLWithProxy(
10034 proxy_host, base::WrapUnique(ssl_conn_pool));
dchengc7eeda422015-12-26 03:56:4810035 peer.SetClientSocketPoolManager(std::move(mock_pool_manager));
[email protected]2d731a32010-04-29 01:04:0610036
10037 EXPECT_EQ(ERR_IO_PENDING,
mmenkee65e7af2015-10-13 17:16:4210038 GroupNameTransactionHelper(tests[i].url, session.get()));
[email protected]e60e47a2010-07-14 03:37:1810039 if (tests[i].ssl)
10040 EXPECT_EQ(tests[i].expected_group_name,
10041 ssl_conn_pool->last_group_name_received());
10042 else
10043 EXPECT_EQ(tests[i].expected_group_name,
10044 http_proxy_pool->last_group_name_received());
[email protected]2d731a32010-04-29 01:04:0610045 }
[email protected]2d731a32010-04-29 01:04:0610046}
10047
bncd16676a2016-07-20 16:23:0110048TEST_F(HttpNetworkTransactionTest, GroupNameForSOCKSConnections) {
[email protected]2d731a32010-04-29 01:04:0610049 const GroupNameTest tests[] = {
bncce36dca22015-04-21 22:11:2310050 {
10051 "socks4://socks_proxy:1080",
10052 "http://www.example.org/socks4_direct",
10053 "socks4/www.example.org:80",
10054 false,
10055 },
10056 {
10057 "socks5://socks_proxy:1080",
10058 "http://www.example.org/socks5_direct",
10059 "socks5/www.example.org:80",
10060 false,
10061 },
[email protected]2d731a32010-04-29 01:04:0610062
bncce36dca22015-04-21 22:11:2310063 // SSL Tests
10064 {
10065 "socks4://socks_proxy:1080",
10066 "https://www.example.org/socks4_ssl",
10067 "socks4/ssl/www.example.org:443",
10068 true,
10069 },
10070 {
10071 "socks5://socks_proxy:1080",
10072 "https://www.example.org/socks5_ssl",
10073 "socks5/ssl/www.example.org:443",
10074 true,
10075 },
[email protected]af3490e2010-10-16 21:02:2910076
bncce36dca22015-04-21 22:11:2310077 {
10078 "socks4://socks_proxy:1080",
bncaa60ff402016-06-22 19:12:4210079 "https://host.with.alternate/direct",
bncce36dca22015-04-21 22:11:2310080 "socks4/ssl/host.with.alternate:443",
10081 true,
10082 },
[email protected]04e5be32009-06-26 20:00:3110083 };
10084
viettrungluue4a8b882014-10-16 06:17:3810085 for (size_t i = 0; i < arraysize(tests); ++i) {
Lily Houghton8c2f97d2018-01-22 05:06:5910086 session_deps_.proxy_resolution_service =
10087 ProxyResolutionService::CreateFixed(tests[i].proxy_server);
danakj1fd259a02016-04-16 03:17:0910088 std::unique_ptr<HttpNetworkSession> session(
bnca9b9e222016-07-11 20:10:4010089 SetupSessionForGroupNameTests(&session_deps_));
[email protected]8b114dd72011-03-25 05:33:0210090
mmenkee65e7af2015-10-13 17:16:4210091 HttpNetworkSessionPeer peer(session.get());
[email protected]04e5be32009-06-26 20:00:3110092
[email protected]e60e47a2010-07-14 03:37:1810093 HostPortPair proxy_host("socks_proxy", 1080);
[email protected]2431756e2010-09-29 20:26:1310094 CaptureGroupNameSOCKSSocketPool* socks_conn_pool =
[email protected]9e1bdd32011-02-03 21:48:3410095 new CaptureGroupNameSOCKSSocketPool(NULL, NULL);
[email protected]2431756e2010-09-29 20:26:1310096 CaptureGroupNameSSLSocketPool* ssl_conn_pool =
[email protected]9e1bdd32011-02-03 21:48:3410097 new CaptureGroupNameSSLSocketPool(NULL, NULL);
Jeremy Roman0579ed62017-08-29 15:56:1910098 auto mock_pool_manager = std::make_unique<MockClientSocketPoolManager>();
aviadef3442016-10-03 18:50:3910099 mock_pool_manager->SetSocketPoolForSOCKSProxy(
10100 proxy_host, base::WrapUnique(socks_conn_pool));
10101 mock_pool_manager->SetSocketPoolForSSLWithProxy(
10102 proxy_host, base::WrapUnique(ssl_conn_pool));
dchengc7eeda422015-12-26 03:56:4810103 peer.SetClientSocketPoolManager(std::move(mock_pool_manager));
[email protected]04e5be32009-06-26 20:00:3110104
bnc691fda62016-08-12 00:43:1610105 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]04e5be32009-06-26 20:00:3110106
[email protected]2d731a32010-04-29 01:04:0610107 EXPECT_EQ(ERR_IO_PENDING,
mmenkee65e7af2015-10-13 17:16:4210108 GroupNameTransactionHelper(tests[i].url, session.get()));
[email protected]e60e47a2010-07-14 03:37:1810109 if (tests[i].ssl)
10110 EXPECT_EQ(tests[i].expected_group_name,
10111 ssl_conn_pool->last_group_name_received());
10112 else
10113 EXPECT_EQ(tests[i].expected_group_name,
10114 socks_conn_pool->last_group_name_received());
[email protected]04e5be32009-06-26 20:00:3110115 }
10116}
10117
bncd16676a2016-07-20 16:23:0110118TEST_F(HttpNetworkTransactionTest, ReconsiderProxyAfterFailedConnection) {
[email protected]cb9bf6ca2011-01-28 13:15:2710119 HttpRequestInfo request;
10120 request.method = "GET";
bncce36dca22015-04-21 22:11:2310121 request.url = GURL("http://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:2710122
Lily Houghton8c2f97d2018-01-22 05:06:5910123 session_deps_.proxy_resolution_service =
10124 ProxyResolutionService::CreateFixed("myproxy:70;foobar:80");
[email protected]b59ff372009-07-15 22:04:3210125
[email protected]69719062010-01-05 20:09:2110126 // This simulates failure resolving all hostnames; that means we will fail
10127 // connecting to both proxies (myproxy:70 and foobar:80).
[email protected]bb88e1d32013-05-03 23:11:0710128 session_deps_.host_resolver->rules()->AddSimulatedFailure("*");
[email protected]b59ff372009-07-15 22:04:3210129
danakj1fd259a02016-04-16 03:17:0910130 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1610131 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]9172a982009-06-06 00:30:2510132
[email protected]49639fa2011-12-20 23:22:4110133 TestCompletionCallback callback;
[email protected]9172a982009-06-06 00:30:2510134
tfarina42834112016-09-22 13:38:2010135 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110136 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]9172a982009-06-06 00:30:2510137
[email protected]9172a982009-06-06 00:30:2510138 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0110139 EXPECT_THAT(rv, IsError(ERR_PROXY_CONNECTION_FAILED));
[email protected]9172a982009-06-06 00:30:2510140}
10141
[email protected]685af592010-05-11 19:31:2410142// Base test to make sure that when the load flags for a request specify to
10143// bypass the cache, the DNS cache is not used.
[email protected]23e482282013-06-14 16:08:0210144void HttpNetworkTransactionTest::BypassHostCacheOnRefreshHelper(
[email protected]bb88e1d32013-05-03 23:11:0710145 int load_flags) {
[email protected]cb9bf6ca2011-01-28 13:15:2710146 // Issue a request, asking to bypass the cache(s).
maksim.sisov31452af2016-07-27 06:38:1010147 HttpRequestInfo request_info;
10148 request_info.method = "GET";
10149 request_info.load_flags = load_flags;
10150 request_info.url = GURL("http://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:2710151
[email protected]a2c2fb92009-07-18 07:31:0410152 // Select a host resolver that does caching.
Jeremy Roman0579ed62017-08-29 15:56:1910153 session_deps_.host_resolver = std::make_unique<MockCachingHostResolver>();
[email protected]b59ff372009-07-15 22:04:3210154
danakj1fd259a02016-04-16 03:17:0910155 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1610156 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]3b9cca42009-06-16 01:08:2810157
bncce36dca22015-04-21 22:11:2310158 // Warm up the host cache so it has an entry for "www.example.org".
[email protected]3b9cca42009-06-16 01:08:2810159 AddressList addrlist;
[email protected]aa22b242011-11-16 18:58:2910160 TestCompletionCallback callback;
maksim.sisov31452af2016-07-27 06:38:1010161 std::unique_ptr<HostResolver::Request> request1;
[email protected]bb88e1d32013-05-03 23:11:0710162 int rv = session_deps_.host_resolver->Resolve(
bncce36dca22015-04-21 22:11:2310163 HostResolver::RequestInfo(HostPortPair("www.example.org", 80)),
maksim.sisov31452af2016-07-27 06:38:1010164 DEFAULT_PRIORITY, &addrlist, callback.callback(), &request1,
tfarina42834112016-09-22 13:38:2010165 NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110166 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]6e78dfb2011-07-28 21:34:4710167 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0110168 EXPECT_THAT(rv, IsOk());
[email protected]3b9cca42009-06-16 01:08:2810169
10170 // Verify that it was added to host cache, by doing a subsequent async lookup
10171 // and confirming it completes synchronously.
maksim.sisov31452af2016-07-27 06:38:1010172 std::unique_ptr<HostResolver::Request> request2;
[email protected]bb88e1d32013-05-03 23:11:0710173 rv = session_deps_.host_resolver->Resolve(
bncce36dca22015-04-21 22:11:2310174 HostResolver::RequestInfo(HostPortPair("www.example.org", 80)),
maksim.sisov31452af2016-07-27 06:38:1010175 DEFAULT_PRIORITY, &addrlist, callback.callback(), &request2,
tfarina42834112016-09-22 13:38:2010176 NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110177 ASSERT_THAT(rv, IsOk());
[email protected]3b9cca42009-06-16 01:08:2810178
bncce36dca22015-04-21 22:11:2310179 // Inject a failure the next time that "www.example.org" is resolved. This way
[email protected]3b9cca42009-06-16 01:08:2810180 // we can tell if the next lookup hit the cache, or the "network".
10181 // (cache --> success, "network" --> failure).
bncce36dca22015-04-21 22:11:2310182 session_deps_.host_resolver->rules()->AddSimulatedFailure("www.example.org");
[email protected]3b9cca42009-06-16 01:08:2810183
10184 // Connect up a mock socket which will fail with ERR_UNEXPECTED during the
10185 // first read -- this won't be reached as the host resolution will fail first.
[email protected]8ddf8322012-02-23 18:08:0610186 MockRead data_reads[] = { MockRead(SYNCHRONOUS, ERR_UNEXPECTED) };
[email protected]31a2bfe2010-02-09 08:03:3910187 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0710188 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]3b9cca42009-06-16 01:08:2810189
[email protected]3b9cca42009-06-16 01:08:2810190 // Run the request.
tfarina42834112016-09-22 13:38:2010191 rv = trans.Start(&request_info, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110192 ASSERT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]49639fa2011-12-20 23:22:4110193 rv = callback.WaitForResult();
[email protected]3b9cca42009-06-16 01:08:2810194
10195 // If we bypassed the cache, we would have gotten a failure while resolving
bncce36dca22015-04-21 22:11:2310196 // "www.example.org".
robpercival214763f2016-07-01 23:27:0110197 EXPECT_THAT(rv, IsError(ERR_NAME_NOT_RESOLVED));
[email protected]3b9cca42009-06-16 01:08:2810198}
10199
[email protected]685af592010-05-11 19:31:2410200// There are multiple load flags that should trigger the host cache bypass.
10201// Test each in isolation:
bncd16676a2016-07-20 16:23:0110202TEST_F(HttpNetworkTransactionTest, BypassHostCacheOnRefresh1) {
[email protected]685af592010-05-11 19:31:2410203 BypassHostCacheOnRefreshHelper(LOAD_BYPASS_CACHE);
10204}
10205
bncd16676a2016-07-20 16:23:0110206TEST_F(HttpNetworkTransactionTest, BypassHostCacheOnRefresh2) {
[email protected]685af592010-05-11 19:31:2410207 BypassHostCacheOnRefreshHelper(LOAD_VALIDATE_CACHE);
10208}
10209
bncd16676a2016-07-20 16:23:0110210TEST_F(HttpNetworkTransactionTest, BypassHostCacheOnRefresh3) {
[email protected]685af592010-05-11 19:31:2410211 BypassHostCacheOnRefreshHelper(LOAD_DISABLE_CACHE);
10212}
10213
[email protected]0877e3d2009-10-17 22:29:5710214// Make sure we can handle an error when writing the request.
bncd16676a2016-07-20 16:23:0110215TEST_F(HttpNetworkTransactionTest, RequestWriteError) {
[email protected]0877e3d2009-10-17 22:29:5710216 HttpRequestInfo request;
10217 request.method = "GET";
10218 request.url = GURL("http://www.foo.com/");
[email protected]0877e3d2009-10-17 22:29:5710219
10220 MockWrite write_failure[] = {
[email protected]8ddf8322012-02-23 18:08:0610221 MockWrite(ASYNC, ERR_CONNECTION_RESET),
[email protected]0877e3d2009-10-17 22:29:5710222 };
[email protected]31a2bfe2010-02-09 08:03:3910223 StaticSocketDataProvider data(NULL, 0,
10224 write_failure, arraysize(write_failure));
[email protected]bb88e1d32013-05-03 23:11:0710225 session_deps_.socket_factory->AddSocketDataProvider(&data);
danakj1fd259a02016-04-16 03:17:0910226 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]0877e3d2009-10-17 22:29:5710227
[email protected]49639fa2011-12-20 23:22:4110228 TestCompletionCallback callback;
[email protected]0877e3d2009-10-17 22:29:5710229
bnc691fda62016-08-12 00:43:1610230 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]0877e3d2009-10-17 22:29:5710231
tfarina42834112016-09-22 13:38:2010232 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110233 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]0877e3d2009-10-17 22:29:5710234
10235 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0110236 EXPECT_THAT(rv, IsError(ERR_CONNECTION_RESET));
ttuttled9dbc652015-09-29 20:00:5910237
10238 IPEndPoint endpoint;
bnc691fda62016-08-12 00:43:1610239 EXPECT_TRUE(trans.GetRemoteEndpoint(&endpoint));
ttuttled9dbc652015-09-29 20:00:5910240 EXPECT_LT(0u, endpoint.address().size());
[email protected]0877e3d2009-10-17 22:29:5710241}
10242
zmo9528c9f42015-08-04 22:12:0810243// Check that a connection closed after the start of the headers finishes ok.
bncd16676a2016-07-20 16:23:0110244TEST_F(HttpNetworkTransactionTest, ConnectionClosedAfterStartOfHeaders) {
[email protected]0877e3d2009-10-17 22:29:5710245 HttpRequestInfo request;
10246 request.method = "GET";
10247 request.url = GURL("http://www.foo.com/");
[email protected]0877e3d2009-10-17 22:29:5710248
10249 MockRead data_reads[] = {
10250 MockRead("HTTP/1."),
[email protected]8ddf8322012-02-23 18:08:0610251 MockRead(SYNCHRONOUS, OK),
[email protected]0877e3d2009-10-17 22:29:5710252 };
10253
[email protected]31a2bfe2010-02-09 08:03:3910254 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0710255 session_deps_.socket_factory->AddSocketDataProvider(&data);
danakj1fd259a02016-04-16 03:17:0910256 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]0877e3d2009-10-17 22:29:5710257
[email protected]49639fa2011-12-20 23:22:4110258 TestCompletionCallback callback;
[email protected]0877e3d2009-10-17 22:29:5710259
bnc691fda62016-08-12 00:43:1610260 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]0877e3d2009-10-17 22:29:5710261
tfarina42834112016-09-22 13:38:2010262 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110263 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]0877e3d2009-10-17 22:29:5710264
10265 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0110266 EXPECT_THAT(rv, IsOk());
zmo9528c9f42015-08-04 22:12:0810267
bnc691fda62016-08-12 00:43:1610268 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5210269 ASSERT_TRUE(response);
zmo9528c9f42015-08-04 22:12:0810270
wezca1070932016-05-26 20:30:5210271 EXPECT_TRUE(response->headers);
zmo9528c9f42015-08-04 22:12:0810272 EXPECT_EQ("HTTP/1.0 200 OK", response->headers->GetStatusLine());
10273
10274 std::string response_data;
bnc691fda62016-08-12 00:43:1610275 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:0110276 EXPECT_THAT(rv, IsOk());
zmo9528c9f42015-08-04 22:12:0810277 EXPECT_EQ("", response_data);
ttuttled9dbc652015-09-29 20:00:5910278
10279 IPEndPoint endpoint;
bnc691fda62016-08-12 00:43:1610280 EXPECT_TRUE(trans.GetRemoteEndpoint(&endpoint));
ttuttled9dbc652015-09-29 20:00:5910281 EXPECT_LT(0u, endpoint.address().size());
[email protected]0877e3d2009-10-17 22:29:5710282}
10283
10284// Make sure that a dropped connection while draining the body for auth
10285// restart does the right thing.
bncd16676a2016-07-20 16:23:0110286TEST_F(HttpNetworkTransactionTest, DrainResetOK) {
[email protected]0877e3d2009-10-17 22:29:5710287 HttpRequestInfo request;
10288 request.method = "GET";
bncce36dca22015-04-21 22:11:2310289 request.url = GURL("http://www.example.org/");
[email protected]0877e3d2009-10-17 22:29:5710290
10291 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:2310292 MockWrite(
10293 "GET / HTTP/1.1\r\n"
10294 "Host: www.example.org\r\n"
10295 "Connection: keep-alive\r\n\r\n"),
[email protected]0877e3d2009-10-17 22:29:5710296 };
10297
10298 MockRead data_reads1[] = {
10299 MockRead("HTTP/1.1 401 Unauthorized\r\n"),
10300 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
10301 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
10302 MockRead("Content-Length: 14\r\n\r\n"),
10303 MockRead("Unauth"),
[email protected]8ddf8322012-02-23 18:08:0610304 MockRead(ASYNC, ERR_CONNECTION_RESET),
[email protected]0877e3d2009-10-17 22:29:5710305 };
10306
[email protected]31a2bfe2010-02-09 08:03:3910307 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
10308 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:0710309 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]0877e3d2009-10-17 22:29:5710310
bnc691fda62016-08-12 00:43:1610311 // After calling trans.RestartWithAuth(), this is the request we should
[email protected]0877e3d2009-10-17 22:29:5710312 // be issuing -- the final header line contains the credentials.
10313 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:2310314 MockWrite(
10315 "GET / HTTP/1.1\r\n"
10316 "Host: www.example.org\r\n"
10317 "Connection: keep-alive\r\n"
10318 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]0877e3d2009-10-17 22:29:5710319 };
10320
10321 // Lastly, the server responds with the actual content.
10322 MockRead data_reads2[] = {
10323 MockRead("HTTP/1.1 200 OK\r\n"),
10324 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
10325 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:0610326 MockRead(SYNCHRONOUS, OK),
[email protected]0877e3d2009-10-17 22:29:5710327 };
10328
[email protected]31a2bfe2010-02-09 08:03:3910329 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
10330 data_writes2, arraysize(data_writes2));
[email protected]bb88e1d32013-05-03 23:11:0710331 session_deps_.socket_factory->AddSocketDataProvider(&data2);
danakj1fd259a02016-04-16 03:17:0910332 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]0877e3d2009-10-17 22:29:5710333
[email protected]49639fa2011-12-20 23:22:4110334 TestCompletionCallback callback1;
[email protected]0877e3d2009-10-17 22:29:5710335
bnc691fda62016-08-12 00:43:1610336 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]0b0bf032010-09-21 18:08:5010337
tfarina42834112016-09-22 13:38:2010338 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110339 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]0877e3d2009-10-17 22:29:5710340
10341 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:0110342 EXPECT_THAT(rv, IsOk());
[email protected]0877e3d2009-10-17 22:29:5710343
bnc691fda62016-08-12 00:43:1610344 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5210345 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:0410346 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]0877e3d2009-10-17 22:29:5710347
[email protected]49639fa2011-12-20 23:22:4110348 TestCompletionCallback callback2;
[email protected]0877e3d2009-10-17 22:29:5710349
bnc691fda62016-08-12 00:43:1610350 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar), callback2.callback());
robpercival214763f2016-07-01 23:27:0110351 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]0877e3d2009-10-17 22:29:5710352
10353 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:0110354 EXPECT_THAT(rv, IsOk());
[email protected]0877e3d2009-10-17 22:29:5710355
bnc691fda62016-08-12 00:43:1610356 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5210357 ASSERT_TRUE(response);
10358 EXPECT_FALSE(response->auth_challenge);
[email protected]0877e3d2009-10-17 22:29:5710359 EXPECT_EQ(100, response->headers->GetContentLength());
10360}
10361
10362// Test HTTPS connections going through a proxy that sends extra data.
bncd16676a2016-07-20 16:23:0110363TEST_F(HttpNetworkTransactionTest, HTTPSViaProxyWithExtraData) {
Lily Houghton8c2f97d2018-01-22 05:06:5910364 session_deps_.proxy_resolution_service =
10365 ProxyResolutionService::CreateFixed("myproxy:70");
[email protected]0877e3d2009-10-17 22:29:5710366
10367 HttpRequestInfo request;
10368 request.method = "GET";
bncce36dca22015-04-21 22:11:2310369 request.url = GURL("https://www.example.org/");
[email protected]0877e3d2009-10-17 22:29:5710370
10371 MockRead proxy_reads[] = {
10372 MockRead("HTTP/1.0 200 Connected\r\n\r\nExtra data"),
[email protected]8ddf8322012-02-23 18:08:0610373 MockRead(SYNCHRONOUS, OK)
[email protected]0877e3d2009-10-17 22:29:5710374 };
10375
[email protected]31a2bfe2010-02-09 08:03:3910376 StaticSocketDataProvider data(proxy_reads, arraysize(proxy_reads), NULL, 0);
[email protected]8ddf8322012-02-23 18:08:0610377 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]0877e3d2009-10-17 22:29:5710378
[email protected]bb88e1d32013-05-03 23:11:0710379 session_deps_.socket_factory->AddSocketDataProvider(&data);
10380 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]0877e3d2009-10-17 22:29:5710381
[email protected]49639fa2011-12-20 23:22:4110382 TestCompletionCallback callback;
[email protected]0877e3d2009-10-17 22:29:5710383
[email protected]bb88e1d32013-05-03 23:11:0710384 session_deps_.socket_factory->ResetNextMockIndexes();
[email protected]0877e3d2009-10-17 22:29:5710385
danakj1fd259a02016-04-16 03:17:0910386 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1610387 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]0877e3d2009-10-17 22:29:5710388
tfarina42834112016-09-22 13:38:2010389 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110390 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]0877e3d2009-10-17 22:29:5710391
10392 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0110393 EXPECT_THAT(rv, IsError(ERR_TUNNEL_CONNECTION_FAILED));
[email protected]0877e3d2009-10-17 22:29:5710394}
10395
bncd16676a2016-07-20 16:23:0110396TEST_F(HttpNetworkTransactionTest, LargeContentLengthThenClose) {
[email protected]9492e4a2010-02-24 00:58:4610397 HttpRequestInfo request;
10398 request.method = "GET";
bncce36dca22015-04-21 22:11:2310399 request.url = GURL("http://www.example.org/");
[email protected]9492e4a2010-02-24 00:58:4610400
danakj1fd259a02016-04-16 03:17:0910401 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1610402 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:2710403
[email protected]e22e1362009-11-23 21:31:1210404 MockRead data_reads[] = {
10405 MockRead("HTTP/1.0 200 OK\r\nContent-Length:6719476739\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:0610406 MockRead(SYNCHRONOUS, OK),
[email protected]e22e1362009-11-23 21:31:1210407 };
[email protected]9492e4a2010-02-24 00:58:4610408
10409 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0710410 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]9492e4a2010-02-24 00:58:4610411
[email protected]49639fa2011-12-20 23:22:4110412 TestCompletionCallback callback;
[email protected]9492e4a2010-02-24 00:58:4610413
tfarina42834112016-09-22 13:38:2010414 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110415 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]9492e4a2010-02-24 00:58:4610416
robpercival214763f2016-07-01 23:27:0110417 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]9492e4a2010-02-24 00:58:4610418
bnc691fda62016-08-12 00:43:1610419 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5210420 ASSERT_TRUE(response);
[email protected]9492e4a2010-02-24 00:58:4610421
wezca1070932016-05-26 20:30:5210422 EXPECT_TRUE(response->headers);
[email protected]9492e4a2010-02-24 00:58:4610423 EXPECT_EQ("HTTP/1.0 200 OK", response->headers->GetStatusLine());
10424
10425 std::string response_data;
bnc691fda62016-08-12 00:43:1610426 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:0110427 EXPECT_THAT(rv, IsError(ERR_CONTENT_LENGTH_MISMATCH));
[email protected]e22e1362009-11-23 21:31:1210428}
10429
bncd16676a2016-07-20 16:23:0110430TEST_F(HttpNetworkTransactionTest, UploadFileSmallerThanLength) {
[email protected]6cdfd7f2013-02-08 20:40:1510431 base::FilePath temp_file_path;
[email protected]03d9afc02013-12-03 17:55:5210432 ASSERT_TRUE(base::CreateTemporaryFile(&temp_file_path));
avibf0746c2015-12-09 19:53:1410433 const uint64_t kFakeSize = 100000; // file is actually blank
[email protected]d98961652012-09-11 20:27:2110434 UploadFileElementReader::ScopedOverridingContentLengthForTests
10435 overriding_content_length(kFakeSize);
[email protected]95d88ffe2010-02-04 21:25:3310436
danakj1fd259a02016-04-16 03:17:0910437 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
Jeremy Roman0579ed62017-08-29 15:56:1910438 element_readers.push_back(std::make_unique<UploadFileElementReader>(
avibf0746c2015-12-09 19:53:1410439 base::ThreadTaskRunnerHandle::Get().get(), temp_file_path, 0,
ricea2deef682016-09-09 08:04:0710440 std::numeric_limits<uint64_t>::max(), base::Time()));
olli.raula6df48b2a2015-11-26 07:40:2210441 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]329b68b2012-11-14 17:54:2710442
10443 HttpRequestInfo request;
10444 request.method = "POST";
bncce36dca22015-04-21 22:11:2310445 request.url = GURL("http://www.example.org/upload");
[email protected]329b68b2012-11-14 17:54:2710446 request.upload_data_stream = &upload_data_stream;
[email protected]329b68b2012-11-14 17:54:2710447
danakj1fd259a02016-04-16 03:17:0910448 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1610449 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]95d88ffe2010-02-04 21:25:3310450
10451 MockRead data_reads[] = {
10452 MockRead("HTTP/1.0 200 OK\r\n\r\n"),
10453 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:0610454 MockRead(SYNCHRONOUS, OK),
[email protected]95d88ffe2010-02-04 21:25:3310455 };
[email protected]31a2bfe2010-02-09 08:03:3910456 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0710457 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]95d88ffe2010-02-04 21:25:3310458
[email protected]49639fa2011-12-20 23:22:4110459 TestCompletionCallback callback;
[email protected]95d88ffe2010-02-04 21:25:3310460
tfarina42834112016-09-22 13:38:2010461 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110462 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]95d88ffe2010-02-04 21:25:3310463
10464 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0110465 EXPECT_THAT(rv, IsError(ERR_UPLOAD_FILE_CHANGED));
[email protected]95d88ffe2010-02-04 21:25:3310466
bnc691fda62016-08-12 00:43:1610467 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5210468 ASSERT_TRUE(response);
[email protected]95d88ffe2010-02-04 21:25:3310469
maksim.sisove869bf52016-06-23 17:11:5210470 EXPECT_FALSE(response->headers);
[email protected]95d88ffe2010-02-04 21:25:3310471
[email protected]dd3aa792013-07-16 19:10:2310472 base::DeleteFile(temp_file_path, false);
[email protected]95d88ffe2010-02-04 21:25:3310473}
10474
bncd16676a2016-07-20 16:23:0110475TEST_F(HttpNetworkTransactionTest, UploadUnreadableFile) {
[email protected]6cdfd7f2013-02-08 20:40:1510476 base::FilePath temp_file;
[email protected]03d9afc02013-12-03 17:55:5210477 ASSERT_TRUE(base::CreateTemporaryFile(&temp_file));
[email protected]6624b4622010-03-29 19:58:3610478 std::string temp_file_content("Unreadable file.");
lazyboy8df84fc2017-04-12 02:12:4810479 ASSERT_EQ(static_cast<int>(temp_file_content.length()),
10480 base::WriteFile(temp_file, temp_file_content.c_str(),
10481 temp_file_content.length()));
[email protected]92be8eb2014-08-07 22:57:1110482 ASSERT_TRUE(base::MakeFileUnreadable(temp_file));
[email protected]6624b4622010-03-29 19:58:3610483
danakj1fd259a02016-04-16 03:17:0910484 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
Jeremy Roman0579ed62017-08-29 15:56:1910485 element_readers.push_back(std::make_unique<UploadFileElementReader>(
avibf0746c2015-12-09 19:53:1410486 base::ThreadTaskRunnerHandle::Get().get(), temp_file, 0,
ricea2deef682016-09-09 08:04:0710487 std::numeric_limits<uint64_t>::max(), base::Time()));
olli.raula6df48b2a2015-11-26 07:40:2210488 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]329b68b2012-11-14 17:54:2710489
10490 HttpRequestInfo request;
10491 request.method = "POST";
bncce36dca22015-04-21 22:11:2310492 request.url = GURL("http://www.example.org/upload");
[email protected]329b68b2012-11-14 17:54:2710493 request.upload_data_stream = &upload_data_stream;
[email protected]329b68b2012-11-14 17:54:2710494
[email protected]999dd8c2013-11-12 06:45:5410495 // If we try to upload an unreadable file, the transaction should fail.
danakj1fd259a02016-04-16 03:17:0910496 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1610497 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]6624b4622010-03-29 19:58:3610498
[email protected]999dd8c2013-11-12 06:45:5410499 StaticSocketDataProvider data(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0710500 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]6624b4622010-03-29 19:58:3610501
[email protected]49639fa2011-12-20 23:22:4110502 TestCompletionCallback callback;
[email protected]6624b4622010-03-29 19:58:3610503
tfarina42834112016-09-22 13:38:2010504 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110505 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]6624b4622010-03-29 19:58:3610506
10507 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0110508 EXPECT_THAT(rv, IsError(ERR_ACCESS_DENIED));
[email protected]6624b4622010-03-29 19:58:3610509
[email protected]dd3aa792013-07-16 19:10:2310510 base::DeleteFile(temp_file, false);
[email protected]6624b4622010-03-29 19:58:3610511}
10512
bncd16676a2016-07-20 16:23:0110513TEST_F(HttpNetworkTransactionTest, CancelDuringInitRequestBody) {
[email protected]02cad5d2013-10-02 08:14:0310514 class FakeUploadElementReader : public UploadElementReader {
10515 public:
Chris Watkins7a41d3552017-12-01 02:13:2710516 FakeUploadElementReader() = default;
10517 ~FakeUploadElementReader() override = default;
[email protected]02cad5d2013-10-02 08:14:0310518
10519 const CompletionCallback& callback() const { return callback_; }
10520
10521 // UploadElementReader overrides:
dchengb03027d2014-10-21 12:00:2010522 int Init(const CompletionCallback& callback) override {
[email protected]02cad5d2013-10-02 08:14:0310523 callback_ = callback;
10524 return ERR_IO_PENDING;
10525 }
avibf0746c2015-12-09 19:53:1410526 uint64_t GetContentLength() const override { return 0; }
10527 uint64_t BytesRemaining() const override { return 0; }
dchengb03027d2014-10-21 12:00:2010528 int Read(IOBuffer* buf,
10529 int buf_length,
10530 const CompletionCallback& callback) override {
[email protected]02cad5d2013-10-02 08:14:0310531 return ERR_FAILED;
10532 }
10533
10534 private:
10535 CompletionCallback callback_;
10536 };
10537
10538 FakeUploadElementReader* fake_reader = new FakeUploadElementReader;
danakj1fd259a02016-04-16 03:17:0910539 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
10540 element_readers.push_back(base::WrapUnique(fake_reader));
olli.raula6df48b2a2015-11-26 07:40:2210541 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]02cad5d2013-10-02 08:14:0310542
10543 HttpRequestInfo request;
10544 request.method = "POST";
bncce36dca22015-04-21 22:11:2310545 request.url = GURL("http://www.example.org/upload");
[email protected]02cad5d2013-10-02 08:14:0310546 request.upload_data_stream = &upload_data_stream;
[email protected]02cad5d2013-10-02 08:14:0310547
danakj1fd259a02016-04-16 03:17:0910548 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc87dcefc2017-05-25 12:47:5810549 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:1910550 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]02cad5d2013-10-02 08:14:0310551
10552 StaticSocketDataProvider data;
10553 session_deps_.socket_factory->AddSocketDataProvider(&data);
10554
10555 TestCompletionCallback callback;
tfarina42834112016-09-22 13:38:2010556 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110557 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
fdoray92e35a72016-06-10 15:54:5510558 base::RunLoop().RunUntilIdle();
[email protected]02cad5d2013-10-02 08:14:0310559
10560 // Transaction is pending on request body initialization.
10561 ASSERT_FALSE(fake_reader->callback().is_null());
10562
10563 // Return Init()'s result after the transaction gets destroyed.
10564 trans.reset();
10565 fake_reader->callback().Run(OK); // Should not crash.
10566}
10567
[email protected]aeefc9e82010-02-19 16:18:2710568// Tests that changes to Auth realms are treated like auth rejections.
bncd16676a2016-07-20 16:23:0110569TEST_F(HttpNetworkTransactionTest, ChangeAuthRealms) {
[email protected]aeefc9e82010-02-19 16:18:2710570 HttpRequestInfo request;
10571 request.method = "GET";
bncce36dca22015-04-21 22:11:2310572 request.url = GURL("http://www.example.org/");
[email protected]aeefc9e82010-02-19 16:18:2710573
10574 // First transaction will request a resource and receive a Basic challenge
10575 // with realm="first_realm".
10576 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:2310577 MockWrite(
10578 "GET / HTTP/1.1\r\n"
10579 "Host: www.example.org\r\n"
10580 "Connection: keep-alive\r\n"
10581 "\r\n"),
[email protected]aeefc9e82010-02-19 16:18:2710582 };
10583 MockRead data_reads1[] = {
10584 MockRead("HTTP/1.1 401 Unauthorized\r\n"
10585 "WWW-Authenticate: Basic realm=\"first_realm\"\r\n"
10586 "\r\n"),
10587 };
10588
bnc691fda62016-08-12 00:43:1610589 // After calling trans.RestartWithAuth(), provide an Authentication header
[email protected]aeefc9e82010-02-19 16:18:2710590 // for first_realm. The server will reject and provide a challenge with
10591 // second_realm.
10592 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:2310593 MockWrite(
10594 "GET / HTTP/1.1\r\n"
10595 "Host: www.example.org\r\n"
10596 "Connection: keep-alive\r\n"
10597 "Authorization: Basic Zmlyc3Q6YmF6\r\n"
10598 "\r\n"),
[email protected]aeefc9e82010-02-19 16:18:2710599 };
10600 MockRead data_reads2[] = {
10601 MockRead("HTTP/1.1 401 Unauthorized\r\n"
10602 "WWW-Authenticate: Basic realm=\"second_realm\"\r\n"
10603 "\r\n"),
10604 };
10605
10606 // This again fails, and goes back to first_realm. Make sure that the
10607 // entry is removed from cache.
10608 MockWrite data_writes3[] = {
bncce36dca22015-04-21 22:11:2310609 MockWrite(
10610 "GET / HTTP/1.1\r\n"
10611 "Host: www.example.org\r\n"
10612 "Connection: keep-alive\r\n"
10613 "Authorization: Basic c2Vjb25kOmZvdQ==\r\n"
10614 "\r\n"),
[email protected]aeefc9e82010-02-19 16:18:2710615 };
10616 MockRead data_reads3[] = {
10617 MockRead("HTTP/1.1 401 Unauthorized\r\n"
10618 "WWW-Authenticate: Basic realm=\"first_realm\"\r\n"
10619 "\r\n"),
10620 };
10621
10622 // Try one last time (with the correct password) and get the resource.
10623 MockWrite data_writes4[] = {
bncce36dca22015-04-21 22:11:2310624 MockWrite(
10625 "GET / HTTP/1.1\r\n"
10626 "Host: www.example.org\r\n"
10627 "Connection: keep-alive\r\n"
10628 "Authorization: Basic Zmlyc3Q6YmFy\r\n"
10629 "\r\n"),
[email protected]aeefc9e82010-02-19 16:18:2710630 };
10631 MockRead data_reads4[] = {
10632 MockRead("HTTP/1.1 200 OK\r\n"
10633 "Content-Type: text/html; charset=iso-8859-1\r\n"
[email protected]0b0bf032010-09-21 18:08:5010634 "Content-Length: 5\r\n"
10635 "\r\n"
10636 "hello"),
[email protected]aeefc9e82010-02-19 16:18:2710637 };
10638
10639 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
10640 data_writes1, arraysize(data_writes1));
10641 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
10642 data_writes2, arraysize(data_writes2));
10643 StaticSocketDataProvider data3(data_reads3, arraysize(data_reads3),
10644 data_writes3, arraysize(data_writes3));
10645 StaticSocketDataProvider data4(data_reads4, arraysize(data_reads4),
10646 data_writes4, arraysize(data_writes4));
[email protected]bb88e1d32013-05-03 23:11:0710647 session_deps_.socket_factory->AddSocketDataProvider(&data1);
10648 session_deps_.socket_factory->AddSocketDataProvider(&data2);
10649 session_deps_.socket_factory->AddSocketDataProvider(&data3);
10650 session_deps_.socket_factory->AddSocketDataProvider(&data4);
[email protected]aeefc9e82010-02-19 16:18:2710651
[email protected]49639fa2011-12-20 23:22:4110652 TestCompletionCallback callback1;
[email protected]aeefc9e82010-02-19 16:18:2710653
danakj1fd259a02016-04-16 03:17:0910654 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1610655 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]0b0bf032010-09-21 18:08:5010656
[email protected]aeefc9e82010-02-19 16:18:2710657 // Issue the first request with Authorize headers. There should be a
10658 // password prompt for first_realm waiting to be filled in after the
10659 // transaction completes.
tfarina42834112016-09-22 13:38:2010660 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110661 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]aeefc9e82010-02-19 16:18:2710662 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:0110663 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:1610664 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5210665 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:0410666 const AuthChallengeInfo* challenge = response->auth_challenge.get();
wezca1070932016-05-26 20:30:5210667 ASSERT_TRUE(challenge);
[email protected]79cb5c12011-09-12 13:12:0410668 EXPECT_FALSE(challenge->is_proxy);
asanka098c0092016-06-16 20:18:4310669 EXPECT_EQ("http://www.example.org", challenge->challenger.Serialize());
[email protected]79cb5c12011-09-12 13:12:0410670 EXPECT_EQ("first_realm", challenge->realm);
aberentbba302d2015-12-03 10:20:1910671 EXPECT_EQ(kBasicAuthScheme, challenge->scheme);
[email protected]aeefc9e82010-02-19 16:18:2710672
10673 // Issue the second request with an incorrect password. There should be a
10674 // password prompt for second_realm waiting to be filled in after the
10675 // transaction completes.
[email protected]49639fa2011-12-20 23:22:4110676 TestCompletionCallback callback2;
bnc691fda62016-08-12 00:43:1610677 rv = trans.RestartWithAuth(AuthCredentials(kFirst, kBaz),
10678 callback2.callback());
robpercival214763f2016-07-01 23:27:0110679 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]aeefc9e82010-02-19 16:18:2710680 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:0110681 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:1610682 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5210683 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:0410684 challenge = response->auth_challenge.get();
wezca1070932016-05-26 20:30:5210685 ASSERT_TRUE(challenge);
[email protected]79cb5c12011-09-12 13:12:0410686 EXPECT_FALSE(challenge->is_proxy);
asanka098c0092016-06-16 20:18:4310687 EXPECT_EQ("http://www.example.org", challenge->challenger.Serialize());
[email protected]79cb5c12011-09-12 13:12:0410688 EXPECT_EQ("second_realm", challenge->realm);
aberentbba302d2015-12-03 10:20:1910689 EXPECT_EQ(kBasicAuthScheme, challenge->scheme);
[email protected]aeefc9e82010-02-19 16:18:2710690
10691 // Issue the third request with another incorrect password. There should be
10692 // a password prompt for first_realm waiting to be filled in. If the password
10693 // prompt is not present, it indicates that the HttpAuthCacheEntry for
10694 // first_realm was not correctly removed.
[email protected]49639fa2011-12-20 23:22:4110695 TestCompletionCallback callback3;
bnc691fda62016-08-12 00:43:1610696 rv = trans.RestartWithAuth(AuthCredentials(kSecond, kFou),
10697 callback3.callback());
robpercival214763f2016-07-01 23:27:0110698 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]aeefc9e82010-02-19 16:18:2710699 rv = callback3.WaitForResult();
robpercival214763f2016-07-01 23:27:0110700 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:1610701 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5210702 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:0410703 challenge = response->auth_challenge.get();
wezca1070932016-05-26 20:30:5210704 ASSERT_TRUE(challenge);
[email protected]79cb5c12011-09-12 13:12:0410705 EXPECT_FALSE(challenge->is_proxy);
asanka098c0092016-06-16 20:18:4310706 EXPECT_EQ("http://www.example.org", challenge->challenger.Serialize());
[email protected]79cb5c12011-09-12 13:12:0410707 EXPECT_EQ("first_realm", challenge->realm);
aberentbba302d2015-12-03 10:20:1910708 EXPECT_EQ(kBasicAuthScheme, challenge->scheme);
[email protected]aeefc9e82010-02-19 16:18:2710709
10710 // Issue the fourth request with the correct password and username.
[email protected]49639fa2011-12-20 23:22:4110711 TestCompletionCallback callback4;
bnc691fda62016-08-12 00:43:1610712 rv = trans.RestartWithAuth(AuthCredentials(kFirst, kBar),
10713 callback4.callback());
robpercival214763f2016-07-01 23:27:0110714 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]aeefc9e82010-02-19 16:18:2710715 rv = callback4.WaitForResult();
robpercival214763f2016-07-01 23:27:0110716 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:1610717 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5210718 ASSERT_TRUE(response);
10719 EXPECT_FALSE(response->auth_challenge);
[email protected]aeefc9e82010-02-19 16:18:2710720}
10721
Bence Béky230ac612017-08-30 19:17:0810722// Regression test for https://crbug.com/754395.
10723TEST_F(HttpNetworkTransactionTest, IgnoreAltSvcWithInvalidCert) {
10724 MockRead data_reads[] = {
10725 MockRead("HTTP/1.1 200 OK\r\n"),
10726 MockRead(kAlternativeServiceHttpHeader),
10727 MockRead("\r\n"),
10728 MockRead("hello world"),
10729 MockRead(SYNCHRONOUS, OK),
10730 };
10731
10732 HttpRequestInfo request;
10733 request.method = "GET";
10734 request.url = GURL("https://www.example.org/");
10735
10736 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
10737 session_deps_.socket_factory->AddSocketDataProvider(&data);
10738
10739 SSLSocketDataProvider ssl(ASYNC, OK);
Ryan Sleevi4f832092017-11-21 23:25:4910740 ssl.ssl_info.cert =
10741 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem");
10742 ASSERT_TRUE(ssl.ssl_info.cert);
10743 ssl.ssl_info.cert_status = CERT_STATUS_COMMON_NAME_INVALID;
Bence Béky230ac612017-08-30 19:17:0810744 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
10745
10746 TestCompletionCallback callback;
10747
10748 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
10749 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
10750
10751 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
10752 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
10753
10754 url::SchemeHostPort test_server(request.url);
10755 HttpServerProperties* http_server_properties =
10756 session->http_server_properties();
10757 EXPECT_TRUE(
10758 http_server_properties->GetAlternativeServiceInfos(test_server).empty());
10759
10760 EXPECT_THAT(callback.WaitForResult(), IsOk());
10761
10762 const HttpResponseInfo* response = trans.GetResponseInfo();
10763 ASSERT_TRUE(response);
10764 ASSERT_TRUE(response->headers);
10765 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
10766 EXPECT_FALSE(response->was_fetched_via_spdy);
10767 EXPECT_FALSE(response->was_alpn_negotiated);
10768
10769 std::string response_data;
10770 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
10771 EXPECT_EQ("hello world", response_data);
10772
10773 EXPECT_TRUE(
10774 http_server_properties->GetAlternativeServiceInfos(test_server).empty());
10775}
10776
bncd16676a2016-07-20 16:23:0110777TEST_F(HttpNetworkTransactionTest, HonorAlternativeServiceHeader) {
bncc958faa2015-07-31 18:14:5210778 MockRead data_reads[] = {
10779 MockRead("HTTP/1.1 200 OK\r\n"),
bnc2df4b522016-07-08 18:17:4310780 MockRead(kAlternativeServiceHttpHeader),
bncc958faa2015-07-31 18:14:5210781 MockRead("\r\n"),
10782 MockRead("hello world"),
10783 MockRead(SYNCHRONOUS, OK),
10784 };
10785
10786 HttpRequestInfo request;
10787 request.method = "GET";
bncb26024382016-06-29 02:39:4510788 request.url = GURL("https://www.example.org/");
bncc958faa2015-07-31 18:14:5210789
10790 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
bncc958faa2015-07-31 18:14:5210791 session_deps_.socket_factory->AddSocketDataProvider(&data);
10792
bncb26024382016-06-29 02:39:4510793 SSLSocketDataProvider ssl(ASYNC, OK);
Ryan Sleevi4f832092017-11-21 23:25:4910794 ssl.ssl_info.cert =
10795 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem");
10796 ASSERT_TRUE(ssl.ssl_info.cert);
bncb26024382016-06-29 02:39:4510797 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
10798
bncc958faa2015-07-31 18:14:5210799 TestCompletionCallback callback;
10800
danakj1fd259a02016-04-16 03:17:0910801 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1610802 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
bncc958faa2015-07-31 18:14:5210803
tfarina42834112016-09-22 13:38:2010804 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110805 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
bncc958faa2015-07-31 18:14:5210806
bncb26024382016-06-29 02:39:4510807 url::SchemeHostPort test_server(request.url);
bnc525e175a2016-06-20 12:36:4010808 HttpServerProperties* http_server_properties =
10809 session->http_server_properties();
zhongyic4de03032017-05-19 04:07:3410810 EXPECT_TRUE(
10811 http_server_properties->GetAlternativeServiceInfos(test_server).empty());
bncc958faa2015-07-31 18:14:5210812
robpercival214763f2016-07-01 23:27:0110813 EXPECT_THAT(callback.WaitForResult(), IsOk());
bncc958faa2015-07-31 18:14:5210814
bnc691fda62016-08-12 00:43:1610815 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5210816 ASSERT_TRUE(response);
10817 ASSERT_TRUE(response->headers);
bncc958faa2015-07-31 18:14:5210818 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
10819 EXPECT_FALSE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5210820 EXPECT_FALSE(response->was_alpn_negotiated);
bncc958faa2015-07-31 18:14:5210821
10822 std::string response_data;
bnc691fda62016-08-12 00:43:1610823 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
bncc958faa2015-07-31 18:14:5210824 EXPECT_EQ("hello world", response_data);
10825
zhongyic4de03032017-05-19 04:07:3410826 AlternativeServiceInfoVector alternative_service_info_vector =
10827 http_server_properties->GetAlternativeServiceInfos(test_server);
10828 ASSERT_EQ(1u, alternative_service_info_vector.size());
10829 AlternativeService alternative_service(kProtoHTTP2, "mail.example.org", 443);
10830 EXPECT_EQ(alternative_service,
zhongyi422ce352017-06-09 23:28:5410831 alternative_service_info_vector[0].alternative_service());
bncc958faa2015-07-31 18:14:5210832}
10833
bnce3dd56f2016-06-01 10:37:1110834// Regression test for https://crbug.com/615497.
bncd16676a2016-07-20 16:23:0110835TEST_F(HttpNetworkTransactionTest,
bnce3dd56f2016-06-01 10:37:1110836 DoNotParseAlternativeServiceHeaderOnInsecureRequest) {
bnce3dd56f2016-06-01 10:37:1110837 MockRead data_reads[] = {
10838 MockRead("HTTP/1.1 200 OK\r\n"),
bnc2df4b522016-07-08 18:17:4310839 MockRead(kAlternativeServiceHttpHeader),
bnce3dd56f2016-06-01 10:37:1110840 MockRead("\r\n"),
10841 MockRead("hello world"),
10842 MockRead(SYNCHRONOUS, OK),
10843 };
10844
10845 HttpRequestInfo request;
10846 request.method = "GET";
10847 request.url = GURL("http://www.example.org/");
10848 request.load_flags = 0;
10849
10850 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
10851 session_deps_.socket_factory->AddSocketDataProvider(&data);
10852
10853 TestCompletionCallback callback;
10854
10855 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1610856 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
bnce3dd56f2016-06-01 10:37:1110857
10858 url::SchemeHostPort test_server(request.url);
bnc525e175a2016-06-20 12:36:4010859 HttpServerProperties* http_server_properties =
10860 session->http_server_properties();
zhongyic4de03032017-05-19 04:07:3410861 EXPECT_TRUE(
10862 http_server_properties->GetAlternativeServiceInfos(test_server).empty());
bnce3dd56f2016-06-01 10:37:1110863
tfarina42834112016-09-22 13:38:2010864 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110865 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
10866 EXPECT_THAT(callback.WaitForResult(), IsOk());
bnce3dd56f2016-06-01 10:37:1110867
bnc691fda62016-08-12 00:43:1610868 const HttpResponseInfo* response = trans.GetResponseInfo();
bnce3dd56f2016-06-01 10:37:1110869 ASSERT_TRUE(response);
10870 ASSERT_TRUE(response->headers);
10871 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
10872 EXPECT_FALSE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5210873 EXPECT_FALSE(response->was_alpn_negotiated);
bnce3dd56f2016-06-01 10:37:1110874
10875 std::string response_data;
bnc691fda62016-08-12 00:43:1610876 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
bnce3dd56f2016-06-01 10:37:1110877 EXPECT_EQ("hello world", response_data);
10878
zhongyic4de03032017-05-19 04:07:3410879 EXPECT_TRUE(
10880 http_server_properties->GetAlternativeServiceInfos(test_server).empty());
bnce3dd56f2016-06-01 10:37:1110881}
10882
bnca86731e2017-04-17 12:31:2810883// HTTP/2 Alternative Services should be disabled by default.
bnc8bef8da22016-05-30 01:28:2510884// TODO(bnc): Remove when https://crbug.com/615413 is fixed.
bncd16676a2016-07-20 16:23:0110885TEST_F(HttpNetworkTransactionTest,
bnc8bef8da22016-05-30 01:28:2510886 DisableHTTP2AlternativeServicesWithDifferentHost) {
bnca86731e2017-04-17 12:31:2810887 session_deps_.enable_http2_alternative_service = false;
bncb26024382016-06-29 02:39:4510888
bnc8bef8da22016-05-30 01:28:2510889 HttpRequestInfo request;
10890 request.method = "GET";
bncb26024382016-06-29 02:39:4510891 request.url = GURL("https://www.example.org/");
bnc8bef8da22016-05-30 01:28:2510892 request.load_flags = 0;
10893
10894 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
10895 StaticSocketDataProvider first_data;
10896 first_data.set_connect_data(mock_connect);
10897 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
bncb26024382016-06-29 02:39:4510898 SSLSocketDataProvider ssl_http11(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3610899 ssl_http11.next_proto = kProtoHTTP11;
bncb26024382016-06-29 02:39:4510900 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_http11);
bnc8bef8da22016-05-30 01:28:2510901
10902 MockRead data_reads[] = {
10903 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello world"),
10904 MockRead(ASYNC, OK),
10905 };
10906 StaticSocketDataProvider second_data(data_reads, arraysize(data_reads), NULL,
10907 0);
10908 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
10909
10910 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
10911
bnc525e175a2016-06-20 12:36:4010912 HttpServerProperties* http_server_properties =
bnc8bef8da22016-05-30 01:28:2510913 session->http_server_properties();
bnc3472afd2016-11-17 15:27:2110914 AlternativeService alternative_service(kProtoHTTP2, "different.example.org",
10915 444);
bnc8bef8da22016-05-30 01:28:2510916 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:2110917 http_server_properties->SetHttp2AlternativeService(
bnc8bef8da22016-05-30 01:28:2510918 url::SchemeHostPort(request.url), alternative_service, expiration);
10919
bnc691fda62016-08-12 00:43:1610920 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
bnc8bef8da22016-05-30 01:28:2510921 TestCompletionCallback callback;
10922
tfarina42834112016-09-22 13:38:2010923 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
bnc8bef8da22016-05-30 01:28:2510924 // Alternative service is not used, request fails.
robpercival214763f2016-07-01 23:27:0110925 EXPECT_THAT(callback.GetResult(rv), IsError(ERR_CONNECTION_REFUSED));
bnc8bef8da22016-05-30 01:28:2510926}
10927
bnce3dd56f2016-06-01 10:37:1110928// Regression test for https://crbug.com/615497:
10929// Alternative Services should be disabled for http origin.
bncd16676a2016-07-20 16:23:0110930TEST_F(HttpNetworkTransactionTest,
bnce3dd56f2016-06-01 10:37:1110931 DisableAlternativeServicesForInsecureOrigin) {
bnce3dd56f2016-06-01 10:37:1110932 HttpRequestInfo request;
10933 request.method = "GET";
10934 request.url = GURL("http://www.example.org/");
10935 request.load_flags = 0;
10936
10937 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
10938 StaticSocketDataProvider first_data;
10939 first_data.set_connect_data(mock_connect);
10940 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
10941
10942 MockRead data_reads[] = {
10943 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello world"),
10944 MockRead(ASYNC, OK),
10945 };
10946 StaticSocketDataProvider second_data(data_reads, arraysize(data_reads), NULL,
10947 0);
10948 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
10949
10950 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
10951
bnc525e175a2016-06-20 12:36:4010952 HttpServerProperties* http_server_properties =
bnce3dd56f2016-06-01 10:37:1110953 session->http_server_properties();
bnc3472afd2016-11-17 15:27:2110954 AlternativeService alternative_service(kProtoHTTP2, "", 444);
bnce3dd56f2016-06-01 10:37:1110955 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:2110956 http_server_properties->SetHttp2AlternativeService(
bnce3dd56f2016-06-01 10:37:1110957 url::SchemeHostPort(request.url), alternative_service, expiration);
10958
bnc691fda62016-08-12 00:43:1610959 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
bnce3dd56f2016-06-01 10:37:1110960 TestCompletionCallback callback;
10961
tfarina42834112016-09-22 13:38:2010962 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
bnce3dd56f2016-06-01 10:37:1110963 // Alternative service is not used, request fails.
robpercival214763f2016-07-01 23:27:0110964 EXPECT_THAT(callback.GetResult(rv), IsError(ERR_CONNECTION_REFUSED));
bnce3dd56f2016-06-01 10:37:1110965}
10966
bncd16676a2016-07-20 16:23:0110967TEST_F(HttpNetworkTransactionTest, ClearAlternativeServices) {
bnc4f575852015-10-14 18:35:0810968 // Set an alternative service for origin.
danakj1fd259a02016-04-16 03:17:0910969 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc525e175a2016-06-20 12:36:4010970 HttpServerProperties* http_server_properties =
10971 session->http_server_properties();
bncb26024382016-06-29 02:39:4510972 url::SchemeHostPort test_server("https", "www.example.org", 443);
bnc3472afd2016-11-17 15:27:2110973 AlternativeService alternative_service(kProtoQUIC, "", 80);
bnc4f575852015-10-14 18:35:0810974 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:2110975 http_server_properties->SetQuicAlternativeService(
10976 test_server, alternative_service, expiration,
10977 session->params().quic_supported_versions);
zhongyic4de03032017-05-19 04:07:3410978 EXPECT_EQ(
10979 1u,
10980 http_server_properties->GetAlternativeServiceInfos(test_server).size());
bnc4f575852015-10-14 18:35:0810981
10982 // Send a clear header.
10983 MockRead data_reads[] = {
10984 MockRead("HTTP/1.1 200 OK\r\n"),
10985 MockRead("Alt-Svc: clear\r\n"),
10986 MockRead("\r\n"),
10987 MockRead("hello world"),
10988 MockRead(SYNCHRONOUS, OK),
10989 };
10990 StaticSocketDataProvider data(data_reads, arraysize(data_reads), nullptr, 0);
10991 session_deps_.socket_factory->AddSocketDataProvider(&data);
10992
bncb26024382016-06-29 02:39:4510993 SSLSocketDataProvider ssl(ASYNC, OK);
Ryan Sleevi4f832092017-11-21 23:25:4910994 ssl.ssl_info.cert =
10995 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem");
10996 ASSERT_TRUE(ssl.ssl_info.cert);
bncb26024382016-06-29 02:39:4510997 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
10998
bnc4f575852015-10-14 18:35:0810999 HttpRequestInfo request;
11000 request.method = "GET";
bncb26024382016-06-29 02:39:4511001 request.url = GURL("https://www.example.org/");
bnc4f575852015-10-14 18:35:0811002
11003 TestCompletionCallback callback;
11004
bnc691fda62016-08-12 00:43:1611005 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
bnc4f575852015-10-14 18:35:0811006
tfarina42834112016-09-22 13:38:2011007 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0111008 EXPECT_THAT(callback.GetResult(rv), IsOk());
bnc4f575852015-10-14 18:35:0811009
bnc691fda62016-08-12 00:43:1611010 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5211011 ASSERT_TRUE(response);
11012 ASSERT_TRUE(response->headers);
bnc4f575852015-10-14 18:35:0811013 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
11014 EXPECT_FALSE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5211015 EXPECT_FALSE(response->was_alpn_negotiated);
bnc4f575852015-10-14 18:35:0811016
11017 std::string response_data;
bnc691fda62016-08-12 00:43:1611018 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
bnc4f575852015-10-14 18:35:0811019 EXPECT_EQ("hello world", response_data);
11020
zhongyic4de03032017-05-19 04:07:3411021 EXPECT_TRUE(
11022 http_server_properties->GetAlternativeServiceInfos(test_server).empty());
bnc4f575852015-10-14 18:35:0811023}
11024
bncd16676a2016-07-20 16:23:0111025TEST_F(HttpNetworkTransactionTest, HonorMultipleAlternativeServiceHeaders) {
bncc958faa2015-07-31 18:14:5211026 MockRead data_reads[] = {
11027 MockRead("HTTP/1.1 200 OK\r\n"),
bnc2df4b522016-07-08 18:17:4311028 MockRead("Alt-Svc: h2=\"www.example.com:443\","),
11029 MockRead("h2=\":1234\"\r\n\r\n"),
bncc958faa2015-07-31 18:14:5211030 MockRead("hello world"),
11031 MockRead(SYNCHRONOUS, OK),
11032 };
11033
11034 HttpRequestInfo request;
11035 request.method = "GET";
bncb26024382016-06-29 02:39:4511036 request.url = GURL("https://www.example.org/");
bncc958faa2015-07-31 18:14:5211037
11038 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
bncc958faa2015-07-31 18:14:5211039 session_deps_.socket_factory->AddSocketDataProvider(&data);
11040
bncb26024382016-06-29 02:39:4511041 SSLSocketDataProvider ssl(ASYNC, OK);
Ryan Sleevi4f832092017-11-21 23:25:4911042 ssl.ssl_info.cert =
11043 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem");
11044 ASSERT_TRUE(ssl.ssl_info.cert);
bncb26024382016-06-29 02:39:4511045 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
11046
bncc958faa2015-07-31 18:14:5211047 TestCompletionCallback callback;
11048
danakj1fd259a02016-04-16 03:17:0911049 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1611050 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
bncc958faa2015-07-31 18:14:5211051
tfarina42834112016-09-22 13:38:2011052 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0111053 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
bncc958faa2015-07-31 18:14:5211054
bncb26024382016-06-29 02:39:4511055 url::SchemeHostPort test_server("https", "www.example.org", 443);
bnc525e175a2016-06-20 12:36:4011056 HttpServerProperties* http_server_properties =
11057 session->http_server_properties();
zhongyic4de03032017-05-19 04:07:3411058 EXPECT_TRUE(
11059 http_server_properties->GetAlternativeServiceInfos(test_server).empty());
bncc958faa2015-07-31 18:14:5211060
robpercival214763f2016-07-01 23:27:0111061 EXPECT_THAT(callback.WaitForResult(), IsOk());
bncc958faa2015-07-31 18:14:5211062
bnc691fda62016-08-12 00:43:1611063 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5211064 ASSERT_TRUE(response);
11065 ASSERT_TRUE(response->headers);
bncc958faa2015-07-31 18:14:5211066 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
11067 EXPECT_FALSE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5211068 EXPECT_FALSE(response->was_alpn_negotiated);
bncc958faa2015-07-31 18:14:5211069
11070 std::string response_data;
bnc691fda62016-08-12 00:43:1611071 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
bncc958faa2015-07-31 18:14:5211072 EXPECT_EQ("hello world", response_data);
11073
zhongyic4de03032017-05-19 04:07:3411074 AlternativeServiceInfoVector alternative_service_info_vector =
11075 http_server_properties->GetAlternativeServiceInfos(test_server);
11076 ASSERT_EQ(2u, alternative_service_info_vector.size());
11077
11078 AlternativeService alternative_service(kProtoHTTP2, "www.example.com", 443);
11079 EXPECT_EQ(alternative_service,
zhongyi422ce352017-06-09 23:28:5411080 alternative_service_info_vector[0].alternative_service());
zhongyic4de03032017-05-19 04:07:3411081 AlternativeService alternative_service_2(kProtoHTTP2, "www.example.org",
11082 1234);
11083 EXPECT_EQ(alternative_service_2,
zhongyi422ce352017-06-09 23:28:5411084 alternative_service_info_vector[1].alternative_service());
bncc958faa2015-07-31 18:14:5211085}
11086
bncd16676a2016-07-20 16:23:0111087TEST_F(HttpNetworkTransactionTest, IdentifyQuicBroken) {
zhongyi3d4a55e72016-04-22 20:36:4611088 url::SchemeHostPort server("https", "origin.example.org", 443);
zhongyi48704c182015-12-07 07:52:0211089 HostPortPair alternative("alternative.example.org", 443);
11090 std::string origin_url = "https://origin.example.org:443";
11091 std::string alternative_url = "https://alternative.example.org:443";
11092
11093 // Negotiate HTTP/1.1 with alternative.example.org.
11094 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3611095 ssl.next_proto = kProtoHTTP11;
zhongyi48704c182015-12-07 07:52:0211096 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
11097
11098 // HTTP/1.1 data for request.
11099 MockWrite http_writes[] = {
11100 MockWrite("GET / HTTP/1.1\r\n"
11101 "Host: alternative.example.org\r\n"
11102 "Connection: keep-alive\r\n\r\n"),
11103 };
11104
11105 MockRead http_reads[] = {
11106 MockRead("HTTP/1.1 200 OK\r\n"
11107 "Content-Type: text/html; charset=iso-8859-1\r\n"
11108 "Content-Length: 40\r\n\r\n"
11109 "first HTTP/1.1 response from alternative"),
11110 };
11111 StaticSocketDataProvider http_data(http_reads, arraysize(http_reads),
11112 http_writes, arraysize(http_writes));
11113 session_deps_.socket_factory->AddSocketDataProvider(&http_data);
11114
11115 StaticSocketDataProvider data_refused;
11116 data_refused.set_connect_data(MockConnect(ASYNC, ERR_CONNECTION_REFUSED));
11117 session_deps_.socket_factory->AddSocketDataProvider(&data_refused);
11118
zhongyi3d4a55e72016-04-22 20:36:4611119 // Set up a QUIC alternative service for server.
danakj1fd259a02016-04-16 03:17:0911120 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc525e175a2016-06-20 12:36:4011121 HttpServerProperties* http_server_properties =
zhongyi48704c182015-12-07 07:52:0211122 session->http_server_properties();
bnc3472afd2016-11-17 15:27:2111123 AlternativeService alternative_service(kProtoQUIC, alternative);
zhongyi48704c182015-12-07 07:52:0211124 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:2111125 http_server_properties->SetQuicAlternativeService(
11126 server, alternative_service, expiration,
11127 HttpNetworkSession::Params().quic_supported_versions);
zhongyi48704c182015-12-07 07:52:0211128 // Mark the QUIC alternative service as broken.
11129 http_server_properties->MarkAlternativeServiceBroken(alternative_service);
11130
zhongyi48704c182015-12-07 07:52:0211131 HttpRequestInfo request;
krasinc06a72a2016-12-21 03:42:4611132 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
zhongyi48704c182015-12-07 07:52:0211133 request.method = "GET";
11134 request.url = GURL(origin_url);
zhongyi48704c182015-12-07 07:52:0211135 TestCompletionCallback callback;
11136 NetErrorDetails details;
11137 EXPECT_FALSE(details.quic_broken);
11138
tfarina42834112016-09-22 13:38:2011139 trans.Start(&request, callback.callback(), NetLogWithSource());
bnc691fda62016-08-12 00:43:1611140 trans.PopulateNetErrorDetails(&details);
zhongyi48704c182015-12-07 07:52:0211141 EXPECT_TRUE(details.quic_broken);
11142}
11143
bncd16676a2016-07-20 16:23:0111144TEST_F(HttpNetworkTransactionTest, IdentifyQuicNotBroken) {
zhongyi3d4a55e72016-04-22 20:36:4611145 url::SchemeHostPort server("https", "origin.example.org", 443);
zhongyi48704c182015-12-07 07:52:0211146 HostPortPair alternative1("alternative1.example.org", 443);
11147 HostPortPair alternative2("alternative2.example.org", 443);
11148 std::string origin_url = "https://origin.example.org:443";
11149 std::string alternative_url1 = "https://alternative1.example.org:443";
11150 std::string alternative_url2 = "https://alternative2.example.org:443";
11151
11152 // Negotiate HTTP/1.1 with alternative1.example.org.
11153 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3611154 ssl.next_proto = kProtoHTTP11;
zhongyi48704c182015-12-07 07:52:0211155 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
11156
11157 // HTTP/1.1 data for request.
11158 MockWrite http_writes[] = {
11159 MockWrite("GET / HTTP/1.1\r\n"
11160 "Host: alternative1.example.org\r\n"
11161 "Connection: keep-alive\r\n\r\n"),
11162 };
11163
11164 MockRead http_reads[] = {
11165 MockRead("HTTP/1.1 200 OK\r\n"
11166 "Content-Type: text/html; charset=iso-8859-1\r\n"
11167 "Content-Length: 40\r\n\r\n"
11168 "first HTTP/1.1 response from alternative1"),
11169 };
11170 StaticSocketDataProvider http_data(http_reads, arraysize(http_reads),
11171 http_writes, arraysize(http_writes));
11172 session_deps_.socket_factory->AddSocketDataProvider(&http_data);
11173
11174 StaticSocketDataProvider data_refused;
11175 data_refused.set_connect_data(MockConnect(ASYNC, ERR_CONNECTION_REFUSED));
11176 session_deps_.socket_factory->AddSocketDataProvider(&data_refused);
11177
danakj1fd259a02016-04-16 03:17:0911178 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc525e175a2016-06-20 12:36:4011179 HttpServerProperties* http_server_properties =
zhongyi48704c182015-12-07 07:52:0211180 session->http_server_properties();
11181
zhongyi3d4a55e72016-04-22 20:36:4611182 // Set up two QUIC alternative services for server.
zhongyi48704c182015-12-07 07:52:0211183 AlternativeServiceInfoVector alternative_service_info_vector;
11184 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
11185
bnc3472afd2016-11-17 15:27:2111186 AlternativeService alternative_service1(kProtoQUIC, alternative1);
zhongyie537a002017-06-27 16:48:2111187 alternative_service_info_vector.push_back(
11188 AlternativeServiceInfo::CreateQuicAlternativeServiceInfo(
11189 alternative_service1, expiration,
11190 session->params().quic_supported_versions));
bnc3472afd2016-11-17 15:27:2111191 AlternativeService alternative_service2(kProtoQUIC, alternative2);
zhongyie537a002017-06-27 16:48:2111192 alternative_service_info_vector.push_back(
11193 AlternativeServiceInfo::CreateQuicAlternativeServiceInfo(
11194 alternative_service2, expiration,
11195 session->params().quic_supported_versions));
zhongyi48704c182015-12-07 07:52:0211196
11197 http_server_properties->SetAlternativeServices(
zhongyi3d4a55e72016-04-22 20:36:4611198 server, alternative_service_info_vector);
zhongyi48704c182015-12-07 07:52:0211199
11200 // Mark one of the QUIC alternative service as broken.
11201 http_server_properties->MarkAlternativeServiceBroken(alternative_service1);
zhongyic4de03032017-05-19 04:07:3411202 EXPECT_EQ(2u,
11203 http_server_properties->GetAlternativeServiceInfos(server).size());
zhongyi48704c182015-12-07 07:52:0211204
zhongyi48704c182015-12-07 07:52:0211205 HttpRequestInfo request;
krasinc06a72a2016-12-21 03:42:4611206 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
zhongyi48704c182015-12-07 07:52:0211207 request.method = "GET";
11208 request.url = GURL(origin_url);
zhongyi48704c182015-12-07 07:52:0211209 TestCompletionCallback callback;
11210 NetErrorDetails details;
11211 EXPECT_FALSE(details.quic_broken);
11212
tfarina42834112016-09-22 13:38:2011213 trans.Start(&request, callback.callback(), NetLogWithSource());
bnc691fda62016-08-12 00:43:1611214 trans.PopulateNetErrorDetails(&details);
zhongyi48704c182015-12-07 07:52:0211215 EXPECT_FALSE(details.quic_broken);
11216}
11217
bncd16676a2016-07-20 16:23:0111218TEST_F(HttpNetworkTransactionTest, MarkBrokenAlternateProtocolAndFallback) {
[email protected]564b4912010-03-09 16:30:4211219 HttpRequestInfo request;
11220 request.method = "GET";
bncb26024382016-06-29 02:39:4511221 request.url = GURL("https://www.example.org/");
[email protected]564b4912010-03-09 16:30:4211222
[email protected]d973e99a2012-02-17 21:02:3611223 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
[email protected]564b4912010-03-09 16:30:4211224 StaticSocketDataProvider first_data;
11225 first_data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:0711226 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
bncb26024382016-06-29 02:39:4511227 SSLSocketDataProvider ssl_http11(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3611228 ssl_http11.next_proto = kProtoHTTP11;
bncb26024382016-06-29 02:39:4511229 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_http11);
[email protected]564b4912010-03-09 16:30:4211230
11231 MockRead data_reads[] = {
11232 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
11233 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:0611234 MockRead(ASYNC, OK),
[email protected]564b4912010-03-09 16:30:4211235 };
11236 StaticSocketDataProvider second_data(
11237 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0711238 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
[email protected]564b4912010-03-09 16:30:4211239
danakj1fd259a02016-04-16 03:17:0911240 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]564b4912010-03-09 16:30:4211241
bnc525e175a2016-06-20 12:36:4011242 HttpServerProperties* http_server_properties =
[email protected]17291a022011-10-10 07:32:5311243 session->http_server_properties();
zhongyi3d4a55e72016-04-22 20:36:4611244 const url::SchemeHostPort server(request.url);
[email protected]3912662a32011-10-04 00:51:1111245 // Port must be < 1024, or the header will be ignored (since initial port was
11246 // port 80 (another restricted port).
zhongyie537a002017-06-27 16:48:2111247 // Port is ignored by MockConnect anyway.
11248 const AlternativeService alternative_service(kProtoHTTP2, "www.example.org",
11249 666);
bnc7dc7e1b42015-07-28 14:43:1211250 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:2111251 http_server_properties->SetHttp2AlternativeService(
11252 server, alternative_service, expiration);
[email protected]564b4912010-03-09 16:30:4211253
bnc691fda62016-08-12 00:43:1611254 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]49639fa2011-12-20 23:22:4111255 TestCompletionCallback callback;
[email protected]564b4912010-03-09 16:30:4211256
tfarina42834112016-09-22 13:38:2011257 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0111258 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
11259 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]564b4912010-03-09 16:30:4211260
bnc691fda62016-08-12 00:43:1611261 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5211262 ASSERT_TRUE(response);
11263 ASSERT_TRUE(response->headers);
[email protected]564b4912010-03-09 16:30:4211264 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
11265
11266 std::string response_data;
bnc691fda62016-08-12 00:43:1611267 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
[email protected]564b4912010-03-09 16:30:4211268 EXPECT_EQ("hello world", response_data);
11269
zhongyic4de03032017-05-19 04:07:3411270 const AlternativeServiceInfoVector alternative_service_info_vector =
11271 http_server_properties->GetAlternativeServiceInfos(server);
11272 ASSERT_EQ(1u, alternative_service_info_vector.size());
11273 EXPECT_EQ(alternative_service,
zhongyi422ce352017-06-09 23:28:5411274 alternative_service_info_vector[0].alternative_service());
zhongyic4de03032017-05-19 04:07:3411275 EXPECT_TRUE(
11276 http_server_properties->IsAlternativeServiceBroken(alternative_service));
[email protected]564b4912010-03-09 16:30:4211277}
11278
bnc55ff9da2015-08-19 18:42:3511279// Ensure that we are not allowed to redirect traffic via an alternate protocol
11280// to an unrestricted (port >= 1024) when the original traffic was on a
11281// restricted port (port < 1024). Ensure that we can redirect in all other
11282// cases.
bncd16676a2016-07-20 16:23:0111283TEST_F(HttpNetworkTransactionTest, AlternateProtocolPortRestrictedBlocked) {
[email protected]3912662a32011-10-04 00:51:1111284 HttpRequestInfo restricted_port_request;
11285 restricted_port_request.method = "GET";
bncb26024382016-06-29 02:39:4511286 restricted_port_request.url = GURL("https://www.example.org:1023/");
[email protected]3912662a32011-10-04 00:51:1111287 restricted_port_request.load_flags = 0;
11288
[email protected]d973e99a2012-02-17 21:02:3611289 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
[email protected]3912662a32011-10-04 00:51:1111290 StaticSocketDataProvider first_data;
11291 first_data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:0711292 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
[email protected]3912662a32011-10-04 00:51:1111293
11294 MockRead data_reads[] = {
11295 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
11296 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:0611297 MockRead(ASYNC, OK),
[email protected]3912662a32011-10-04 00:51:1111298 };
11299 StaticSocketDataProvider second_data(
11300 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0711301 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
bncb26024382016-06-29 02:39:4511302 SSLSocketDataProvider ssl_http11(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3611303 ssl_http11.next_proto = kProtoHTTP11;
bncb26024382016-06-29 02:39:4511304 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_http11);
[email protected]3912662a32011-10-04 00:51:1111305
danakj1fd259a02016-04-16 03:17:0911306 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]3912662a32011-10-04 00:51:1111307
bnc525e175a2016-06-20 12:36:4011308 HttpServerProperties* http_server_properties =
[email protected]17291a022011-10-10 07:32:5311309 session->http_server_properties();
[email protected]3912662a32011-10-04 00:51:1111310 const int kUnrestrictedAlternatePort = 1024;
bnc3472afd2016-11-17 15:27:2111311 AlternativeService alternative_service(kProtoHTTP2, "www.example.org",
11312 kUnrestrictedAlternatePort);
bnc7dc7e1b42015-07-28 14:43:1211313 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:2111314 http_server_properties->SetHttp2AlternativeService(
zhongyi3d4a55e72016-04-22 20:36:4611315 url::SchemeHostPort(restricted_port_request.url), alternative_service,
rchdc7b9052016-03-17 20:51:5011316 expiration);
[email protected]3912662a32011-10-04 00:51:1111317
bnc691fda62016-08-12 00:43:1611318 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]49639fa2011-12-20 23:22:4111319 TestCompletionCallback callback;
[email protected]3912662a32011-10-04 00:51:1111320
tfarina42834112016-09-22 13:38:2011321 int rv = trans.Start(&restricted_port_request, callback.callback(),
11322 NetLogWithSource());
robpercival214763f2016-07-01 23:27:0111323 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]3912662a32011-10-04 00:51:1111324 // Invalid change to unrestricted port should fail.
robpercival214763f2016-07-01 23:27:0111325 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_CONNECTION_REFUSED));
[email protected]c54c6962013-02-01 04:53:1911326}
[email protected]3912662a32011-10-04 00:51:1111327
bnc55ff9da2015-08-19 18:42:3511328// Ensure that we are allowed to redirect traffic via an alternate protocol to
11329// an unrestricted (port >= 1024) when the original traffic was on a restricted
11330// port (port < 1024) if we set |enable_user_alternate_protocol_ports|.
bncd16676a2016-07-20 16:23:0111331TEST_F(HttpNetworkTransactionTest, AlternateProtocolPortRestrictedPermitted) {
[email protected]bb88e1d32013-05-03 23:11:0711332 session_deps_.enable_user_alternate_protocol_ports = true;
[email protected]c54c6962013-02-01 04:53:1911333
11334 HttpRequestInfo restricted_port_request;
11335 restricted_port_request.method = "GET";
bncb26024382016-06-29 02:39:4511336 restricted_port_request.url = GURL("https://www.example.org:1023/");
[email protected]c54c6962013-02-01 04:53:1911337 restricted_port_request.load_flags = 0;
11338
11339 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
11340 StaticSocketDataProvider first_data;
11341 first_data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:0711342 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
[email protected]c54c6962013-02-01 04:53:1911343
11344 MockRead data_reads[] = {
11345 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
11346 MockRead("hello world"),
11347 MockRead(ASYNC, OK),
11348 };
11349 StaticSocketDataProvider second_data(
11350 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0711351 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
bncb26024382016-06-29 02:39:4511352 SSLSocketDataProvider ssl_http11(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3611353 ssl_http11.next_proto = kProtoHTTP11;
bncb26024382016-06-29 02:39:4511354 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_http11);
[email protected]c54c6962013-02-01 04:53:1911355
danakj1fd259a02016-04-16 03:17:0911356 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]c54c6962013-02-01 04:53:1911357
bnc525e175a2016-06-20 12:36:4011358 HttpServerProperties* http_server_properties =
[email protected]c54c6962013-02-01 04:53:1911359 session->http_server_properties();
11360 const int kUnrestrictedAlternatePort = 1024;
bnc3472afd2016-11-17 15:27:2111361 AlternativeService alternative_service(kProtoHTTP2, "www.example.org",
11362 kUnrestrictedAlternatePort);
bnc7dc7e1b42015-07-28 14:43:1211363 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:2111364 http_server_properties->SetHttp2AlternativeService(
zhongyi3d4a55e72016-04-22 20:36:4611365 url::SchemeHostPort(restricted_port_request.url), alternative_service,
rchdc7b9052016-03-17 20:51:5011366 expiration);
[email protected]c54c6962013-02-01 04:53:1911367
bnc691fda62016-08-12 00:43:1611368 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]c54c6962013-02-01 04:53:1911369 TestCompletionCallback callback;
11370
tfarina42834112016-09-22 13:38:2011371 EXPECT_EQ(ERR_IO_PENDING,
11372 trans.Start(&restricted_port_request, callback.callback(),
11373 NetLogWithSource()));
[email protected]c54c6962013-02-01 04:53:1911374 // Change to unrestricted port should succeed.
robpercival214763f2016-07-01 23:27:0111375 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]3912662a32011-10-04 00:51:1111376}
11377
bnc55ff9da2015-08-19 18:42:3511378// Ensure that we are not allowed to redirect traffic via an alternate protocol
11379// to an unrestricted (port >= 1024) when the original traffic was on a
11380// restricted port (port < 1024). Ensure that we can redirect in all other
11381// cases.
bncd16676a2016-07-20 16:23:0111382TEST_F(HttpNetworkTransactionTest, AlternateProtocolPortRestrictedAllowed) {
[email protected]3912662a32011-10-04 00:51:1111383 HttpRequestInfo restricted_port_request;
11384 restricted_port_request.method = "GET";
bncb26024382016-06-29 02:39:4511385 restricted_port_request.url = GURL("https://www.example.org:1023/");
[email protected]3912662a32011-10-04 00:51:1111386 restricted_port_request.load_flags = 0;
11387
[email protected]d973e99a2012-02-17 21:02:3611388 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
[email protected]3912662a32011-10-04 00:51:1111389 StaticSocketDataProvider first_data;
11390 first_data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:0711391 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
[email protected]3912662a32011-10-04 00:51:1111392
11393 MockRead data_reads[] = {
11394 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
11395 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:0611396 MockRead(ASYNC, OK),
[email protected]3912662a32011-10-04 00:51:1111397 };
11398 StaticSocketDataProvider second_data(
11399 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0711400 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
[email protected]3912662a32011-10-04 00:51:1111401
bncb26024382016-06-29 02:39:4511402 SSLSocketDataProvider ssl(ASYNC, OK);
11403 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
11404
danakj1fd259a02016-04-16 03:17:0911405 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]3912662a32011-10-04 00:51:1111406
bnc525e175a2016-06-20 12:36:4011407 HttpServerProperties* http_server_properties =
[email protected]17291a022011-10-10 07:32:5311408 session->http_server_properties();
[email protected]3912662a32011-10-04 00:51:1111409 const int kRestrictedAlternatePort = 80;
bnc3472afd2016-11-17 15:27:2111410 AlternativeService alternative_service(kProtoHTTP2, "www.example.org",
11411 kRestrictedAlternatePort);
bnc7dc7e1b42015-07-28 14:43:1211412 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:2111413 http_server_properties->SetHttp2AlternativeService(
zhongyi3d4a55e72016-04-22 20:36:4611414 url::SchemeHostPort(restricted_port_request.url), alternative_service,
rchdc7b9052016-03-17 20:51:5011415 expiration);
[email protected]3912662a32011-10-04 00:51:1111416
bnc691fda62016-08-12 00:43:1611417 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]49639fa2011-12-20 23:22:4111418 TestCompletionCallback callback;
[email protected]3912662a32011-10-04 00:51:1111419
tfarina42834112016-09-22 13:38:2011420 int rv = trans.Start(&restricted_port_request, callback.callback(),
11421 NetLogWithSource());
robpercival214763f2016-07-01 23:27:0111422 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]3912662a32011-10-04 00:51:1111423 // Valid change to restricted port should pass.
robpercival214763f2016-07-01 23:27:0111424 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]3912662a32011-10-04 00:51:1111425}
11426
bnc55ff9da2015-08-19 18:42:3511427// Ensure that we are not allowed to redirect traffic via an alternate protocol
11428// to an unrestricted (port >= 1024) when the original traffic was on a
11429// restricted port (port < 1024). Ensure that we can redirect in all other
11430// cases.
bncd16676a2016-07-20 16:23:0111431TEST_F(HttpNetworkTransactionTest, AlternateProtocolPortUnrestrictedAllowed1) {
[email protected]3912662a32011-10-04 00:51:1111432 HttpRequestInfo unrestricted_port_request;
11433 unrestricted_port_request.method = "GET";
bncb26024382016-06-29 02:39:4511434 unrestricted_port_request.url = GURL("https://www.example.org:1024/");
[email protected]3912662a32011-10-04 00:51:1111435 unrestricted_port_request.load_flags = 0;
11436
[email protected]d973e99a2012-02-17 21:02:3611437 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
[email protected]3912662a32011-10-04 00:51:1111438 StaticSocketDataProvider first_data;
11439 first_data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:0711440 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
[email protected]3912662a32011-10-04 00:51:1111441
11442 MockRead data_reads[] = {
11443 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
11444 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:0611445 MockRead(ASYNC, OK),
[email protected]3912662a32011-10-04 00:51:1111446 };
11447 StaticSocketDataProvider second_data(
11448 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0711449 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
bncb26024382016-06-29 02:39:4511450 SSLSocketDataProvider ssl_http11(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3611451 ssl_http11.next_proto = kProtoHTTP11;
bncb26024382016-06-29 02:39:4511452 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_http11);
[email protected]3912662a32011-10-04 00:51:1111453
danakj1fd259a02016-04-16 03:17:0911454 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]3912662a32011-10-04 00:51:1111455
bnc525e175a2016-06-20 12:36:4011456 HttpServerProperties* http_server_properties =
[email protected]17291a022011-10-10 07:32:5311457 session->http_server_properties();
[email protected]3912662a32011-10-04 00:51:1111458 const int kRestrictedAlternatePort = 80;
bnc3472afd2016-11-17 15:27:2111459 AlternativeService alternative_service(kProtoHTTP2, "www.example.org",
11460 kRestrictedAlternatePort);
bnc7dc7e1b42015-07-28 14:43:1211461 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:2111462 http_server_properties->SetHttp2AlternativeService(
zhongyi3d4a55e72016-04-22 20:36:4611463 url::SchemeHostPort(unrestricted_port_request.url), alternative_service,
rchdc7b9052016-03-17 20:51:5011464 expiration);
[email protected]3912662a32011-10-04 00:51:1111465
bnc691fda62016-08-12 00:43:1611466 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]49639fa2011-12-20 23:22:4111467 TestCompletionCallback callback;
[email protected]3912662a32011-10-04 00:51:1111468
bnc691fda62016-08-12 00:43:1611469 int rv = trans.Start(&unrestricted_port_request, callback.callback(),
tfarina42834112016-09-22 13:38:2011470 NetLogWithSource());
robpercival214763f2016-07-01 23:27:0111471 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]3912662a32011-10-04 00:51:1111472 // Valid change to restricted port should pass.
robpercival214763f2016-07-01 23:27:0111473 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]3912662a32011-10-04 00:51:1111474}
11475
bnc55ff9da2015-08-19 18:42:3511476// Ensure that we are not allowed to redirect traffic via an alternate protocol
11477// to an unrestricted (port >= 1024) when the original traffic was on a
11478// restricted port (port < 1024). Ensure that we can redirect in all other
11479// cases.
bncd16676a2016-07-20 16:23:0111480TEST_F(HttpNetworkTransactionTest, AlternateProtocolPortUnrestrictedAllowed2) {
[email protected]3912662a32011-10-04 00:51:1111481 HttpRequestInfo unrestricted_port_request;
11482 unrestricted_port_request.method = "GET";
bncb26024382016-06-29 02:39:4511483 unrestricted_port_request.url = GURL("https://www.example.org:1024/");
[email protected]3912662a32011-10-04 00:51:1111484 unrestricted_port_request.load_flags = 0;
11485
[email protected]d973e99a2012-02-17 21:02:3611486 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
[email protected]3912662a32011-10-04 00:51:1111487 StaticSocketDataProvider first_data;
11488 first_data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:0711489 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
[email protected]3912662a32011-10-04 00:51:1111490
11491 MockRead data_reads[] = {
11492 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
11493 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:0611494 MockRead(ASYNC, OK),
[email protected]3912662a32011-10-04 00:51:1111495 };
11496 StaticSocketDataProvider second_data(
11497 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0711498 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
[email protected]3912662a32011-10-04 00:51:1111499
bncb26024382016-06-29 02:39:4511500 SSLSocketDataProvider ssl(ASYNC, OK);
11501 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
11502
danakj1fd259a02016-04-16 03:17:0911503 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]3912662a32011-10-04 00:51:1111504
bnc525e175a2016-06-20 12:36:4011505 HttpServerProperties* http_server_properties =
[email protected]17291a022011-10-10 07:32:5311506 session->http_server_properties();
bnc0bbb02622015-07-23 10:06:2211507 const int kUnrestrictedAlternatePort = 1025;
bnc3472afd2016-11-17 15:27:2111508 AlternativeService alternative_service(kProtoHTTP2, "www.example.org",
11509 kUnrestrictedAlternatePort);
bnc7dc7e1b42015-07-28 14:43:1211510 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:2111511 http_server_properties->SetHttp2AlternativeService(
zhongyi3d4a55e72016-04-22 20:36:4611512 url::SchemeHostPort(unrestricted_port_request.url), alternative_service,
rchdc7b9052016-03-17 20:51:5011513 expiration);
[email protected]3912662a32011-10-04 00:51:1111514
bnc691fda62016-08-12 00:43:1611515 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]49639fa2011-12-20 23:22:4111516 TestCompletionCallback callback;
[email protected]3912662a32011-10-04 00:51:1111517
bnc691fda62016-08-12 00:43:1611518 int rv = trans.Start(&unrestricted_port_request, callback.callback(),
tfarina42834112016-09-22 13:38:2011519 NetLogWithSource());
robpercival214763f2016-07-01 23:27:0111520 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]3912662a32011-10-04 00:51:1111521 // Valid change to an unrestricted port should pass.
robpercival214763f2016-07-01 23:27:0111522 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]3912662a32011-10-04 00:51:1111523}
11524
bnc55ff9da2015-08-19 18:42:3511525// Ensure that we are not allowed to redirect traffic via an alternate protocol
11526// to an unsafe port, and that we resume the second HttpStreamFactoryImpl::Job
11527// once the alternate protocol request fails.
bncd16676a2016-07-20 16:23:0111528TEST_F(HttpNetworkTransactionTest, AlternateProtocolUnsafeBlocked) {
[email protected]eb6234e2012-01-19 01:50:0211529 HttpRequestInfo request;
11530 request.method = "GET";
bncce36dca22015-04-21 22:11:2311531 request.url = GURL("http://www.example.org/");
[email protected]eb6234e2012-01-19 01:50:0211532
11533 // The alternate protocol request will error out before we attempt to connect,
11534 // so only the standard HTTP request will try to connect.
11535 MockRead data_reads[] = {
11536 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
11537 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:0611538 MockRead(ASYNC, OK),
[email protected]eb6234e2012-01-19 01:50:0211539 };
11540 StaticSocketDataProvider data(
11541 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0711542 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]eb6234e2012-01-19 01:50:0211543
danakj1fd259a02016-04-16 03:17:0911544 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]eb6234e2012-01-19 01:50:0211545
bnc525e175a2016-06-20 12:36:4011546 HttpServerProperties* http_server_properties =
[email protected]eb6234e2012-01-19 01:50:0211547 session->http_server_properties();
11548 const int kUnsafePort = 7;
bnc3472afd2016-11-17 15:27:2111549 AlternativeService alternative_service(kProtoHTTP2, "www.example.org",
11550 kUnsafePort);
bnc7dc7e1b42015-07-28 14:43:1211551 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:2111552 http_server_properties->SetHttp2AlternativeService(
zhongyi3d4a55e72016-04-22 20:36:4611553 url::SchemeHostPort(request.url), alternative_service, expiration);
[email protected]eb6234e2012-01-19 01:50:0211554
bnc691fda62016-08-12 00:43:1611555 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]eb6234e2012-01-19 01:50:0211556 TestCompletionCallback callback;
11557
tfarina42834112016-09-22 13:38:2011558 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0111559 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]eb6234e2012-01-19 01:50:0211560 // The HTTP request should succeed.
robpercival214763f2016-07-01 23:27:0111561 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]eb6234e2012-01-19 01:50:0211562
bnc691fda62016-08-12 00:43:1611563 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5211564 ASSERT_TRUE(response);
11565 ASSERT_TRUE(response->headers);
[email protected]eb6234e2012-01-19 01:50:0211566 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
11567
11568 std::string response_data;
bnc691fda62016-08-12 00:43:1611569 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
[email protected]eb6234e2012-01-19 01:50:0211570 EXPECT_EQ("hello world", response_data);
11571}
11572
bncd16676a2016-07-20 16:23:0111573TEST_F(HttpNetworkTransactionTest, UseAlternateProtocolForNpnSpdy) {
[email protected]2ff8b312010-04-26 22:20:5411574 HttpRequestInfo request;
11575 request.method = "GET";
bncb26024382016-06-29 02:39:4511576 request.url = GURL("https://www.example.org/");
[email protected]2ff8b312010-04-26 22:20:5411577
11578 MockRead data_reads[] = {
bncc958faa2015-07-31 18:14:5211579 MockRead("HTTP/1.1 200 OK\r\n"),
bnc2df4b522016-07-08 18:17:4311580 MockRead(kAlternativeServiceHttpHeader),
bncc958faa2015-07-31 18:14:5211581 MockRead("\r\n"),
11582 MockRead("hello world"),
11583 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
11584 MockRead(ASYNC, OK)};
[email protected]2ff8b312010-04-26 22:20:5411585
11586 StaticSocketDataProvider first_transaction(
11587 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0711588 session_deps_.socket_factory->AddSocketDataProvider(&first_transaction);
bncb26024382016-06-29 02:39:4511589 SSLSocketDataProvider ssl_http11(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3611590 ssl_http11.next_proto = kProtoHTTP11;
bncb26024382016-06-29 02:39:4511591 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_http11);
[email protected]2ff8b312010-04-26 22:20:5411592
bnc032658ba2016-09-26 18:17:1511593 AddSSLSocketData();
[email protected]2ff8b312010-04-26 22:20:5411594
bncdf80d44fd2016-07-15 20:27:4111595 SpdySerializedFrame req(
bncb26024382016-06-29 02:39:4511596 spdy_util_.ConstructSpdyGet("https://www.example.org/", 1, LOWEST));
bncdf80d44fd2016-07-15 20:27:4111597 MockWrite spdy_writes[] = {CreateMockWrite(req, 0)};
[email protected]2ff8b312010-04-26 22:20:5411598
bnc42331402016-07-25 13:36:1511599 SpdySerializedFrame resp(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
bncdf80d44fd2016-07-15 20:27:4111600 SpdySerializedFrame data(spdy_util_.ConstructSpdyDataFrame(1, true));
[email protected]2ff8b312010-04-26 22:20:5411601 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:4111602 CreateMockRead(resp, 1), CreateMockRead(data, 2), MockRead(ASYNC, 0, 3),
[email protected]2ff8b312010-04-26 22:20:5411603 };
11604
rch8e6c6c42015-05-01 14:05:1311605 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
11606 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:0711607 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]2ff8b312010-04-26 22:20:5411608
[email protected]d973e99a2012-02-17 21:02:3611609 MockConnect never_finishing_connect(SYNCHRONOUS, ERR_IO_PENDING);
[email protected]2d6728692011-03-12 01:39:5511610 StaticSocketDataProvider hanging_non_alternate_protocol_socket(
11611 NULL, 0, NULL, 0);
11612 hanging_non_alternate_protocol_socket.set_connect_data(
11613 never_finishing_connect);
[email protected]bb88e1d32013-05-03 23:11:0711614 session_deps_.socket_factory->AddSocketDataProvider(
[email protected]2d6728692011-03-12 01:39:5511615 &hanging_non_alternate_protocol_socket);
11616
[email protected]49639fa2011-12-20 23:22:4111617 TestCompletionCallback callback;
[email protected]2ff8b312010-04-26 22:20:5411618
danakj1fd259a02016-04-16 03:17:0911619 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc87dcefc2017-05-25 12:47:5811620 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:1911621 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]2ff8b312010-04-26 22:20:5411622
tfarina42834112016-09-22 13:38:2011623 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0111624 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
11625 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]2ff8b312010-04-26 22:20:5411626
11627 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5211628 ASSERT_TRUE(response);
11629 ASSERT_TRUE(response->headers);
[email protected]2ff8b312010-04-26 22:20:5411630 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
11631
11632 std::string response_data;
robpercival214763f2016-07-01 23:27:0111633 ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
[email protected]2ff8b312010-04-26 22:20:5411634 EXPECT_EQ("hello world", response_data);
11635
bnc87dcefc2017-05-25 12:47:5811636 trans =
Jeremy Roman0579ed62017-08-29 15:56:1911637 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]2ff8b312010-04-26 22:20:5411638
tfarina42834112016-09-22 13:38:2011639 rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0111640 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
11641 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]2ff8b312010-04-26 22:20:5411642
11643 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5211644 ASSERT_TRUE(response);
11645 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0211646 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]65041fa2010-05-21 06:56:5311647 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5211648 EXPECT_TRUE(response->was_alpn_negotiated);
[email protected]2ff8b312010-04-26 22:20:5411649
robpercival214763f2016-07-01 23:27:0111650 ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
[email protected]2ff8b312010-04-26 22:20:5411651 EXPECT_EQ("hello!", response_data);
[email protected]2ff8b312010-04-26 22:20:5411652}
11653
bncd16676a2016-07-20 16:23:0111654TEST_F(HttpNetworkTransactionTest, AlternateProtocolWithSpdyLateBinding) {
[email protected]2d6728692011-03-12 01:39:5511655 HttpRequestInfo request;
11656 request.method = "GET";
bncb26024382016-06-29 02:39:4511657 request.url = GURL("https://www.example.org/");
[email protected]2d6728692011-03-12 01:39:5511658
bncb26024382016-06-29 02:39:4511659 // First transaction receives Alt-Svc header over HTTP/1.1.
[email protected]2d6728692011-03-12 01:39:5511660 MockRead data_reads[] = {
bncc958faa2015-07-31 18:14:5211661 MockRead("HTTP/1.1 200 OK\r\n"),
bnc2df4b522016-07-08 18:17:4311662 MockRead(kAlternativeServiceHttpHeader),
bncc958faa2015-07-31 18:14:5211663 MockRead("\r\n"),
11664 MockRead("hello world"),
11665 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
11666 MockRead(ASYNC, OK),
[email protected]2d6728692011-03-12 01:39:5511667 };
11668
bncb26024382016-06-29 02:39:4511669 StaticSocketDataProvider http11_data(data_reads, arraysize(data_reads), NULL,
11670 0);
11671 session_deps_.socket_factory->AddSocketDataProvider(&http11_data);
[email protected]2d6728692011-03-12 01:39:5511672
bncb26024382016-06-29 02:39:4511673 SSLSocketDataProvider ssl_http11(ASYNC, OK);
Ryan Sleevi4f832092017-11-21 23:25:4911674 ssl_http11.ssl_info.cert =
11675 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem");
11676 ASSERT_TRUE(ssl_http11.ssl_info.cert);
bncb26024382016-06-29 02:39:4511677 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_http11);
11678
11679 // Second transaction starts an alternative and a non-alternative Job.
11680 // Both sockets hang.
[email protected]d973e99a2012-02-17 21:02:3611681 MockConnect never_finishing_connect(SYNCHRONOUS, ERR_IO_PENDING);
mmenkecc2298e2015-12-07 18:20:1811682 StaticSocketDataProvider hanging_socket1(NULL, 0, NULL, 0);
11683 hanging_socket1.set_connect_data(never_finishing_connect);
mmenkecc2298e2015-12-07 18:20:1811684 session_deps_.socket_factory->AddSocketDataProvider(&hanging_socket1);
11685
11686 StaticSocketDataProvider hanging_socket2(NULL, 0, NULL, 0);
11687 hanging_socket2.set_connect_data(never_finishing_connect);
11688 session_deps_.socket_factory->AddSocketDataProvider(&hanging_socket2);
[email protected]2d6728692011-03-12 01:39:5511689
bncb26024382016-06-29 02:39:4511690 // Third transaction starts an alternative and a non-alternative job.
11691 // The non-alternative job hangs, but the alternative one succeeds.
11692 // The second transaction, still pending, binds to this socket.
bncdf80d44fd2016-07-15 20:27:4111693 SpdySerializedFrame req1(
bncb26024382016-06-29 02:39:4511694 spdy_util_.ConstructSpdyGet("https://www.example.org/", 1, LOWEST));
bncdf80d44fd2016-07-15 20:27:4111695 SpdySerializedFrame req2(
bncb26024382016-06-29 02:39:4511696 spdy_util_.ConstructSpdyGet("https://www.example.org/", 3, LOWEST));
[email protected]2d6728692011-03-12 01:39:5511697 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:4111698 CreateMockWrite(req1, 0), CreateMockWrite(req2, 1),
[email protected]2d6728692011-03-12 01:39:5511699 };
bnc42331402016-07-25 13:36:1511700 SpdySerializedFrame resp1(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
bncdf80d44fd2016-07-15 20:27:4111701 SpdySerializedFrame data1(spdy_util_.ConstructSpdyDataFrame(1, true));
bnc42331402016-07-25 13:36:1511702 SpdySerializedFrame resp2(spdy_util_.ConstructSpdyGetReply(NULL, 0, 3));
bncdf80d44fd2016-07-15 20:27:4111703 SpdySerializedFrame data2(spdy_util_.ConstructSpdyDataFrame(3, true));
[email protected]2d6728692011-03-12 01:39:5511704 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:4111705 CreateMockRead(resp1, 2), CreateMockRead(data1, 3),
11706 CreateMockRead(resp2, 4), CreateMockRead(data2, 5),
rch8e6c6c42015-05-01 14:05:1311707 MockRead(ASYNC, 0, 6),
[email protected]2d6728692011-03-12 01:39:5511708 };
11709
rch8e6c6c42015-05-01 14:05:1311710 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
11711 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:0711712 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]2d6728692011-03-12 01:39:5511713
bnc032658ba2016-09-26 18:17:1511714 AddSSLSocketData();
bncb26024382016-06-29 02:39:4511715
mmenkecc2298e2015-12-07 18:20:1811716 StaticSocketDataProvider hanging_socket3(NULL, 0, NULL, 0);
11717 hanging_socket3.set_connect_data(never_finishing_connect);
11718 session_deps_.socket_factory->AddSocketDataProvider(&hanging_socket3);
[email protected]2d6728692011-03-12 01:39:5511719
danakj1fd259a02016-04-16 03:17:0911720 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]49639fa2011-12-20 23:22:4111721 TestCompletionCallback callback1;
[email protected]90499482013-06-01 00:39:5011722 HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
[email protected]2d6728692011-03-12 01:39:5511723
tfarina42834112016-09-22 13:38:2011724 int rv = trans1.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0111725 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
11726 EXPECT_THAT(callback1.WaitForResult(), IsOk());
[email protected]2d6728692011-03-12 01:39:5511727
11728 const HttpResponseInfo* response = trans1.GetResponseInfo();
wezca1070932016-05-26 20:30:5211729 ASSERT_TRUE(response);
11730 ASSERT_TRUE(response->headers);
[email protected]2d6728692011-03-12 01:39:5511731 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
11732
11733 std::string response_data;
robpercival214763f2016-07-01 23:27:0111734 ASSERT_THAT(ReadTransaction(&trans1, &response_data), IsOk());
[email protected]2d6728692011-03-12 01:39:5511735 EXPECT_EQ("hello world", response_data);
11736
[email protected]49639fa2011-12-20 23:22:4111737 TestCompletionCallback callback2;
[email protected]90499482013-06-01 00:39:5011738 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:2011739 rv = trans2.Start(&request, callback2.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0111740 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2d6728692011-03-12 01:39:5511741
[email protected]49639fa2011-12-20 23:22:4111742 TestCompletionCallback callback3;
[email protected]90499482013-06-01 00:39:5011743 HttpNetworkTransaction trans3(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:2011744 rv = trans3.Start(&request, callback3.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0111745 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2d6728692011-03-12 01:39:5511746
robpercival214763f2016-07-01 23:27:0111747 EXPECT_THAT(callback2.WaitForResult(), IsOk());
11748 EXPECT_THAT(callback3.WaitForResult(), IsOk());
[email protected]2d6728692011-03-12 01:39:5511749
11750 response = trans2.GetResponseInfo();
wezca1070932016-05-26 20:30:5211751 ASSERT_TRUE(response);
11752 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0211753 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]2d6728692011-03-12 01:39:5511754 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5211755 EXPECT_TRUE(response->was_alpn_negotiated);
robpercival214763f2016-07-01 23:27:0111756 ASSERT_THAT(ReadTransaction(&trans2, &response_data), IsOk());
[email protected]2d6728692011-03-12 01:39:5511757 EXPECT_EQ("hello!", response_data);
11758
11759 response = trans3.GetResponseInfo();
wezca1070932016-05-26 20:30:5211760 ASSERT_TRUE(response);
11761 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0211762 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]2d6728692011-03-12 01:39:5511763 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5211764 EXPECT_TRUE(response->was_alpn_negotiated);
robpercival214763f2016-07-01 23:27:0111765 ASSERT_THAT(ReadTransaction(&trans3, &response_data), IsOk());
[email protected]2d6728692011-03-12 01:39:5511766 EXPECT_EQ("hello!", response_data);
[email protected]2d6728692011-03-12 01:39:5511767}
11768
bncd16676a2016-07-20 16:23:0111769TEST_F(HttpNetworkTransactionTest, StallAlternativeServiceForNpnSpdy) {
[email protected]2d6728692011-03-12 01:39:5511770 HttpRequestInfo request;
11771 request.method = "GET";
bncb26024382016-06-29 02:39:4511772 request.url = GURL("https://www.example.org/");
[email protected]2d6728692011-03-12 01:39:5511773
11774 MockRead data_reads[] = {
bncc958faa2015-07-31 18:14:5211775 MockRead("HTTP/1.1 200 OK\r\n"),
bnc2df4b522016-07-08 18:17:4311776 MockRead(kAlternativeServiceHttpHeader),
bncc958faa2015-07-31 18:14:5211777 MockRead("\r\n"),
11778 MockRead("hello world"),
11779 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
11780 MockRead(ASYNC, OK),
[email protected]2d6728692011-03-12 01:39:5511781 };
11782
11783 StaticSocketDataProvider first_transaction(
11784 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0711785 session_deps_.socket_factory->AddSocketDataProvider(&first_transaction);
[email protected]2d6728692011-03-12 01:39:5511786
[email protected]8ddf8322012-02-23 18:08:0611787 SSLSocketDataProvider ssl(ASYNC, OK);
Ryan Sleevi4f832092017-11-21 23:25:4911788 ssl.ssl_info.cert =
11789 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem");
11790 ASSERT_TRUE(ssl.ssl_info.cert);
[email protected]bb88e1d32013-05-03 23:11:0711791 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]2d6728692011-03-12 01:39:5511792
[email protected]d973e99a2012-02-17 21:02:3611793 MockConnect never_finishing_connect(SYNCHRONOUS, ERR_IO_PENDING);
[email protected]2d6728692011-03-12 01:39:5511794 StaticSocketDataProvider hanging_alternate_protocol_socket(
11795 NULL, 0, NULL, 0);
11796 hanging_alternate_protocol_socket.set_connect_data(
11797 never_finishing_connect);
[email protected]bb88e1d32013-05-03 23:11:0711798 session_deps_.socket_factory->AddSocketDataProvider(
[email protected]2d6728692011-03-12 01:39:5511799 &hanging_alternate_protocol_socket);
11800
bncb26024382016-06-29 02:39:4511801 // 2nd request is just a copy of the first one, over HTTP/1.1 again.
mmenkecc2298e2015-12-07 18:20:1811802 StaticSocketDataProvider second_transaction(data_reads, arraysize(data_reads),
11803 NULL, 0);
11804 session_deps_.socket_factory->AddSocketDataProvider(&second_transaction);
bncb26024382016-06-29 02:39:4511805 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]2d6728692011-03-12 01:39:5511806
[email protected]49639fa2011-12-20 23:22:4111807 TestCompletionCallback callback;
[email protected]2d6728692011-03-12 01:39:5511808
danakj1fd259a02016-04-16 03:17:0911809 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc87dcefc2017-05-25 12:47:5811810 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:1911811 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]2d6728692011-03-12 01:39:5511812
tfarina42834112016-09-22 13:38:2011813 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0111814 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
11815 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]2d6728692011-03-12 01:39:5511816
11817 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5211818 ASSERT_TRUE(response);
11819 ASSERT_TRUE(response->headers);
[email protected]2d6728692011-03-12 01:39:5511820 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
11821
11822 std::string response_data;
robpercival214763f2016-07-01 23:27:0111823 ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
[email protected]2d6728692011-03-12 01:39:5511824 EXPECT_EQ("hello world", response_data);
11825
bnc87dcefc2017-05-25 12:47:5811826 trans =
Jeremy Roman0579ed62017-08-29 15:56:1911827 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]2d6728692011-03-12 01:39:5511828
tfarina42834112016-09-22 13:38:2011829 rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0111830 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
11831 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]2d6728692011-03-12 01:39:5511832
11833 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5211834 ASSERT_TRUE(response);
11835 ASSERT_TRUE(response->headers);
[email protected]2d6728692011-03-12 01:39:5511836 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
11837 EXPECT_FALSE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5211838 EXPECT_FALSE(response->was_alpn_negotiated);
[email protected]2d6728692011-03-12 01:39:5511839
robpercival214763f2016-07-01 23:27:0111840 ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
[email protected]2d6728692011-03-12 01:39:5511841 EXPECT_EQ("hello world", response_data);
[email protected]2d6728692011-03-12 01:39:5511842}
11843
[email protected]631f1322010-04-30 17:59:1111844class CapturingProxyResolver : public ProxyResolver {
11845 public:
Chris Watkins7a41d3552017-12-01 02:13:2711846 CapturingProxyResolver() = default;
11847 ~CapturingProxyResolver() override = default;
[email protected]631f1322010-04-30 17:59:1111848
dchengb03027d2014-10-21 12:00:2011849 int GetProxyForURL(const GURL& url,
11850 ProxyInfo* results,
11851 const CompletionCallback& callback,
maksim.sisov7e157262016-10-20 11:19:5511852 std::unique_ptr<Request>* request,
tfarina42834112016-09-22 13:38:2011853 const NetLogWithSource& net_log) override {
[email protected]fae7669f2010-08-02 21:49:4011854 ProxyServer proxy_server(ProxyServer::SCHEME_HTTP,
11855 HostPortPair("myproxy", 80));
[email protected]d911f1b2010-05-05 22:39:4211856 results->UseProxyServer(proxy_server);
[email protected]631f1322010-04-30 17:59:1111857 resolved_.push_back(url);
[email protected]d911f1b2010-05-05 22:39:4211858 return OK;
[email protected]631f1322010-04-30 17:59:1111859 }
11860
[email protected]24476402010-07-20 20:55:1711861 const std::vector<GURL>& resolved() const { return resolved_; }
11862
11863 private:
[email protected]631f1322010-04-30 17:59:1111864 std::vector<GURL> resolved_;
11865
11866 DISALLOW_COPY_AND_ASSIGN(CapturingProxyResolver);
11867};
11868
sammce64b2362015-04-29 03:50:2311869class CapturingProxyResolverFactory : public ProxyResolverFactory {
11870 public:
11871 explicit CapturingProxyResolverFactory(CapturingProxyResolver* resolver)
11872 : ProxyResolverFactory(false), resolver_(resolver) {}
11873
11874 int CreateProxyResolver(
11875 const scoped_refptr<ProxyResolverScriptData>& pac_script,
danakj1fd259a02016-04-16 03:17:0911876 std::unique_ptr<ProxyResolver>* resolver,
sammce64b2362015-04-29 03:50:2311877 const net::CompletionCallback& callback,
danakj1fd259a02016-04-16 03:17:0911878 std::unique_ptr<Request>* request) override {
Jeremy Roman0579ed62017-08-29 15:56:1911879 *resolver = std::make_unique<ForwardingProxyResolver>(resolver_);
sammce64b2362015-04-29 03:50:2311880 return OK;
11881 }
11882
11883 private:
11884 ProxyResolver* resolver_;
11885};
11886
bnc2e884782016-08-11 19:45:1911887// Test that proxy is resolved using the origin url,
11888// regardless of the alternative server.
11889TEST_F(HttpNetworkTransactionTest, UseOriginNotAlternativeForProxy) {
11890 // Configure proxy to bypass www.example.org, which is the origin URL.
11891 ProxyConfig proxy_config;
11892 proxy_config.proxy_rules().ParseFromString("myproxy:70");
11893 proxy_config.proxy_rules().bypass_rules.AddRuleFromString("www.example.org");
11894 auto proxy_config_service =
Jeremy Roman0579ed62017-08-29 15:56:1911895 std::make_unique<ProxyConfigServiceFixed>(proxy_config);
bnc2e884782016-08-11 19:45:1911896
11897 CapturingProxyResolver capturing_proxy_resolver;
Jeremy Roman0579ed62017-08-29 15:56:1911898 auto proxy_resolver_factory = std::make_unique<CapturingProxyResolverFactory>(
bnc2e884782016-08-11 19:45:1911899 &capturing_proxy_resolver);
11900
11901 TestNetLog net_log;
11902
Lily Houghton8c2f97d2018-01-22 05:06:5911903 session_deps_.proxy_resolution_service = std::make_unique<ProxyResolutionService>(
bnc2e884782016-08-11 19:45:1911904 std::move(proxy_config_service), std::move(proxy_resolver_factory),
11905 &net_log);
11906
11907 session_deps_.net_log = &net_log;
11908
11909 // Configure alternative service with a hostname that is not bypassed by the
11910 // proxy.
11911 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
11912 HttpServerProperties* http_server_properties =
11913 session->http_server_properties();
11914 url::SchemeHostPort server("https", "www.example.org", 443);
11915 HostPortPair alternative("www.example.com", 443);
bnc3472afd2016-11-17 15:27:2111916 AlternativeService alternative_service(kProtoHTTP2, alternative);
bnc2e884782016-08-11 19:45:1911917 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:2111918 http_server_properties->SetHttp2AlternativeService(
11919 server, alternative_service, expiration);
bnc2e884782016-08-11 19:45:1911920
11921 // Non-alternative job should hang.
11922 MockConnect never_finishing_connect(SYNCHRONOUS, ERR_IO_PENDING);
11923 StaticSocketDataProvider hanging_alternate_protocol_socket(nullptr, 0,
11924 nullptr, 0);
11925 hanging_alternate_protocol_socket.set_connect_data(never_finishing_connect);
11926 session_deps_.socket_factory->AddSocketDataProvider(
11927 &hanging_alternate_protocol_socket);
11928
bnc032658ba2016-09-26 18:17:1511929 AddSSLSocketData();
bnc2e884782016-08-11 19:45:1911930
11931 HttpRequestInfo request;
11932 request.method = "GET";
11933 request.url = GURL("https://www.example.org/");
11934 request.load_flags = 0;
11935
11936 SpdySerializedFrame req(
11937 spdy_util_.ConstructSpdyGet("https://www.example.org/", 1, LOWEST));
11938
11939 MockWrite spdy_writes[] = {CreateMockWrite(req, 0)};
11940
11941 SpdySerializedFrame resp(spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
11942 SpdySerializedFrame data(spdy_util_.ConstructSpdyDataFrame(1, true));
11943 MockRead spdy_reads[] = {
11944 CreateMockRead(resp, 1), CreateMockRead(data, 2), MockRead(ASYNC, 0, 3),
11945 };
11946
11947 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
11948 arraysize(spdy_writes));
11949 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
11950
11951 TestCompletionCallback callback;
11952
11953 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
11954
tfarina42834112016-09-22 13:38:2011955 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
bnc2e884782016-08-11 19:45:1911956 EXPECT_THAT(callback.GetResult(rv), IsOk());
11957
11958 const HttpResponseInfo* response = trans.GetResponseInfo();
11959 ASSERT_TRUE(response);
11960 ASSERT_TRUE(response->headers);
11961 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
11962 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5211963 EXPECT_TRUE(response->was_alpn_negotiated);
bnc2e884782016-08-11 19:45:1911964
11965 std::string response_data;
11966 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
11967 EXPECT_EQ("hello!", response_data);
11968
11969 // Origin host bypasses proxy, no resolution should have happened.
11970 ASSERT_TRUE(capturing_proxy_resolver.resolved().empty());
11971}
11972
bncd16676a2016-07-20 16:23:0111973TEST_F(HttpNetworkTransactionTest, UseAlternativeServiceForTunneledNpnSpdy) {
[email protected]631f1322010-04-30 17:59:1111974 ProxyConfig proxy_config;
[email protected]d911f1b2010-05-05 22:39:4211975 proxy_config.set_auto_detect(true);
11976 proxy_config.set_pac_url(GURL("http://fooproxyurl"));
[email protected]2227c692010-05-04 15:36:1111977
sammc5dd160c2015-04-02 02:43:1311978 CapturingProxyResolver capturing_proxy_resolver;
Lily Houghton8c2f97d2018-01-22 05:06:5911979 session_deps_.proxy_resolution_service = std::make_unique<ProxyResolutionService>(
Jeremy Roman0579ed62017-08-29 15:56:1911980 std::make_unique<ProxyConfigServiceFixed>(proxy_config),
11981 std::make_unique<CapturingProxyResolverFactory>(
bnc87dcefc2017-05-25 12:47:5811982 &capturing_proxy_resolver),
11983 nullptr);
vishal.b62985ca92015-04-17 08:45:5111984 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:0711985 session_deps_.net_log = &net_log;
[email protected]631f1322010-04-30 17:59:1111986
11987 HttpRequestInfo request;
11988 request.method = "GET";
bncb26024382016-06-29 02:39:4511989 request.url = GURL("https://www.example.org/");
[email protected]631f1322010-04-30 17:59:1111990
11991 MockRead data_reads[] = {
bncc958faa2015-07-31 18:14:5211992 MockRead("HTTP/1.1 200 OK\r\n"),
bnc2df4b522016-07-08 18:17:4311993 MockRead(kAlternativeServiceHttpHeader),
bncc958faa2015-07-31 18:14:5211994 MockRead("\r\n"),
11995 MockRead("hello world"),
11996 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
11997 MockRead(ASYNC, OK),
[email protected]631f1322010-04-30 17:59:1111998 };
11999
12000 StaticSocketDataProvider first_transaction(
12001 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0712002 session_deps_.socket_factory->AddSocketDataProvider(&first_transaction);
bncb26024382016-06-29 02:39:4512003 SSLSocketDataProvider ssl_http11(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3612004 ssl_http11.next_proto = kProtoHTTP11;
bncb26024382016-06-29 02:39:4512005 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_http11);
[email protected]631f1322010-04-30 17:59:1112006
bnc032658ba2016-09-26 18:17:1512007 AddSSLSocketData();
[email protected]631f1322010-04-30 17:59:1112008
bncdf80d44fd2016-07-15 20:27:4112009 SpdySerializedFrame req(
bncb26024382016-06-29 02:39:4512010 spdy_util_.ConstructSpdyGet("https://www.example.org/", 1, LOWEST));
[email protected]631f1322010-04-30 17:59:1112011 MockWrite spdy_writes[] = {
rch8e6c6c42015-05-01 14:05:1312012 MockWrite(ASYNC, 0,
bnc8bef8da22016-05-30 01:28:2512013 "CONNECT www.example.org:443 HTTP/1.1\r\n"
12014 "Host: www.example.org:443\r\n"
rch8e6c6c42015-05-01 14:05:1312015 "Proxy-Connection: keep-alive\r\n\r\n"),
bncdf80d44fd2016-07-15 20:27:4112016 CreateMockWrite(req, 2),
[email protected]631f1322010-04-30 17:59:1112017 };
12018
[email protected]d911f1b2010-05-05 22:39:4212019 const char kCONNECTResponse[] = "HTTP/1.1 200 Connected\r\n\r\n";
12020
bnc42331402016-07-25 13:36:1512021 SpdySerializedFrame resp(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
bncdf80d44fd2016-07-15 20:27:4112022 SpdySerializedFrame data(spdy_util_.ConstructSpdyDataFrame(1, true));
[email protected]631f1322010-04-30 17:59:1112023 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:4112024 MockRead(ASYNC, 1, kCONNECTResponse), CreateMockRead(resp, 3),
12025 CreateMockRead(data, 4), MockRead(SYNCHRONOUS, ERR_IO_PENDING, 5),
[email protected]631f1322010-04-30 17:59:1112026 };
12027
rch8e6c6c42015-05-01 14:05:1312028 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
12029 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:0712030 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]631f1322010-04-30 17:59:1112031
[email protected]d973e99a2012-02-17 21:02:3612032 MockConnect never_finishing_connect(SYNCHRONOUS, ERR_IO_PENDING);
[email protected]2d6728692011-03-12 01:39:5512033 StaticSocketDataProvider hanging_non_alternate_protocol_socket(
12034 NULL, 0, NULL, 0);
12035 hanging_non_alternate_protocol_socket.set_connect_data(
12036 never_finishing_connect);
[email protected]bb88e1d32013-05-03 23:11:0712037 session_deps_.socket_factory->AddSocketDataProvider(
[email protected]2d6728692011-03-12 01:39:5512038 &hanging_non_alternate_protocol_socket);
12039
[email protected]49639fa2011-12-20 23:22:4112040 TestCompletionCallback callback;
[email protected]631f1322010-04-30 17:59:1112041
danakj1fd259a02016-04-16 03:17:0912042 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc87dcefc2017-05-25 12:47:5812043 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:1912044 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]631f1322010-04-30 17:59:1112045
tfarina42834112016-09-22 13:38:2012046 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
mmenkea2dcd3bf2016-08-16 21:49:4112047 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
12048 EXPECT_THAT(callback.WaitForResult(), IsOk());
12049
12050 const HttpResponseInfo* response = trans->GetResponseInfo();
12051 ASSERT_TRUE(response);
12052 ASSERT_TRUE(response->headers);
12053 EXPECT_EQ("HTTP/0.9 200 OK", response->headers->GetStatusLine());
12054 EXPECT_FALSE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5212055 EXPECT_TRUE(response->was_alpn_negotiated);
mmenkea2dcd3bf2016-08-16 21:49:4112056
12057 std::string response_data;
12058 ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
12059 EXPECT_EQ("hello world", response_data);
[email protected]631f1322010-04-30 17:59:1112060
bnc87dcefc2017-05-25 12:47:5812061 trans =
Jeremy Roman0579ed62017-08-29 15:56:1912062 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]631f1322010-04-30 17:59:1112063
tfarina42834112016-09-22 13:38:2012064 rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0112065 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
12066 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]631f1322010-04-30 17:59:1112067
mmenkea2dcd3bf2016-08-16 21:49:4112068 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5212069 ASSERT_TRUE(response);
12070 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0212071 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]65041fa2010-05-21 06:56:5312072 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5212073 EXPECT_TRUE(response->was_alpn_negotiated);
[email protected]631f1322010-04-30 17:59:1112074
robpercival214763f2016-07-01 23:27:0112075 ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
[email protected]631f1322010-04-30 17:59:1112076 EXPECT_EQ("hello!", response_data);
bncb26024382016-06-29 02:39:4512077 ASSERT_EQ(2u, capturing_proxy_resolver.resolved().size());
12078 EXPECT_EQ("https://www.example.org/",
sammc5dd160c2015-04-02 02:43:1312079 capturing_proxy_resolver.resolved()[0].spec());
bncce36dca22015-04-21 22:11:2312080 EXPECT_EQ("https://www.example.org/",
sammc5dd160c2015-04-02 02:43:1312081 capturing_proxy_resolver.resolved()[1].spec());
[email protected]631f1322010-04-30 17:59:1112082
[email protected]029c83b62013-01-24 05:28:2012083 LoadTimingInfo load_timing_info;
12084 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
12085 TestLoadTimingNotReusedWithPac(load_timing_info,
12086 CONNECT_TIMING_HAS_SSL_TIMES);
[email protected]631f1322010-04-30 17:59:1112087}
[email protected]631f1322010-04-30 17:59:1112088
bncd16676a2016-07-20 16:23:0112089TEST_F(HttpNetworkTransactionTest,
bnc1c196c6e2016-05-28 13:51:4812090 UseAlternativeServiceForNpnSpdyWithExistingSpdySession) {
[email protected]2ff8b312010-04-26 22:20:5412091 HttpRequestInfo request;
12092 request.method = "GET";
bncb26024382016-06-29 02:39:4512093 request.url = GURL("https://www.example.org/");
[email protected]2ff8b312010-04-26 22:20:5412094
12095 MockRead data_reads[] = {
bncc958faa2015-07-31 18:14:5212096 MockRead("HTTP/1.1 200 OK\r\n"),
bnc2df4b522016-07-08 18:17:4312097 MockRead(kAlternativeServiceHttpHeader),
bncc958faa2015-07-31 18:14:5212098 MockRead("\r\n"),
12099 MockRead("hello world"),
12100 MockRead(ASYNC, OK),
[email protected]2ff8b312010-04-26 22:20:5412101 };
12102
12103 StaticSocketDataProvider first_transaction(
12104 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0712105 session_deps_.socket_factory->AddSocketDataProvider(&first_transaction);
bncb26024382016-06-29 02:39:4512106 SSLSocketDataProvider ssl_http11(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3612107 ssl_http11.next_proto = kProtoHTTP11;
bncb26024382016-06-29 02:39:4512108 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_http11);
[email protected]2ff8b312010-04-26 22:20:5412109
bnc032658ba2016-09-26 18:17:1512110 AddSSLSocketData();
[email protected]2ff8b312010-04-26 22:20:5412111
bncdf80d44fd2016-07-15 20:27:4112112 SpdySerializedFrame req(
bncb26024382016-06-29 02:39:4512113 spdy_util_.ConstructSpdyGet("https://www.example.org/", 1, LOWEST));
bncdf80d44fd2016-07-15 20:27:4112114 MockWrite spdy_writes[] = {CreateMockWrite(req, 0)};
[email protected]2ff8b312010-04-26 22:20:5412115
bnc42331402016-07-25 13:36:1512116 SpdySerializedFrame resp(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
bncdf80d44fd2016-07-15 20:27:4112117 SpdySerializedFrame data(spdy_util_.ConstructSpdyDataFrame(1, true));
[email protected]2ff8b312010-04-26 22:20:5412118 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:4112119 CreateMockRead(resp, 1), CreateMockRead(data, 2), MockRead(ASYNC, 0, 3),
[email protected]2ff8b312010-04-26 22:20:5412120 };
12121
rch8e6c6c42015-05-01 14:05:1312122 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
12123 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:0712124 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]2ff8b312010-04-26 22:20:5412125
[email protected]83039bb2011-12-09 18:43:5512126 TestCompletionCallback callback;
[email protected]2ff8b312010-04-26 22:20:5412127
danakj1fd259a02016-04-16 03:17:0912128 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]2ff8b312010-04-26 22:20:5412129
bnc87dcefc2017-05-25 12:47:5812130 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:1912131 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]2ff8b312010-04-26 22:20:5412132
tfarina42834112016-09-22 13:38:2012133 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0112134 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
12135 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]2ff8b312010-04-26 22:20:5412136
12137 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5212138 ASSERT_TRUE(response);
12139 ASSERT_TRUE(response->headers);
[email protected]2ff8b312010-04-26 22:20:5412140 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
12141
12142 std::string response_data;
robpercival214763f2016-07-01 23:27:0112143 ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
[email protected]2ff8b312010-04-26 22:20:5412144 EXPECT_EQ("hello world", response_data);
12145
12146 // Set up an initial SpdySession in the pool to reuse.
bnc8bef8da22016-05-30 01:28:2512147 HostPortPair host_port_pair("www.example.org", 443);
[email protected]e6d017652013-05-17 18:01:4012148 SpdySessionKey key(host_port_pair, ProxyServer::Direct(),
Paul Jensena457017a2018-01-19 23:52:0412149 PRIVACY_MODE_DISABLED, SocketTag());
[email protected]795cbf82013-07-22 09:37:2712150 base::WeakPtr<SpdySession> spdy_session =
Bence Béky0ef1556e2017-06-30 19:52:5212151 CreateSpdySession(session.get(), key, NetLogWithSource());
[email protected]02b0c342010-09-25 21:09:3812152
bnc87dcefc2017-05-25 12:47:5812153 trans =
Jeremy Roman0579ed62017-08-29 15:56:1912154 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]2ff8b312010-04-26 22:20:5412155
tfarina42834112016-09-22 13:38:2012156 rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0112157 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
12158 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]2ff8b312010-04-26 22:20:5412159
12160 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5212161 ASSERT_TRUE(response);
12162 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0212163 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]65041fa2010-05-21 06:56:5312164 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5212165 EXPECT_TRUE(response->was_alpn_negotiated);
[email protected]2ff8b312010-04-26 22:20:5412166
robpercival214763f2016-07-01 23:27:0112167 ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
[email protected]2ff8b312010-04-26 22:20:5412168 EXPECT_EQ("hello!", response_data);
[email protected]564b4912010-03-09 16:30:4212169}
12170
[email protected]044de0642010-06-17 10:42:1512171// GenerateAuthToken is a mighty big test.
12172// It tests all permutation of GenerateAuthToken behavior:
12173// - Synchronous and Asynchronous completion.
12174// - OK or error on completion.
12175// - Direct connection, non-authenticating proxy, and authenticating proxy.
12176// - HTTP or HTTPS backend (to include proxy tunneling).
12177// - Non-authenticating and authenticating backend.
12178//
[email protected]fe3b7dc2012-02-03 19:52:0912179// In all, there are 44 reasonable permuations (for example, if there are
[email protected]044de0642010-06-17 10:42:1512180// problems generating an auth token for an authenticating proxy, we don't
12181// need to test all permutations of the backend server).
12182//
12183// The test proceeds by going over each of the configuration cases, and
12184// potentially running up to three rounds in each of the tests. The TestConfig
12185// specifies both the configuration for the test as well as the expectations
12186// for the results.
bncd16676a2016-07-20 16:23:0112187TEST_F(HttpNetworkTransactionTest, GenerateAuthToken) {
[email protected]0b0bf032010-09-21 18:08:5012188 static const char kServer[] = "http://www.example.com";
12189 static const char kSecureServer[] = "https://www.example.com";
12190 static const char kProxy[] = "myproxy:70";
[email protected]044de0642010-06-17 10:42:1512191
12192 enum AuthTiming {
12193 AUTH_NONE,
12194 AUTH_SYNC,
12195 AUTH_ASYNC,
12196 };
12197
12198 const MockWrite kGet(
12199 "GET / HTTP/1.1\r\n"
12200 "Host: www.example.com\r\n"
12201 "Connection: keep-alive\r\n\r\n");
12202 const MockWrite kGetProxy(
12203 "GET http://www.example.com/ HTTP/1.1\r\n"
12204 "Host: www.example.com\r\n"
12205 "Proxy-Connection: keep-alive\r\n\r\n");
12206 const MockWrite kGetAuth(
12207 "GET / HTTP/1.1\r\n"
12208 "Host: www.example.com\r\n"
12209 "Connection: keep-alive\r\n"
12210 "Authorization: auth_token\r\n\r\n");
12211 const MockWrite kGetProxyAuth(
12212 "GET http://www.example.com/ HTTP/1.1\r\n"
12213 "Host: www.example.com\r\n"
12214 "Proxy-Connection: keep-alive\r\n"
12215 "Proxy-Authorization: auth_token\r\n\r\n");
12216 const MockWrite kGetAuthThroughProxy(
12217 "GET http://www.example.com/ HTTP/1.1\r\n"
12218 "Host: www.example.com\r\n"
12219 "Proxy-Connection: keep-alive\r\n"
12220 "Authorization: auth_token\r\n\r\n");
12221 const MockWrite kGetAuthWithProxyAuth(
12222 "GET http://www.example.com/ HTTP/1.1\r\n"
12223 "Host: www.example.com\r\n"
12224 "Proxy-Connection: keep-alive\r\n"
12225 "Proxy-Authorization: auth_token\r\n"
12226 "Authorization: auth_token\r\n\r\n");
12227 const MockWrite kConnect(
12228 "CONNECT www.example.com:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:1712229 "Host: www.example.com:443\r\n"
[email protected]044de0642010-06-17 10:42:1512230 "Proxy-Connection: keep-alive\r\n\r\n");
12231 const MockWrite kConnectProxyAuth(
12232 "CONNECT www.example.com:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:1712233 "Host: www.example.com:443\r\n"
[email protected]044de0642010-06-17 10:42:1512234 "Proxy-Connection: keep-alive\r\n"
12235 "Proxy-Authorization: auth_token\r\n\r\n");
12236
12237 const MockRead kSuccess(
12238 "HTTP/1.1 200 OK\r\n"
12239 "Content-Type: text/html; charset=iso-8859-1\r\n"
12240 "Content-Length: 3\r\n\r\n"
12241 "Yes");
12242 const MockRead kFailure(
12243 "Should not be called.");
12244 const MockRead kServerChallenge(
12245 "HTTP/1.1 401 Unauthorized\r\n"
12246 "WWW-Authenticate: Mock realm=server\r\n"
12247 "Content-Type: text/html; charset=iso-8859-1\r\n"
12248 "Content-Length: 14\r\n\r\n"
12249 "Unauthorized\r\n");
12250 const MockRead kProxyChallenge(
12251 "HTTP/1.1 407 Unauthorized\r\n"
12252 "Proxy-Authenticate: Mock realm=proxy\r\n"
12253 "Proxy-Connection: close\r\n"
12254 "Content-Type: text/html; charset=iso-8859-1\r\n"
12255 "Content-Length: 14\r\n\r\n"
12256 "Unauthorized\r\n");
12257 const MockRead kProxyConnected(
12258 "HTTP/1.1 200 Connection Established\r\n\r\n");
12259
12260 // NOTE(cbentzel): I wanted TestReadWriteRound to be a simple struct with
12261 // no constructors, but the C++ compiler on Windows warns about
12262 // unspecified data in compound literals. So, moved to using constructors,
12263 // and TestRound's created with the default constructor should not be used.
12264 struct TestRound {
12265 TestRound()
12266 : expected_rv(ERR_UNEXPECTED),
12267 extra_write(NULL),
12268 extra_read(NULL) {
12269 }
12270 TestRound(const MockWrite& write_arg, const MockRead& read_arg,
12271 int expected_rv_arg)
12272 : write(write_arg),
12273 read(read_arg),
12274 expected_rv(expected_rv_arg),
12275 extra_write(NULL),
12276 extra_read(NULL) {
12277 }
12278 TestRound(const MockWrite& write_arg, const MockRead& read_arg,
12279 int expected_rv_arg, const MockWrite* extra_write_arg,
[email protected]f871ee152012-07-27 19:02:0112280 const MockRead* extra_read_arg)
[email protected]044de0642010-06-17 10:42:1512281 : write(write_arg),
12282 read(read_arg),
12283 expected_rv(expected_rv_arg),
12284 extra_write(extra_write_arg),
12285 extra_read(extra_read_arg) {
12286 }
12287 MockWrite write;
12288 MockRead read;
12289 int expected_rv;
12290 const MockWrite* extra_write;
12291 const MockRead* extra_read;
12292 };
12293
12294 static const int kNoSSL = 500;
12295
12296 struct TestConfig {
asanka463ca4262016-11-16 02:34:3112297 int line_number;
thestig9d3bb0c2015-01-24 00:49:5112298 const char* const proxy_url;
[email protected]044de0642010-06-17 10:42:1512299 AuthTiming proxy_auth_timing;
asanka463ca4262016-11-16 02:34:3112300 int first_generate_proxy_token_rv;
thestig9d3bb0c2015-01-24 00:49:5112301 const char* const server_url;
[email protected]044de0642010-06-17 10:42:1512302 AuthTiming server_auth_timing;
asanka463ca4262016-11-16 02:34:3112303 int first_generate_server_token_rv;
[email protected]044de0642010-06-17 10:42:1512304 int num_auth_rounds;
12305 int first_ssl_round;
asankae2257db2016-10-11 22:03:1612306 TestRound rounds[4];
[email protected]044de0642010-06-17 10:42:1512307 } test_configs[] = {
asankac93076192016-10-03 15:46:0212308 // Non-authenticating HTTP server with a direct connection.
asanka463ca4262016-11-16 02:34:3112309 {__LINE__,
12310 nullptr,
asankac93076192016-10-03 15:46:0212311 AUTH_NONE,
12312 OK,
12313 kServer,
12314 AUTH_NONE,
12315 OK,
12316 1,
12317 kNoSSL,
12318 {TestRound(kGet, kSuccess, OK)}},
12319 // Authenticating HTTP server with a direct connection.
asanka463ca4262016-11-16 02:34:3112320 {__LINE__,
12321 nullptr,
asankac93076192016-10-03 15:46:0212322 AUTH_NONE,
12323 OK,
12324 kServer,
12325 AUTH_SYNC,
12326 OK,
12327 2,
12328 kNoSSL,
12329 {TestRound(kGet, kServerChallenge, OK),
[email protected]044de0642010-06-17 10:42:1512330 TestRound(kGetAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112331 {__LINE__,
12332 nullptr,
asankac93076192016-10-03 15:46:0212333 AUTH_NONE,
12334 OK,
12335 kServer,
12336 AUTH_SYNC,
12337 ERR_INVALID_AUTH_CREDENTIALS,
asankae2257db2016-10-11 22:03:1612338 3,
12339 kNoSSL,
12340 {TestRound(kGet, kServerChallenge, OK),
12341 TestRound(kGet, kServerChallenge, OK),
12342 TestRound(kGetAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112343 {__LINE__,
12344 nullptr,
asankae2257db2016-10-11 22:03:1612345 AUTH_NONE,
12346 OK,
12347 kServer,
12348 AUTH_SYNC,
12349 ERR_UNSUPPORTED_AUTH_SCHEME,
12350 2,
12351 kNoSSL,
12352 {TestRound(kGet, kServerChallenge, OK), TestRound(kGet, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112353 {__LINE__,
12354 nullptr,
asankae2257db2016-10-11 22:03:1612355 AUTH_NONE,
12356 OK,
12357 kServer,
12358 AUTH_SYNC,
12359 ERR_UNDOCUMENTED_SECURITY_LIBRARY_STATUS,
12360 2,
12361 kNoSSL,
12362 {TestRound(kGet, kServerChallenge, OK), TestRound(kGet, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112363 {__LINE__,
12364 kProxy,
asankae2257db2016-10-11 22:03:1612365 AUTH_SYNC,
12366 ERR_FAILED,
12367 kServer,
12368 AUTH_NONE,
12369 OK,
12370 2,
12371 kNoSSL,
12372 {TestRound(kGetProxy, kProxyChallenge, OK),
12373 TestRound(kGetProxy, kFailure, ERR_FAILED)}},
asanka463ca4262016-11-16 02:34:3112374 {__LINE__,
12375 kProxy,
asankae2257db2016-10-11 22:03:1612376 AUTH_ASYNC,
12377 ERR_FAILED,
12378 kServer,
12379 AUTH_NONE,
12380 OK,
12381 2,
12382 kNoSSL,
12383 {TestRound(kGetProxy, kProxyChallenge, OK),
12384 TestRound(kGetProxy, kFailure, ERR_FAILED)}},
asanka463ca4262016-11-16 02:34:3112385 {__LINE__,
12386 nullptr,
asankae2257db2016-10-11 22:03:1612387 AUTH_NONE,
12388 OK,
12389 kServer,
12390 AUTH_SYNC,
12391 ERR_FAILED,
asankac93076192016-10-03 15:46:0212392 2,
12393 kNoSSL,
12394 {TestRound(kGet, kServerChallenge, OK),
asankae2257db2016-10-11 22:03:1612395 TestRound(kGet, kFailure, ERR_FAILED)}},
asanka463ca4262016-11-16 02:34:3112396 {__LINE__,
12397 nullptr,
asankae2257db2016-10-11 22:03:1612398 AUTH_NONE,
12399 OK,
12400 kServer,
12401 AUTH_ASYNC,
12402 ERR_FAILED,
12403 2,
12404 kNoSSL,
12405 {TestRound(kGet, kServerChallenge, OK),
12406 TestRound(kGet, kFailure, ERR_FAILED)}},
asanka463ca4262016-11-16 02:34:3112407 {__LINE__,
12408 nullptr,
asankac93076192016-10-03 15:46:0212409 AUTH_NONE,
12410 OK,
12411 kServer,
12412 AUTH_ASYNC,
12413 OK,
12414 2,
12415 kNoSSL,
12416 {TestRound(kGet, kServerChallenge, OK),
[email protected]044de0642010-06-17 10:42:1512417 TestRound(kGetAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112418 {__LINE__,
12419 nullptr,
asankac93076192016-10-03 15:46:0212420 AUTH_NONE,
12421 OK,
12422 kServer,
12423 AUTH_ASYNC,
12424 ERR_INVALID_AUTH_CREDENTIALS,
asankae2257db2016-10-11 22:03:1612425 3,
asankac93076192016-10-03 15:46:0212426 kNoSSL,
12427 {TestRound(kGet, kServerChallenge, OK),
asankae2257db2016-10-11 22:03:1612428 // The second round uses a HttpAuthHandlerMock that always succeeds.
12429 TestRound(kGet, kServerChallenge, OK),
12430 TestRound(kGetAuth, kSuccess, OK)}},
asankac93076192016-10-03 15:46:0212431 // Non-authenticating HTTP server through a non-authenticating proxy.
asanka463ca4262016-11-16 02:34:3112432 {__LINE__,
12433 kProxy,
asankac93076192016-10-03 15:46:0212434 AUTH_NONE,
12435 OK,
12436 kServer,
12437 AUTH_NONE,
12438 OK,
12439 1,
12440 kNoSSL,
12441 {TestRound(kGetProxy, kSuccess, OK)}},
12442 // Authenticating HTTP server through a non-authenticating proxy.
asanka463ca4262016-11-16 02:34:3112443 {__LINE__,
12444 kProxy,
asankac93076192016-10-03 15:46:0212445 AUTH_NONE,
12446 OK,
12447 kServer,
12448 AUTH_SYNC,
12449 OK,
12450 2,
12451 kNoSSL,
12452 {TestRound(kGetProxy, kServerChallenge, OK),
[email protected]044de0642010-06-17 10:42:1512453 TestRound(kGetAuthThroughProxy, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112454 {__LINE__,
12455 kProxy,
asankac93076192016-10-03 15:46:0212456 AUTH_NONE,
12457 OK,
12458 kServer,
12459 AUTH_SYNC,
12460 ERR_INVALID_AUTH_CREDENTIALS,
asankae2257db2016-10-11 22:03:1612461 3,
asankac93076192016-10-03 15:46:0212462 kNoSSL,
12463 {TestRound(kGetProxy, kServerChallenge, OK),
asankae2257db2016-10-11 22:03:1612464 TestRound(kGetProxy, kServerChallenge, OK),
12465 TestRound(kGetAuthThroughProxy, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112466 {__LINE__,
12467 kProxy,
asankac93076192016-10-03 15:46:0212468 AUTH_NONE,
12469 OK,
12470 kServer,
12471 AUTH_ASYNC,
12472 OK,
12473 2,
12474 kNoSSL,
12475 {TestRound(kGetProxy, kServerChallenge, OK),
[email protected]044de0642010-06-17 10:42:1512476 TestRound(kGetAuthThroughProxy, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112477 {__LINE__,
12478 kProxy,
asankac93076192016-10-03 15:46:0212479 AUTH_NONE,
12480 OK,
12481 kServer,
12482 AUTH_ASYNC,
12483 ERR_INVALID_AUTH_CREDENTIALS,
12484 2,
12485 kNoSSL,
12486 {TestRound(kGetProxy, kServerChallenge, OK),
asankae2257db2016-10-11 22:03:1612487 TestRound(kGetProxy, kSuccess, OK)}},
asankac93076192016-10-03 15:46:0212488 // Non-authenticating HTTP server through an authenticating proxy.
asanka463ca4262016-11-16 02:34:3112489 {__LINE__,
12490 kProxy,
asankac93076192016-10-03 15:46:0212491 AUTH_SYNC,
12492 OK,
12493 kServer,
12494 AUTH_NONE,
12495 OK,
12496 2,
12497 kNoSSL,
12498 {TestRound(kGetProxy, kProxyChallenge, OK),
[email protected]044de0642010-06-17 10:42:1512499 TestRound(kGetProxyAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112500 {__LINE__,
12501 kProxy,
asankac93076192016-10-03 15:46:0212502 AUTH_SYNC,
12503 ERR_INVALID_AUTH_CREDENTIALS,
12504 kServer,
12505 AUTH_NONE,
12506 OK,
12507 2,
12508 kNoSSL,
12509 {TestRound(kGetProxy, kProxyChallenge, OK),
asankae2257db2016-10-11 22:03:1612510 TestRound(kGetProxy, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112511 {__LINE__,
12512 kProxy,
asankac93076192016-10-03 15:46:0212513 AUTH_ASYNC,
12514 OK,
12515 kServer,
12516 AUTH_NONE,
12517 OK,
12518 2,
12519 kNoSSL,
12520 {TestRound(kGetProxy, kProxyChallenge, OK),
[email protected]044de0642010-06-17 10:42:1512521 TestRound(kGetProxyAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112522 {__LINE__,
12523 kProxy,
asankac93076192016-10-03 15:46:0212524 AUTH_ASYNC,
12525 ERR_INVALID_AUTH_CREDENTIALS,
12526 kServer,
12527 AUTH_NONE,
12528 OK,
12529 2,
12530 kNoSSL,
12531 {TestRound(kGetProxy, kProxyChallenge, OK),
asankae2257db2016-10-11 22:03:1612532 TestRound(kGetProxy, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112533 {__LINE__,
12534 kProxy,
12535 AUTH_ASYNC,
12536 ERR_INVALID_AUTH_CREDENTIALS,
12537 kServer,
12538 AUTH_NONE,
12539 OK,
12540 3,
12541 kNoSSL,
12542 {TestRound(kGetProxy, kProxyChallenge, OK),
12543 TestRound(kGetProxy, kProxyChallenge, OK),
12544 TestRound(kGetProxyAuth, kSuccess, OK)}},
asankac93076192016-10-03 15:46:0212545 // Authenticating HTTP server through an authenticating proxy.
asanka463ca4262016-11-16 02:34:3112546 {__LINE__,
12547 kProxy,
asankac93076192016-10-03 15:46:0212548 AUTH_SYNC,
12549 OK,
12550 kServer,
12551 AUTH_SYNC,
12552 OK,
12553 3,
12554 kNoSSL,
12555 {TestRound(kGetProxy, kProxyChallenge, OK),
[email protected]044de0642010-06-17 10:42:1512556 TestRound(kGetProxyAuth, kServerChallenge, OK),
12557 TestRound(kGetAuthWithProxyAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112558 {__LINE__,
12559 kProxy,
asankac93076192016-10-03 15:46:0212560 AUTH_SYNC,
12561 OK,
12562 kServer,
12563 AUTH_SYNC,
12564 ERR_INVALID_AUTH_CREDENTIALS,
12565 3,
12566 kNoSSL,
12567 {TestRound(kGetProxy, kProxyChallenge, OK),
[email protected]044de0642010-06-17 10:42:1512568 TestRound(kGetProxyAuth, kServerChallenge, OK),
asankae2257db2016-10-11 22:03:1612569 TestRound(kGetProxyAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112570 {__LINE__,
12571 kProxy,
asankac93076192016-10-03 15:46:0212572 AUTH_ASYNC,
12573 OK,
12574 kServer,
12575 AUTH_SYNC,
12576 OK,
12577 3,
12578 kNoSSL,
12579 {TestRound(kGetProxy, kProxyChallenge, OK),
[email protected]044de0642010-06-17 10:42:1512580 TestRound(kGetProxyAuth, kServerChallenge, OK),
12581 TestRound(kGetAuthWithProxyAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112582 {__LINE__,
12583 kProxy,
asankac93076192016-10-03 15:46:0212584 AUTH_ASYNC,
12585 OK,
12586 kServer,
12587 AUTH_SYNC,
12588 ERR_INVALID_AUTH_CREDENTIALS,
12589 3,
12590 kNoSSL,
12591 {TestRound(kGetProxy, kProxyChallenge, OK),
[email protected]044de0642010-06-17 10:42:1512592 TestRound(kGetProxyAuth, kServerChallenge, OK),
asankae2257db2016-10-11 22:03:1612593 TestRound(kGetProxyAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112594 {__LINE__,
12595 kProxy,
asankac93076192016-10-03 15:46:0212596 AUTH_SYNC,
12597 OK,
12598 kServer,
12599 AUTH_ASYNC,
12600 OK,
12601 3,
12602 kNoSSL,
12603 {TestRound(kGetProxy, kProxyChallenge, OK),
[email protected]044de0642010-06-17 10:42:1512604 TestRound(kGetProxyAuth, kServerChallenge, OK),
12605 TestRound(kGetAuthWithProxyAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112606 {__LINE__,
12607 kProxy,
12608 AUTH_SYNC,
12609 ERR_INVALID_AUTH_CREDENTIALS,
12610 kServer,
12611 AUTH_ASYNC,
12612 OK,
12613 4,
12614 kNoSSL,
12615 {TestRound(kGetProxy, kProxyChallenge, OK),
12616 TestRound(kGetProxy, kProxyChallenge, OK),
12617 TestRound(kGetProxyAuth, kServerChallenge, OK),
12618 TestRound(kGetAuthWithProxyAuth, kSuccess, OK)}},
12619 {__LINE__,
12620 kProxy,
asankac93076192016-10-03 15:46:0212621 AUTH_SYNC,
12622 OK,
12623 kServer,
12624 AUTH_ASYNC,
12625 ERR_INVALID_AUTH_CREDENTIALS,
12626 3,
12627 kNoSSL,
12628 {TestRound(kGetProxy, kProxyChallenge, OK),
[email protected]044de0642010-06-17 10:42:1512629 TestRound(kGetProxyAuth, kServerChallenge, OK),
asankae2257db2016-10-11 22:03:1612630 TestRound(kGetProxyAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112631 {__LINE__,
12632 kProxy,
asankac93076192016-10-03 15:46:0212633 AUTH_ASYNC,
12634 OK,
12635 kServer,
12636 AUTH_ASYNC,
12637 OK,
12638 3,
12639 kNoSSL,
12640 {TestRound(kGetProxy, kProxyChallenge, OK),
[email protected]044de0642010-06-17 10:42:1512641 TestRound(kGetProxyAuth, kServerChallenge, OK),
12642 TestRound(kGetAuthWithProxyAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112643 {__LINE__,
12644 kProxy,
asankac93076192016-10-03 15:46:0212645 AUTH_ASYNC,
12646 OK,
12647 kServer,
12648 AUTH_ASYNC,
12649 ERR_INVALID_AUTH_CREDENTIALS,
12650 3,
12651 kNoSSL,
12652 {TestRound(kGetProxy, kProxyChallenge, OK),
[email protected]044de0642010-06-17 10:42:1512653 TestRound(kGetProxyAuth, kServerChallenge, OK),
asankae2257db2016-10-11 22:03:1612654 TestRound(kGetProxyAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112655 {__LINE__,
12656 kProxy,
12657 AUTH_ASYNC,
12658 ERR_INVALID_AUTH_CREDENTIALS,
12659 kServer,
12660 AUTH_ASYNC,
12661 ERR_INVALID_AUTH_CREDENTIALS,
12662 4,
12663 kNoSSL,
12664 {TestRound(kGetProxy, kProxyChallenge, OK),
12665 TestRound(kGetProxy, kProxyChallenge, OK),
12666 TestRound(kGetProxyAuth, kServerChallenge, OK),
12667 TestRound(kGetProxyAuth, kSuccess, OK)}},
asankac93076192016-10-03 15:46:0212668 // Non-authenticating HTTPS server with a direct connection.
asanka463ca4262016-11-16 02:34:3112669 {__LINE__,
12670 nullptr,
asankac93076192016-10-03 15:46:0212671 AUTH_NONE,
12672 OK,
12673 kSecureServer,
12674 AUTH_NONE,
12675 OK,
12676 1,
12677 0,
12678 {TestRound(kGet, kSuccess, OK)}},
12679 // Authenticating HTTPS server with a direct connection.
asanka463ca4262016-11-16 02:34:3112680 {__LINE__,
12681 nullptr,
asankac93076192016-10-03 15:46:0212682 AUTH_NONE,
12683 OK,
12684 kSecureServer,
12685 AUTH_SYNC,
12686 OK,
12687 2,
12688 0,
12689 {TestRound(kGet, kServerChallenge, OK),
[email protected]044de0642010-06-17 10:42:1512690 TestRound(kGetAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112691 {__LINE__,
12692 nullptr,
asankac93076192016-10-03 15:46:0212693 AUTH_NONE,
12694 OK,
12695 kSecureServer,
12696 AUTH_SYNC,
12697 ERR_INVALID_AUTH_CREDENTIALS,
12698 2,
12699 0,
asankae2257db2016-10-11 22:03:1612700 {TestRound(kGet, kServerChallenge, OK), TestRound(kGet, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112701 {__LINE__,
12702 nullptr,
asankac93076192016-10-03 15:46:0212703 AUTH_NONE,
12704 OK,
12705 kSecureServer,
12706 AUTH_ASYNC,
12707 OK,
12708 2,
12709 0,
12710 {TestRound(kGet, kServerChallenge, OK),
[email protected]044de0642010-06-17 10:42:1512711 TestRound(kGetAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112712 {__LINE__,
12713 nullptr,
asankac93076192016-10-03 15:46:0212714 AUTH_NONE,
12715 OK,
12716 kSecureServer,
12717 AUTH_ASYNC,
12718 ERR_INVALID_AUTH_CREDENTIALS,
12719 2,
12720 0,
asankae2257db2016-10-11 22:03:1612721 {TestRound(kGet, kServerChallenge, OK), TestRound(kGet, kSuccess, OK)}},
asankac93076192016-10-03 15:46:0212722 // Non-authenticating HTTPS server with a non-authenticating proxy.
asanka463ca4262016-11-16 02:34:3112723 {__LINE__,
12724 kProxy,
asankac93076192016-10-03 15:46:0212725 AUTH_NONE,
12726 OK,
12727 kSecureServer,
12728 AUTH_NONE,
12729 OK,
12730 1,
12731 0,
12732 {TestRound(kConnect, kProxyConnected, OK, &kGet, &kSuccess)}},
12733 // Authenticating HTTPS server through a non-authenticating proxy.
asanka463ca4262016-11-16 02:34:3112734 {__LINE__,
12735 kProxy,
asankac93076192016-10-03 15:46:0212736 AUTH_NONE,
12737 OK,
12738 kSecureServer,
12739 AUTH_SYNC,
12740 OK,
12741 2,
12742 0,
12743 {TestRound(kConnect, kProxyConnected, OK, &kGet, &kServerChallenge),
[email protected]044de0642010-06-17 10:42:1512744 TestRound(kGetAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112745 {__LINE__,
12746 kProxy,
asankac93076192016-10-03 15:46:0212747 AUTH_NONE,
12748 OK,
12749 kSecureServer,
12750 AUTH_SYNC,
12751 ERR_INVALID_AUTH_CREDENTIALS,
12752 2,
12753 0,
12754 {TestRound(kConnect, kProxyConnected, OK, &kGet, &kServerChallenge),
asankae2257db2016-10-11 22:03:1612755 TestRound(kGet, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112756 {__LINE__,
12757 kProxy,
asankac93076192016-10-03 15:46:0212758 AUTH_NONE,
12759 OK,
12760 kSecureServer,
12761 AUTH_ASYNC,
12762 OK,
12763 2,
12764 0,
12765 {TestRound(kConnect, kProxyConnected, OK, &kGet, &kServerChallenge),
[email protected]044de0642010-06-17 10:42:1512766 TestRound(kGetAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112767 {__LINE__,
12768 kProxy,
asankac93076192016-10-03 15:46:0212769 AUTH_NONE,
12770 OK,
12771 kSecureServer,
12772 AUTH_ASYNC,
12773 ERR_INVALID_AUTH_CREDENTIALS,
12774 2,
12775 0,
12776 {TestRound(kConnect, kProxyConnected, OK, &kGet, &kServerChallenge),
asankae2257db2016-10-11 22:03:1612777 TestRound(kGet, kSuccess, OK)}},
asankac93076192016-10-03 15:46:0212778 // Non-Authenticating HTTPS server through an authenticating proxy.
asanka463ca4262016-11-16 02:34:3112779 {__LINE__,
12780 kProxy,
asankac93076192016-10-03 15:46:0212781 AUTH_SYNC,
12782 OK,
12783 kSecureServer,
12784 AUTH_NONE,
12785 OK,
12786 2,
12787 1,
12788 {TestRound(kConnect, kProxyChallenge, OK),
[email protected]044de0642010-06-17 10:42:1512789 TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet, &kSuccess)}},
asanka463ca4262016-11-16 02:34:3112790 {__LINE__,
12791 kProxy,
asankac93076192016-10-03 15:46:0212792 AUTH_SYNC,
12793 ERR_INVALID_AUTH_CREDENTIALS,
12794 kSecureServer,
12795 AUTH_NONE,
12796 OK,
12797 2,
12798 kNoSSL,
12799 {TestRound(kConnect, kProxyChallenge, OK),
asankae2257db2016-10-11 22:03:1612800 TestRound(kConnect, kProxyConnected, OK, &kGet, &kSuccess)}},
asanka463ca4262016-11-16 02:34:3112801 {__LINE__,
12802 kProxy,
asankae2257db2016-10-11 22:03:1612803 AUTH_SYNC,
12804 ERR_UNSUPPORTED_AUTH_SCHEME,
12805 kSecureServer,
12806 AUTH_NONE,
12807 OK,
12808 2,
12809 kNoSSL,
12810 {TestRound(kConnect, kProxyChallenge, OK),
12811 TestRound(kConnect, kProxyConnected, OK, &kGet, &kSuccess)}},
asanka463ca4262016-11-16 02:34:3112812 {__LINE__,
12813 kProxy,
asankae2257db2016-10-11 22:03:1612814 AUTH_SYNC,
12815 ERR_UNEXPECTED,
12816 kSecureServer,
12817 AUTH_NONE,
12818 OK,
12819 2,
12820 kNoSSL,
12821 {TestRound(kConnect, kProxyChallenge, OK),
12822 TestRound(kConnect, kProxyConnected, ERR_UNEXPECTED)}},
asanka463ca4262016-11-16 02:34:3112823 {__LINE__,
12824 kProxy,
asankac93076192016-10-03 15:46:0212825 AUTH_ASYNC,
12826 OK,
12827 kSecureServer,
12828 AUTH_NONE,
12829 OK,
12830 2,
12831 1,
12832 {TestRound(kConnect, kProxyChallenge, OK),
[email protected]044de0642010-06-17 10:42:1512833 TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet, &kSuccess)}},
asanka463ca4262016-11-16 02:34:3112834 {__LINE__,
12835 kProxy,
asankac93076192016-10-03 15:46:0212836 AUTH_ASYNC,
12837 ERR_INVALID_AUTH_CREDENTIALS,
12838 kSecureServer,
12839 AUTH_NONE,
12840 OK,
12841 2,
12842 kNoSSL,
12843 {TestRound(kConnect, kProxyChallenge, OK),
asankae2257db2016-10-11 22:03:1612844 TestRound(kConnect, kProxyConnected, OK, &kGet, &kSuccess)}},
asankac93076192016-10-03 15:46:0212845 // Authenticating HTTPS server through an authenticating proxy.
asanka463ca4262016-11-16 02:34:3112846 {__LINE__,
12847 kProxy,
asankac93076192016-10-03 15:46:0212848 AUTH_SYNC,
12849 OK,
12850 kSecureServer,
12851 AUTH_SYNC,
12852 OK,
12853 3,
12854 1,
12855 {TestRound(kConnect, kProxyChallenge, OK),
12856 TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet,
12857 &kServerChallenge),
[email protected]044de0642010-06-17 10:42:1512858 TestRound(kGetAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112859 {__LINE__,
12860 kProxy,
asankac93076192016-10-03 15:46:0212861 AUTH_SYNC,
12862 OK,
12863 kSecureServer,
12864 AUTH_SYNC,
12865 ERR_INVALID_AUTH_CREDENTIALS,
12866 3,
12867 1,
12868 {TestRound(kConnect, kProxyChallenge, OK),
12869 TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet,
12870 &kServerChallenge),
asankae2257db2016-10-11 22:03:1612871 TestRound(kGet, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112872 {__LINE__,
12873 kProxy,
asankac93076192016-10-03 15:46:0212874 AUTH_ASYNC,
12875 OK,
12876 kSecureServer,
12877 AUTH_SYNC,
12878 OK,
12879 3,
12880 1,
12881 {TestRound(kConnect, kProxyChallenge, OK),
12882 TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet,
12883 &kServerChallenge),
[email protected]044de0642010-06-17 10:42:1512884 TestRound(kGetAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112885 {__LINE__,
12886 kProxy,
asankac93076192016-10-03 15:46:0212887 AUTH_ASYNC,
12888 OK,
12889 kSecureServer,
12890 AUTH_SYNC,
12891 ERR_INVALID_AUTH_CREDENTIALS,
12892 3,
12893 1,
12894 {TestRound(kConnect, kProxyChallenge, OK),
12895 TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet,
12896 &kServerChallenge),
asankae2257db2016-10-11 22:03:1612897 TestRound(kGet, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112898 {__LINE__,
12899 kProxy,
asankac93076192016-10-03 15:46:0212900 AUTH_SYNC,
12901 OK,
12902 kSecureServer,
12903 AUTH_ASYNC,
12904 OK,
12905 3,
12906 1,
12907 {TestRound(kConnect, kProxyChallenge, OK),
12908 TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet,
12909 &kServerChallenge),
[email protected]044de0642010-06-17 10:42:1512910 TestRound(kGetAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112911 {__LINE__,
12912 kProxy,
asankac93076192016-10-03 15:46:0212913 AUTH_SYNC,
12914 OK,
12915 kSecureServer,
12916 AUTH_ASYNC,
12917 ERR_INVALID_AUTH_CREDENTIALS,
12918 3,
12919 1,
12920 {TestRound(kConnect, kProxyChallenge, OK),
12921 TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet,
12922 &kServerChallenge),
asankae2257db2016-10-11 22:03:1612923 TestRound(kGet, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112924 {__LINE__,
12925 kProxy,
asankac93076192016-10-03 15:46:0212926 AUTH_ASYNC,
12927 OK,
12928 kSecureServer,
12929 AUTH_ASYNC,
12930 OK,
12931 3,
12932 1,
12933 {TestRound(kConnect, kProxyChallenge, OK),
12934 TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet,
12935 &kServerChallenge),
[email protected]044de0642010-06-17 10:42:1512936 TestRound(kGetAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112937 {__LINE__,
12938 kProxy,
asankac93076192016-10-03 15:46:0212939 AUTH_ASYNC,
12940 OK,
12941 kSecureServer,
12942 AUTH_ASYNC,
12943 ERR_INVALID_AUTH_CREDENTIALS,
12944 3,
12945 1,
12946 {TestRound(kConnect, kProxyChallenge, OK),
12947 TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet,
12948 &kServerChallenge),
asankae2257db2016-10-11 22:03:1612949 TestRound(kGet, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112950 {__LINE__,
12951 kProxy,
12952 AUTH_ASYNC,
12953 ERR_INVALID_AUTH_CREDENTIALS,
12954 kSecureServer,
12955 AUTH_ASYNC,
12956 ERR_INVALID_AUTH_CREDENTIALS,
12957 4,
12958 2,
12959 {TestRound(kConnect, kProxyChallenge, OK),
12960 TestRound(kConnect, kProxyChallenge, OK),
12961 TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet,
12962 &kServerChallenge),
12963 TestRound(kGet, kSuccess, OK)}},
[email protected]044de0642010-06-17 10:42:1512964 };
12965
asanka463ca4262016-11-16 02:34:3112966 for (const auto& test_config : test_configs) {
12967 SCOPED_TRACE(::testing::Message() << "Test config at "
12968 << test_config.line_number);
[email protected]2d01c262011-08-11 23:07:0812969 HttpAuthHandlerMock::Factory* auth_factory(
12970 new HttpAuthHandlerMock::Factory());
[email protected]bb88e1d32013-05-03 23:11:0712971 session_deps_.http_auth_handler_factory.reset(auth_factory);
asanka5ffd5d72016-03-23 16:20:4912972 SSLInfo empty_ssl_info;
[email protected]65d34382010-07-01 18:12:2612973
12974 // Set up authentication handlers as necessary.
[email protected]044de0642010-06-17 10:42:1512975 if (test_config.proxy_auth_timing != AUTH_NONE) {
asanka463ca4262016-11-16 02:34:3112976 for (int n = 0; n < 3; n++) {
[email protected]2d01c262011-08-11 23:07:0812977 HttpAuthHandlerMock* auth_handler(new HttpAuthHandlerMock());
12978 std::string auth_challenge = "Mock realm=proxy";
12979 GURL origin(test_config.proxy_url);
[email protected]df41d0d82014-03-13 00:43:2412980 HttpAuthChallengeTokenizer tokenizer(auth_challenge.begin(),
12981 auth_challenge.end());
[email protected]2d01c262011-08-11 23:07:0812982 auth_handler->InitFromChallenge(&tokenizer, HttpAuth::AUTH_PROXY,
tfarina42834112016-09-22 13:38:2012983 empty_ssl_info, origin,
12984 NetLogWithSource());
[email protected]2d01c262011-08-11 23:07:0812985 auth_handler->SetGenerateExpectation(
12986 test_config.proxy_auth_timing == AUTH_ASYNC,
asanka463ca4262016-11-16 02:34:3112987 n == 0 ? test_config.first_generate_proxy_token_rv : OK);
[email protected]2d01c262011-08-11 23:07:0812988 auth_factory->AddMockHandler(auth_handler, HttpAuth::AUTH_PROXY);
12989 }
[email protected]044de0642010-06-17 10:42:1512990 }
12991 if (test_config.server_auth_timing != AUTH_NONE) {
[email protected]3fd9dae2010-06-21 11:39:0012992 HttpAuthHandlerMock* auth_handler(new HttpAuthHandlerMock());
[email protected]044de0642010-06-17 10:42:1512993 std::string auth_challenge = "Mock realm=server";
12994 GURL origin(test_config.server_url);
[email protected]df41d0d82014-03-13 00:43:2412995 HttpAuthChallengeTokenizer tokenizer(auth_challenge.begin(),
12996 auth_challenge.end());
[email protected]044de0642010-06-17 10:42:1512997 auth_handler->InitFromChallenge(&tokenizer, HttpAuth::AUTH_SERVER,
tfarina42834112016-09-22 13:38:2012998 empty_ssl_info, origin,
12999 NetLogWithSource());
[email protected]044de0642010-06-17 10:42:1513000 auth_handler->SetGenerateExpectation(
13001 test_config.server_auth_timing == AUTH_ASYNC,
asanka463ca4262016-11-16 02:34:3113002 test_config.first_generate_server_token_rv);
[email protected]2d01c262011-08-11 23:07:0813003 auth_factory->AddMockHandler(auth_handler, HttpAuth::AUTH_SERVER);
asankae2257db2016-10-11 22:03:1613004
13005 // The second handler always succeeds. It should only be used where there
13006 // are multiple auth sessions for server auth in the same network
13007 // transaction using the same auth scheme.
13008 std::unique_ptr<HttpAuthHandlerMock> second_handler =
Jeremy Roman0579ed62017-08-29 15:56:1913009 std::make_unique<HttpAuthHandlerMock>();
asankae2257db2016-10-11 22:03:1613010 second_handler->InitFromChallenge(&tokenizer, HttpAuth::AUTH_SERVER,
13011 empty_ssl_info, origin,
13012 NetLogWithSource());
13013 second_handler->SetGenerateExpectation(true, OK);
13014 auth_factory->AddMockHandler(second_handler.release(),
13015 HttpAuth::AUTH_SERVER);
[email protected]044de0642010-06-17 10:42:1513016 }
13017 if (test_config.proxy_url) {
Lily Houghton8c2f97d2018-01-22 05:06:5913018 session_deps_.proxy_resolution_service =
13019 ProxyResolutionService::CreateFixed(test_config.proxy_url);
[email protected]044de0642010-06-17 10:42:1513020 } else {
Lily Houghton8c2f97d2018-01-22 05:06:5913021 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateDirect();
[email protected]044de0642010-06-17 10:42:1513022 }
13023
13024 HttpRequestInfo request;
13025 request.method = "GET";
13026 request.url = GURL(test_config.server_url);
[email protected]044de0642010-06-17 10:42:1513027
danakj1fd259a02016-04-16 03:17:0913028 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]044de0642010-06-17 10:42:1513029
rchcb68dc62015-05-21 04:45:3613030 SSLSocketDataProvider ssl_socket_data_provider(SYNCHRONOUS, OK);
13031
13032 std::vector<std::vector<MockRead>> mock_reads(1);
13033 std::vector<std::vector<MockWrite>> mock_writes(1);
[email protected]044de0642010-06-17 10:42:1513034 for (int round = 0; round < test_config.num_auth_rounds; ++round) {
davidben8c7089a2017-04-17 20:38:2213035 SCOPED_TRACE(round);
[email protected]044de0642010-06-17 10:42:1513036 const TestRound& read_write_round = test_config.rounds[round];
13037
13038 // Set up expected reads and writes.
rchcb68dc62015-05-21 04:45:3613039 mock_reads.back().push_back(read_write_round.read);
13040 mock_writes.back().push_back(read_write_round.write);
13041
13042 // kProxyChallenge uses Proxy-Connection: close which means that the
13043 // socket is closed and a new one will be created for the next request.
mmenkee71e15332015-10-07 16:39:5413044 if (read_write_round.read.data == kProxyChallenge.data) {
rchcb68dc62015-05-21 04:45:3613045 mock_reads.push_back(std::vector<MockRead>());
13046 mock_writes.push_back(std::vector<MockWrite>());
[email protected]044de0642010-06-17 10:42:1513047 }
13048
rchcb68dc62015-05-21 04:45:3613049 if (read_write_round.extra_read) {
13050 mock_reads.back().push_back(*read_write_round.extra_read);
[email protected]044de0642010-06-17 10:42:1513051 }
rchcb68dc62015-05-21 04:45:3613052 if (read_write_round.extra_write) {
13053 mock_writes.back().push_back(*read_write_round.extra_write);
13054 }
[email protected]044de0642010-06-17 10:42:1513055
13056 // Add an SSL sequence if necessary.
[email protected]044de0642010-06-17 10:42:1513057 if (round >= test_config.first_ssl_round)
[email protected]bb88e1d32013-05-03 23:11:0713058 session_deps_.socket_factory->AddSSLSocketDataProvider(
[email protected]044de0642010-06-17 10:42:1513059 &ssl_socket_data_provider);
rchcb68dc62015-05-21 04:45:3613060 }
[email protected]044de0642010-06-17 10:42:1513061
danakj1fd259a02016-04-16 03:17:0913062 std::vector<std::unique_ptr<StaticSocketDataProvider>> data_providers;
rchcb68dc62015-05-21 04:45:3613063 for (size_t i = 0; i < mock_reads.size(); ++i) {
Jeremy Roman0579ed62017-08-29 15:56:1913064 data_providers.push_back(std::make_unique<StaticSocketDataProvider>(
davidben5f8b6bc2015-11-25 03:19:5413065 mock_reads[i].data(), mock_reads[i].size(), mock_writes[i].data(),
bnc87dcefc2017-05-25 12:47:5813066 mock_writes[i].size()));
rchcb68dc62015-05-21 04:45:3613067 session_deps_.socket_factory->AddSocketDataProvider(
olli.raula525048c2015-12-10 07:38:3213068 data_providers.back().get());
rchcb68dc62015-05-21 04:45:3613069 }
13070
mmenkecc2298e2015-12-07 18:20:1813071 // Transaction must be created after DataProviders, so it's destroyed before
13072 // they are as well.
13073 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
13074
rchcb68dc62015-05-21 04:45:3613075 for (int round = 0; round < test_config.num_auth_rounds; ++round) {
davidben8c7089a2017-04-17 20:38:2213076 SCOPED_TRACE(round);
rchcb68dc62015-05-21 04:45:3613077 const TestRound& read_write_round = test_config.rounds[round];
[email protected]044de0642010-06-17 10:42:1513078 // Start or restart the transaction.
[email protected]49639fa2011-12-20 23:22:4113079 TestCompletionCallback callback;
[email protected]044de0642010-06-17 10:42:1513080 int rv;
13081 if (round == 0) {
tfarina42834112016-09-22 13:38:2013082 rv = trans.Start(&request, callback.callback(), NetLogWithSource());
[email protected]044de0642010-06-17 10:42:1513083 } else {
[email protected]49639fa2011-12-20 23:22:4113084 rv = trans.RestartWithAuth(
13085 AuthCredentials(kFoo, kBar), callback.callback());
[email protected]044de0642010-06-17 10:42:1513086 }
13087 if (rv == ERR_IO_PENDING)
13088 rv = callback.WaitForResult();
13089
13090 // Compare results with expected data.
asankae2257db2016-10-11 22:03:1613091 EXPECT_THAT(rv, IsError(read_write_round.expected_rv));
[email protected]0b0bf032010-09-21 18:08:5013092 const HttpResponseInfo* response = trans.GetResponseInfo();
ttuttlec0c828492015-05-15 01:25:5513093 if (read_write_round.expected_rv != OK) {
[email protected]044de0642010-06-17 10:42:1513094 EXPECT_EQ(round + 1, test_config.num_auth_rounds);
13095 continue;
13096 }
13097 if (round + 1 < test_config.num_auth_rounds) {
wezca1070932016-05-26 20:30:5213098 EXPECT_TRUE(response->auth_challenge);
[email protected]044de0642010-06-17 10:42:1513099 } else {
wezca1070932016-05-26 20:30:5213100 EXPECT_FALSE(response->auth_challenge);
asankae2257db2016-10-11 22:03:1613101 EXPECT_FALSE(trans.IsReadyToRestartForAuth());
[email protected]044de0642010-06-17 10:42:1513102 }
13103 }
[email protected]e5ae96a2010-04-14 20:12:4513104 }
13105}
13106
bncd16676a2016-07-20 16:23:0113107TEST_F(HttpNetworkTransactionTest, MultiRoundAuth) {
[email protected]c871bce92010-07-15 21:51:1413108 // Do multi-round authentication and make sure it works correctly.
[email protected]c871bce92010-07-15 21:51:1413109 HttpAuthHandlerMock::Factory* auth_factory(
13110 new HttpAuthHandlerMock::Factory());
[email protected]bb88e1d32013-05-03 23:11:0713111 session_deps_.http_auth_handler_factory.reset(auth_factory);
Lily Houghton8c2f97d2018-01-22 05:06:5913112 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateDirect();
[email protected]bb88e1d32013-05-03 23:11:0713113 session_deps_.host_resolver->rules()->AddRule("www.example.com", "10.0.0.1");
13114 session_deps_.host_resolver->set_synchronous_mode(true);
[email protected]c871bce92010-07-15 21:51:1413115
13116 HttpAuthHandlerMock* auth_handler(new HttpAuthHandlerMock());
13117 auth_handler->set_connection_based(true);
13118 std::string auth_challenge = "Mock realm=server";
13119 GURL origin("http://www.example.com");
[email protected]df41d0d82014-03-13 00:43:2413120 HttpAuthChallengeTokenizer tokenizer(auth_challenge.begin(),
13121 auth_challenge.end());
asanka5ffd5d72016-03-23 16:20:4913122 SSLInfo empty_ssl_info;
[email protected]c871bce92010-07-15 21:51:1413123 auth_handler->InitFromChallenge(&tokenizer, HttpAuth::AUTH_SERVER,
tfarina42834112016-09-22 13:38:2013124 empty_ssl_info, origin, NetLogWithSource());
[email protected]2d01c262011-08-11 23:07:0813125 auth_factory->AddMockHandler(auth_handler, HttpAuth::AUTH_SERVER);
[email protected]c871bce92010-07-15 21:51:1413126
[email protected]c871bce92010-07-15 21:51:1413127 int rv = OK;
13128 const HttpResponseInfo* response = NULL;
13129 HttpRequestInfo request;
13130 request.method = "GET";
13131 request.url = origin;
[email protected]cb9bf6ca2011-01-28 13:15:2713132
danakj1fd259a02016-04-16 03:17:0913133 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]7ef4cbbb2011-02-06 11:19:1013134
13135 // Use a TCP Socket Pool with only one connection per group. This is used
13136 // to validate that the TCP socket is not released to the pool between
13137 // each round of multi-round authentication.
mmenkee65e7af2015-10-13 17:16:4213138 HttpNetworkSessionPeer session_peer(session.get());
[email protected]ab739042011-04-07 15:22:2813139 TransportClientSocketPool* transport_pool = new TransportClientSocketPool(
[email protected]7ef4cbbb2011-02-06 11:19:1013140 50, // Max sockets for pool
13141 1, // Max sockets per group
tbansal7b403bcc2016-04-13 22:33:2113142 session_deps_.host_resolver.get(), session_deps_.socket_factory.get(),
13143 NULL, session_deps_.net_log);
Jeremy Roman0579ed62017-08-29 15:56:1913144 auto mock_pool_manager = std::make_unique<MockClientSocketPoolManager>();
[email protected]a42dbd142011-11-17 16:42:0213145 mock_pool_manager->SetTransportSocketPool(transport_pool);
dchengc7eeda422015-12-26 03:56:4813146 session_peer.SetClientSocketPoolManager(std::move(mock_pool_manager));
[email protected]7ef4cbbb2011-02-06 11:19:1013147
bnc691fda62016-08-12 00:43:1613148 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]49639fa2011-12-20 23:22:4113149 TestCompletionCallback callback;
[email protected]c871bce92010-07-15 21:51:1413150
13151 const MockWrite kGet(
13152 "GET / HTTP/1.1\r\n"
13153 "Host: www.example.com\r\n"
13154 "Connection: keep-alive\r\n\r\n");
13155 const MockWrite kGetAuth(
13156 "GET / HTTP/1.1\r\n"
13157 "Host: www.example.com\r\n"
13158 "Connection: keep-alive\r\n"
13159 "Authorization: auth_token\r\n\r\n");
13160
13161 const MockRead kServerChallenge(
13162 "HTTP/1.1 401 Unauthorized\r\n"
13163 "WWW-Authenticate: Mock realm=server\r\n"
13164 "Content-Type: text/html; charset=iso-8859-1\r\n"
13165 "Content-Length: 14\r\n\r\n"
13166 "Unauthorized\r\n");
13167 const MockRead kSuccess(
13168 "HTTP/1.1 200 OK\r\n"
13169 "Content-Type: text/html; charset=iso-8859-1\r\n"
13170 "Content-Length: 3\r\n\r\n"
13171 "Yes");
13172
13173 MockWrite writes[] = {
13174 // First round
13175 kGet,
13176 // Second round
13177 kGetAuth,
13178 // Third round
13179 kGetAuth,
[email protected]eca50e122010-09-11 14:03:3013180 // Fourth round
[email protected]7ef4cbbb2011-02-06 11:19:1013181 kGetAuth,
13182 // Competing request
13183 kGet,
[email protected]c871bce92010-07-15 21:51:1413184 };
13185 MockRead reads[] = {
13186 // First round
13187 kServerChallenge,
13188 // Second round
13189 kServerChallenge,
13190 // Third round
[email protected]eca50e122010-09-11 14:03:3013191 kServerChallenge,
13192 // Fourth round
[email protected]c871bce92010-07-15 21:51:1413193 kSuccess,
[email protected]7ef4cbbb2011-02-06 11:19:1013194 // Competing response
13195 kSuccess,
[email protected]c871bce92010-07-15 21:51:1413196 };
13197 StaticSocketDataProvider data_provider(reads, arraysize(reads),
13198 writes, arraysize(writes));
[email protected]bb88e1d32013-05-03 23:11:0713199 session_deps_.socket_factory->AddSocketDataProvider(&data_provider);
[email protected]c871bce92010-07-15 21:51:1413200
thestig9d3bb0c2015-01-24 00:49:5113201 const char kSocketGroup[] = "www.example.com:80";
[email protected]7ef4cbbb2011-02-06 11:19:1013202
13203 // First round of authentication.
[email protected]c871bce92010-07-15 21:51:1413204 auth_handler->SetGenerateExpectation(false, OK);
tfarina42834112016-09-22 13:38:2013205 rv = trans.Start(&request, callback.callback(), NetLogWithSource());
[email protected]c871bce92010-07-15 21:51:1413206 if (rv == ERR_IO_PENDING)
13207 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0113208 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:1613209 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5213210 ASSERT_TRUE(response);
13211 EXPECT_TRUE(response->auth_challenge);
[email protected]ab739042011-04-07 15:22:2813212 EXPECT_EQ(0, transport_pool->IdleSocketCountInGroup(kSocketGroup));
asanka463ca4262016-11-16 02:34:3113213 EXPECT_EQ(HttpAuthHandlerMock::State::WAIT_FOR_GENERATE_AUTH_TOKEN,
13214 auth_handler->state());
[email protected]c871bce92010-07-15 21:51:1413215
[email protected]7ef4cbbb2011-02-06 11:19:1013216 // In between rounds, another request comes in for the same domain.
13217 // It should not be able to grab the TCP socket that trans has already
13218 // claimed.
bnc691fda62016-08-12 00:43:1613219 HttpNetworkTransaction trans_compete(DEFAULT_PRIORITY, session.get());
[email protected]49639fa2011-12-20 23:22:4113220 TestCompletionCallback callback_compete;
tfarina42834112016-09-22 13:38:2013221 rv = trans_compete.Start(&request, callback_compete.callback(),
13222 NetLogWithSource());
robpercival214763f2016-07-01 23:27:0113223 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]7ef4cbbb2011-02-06 11:19:1013224 // callback_compete.WaitForResult at this point would stall forever,
13225 // since the HttpNetworkTransaction does not release the request back to
13226 // the pool until after authentication completes.
13227
13228 // Second round of authentication.
[email protected]c871bce92010-07-15 21:51:1413229 auth_handler->SetGenerateExpectation(false, OK);
bnc691fda62016-08-12 00:43:1613230 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar), callback.callback());
[email protected]c871bce92010-07-15 21:51:1413231 if (rv == ERR_IO_PENDING)
13232 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0113233 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:1613234 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5213235 ASSERT_TRUE(response);
13236 EXPECT_FALSE(response->auth_challenge);
[email protected]ab739042011-04-07 15:22:2813237 EXPECT_EQ(0, transport_pool->IdleSocketCountInGroup(kSocketGroup));
asanka463ca4262016-11-16 02:34:3113238 EXPECT_EQ(HttpAuthHandlerMock::State::WAIT_FOR_GENERATE_AUTH_TOKEN,
13239 auth_handler->state());
[email protected]c871bce92010-07-15 21:51:1413240
[email protected]7ef4cbbb2011-02-06 11:19:1013241 // Third round of authentication.
[email protected]c871bce92010-07-15 21:51:1413242 auth_handler->SetGenerateExpectation(false, OK);
bnc691fda62016-08-12 00:43:1613243 rv = trans.RestartWithAuth(AuthCredentials(), callback.callback());
[email protected]c871bce92010-07-15 21:51:1413244 if (rv == ERR_IO_PENDING)
13245 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0113246 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:1613247 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5213248 ASSERT_TRUE(response);
13249 EXPECT_FALSE(response->auth_challenge);
[email protected]ab739042011-04-07 15:22:2813250 EXPECT_EQ(0, transport_pool->IdleSocketCountInGroup(kSocketGroup));
asanka463ca4262016-11-16 02:34:3113251 EXPECT_EQ(HttpAuthHandlerMock::State::WAIT_FOR_GENERATE_AUTH_TOKEN,
13252 auth_handler->state());
[email protected]eca50e122010-09-11 14:03:3013253
[email protected]7ef4cbbb2011-02-06 11:19:1013254 // Fourth round of authentication, which completes successfully.
[email protected]eca50e122010-09-11 14:03:3013255 auth_handler->SetGenerateExpectation(false, OK);
bnc691fda62016-08-12 00:43:1613256 rv = trans.RestartWithAuth(AuthCredentials(), callback.callback());
[email protected]eca50e122010-09-11 14:03:3013257 if (rv == ERR_IO_PENDING)
13258 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0113259 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:1613260 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5213261 ASSERT_TRUE(response);
13262 EXPECT_FALSE(response->auth_challenge);
[email protected]ab739042011-04-07 15:22:2813263 EXPECT_EQ(0, transport_pool->IdleSocketCountInGroup(kSocketGroup));
[email protected]7ef4cbbb2011-02-06 11:19:1013264
asanka463ca4262016-11-16 02:34:3113265 // In WAIT_FOR_CHALLENGE, although in reality the auth handler is done. A real
13266 // auth handler should transition to a DONE state in concert with the remote
13267 // server. But that's not something we can test here with a mock handler.
13268 EXPECT_EQ(HttpAuthHandlerMock::State::WAIT_FOR_CHALLENGE,
13269 auth_handler->state());
13270
[email protected]7ef4cbbb2011-02-06 11:19:1013271 // Read the body since the fourth round was successful. This will also
13272 // release the socket back to the pool.
13273 scoped_refptr<IOBufferWithSize> io_buf(new IOBufferWithSize(50));
bnc691fda62016-08-12 00:43:1613274 rv = trans.Read(io_buf.get(), io_buf->size(), callback.callback());
[email protected]7ef4cbbb2011-02-06 11:19:1013275 if (rv == ERR_IO_PENDING)
13276 rv = callback.WaitForResult();
13277 EXPECT_EQ(3, rv);
bnc691fda62016-08-12 00:43:1613278 rv = trans.Read(io_buf.get(), io_buf->size(), callback.callback());
[email protected]7ef4cbbb2011-02-06 11:19:1013279 EXPECT_EQ(0, rv);
13280 // There are still 0 idle sockets, since the trans_compete transaction
13281 // will be handed it immediately after trans releases it to the group.
[email protected]ab739042011-04-07 15:22:2813282 EXPECT_EQ(0, transport_pool->IdleSocketCountInGroup(kSocketGroup));
[email protected]7ef4cbbb2011-02-06 11:19:1013283
13284 // The competing request can now finish. Wait for the headers and then
13285 // read the body.
13286 rv = callback_compete.WaitForResult();
robpercival214763f2016-07-01 23:27:0113287 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:1613288 rv = trans_compete.Read(io_buf.get(), io_buf->size(), callback.callback());
[email protected]7ef4cbbb2011-02-06 11:19:1013289 if (rv == ERR_IO_PENDING)
13290 rv = callback.WaitForResult();
13291 EXPECT_EQ(3, rv);
bnc691fda62016-08-12 00:43:1613292 rv = trans_compete.Read(io_buf.get(), io_buf->size(), callback.callback());
[email protected]7ef4cbbb2011-02-06 11:19:1013293 EXPECT_EQ(0, rv);
13294
13295 // Finally, the socket is released to the group.
[email protected]ab739042011-04-07 15:22:2813296 EXPECT_EQ(1, transport_pool->IdleSocketCountInGroup(kSocketGroup));
[email protected]c871bce92010-07-15 21:51:1413297}
13298
[email protected]65041fa2010-05-21 06:56:5313299// This tests the case that a request is issued via http instead of spdy after
13300// npn is negotiated.
bncd16676a2016-07-20 16:23:0113301TEST_F(HttpNetworkTransactionTest, NpnWithHttpOverSSL) {
[email protected]65041fa2010-05-21 06:56:5313302 HttpRequestInfo request;
13303 request.method = "GET";
bncce36dca22015-04-21 22:11:2313304 request.url = GURL("https://www.example.org/");
[email protected]65041fa2010-05-21 06:56:5313305
13306 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:2313307 MockWrite(
13308 "GET / HTTP/1.1\r\n"
13309 "Host: www.example.org\r\n"
13310 "Connection: keep-alive\r\n\r\n"),
[email protected]65041fa2010-05-21 06:56:5313311 };
13312
13313 MockRead data_reads[] = {
bncc958faa2015-07-31 18:14:5213314 MockRead("HTTP/1.1 200 OK\r\n"),
bnc2df4b522016-07-08 18:17:4313315 MockRead(kAlternativeServiceHttpHeader),
bncc958faa2015-07-31 18:14:5213316 MockRead("\r\n"),
13317 MockRead("hello world"),
13318 MockRead(SYNCHRONOUS, OK),
[email protected]65041fa2010-05-21 06:56:5313319 };
13320
[email protected]8ddf8322012-02-23 18:08:0613321 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3613322 ssl.next_proto = kProtoHTTP11;
[email protected]65041fa2010-05-21 06:56:5313323
[email protected]bb88e1d32013-05-03 23:11:0713324 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]65041fa2010-05-21 06:56:5313325
13326 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
13327 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:0713328 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]65041fa2010-05-21 06:56:5313329
[email protected]49639fa2011-12-20 23:22:4113330 TestCompletionCallback callback;
[email protected]65041fa2010-05-21 06:56:5313331
danakj1fd259a02016-04-16 03:17:0913332 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1613333 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]65041fa2010-05-21 06:56:5313334
tfarina42834112016-09-22 13:38:2013335 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
[email protected]65041fa2010-05-21 06:56:5313336
robpercival214763f2016-07-01 23:27:0113337 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
13338 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]65041fa2010-05-21 06:56:5313339
bnc691fda62016-08-12 00:43:1613340 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5213341 ASSERT_TRUE(response);
13342 ASSERT_TRUE(response->headers);
[email protected]65041fa2010-05-21 06:56:5313343 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
13344
13345 std::string response_data;
bnc691fda62016-08-12 00:43:1613346 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
[email protected]65041fa2010-05-21 06:56:5313347 EXPECT_EQ("hello world", response_data);
13348
13349 EXPECT_FALSE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5213350 EXPECT_TRUE(response->was_alpn_negotiated);
[email protected]65041fa2010-05-21 06:56:5313351}
[email protected]26ef6582010-06-24 02:30:4713352
bnc55ff9da2015-08-19 18:42:3513353// Simulate the SSL handshake completing with an NPN negotiation followed by an
13354// immediate server closing of the socket.
13355// Regression test for https://crbug.com/46369.
bncd16676a2016-07-20 16:23:0113356TEST_F(HttpNetworkTransactionTest, SpdyPostNPNServerHangup) {
[email protected]26ef6582010-06-24 02:30:4713357 HttpRequestInfo request;
13358 request.method = "GET";
bncce36dca22015-04-21 22:11:2313359 request.url = GURL("https://www.example.org/");
[email protected]26ef6582010-06-24 02:30:4713360
[email protected]8ddf8322012-02-23 18:08:0613361 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3613362 ssl.next_proto = kProtoHTTP2;
[email protected]bb88e1d32013-05-03 23:11:0713363 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]26ef6582010-06-24 02:30:4713364
bncdf80d44fd2016-07-15 20:27:4113365 SpdySerializedFrame req(
bnc38dcd392016-02-09 23:19:4913366 spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST, true));
bncdf80d44fd2016-07-15 20:27:4113367 MockWrite spdy_writes[] = {CreateMockWrite(req, 1)};
[email protected]26ef6582010-06-24 02:30:4713368
13369 MockRead spdy_reads[] = {
[email protected]8ddf8322012-02-23 18:08:0613370 MockRead(SYNCHRONOUS, 0, 0) // Not async - return 0 immediately.
[email protected]26ef6582010-06-24 02:30:4713371 };
13372
rch8e6c6c42015-05-01 14:05:1313373 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
13374 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:0713375 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]26ef6582010-06-24 02:30:4713376
[email protected]49639fa2011-12-20 23:22:4113377 TestCompletionCallback callback;
[email protected]26ef6582010-06-24 02:30:4713378
danakj1fd259a02016-04-16 03:17:0913379 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1613380 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]26ef6582010-06-24 02:30:4713381
tfarina42834112016-09-22 13:38:2013382 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0113383 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
13384 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_CONNECTION_CLOSED));
[email protected]26ef6582010-06-24 02:30:4713385}
[email protected]65d34382010-07-01 18:12:2613386
[email protected]795cbf82013-07-22 09:37:2713387// A subclass of HttpAuthHandlerMock that records the request URL when
13388// it gets it. This is needed since the auth handler may get destroyed
13389// before we get a chance to query it.
13390class UrlRecordingHttpAuthHandlerMock : public HttpAuthHandlerMock {
13391 public:
13392 explicit UrlRecordingHttpAuthHandlerMock(GURL* url) : url_(url) {}
13393
Chris Watkins7a41d3552017-12-01 02:13:2713394 ~UrlRecordingHttpAuthHandlerMock() override = default;
[email protected]795cbf82013-07-22 09:37:2713395
13396 protected:
dchengb03027d2014-10-21 12:00:2013397 int GenerateAuthTokenImpl(const AuthCredentials* credentials,
13398 const HttpRequestInfo* request,
13399 const CompletionCallback& callback,
13400 std::string* auth_token) override {
[email protected]795cbf82013-07-22 09:37:2713401 *url_ = request->url;
13402 return HttpAuthHandlerMock::GenerateAuthTokenImpl(
13403 credentials, request, callback, auth_token);
13404 }
13405
13406 private:
13407 GURL* url_;
13408};
13409
[email protected]8e6441ca2010-08-19 05:56:3813410// Test that if we cancel the transaction as the connection is completing, that
13411// everything tears down correctly.
bncd16676a2016-07-20 16:23:0113412TEST_F(HttpNetworkTransactionTest, SimpleCancel) {
[email protected]8e6441ca2010-08-19 05:56:3813413 // Setup everything about the connection to complete synchronously, so that
13414 // after calling HttpNetworkTransaction::Start, the only thing we're waiting
13415 // for is the callback from the HttpStreamRequest.
13416 // Then cancel the transaction.
13417 // Verify that we don't crash.
[email protected]d973e99a2012-02-17 21:02:3613418 MockConnect mock_connect(SYNCHRONOUS, OK);
[email protected]8e6441ca2010-08-19 05:56:3813419 MockRead data_reads[] = {
[email protected]8ddf8322012-02-23 18:08:0613420 MockRead(SYNCHRONOUS, "HTTP/1.0 200 OK\r\n\r\n"),
13421 MockRead(SYNCHRONOUS, "hello world"),
13422 MockRead(SYNCHRONOUS, OK),
[email protected]8e6441ca2010-08-19 05:56:3813423 };
13424
[email protected]8e6441ca2010-08-19 05:56:3813425 HttpRequestInfo request;
13426 request.method = "GET";
bncce36dca22015-04-21 22:11:2313427 request.url = GURL("http://www.example.org/");
[email protected]8e6441ca2010-08-19 05:56:3813428
[email protected]bb88e1d32013-05-03 23:11:0713429 session_deps_.host_resolver->set_synchronous_mode(true);
danakj1fd259a02016-04-16 03:17:0913430 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc87dcefc2017-05-25 12:47:5813431 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:1913432 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:2713433
[email protected]8e6441ca2010-08-19 05:56:3813434 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
13435 data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:0713436 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]8e6441ca2010-08-19 05:56:3813437
[email protected]49639fa2011-12-20 23:22:4113438 TestCompletionCallback callback;
[email protected]8e6441ca2010-08-19 05:56:3813439
vishal.b62985ca92015-04-17 08:45:5113440 BoundTestNetLog log;
[email protected]49639fa2011-12-20 23:22:4113441 int rv = trans->Start(&request, callback.callback(), log.bound());
robpercival214763f2016-07-01 23:27:0113442 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]8e6441ca2010-08-19 05:56:3813443 trans.reset(); // Cancel the transaction here.
13444
fdoray92e35a72016-06-10 15:54:5513445 base::RunLoop().RunUntilIdle();
[email protected]f45c1ee2010-08-03 00:54:3013446}
13447
[email protected]ecab6e052014-05-16 14:58:1213448// Test that if a transaction is cancelled after receiving the headers, the
13449// stream is drained properly and added back to the socket pool. The main
13450// purpose of this test is to make sure that an HttpStreamParser can be read
13451// from after the HttpNetworkTransaction and the objects it owns have been
13452// deleted.
13453// See http://crbug.com/368418
bncd16676a2016-07-20 16:23:0113454TEST_F(HttpNetworkTransactionTest, CancelAfterHeaders) {
[email protected]ecab6e052014-05-16 14:58:1213455 MockRead data_reads[] = {
13456 MockRead(ASYNC, "HTTP/1.1 200 OK\r\n"),
13457 MockRead(ASYNC, "Content-Length: 2\r\n"),
13458 MockRead(ASYNC, "Connection: Keep-Alive\r\n\r\n"),
13459 MockRead(ASYNC, "1"),
13460 // 2 async reads are necessary to trigger a ReadResponseBody call after the
13461 // HttpNetworkTransaction has been deleted.
13462 MockRead(ASYNC, "2"),
13463 MockRead(SYNCHRONOUS, ERR_IO_PENDING), // Should never read this.
13464 };
13465 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
13466 session_deps_.socket_factory->AddSocketDataProvider(&data);
13467
danakj1fd259a02016-04-16 03:17:0913468 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]ecab6e052014-05-16 14:58:1213469
13470 {
13471 HttpRequestInfo request;
13472 request.method = "GET";
bncce36dca22015-04-21 22:11:2313473 request.url = GURL("http://www.example.org/");
[email protected]ecab6e052014-05-16 14:58:1213474
dcheng48459ac22014-08-26 00:46:4113475 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]ecab6e052014-05-16 14:58:1213476 TestCompletionCallback callback;
13477
tfarina42834112016-09-22 13:38:2013478 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0113479 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]ecab6e052014-05-16 14:58:1213480 callback.WaitForResult();
13481
13482 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5213483 ASSERT_TRUE(response);
13484 EXPECT_TRUE(response->headers);
[email protected]ecab6e052014-05-16 14:58:1213485 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
13486
13487 // The transaction and HttpRequestInfo are deleted.
13488 }
13489
13490 // Let the HttpResponseBodyDrainer drain the socket.
fdoray92e35a72016-06-10 15:54:5513491 base::RunLoop().RunUntilIdle();
[email protected]ecab6e052014-05-16 14:58:1213492
13493 // Socket should now be idle, waiting to be reused.
dcheng48459ac22014-08-26 00:46:4113494 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]ecab6e052014-05-16 14:58:1213495}
13496
[email protected]76a505b2010-08-25 06:23:0013497// Test a basic GET request through a proxy.
bncd16676a2016-07-20 16:23:0113498TEST_F(HttpNetworkTransactionTest, ProxyGet) {
Lily Houghton8c2f97d2018-01-22 05:06:5913499 session_deps_.proxy_resolution_service =
13500 ProxyResolutionService::CreateFixedFromPacResult("PROXY myproxy:70");
vishal.b62985ca92015-04-17 08:45:5113501 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:0713502 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:0913503 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]76a505b2010-08-25 06:23:0013504
[email protected]76a505b2010-08-25 06:23:0013505 HttpRequestInfo request;
13506 request.method = "GET";
bncce36dca22015-04-21 22:11:2313507 request.url = GURL("http://www.example.org/");
[email protected]76a505b2010-08-25 06:23:0013508
13509 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:2313510 MockWrite(
13511 "GET http://www.example.org/ HTTP/1.1\r\n"
13512 "Host: www.example.org\r\n"
13513 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]76a505b2010-08-25 06:23:0013514 };
13515
13516 MockRead data_reads1[] = {
13517 MockRead("HTTP/1.1 200 OK\r\n"),
13518 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
13519 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:0613520 MockRead(SYNCHRONOUS, OK),
[email protected]76a505b2010-08-25 06:23:0013521 };
13522
13523 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
13524 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:0713525 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]76a505b2010-08-25 06:23:0013526
[email protected]49639fa2011-12-20 23:22:4113527 TestCompletionCallback callback1;
[email protected]76a505b2010-08-25 06:23:0013528
bnc691fda62016-08-12 00:43:1613529 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
ryansturm49a8cb12016-06-15 16:51:0913530 BeforeHeadersSentHandler headers_handler;
bnc691fda62016-08-12 00:43:1613531 trans.SetBeforeHeadersSentCallback(
ryansturm49a8cb12016-06-15 16:51:0913532 base::Bind(&BeforeHeadersSentHandler::OnBeforeHeadersSent,
13533 base::Unretained(&headers_handler)));
[email protected]0b0bf032010-09-21 18:08:5013534
bnc691fda62016-08-12 00:43:1613535 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:0113536 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]76a505b2010-08-25 06:23:0013537
13538 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:0113539 EXPECT_THAT(rv, IsOk());
[email protected]76a505b2010-08-25 06:23:0013540
bnc691fda62016-08-12 00:43:1613541 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5213542 ASSERT_TRUE(response);
[email protected]76a505b2010-08-25 06:23:0013543
13544 EXPECT_TRUE(response->headers->IsKeepAlive());
13545 EXPECT_EQ(200, response->headers->response_code());
13546 EXPECT_EQ(100, response->headers->GetContentLength());
13547 EXPECT_TRUE(response->was_fetched_via_proxy);
tbansal2ecbbc72016-10-06 17:15:4713548 EXPECT_EQ(ProxyServer(ProxyServer::SCHEME_HTTP,
13549 HostPortPair::FromString("myproxy:70")),
13550 response->proxy_server);
ryansturm49a8cb12016-06-15 16:51:0913551 EXPECT_TRUE(headers_handler.observed_before_headers_sent());
13552 EXPECT_TRUE(headers_handler.observed_before_headers_sent_with_proxy());
13553 EXPECT_EQ("myproxy:70", headers_handler.observed_proxy_server_uri());
[email protected]76a505b2010-08-25 06:23:0013554 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
[email protected]029c83b62013-01-24 05:28:2013555
13556 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:1613557 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]029c83b62013-01-24 05:28:2013558 TestLoadTimingNotReusedWithPac(load_timing_info,
13559 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
[email protected]76a505b2010-08-25 06:23:0013560}
13561
13562// Test a basic HTTPS GET request through a proxy.
bncd16676a2016-07-20 16:23:0113563TEST_F(HttpNetworkTransactionTest, ProxyTunnelGet) {
Lily Houghton8c2f97d2018-01-22 05:06:5913564 session_deps_.proxy_resolution_service =
13565 ProxyResolutionService::CreateFixedFromPacResult("PROXY myproxy:70");
vishal.b62985ca92015-04-17 08:45:5113566 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:0713567 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:0913568 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]76a505b2010-08-25 06:23:0013569
[email protected]76a505b2010-08-25 06:23:0013570 HttpRequestInfo request;
13571 request.method = "GET";
bncce36dca22015-04-21 22:11:2313572 request.url = GURL("https://www.example.org/");
[email protected]76a505b2010-08-25 06:23:0013573
13574 // Since we have proxy, should try to establish tunnel.
13575 MockWrite data_writes1[] = {
rsleevidb16bb02015-11-12 23:47:1713576 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
13577 "Host: www.example.org:443\r\n"
13578 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]76a505b2010-08-25 06:23:0013579
rsleevidb16bb02015-11-12 23:47:1713580 MockWrite("GET / HTTP/1.1\r\n"
13581 "Host: www.example.org\r\n"
13582 "Connection: keep-alive\r\n\r\n"),
[email protected]76a505b2010-08-25 06:23:0013583 };
13584
13585 MockRead data_reads1[] = {
13586 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
13587
13588 MockRead("HTTP/1.1 200 OK\r\n"),
13589 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
13590 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:0613591 MockRead(SYNCHRONOUS, OK),
[email protected]76a505b2010-08-25 06:23:0013592 };
13593
13594 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
13595 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:0713596 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8ddf8322012-02-23 18:08:0613597 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:0713598 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]76a505b2010-08-25 06:23:0013599
[email protected]49639fa2011-12-20 23:22:4113600 TestCompletionCallback callback1;
[email protected]76a505b2010-08-25 06:23:0013601
bnc691fda62016-08-12 00:43:1613602 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
ryansturm49a8cb12016-06-15 16:51:0913603 BeforeHeadersSentHandler headers_handler;
bnc691fda62016-08-12 00:43:1613604 trans.SetBeforeHeadersSentCallback(
ryansturm49a8cb12016-06-15 16:51:0913605 base::Bind(&BeforeHeadersSentHandler::OnBeforeHeadersSent,
13606 base::Unretained(&headers_handler)));
[email protected]0b0bf032010-09-21 18:08:5013607
bnc691fda62016-08-12 00:43:1613608 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:0113609 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]76a505b2010-08-25 06:23:0013610
13611 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:0113612 EXPECT_THAT(rv, IsOk());
mmenke43758e62015-05-04 21:09:4613613 TestNetLogEntry::List entries;
[email protected]b2fcd0e2010-12-01 15:19:4013614 log.GetEntries(&entries);
[email protected]76a505b2010-08-25 06:23:0013615 size_t pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:0013616 entries, 0, NetLogEventType::HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
13617 NetLogEventPhase::NONE);
[email protected]76a505b2010-08-25 06:23:0013618 ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:4013619 entries, pos,
mikecirone8b85c432016-09-08 19:11:0013620 NetLogEventType::HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
13621 NetLogEventPhase::NONE);
[email protected]76a505b2010-08-25 06:23:0013622
bnc691fda62016-08-12 00:43:1613623 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5213624 ASSERT_TRUE(response);
[email protected]76a505b2010-08-25 06:23:0013625
13626 EXPECT_TRUE(response->headers->IsKeepAlive());
13627 EXPECT_EQ(200, response->headers->response_code());
13628 EXPECT_EQ(100, response->headers->GetContentLength());
13629 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
13630 EXPECT_TRUE(response->was_fetched_via_proxy);
tbansal2ecbbc72016-10-06 17:15:4713631 EXPECT_EQ(ProxyServer(ProxyServer::SCHEME_HTTP,
13632 HostPortPair::FromString("myproxy:70")),
13633 response->proxy_server);
ryansturm49a8cb12016-06-15 16:51:0913634 EXPECT_TRUE(headers_handler.observed_before_headers_sent());
13635 EXPECT_TRUE(headers_handler.observed_before_headers_sent_with_proxy());
13636 EXPECT_EQ("myproxy:70", headers_handler.observed_proxy_server_uri());
[email protected]029c83b62013-01-24 05:28:2013637
13638 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:1613639 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]029c83b62013-01-24 05:28:2013640 TestLoadTimingNotReusedWithPac(load_timing_info,
13641 CONNECT_TIMING_HAS_SSL_TIMES);
[email protected]76a505b2010-08-25 06:23:0013642}
13643
rsleevidb16bb02015-11-12 23:47:1713644// Test a basic HTTPS GET request through a proxy, connecting to an IPv6
13645// literal host.
bncd16676a2016-07-20 16:23:0113646TEST_F(HttpNetworkTransactionTest, ProxyTunnelGetIPv6) {
Lily Houghton8c2f97d2018-01-22 05:06:5913647 session_deps_.proxy_resolution_service =
13648 ProxyResolutionService::CreateFixedFromPacResult("PROXY myproxy:70");
rsleevidb16bb02015-11-12 23:47:1713649 BoundTestNetLog log;
13650 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:0913651 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
rsleevidb16bb02015-11-12 23:47:1713652
13653 HttpRequestInfo request;
13654 request.method = "GET";
13655 request.url = GURL("https://[::1]:443/");
13656
13657 // Since we have proxy, should try to establish tunnel.
13658 MockWrite data_writes1[] = {
13659 MockWrite("CONNECT [::1]:443 HTTP/1.1\r\n"
13660 "Host: [::1]:443\r\n"
13661 "Proxy-Connection: keep-alive\r\n\r\n"),
13662
13663 MockWrite("GET / HTTP/1.1\r\n"
13664 "Host: [::1]\r\n"
13665 "Connection: keep-alive\r\n\r\n"),
13666 };
13667
13668 MockRead data_reads1[] = {
13669 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
13670
13671 MockRead("HTTP/1.1 200 OK\r\n"),
13672 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
13673 MockRead("Content-Length: 100\r\n\r\n"),
13674 MockRead(SYNCHRONOUS, OK),
13675 };
13676
13677 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
13678 data_writes1, arraysize(data_writes1));
13679 session_deps_.socket_factory->AddSocketDataProvider(&data1);
13680 SSLSocketDataProvider ssl(ASYNC, OK);
13681 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
13682
13683 TestCompletionCallback callback1;
13684
bnc691fda62016-08-12 00:43:1613685 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
rsleevidb16bb02015-11-12 23:47:1713686
bnc691fda62016-08-12 00:43:1613687 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:0113688 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
rsleevidb16bb02015-11-12 23:47:1713689
13690 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:0113691 EXPECT_THAT(rv, IsOk());
rsleevidb16bb02015-11-12 23:47:1713692 TestNetLogEntry::List entries;
13693 log.GetEntries(&entries);
13694 size_t pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:0013695 entries, 0, NetLogEventType::HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
13696 NetLogEventPhase::NONE);
rsleevidb16bb02015-11-12 23:47:1713697 ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:0013698 entries, pos,
13699 NetLogEventType::HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
13700 NetLogEventPhase::NONE);
rsleevidb16bb02015-11-12 23:47:1713701
bnc691fda62016-08-12 00:43:1613702 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5213703 ASSERT_TRUE(response);
rsleevidb16bb02015-11-12 23:47:1713704
13705 EXPECT_TRUE(response->headers->IsKeepAlive());
13706 EXPECT_EQ(200, response->headers->response_code());
13707 EXPECT_EQ(100, response->headers->GetContentLength());
13708 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
13709 EXPECT_TRUE(response->was_fetched_via_proxy);
tbansal2ecbbc72016-10-06 17:15:4713710 EXPECT_EQ(ProxyServer(ProxyServer::SCHEME_HTTP,
13711 HostPortPair::FromString("myproxy:70")),
13712 response->proxy_server);
rsleevidb16bb02015-11-12 23:47:1713713
13714 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:1613715 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
rsleevidb16bb02015-11-12 23:47:1713716 TestLoadTimingNotReusedWithPac(load_timing_info,
13717 CONNECT_TIMING_HAS_SSL_TIMES);
13718}
13719
[email protected]76a505b2010-08-25 06:23:0013720// Test a basic HTTPS GET request through a proxy, but the server hangs up
13721// while establishing the tunnel.
bncd16676a2016-07-20 16:23:0113722TEST_F(HttpNetworkTransactionTest, ProxyTunnelGetHangup) {
Lily Houghton8c2f97d2018-01-22 05:06:5913723 session_deps_.proxy_resolution_service =
13724 ProxyResolutionService::CreateFixed("myproxy:70");
vishal.b62985ca92015-04-17 08:45:5113725 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:0713726 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:0913727 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]76a505b2010-08-25 06:23:0013728
[email protected]76a505b2010-08-25 06:23:0013729 HttpRequestInfo request;
13730 request.method = "GET";
bncce36dca22015-04-21 22:11:2313731 request.url = GURL("https://www.example.org/");
[email protected]76a505b2010-08-25 06:23:0013732
13733 // Since we have proxy, should try to establish tunnel.
13734 MockWrite data_writes1[] = {
rsleevidb16bb02015-11-12 23:47:1713735 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
13736 "Host: www.example.org:443\r\n"
13737 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]76a505b2010-08-25 06:23:0013738
rsleevidb16bb02015-11-12 23:47:1713739 MockWrite("GET / HTTP/1.1\r\n"
13740 "Host: www.example.org\r\n"
13741 "Connection: keep-alive\r\n\r\n"),
[email protected]76a505b2010-08-25 06:23:0013742 };
13743
13744 MockRead data_reads1[] = {
[email protected]76a505b2010-08-25 06:23:0013745 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:0613746 MockRead(ASYNC, 0, 0), // EOF
[email protected]76a505b2010-08-25 06:23:0013747 };
13748
13749 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
13750 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:0713751 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8ddf8322012-02-23 18:08:0613752 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:0713753 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]76a505b2010-08-25 06:23:0013754
[email protected]49639fa2011-12-20 23:22:4113755 TestCompletionCallback callback1;
[email protected]76a505b2010-08-25 06:23:0013756
bnc691fda62016-08-12 00:43:1613757 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]0b0bf032010-09-21 18:08:5013758
bnc691fda62016-08-12 00:43:1613759 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:0113760 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]76a505b2010-08-25 06:23:0013761
13762 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:0113763 EXPECT_THAT(rv, IsError(ERR_EMPTY_RESPONSE));
mmenke43758e62015-05-04 21:09:4613764 TestNetLogEntry::List entries;
[email protected]b2fcd0e2010-12-01 15:19:4013765 log.GetEntries(&entries);
[email protected]76a505b2010-08-25 06:23:0013766 size_t pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:0013767 entries, 0, NetLogEventType::HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
13768 NetLogEventPhase::NONE);
[email protected]76a505b2010-08-25 06:23:0013769 ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:4013770 entries, pos,
mikecirone8b85c432016-09-08 19:11:0013771 NetLogEventType::HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
13772 NetLogEventPhase::NONE);
[email protected]76a505b2010-08-25 06:23:0013773}
13774
[email protected]749eefa82010-09-13 22:14:0313775// Test for crbug.com/55424.
bncd16676a2016-07-20 16:23:0113776TEST_F(HttpNetworkTransactionTest, PreconnectWithExistingSpdySession) {
bncdf80d44fd2016-07-15 20:27:4113777 SpdySerializedFrame req(
bnc38dcd392016-02-09 23:19:4913778 spdy_util_.ConstructSpdyGet("https://www.example.org", 1, LOWEST));
bncdf80d44fd2016-07-15 20:27:4113779 MockWrite spdy_writes[] = {CreateMockWrite(req, 0)};
[email protected]749eefa82010-09-13 22:14:0313780
bnc42331402016-07-25 13:36:1513781 SpdySerializedFrame resp(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
bncdf80d44fd2016-07-15 20:27:4113782 SpdySerializedFrame data(spdy_util_.ConstructSpdyDataFrame(1, true));
[email protected]749eefa82010-09-13 22:14:0313783 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:4113784 CreateMockRead(resp, 1), CreateMockRead(data, 2), MockRead(ASYNC, 0, 3),
[email protected]749eefa82010-09-13 22:14:0313785 };
13786
rch8e6c6c42015-05-01 14:05:1313787 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
13788 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:0713789 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]749eefa82010-09-13 22:14:0313790
[email protected]8ddf8322012-02-23 18:08:0613791 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3613792 ssl.next_proto = kProtoHTTP2;
[email protected]bb88e1d32013-05-03 23:11:0713793 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]749eefa82010-09-13 22:14:0313794
danakj1fd259a02016-04-16 03:17:0913795 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]749eefa82010-09-13 22:14:0313796
13797 // Set up an initial SpdySession in the pool to reuse.
bncce36dca22015-04-21 22:11:2313798 HostPortPair host_port_pair("www.example.org", 443);
[email protected]e6d017652013-05-17 18:01:4013799 SpdySessionKey key(host_port_pair, ProxyServer::Direct(),
Paul Jensena457017a2018-01-19 23:52:0413800 PRIVACY_MODE_DISABLED, SocketTag());
[email protected]795cbf82013-07-22 09:37:2713801 base::WeakPtr<SpdySession> spdy_session =
Bence Béky0ef1556e2017-06-30 19:52:5213802 CreateSpdySession(session.get(), key, NetLogWithSource());
[email protected]749eefa82010-09-13 22:14:0313803
13804 HttpRequestInfo request;
13805 request.method = "GET";
bncce36dca22015-04-21 22:11:2313806 request.url = GURL("https://www.example.org/");
[email protected]749eefa82010-09-13 22:14:0313807
13808 // This is the important line that marks this as a preconnect.
13809 request.motivation = HttpRequestInfo::PRECONNECT_MOTIVATED;
13810
bnc691fda62016-08-12 00:43:1613811 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]749eefa82010-09-13 22:14:0313812
[email protected]41d64e82013-07-03 22:44:2613813 TestCompletionCallback callback;
tfarina42834112016-09-22 13:38:2013814 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0113815 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
13816 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]749eefa82010-09-13 22:14:0313817}
13818
[email protected]73b8dd222010-11-11 19:55:2413819// Given a net error, cause that error to be returned from the first Write()
bnc691fda62016-08-12 00:43:1613820// call and verify that the HttpNetworkTransaction fails with that error.
[email protected]23e482282013-06-14 16:08:0213821void HttpNetworkTransactionTest::CheckErrorIsPassedBack(
[email protected]bb88e1d32013-05-03 23:11:0713822 int error, IoMode mode) {
ttuttle859dc7a2015-04-23 19:42:2913823 HttpRequestInfo request_info;
[email protected]cb9bf6ca2011-01-28 13:15:2713824 request_info.url = GURL("https://www.example.com/");
13825 request_info.method = "GET";
ttuttle859dc7a2015-04-23 19:42:2913826 request_info.load_flags = LOAD_NORMAL;
[email protected]cb9bf6ca2011-01-28 13:15:2713827
[email protected]8ddf8322012-02-23 18:08:0613828 SSLSocketDataProvider ssl_data(mode, OK);
ttuttle859dc7a2015-04-23 19:42:2913829 MockWrite data_writes[] = {
13830 MockWrite(mode, error),
[email protected]73b8dd222010-11-11 19:55:2413831 };
ttuttle859dc7a2015-04-23 19:42:2913832 StaticSocketDataProvider data(NULL, 0, data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:0713833 session_deps_.socket_factory->AddSocketDataProvider(&data);
13834 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data);
[email protected]73b8dd222010-11-11 19:55:2413835
danakj1fd259a02016-04-16 03:17:0913836 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1613837 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]73b8dd222010-11-11 19:55:2413838
[email protected]49639fa2011-12-20 23:22:4113839 TestCompletionCallback callback;
tfarina42834112016-09-22 13:38:2013840 int rv = trans.Start(&request_info, callback.callback(), NetLogWithSource());
ttuttle859dc7a2015-04-23 19:42:2913841 if (rv == ERR_IO_PENDING)
[email protected]73b8dd222010-11-11 19:55:2413842 rv = callback.WaitForResult();
13843 ASSERT_EQ(error, rv);
13844}
13845
bncd16676a2016-07-20 16:23:0113846TEST_F(HttpNetworkTransactionTest, SSLWriteCertError) {
[email protected]73b8dd222010-11-11 19:55:2413847 // Just check a grab bag of cert errors.
13848 static const int kErrors[] = {
13849 ERR_CERT_COMMON_NAME_INVALID,
13850 ERR_CERT_AUTHORITY_INVALID,
13851 ERR_CERT_DATE_INVALID,
13852 };
13853 for (size_t i = 0; i < arraysize(kErrors); i++) {
[email protected]8ddf8322012-02-23 18:08:0613854 CheckErrorIsPassedBack(kErrors[i], ASYNC);
13855 CheckErrorIsPassedBack(kErrors[i], SYNCHRONOUS);
[email protected]73b8dd222010-11-11 19:55:2413856 }
13857}
13858
[email protected]bd0b6772011-01-11 19:59:3013859// Ensure that a client certificate is removed from the SSL client auth
13860// cache when:
13861// 1) No proxy is involved.
13862// 2) TLS False Start is disabled.
13863// 3) The initial TLS handshake requests a client certificate.
13864// 4) The client supplies an invalid/unacceptable certificate.
bncd16676a2016-07-20 16:23:0113865TEST_F(HttpNetworkTransactionTest, ClientAuthCertCache_Direct_NoFalseStart) {
ttuttle859dc7a2015-04-23 19:42:2913866 HttpRequestInfo request_info;
[email protected]cb9bf6ca2011-01-28 13:15:2713867 request_info.url = GURL("https://www.example.com/");
13868 request_info.method = "GET";
ttuttle859dc7a2015-04-23 19:42:2913869 request_info.load_flags = LOAD_NORMAL;
[email protected]cb9bf6ca2011-01-28 13:15:2713870
[email protected]bd0b6772011-01-11 19:59:3013871 scoped_refptr<SSLCertRequestInfo> cert_request(new SSLCertRequestInfo());
[email protected]791879c2013-12-17 07:22:4113872 cert_request->host_and_port = HostPortPair("www.example.com", 443);
[email protected]bd0b6772011-01-11 19:59:3013873
13874 // [ssl_]data1 contains the data for the first SSL handshake. When a
13875 // CertificateRequest is received for the first time, the handshake will
13876 // be aborted to allow the caller to provide a certificate.
ttuttle859dc7a2015-04-23 19:42:2913877 SSLSocketDataProvider ssl_data1(ASYNC, ERR_SSL_CLIENT_AUTH_CERT_NEEDED);
[email protected]bd0b6772011-01-11 19:59:3013878 ssl_data1.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0713879 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data1);
ttuttle859dc7a2015-04-23 19:42:2913880 StaticSocketDataProvider data1(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0713881 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]bd0b6772011-01-11 19:59:3013882
13883 // [ssl_]data2 contains the data for the second SSL handshake. When TLS
13884 // False Start is not being used, the result of the SSL handshake will be
13885 // returned as part of the SSLClientSocket::Connect() call. This test
13886 // matches the result of a server sending a handshake_failure alert,
13887 // rather than a Finished message, because it requires a client
13888 // certificate and none was supplied.
ttuttle859dc7a2015-04-23 19:42:2913889 SSLSocketDataProvider ssl_data2(ASYNC, ERR_SSL_PROTOCOL_ERROR);
[email protected]bd0b6772011-01-11 19:59:3013890 ssl_data2.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0713891 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data2);
ttuttle859dc7a2015-04-23 19:42:2913892 StaticSocketDataProvider data2(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0713893 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]bd0b6772011-01-11 19:59:3013894
13895 // [ssl_]data3 contains the data for the third SSL handshake. When a
13896 // connection to a server fails during an SSL handshake,
davidbenb937d6c2015-05-14 04:53:4213897 // HttpNetworkTransaction will attempt to fallback to TLSv1.1 if the previous
13898 // connection was attempted with TLSv1.2. This is transparent to the caller
[email protected]bd0b6772011-01-11 19:59:3013899 // of the HttpNetworkTransaction. Because this test failure is due to
13900 // requiring a client certificate, this fallback handshake should also
13901 // fail.
ttuttle859dc7a2015-04-23 19:42:2913902 SSLSocketDataProvider ssl_data3(ASYNC, ERR_SSL_PROTOCOL_ERROR);
[email protected]bd0b6772011-01-11 19:59:3013903 ssl_data3.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0713904 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data3);
ttuttle859dc7a2015-04-23 19:42:2913905 StaticSocketDataProvider data3(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0713906 session_deps_.socket_factory->AddSocketDataProvider(&data3);
[email protected]bd0b6772011-01-11 19:59:3013907
[email protected]80c75f682012-05-26 16:22:1713908 // [ssl_]data4 contains the data for the fourth SSL handshake. When a
13909 // connection to a server fails during an SSL handshake,
davidbenb937d6c2015-05-14 04:53:4213910 // HttpNetworkTransaction will attempt to fallback to TLSv1 if the previous
13911 // connection was attempted with TLSv1.1. This is transparent to the caller
[email protected]80c75f682012-05-26 16:22:1713912 // of the HttpNetworkTransaction. Because this test failure is due to
13913 // requiring a client certificate, this fallback handshake should also
13914 // fail.
ttuttle859dc7a2015-04-23 19:42:2913915 SSLSocketDataProvider ssl_data4(ASYNC, ERR_SSL_PROTOCOL_ERROR);
[email protected]80c75f682012-05-26 16:22:1713916 ssl_data4.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0713917 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data4);
ttuttle859dc7a2015-04-23 19:42:2913918 StaticSocketDataProvider data4(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0713919 session_deps_.socket_factory->AddSocketDataProvider(&data4);
[email protected]80c75f682012-05-26 16:22:1713920
danakj1fd259a02016-04-16 03:17:0913921 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1613922 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]bd0b6772011-01-11 19:59:3013923
[email protected]bd0b6772011-01-11 19:59:3013924 // Begin the SSL handshake with the peer. This consumes ssl_data1.
[email protected]49639fa2011-12-20 23:22:4113925 TestCompletionCallback callback;
tfarina42834112016-09-22 13:38:2013926 int rv = trans.Start(&request_info, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0113927 ASSERT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]bd0b6772011-01-11 19:59:3013928
13929 // Complete the SSL handshake, which should abort due to requiring a
13930 // client certificate.
13931 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0113932 ASSERT_THAT(rv, IsError(ERR_SSL_CLIENT_AUTH_CERT_NEEDED));
[email protected]bd0b6772011-01-11 19:59:3013933
13934 // Indicate that no certificate should be supplied. From the perspective
13935 // of SSLClientCertCache, NULL is just as meaningful as a real
13936 // certificate, so this is the same as supply a
13937 // legitimate-but-unacceptable certificate.
bnc691fda62016-08-12 00:43:1613938 rv = trans.RestartWithCertificate(NULL, NULL, callback.callback());
robpercival214763f2016-07-01 23:27:0113939 ASSERT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]bd0b6772011-01-11 19:59:3013940
13941 // Ensure the certificate was added to the client auth cache before
13942 // allowing the connection to continue restarting.
13943 scoped_refptr<X509Certificate> client_cert;
svaldez7872fd02015-11-19 21:10:5413944 scoped_refptr<SSLPrivateKey> client_private_key;
[email protected]791879c2013-12-17 07:22:4113945 ASSERT_TRUE(session->ssl_client_auth_cache()->Lookup(
svaldez7872fd02015-11-19 21:10:5413946 HostPortPair("www.example.com", 443), &client_cert, &client_private_key));
wezca1070932016-05-26 20:30:5213947 ASSERT_FALSE(client_cert);
[email protected]bd0b6772011-01-11 19:59:3013948
13949 // Restart the handshake. This will consume ssl_data2, which fails, and
[email protected]80c75f682012-05-26 16:22:1713950 // then consume ssl_data3 and ssl_data4, both of which should also fail.
13951 // The result code is checked against what ssl_data4 should return.
[email protected]bd0b6772011-01-11 19:59:3013952 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0113953 ASSERT_THAT(rv, IsError(ERR_SSL_PROTOCOL_ERROR));
[email protected]bd0b6772011-01-11 19:59:3013954
13955 // Ensure that the client certificate is removed from the cache on a
13956 // handshake failure.
[email protected]791879c2013-12-17 07:22:4113957 ASSERT_FALSE(session->ssl_client_auth_cache()->Lookup(
svaldez7872fd02015-11-19 21:10:5413958 HostPortPair("www.example.com", 443), &client_cert, &client_private_key));
[email protected]bd0b6772011-01-11 19:59:3013959}
13960
13961// Ensure that a client certificate is removed from the SSL client auth
13962// cache when:
13963// 1) No proxy is involved.
13964// 2) TLS False Start is enabled.
13965// 3) The initial TLS handshake requests a client certificate.
13966// 4) The client supplies an invalid/unacceptable certificate.
bncd16676a2016-07-20 16:23:0113967TEST_F(HttpNetworkTransactionTest, ClientAuthCertCache_Direct_FalseStart) {
ttuttle859dc7a2015-04-23 19:42:2913968 HttpRequestInfo request_info;
[email protected]cb9bf6ca2011-01-28 13:15:2713969 request_info.url = GURL("https://www.example.com/");
13970 request_info.method = "GET";
ttuttle859dc7a2015-04-23 19:42:2913971 request_info.load_flags = LOAD_NORMAL;
[email protected]cb9bf6ca2011-01-28 13:15:2713972
[email protected]bd0b6772011-01-11 19:59:3013973 scoped_refptr<SSLCertRequestInfo> cert_request(new SSLCertRequestInfo());
[email protected]791879c2013-12-17 07:22:4113974 cert_request->host_and_port = HostPortPair("www.example.com", 443);
[email protected]bd0b6772011-01-11 19:59:3013975
13976 // When TLS False Start is used, SSLClientSocket::Connect() calls will
13977 // return successfully after reading up to the peer's Certificate message.
13978 // This is to allow the caller to call SSLClientSocket::Write(), which can
13979 // enqueue application data to be sent in the same packet as the
13980 // ChangeCipherSpec and Finished messages.
13981 // The actual handshake will be finished when SSLClientSocket::Read() is
13982 // called, which expects to process the peer's ChangeCipherSpec and
13983 // Finished messages. If there was an error negotiating with the peer,
13984 // such as due to the peer requiring a client certificate when none was
13985 // supplied, the alert sent by the peer won't be processed until Read() is
13986 // called.
13987
13988 // Like the non-False Start case, when a client certificate is requested by
13989 // the peer, the handshake is aborted during the Connect() call.
13990 // [ssl_]data1 represents the initial SSL handshake with the peer.
ttuttle859dc7a2015-04-23 19:42:2913991 SSLSocketDataProvider ssl_data1(ASYNC, ERR_SSL_CLIENT_AUTH_CERT_NEEDED);
[email protected]bd0b6772011-01-11 19:59:3013992 ssl_data1.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0713993 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data1);
ttuttle859dc7a2015-04-23 19:42:2913994 StaticSocketDataProvider data1(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0713995 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]bd0b6772011-01-11 19:59:3013996
13997 // When a client certificate is supplied, Connect() will not be aborted
13998 // when the peer requests the certificate. Instead, the handshake will
13999 // artificially succeed, allowing the caller to write the HTTP request to
14000 // the socket. The handshake messages are not processed until Read() is
14001 // called, which then detects that the handshake was aborted, due to the
14002 // peer sending a handshake_failure because it requires a client
14003 // certificate.
ttuttle859dc7a2015-04-23 19:42:2914004 SSLSocketDataProvider ssl_data2(ASYNC, OK);
[email protected]bd0b6772011-01-11 19:59:3014005 ssl_data2.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0714006 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data2);
ttuttle859dc7a2015-04-23 19:42:2914007 MockRead data2_reads[] = {
14008 MockRead(ASYNC /* async */, ERR_SSL_PROTOCOL_ERROR),
[email protected]bd0b6772011-01-11 19:59:3014009 };
ttuttle859dc7a2015-04-23 19:42:2914010 StaticSocketDataProvider data2(data2_reads, arraysize(data2_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0714011 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]bd0b6772011-01-11 19:59:3014012
14013 // As described in ClientAuthCertCache_Direct_NoFalseStart, [ssl_]data3 is
[email protected]80c75f682012-05-26 16:22:1714014 // the data for the SSL handshake once the TLSv1.1 connection falls back to
14015 // TLSv1. It has the same behaviour as [ssl_]data2.
ttuttle859dc7a2015-04-23 19:42:2914016 SSLSocketDataProvider ssl_data3(ASYNC, OK);
[email protected]bd0b6772011-01-11 19:59:3014017 ssl_data3.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0714018 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data3);
ttuttle859dc7a2015-04-23 19:42:2914019 StaticSocketDataProvider data3(data2_reads, arraysize(data2_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0714020 session_deps_.socket_factory->AddSocketDataProvider(&data3);
[email protected]bd0b6772011-01-11 19:59:3014021
[email protected]80c75f682012-05-26 16:22:1714022 // [ssl_]data4 is the data for the SSL handshake once the TLSv1 connection
14023 // falls back to SSLv3. It has the same behaviour as [ssl_]data2.
ttuttle859dc7a2015-04-23 19:42:2914024 SSLSocketDataProvider ssl_data4(ASYNC, OK);
[email protected]80c75f682012-05-26 16:22:1714025 ssl_data4.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0714026 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data4);
ttuttle859dc7a2015-04-23 19:42:2914027 StaticSocketDataProvider data4(data2_reads, arraysize(data2_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0714028 session_deps_.socket_factory->AddSocketDataProvider(&data4);
[email protected]80c75f682012-05-26 16:22:1714029
[email protected]7799de12013-05-30 05:52:5114030 // Need one more if TLSv1.2 is enabled.
ttuttle859dc7a2015-04-23 19:42:2914031 SSLSocketDataProvider ssl_data5(ASYNC, OK);
[email protected]7799de12013-05-30 05:52:5114032 ssl_data5.cert_request_info = cert_request.get();
14033 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data5);
ttuttle859dc7a2015-04-23 19:42:2914034 StaticSocketDataProvider data5(data2_reads, arraysize(data2_reads), NULL, 0);
[email protected]7799de12013-05-30 05:52:5114035 session_deps_.socket_factory->AddSocketDataProvider(&data5);
14036
danakj1fd259a02016-04-16 03:17:0914037 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1614038 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]bd0b6772011-01-11 19:59:3014039
[email protected]bd0b6772011-01-11 19:59:3014040 // Begin the initial SSL handshake.
[email protected]49639fa2011-12-20 23:22:4114041 TestCompletionCallback callback;
tfarina42834112016-09-22 13:38:2014042 int rv = trans.Start(&request_info, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0114043 ASSERT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]bd0b6772011-01-11 19:59:3014044
14045 // Complete the SSL handshake, which should abort due to requiring a
14046 // client certificate.
14047 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0114048 ASSERT_THAT(rv, IsError(ERR_SSL_CLIENT_AUTH_CERT_NEEDED));
[email protected]bd0b6772011-01-11 19:59:3014049
14050 // Indicate that no certificate should be supplied. From the perspective
14051 // of SSLClientCertCache, NULL is just as meaningful as a real
14052 // certificate, so this is the same as supply a
14053 // legitimate-but-unacceptable certificate.
bnc691fda62016-08-12 00:43:1614054 rv = trans.RestartWithCertificate(NULL, NULL, callback.callback());
robpercival214763f2016-07-01 23:27:0114055 ASSERT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]bd0b6772011-01-11 19:59:3014056
14057 // Ensure the certificate was added to the client auth cache before
14058 // allowing the connection to continue restarting.
14059 scoped_refptr<X509Certificate> client_cert;
svaldez7872fd02015-11-19 21:10:5414060 scoped_refptr<SSLPrivateKey> client_private_key;
[email protected]791879c2013-12-17 07:22:4114061 ASSERT_TRUE(session->ssl_client_auth_cache()->Lookup(
svaldez7872fd02015-11-19 21:10:5414062 HostPortPair("www.example.com", 443), &client_cert, &client_private_key));
wezca1070932016-05-26 20:30:5214063 ASSERT_FALSE(client_cert);
[email protected]bd0b6772011-01-11 19:59:3014064
[email protected]bd0b6772011-01-11 19:59:3014065 // Restart the handshake. This will consume ssl_data2, which fails, and
[email protected]80c75f682012-05-26 16:22:1714066 // then consume ssl_data3 and ssl_data4, both of which should also fail.
14067 // The result code is checked against what ssl_data4 should return.
[email protected]bd0b6772011-01-11 19:59:3014068 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0114069 ASSERT_THAT(rv, IsError(ERR_SSL_PROTOCOL_ERROR));
[email protected]bd0b6772011-01-11 19:59:3014070
14071 // Ensure that the client certificate is removed from the cache on a
14072 // handshake failure.
[email protected]791879c2013-12-17 07:22:4114073 ASSERT_FALSE(session->ssl_client_auth_cache()->Lookup(
svaldez7872fd02015-11-19 21:10:5414074 HostPortPair("www.example.com", 443), &client_cert, &client_private_key));
[email protected]bd0b6772011-01-11 19:59:3014075}
14076
[email protected]8c405132011-01-11 22:03:1814077// Ensure that a client certificate is removed from the SSL client auth
14078// cache when:
14079// 1) An HTTPS proxy is involved.
14080// 3) The HTTPS proxy requests a client certificate.
14081// 4) The client supplies an invalid/unacceptable certificate for the
14082// proxy.
14083// The test is repeated twice, first for connecting to an HTTPS endpoint,
14084// then for connecting to an HTTP endpoint.
bncd16676a2016-07-20 16:23:0114085TEST_F(HttpNetworkTransactionTest, ClientAuthCertCache_Proxy_Fail) {
Lily Houghton8c2f97d2018-01-22 05:06:5914086 session_deps_.proxy_resolution_service =
14087 ProxyResolutionService::CreateFixed("https://proxy:70");
vishal.b62985ca92015-04-17 08:45:5114088 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:0714089 session_deps_.net_log = log.bound().net_log();
[email protected]8c405132011-01-11 22:03:1814090
14091 scoped_refptr<SSLCertRequestInfo> cert_request(new SSLCertRequestInfo());
[email protected]791879c2013-12-17 07:22:4114092 cert_request->host_and_port = HostPortPair("proxy", 70);
[email protected]8c405132011-01-11 22:03:1814093
14094 // See ClientAuthCertCache_Direct_NoFalseStart for the explanation of
14095 // [ssl_]data[1-3]. Rather than represending the endpoint
14096 // (www.example.com:443), they represent failures with the HTTPS proxy
14097 // (proxy:70).
ttuttle859dc7a2015-04-23 19:42:2914098 SSLSocketDataProvider ssl_data1(ASYNC, ERR_SSL_CLIENT_AUTH_CERT_NEEDED);
[email protected]8c405132011-01-11 22:03:1814099 ssl_data1.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0714100 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data1);
ttuttle859dc7a2015-04-23 19:42:2914101 StaticSocketDataProvider data1(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0714102 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8c405132011-01-11 22:03:1814103
ttuttle859dc7a2015-04-23 19:42:2914104 SSLSocketDataProvider ssl_data2(ASYNC, ERR_SSL_PROTOCOL_ERROR);
[email protected]8c405132011-01-11 22:03:1814105 ssl_data2.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0714106 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data2);
ttuttle859dc7a2015-04-23 19:42:2914107 StaticSocketDataProvider data2(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0714108 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]8c405132011-01-11 22:03:1814109
[email protected]80c75f682012-05-26 16:22:1714110 // TODO(wtc): find out why this unit test doesn't need [ssl_]data3.
14111#if 0
ttuttle859dc7a2015-04-23 19:42:2914112 SSLSocketDataProvider ssl_data3(ASYNC, ERR_SSL_PROTOCOL_ERROR);
[email protected]8c405132011-01-11 22:03:1814113 ssl_data3.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0714114 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data3);
ttuttle859dc7a2015-04-23 19:42:2914115 StaticSocketDataProvider data3(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0714116 session_deps_.socket_factory->AddSocketDataProvider(&data3);
[email protected]80c75f682012-05-26 16:22:1714117#endif
[email protected]8c405132011-01-11 22:03:1814118
ttuttle859dc7a2015-04-23 19:42:2914119 HttpRequestInfo requests[2];
[email protected]8c405132011-01-11 22:03:1814120 requests[0].url = GURL("https://www.example.com/");
14121 requests[0].method = "GET";
ttuttle859dc7a2015-04-23 19:42:2914122 requests[0].load_flags = LOAD_NORMAL;
[email protected]8c405132011-01-11 22:03:1814123
14124 requests[1].url = GURL("http://www.example.com/");
14125 requests[1].method = "GET";
ttuttle859dc7a2015-04-23 19:42:2914126 requests[1].load_flags = LOAD_NORMAL;
[email protected]8c405132011-01-11 22:03:1814127
14128 for (size_t i = 0; i < arraysize(requests); ++i) {
[email protected]bb88e1d32013-05-03 23:11:0714129 session_deps_.socket_factory->ResetNextMockIndexes();
danakj1fd259a02016-04-16 03:17:0914130 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1614131 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]8c405132011-01-11 22:03:1814132
14133 // Begin the SSL handshake with the proxy.
[email protected]49639fa2011-12-20 23:22:4114134 TestCompletionCallback callback;
tfarina42834112016-09-22 13:38:2014135 int rv = trans.Start(&requests[i], callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0114136 ASSERT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]8c405132011-01-11 22:03:1814137
14138 // Complete the SSL handshake, which should abort due to requiring a
14139 // client certificate.
14140 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0114141 ASSERT_THAT(rv, IsError(ERR_SSL_CLIENT_AUTH_CERT_NEEDED));
[email protected]8c405132011-01-11 22:03:1814142
14143 // Indicate that no certificate should be supplied. From the perspective
14144 // of SSLClientCertCache, NULL is just as meaningful as a real
14145 // certificate, so this is the same as supply a
14146 // legitimate-but-unacceptable certificate.
bnc691fda62016-08-12 00:43:1614147 rv = trans.RestartWithCertificate(NULL, NULL, callback.callback());
robpercival214763f2016-07-01 23:27:0114148 ASSERT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]8c405132011-01-11 22:03:1814149
14150 // Ensure the certificate was added to the client auth cache before
14151 // allowing the connection to continue restarting.
14152 scoped_refptr<X509Certificate> client_cert;
svaldez7872fd02015-11-19 21:10:5414153 scoped_refptr<SSLPrivateKey> client_private_key;
[email protected]791879c2013-12-17 07:22:4114154 ASSERT_TRUE(session->ssl_client_auth_cache()->Lookup(
svaldez7872fd02015-11-19 21:10:5414155 HostPortPair("proxy", 70), &client_cert, &client_private_key));
wezca1070932016-05-26 20:30:5214156 ASSERT_FALSE(client_cert);
[email protected]8c405132011-01-11 22:03:1814157 // Ensure the certificate was NOT cached for the endpoint. This only
14158 // applies to HTTPS requests, but is fine to check for HTTP requests.
[email protected]791879c2013-12-17 07:22:4114159 ASSERT_FALSE(session->ssl_client_auth_cache()->Lookup(
svaldez7872fd02015-11-19 21:10:5414160 HostPortPair("www.example.com", 443), &client_cert,
14161 &client_private_key));
[email protected]8c405132011-01-11 22:03:1814162
14163 // Restart the handshake. This will consume ssl_data2, which fails, and
14164 // then consume ssl_data3, which should also fail. The result code is
14165 // checked against what ssl_data3 should return.
14166 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0114167 ASSERT_THAT(rv, IsError(ERR_PROXY_CONNECTION_FAILED));
[email protected]8c405132011-01-11 22:03:1814168
14169 // Now that the new handshake has failed, ensure that the client
14170 // certificate was removed from the client auth cache.
[email protected]791879c2013-12-17 07:22:4114171 ASSERT_FALSE(session->ssl_client_auth_cache()->Lookup(
svaldez7872fd02015-11-19 21:10:5414172 HostPortPair("proxy", 70), &client_cert, &client_private_key));
[email protected]791879c2013-12-17 07:22:4114173 ASSERT_FALSE(session->ssl_client_auth_cache()->Lookup(
svaldez7872fd02015-11-19 21:10:5414174 HostPortPair("www.example.com", 443), &client_cert,
14175 &client_private_key));
[email protected]8c405132011-01-11 22:03:1814176 }
14177}
14178
bncd16676a2016-07-20 16:23:0114179TEST_F(HttpNetworkTransactionTest, UseIPConnectionPooling) {
[email protected]e3ceb682011-06-28 23:55:4614180 // Set up a special HttpNetworkSession with a MockCachingHostResolver.
Jeremy Roman0579ed62017-08-29 15:56:1914181 session_deps_.host_resolver = std::make_unique<MockCachingHostResolver>();
danakj1fd259a02016-04-16 03:17:0914182 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]e3ceb682011-06-28 23:55:4614183
bnc032658ba2016-09-26 18:17:1514184 AddSSLSocketData();
[email protected]e3ceb682011-06-28 23:55:4614185
bncdf80d44fd2016-07-15 20:27:4114186 SpdySerializedFrame host1_req(
bnc38dcd392016-02-09 23:19:4914187 spdy_util_.ConstructSpdyGet("https://www.example.org", 1, LOWEST));
rdsmithebb50aa2015-11-12 03:44:3814188 spdy_util_.UpdateWithStreamDestruction(1);
bncdf80d44fd2016-07-15 20:27:4114189 SpdySerializedFrame host2_req(
bnca4d611d2016-09-22 19:55:3714190 spdy_util_.ConstructSpdyGet("https://mail.example.com", 3, LOWEST));
[email protected]e3ceb682011-06-28 23:55:4614191 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:4114192 CreateMockWrite(host1_req, 0), CreateMockWrite(host2_req, 3),
[email protected]e3ceb682011-06-28 23:55:4614193 };
bnc42331402016-07-25 13:36:1514194 SpdySerializedFrame host1_resp(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
bncdf80d44fd2016-07-15 20:27:4114195 SpdySerializedFrame host1_resp_body(
14196 spdy_util_.ConstructSpdyDataFrame(1, true));
bnc42331402016-07-25 13:36:1514197 SpdySerializedFrame host2_resp(spdy_util_.ConstructSpdyGetReply(NULL, 0, 3));
bncdf80d44fd2016-07-15 20:27:4114198 SpdySerializedFrame host2_resp_body(
14199 spdy_util_.ConstructSpdyDataFrame(3, true));
[email protected]e3ceb682011-06-28 23:55:4614200 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:4114201 CreateMockRead(host1_resp, 1), CreateMockRead(host1_resp_body, 2),
14202 CreateMockRead(host2_resp, 4), CreateMockRead(host2_resp_body, 5),
rch8e6c6c42015-05-01 14:05:1314203 MockRead(ASYNC, 0, 6),
[email protected]e3ceb682011-06-28 23:55:4614204 };
14205
eroman36d84e54432016-03-17 03:23:0214206 IPEndPoint peer_addr(IPAddress::IPv4Localhost(), 443);
[email protected]d2b5f092012-06-08 23:55:0214207 MockConnect connect(ASYNC, OK, peer_addr);
rch8e6c6c42015-05-01 14:05:1314208 SequencedSocketData spdy_data(connect, spdy_reads, arraysize(spdy_reads),
14209 spdy_writes, arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:0714210 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]e3ceb682011-06-28 23:55:4614211
[email protected]aa22b242011-11-16 18:58:2914212 TestCompletionCallback callback;
[email protected]e3ceb682011-06-28 23:55:4614213 HttpRequestInfo request1;
14214 request1.method = "GET";
bncce36dca22015-04-21 22:11:2314215 request1.url = GURL("https://www.example.org/");
[email protected]e3ceb682011-06-28 23:55:4614216 request1.load_flags = 0;
[email protected]90499482013-06-01 00:39:5014217 HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
[email protected]e3ceb682011-06-28 23:55:4614218
tfarina42834112016-09-22 13:38:2014219 int rv = trans1.Start(&request1, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0114220 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
14221 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]e3ceb682011-06-28 23:55:4614222
14223 const HttpResponseInfo* response = trans1.GetResponseInfo();
wezca1070932016-05-26 20:30:5214224 ASSERT_TRUE(response);
14225 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0214226 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]e3ceb682011-06-28 23:55:4614227
14228 std::string response_data;
robpercival214763f2016-07-01 23:27:0114229 ASSERT_THAT(ReadTransaction(&trans1, &response_data), IsOk());
[email protected]e3ceb682011-06-28 23:55:4614230 EXPECT_EQ("hello!", response_data);
14231
bnca4d611d2016-09-22 19:55:3714232 // Preload mail.example.com into HostCache.
14233 HostPortPair host_port("mail.example.com", 443);
[email protected]5109c1952013-08-20 18:44:1014234 HostResolver::RequestInfo resolve_info(host_port);
[email protected]e3ceb682011-06-28 23:55:4614235 AddressList ignored;
maksim.sisov31452af2016-07-27 06:38:1014236 std::unique_ptr<HostResolver::Request> request;
14237 rv = session_deps_.host_resolver->Resolve(resolve_info, DEFAULT_PRIORITY,
14238 &ignored, callback.callback(),
tfarina42834112016-09-22 13:38:2014239 &request, NetLogWithSource());
robpercival214763f2016-07-01 23:27:0114240 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]6e78dfb2011-07-28 21:34:4714241 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0114242 EXPECT_THAT(rv, IsOk());
[email protected]e3ceb682011-06-28 23:55:4614243
14244 HttpRequestInfo request2;
14245 request2.method = "GET";
bnca4d611d2016-09-22 19:55:3714246 request2.url = GURL("https://mail.example.com/");
[email protected]e3ceb682011-06-28 23:55:4614247 request2.load_flags = 0;
[email protected]90499482013-06-01 00:39:5014248 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
[email protected]e3ceb682011-06-28 23:55:4614249
tfarina42834112016-09-22 13:38:2014250 rv = trans2.Start(&request2, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0114251 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
14252 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]e3ceb682011-06-28 23:55:4614253
14254 response = trans2.GetResponseInfo();
wezca1070932016-05-26 20:30:5214255 ASSERT_TRUE(response);
14256 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0214257 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]e3ceb682011-06-28 23:55:4614258 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5214259 EXPECT_TRUE(response->was_alpn_negotiated);
robpercival214763f2016-07-01 23:27:0114260 ASSERT_THAT(ReadTransaction(&trans2, &response_data), IsOk());
[email protected]e3ceb682011-06-28 23:55:4614261 EXPECT_EQ("hello!", response_data);
[email protected]e3ceb682011-06-28 23:55:4614262}
14263
bncd16676a2016-07-20 16:23:0114264TEST_F(HttpNetworkTransactionTest, UseIPConnectionPoolingAfterResolution) {
[email protected]d2b5f092012-06-08 23:55:0214265 // Set up a special HttpNetworkSession with a MockCachingHostResolver.
Jeremy Roman0579ed62017-08-29 15:56:1914266 session_deps_.host_resolver = std::make_unique<MockCachingHostResolver>();
danakj1fd259a02016-04-16 03:17:0914267 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]d2b5f092012-06-08 23:55:0214268
bnc032658ba2016-09-26 18:17:1514269 AddSSLSocketData();
[email protected]d2b5f092012-06-08 23:55:0214270
bncdf80d44fd2016-07-15 20:27:4114271 SpdySerializedFrame host1_req(
bnc38dcd392016-02-09 23:19:4914272 spdy_util_.ConstructSpdyGet("https://www.example.org", 1, LOWEST));
rdsmithebb50aa2015-11-12 03:44:3814273 spdy_util_.UpdateWithStreamDestruction(1);
bncdf80d44fd2016-07-15 20:27:4114274 SpdySerializedFrame host2_req(
bnca4d611d2016-09-22 19:55:3714275 spdy_util_.ConstructSpdyGet("https://mail.example.com", 3, LOWEST));
[email protected]d2b5f092012-06-08 23:55:0214276 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:4114277 CreateMockWrite(host1_req, 0), CreateMockWrite(host2_req, 3),
[email protected]d2b5f092012-06-08 23:55:0214278 };
bnc42331402016-07-25 13:36:1514279 SpdySerializedFrame host1_resp(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
bncdf80d44fd2016-07-15 20:27:4114280 SpdySerializedFrame host1_resp_body(
14281 spdy_util_.ConstructSpdyDataFrame(1, true));
bnc42331402016-07-25 13:36:1514282 SpdySerializedFrame host2_resp(spdy_util_.ConstructSpdyGetReply(NULL, 0, 3));
bncdf80d44fd2016-07-15 20:27:4114283 SpdySerializedFrame host2_resp_body(
14284 spdy_util_.ConstructSpdyDataFrame(3, true));
[email protected]d2b5f092012-06-08 23:55:0214285 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:4114286 CreateMockRead(host1_resp, 1), CreateMockRead(host1_resp_body, 2),
14287 CreateMockRead(host2_resp, 4), CreateMockRead(host2_resp_body, 5),
rch8e6c6c42015-05-01 14:05:1314288 MockRead(ASYNC, 0, 6),
[email protected]d2b5f092012-06-08 23:55:0214289 };
14290
eroman36d84e54432016-03-17 03:23:0214291 IPEndPoint peer_addr(IPAddress::IPv4Localhost(), 443);
[email protected]d2b5f092012-06-08 23:55:0214292 MockConnect connect(ASYNC, OK, peer_addr);
rch8e6c6c42015-05-01 14:05:1314293 SequencedSocketData spdy_data(connect, spdy_reads, arraysize(spdy_reads),
14294 spdy_writes, arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:0714295 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]d2b5f092012-06-08 23:55:0214296
14297 TestCompletionCallback callback;
14298 HttpRequestInfo request1;
14299 request1.method = "GET";
bncce36dca22015-04-21 22:11:2314300 request1.url = GURL("https://www.example.org/");
[email protected]d2b5f092012-06-08 23:55:0214301 request1.load_flags = 0;
[email protected]90499482013-06-01 00:39:5014302 HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
[email protected]d2b5f092012-06-08 23:55:0214303
tfarina42834112016-09-22 13:38:2014304 int rv = trans1.Start(&request1, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0114305 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
14306 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]d2b5f092012-06-08 23:55:0214307
14308 const HttpResponseInfo* response = trans1.GetResponseInfo();
wezca1070932016-05-26 20:30:5214309 ASSERT_TRUE(response);
14310 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0214311 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]d2b5f092012-06-08 23:55:0214312
14313 std::string response_data;
robpercival214763f2016-07-01 23:27:0114314 ASSERT_THAT(ReadTransaction(&trans1, &response_data), IsOk());
[email protected]d2b5f092012-06-08 23:55:0214315 EXPECT_EQ("hello!", response_data);
14316
14317 HttpRequestInfo request2;
14318 request2.method = "GET";
bnca4d611d2016-09-22 19:55:3714319 request2.url = GURL("https://mail.example.com/");
[email protected]d2b5f092012-06-08 23:55:0214320 request2.load_flags = 0;
[email protected]90499482013-06-01 00:39:5014321 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
[email protected]d2b5f092012-06-08 23:55:0214322
tfarina42834112016-09-22 13:38:2014323 rv = trans2.Start(&request2, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0114324 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
14325 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]d2b5f092012-06-08 23:55:0214326
14327 response = trans2.GetResponseInfo();
wezca1070932016-05-26 20:30:5214328 ASSERT_TRUE(response);
14329 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0214330 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]d2b5f092012-06-08 23:55:0214331 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5214332 EXPECT_TRUE(response->was_alpn_negotiated);
robpercival214763f2016-07-01 23:27:0114333 ASSERT_THAT(ReadTransaction(&trans2, &response_data), IsOk());
[email protected]d2b5f092012-06-08 23:55:0214334 EXPECT_EQ("hello!", response_data);
[email protected]d2b5f092012-06-08 23:55:0214335}
14336
bnc8016c1f2017-03-31 02:11:2914337// Regression test for https://crbug.com/546991.
14338// The server might not be able to serve an IP pooled request, and might send a
14339// 421 Misdirected Request response status to indicate this.
14340// HttpNetworkTransaction should reset the request and retry without IP pooling.
14341TEST_F(HttpNetworkTransactionTest, RetryWithoutConnectionPooling) {
14342 // Two hosts resolve to the same IP address.
14343 const std::string ip_addr = "1.2.3.4";
14344 IPAddress ip;
14345 ASSERT_TRUE(ip.AssignFromIPLiteral(ip_addr));
14346 IPEndPoint peer_addr = IPEndPoint(ip, 443);
14347
Jeremy Roman0579ed62017-08-29 15:56:1914348 session_deps_.host_resolver = std::make_unique<MockCachingHostResolver>();
bnc8016c1f2017-03-31 02:11:2914349 session_deps_.host_resolver->rules()->AddRule("www.example.org", ip_addr);
14350 session_deps_.host_resolver->rules()->AddRule("mail.example.org", ip_addr);
14351
14352 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
14353
14354 // Two requests on the first connection.
14355 SpdySerializedFrame req1(
14356 spdy_util_.ConstructSpdyGet("https://www.example.org", 1, LOWEST));
14357 spdy_util_.UpdateWithStreamDestruction(1);
14358 SpdySerializedFrame req2(
14359 spdy_util_.ConstructSpdyGet("https://mail.example.org", 3, LOWEST));
14360 SpdySerializedFrame rst(
14361 spdy_util_.ConstructSpdyRstStream(3, ERROR_CODE_CANCEL));
14362 MockWrite writes1[] = {
14363 CreateMockWrite(req1, 0), CreateMockWrite(req2, 3),
14364 CreateMockWrite(rst, 6),
14365 };
14366
14367 // The first one succeeds, the second gets error 421 Misdirected Request.
14368 SpdySerializedFrame resp1(spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
14369 SpdySerializedFrame body1(spdy_util_.ConstructSpdyDataFrame(1, true));
14370 SpdyHeaderBlock response_headers;
Bence Békybda82952017-10-02 17:35:2714371 response_headers[kHttp2StatusHeader] = "421";
bnc8016c1f2017-03-31 02:11:2914372 SpdySerializedFrame resp2(
14373 spdy_util_.ConstructSpdyReply(3, std::move(response_headers)));
14374 MockRead reads1[] = {CreateMockRead(resp1, 1), CreateMockRead(body1, 2),
14375 CreateMockRead(resp2, 4), MockRead(ASYNC, 0, 5)};
14376
14377 MockConnect connect1(ASYNC, OK, peer_addr);
14378 SequencedSocketData data1(connect1, reads1, arraysize(reads1), writes1,
14379 arraysize(writes1));
14380 session_deps_.socket_factory->AddSocketDataProvider(&data1);
14381
14382 AddSSLSocketData();
14383
14384 // Retry the second request on a second connection.
14385 SpdyTestUtil spdy_util2;
14386 SpdySerializedFrame req3(
14387 spdy_util2.ConstructSpdyGet("https://mail.example.org", 1, LOWEST));
14388 MockWrite writes2[] = {
14389 CreateMockWrite(req3, 0),
14390 };
14391
14392 SpdySerializedFrame resp3(spdy_util2.ConstructSpdyGetReply(nullptr, 0, 1));
14393 SpdySerializedFrame body3(spdy_util2.ConstructSpdyDataFrame(1, true));
14394 MockRead reads2[] = {CreateMockRead(resp3, 1), CreateMockRead(body3, 2),
14395 MockRead(ASYNC, 0, 3)};
14396
14397 MockConnect connect2(ASYNC, OK, peer_addr);
14398 SequencedSocketData data2(connect2, reads2, arraysize(reads2), writes2,
14399 arraysize(writes2));
14400 session_deps_.socket_factory->AddSocketDataProvider(&data2);
14401
14402 AddSSLSocketData();
14403
14404 // Preload mail.example.org into HostCache.
14405 HostPortPair host_port("mail.example.org", 443);
14406 HostResolver::RequestInfo resolve_info(host_port);
14407 AddressList ignored;
14408 std::unique_ptr<HostResolver::Request> request;
14409 TestCompletionCallback callback;
14410 int rv = session_deps_.host_resolver->Resolve(resolve_info, DEFAULT_PRIORITY,
14411 &ignored, callback.callback(),
14412 &request, NetLogWithSource());
14413 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
14414 rv = callback.WaitForResult();
14415 EXPECT_THAT(rv, IsOk());
14416
14417 HttpRequestInfo request1;
14418 request1.method = "GET";
14419 request1.url = GURL("https://www.example.org/");
14420 request1.load_flags = 0;
14421 HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
14422
14423 rv = trans1.Start(&request1, callback.callback(), NetLogWithSource());
14424 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
14425 rv = callback.WaitForResult();
14426 EXPECT_THAT(rv, IsOk());
14427
14428 const HttpResponseInfo* response = trans1.GetResponseInfo();
14429 ASSERT_TRUE(response);
14430 ASSERT_TRUE(response->headers);
14431 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
14432 EXPECT_TRUE(response->was_fetched_via_spdy);
14433 EXPECT_TRUE(response->was_alpn_negotiated);
14434 std::string response_data;
14435 ASSERT_THAT(ReadTransaction(&trans1, &response_data), IsOk());
14436 EXPECT_EQ("hello!", response_data);
14437
14438 HttpRequestInfo request2;
14439 request2.method = "GET";
14440 request2.url = GURL("https://mail.example.org/");
14441 request2.load_flags = 0;
14442 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
14443
14444 BoundTestNetLog log;
14445 rv = trans2.Start(&request2, callback.callback(), log.bound());
14446 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
14447 rv = callback.WaitForResult();
14448 EXPECT_THAT(rv, IsOk());
14449
14450 response = trans2.GetResponseInfo();
14451 ASSERT_TRUE(response);
14452 ASSERT_TRUE(response->headers);
14453 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
14454 EXPECT_TRUE(response->was_fetched_via_spdy);
14455 EXPECT_TRUE(response->was_alpn_negotiated);
14456 ASSERT_THAT(ReadTransaction(&trans2, &response_data), IsOk());
14457 EXPECT_EQ("hello!", response_data);
14458
14459 TestNetLogEntry::List entries;
14460 log.GetEntries(&entries);
davidbence688ae2017-05-04 15:12:5914461 ExpectLogContainsSomewhere(
14462 entries, 0, NetLogEventType::HTTP_TRANSACTION_RESTART_MISDIRECTED_REQUEST,
bnc8016c1f2017-03-31 02:11:2914463 NetLogEventPhase::NONE);
davidbence688ae2017-05-04 15:12:5914464}
14465
14466// Test that HTTP 421 responses are properly returned to the caller if received
14467// on the retry as well. HttpNetworkTransaction should not infinite loop or lose
14468// portions of the response.
14469TEST_F(HttpNetworkTransactionTest, ReturnHTTP421OnRetry) {
14470 // Two hosts resolve to the same IP address.
14471 const std::string ip_addr = "1.2.3.4";
14472 IPAddress ip;
14473 ASSERT_TRUE(ip.AssignFromIPLiteral(ip_addr));
14474 IPEndPoint peer_addr = IPEndPoint(ip, 443);
14475
Jeremy Roman0579ed62017-08-29 15:56:1914476 session_deps_.host_resolver = std::make_unique<MockCachingHostResolver>();
davidbence688ae2017-05-04 15:12:5914477 session_deps_.host_resolver->rules()->AddRule("www.example.org", ip_addr);
14478 session_deps_.host_resolver->rules()->AddRule("mail.example.org", ip_addr);
14479
14480 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
14481
14482 // Two requests on the first connection.
14483 SpdySerializedFrame req1(
14484 spdy_util_.ConstructSpdyGet("https://www.example.org", 1, LOWEST));
14485 spdy_util_.UpdateWithStreamDestruction(1);
14486 SpdySerializedFrame req2(
14487 spdy_util_.ConstructSpdyGet("https://mail.example.org", 3, LOWEST));
14488 SpdySerializedFrame rst(
14489 spdy_util_.ConstructSpdyRstStream(3, ERROR_CODE_CANCEL));
14490 MockWrite writes1[] = {
14491 CreateMockWrite(req1, 0), CreateMockWrite(req2, 3),
14492 CreateMockWrite(rst, 6),
14493 };
14494
14495 // The first one succeeds, the second gets error 421 Misdirected Request.
14496 SpdySerializedFrame resp1(spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
14497 SpdySerializedFrame body1(spdy_util_.ConstructSpdyDataFrame(1, true));
14498 SpdyHeaderBlock response_headers;
Bence Békybda82952017-10-02 17:35:2714499 response_headers[kHttp2StatusHeader] = "421";
davidbence688ae2017-05-04 15:12:5914500 SpdySerializedFrame resp2(
14501 spdy_util_.ConstructSpdyReply(3, response_headers.Clone()));
14502 MockRead reads1[] = {CreateMockRead(resp1, 1), CreateMockRead(body1, 2),
14503 CreateMockRead(resp2, 4), MockRead(ASYNC, 0, 5)};
14504
14505 MockConnect connect1(ASYNC, OK, peer_addr);
14506 SequencedSocketData data1(connect1, reads1, arraysize(reads1), writes1,
14507 arraysize(writes1));
14508 session_deps_.socket_factory->AddSocketDataProvider(&data1);
14509
14510 AddSSLSocketData();
14511
14512 // Retry the second request on a second connection. It returns 421 Misdirected
14513 // Retry again.
14514 SpdyTestUtil spdy_util2;
14515 SpdySerializedFrame req3(
14516 spdy_util2.ConstructSpdyGet("https://mail.example.org", 1, LOWEST));
14517 MockWrite writes2[] = {
14518 CreateMockWrite(req3, 0),
14519 };
14520
14521 SpdySerializedFrame resp3(
14522 spdy_util2.ConstructSpdyReply(1, std::move(response_headers)));
14523 SpdySerializedFrame body3(spdy_util2.ConstructSpdyDataFrame(1, true));
14524 MockRead reads2[] = {CreateMockRead(resp3, 1), CreateMockRead(body3, 2),
14525 MockRead(ASYNC, 0, 3)};
14526
14527 MockConnect connect2(ASYNC, OK, peer_addr);
14528 SequencedSocketData data2(connect2, reads2, arraysize(reads2), writes2,
14529 arraysize(writes2));
14530 session_deps_.socket_factory->AddSocketDataProvider(&data2);
14531
14532 AddSSLSocketData();
14533
14534 // Preload mail.example.org into HostCache.
14535 HostPortPair host_port("mail.example.org", 443);
14536 HostResolver::RequestInfo resolve_info(host_port);
14537 AddressList ignored;
14538 std::unique_ptr<HostResolver::Request> request;
14539 TestCompletionCallback callback;
14540 int rv = session_deps_.host_resolver->Resolve(resolve_info, DEFAULT_PRIORITY,
14541 &ignored, callback.callback(),
14542 &request, NetLogWithSource());
14543 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
14544 rv = callback.WaitForResult();
14545 EXPECT_THAT(rv, IsOk());
14546
14547 HttpRequestInfo request1;
14548 request1.method = "GET";
14549 request1.url = GURL("https://www.example.org/");
14550 request1.load_flags = 0;
14551 HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
14552
14553 rv = trans1.Start(&request1, callback.callback(), NetLogWithSource());
14554 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
14555 rv = callback.WaitForResult();
14556 EXPECT_THAT(rv, IsOk());
14557
14558 const HttpResponseInfo* response = trans1.GetResponseInfo();
14559 ASSERT_TRUE(response);
14560 ASSERT_TRUE(response->headers);
14561 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
14562 EXPECT_TRUE(response->was_fetched_via_spdy);
14563 EXPECT_TRUE(response->was_alpn_negotiated);
14564 std::string response_data;
14565 ASSERT_THAT(ReadTransaction(&trans1, &response_data), IsOk());
14566 EXPECT_EQ("hello!", response_data);
14567
14568 HttpRequestInfo request2;
14569 request2.method = "GET";
14570 request2.url = GURL("https://mail.example.org/");
14571 request2.load_flags = 0;
14572 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
14573
14574 BoundTestNetLog log;
14575 rv = trans2.Start(&request2, callback.callback(), log.bound());
14576 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
14577 rv = callback.WaitForResult();
14578 EXPECT_THAT(rv, IsOk());
14579
14580 // After a retry, the 421 Misdirected Request is reported back up to the
14581 // caller.
14582 response = trans2.GetResponseInfo();
14583 ASSERT_TRUE(response);
14584 ASSERT_TRUE(response->headers);
14585 EXPECT_EQ("HTTP/1.1 421", response->headers->GetStatusLine());
14586 EXPECT_TRUE(response->was_fetched_via_spdy);
14587 EXPECT_TRUE(response->was_alpn_negotiated);
14588 EXPECT_TRUE(response->ssl_info.cert);
14589 ASSERT_THAT(ReadTransaction(&trans2, &response_data), IsOk());
14590 EXPECT_EQ("hello!", response_data);
bnc8016c1f2017-03-31 02:11:2914591}
14592
bnc6dcd8192017-05-25 20:11:5014593class OneTimeCachingHostResolver : public MockHostResolverBase {
[email protected]e3ceb682011-06-28 23:55:4614594 public:
14595 explicit OneTimeCachingHostResolver(const HostPortPair& host_port)
bnc6dcd8192017-05-25 20:11:5014596 : MockHostResolverBase(/* use_caching = */ true), host_port_(host_port) {}
Chris Watkins7a41d3552017-12-01 02:13:2714597 ~OneTimeCachingHostResolver() override = default;
[email protected]e3ceb682011-06-28 23:55:4614598
dchengb03027d2014-10-21 12:00:2014599 int ResolveFromCache(const RequestInfo& info,
14600 AddressList* addresses,
tfarina42834112016-09-22 13:38:2014601 const NetLogWithSource& net_log) override {
bnc6dcd8192017-05-25 20:11:5014602 int rv = MockHostResolverBase::ResolveFromCache(info, addresses, net_log);
[email protected]95a214c2011-08-04 21:50:4014603 if (rv == OK && info.host_port_pair().Equals(host_port_))
bnc6dcd8192017-05-25 20:11:5014604 GetHostCache()->clear();
[email protected]e3ceb682011-06-28 23:55:4614605 return rv;
14606 }
14607
[email protected]e3ceb682011-06-28 23:55:4614608 private:
[email protected]e3ceb682011-06-28 23:55:4614609 const HostPortPair host_port_;
14610};
14611
bncd16676a2016-07-20 16:23:0114612TEST_F(HttpNetworkTransactionTest,
mmenke5c642132015-06-02 16:05:1314613 UseIPConnectionPoolingWithHostCacheExpiration) {
[email protected]e3ceb682011-06-28 23:55:4614614 // Set up a special HttpNetworkSession with a OneTimeCachingHostResolver.
Jeremy Roman0579ed62017-08-29 15:56:1914615 session_deps_.host_resolver = std::make_unique<OneTimeCachingHostResolver>(
bnca4d611d2016-09-22 19:55:3714616 HostPortPair("mail.example.com", 443));
danakj1fd259a02016-04-16 03:17:0914617 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]e3ceb682011-06-28 23:55:4614618
bnc032658ba2016-09-26 18:17:1514619 AddSSLSocketData();
[email protected]e3ceb682011-06-28 23:55:4614620
bncdf80d44fd2016-07-15 20:27:4114621 SpdySerializedFrame host1_req(
bnc38dcd392016-02-09 23:19:4914622 spdy_util_.ConstructSpdyGet("https://www.example.org", 1, LOWEST));
rdsmithebb50aa2015-11-12 03:44:3814623 spdy_util_.UpdateWithStreamDestruction(1);
bncdf80d44fd2016-07-15 20:27:4114624 SpdySerializedFrame host2_req(
bnca4d611d2016-09-22 19:55:3714625 spdy_util_.ConstructSpdyGet("https://mail.example.com", 3, LOWEST));
[email protected]e3ceb682011-06-28 23:55:4614626 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:4114627 CreateMockWrite(host1_req, 0), CreateMockWrite(host2_req, 3),
[email protected]e3ceb682011-06-28 23:55:4614628 };
bnc42331402016-07-25 13:36:1514629 SpdySerializedFrame host1_resp(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
bncdf80d44fd2016-07-15 20:27:4114630 SpdySerializedFrame host1_resp_body(
14631 spdy_util_.ConstructSpdyDataFrame(1, true));
bnc42331402016-07-25 13:36:1514632 SpdySerializedFrame host2_resp(spdy_util_.ConstructSpdyGetReply(NULL, 0, 3));
bncdf80d44fd2016-07-15 20:27:4114633 SpdySerializedFrame host2_resp_body(
14634 spdy_util_.ConstructSpdyDataFrame(3, true));
[email protected]e3ceb682011-06-28 23:55:4614635 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:4114636 CreateMockRead(host1_resp, 1), CreateMockRead(host1_resp_body, 2),
14637 CreateMockRead(host2_resp, 4), CreateMockRead(host2_resp_body, 5),
rch8e6c6c42015-05-01 14:05:1314638 MockRead(ASYNC, 0, 6),
[email protected]e3ceb682011-06-28 23:55:4614639 };
14640
eroman36d84e54432016-03-17 03:23:0214641 IPEndPoint peer_addr(IPAddress::IPv4Localhost(), 443);
[email protected]d2b5f092012-06-08 23:55:0214642 MockConnect connect(ASYNC, OK, peer_addr);
rch8e6c6c42015-05-01 14:05:1314643 SequencedSocketData spdy_data(connect, spdy_reads, arraysize(spdy_reads),
14644 spdy_writes, arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:0714645 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]e3ceb682011-06-28 23:55:4614646
[email protected]aa22b242011-11-16 18:58:2914647 TestCompletionCallback callback;
[email protected]e3ceb682011-06-28 23:55:4614648 HttpRequestInfo request1;
14649 request1.method = "GET";
bncce36dca22015-04-21 22:11:2314650 request1.url = GURL("https://www.example.org/");
[email protected]e3ceb682011-06-28 23:55:4614651 request1.load_flags = 0;
[email protected]90499482013-06-01 00:39:5014652 HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
[email protected]e3ceb682011-06-28 23:55:4614653
tfarina42834112016-09-22 13:38:2014654 int rv = trans1.Start(&request1, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0114655 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
14656 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]e3ceb682011-06-28 23:55:4614657
14658 const HttpResponseInfo* response = trans1.GetResponseInfo();
wezca1070932016-05-26 20:30:5214659 ASSERT_TRUE(response);
14660 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0214661 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]e3ceb682011-06-28 23:55:4614662
14663 std::string response_data;
robpercival214763f2016-07-01 23:27:0114664 ASSERT_THAT(ReadTransaction(&trans1, &response_data), IsOk());
[email protected]e3ceb682011-06-28 23:55:4614665 EXPECT_EQ("hello!", response_data);
14666
14667 // Preload cache entries into HostCache.
bnca4d611d2016-09-22 19:55:3714668 HostResolver::RequestInfo resolve_info(HostPortPair("mail.example.com", 443));
[email protected]e3ceb682011-06-28 23:55:4614669 AddressList ignored;
maksim.sisov31452af2016-07-27 06:38:1014670 std::unique_ptr<HostResolver::Request> request;
bnc6dcd8192017-05-25 20:11:5014671 rv = session_deps_.host_resolver->Resolve(resolve_info, DEFAULT_PRIORITY,
14672 &ignored, callback.callback(),
14673 &request, NetLogWithSource());
robpercival214763f2016-07-01 23:27:0114674 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]6e78dfb2011-07-28 21:34:4714675 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0114676 EXPECT_THAT(rv, IsOk());
[email protected]e3ceb682011-06-28 23:55:4614677
14678 HttpRequestInfo request2;
14679 request2.method = "GET";
bnca4d611d2016-09-22 19:55:3714680 request2.url = GURL("https://mail.example.com/");
[email protected]e3ceb682011-06-28 23:55:4614681 request2.load_flags = 0;
[email protected]90499482013-06-01 00:39:5014682 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
[email protected]e3ceb682011-06-28 23:55:4614683
tfarina42834112016-09-22 13:38:2014684 rv = trans2.Start(&request2, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0114685 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
14686 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]e3ceb682011-06-28 23:55:4614687
14688 response = trans2.GetResponseInfo();
wezca1070932016-05-26 20:30:5214689 ASSERT_TRUE(response);
14690 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0214691 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]e3ceb682011-06-28 23:55:4614692 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5214693 EXPECT_TRUE(response->was_alpn_negotiated);
robpercival214763f2016-07-01 23:27:0114694 ASSERT_THAT(ReadTransaction(&trans2, &response_data), IsOk());
[email protected]e3ceb682011-06-28 23:55:4614695 EXPECT_EQ("hello!", response_data);
[email protected]e3ceb682011-06-28 23:55:4614696}
14697
bncd16676a2016-07-20 16:23:0114698TEST_F(HttpNetworkTransactionTest, DoNotUseSpdySessionForHttp) {
bncce36dca22015-04-21 22:11:2314699 const std::string https_url = "https://www.example.org:8080/";
14700 const std::string http_url = "http://www.example.org:8080/";
[email protected]8450d722012-07-02 19:14:0414701
14702 // SPDY GET for HTTPS URL
bncdf80d44fd2016-07-15 20:27:4114703 SpdySerializedFrame req1(
bnc38dcd392016-02-09 23:19:4914704 spdy_util_.ConstructSpdyGet(https_url.c_str(), 1, LOWEST));
[email protected]8450d722012-07-02 19:14:0414705
14706 MockWrite writes1[] = {
bncdf80d44fd2016-07-15 20:27:4114707 CreateMockWrite(req1, 0),
[email protected]8450d722012-07-02 19:14:0414708 };
14709
bnc42331402016-07-25 13:36:1514710 SpdySerializedFrame resp1(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
bncdf80d44fd2016-07-15 20:27:4114711 SpdySerializedFrame body1(spdy_util_.ConstructSpdyDataFrame(1, true));
14712 MockRead reads1[] = {CreateMockRead(resp1, 1), CreateMockRead(body1, 2),
mmenkee24011922015-12-17 22:12:5914713 MockRead(SYNCHRONOUS, ERR_IO_PENDING, 3)};
[email protected]8450d722012-07-02 19:14:0414714
rch8e6c6c42015-05-01 14:05:1314715 SequencedSocketData data1(reads1, arraysize(reads1), writes1,
14716 arraysize(writes1));
[email protected]8450d722012-07-02 19:14:0414717 MockConnect connect_data1(ASYNC, OK);
[email protected]dd54bd82012-07-19 23:44:5714718 data1.set_connect_data(connect_data1);
[email protected]8450d722012-07-02 19:14:0414719
14720 // HTTP GET for the HTTP URL
14721 MockWrite writes2[] = {
rch8e6c6c42015-05-01 14:05:1314722 MockWrite(ASYNC, 0,
lgarrona91df87f2014-12-05 00:51:3414723 "GET / HTTP/1.1\r\n"
bncce36dca22015-04-21 22:11:2314724 "Host: www.example.org:8080\r\n"
lgarrona91df87f2014-12-05 00:51:3414725 "Connection: keep-alive\r\n\r\n"),
[email protected]8450d722012-07-02 19:14:0414726 };
14727
14728 MockRead reads2[] = {
rch8e6c6c42015-05-01 14:05:1314729 MockRead(ASYNC, 1, "HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
14730 MockRead(ASYNC, 2, "hello"),
14731 MockRead(ASYNC, OK, 3),
[email protected]8450d722012-07-02 19:14:0414732 };
14733
rch8e6c6c42015-05-01 14:05:1314734 SequencedSocketData data2(reads2, arraysize(reads2), writes2,
14735 arraysize(writes2));
[email protected]8450d722012-07-02 19:14:0414736
[email protected]8450d722012-07-02 19:14:0414737 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3614738 ssl.next_proto = kProtoHTTP2;
[email protected]bb88e1d32013-05-03 23:11:0714739 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
14740 session_deps_.socket_factory->AddSocketDataProvider(&data1);
14741 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]8450d722012-07-02 19:14:0414742
danakj1fd259a02016-04-16 03:17:0914743 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]8450d722012-07-02 19:14:0414744
14745 // Start the first transaction to set up the SpdySession
14746 HttpRequestInfo request1;
14747 request1.method = "GET";
14748 request1.url = GURL(https_url);
[email protected]8450d722012-07-02 19:14:0414749 request1.load_flags = 0;
[email protected]90499482013-06-01 00:39:5014750 HttpNetworkTransaction trans1(LOWEST, session.get());
[email protected]8450d722012-07-02 19:14:0414751 TestCompletionCallback callback1;
14752 EXPECT_EQ(ERR_IO_PENDING,
tfarina42834112016-09-22 13:38:2014753 trans1.Start(&request1, callback1.callback(), NetLogWithSource()));
fdoray92e35a72016-06-10 15:54:5514754 base::RunLoop().RunUntilIdle();
[email protected]8450d722012-07-02 19:14:0414755
robpercival214763f2016-07-01 23:27:0114756 EXPECT_THAT(callback1.WaitForResult(), IsOk());
[email protected]8450d722012-07-02 19:14:0414757 EXPECT_TRUE(trans1.GetResponseInfo()->was_fetched_via_spdy);
14758
14759 // Now, start the HTTP request
14760 HttpRequestInfo request2;
14761 request2.method = "GET";
14762 request2.url = GURL(http_url);
[email protected]8450d722012-07-02 19:14:0414763 request2.load_flags = 0;
[email protected]90499482013-06-01 00:39:5014764 HttpNetworkTransaction trans2(MEDIUM, session.get());
[email protected]8450d722012-07-02 19:14:0414765 TestCompletionCallback callback2;
14766 EXPECT_EQ(ERR_IO_PENDING,
tfarina42834112016-09-22 13:38:2014767 trans2.Start(&request2, callback2.callback(), NetLogWithSource()));
fdoray92e35a72016-06-10 15:54:5514768 base::RunLoop().RunUntilIdle();
[email protected]8450d722012-07-02 19:14:0414769
robpercival214763f2016-07-01 23:27:0114770 EXPECT_THAT(callback2.WaitForResult(), IsOk());
[email protected]8450d722012-07-02 19:14:0414771 EXPECT_FALSE(trans2.GetResponseInfo()->was_fetched_via_spdy);
14772}
14773
bnc5452e2a2015-05-08 16:27:4214774// Alternative service requires HTTP/2 (or SPDY), but HTTP/1.1 is negotiated
14775// with the alternative server. That connection should not be used.
bncd16676a2016-07-20 16:23:0114776TEST_F(HttpNetworkTransactionTest, AlternativeServiceNotOnHttp11) {
bnc8bef8da22016-05-30 01:28:2514777 url::SchemeHostPort server("https", "www.example.org", 443);
14778 HostPortPair alternative("www.example.org", 444);
bnc5452e2a2015-05-08 16:27:4214779
bnc8bef8da22016-05-30 01:28:2514780 // Negotiate HTTP/1.1 with alternative.
bnc5452e2a2015-05-08 16:27:4214781 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3614782 ssl.next_proto = kProtoHTTP11;
bnc5452e2a2015-05-08 16:27:4214783 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
14784
14785 // No data should be read from the alternative, because HTTP/1.1 is
14786 // negotiated.
14787 StaticSocketDataProvider data;
14788 session_deps_.socket_factory->AddSocketDataProvider(&data);
14789
14790 // This test documents that an alternate Job should not be used if HTTP/1.1 is
zhongyi3d4a55e72016-04-22 20:36:4614791 // negotiated. In order to test this, a failed connection to the server is
bnc5452e2a2015-05-08 16:27:4214792 // mocked. This way the request relies on the alternate Job.
14793 StaticSocketDataProvider data_refused;
14794 data_refused.set_connect_data(MockConnect(ASYNC, ERR_CONNECTION_REFUSED));
14795 session_deps_.socket_factory->AddSocketDataProvider(&data_refused);
14796
zhongyi3d4a55e72016-04-22 20:36:4614797 // Set up alternative service for server.
danakj1fd259a02016-04-16 03:17:0914798 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc525e175a2016-06-20 12:36:4014799 HttpServerProperties* http_server_properties =
bnc5452e2a2015-05-08 16:27:4214800 session->http_server_properties();
bnc3472afd2016-11-17 15:27:2114801 AlternativeService alternative_service(kProtoHTTP2, alternative);
bnc7dc7e1b42015-07-28 14:43:1214802 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:2114803 http_server_properties->SetHttp2AlternativeService(
14804 server, alternative_service, expiration);
bnc5452e2a2015-05-08 16:27:4214805
bnc5452e2a2015-05-08 16:27:4214806 HttpRequestInfo request;
krasinc06a72a2016-12-21 03:42:4614807 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
bnc5452e2a2015-05-08 16:27:4214808 request.method = "GET";
bnc8bef8da22016-05-30 01:28:2514809 request.url = GURL("https://www.example.org:443");
bnc5452e2a2015-05-08 16:27:4214810 TestCompletionCallback callback;
14811
14812 // HTTP/2 (or SPDY) is required for alternative service, if HTTP/1.1 is
bnc94c92842016-09-21 15:22:5214813 // negotiated, the alternate Job should fail with ERR_ALPN_NEGOTIATION_FAILED.
tfarina42834112016-09-22 13:38:2014814 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
bnc94c92842016-09-21 15:22:5214815 EXPECT_THAT(callback.GetResult(rv), IsError(ERR_ALPN_NEGOTIATION_FAILED));
bnc5452e2a2015-05-08 16:27:4214816}
14817
bnc40448a532015-05-11 19:13:1414818// A request to a server with an alternative service fires two Jobs: one to the
zhongyi3d4a55e72016-04-22 20:36:4614819// server, and an alternate one to the alternative server. If the former
bnc40448a532015-05-11 19:13:1414820// succeeds, the request should succeed, even if the latter fails because
14821// HTTP/1.1 is negotiated which is insufficient for alternative service.
bncd16676a2016-07-20 16:23:0114822TEST_F(HttpNetworkTransactionTest, FailedAlternativeServiceIsNotUserVisible) {
bnc8bef8da22016-05-30 01:28:2514823 url::SchemeHostPort server("https", "www.example.org", 443);
14824 HostPortPair alternative("www.example.org", 444);
bnc40448a532015-05-11 19:13:1414825
14826 // Negotiate HTTP/1.1 with alternative.
14827 SSLSocketDataProvider alternative_ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3614828 alternative_ssl.next_proto = kProtoHTTP11;
bnc40448a532015-05-11 19:13:1414829 session_deps_.socket_factory->AddSSLSocketDataProvider(&alternative_ssl);
14830
14831 // No data should be read from the alternative, because HTTP/1.1 is
14832 // negotiated.
14833 StaticSocketDataProvider data;
14834 session_deps_.socket_factory->AddSocketDataProvider(&data);
14835
zhongyi3d4a55e72016-04-22 20:36:4614836 // Negotiate HTTP/1.1 with server.
bnc40448a532015-05-11 19:13:1414837 SSLSocketDataProvider origin_ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3614838 origin_ssl.next_proto = kProtoHTTP11;
bnc40448a532015-05-11 19:13:1414839 session_deps_.socket_factory->AddSSLSocketDataProvider(&origin_ssl);
14840
14841 MockWrite http_writes[] = {
bnc8bef8da22016-05-30 01:28:2514842 MockWrite("GET / HTTP/1.1\r\n"
14843 "Host: www.example.org\r\n"
14844 "Connection: keep-alive\r\n\r\n"),
14845 MockWrite("GET /second HTTP/1.1\r\n"
14846 "Host: www.example.org\r\n"
14847 "Connection: keep-alive\r\n\r\n"),
bnc40448a532015-05-11 19:13:1414848 };
14849
14850 MockRead http_reads[] = {
14851 MockRead("HTTP/1.1 200 OK\r\n"),
14852 MockRead("Content-Type: text/html\r\n"),
14853 MockRead("Content-Length: 6\r\n\r\n"),
14854 MockRead("foobar"),
14855 MockRead("HTTP/1.1 200 OK\r\n"),
14856 MockRead("Content-Type: text/html\r\n"),
14857 MockRead("Content-Length: 7\r\n\r\n"),
14858 MockRead("another"),
14859 };
14860 StaticSocketDataProvider http_data(http_reads, arraysize(http_reads),
14861 http_writes, arraysize(http_writes));
14862 session_deps_.socket_factory->AddSocketDataProvider(&http_data);
14863
zhongyi3d4a55e72016-04-22 20:36:4614864 // Set up alternative service for server.
danakj1fd259a02016-04-16 03:17:0914865 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc525e175a2016-06-20 12:36:4014866 HttpServerProperties* http_server_properties =
bnc40448a532015-05-11 19:13:1414867 session->http_server_properties();
bnc3472afd2016-11-17 15:27:2114868 AlternativeService alternative_service(kProtoHTTP2, alternative);
bnc7dc7e1b42015-07-28 14:43:1214869 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:2114870 http_server_properties->SetHttp2AlternativeService(
14871 server, alternative_service, expiration);
bnc40448a532015-05-11 19:13:1414872
14873 HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
14874 HttpRequestInfo request1;
14875 request1.method = "GET";
bnc8bef8da22016-05-30 01:28:2514876 request1.url = GURL("https://www.example.org:443");
bnc40448a532015-05-11 19:13:1414877 request1.load_flags = 0;
14878 TestCompletionCallback callback1;
14879
tfarina42834112016-09-22 13:38:2014880 int rv = trans1.Start(&request1, callback1.callback(), NetLogWithSource());
bnc40448a532015-05-11 19:13:1414881 rv = callback1.GetResult(rv);
robpercival214763f2016-07-01 23:27:0114882 EXPECT_THAT(rv, IsOk());
bnc40448a532015-05-11 19:13:1414883
14884 const HttpResponseInfo* response1 = trans1.GetResponseInfo();
wezca1070932016-05-26 20:30:5214885 ASSERT_TRUE(response1);
14886 ASSERT_TRUE(response1->headers);
bnc40448a532015-05-11 19:13:1414887 EXPECT_EQ("HTTP/1.1 200 OK", response1->headers->GetStatusLine());
14888
14889 std::string response_data1;
robpercival214763f2016-07-01 23:27:0114890 ASSERT_THAT(ReadTransaction(&trans1, &response_data1), IsOk());
bnc40448a532015-05-11 19:13:1414891 EXPECT_EQ("foobar", response_data1);
14892
14893 // Alternative should be marked as broken, because HTTP/1.1 is not sufficient
14894 // for alternative service.
14895 EXPECT_TRUE(
14896 http_server_properties->IsAlternativeServiceBroken(alternative_service));
14897
zhongyi3d4a55e72016-04-22 20:36:4614898 // Since |alternative_service| is broken, a second transaction to server
bnc40448a532015-05-11 19:13:1414899 // should not start an alternate Job. It should pool to existing connection
zhongyi3d4a55e72016-04-22 20:36:4614900 // to server.
bnc40448a532015-05-11 19:13:1414901 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
14902 HttpRequestInfo request2;
14903 request2.method = "GET";
bnc8bef8da22016-05-30 01:28:2514904 request2.url = GURL("https://www.example.org:443/second");
bnc40448a532015-05-11 19:13:1414905 request2.load_flags = 0;
14906 TestCompletionCallback callback2;
14907
tfarina42834112016-09-22 13:38:2014908 rv = trans2.Start(&request2, callback2.callback(), NetLogWithSource());
bnc40448a532015-05-11 19:13:1414909 rv = callback2.GetResult(rv);
robpercival214763f2016-07-01 23:27:0114910 EXPECT_THAT(rv, IsOk());
bnc40448a532015-05-11 19:13:1414911
14912 const HttpResponseInfo* response2 = trans2.GetResponseInfo();
wezca1070932016-05-26 20:30:5214913 ASSERT_TRUE(response2);
14914 ASSERT_TRUE(response2->headers);
bnc40448a532015-05-11 19:13:1414915 EXPECT_EQ("HTTP/1.1 200 OK", response2->headers->GetStatusLine());
14916
14917 std::string response_data2;
robpercival214763f2016-07-01 23:27:0114918 ASSERT_THAT(ReadTransaction(&trans2, &response_data2), IsOk());
bnc40448a532015-05-11 19:13:1414919 EXPECT_EQ("another", response_data2);
14920}
14921
bnc5452e2a2015-05-08 16:27:4214922// Alternative service requires HTTP/2 (or SPDY), but there is already a
14923// HTTP/1.1 socket open to the alternative server. That socket should not be
14924// used.
bncd16676a2016-07-20 16:23:0114925TEST_F(HttpNetworkTransactionTest, AlternativeServiceShouldNotPoolToHttp11) {
zhongyi3d4a55e72016-04-22 20:36:4614926 url::SchemeHostPort server("https", "origin.example.org", 443);
bnc5452e2a2015-05-08 16:27:4214927 HostPortPair alternative("alternative.example.org", 443);
14928 std::string origin_url = "https://origin.example.org:443";
14929 std::string alternative_url = "https://alternative.example.org:443";
14930
14931 // Negotiate HTTP/1.1 with alternative.example.org.
14932 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3614933 ssl.next_proto = kProtoHTTP11;
bnc5452e2a2015-05-08 16:27:4214934 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
14935
14936 // HTTP/1.1 data for |request1| and |request2|.
14937 MockWrite http_writes[] = {
14938 MockWrite(
14939 "GET / HTTP/1.1\r\n"
14940 "Host: alternative.example.org\r\n"
14941 "Connection: keep-alive\r\n\r\n"),
14942 MockWrite(
14943 "GET / HTTP/1.1\r\n"
14944 "Host: alternative.example.org\r\n"
14945 "Connection: keep-alive\r\n\r\n"),
14946 };
14947
14948 MockRead http_reads[] = {
14949 MockRead(
14950 "HTTP/1.1 200 OK\r\n"
14951 "Content-Type: text/html; charset=iso-8859-1\r\n"
14952 "Content-Length: 40\r\n\r\n"
14953 "first HTTP/1.1 response from alternative"),
14954 MockRead(
14955 "HTTP/1.1 200 OK\r\n"
14956 "Content-Type: text/html; charset=iso-8859-1\r\n"
14957 "Content-Length: 41\r\n\r\n"
14958 "second HTTP/1.1 response from alternative"),
14959 };
14960 StaticSocketDataProvider http_data(http_reads, arraysize(http_reads),
14961 http_writes, arraysize(http_writes));
14962 session_deps_.socket_factory->AddSocketDataProvider(&http_data);
14963
14964 // This test documents that an alternate Job should not pool to an already
14965 // existing HTTP/1.1 connection. In order to test this, a failed connection
zhongyi3d4a55e72016-04-22 20:36:4614966 // to the server is mocked. This way |request2| relies on the alternate Job.
bnc5452e2a2015-05-08 16:27:4214967 StaticSocketDataProvider data_refused;
14968 data_refused.set_connect_data(MockConnect(ASYNC, ERR_CONNECTION_REFUSED));
14969 session_deps_.socket_factory->AddSocketDataProvider(&data_refused);
14970
zhongyi3d4a55e72016-04-22 20:36:4614971 // Set up alternative service for server.
danakj1fd259a02016-04-16 03:17:0914972 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc525e175a2016-06-20 12:36:4014973 HttpServerProperties* http_server_properties =
bnc5452e2a2015-05-08 16:27:4214974 session->http_server_properties();
bnc3472afd2016-11-17 15:27:2114975 AlternativeService alternative_service(kProtoHTTP2, alternative);
bnc7dc7e1b42015-07-28 14:43:1214976 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:2114977 http_server_properties->SetHttp2AlternativeService(
14978 server, alternative_service, expiration);
bnc5452e2a2015-05-08 16:27:4214979
14980 // First transaction to alternative to open an HTTP/1.1 socket.
bnc5452e2a2015-05-08 16:27:4214981 HttpRequestInfo request1;
krasinc06a72a2016-12-21 03:42:4614982 HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
bnc5452e2a2015-05-08 16:27:4214983 request1.method = "GET";
14984 request1.url = GURL(alternative_url);
14985 request1.load_flags = 0;
14986 TestCompletionCallback callback1;
14987
tfarina42834112016-09-22 13:38:2014988 int rv = trans1.Start(&request1, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0114989 EXPECT_THAT(callback1.GetResult(rv), IsOk());
bnc691fda62016-08-12 00:43:1614990 const HttpResponseInfo* response1 = trans1.GetResponseInfo();
bnc5452e2a2015-05-08 16:27:4214991 ASSERT_TRUE(response1);
wezca1070932016-05-26 20:30:5214992 ASSERT_TRUE(response1->headers);
bnc5452e2a2015-05-08 16:27:4214993 EXPECT_EQ("HTTP/1.1 200 OK", response1->headers->GetStatusLine());
bnc94c92842016-09-21 15:22:5214994 EXPECT_TRUE(response1->was_alpn_negotiated);
bnc5452e2a2015-05-08 16:27:4214995 EXPECT_FALSE(response1->was_fetched_via_spdy);
14996 std::string response_data1;
bnc691fda62016-08-12 00:43:1614997 ASSERT_THAT(ReadTransaction(&trans1, &response_data1), IsOk());
bnc5452e2a2015-05-08 16:27:4214998 EXPECT_EQ("first HTTP/1.1 response from alternative", response_data1);
14999
15000 // Request for origin.example.org, which has an alternative service. This
15001 // will start two Jobs: the alternative looks for connections to pool to,
15002 // finds one which is HTTP/1.1, and should ignore it, and should not try to
zhongyi3d4a55e72016-04-22 20:36:4615003 // open other connections to alternative server. The Job to server fails, so
bnc5452e2a2015-05-08 16:27:4215004 // this request fails.
bnc5452e2a2015-05-08 16:27:4215005 HttpRequestInfo request2;
krasinc06a72a2016-12-21 03:42:4615006 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
bnc5452e2a2015-05-08 16:27:4215007 request2.method = "GET";
15008 request2.url = GURL(origin_url);
15009 request2.load_flags = 0;
15010 TestCompletionCallback callback2;
15011
tfarina42834112016-09-22 13:38:2015012 rv = trans2.Start(&request2, callback2.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0115013 EXPECT_THAT(callback2.GetResult(rv), IsError(ERR_CONNECTION_REFUSED));
bnc5452e2a2015-05-08 16:27:4215014
15015 // Another transaction to alternative. This is to test that the HTTP/1.1
15016 // socket is still open and in the pool.
bnc5452e2a2015-05-08 16:27:4215017 HttpRequestInfo request3;
krasinc06a72a2016-12-21 03:42:4615018 HttpNetworkTransaction trans3(DEFAULT_PRIORITY, session.get());
bnc5452e2a2015-05-08 16:27:4215019 request3.method = "GET";
15020 request3.url = GURL(alternative_url);
15021 request3.load_flags = 0;
15022 TestCompletionCallback callback3;
15023
tfarina42834112016-09-22 13:38:2015024 rv = trans3.Start(&request3, callback3.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0115025 EXPECT_THAT(callback3.GetResult(rv), IsOk());
bnc691fda62016-08-12 00:43:1615026 const HttpResponseInfo* response3 = trans3.GetResponseInfo();
bnc5452e2a2015-05-08 16:27:4215027 ASSERT_TRUE(response3);
wezca1070932016-05-26 20:30:5215028 ASSERT_TRUE(response3->headers);
bnc5452e2a2015-05-08 16:27:4215029 EXPECT_EQ("HTTP/1.1 200 OK", response3->headers->GetStatusLine());
bnc94c92842016-09-21 15:22:5215030 EXPECT_TRUE(response3->was_alpn_negotiated);
bnc5452e2a2015-05-08 16:27:4215031 EXPECT_FALSE(response3->was_fetched_via_spdy);
15032 std::string response_data3;
bnc691fda62016-08-12 00:43:1615033 ASSERT_THAT(ReadTransaction(&trans3, &response_data3), IsOk());
bnc5452e2a2015-05-08 16:27:4215034 EXPECT_EQ("second HTTP/1.1 response from alternative", response_data3);
15035}
15036
bncd16676a2016-07-20 16:23:0115037TEST_F(HttpNetworkTransactionTest, DoNotUseSpdySessionForHttpOverTunnel) {
bncce36dca22015-04-21 22:11:2315038 const std::string https_url = "https://www.example.org:8080/";
15039 const std::string http_url = "http://www.example.org:8080/";
[email protected]8450d722012-07-02 19:14:0415040
rdsmithebb50aa2015-11-12 03:44:3815041 // Separate SPDY util instance for naked and wrapped requests.
bncd16676a2016-07-20 16:23:0115042 SpdyTestUtil spdy_util_wrapped;
rdsmithebb50aa2015-11-12 03:44:3815043
[email protected]8450d722012-07-02 19:14:0415044 // SPDY GET for HTTPS URL (through CONNECT tunnel)
bncce36dca22015-04-21 22:11:2315045 const HostPortPair host_port_pair("www.example.org", 8080);
bncdf80d44fd2016-07-15 20:27:4115046 SpdySerializedFrame connect(
lgarrona91df87f2014-12-05 00:51:3415047 spdy_util_.ConstructSpdyConnect(NULL, 0, 1, LOWEST, host_port_pair));
bncdf80d44fd2016-07-15 20:27:4115048 SpdySerializedFrame req1(
bnc38dcd392016-02-09 23:19:4915049 spdy_util_wrapped.ConstructSpdyGet(https_url.c_str(), 1, LOWEST));
bncdf80d44fd2016-07-15 20:27:4115050 SpdySerializedFrame wrapped_req1(
[email protected]23e482282013-06-14 16:08:0215051 spdy_util_.ConstructWrappedSpdyFrame(req1, 1));
[email protected]601e03f12014-04-06 16:26:3915052
15053 // SPDY GET for HTTP URL (through the proxy, but not the tunnel).
[email protected]745aa9c2014-06-27 02:21:2915054 SpdyHeaderBlock req2_block;
Bence Békybda82952017-10-02 17:35:2715055 req2_block[kHttp2MethodHeader] = "GET";
15056 req2_block[kHttp2AuthorityHeader] = "www.example.org:8080";
15057 req2_block[kHttp2SchemeHeader] = "http";
15058 req2_block[kHttp2PathHeader] = "/";
bncdf80d44fd2016-07-15 20:27:4115059 SpdySerializedFrame req2(
bnc42331402016-07-25 13:36:1515060 spdy_util_.ConstructSpdyHeaders(3, std::move(req2_block), MEDIUM, true));
[email protected]8450d722012-07-02 19:14:0415061
15062 MockWrite writes1[] = {
bncdf80d44fd2016-07-15 20:27:4115063 CreateMockWrite(connect, 0), CreateMockWrite(wrapped_req1, 2),
15064 CreateMockWrite(req2, 6),
[email protected]8450d722012-07-02 19:14:0415065 };
15066
bncdf80d44fd2016-07-15 20:27:4115067 SpdySerializedFrame conn_resp(
bnc42331402016-07-25 13:36:1515068 spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
bncdf80d44fd2016-07-15 20:27:4115069 SpdySerializedFrame resp1(
bnc42331402016-07-25 13:36:1515070 spdy_util_wrapped.ConstructSpdyGetReply(nullptr, 0, 1));
bncdf80d44fd2016-07-15 20:27:4115071 SpdySerializedFrame body1(spdy_util_wrapped.ConstructSpdyDataFrame(1, true));
15072 SpdySerializedFrame wrapped_resp1(
rdsmithebb50aa2015-11-12 03:44:3815073 spdy_util_wrapped.ConstructWrappedSpdyFrame(resp1, 1));
bncdf80d44fd2016-07-15 20:27:4115074 SpdySerializedFrame wrapped_body1(
rdsmithebb50aa2015-11-12 03:44:3815075 spdy_util_wrapped.ConstructWrappedSpdyFrame(body1, 1));
bnc42331402016-07-25 13:36:1515076 SpdySerializedFrame resp2(spdy_util_.ConstructSpdyGetReply(NULL, 0, 3));
bncdf80d44fd2016-07-15 20:27:4115077 SpdySerializedFrame body2(spdy_util_.ConstructSpdyDataFrame(3, true));
mmenke666a6fea2015-12-19 04:16:3315078 MockRead reads1[] = {
bncdf80d44fd2016-07-15 20:27:4115079 CreateMockRead(conn_resp, 1),
mmenke666a6fea2015-12-19 04:16:3315080 MockRead(ASYNC, ERR_IO_PENDING, 3),
bncdf80d44fd2016-07-15 20:27:4115081 CreateMockRead(wrapped_resp1, 4),
15082 CreateMockRead(wrapped_body1, 5),
mmenke666a6fea2015-12-19 04:16:3315083 MockRead(ASYNC, ERR_IO_PENDING, 7),
bncdf80d44fd2016-07-15 20:27:4115084 CreateMockRead(resp2, 8),
15085 CreateMockRead(body2, 9),
mmenke666a6fea2015-12-19 04:16:3315086 MockRead(SYNCHRONOUS, ERR_IO_PENDING, 10),
15087 };
[email protected]8450d722012-07-02 19:14:0415088
mmenke666a6fea2015-12-19 04:16:3315089 SequencedSocketData data1(reads1, arraysize(reads1), writes1,
15090 arraysize(writes1));
[email protected]8450d722012-07-02 19:14:0415091 MockConnect connect_data1(ASYNC, OK);
[email protected]dd54bd82012-07-19 23:44:5715092 data1.set_connect_data(connect_data1);
[email protected]8450d722012-07-02 19:14:0415093
Lily Houghton8c2f97d2018-01-22 05:06:5915094 session_deps_.proxy_resolution_service =
15095 ProxyResolutionService::CreateFixedFromPacResult("HTTPS proxy:70");
vishal.b62985ca92015-04-17 08:45:5115096 TestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:0715097 session_deps_.net_log = &log;
[email protected]8450d722012-07-02 19:14:0415098 SSLSocketDataProvider ssl1(ASYNC, OK); // to the proxy
bnc3cf2a592016-08-11 14:48:3615099 ssl1.next_proto = kProtoHTTP2;
mmenke666a6fea2015-12-19 04:16:3315100 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl1);
[email protected]8450d722012-07-02 19:14:0415101 SSLSocketDataProvider ssl2(ASYNC, OK); // to the server
bnc3cf2a592016-08-11 14:48:3615102 ssl2.next_proto = kProtoHTTP2;
mmenke666a6fea2015-12-19 04:16:3315103 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
15104 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8450d722012-07-02 19:14:0415105
danakj1fd259a02016-04-16 03:17:0915106 std::unique_ptr<HttpNetworkSession> session = CreateSession(&session_deps_);
[email protected]8450d722012-07-02 19:14:0415107
15108 // Start the first transaction to set up the SpdySession
15109 HttpRequestInfo request1;
15110 request1.method = "GET";
15111 request1.url = GURL(https_url);
[email protected]8450d722012-07-02 19:14:0415112 request1.load_flags = 0;
[email protected]90499482013-06-01 00:39:5015113 HttpNetworkTransaction trans1(LOWEST, session.get());
[email protected]8450d722012-07-02 19:14:0415114 TestCompletionCallback callback1;
tfarina42834112016-09-22 13:38:2015115 int rv = trans1.Start(&request1, callback1.callback(), NetLogWithSource());
[email protected]8450d722012-07-02 19:14:0415116
mmenke666a6fea2015-12-19 04:16:3315117 // This pause is a hack to avoid running into https://crbug.com/497228.
15118 data1.RunUntilPaused();
15119 base::RunLoop().RunUntilIdle();
15120 data1.Resume();
robpercival214763f2016-07-01 23:27:0115121 EXPECT_THAT(callback1.GetResult(rv), IsOk());
[email protected]8450d722012-07-02 19:14:0415122 EXPECT_TRUE(trans1.GetResponseInfo()->was_fetched_via_spdy);
15123
[email protected]f6c63db52013-02-02 00:35:2215124 LoadTimingInfo load_timing_info1;
15125 EXPECT_TRUE(trans1.GetLoadTimingInfo(&load_timing_info1));
15126 TestLoadTimingNotReusedWithPac(load_timing_info1,
15127 CONNECT_TIMING_HAS_SSL_TIMES);
15128
mmenke666a6fea2015-12-19 04:16:3315129 // Now, start the HTTP request.
[email protected]8450d722012-07-02 19:14:0415130 HttpRequestInfo request2;
15131 request2.method = "GET";
15132 request2.url = GURL(http_url);
[email protected]8450d722012-07-02 19:14:0415133 request2.load_flags = 0;
[email protected]90499482013-06-01 00:39:5015134 HttpNetworkTransaction trans2(MEDIUM, session.get());
[email protected]8450d722012-07-02 19:14:0415135 TestCompletionCallback callback2;
tfarina42834112016-09-22 13:38:2015136 rv = trans2.Start(&request2, callback2.callback(), NetLogWithSource());
[email protected]8450d722012-07-02 19:14:0415137
mmenke666a6fea2015-12-19 04:16:3315138 // This pause is a hack to avoid running into https://crbug.com/497228.
15139 data1.RunUntilPaused();
15140 base::RunLoop().RunUntilIdle();
15141 data1.Resume();
robpercival214763f2016-07-01 23:27:0115142 EXPECT_THAT(callback2.GetResult(rv), IsOk());
mmenke666a6fea2015-12-19 04:16:3315143
[email protected]8450d722012-07-02 19:14:0415144 EXPECT_TRUE(trans2.GetResponseInfo()->was_fetched_via_spdy);
[email protected]f6c63db52013-02-02 00:35:2215145
15146 LoadTimingInfo load_timing_info2;
15147 EXPECT_TRUE(trans2.GetLoadTimingInfo(&load_timing_info2));
15148 // The established SPDY sessions is considered reused by the HTTP request.
15149 TestLoadTimingReusedWithPac(load_timing_info2);
15150 // HTTP requests over a SPDY session should have a different connection
15151 // socket_log_id than requests over a tunnel.
15152 EXPECT_NE(load_timing_info1.socket_log_id, load_timing_info2.socket_log_id);
[email protected]8450d722012-07-02 19:14:0415153}
15154
[email protected]2d88e7d2012-07-19 17:55:1715155// Test that in the case where we have a SPDY session to a SPDY proxy
15156// that we do not pool other origins that resolve to the same IP when
15157// the certificate does not match the new origin.
15158// http://crbug.com/134690
bncd16676a2016-07-20 16:23:0115159TEST_F(HttpNetworkTransactionTest, DoNotUseSpdySessionIfCertDoesNotMatch) {
bncce36dca22015-04-21 22:11:2315160 const std::string url1 = "http://www.example.org/";
15161 const std::string url2 = "https://news.example.org/";
[email protected]2d88e7d2012-07-19 17:55:1715162 const std::string ip_addr = "1.2.3.4";
15163
rdsmithebb50aa2015-11-12 03:44:3815164 // Second SpdyTestUtil instance for the second socket.
bncd16676a2016-07-20 16:23:0115165 SpdyTestUtil spdy_util_secure;
rdsmithebb50aa2015-11-12 03:44:3815166
[email protected]2d88e7d2012-07-19 17:55:1715167 // SPDY GET for HTTP URL (through SPDY proxy)
bnc086b39e12016-06-24 13:05:2615168 SpdyHeaderBlock headers(
bncce36dca22015-04-21 22:11:2315169 spdy_util_.ConstructGetHeaderBlockForProxy("http://www.example.org/"));
bncdf80d44fd2016-07-15 20:27:4115170 SpdySerializedFrame req1(
bnc42331402016-07-25 13:36:1515171 spdy_util_.ConstructSpdyHeaders(1, std::move(headers), LOWEST, true));
[email protected]2d88e7d2012-07-19 17:55:1715172
15173 MockWrite writes1[] = {
bncdf80d44fd2016-07-15 20:27:4115174 CreateMockWrite(req1, 0),
[email protected]2d88e7d2012-07-19 17:55:1715175 };
15176
bnc42331402016-07-25 13:36:1515177 SpdySerializedFrame resp1(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
bncdf80d44fd2016-07-15 20:27:4115178 SpdySerializedFrame body1(spdy_util_.ConstructSpdyDataFrame(1, true));
[email protected]2d88e7d2012-07-19 17:55:1715179 MockRead reads1[] = {
bncdf80d44fd2016-07-15 20:27:4115180 MockRead(ASYNC, ERR_IO_PENDING, 1), CreateMockRead(resp1, 2),
15181 CreateMockRead(body1, 3), MockRead(ASYNC, OK, 4), // EOF
[email protected]2d88e7d2012-07-19 17:55:1715182 };
15183
mmenke666a6fea2015-12-19 04:16:3315184 SequencedSocketData data1(reads1, arraysize(reads1), writes1,
15185 arraysize(writes1));
martijnfe9636e2016-02-06 14:33:3215186 IPAddress ip;
martijn654c8c42016-02-10 22:10:5915187 ASSERT_TRUE(ip.AssignFromIPLiteral(ip_addr));
[email protected]2d88e7d2012-07-19 17:55:1715188 IPEndPoint peer_addr = IPEndPoint(ip, 443);
15189 MockConnect connect_data1(ASYNC, OK, peer_addr);
mmenke666a6fea2015-12-19 04:16:3315190 data1.set_connect_data(connect_data1);
[email protected]2d88e7d2012-07-19 17:55:1715191
15192 // SPDY GET for HTTPS URL (direct)
bncdf80d44fd2016-07-15 20:27:4115193 SpdySerializedFrame req2(
bnc38dcd392016-02-09 23:19:4915194 spdy_util_secure.ConstructSpdyGet(url2.c_str(), 1, MEDIUM));
[email protected]2d88e7d2012-07-19 17:55:1715195
15196 MockWrite writes2[] = {
bncdf80d44fd2016-07-15 20:27:4115197 CreateMockWrite(req2, 0),
[email protected]2d88e7d2012-07-19 17:55:1715198 };
15199
bnc42331402016-07-25 13:36:1515200 SpdySerializedFrame resp2(spdy_util_secure.ConstructSpdyGetReply(NULL, 0, 1));
bncdf80d44fd2016-07-15 20:27:4115201 SpdySerializedFrame body2(spdy_util_secure.ConstructSpdyDataFrame(1, true));
15202 MockRead reads2[] = {CreateMockRead(resp2, 1), CreateMockRead(body2, 2),
mmenke666a6fea2015-12-19 04:16:3315203 MockRead(ASYNC, OK, 3)};
[email protected]2d88e7d2012-07-19 17:55:1715204
mmenke666a6fea2015-12-19 04:16:3315205 SequencedSocketData data2(reads2, arraysize(reads2), writes2,
15206 arraysize(writes2));
[email protected]2d88e7d2012-07-19 17:55:1715207 MockConnect connect_data2(ASYNC, OK);
mmenke666a6fea2015-12-19 04:16:3315208 data2.set_connect_data(connect_data2);
[email protected]2d88e7d2012-07-19 17:55:1715209
15210 // Set up a proxy config that sends HTTP requests to a proxy, and
15211 // all others direct.
15212 ProxyConfig proxy_config;
15213 proxy_config.proxy_rules().ParseFromString("http=https://proxy:443");
Lily Houghton8c2f97d2018-01-22 05:06:5915214 session_deps_.proxy_resolution_service = std::make_unique<ProxyResolutionService>(
Jeremy Roman0579ed62017-08-29 15:56:1915215 std::make_unique<ProxyConfigServiceFixed>(proxy_config), nullptr,
bnc87dcefc2017-05-25 12:47:5815216 nullptr);
[email protected]2d88e7d2012-07-19 17:55:1715217
bncce36dca22015-04-21 22:11:2315218 SSLSocketDataProvider ssl1(ASYNC, OK); // to the proxy
bnc3cf2a592016-08-11 14:48:3615219 ssl1.next_proto = kProtoHTTP2;
[email protected]2d88e7d2012-07-19 17:55:1715220 // Load a valid cert. Note, that this does not need to
15221 // be valid for proxy because the MockSSLClientSocket does
15222 // not actually verify it. But SpdySession will use this
15223 // to see if it is valid for the new origin
Ryan Sleevi4f832092017-11-21 23:25:4915224 ssl1.ssl_info.cert =
15225 ImportCertFromFile(GetTestCertsDirectory(), "ok_cert.pem");
15226 ASSERT_TRUE(ssl1.ssl_info.cert);
mmenke666a6fea2015-12-19 04:16:3315227 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl1);
15228 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]2d88e7d2012-07-19 17:55:1715229
15230 SSLSocketDataProvider ssl2(ASYNC, OK); // to the server
bnc3cf2a592016-08-11 14:48:3615231 ssl2.next_proto = kProtoHTTP2;
mmenke666a6fea2015-12-19 04:16:3315232 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
15233 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]2d88e7d2012-07-19 17:55:1715234
Jeremy Roman0579ed62017-08-29 15:56:1915235 session_deps_.host_resolver = std::make_unique<MockCachingHostResolver>();
bncce36dca22015-04-21 22:11:2315236 session_deps_.host_resolver->rules()->AddRule("news.example.org", ip_addr);
[email protected]bb88e1d32013-05-03 23:11:0715237 session_deps_.host_resolver->rules()->AddRule("proxy", ip_addr);
[email protected]2d88e7d2012-07-19 17:55:1715238
danakj1fd259a02016-04-16 03:17:0915239 std::unique_ptr<HttpNetworkSession> session = CreateSession(&session_deps_);
[email protected]2d88e7d2012-07-19 17:55:1715240
15241 // Start the first transaction to set up the SpdySession
15242 HttpRequestInfo request1;
15243 request1.method = "GET";
15244 request1.url = GURL(url1);
[email protected]2d88e7d2012-07-19 17:55:1715245 request1.load_flags = 0;
[email protected]90499482013-06-01 00:39:5015246 HttpNetworkTransaction trans1(LOWEST, session.get());
[email protected]2d88e7d2012-07-19 17:55:1715247 TestCompletionCallback callback1;
15248 ASSERT_EQ(ERR_IO_PENDING,
tfarina42834112016-09-22 13:38:2015249 trans1.Start(&request1, callback1.callback(), NetLogWithSource()));
mmenke666a6fea2015-12-19 04:16:3315250 // This pause is a hack to avoid running into https://crbug.com/497228.
15251 data1.RunUntilPaused();
15252 base::RunLoop().RunUntilIdle();
15253 data1.Resume();
[email protected]2d88e7d2012-07-19 17:55:1715254
robpercival214763f2016-07-01 23:27:0115255 EXPECT_THAT(callback1.WaitForResult(), IsOk());
[email protected]2d88e7d2012-07-19 17:55:1715256 EXPECT_TRUE(trans1.GetResponseInfo()->was_fetched_via_spdy);
15257
15258 // Now, start the HTTP request
15259 HttpRequestInfo request2;
15260 request2.method = "GET";
15261 request2.url = GURL(url2);
[email protected]2d88e7d2012-07-19 17:55:1715262 request2.load_flags = 0;
[email protected]90499482013-06-01 00:39:5015263 HttpNetworkTransaction trans2(MEDIUM, session.get());
[email protected]2d88e7d2012-07-19 17:55:1715264 TestCompletionCallback callback2;
15265 EXPECT_EQ(ERR_IO_PENDING,
tfarina42834112016-09-22 13:38:2015266 trans2.Start(&request2, callback2.callback(), NetLogWithSource()));
fdoray92e35a72016-06-10 15:54:5515267 base::RunLoop().RunUntilIdle();
[email protected]2d88e7d2012-07-19 17:55:1715268
15269 ASSERT_TRUE(callback2.have_result());
robpercival214763f2016-07-01 23:27:0115270 EXPECT_THAT(callback2.WaitForResult(), IsOk());
[email protected]2d88e7d2012-07-19 17:55:1715271 EXPECT_TRUE(trans2.GetResponseInfo()->was_fetched_via_spdy);
15272}
15273
[email protected]85f97342013-04-17 06:12:2415274// Test to verify that a failed socket read (due to an ERR_CONNECTION_CLOSED
15275// error) in SPDY session, removes the socket from pool and closes the SPDY
15276// session. Verify that new url's from the same HttpNetworkSession (and a new
15277// SpdySession) do work. http://crbug.com/224701
bncd16676a2016-07-20 16:23:0115278TEST_F(HttpNetworkTransactionTest, ErrorSocketNotConnected) {
bncce36dca22015-04-21 22:11:2315279 const std::string https_url = "https://www.example.org/";
[email protected]85f97342013-04-17 06:12:2415280
15281 MockRead reads1[] = {
15282 MockRead(SYNCHRONOUS, ERR_CONNECTION_CLOSED, 0)
15283 };
15284
mmenke11eb5152015-06-09 14:50:5015285 SequencedSocketData data1(reads1, arraysize(reads1), NULL, 0);
[email protected]85f97342013-04-17 06:12:2415286
bncdf80d44fd2016-07-15 20:27:4115287 SpdySerializedFrame req2(
bnc38dcd392016-02-09 23:19:4915288 spdy_util_.ConstructSpdyGet(https_url.c_str(), 1, MEDIUM));
[email protected]85f97342013-04-17 06:12:2415289 MockWrite writes2[] = {
bncdf80d44fd2016-07-15 20:27:4115290 CreateMockWrite(req2, 0),
[email protected]85f97342013-04-17 06:12:2415291 };
15292
bnc42331402016-07-25 13:36:1515293 SpdySerializedFrame resp2(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
bncdf80d44fd2016-07-15 20:27:4115294 SpdySerializedFrame body2(spdy_util_.ConstructSpdyDataFrame(1, true));
[email protected]85f97342013-04-17 06:12:2415295 MockRead reads2[] = {
bncdf80d44fd2016-07-15 20:27:4115296 CreateMockRead(resp2, 1), CreateMockRead(body2, 2),
15297 MockRead(ASYNC, OK, 3) // EOF
[email protected]85f97342013-04-17 06:12:2415298 };
15299
mmenke11eb5152015-06-09 14:50:5015300 SequencedSocketData data2(reads2, arraysize(reads2), writes2,
15301 arraysize(writes2));
[email protected]85f97342013-04-17 06:12:2415302
[email protected]85f97342013-04-17 06:12:2415303 SSLSocketDataProvider ssl1(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3615304 ssl1.next_proto = kProtoHTTP2;
mmenke11eb5152015-06-09 14:50:5015305 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl1);
15306 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]85f97342013-04-17 06:12:2415307
15308 SSLSocketDataProvider ssl2(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3615309 ssl2.next_proto = kProtoHTTP2;
mmenke11eb5152015-06-09 14:50:5015310 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
15311 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]85f97342013-04-17 06:12:2415312
danakj1fd259a02016-04-16 03:17:0915313 std::unique_ptr<HttpNetworkSession> session(
mmenke11eb5152015-06-09 14:50:5015314 SpdySessionDependencies::SpdyCreateSession(&session_deps_));
[email protected]85f97342013-04-17 06:12:2415315
15316 // Start the first transaction to set up the SpdySession and verify that
15317 // connection was closed.
15318 HttpRequestInfo request1;
15319 request1.method = "GET";
15320 request1.url = GURL(https_url);
15321 request1.load_flags = 0;
[email protected]90499482013-06-01 00:39:5015322 HttpNetworkTransaction trans1(MEDIUM, session.get());
[email protected]85f97342013-04-17 06:12:2415323 TestCompletionCallback callback1;
15324 EXPECT_EQ(ERR_IO_PENDING,
tfarina42834112016-09-22 13:38:2015325 trans1.Start(&request1, callback1.callback(), NetLogWithSource()));
robpercival214763f2016-07-01 23:27:0115326 EXPECT_THAT(callback1.WaitForResult(), IsError(ERR_CONNECTION_CLOSED));
[email protected]85f97342013-04-17 06:12:2415327
15328 // Now, start the second request and make sure it succeeds.
15329 HttpRequestInfo request2;
15330 request2.method = "GET";
15331 request2.url = GURL(https_url);
15332 request2.load_flags = 0;
[email protected]90499482013-06-01 00:39:5015333 HttpNetworkTransaction trans2(MEDIUM, session.get());
[email protected]85f97342013-04-17 06:12:2415334 TestCompletionCallback callback2;
15335 EXPECT_EQ(ERR_IO_PENDING,
tfarina42834112016-09-22 13:38:2015336 trans2.Start(&request2, callback2.callback(), NetLogWithSource()));
[email protected]85f97342013-04-17 06:12:2415337
robpercival214763f2016-07-01 23:27:0115338 ASSERT_THAT(callback2.WaitForResult(), IsOk());
[email protected]85f97342013-04-17 06:12:2415339 EXPECT_TRUE(trans2.GetResponseInfo()->was_fetched_via_spdy);
15340}
15341
bncd16676a2016-07-20 16:23:0115342TEST_F(HttpNetworkTransactionTest, CloseIdleSpdySessionToOpenNewOne) {
[email protected]483fa202013-05-14 01:07:0315343 ClientSocketPoolManager::set_max_sockets_per_group(
15344 HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
15345 ClientSocketPoolManager::set_max_sockets_per_pool(
15346 HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
15347
15348 // Use two different hosts with different IPs so they don't get pooled.
15349 session_deps_.host_resolver->rules()->AddRule("www.a.com", "10.0.0.1");
15350 session_deps_.host_resolver->rules()->AddRule("www.b.com", "10.0.0.2");
danakj1fd259a02016-04-16 03:17:0915351 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]483fa202013-05-14 01:07:0315352
15353 SSLSocketDataProvider ssl1(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3615354 ssl1.next_proto = kProtoHTTP2;
[email protected]483fa202013-05-14 01:07:0315355 SSLSocketDataProvider ssl2(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3615356 ssl2.next_proto = kProtoHTTP2;
[email protected]483fa202013-05-14 01:07:0315357 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl1);
15358 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
15359
bncdf80d44fd2016-07-15 20:27:4115360 SpdySerializedFrame host1_req(
bnc38dcd392016-02-09 23:19:4915361 spdy_util_.ConstructSpdyGet("https://www.a.com", 1, DEFAULT_PRIORITY));
[email protected]483fa202013-05-14 01:07:0315362 MockWrite spdy1_writes[] = {
bncdf80d44fd2016-07-15 20:27:4115363 CreateMockWrite(host1_req, 0),
[email protected]483fa202013-05-14 01:07:0315364 };
bnc42331402016-07-25 13:36:1515365 SpdySerializedFrame host1_resp(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
bncdf80d44fd2016-07-15 20:27:4115366 SpdySerializedFrame host1_resp_body(
15367 spdy_util_.ConstructSpdyDataFrame(1, true));
[email protected]483fa202013-05-14 01:07:0315368 MockRead spdy1_reads[] = {
bncdf80d44fd2016-07-15 20:27:4115369 CreateMockRead(host1_resp, 1), CreateMockRead(host1_resp_body, 2),
mmenkee24011922015-12-17 22:12:5915370 MockRead(SYNCHRONOUS, ERR_IO_PENDING, 3),
[email protected]483fa202013-05-14 01:07:0315371 };
15372
rdsmithebb50aa2015-11-12 03:44:3815373 // Use a separate test instance for the separate SpdySession that will be
15374 // created.
bncd16676a2016-07-20 16:23:0115375 SpdyTestUtil spdy_util_2;
Jeremy Roman0579ed62017-08-29 15:56:1915376 auto spdy1_data = std::make_unique<SequencedSocketData>(
bnc87dcefc2017-05-25 12:47:5815377 spdy1_reads, arraysize(spdy1_reads), spdy1_writes,
15378 arraysize(spdy1_writes));
[email protected]483fa202013-05-14 01:07:0315379 session_deps_.socket_factory->AddSocketDataProvider(spdy1_data.get());
15380
bncdf80d44fd2016-07-15 20:27:4115381 SpdySerializedFrame host2_req(
bnc38dcd392016-02-09 23:19:4915382 spdy_util_2.ConstructSpdyGet("https://www.b.com", 1, DEFAULT_PRIORITY));
[email protected]483fa202013-05-14 01:07:0315383 MockWrite spdy2_writes[] = {
bncdf80d44fd2016-07-15 20:27:4115384 CreateMockWrite(host2_req, 0),
[email protected]483fa202013-05-14 01:07:0315385 };
bnc42331402016-07-25 13:36:1515386 SpdySerializedFrame host2_resp(spdy_util_2.ConstructSpdyGetReply(NULL, 0, 1));
bncdf80d44fd2016-07-15 20:27:4115387 SpdySerializedFrame host2_resp_body(
15388 spdy_util_2.ConstructSpdyDataFrame(1, true));
[email protected]483fa202013-05-14 01:07:0315389 MockRead spdy2_reads[] = {
bncdf80d44fd2016-07-15 20:27:4115390 CreateMockRead(host2_resp, 1), CreateMockRead(host2_resp_body, 2),
mmenkee24011922015-12-17 22:12:5915391 MockRead(SYNCHRONOUS, ERR_IO_PENDING, 3),
[email protected]483fa202013-05-14 01:07:0315392 };
15393
Jeremy Roman0579ed62017-08-29 15:56:1915394 auto spdy2_data = std::make_unique<SequencedSocketData>(
bnc87dcefc2017-05-25 12:47:5815395 spdy2_reads, arraysize(spdy2_reads), spdy2_writes,
15396 arraysize(spdy2_writes));
[email protected]483fa202013-05-14 01:07:0315397 session_deps_.socket_factory->AddSocketDataProvider(spdy2_data.get());
15398
15399 MockWrite http_write[] = {
15400 MockWrite("GET / HTTP/1.1\r\n"
15401 "Host: www.a.com\r\n"
15402 "Connection: keep-alive\r\n\r\n"),
15403 };
15404
15405 MockRead http_read[] = {
15406 MockRead("HTTP/1.1 200 OK\r\n"),
15407 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
15408 MockRead("Content-Length: 6\r\n\r\n"),
15409 MockRead("hello!"),
15410 };
15411 StaticSocketDataProvider http_data(http_read, arraysize(http_read),
15412 http_write, arraysize(http_write));
15413 session_deps_.socket_factory->AddSocketDataProvider(&http_data);
15414
15415 HostPortPair host_port_pair_a("www.a.com", 443);
Paul Jensena457017a2018-01-19 23:52:0415416 SpdySessionKey spdy_session_key_a(host_port_pair_a, ProxyServer::Direct(),
15417 PRIVACY_MODE_DISABLED, SocketTag());
[email protected]483fa202013-05-14 01:07:0315418 EXPECT_FALSE(
[email protected]41d64e82013-07-03 22:44:2615419 HasSpdySession(session->spdy_session_pool(), spdy_session_key_a));
[email protected]483fa202013-05-14 01:07:0315420
15421 TestCompletionCallback callback;
15422 HttpRequestInfo request1;
15423 request1.method = "GET";
15424 request1.url = GURL("https://www.a.com/");
15425 request1.load_flags = 0;
bnc87dcefc2017-05-25 12:47:5815426 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:1915427 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]483fa202013-05-14 01:07:0315428
tfarina42834112016-09-22 13:38:2015429 int rv = trans->Start(&request1, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0115430 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
15431 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]483fa202013-05-14 01:07:0315432
15433 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5215434 ASSERT_TRUE(response);
15435 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0215436 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]483fa202013-05-14 01:07:0315437 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5215438 EXPECT_TRUE(response->was_alpn_negotiated);
[email protected]483fa202013-05-14 01:07:0315439
15440 std::string response_data;
robpercival214763f2016-07-01 23:27:0115441 ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
[email protected]483fa202013-05-14 01:07:0315442 EXPECT_EQ("hello!", response_data);
15443 trans.reset();
15444 EXPECT_TRUE(
[email protected]41d64e82013-07-03 22:44:2615445 HasSpdySession(session->spdy_session_pool(), spdy_session_key_a));
[email protected]483fa202013-05-14 01:07:0315446
15447 HostPortPair host_port_pair_b("www.b.com", 443);
Paul Jensena457017a2018-01-19 23:52:0415448 SpdySessionKey spdy_session_key_b(host_port_pair_b, ProxyServer::Direct(),
15449 PRIVACY_MODE_DISABLED, SocketTag());
[email protected]483fa202013-05-14 01:07:0315450 EXPECT_FALSE(
[email protected]41d64e82013-07-03 22:44:2615451 HasSpdySession(session->spdy_session_pool(), spdy_session_key_b));
[email protected]483fa202013-05-14 01:07:0315452 HttpRequestInfo request2;
15453 request2.method = "GET";
15454 request2.url = GURL("https://www.b.com/");
15455 request2.load_flags = 0;
bnc87dcefc2017-05-25 12:47:5815456 trans =
Jeremy Roman0579ed62017-08-29 15:56:1915457 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]483fa202013-05-14 01:07:0315458
tfarina42834112016-09-22 13:38:2015459 rv = trans->Start(&request2, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0115460 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
15461 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]483fa202013-05-14 01:07:0315462
15463 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5215464 ASSERT_TRUE(response);
15465 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0215466 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]483fa202013-05-14 01:07:0315467 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5215468 EXPECT_TRUE(response->was_alpn_negotiated);
robpercival214763f2016-07-01 23:27:0115469 ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
[email protected]483fa202013-05-14 01:07:0315470 EXPECT_EQ("hello!", response_data);
15471 EXPECT_FALSE(
[email protected]41d64e82013-07-03 22:44:2615472 HasSpdySession(session->spdy_session_pool(), spdy_session_key_a));
[email protected]483fa202013-05-14 01:07:0315473 EXPECT_TRUE(
[email protected]41d64e82013-07-03 22:44:2615474 HasSpdySession(session->spdy_session_pool(), spdy_session_key_b));
[email protected]483fa202013-05-14 01:07:0315475
15476 HostPortPair host_port_pair_a1("www.a.com", 80);
Paul Jensena457017a2018-01-19 23:52:0415477 SpdySessionKey spdy_session_key_a1(host_port_pair_a1, ProxyServer::Direct(),
15478 PRIVACY_MODE_DISABLED, SocketTag());
[email protected]483fa202013-05-14 01:07:0315479 EXPECT_FALSE(
[email protected]41d64e82013-07-03 22:44:2615480 HasSpdySession(session->spdy_session_pool(), spdy_session_key_a1));
[email protected]483fa202013-05-14 01:07:0315481 HttpRequestInfo request3;
15482 request3.method = "GET";
15483 request3.url = GURL("http://www.a.com/");
15484 request3.load_flags = 0;
bnc87dcefc2017-05-25 12:47:5815485 trans =
Jeremy Roman0579ed62017-08-29 15:56:1915486 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]483fa202013-05-14 01:07:0315487
tfarina42834112016-09-22 13:38:2015488 rv = trans->Start(&request3, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0115489 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
15490 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]483fa202013-05-14 01:07:0315491
15492 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5215493 ASSERT_TRUE(response);
15494 ASSERT_TRUE(response->headers);
[email protected]483fa202013-05-14 01:07:0315495 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
15496 EXPECT_FALSE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5215497 EXPECT_FALSE(response->was_alpn_negotiated);
robpercival214763f2016-07-01 23:27:0115498 ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
[email protected]483fa202013-05-14 01:07:0315499 EXPECT_EQ("hello!", response_data);
15500 EXPECT_FALSE(
[email protected]41d64e82013-07-03 22:44:2615501 HasSpdySession(session->spdy_session_pool(), spdy_session_key_a));
[email protected]483fa202013-05-14 01:07:0315502 EXPECT_FALSE(
[email protected]41d64e82013-07-03 22:44:2615503 HasSpdySession(session->spdy_session_pool(), spdy_session_key_b));
[email protected]483fa202013-05-14 01:07:0315504}
15505
bncd16676a2016-07-20 16:23:0115506TEST_F(HttpNetworkTransactionTest, HttpSyncConnectError) {
[email protected]79e1fd62013-06-20 06:50:0415507 HttpRequestInfo request;
15508 request.method = "GET";
bncce36dca22015-04-21 22:11:2315509 request.url = GURL("http://www.example.org/");
[email protected]79e1fd62013-06-20 06:50:0415510
danakj1fd259a02016-04-16 03:17:0915511 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1615512 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]79e1fd62013-06-20 06:50:0415513
ttuttled9dbc652015-09-29 20:00:5915514 MockConnect mock_connect(SYNCHRONOUS, ERR_NAME_NOT_RESOLVED);
[email protected]79e1fd62013-06-20 06:50:0415515 StaticSocketDataProvider data;
15516 data.set_connect_data(mock_connect);
15517 session_deps_.socket_factory->AddSocketDataProvider(&data);
15518
15519 TestCompletionCallback callback;
15520
tfarina42834112016-09-22 13:38:2015521 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0115522 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]79e1fd62013-06-20 06:50:0415523
15524 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0115525 EXPECT_THAT(rv, IsError(ERR_NAME_NOT_RESOLVED));
[email protected]79e1fd62013-06-20 06:50:0415526
[email protected]79e1fd62013-06-20 06:50:0415527 // We don't care whether this succeeds or fails, but it shouldn't crash.
15528 HttpRequestHeaders request_headers;
bnc691fda62016-08-12 00:43:1615529 trans.GetFullRequestHeaders(&request_headers);
ttuttle1f2d7e92015-04-28 16:17:4715530
15531 ConnectionAttempts attempts;
bnc691fda62016-08-12 00:43:1615532 trans.GetConnectionAttempts(&attempts);
ttuttle1f2d7e92015-04-28 16:17:4715533 ASSERT_EQ(1u, attempts.size());
robpercival214763f2016-07-01 23:27:0115534 EXPECT_THAT(attempts[0].result, IsError(ERR_NAME_NOT_RESOLVED));
ttuttled9dbc652015-09-29 20:00:5915535
15536 IPEndPoint endpoint;
bnc691fda62016-08-12 00:43:1615537 EXPECT_FALSE(trans.GetRemoteEndpoint(&endpoint));
ttuttled9dbc652015-09-29 20:00:5915538 EXPECT_TRUE(endpoint.address().empty());
[email protected]79e1fd62013-06-20 06:50:0415539}
15540
bncd16676a2016-07-20 16:23:0115541TEST_F(HttpNetworkTransactionTest, HttpAsyncConnectError) {
[email protected]79e1fd62013-06-20 06:50:0415542 HttpRequestInfo request;
15543 request.method = "GET";
bncce36dca22015-04-21 22:11:2315544 request.url = GURL("http://www.example.org/");
[email protected]79e1fd62013-06-20 06:50:0415545
danakj1fd259a02016-04-16 03:17:0915546 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1615547 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]79e1fd62013-06-20 06:50:0415548
ttuttled9dbc652015-09-29 20:00:5915549 MockConnect mock_connect(ASYNC, ERR_NAME_NOT_RESOLVED);
[email protected]79e1fd62013-06-20 06:50:0415550 StaticSocketDataProvider data;
15551 data.set_connect_data(mock_connect);
15552 session_deps_.socket_factory->AddSocketDataProvider(&data);
15553
15554 TestCompletionCallback callback;
15555
tfarina42834112016-09-22 13:38:2015556 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0115557 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]79e1fd62013-06-20 06:50:0415558
15559 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0115560 EXPECT_THAT(rv, IsError(ERR_NAME_NOT_RESOLVED));
[email protected]79e1fd62013-06-20 06:50:0415561
[email protected]79e1fd62013-06-20 06:50:0415562 // We don't care whether this succeeds or fails, but it shouldn't crash.
15563 HttpRequestHeaders request_headers;
bnc691fda62016-08-12 00:43:1615564 trans.GetFullRequestHeaders(&request_headers);
ttuttle1f2d7e92015-04-28 16:17:4715565
15566 ConnectionAttempts attempts;
bnc691fda62016-08-12 00:43:1615567 trans.GetConnectionAttempts(&attempts);
ttuttle1f2d7e92015-04-28 16:17:4715568 ASSERT_EQ(1u, attempts.size());
robpercival214763f2016-07-01 23:27:0115569 EXPECT_THAT(attempts[0].result, IsError(ERR_NAME_NOT_RESOLVED));
ttuttled9dbc652015-09-29 20:00:5915570
15571 IPEndPoint endpoint;
bnc691fda62016-08-12 00:43:1615572 EXPECT_FALSE(trans.GetRemoteEndpoint(&endpoint));
ttuttled9dbc652015-09-29 20:00:5915573 EXPECT_TRUE(endpoint.address().empty());
[email protected]79e1fd62013-06-20 06:50:0415574}
15575
bncd16676a2016-07-20 16:23:0115576TEST_F(HttpNetworkTransactionTest, HttpSyncWriteError) {
[email protected]79e1fd62013-06-20 06:50:0415577 HttpRequestInfo request;
15578 request.method = "GET";
bncce36dca22015-04-21 22:11:2315579 request.url = GURL("http://www.example.org/");
[email protected]79e1fd62013-06-20 06:50:0415580
danakj1fd259a02016-04-16 03:17:0915581 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1615582 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]79e1fd62013-06-20 06:50:0415583
15584 MockWrite data_writes[] = {
15585 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
15586 };
15587 MockRead data_reads[] = {
15588 MockRead(SYNCHRONOUS, ERR_UNEXPECTED), // Should not be reached.
15589 };
15590
15591 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
15592 data_writes, arraysize(data_writes));
15593 session_deps_.socket_factory->AddSocketDataProvider(&data);
15594
15595 TestCompletionCallback callback;
15596
tfarina42834112016-09-22 13:38:2015597 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0115598 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]79e1fd62013-06-20 06:50:0415599
15600 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0115601 EXPECT_THAT(rv, IsError(ERR_CONNECTION_RESET));
[email protected]79e1fd62013-06-20 06:50:0415602
[email protected]79e1fd62013-06-20 06:50:0415603 HttpRequestHeaders request_headers;
bnc691fda62016-08-12 00:43:1615604 EXPECT_TRUE(trans.GetFullRequestHeaders(&request_headers));
[email protected]79e1fd62013-06-20 06:50:0415605 EXPECT_TRUE(request_headers.HasHeader("Host"));
15606}
15607
bncd16676a2016-07-20 16:23:0115608TEST_F(HttpNetworkTransactionTest, HttpAsyncWriteError) {
[email protected]79e1fd62013-06-20 06:50:0415609 HttpRequestInfo request;
15610 request.method = "GET";
bncce36dca22015-04-21 22:11:2315611 request.url = GURL("http://www.example.org/");
[email protected]79e1fd62013-06-20 06:50:0415612
danakj1fd259a02016-04-16 03:17:0915613 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1615614 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]79e1fd62013-06-20 06:50:0415615
15616 MockWrite data_writes[] = {
15617 MockWrite(ASYNC, ERR_CONNECTION_RESET),
15618 };
15619 MockRead data_reads[] = {
15620 MockRead(SYNCHRONOUS, ERR_UNEXPECTED), // Should not be reached.
15621 };
15622
15623 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
15624 data_writes, arraysize(data_writes));
15625 session_deps_.socket_factory->AddSocketDataProvider(&data);
15626
15627 TestCompletionCallback callback;
15628
tfarina42834112016-09-22 13:38:2015629 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0115630 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]79e1fd62013-06-20 06:50:0415631
15632 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0115633 EXPECT_THAT(rv, IsError(ERR_CONNECTION_RESET));
[email protected]79e1fd62013-06-20 06:50:0415634
[email protected]79e1fd62013-06-20 06:50:0415635 HttpRequestHeaders request_headers;
bnc691fda62016-08-12 00:43:1615636 EXPECT_TRUE(trans.GetFullRequestHeaders(&request_headers));
[email protected]79e1fd62013-06-20 06:50:0415637 EXPECT_TRUE(request_headers.HasHeader("Host"));
15638}
15639
bncd16676a2016-07-20 16:23:0115640TEST_F(HttpNetworkTransactionTest, HttpSyncReadError) {
[email protected]79e1fd62013-06-20 06:50:0415641 HttpRequestInfo request;
15642 request.method = "GET";
bncce36dca22015-04-21 22:11:2315643 request.url = GURL("http://www.example.org/");
[email protected]79e1fd62013-06-20 06:50:0415644
danakj1fd259a02016-04-16 03:17:0915645 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1615646 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]79e1fd62013-06-20 06:50:0415647
15648 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:2315649 MockWrite(
15650 "GET / HTTP/1.1\r\n"
15651 "Host: www.example.org\r\n"
15652 "Connection: keep-alive\r\n\r\n"),
[email protected]79e1fd62013-06-20 06:50:0415653 };
15654 MockRead data_reads[] = {
15655 MockRead(SYNCHRONOUS, ERR_CONNECTION_RESET),
15656 };
15657
15658 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
15659 data_writes, arraysize(data_writes));
15660 session_deps_.socket_factory->AddSocketDataProvider(&data);
15661
15662 TestCompletionCallback callback;
15663
tfarina42834112016-09-22 13:38:2015664 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0115665 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]79e1fd62013-06-20 06:50:0415666
15667 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0115668 EXPECT_THAT(rv, IsError(ERR_CONNECTION_RESET));
[email protected]79e1fd62013-06-20 06:50:0415669
[email protected]79e1fd62013-06-20 06:50:0415670 HttpRequestHeaders request_headers;
bnc691fda62016-08-12 00:43:1615671 EXPECT_TRUE(trans.GetFullRequestHeaders(&request_headers));
[email protected]79e1fd62013-06-20 06:50:0415672 EXPECT_TRUE(request_headers.HasHeader("Host"));
15673}
15674
bncd16676a2016-07-20 16:23:0115675TEST_F(HttpNetworkTransactionTest, HttpAsyncReadError) {
[email protected]79e1fd62013-06-20 06:50:0415676 HttpRequestInfo request;
15677 request.method = "GET";
bncce36dca22015-04-21 22:11:2315678 request.url = GURL("http://www.example.org/");
[email protected]79e1fd62013-06-20 06:50:0415679
danakj1fd259a02016-04-16 03:17:0915680 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1615681 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]79e1fd62013-06-20 06:50:0415682
15683 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:2315684 MockWrite(
15685 "GET / HTTP/1.1\r\n"
15686 "Host: www.example.org\r\n"
15687 "Connection: keep-alive\r\n\r\n"),
[email protected]79e1fd62013-06-20 06:50:0415688 };
15689 MockRead data_reads[] = {
15690 MockRead(ASYNC, ERR_CONNECTION_RESET),
15691 };
15692
15693 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
15694 data_writes, arraysize(data_writes));
15695 session_deps_.socket_factory->AddSocketDataProvider(&data);
15696
15697 TestCompletionCallback callback;
15698
tfarina42834112016-09-22 13:38:2015699 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0115700 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]79e1fd62013-06-20 06:50:0415701
15702 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0115703 EXPECT_THAT(rv, IsError(ERR_CONNECTION_RESET));
[email protected]79e1fd62013-06-20 06:50:0415704
[email protected]79e1fd62013-06-20 06:50:0415705 HttpRequestHeaders request_headers;
bnc691fda62016-08-12 00:43:1615706 EXPECT_TRUE(trans.GetFullRequestHeaders(&request_headers));
[email protected]79e1fd62013-06-20 06:50:0415707 EXPECT_TRUE(request_headers.HasHeader("Host"));
15708}
15709
bncd16676a2016-07-20 16:23:0115710TEST_F(HttpNetworkTransactionTest, GetFullRequestHeadersIncludesExtraHeader) {
[email protected]79e1fd62013-06-20 06:50:0415711 HttpRequestInfo request;
15712 request.method = "GET";
bncce36dca22015-04-21 22:11:2315713 request.url = GURL("http://www.example.org/");
[email protected]79e1fd62013-06-20 06:50:0415714 request.extra_headers.SetHeader("X-Foo", "bar");
15715
danakj1fd259a02016-04-16 03:17:0915716 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1615717 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]79e1fd62013-06-20 06:50:0415718
15719 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:2315720 MockWrite(
15721 "GET / HTTP/1.1\r\n"
15722 "Host: www.example.org\r\n"
15723 "Connection: keep-alive\r\n"
15724 "X-Foo: bar\r\n\r\n"),
[email protected]79e1fd62013-06-20 06:50:0415725 };
15726 MockRead data_reads[] = {
15727 MockRead("HTTP/1.1 200 OK\r\n"
15728 "Content-Length: 5\r\n\r\n"
15729 "hello"),
15730 MockRead(ASYNC, ERR_UNEXPECTED),
15731 };
15732
15733 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
15734 data_writes, arraysize(data_writes));
15735 session_deps_.socket_factory->AddSocketDataProvider(&data);
15736
15737 TestCompletionCallback callback;
15738
tfarina42834112016-09-22 13:38:2015739 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0115740 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]79e1fd62013-06-20 06:50:0415741
15742 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0115743 EXPECT_THAT(rv, IsOk());
[email protected]79e1fd62013-06-20 06:50:0415744
15745 HttpRequestHeaders request_headers;
bnc691fda62016-08-12 00:43:1615746 EXPECT_TRUE(trans.GetFullRequestHeaders(&request_headers));
[email protected]79e1fd62013-06-20 06:50:0415747 std::string foo;
15748 EXPECT_TRUE(request_headers.GetHeader("X-Foo", &foo));
15749 EXPECT_EQ("bar", foo);
15750}
15751
[email protected]bf828982013-08-14 18:01:4715752namespace {
15753
yhiranoa7e05bb2014-11-06 05:40:3915754// Fake HttpStream that simply records calls to SetPriority().
15755class FakeStream : public HttpStream,
[email protected]e86839fd2013-08-14 18:29:0315756 public base::SupportsWeakPtr<FakeStream> {
15757 public:
15758 explicit FakeStream(RequestPriority priority) : priority_(priority) {}
Chris Watkins7a41d3552017-12-01 02:13:2715759 ~FakeStream() override = default;
[email protected]e86839fd2013-08-14 18:29:0315760
15761 RequestPriority priority() const { return priority_; }
15762
dchengb03027d2014-10-21 12:00:2015763 int InitializeStream(const HttpRequestInfo* request_info,
Steven Valdezb4ff0412018-01-18 22:39:2715764 bool can_send_early,
dchengb03027d2014-10-21 12:00:2015765 RequestPriority priority,
tfarina42834112016-09-22 13:38:2015766 const NetLogWithSource& net_log,
dchengb03027d2014-10-21 12:00:2015767 const CompletionCallback& callback) override {
[email protected]e86839fd2013-08-14 18:29:0315768 return ERR_IO_PENDING;
15769 }
15770
dchengb03027d2014-10-21 12:00:2015771 int SendRequest(const HttpRequestHeaders& request_headers,
15772 HttpResponseInfo* response,
15773 const CompletionCallback& callback) override {
[email protected]e86839fd2013-08-14 18:29:0315774 ADD_FAILURE();
15775 return ERR_UNEXPECTED;
15776 }
15777
dchengb03027d2014-10-21 12:00:2015778 int ReadResponseHeaders(const CompletionCallback& callback) override {
[email protected]e86839fd2013-08-14 18:29:0315779 ADD_FAILURE();
15780 return ERR_UNEXPECTED;
15781 }
15782
dchengb03027d2014-10-21 12:00:2015783 int ReadResponseBody(IOBuffer* buf,
15784 int buf_len,
15785 const CompletionCallback& callback) override {
[email protected]e86839fd2013-08-14 18:29:0315786 ADD_FAILURE();
15787 return ERR_UNEXPECTED;
15788 }
15789
dchengb03027d2014-10-21 12:00:2015790 void Close(bool not_reusable) override {}
[email protected]e86839fd2013-08-14 18:29:0315791
dchengb03027d2014-10-21 12:00:2015792 bool IsResponseBodyComplete() const override {
[email protected]e86839fd2013-08-14 18:29:0315793 ADD_FAILURE();
15794 return false;
15795 }
15796
dchengb03027d2014-10-21 12:00:2015797 bool IsConnectionReused() const override {
[email protected]e86839fd2013-08-14 18:29:0315798 ADD_FAILURE();
15799 return false;
15800 }
15801
dchengb03027d2014-10-21 12:00:2015802 void SetConnectionReused() override { ADD_FAILURE(); }
[email protected]e86839fd2013-08-14 18:29:0315803
mmenkebd84c392015-09-02 14:12:3415804 bool CanReuseConnection() const override { return false; }
[email protected]e86839fd2013-08-14 18:29:0315805
sclittle4de1bab92015-09-22 21:28:2415806 int64_t GetTotalReceivedBytes() const override {
[email protected]bc92bc972013-12-13 08:32:5915807 ADD_FAILURE();
15808 return 0;
15809 }
15810
sclittlebe1ccf62015-09-02 19:40:3615811 int64_t GetTotalSentBytes() const override {
15812 ADD_FAILURE();
15813 return 0;
15814 }
15815
dchengb03027d2014-10-21 12:00:2015816 bool GetLoadTimingInfo(LoadTimingInfo* load_timing_info) const override {
[email protected]e86839fd2013-08-14 18:29:0315817 ADD_FAILURE();
15818 return false;
15819 }
15820
rchcd379012017-04-12 21:53:3215821 bool GetAlternativeService(
15822 AlternativeService* alternative_service) const override {
15823 ADD_FAILURE();
15824 return false;
15825 }
15826
dchengb03027d2014-10-21 12:00:2015827 void GetSSLInfo(SSLInfo* ssl_info) override { ADD_FAILURE(); }
15828
15829 void GetSSLCertRequestInfo(SSLCertRequestInfo* cert_request_info) override {
[email protected]e86839fd2013-08-14 18:29:0315830 ADD_FAILURE();
15831 }
15832
ttuttled9dbc652015-09-29 20:00:5915833 bool GetRemoteEndpoint(IPEndPoint* endpoint) override { return false; }
15834
nharper78e6d2b2016-09-21 05:42:3515835 Error GetTokenBindingSignature(crypto::ECPrivateKey* key,
15836 TokenBindingType tb_type,
15837 std::vector<uint8_t>* out) override {
nharperb7441ef2016-01-25 23:54:1415838 ADD_FAILURE();
15839 return ERR_NOT_IMPLEMENTED;
15840 }
15841
dchengb03027d2014-10-21 12:00:2015842 void Drain(HttpNetworkSession* session) override { ADD_FAILURE(); }
[email protected]e86839fd2013-08-14 18:29:0315843
zhongyica364fbb2015-12-12 03:39:1215844 void PopulateNetErrorDetails(NetErrorDetails* details) override { return; }
15845
dchengb03027d2014-10-21 12:00:2015846 void SetPriority(RequestPriority priority) override { priority_ = priority; }
[email protected]e86839fd2013-08-14 18:29:0315847
yhiranoa7e05bb2014-11-06 05:40:3915848 HttpStream* RenewStreamForAuth() override { return NULL; }
15849
Andrey Kosyakov83a6eee2017-08-14 19:20:0415850 void SetRequestHeadersCallback(RequestHeadersCallback callback) override {}
15851
[email protected]e86839fd2013-08-14 18:29:0315852 private:
15853 RequestPriority priority_;
15854
15855 DISALLOW_COPY_AND_ASSIGN(FakeStream);
15856};
15857
15858// Fake HttpStreamRequest that simply records calls to SetPriority()
15859// and vends FakeStreams with its current priority.
[email protected]bf828982013-08-14 18:01:4715860class FakeStreamRequest : public HttpStreamRequest,
15861 public base::SupportsWeakPtr<FakeStreamRequest> {
15862 public:
[email protected]e86839fd2013-08-14 18:29:0315863 FakeStreamRequest(RequestPriority priority,
15864 HttpStreamRequest::Delegate* delegate)
15865 : priority_(priority),
[email protected]831e4a32013-11-14 02:14:4415866 delegate_(delegate),
15867 websocket_stream_create_helper_(NULL) {}
15868
15869 FakeStreamRequest(RequestPriority priority,
15870 HttpStreamRequest::Delegate* delegate,
15871 WebSocketHandshakeStreamBase::CreateHelper* create_helper)
15872 : priority_(priority),
15873 delegate_(delegate),
15874 websocket_stream_create_helper_(create_helper) {}
[email protected]e86839fd2013-08-14 18:29:0315875
Chris Watkins7a41d3552017-12-01 02:13:2715876 ~FakeStreamRequest() override = default;
[email protected]bf828982013-08-14 18:01:4715877
15878 RequestPriority priority() const { return priority_; }
15879
[email protected]831e4a32013-11-14 02:14:4415880 const WebSocketHandshakeStreamBase::CreateHelper*
15881 websocket_stream_create_helper() const {
15882 return websocket_stream_create_helper_;
15883 }
15884
[email protected]e86839fd2013-08-14 18:29:0315885 // Create a new FakeStream and pass it to the request's
15886 // delegate. Returns a weak pointer to the FakeStream.
15887 base::WeakPtr<FakeStream> FinishStreamRequest() {
Jeremy Roman0579ed62017-08-29 15:56:1915888 auto fake_stream = std::make_unique<FakeStream>(priority_);
[email protected]e86839fd2013-08-14 18:29:0315889 // Do this before calling OnStreamReady() as OnStreamReady() may
15890 // immediately delete |fake_stream|.
15891 base::WeakPtr<FakeStream> weak_stream = fake_stream->AsWeakPtr();
bnc5029f4632017-06-08 16:19:0015892 delegate_->OnStreamReady(SSLConfig(), ProxyInfo(), std::move(fake_stream));
[email protected]e86839fd2013-08-14 18:29:0315893 return weak_stream;
15894 }
15895
asanka681f02d2017-02-22 17:06:3915896 int RestartTunnelWithProxyAuth() override {
[email protected]bf828982013-08-14 18:01:4715897 ADD_FAILURE();
15898 return ERR_UNEXPECTED;
15899 }
15900
dchengb03027d2014-10-21 12:00:2015901 LoadState GetLoadState() const override {
[email protected]bf828982013-08-14 18:01:4715902 ADD_FAILURE();
15903 return LoadState();
15904 }
15905
dchengb03027d2014-10-21 12:00:2015906 void SetPriority(RequestPriority priority) override { priority_ = priority; }
[email protected]bf828982013-08-14 18:01:4715907
bnc94c92842016-09-21 15:22:5215908 bool was_alpn_negotiated() const override { return false; }
[email protected]bf828982013-08-14 18:01:4715909
bnc6227b26e2016-08-12 02:00:4315910 NextProto negotiated_protocol() const override { return kProtoUnknown; }
[email protected]bf828982013-08-14 18:01:4715911
dchengb03027d2014-10-21 12:00:2015912 bool using_spdy() const override { return false; }
[email protected]bf828982013-08-14 18:01:4715913
ttuttle1f2d7e92015-04-28 16:17:4715914 const ConnectionAttempts& connection_attempts() const override {
15915 static ConnectionAttempts no_attempts;
15916 return no_attempts;
15917 }
15918
[email protected]bf828982013-08-14 18:01:4715919 private:
15920 RequestPriority priority_;
[email protected]e86839fd2013-08-14 18:29:0315921 HttpStreamRequest::Delegate* const delegate_;
[email protected]831e4a32013-11-14 02:14:4415922 WebSocketHandshakeStreamBase::CreateHelper* websocket_stream_create_helper_;
[email protected]bf828982013-08-14 18:01:4715923
15924 DISALLOW_COPY_AND_ASSIGN(FakeStreamRequest);
15925};
15926
15927// Fake HttpStreamFactory that vends FakeStreamRequests.
15928class FakeStreamFactory : public HttpStreamFactory {
15929 public:
Chris Watkins7a41d3552017-12-01 02:13:2715930 FakeStreamFactory() = default;
15931 ~FakeStreamFactory() override = default;
[email protected]bf828982013-08-14 18:01:4715932
15933 // Returns a WeakPtr<> to the last HttpStreamRequest returned by
15934 // RequestStream() (which may be NULL if it was destroyed already).
15935 base::WeakPtr<FakeStreamRequest> last_stream_request() {
15936 return last_stream_request_;
15937 }
15938
xunjieli96f2a402017-06-05 17:24:2715939 std::unique_ptr<HttpStreamRequest> RequestStream(
15940 const HttpRequestInfo& info,
15941 RequestPriority priority,
15942 const SSLConfig& server_ssl_config,
15943 const SSLConfig& proxy_ssl_config,
15944 HttpStreamRequest::Delegate* delegate,
15945 bool enable_ip_based_pooling,
15946 bool enable_alternative_services,
15947 const NetLogWithSource& net_log) override {
Jeremy Roman0579ed62017-08-29 15:56:1915948 auto fake_request = std::make_unique<FakeStreamRequest>(priority, delegate);
[email protected]bf828982013-08-14 18:01:4715949 last_stream_request_ = fake_request->AsWeakPtr();
xunjieli96f2a402017-06-05 17:24:2715950 return std::move(fake_request);
[email protected]bf828982013-08-14 18:01:4715951 }
15952
xunjieli96f2a402017-06-05 17:24:2715953 std::unique_ptr<HttpStreamRequest> RequestBidirectionalStreamImpl(
xunjieli11834f02015-12-22 04:27:0815954 const HttpRequestInfo& info,
15955 RequestPriority priority,
15956 const SSLConfig& server_ssl_config,
15957 const SSLConfig& proxy_ssl_config,
15958 HttpStreamRequest::Delegate* delegate,
bnc8016c1f2017-03-31 02:11:2915959 bool enable_ip_based_pooling,
bncaccd4962017-04-06 21:00:2615960 bool enable_alternative_services,
tfarina42834112016-09-22 13:38:2015961 const NetLogWithSource& net_log) override {
xunjieli11834f02015-12-22 04:27:0815962 NOTREACHED();
15963 return nullptr;
15964 }
15965
xunjieli96f2a402017-06-05 17:24:2715966 std::unique_ptr<HttpStreamRequest> RequestWebSocketHandshakeStream(
[email protected]bf828982013-08-14 18:01:4715967 const HttpRequestInfo& info,
15968 RequestPriority priority,
15969 const SSLConfig& server_ssl_config,
15970 const SSLConfig& proxy_ssl_config,
15971 HttpStreamRequest::Delegate* delegate,
[email protected]467086b2013-11-12 08:19:4615972 WebSocketHandshakeStreamBase::CreateHelper* create_helper,
bnc8016c1f2017-03-31 02:11:2915973 bool enable_ip_based_pooling,
bncaccd4962017-04-06 21:00:2615974 bool enable_alternative_services,
tfarina42834112016-09-22 13:38:2015975 const NetLogWithSource& net_log) override {
xunjieli96f2a402017-06-05 17:24:2715976 auto fake_request =
Jeremy Roman0579ed62017-08-29 15:56:1915977 std::make_unique<FakeStreamRequest>(priority, delegate, create_helper);
[email protected]831e4a32013-11-14 02:14:4415978 last_stream_request_ = fake_request->AsWeakPtr();
xunjieli96f2a402017-06-05 17:24:2715979 return std::move(fake_request);
[email protected]bf828982013-08-14 18:01:4715980 }
15981
dchengb03027d2014-10-21 12:00:2015982 void PreconnectStreams(int num_streams,
nharper8cdb0fb2016-04-22 21:34:5915983 const HttpRequestInfo& info) override {
[email protected]bf828982013-08-14 18:01:4715984 ADD_FAILURE();
15985 }
15986
dchengb03027d2014-10-21 12:00:2015987 const HostMappingRules* GetHostMappingRules() const override {
[email protected]bf828982013-08-14 18:01:4715988 ADD_FAILURE();
15989 return NULL;
15990 }
15991
xunjielif5267de2017-01-20 21:18:5715992 void DumpMemoryStats(base::trace_event::ProcessMemoryDump* pmd,
15993 const std::string& parent_absolute_name) const override {
15994 ADD_FAILURE();
15995 }
15996
[email protected]bf828982013-08-14 18:01:4715997 private:
15998 base::WeakPtr<FakeStreamRequest> last_stream_request_;
15999
16000 DISALLOW_COPY_AND_ASSIGN(FakeStreamFactory);
16001};
16002
Adam Rice425cf122015-01-19 06:18:2416003// TODO(ricea): Maybe unify this with the one in
16004// url_request_http_job_unittest.cc ?
16005class FakeWebSocketBasicHandshakeStream : public WebSocketHandshakeStreamBase {
16006 public:
danakj1fd259a02016-04-16 03:17:0916007 FakeWebSocketBasicHandshakeStream(
16008 std::unique_ptr<ClientSocketHandle> connection,
16009 bool using_proxy)
mmenkea7da6da2016-09-01 21:56:5216010 : state_(std::move(connection), using_proxy, false) {}
Adam Rice425cf122015-01-19 06:18:2416011
16012 // Fake implementation of HttpStreamBase methods.
16013 // This ends up being quite "real" because this object has to really send data
16014 // on the mock socket. It might be easier to use the real implementation, but
16015 // the fact that the WebSocket code is not compiled on iOS makes that
16016 // difficult.
16017 int InitializeStream(const HttpRequestInfo* request_info,
Steven Valdezb4ff0412018-01-18 22:39:2716018 bool can_send_early,
Adam Rice425cf122015-01-19 06:18:2416019 RequestPriority priority,
tfarina42834112016-09-22 13:38:2016020 const NetLogWithSource& net_log,
Adam Rice425cf122015-01-19 06:18:2416021 const CompletionCallback& callback) override {
Steven Valdezb4ff0412018-01-18 22:39:2716022 state_.Initialize(request_info, can_send_early, priority, net_log,
16023 callback);
Adam Rice425cf122015-01-19 06:18:2416024 return OK;
16025 }
16026
16027 int SendRequest(const HttpRequestHeaders& request_headers,
16028 HttpResponseInfo* response,
16029 const CompletionCallback& callback) override {
16030 return parser()->SendRequest(state_.GenerateRequestLine(), request_headers,
[email protected]baee31a2018-01-18 06:10:2316031 TRAFFIC_ANNOTATION_FOR_TESTS, response,
16032 callback);
Adam Rice425cf122015-01-19 06:18:2416033 }
16034
16035 int ReadResponseHeaders(const CompletionCallback& callback) override {
16036 return parser()->ReadResponseHeaders(callback);
16037 }
16038
16039 int ReadResponseBody(IOBuffer* buf,
16040 int buf_len,
16041 const CompletionCallback& callback) override {
16042 NOTREACHED();
16043 return ERR_IO_PENDING;
16044 }
16045
16046 void Close(bool not_reusable) override {
16047 if (parser())
16048 parser()->Close(true);
16049 }
16050
16051 bool IsResponseBodyComplete() const override {
16052 NOTREACHED();
16053 return false;
16054 }
16055
Adam Rice425cf122015-01-19 06:18:2416056 bool IsConnectionReused() const override {
16057 NOTREACHED();
16058 return false;
16059 }
16060 void SetConnectionReused() override { NOTREACHED(); }
16061
mmenkebd84c392015-09-02 14:12:3416062 bool CanReuseConnection() const override { return false; }
Adam Rice425cf122015-01-19 06:18:2416063
sclittle4de1bab92015-09-22 21:28:2416064 int64_t GetTotalReceivedBytes() const override {
Adam Rice425cf122015-01-19 06:18:2416065 NOTREACHED();
16066 return 0;
16067 }
16068
sclittlebe1ccf62015-09-02 19:40:3616069 int64_t GetTotalSentBytes() const override {
16070 NOTREACHED();
16071 return 0;
16072 }
16073
Adam Rice425cf122015-01-19 06:18:2416074 bool GetLoadTimingInfo(LoadTimingInfo* load_timing_info) const override {
16075 NOTREACHED();
16076 return false;
16077 }
16078
rchcd379012017-04-12 21:53:3216079 bool GetAlternativeService(
16080 AlternativeService* alternative_service) const override {
16081 ADD_FAILURE();
16082 return false;
16083 }
16084
Adam Ricecb76ac62015-02-20 05:33:2516085 void GetSSLInfo(SSLInfo* ssl_info) override {}
Adam Rice425cf122015-01-19 06:18:2416086
16087 void GetSSLCertRequestInfo(SSLCertRequestInfo* cert_request_info) override {
16088 NOTREACHED();
16089 }
16090
ttuttled9dbc652015-09-29 20:00:5916091 bool GetRemoteEndpoint(IPEndPoint* endpoint) override { return false; }
16092
nharper78e6d2b2016-09-21 05:42:3516093 Error GetTokenBindingSignature(crypto::ECPrivateKey* key,
16094 TokenBindingType tb_type,
16095 std::vector<uint8_t>* out) override {
nharperb7441ef2016-01-25 23:54:1416096 ADD_FAILURE();
16097 return ERR_NOT_IMPLEMENTED;
16098 }
16099
Adam Rice425cf122015-01-19 06:18:2416100 void Drain(HttpNetworkSession* session) override { NOTREACHED(); }
16101
zhongyica364fbb2015-12-12 03:39:1216102 void PopulateNetErrorDetails(NetErrorDetails* details) override { return; }
16103
Adam Rice425cf122015-01-19 06:18:2416104 void SetPriority(RequestPriority priority) override { NOTREACHED(); }
16105
Adam Rice425cf122015-01-19 06:18:2416106 HttpStream* RenewStreamForAuth() override {
16107 NOTREACHED();
16108 return nullptr;
16109 }
16110
16111 // Fake implementation of WebSocketHandshakeStreamBase method(s)
danakj1fd259a02016-04-16 03:17:0916112 std::unique_ptr<WebSocketStream> Upgrade() override {
Adam Rice425cf122015-01-19 06:18:2416113 NOTREACHED();
danakj1fd259a02016-04-16 03:17:0916114 return std::unique_ptr<WebSocketStream>();
Adam Rice425cf122015-01-19 06:18:2416115 }
16116
16117 private:
16118 HttpStreamParser* parser() const { return state_.parser(); }
16119 HttpBasicState state_;
16120
16121 DISALLOW_COPY_AND_ASSIGN(FakeWebSocketBasicHandshakeStream);
16122};
16123
[email protected]831e4a32013-11-14 02:14:4416124// TODO(yhirano): Split this class out into a net/websockets file, if it is
16125// worth doing.
16126class FakeWebSocketStreamCreateHelper :
16127 public WebSocketHandshakeStreamBase::CreateHelper {
16128 public:
bnc615cf2f2017-05-19 18:53:2616129 std::unique_ptr<WebSocketHandshakeStreamBase> CreateBasicStream(
danakj1fd259a02016-04-16 03:17:0916130 std::unique_ptr<ClientSocketHandle> connection,
mostynbba063d6032014-10-09 11:01:1316131 bool using_proxy) override {
Jeremy Roman0579ed62017-08-29 15:56:1916132 return std::make_unique<FakeWebSocketBasicHandshakeStream>(
bnc615cf2f2017-05-19 18:53:2616133 std::move(connection), using_proxy);
[email protected]831e4a32013-11-14 02:14:4416134 }
16135
Chris Watkins7a41d3552017-12-01 02:13:2716136 ~FakeWebSocketStreamCreateHelper() override = default;
[email protected]831e4a32013-11-14 02:14:4416137
danakj1fd259a02016-04-16 03:17:0916138 virtual std::unique_ptr<WebSocketStream> Upgrade() {
[email protected]831e4a32013-11-14 02:14:4416139 NOTREACHED();
danakj1fd259a02016-04-16 03:17:0916140 return std::unique_ptr<WebSocketStream>();
[email protected]831e4a32013-11-14 02:14:4416141 }
16142};
16143
[email protected]bf828982013-08-14 18:01:4716144} // namespace
16145
16146// Make sure that HttpNetworkTransaction passes on its priority to its
16147// stream request on start.
bncd16676a2016-07-20 16:23:0116148TEST_F(HttpNetworkTransactionTest, SetStreamRequestPriorityOnStart) {
danakj1fd259a02016-04-16 03:17:0916149 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
mmenkee65e7af2015-10-13 17:16:4216150 HttpNetworkSessionPeer peer(session.get());
[email protected]bf828982013-08-14 18:01:4716151 FakeStreamFactory* fake_factory = new FakeStreamFactory();
danakj1fd259a02016-04-16 03:17:0916152 peer.SetHttpStreamFactory(std::unique_ptr<HttpStreamFactory>(fake_factory));
[email protected]bf828982013-08-14 18:01:4716153
krasinc06a72a2016-12-21 03:42:4616154 HttpRequestInfo request;
dcheng48459ac22014-08-26 00:46:4116155 HttpNetworkTransaction trans(LOW, session.get());
[email protected]bf828982013-08-14 18:01:4716156
wezca1070932016-05-26 20:30:5216157 ASSERT_FALSE(fake_factory->last_stream_request());
[email protected]bf828982013-08-14 18:01:4716158
[email protected]bf828982013-08-14 18:01:4716159 TestCompletionCallback callback;
16160 EXPECT_EQ(ERR_IO_PENDING,
tfarina42834112016-09-22 13:38:2016161 trans.Start(&request, callback.callback(), NetLogWithSource()));
[email protected]bf828982013-08-14 18:01:4716162
16163 base::WeakPtr<FakeStreamRequest> fake_request =
16164 fake_factory->last_stream_request();
wezca1070932016-05-26 20:30:5216165 ASSERT_TRUE(fake_request);
[email protected]bf828982013-08-14 18:01:4716166 EXPECT_EQ(LOW, fake_request->priority());
16167}
16168
16169// Make sure that HttpNetworkTransaction passes on its priority
16170// updates to its stream request.
bncd16676a2016-07-20 16:23:0116171TEST_F(HttpNetworkTransactionTest, SetStreamRequestPriority) {
danakj1fd259a02016-04-16 03:17:0916172 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
mmenkee65e7af2015-10-13 17:16:4216173 HttpNetworkSessionPeer peer(session.get());
[email protected]bf828982013-08-14 18:01:4716174 FakeStreamFactory* fake_factory = new FakeStreamFactory();
danakj1fd259a02016-04-16 03:17:0916175 peer.SetHttpStreamFactory(std::unique_ptr<HttpStreamFactory>(fake_factory));
[email protected]bf828982013-08-14 18:01:4716176
krasinc06a72a2016-12-21 03:42:4616177 HttpRequestInfo request;
dcheng48459ac22014-08-26 00:46:4116178 HttpNetworkTransaction trans(LOW, session.get());
[email protected]bf828982013-08-14 18:01:4716179
[email protected]bf828982013-08-14 18:01:4716180 TestCompletionCallback callback;
16181 EXPECT_EQ(ERR_IO_PENDING,
tfarina42834112016-09-22 13:38:2016182 trans.Start(&request, callback.callback(), NetLogWithSource()));
[email protected]bf828982013-08-14 18:01:4716183
16184 base::WeakPtr<FakeStreamRequest> fake_request =
16185 fake_factory->last_stream_request();
wezca1070932016-05-26 20:30:5216186 ASSERT_TRUE(fake_request);
[email protected]bf828982013-08-14 18:01:4716187 EXPECT_EQ(LOW, fake_request->priority());
16188
16189 trans.SetPriority(LOWEST);
wezca1070932016-05-26 20:30:5216190 ASSERT_TRUE(fake_request);
[email protected]bf828982013-08-14 18:01:4716191 EXPECT_EQ(LOWEST, fake_request->priority());
16192}
16193
[email protected]e86839fd2013-08-14 18:29:0316194// Make sure that HttpNetworkTransaction passes on its priority
16195// updates to its stream.
bncd16676a2016-07-20 16:23:0116196TEST_F(HttpNetworkTransactionTest, SetStreamPriority) {
danakj1fd259a02016-04-16 03:17:0916197 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
mmenkee65e7af2015-10-13 17:16:4216198 HttpNetworkSessionPeer peer(session.get());
[email protected]e86839fd2013-08-14 18:29:0316199 FakeStreamFactory* fake_factory = new FakeStreamFactory();
danakj1fd259a02016-04-16 03:17:0916200 peer.SetHttpStreamFactory(std::unique_ptr<HttpStreamFactory>(fake_factory));
[email protected]e86839fd2013-08-14 18:29:0316201
krasinc06a72a2016-12-21 03:42:4616202 HttpRequestInfo request;
dcheng48459ac22014-08-26 00:46:4116203 HttpNetworkTransaction trans(LOW, session.get());
[email protected]e86839fd2013-08-14 18:29:0316204
[email protected]e86839fd2013-08-14 18:29:0316205 TestCompletionCallback callback;
16206 EXPECT_EQ(ERR_IO_PENDING,
tfarina42834112016-09-22 13:38:2016207 trans.Start(&request, callback.callback(), NetLogWithSource()));
[email protected]e86839fd2013-08-14 18:29:0316208
16209 base::WeakPtr<FakeStreamRequest> fake_request =
16210 fake_factory->last_stream_request();
wezca1070932016-05-26 20:30:5216211 ASSERT_TRUE(fake_request);
[email protected]e86839fd2013-08-14 18:29:0316212 base::WeakPtr<FakeStream> fake_stream = fake_request->FinishStreamRequest();
wezca1070932016-05-26 20:30:5216213 ASSERT_TRUE(fake_stream);
[email protected]e86839fd2013-08-14 18:29:0316214 EXPECT_EQ(LOW, fake_stream->priority());
16215
16216 trans.SetPriority(LOWEST);
16217 EXPECT_EQ(LOWEST, fake_stream->priority());
16218}
16219
bncd16676a2016-07-20 16:23:0116220TEST_F(HttpNetworkTransactionTest, CreateWebSocketHandshakeStream) {
[email protected]831e4a32013-11-14 02:14:4416221 // The same logic needs to be tested for both ws: and wss: schemes, but this
16222 // test is already parameterised on NextProto, so it uses a loop to verify
16223 // that the different schemes work.
bncce36dca22015-04-21 22:11:2316224 std::string test_cases[] = {"ws://www.example.org/",
16225 "wss://www.example.org/"};
[email protected]831e4a32013-11-14 02:14:4416226 for (size_t i = 0; i < arraysize(test_cases); ++i) {
danakj1fd259a02016-04-16 03:17:0916227 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
mmenkee65e7af2015-10-13 17:16:4216228 HttpNetworkSessionPeer peer(session.get());
[email protected]831e4a32013-11-14 02:14:4416229 FakeStreamFactory* fake_factory = new FakeStreamFactory();
16230 FakeWebSocketStreamCreateHelper websocket_stream_create_helper;
Bence Béky8cae04e2018-01-15 18:37:0616231 peer.SetHttpStreamFactory(std::unique_ptr<HttpStreamFactory>(fake_factory));
[email protected]831e4a32013-11-14 02:14:4416232
krasinc06a72a2016-12-21 03:42:4616233 HttpRequestInfo request;
dcheng48459ac22014-08-26 00:46:4116234 HttpNetworkTransaction trans(LOW, session.get());
[email protected]831e4a32013-11-14 02:14:4416235 trans.SetWebSocketHandshakeStreamCreateHelper(
16236 &websocket_stream_create_helper);
16237
[email protected]831e4a32013-11-14 02:14:4416238 TestCompletionCallback callback;
16239 request.method = "GET";
16240 request.url = GURL(test_cases[i]);
16241
16242 EXPECT_EQ(ERR_IO_PENDING,
tfarina42834112016-09-22 13:38:2016243 trans.Start(&request, callback.callback(), NetLogWithSource()));
[email protected]831e4a32013-11-14 02:14:4416244
16245 base::WeakPtr<FakeStreamRequest> fake_request =
16246 fake_factory->last_stream_request();
wezca1070932016-05-26 20:30:5216247 ASSERT_TRUE(fake_request);
[email protected]831e4a32013-11-14 02:14:4416248 EXPECT_EQ(&websocket_stream_create_helper,
16249 fake_request->websocket_stream_create_helper());
16250 }
16251}
16252
[email protected]043b68c82013-08-22 23:41:5216253// Tests that when a used socket is returned to the SSL socket pool, it's closed
16254// if the transport socket pool is stalled on the global socket limit.
bncd16676a2016-07-20 16:23:0116255TEST_F(HttpNetworkTransactionTest, CloseSSLSocketOnIdleForHttpRequest) {
[email protected]043b68c82013-08-22 23:41:5216256 ClientSocketPoolManager::set_max_sockets_per_group(
16257 HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
16258 ClientSocketPoolManager::set_max_sockets_per_pool(
16259 HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
16260
16261 // Set up SSL request.
16262
16263 HttpRequestInfo ssl_request;
16264 ssl_request.method = "GET";
bncce36dca22015-04-21 22:11:2316265 ssl_request.url = GURL("https://www.example.org/");
[email protected]043b68c82013-08-22 23:41:5216266
16267 MockWrite ssl_writes[] = {
bncce36dca22015-04-21 22:11:2316268 MockWrite(
16269 "GET / HTTP/1.1\r\n"
16270 "Host: www.example.org\r\n"
16271 "Connection: keep-alive\r\n\r\n"),
[email protected]043b68c82013-08-22 23:41:5216272 };
16273 MockRead ssl_reads[] = {
16274 MockRead("HTTP/1.1 200 OK\r\n"),
16275 MockRead("Content-Length: 11\r\n\r\n"),
16276 MockRead("hello world"),
16277 MockRead(SYNCHRONOUS, OK),
16278 };
16279 StaticSocketDataProvider ssl_data(ssl_reads, arraysize(ssl_reads),
16280 ssl_writes, arraysize(ssl_writes));
16281 session_deps_.socket_factory->AddSocketDataProvider(&ssl_data);
16282
16283 SSLSocketDataProvider ssl(ASYNC, OK);
16284 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
16285
16286 // Set up HTTP request.
16287
16288 HttpRequestInfo http_request;
16289 http_request.method = "GET";
bncce36dca22015-04-21 22:11:2316290 http_request.url = GURL("http://www.example.org/");
[email protected]043b68c82013-08-22 23:41:5216291
16292 MockWrite http_writes[] = {
bncce36dca22015-04-21 22:11:2316293 MockWrite(
16294 "GET / HTTP/1.1\r\n"
16295 "Host: www.example.org\r\n"
16296 "Connection: keep-alive\r\n\r\n"),
[email protected]043b68c82013-08-22 23:41:5216297 };
16298 MockRead http_reads[] = {
16299 MockRead("HTTP/1.1 200 OK\r\n"),
16300 MockRead("Content-Length: 7\r\n\r\n"),
16301 MockRead("falafel"),
16302 MockRead(SYNCHRONOUS, OK),
16303 };
16304 StaticSocketDataProvider http_data(http_reads, arraysize(http_reads),
16305 http_writes, arraysize(http_writes));
16306 session_deps_.socket_factory->AddSocketDataProvider(&http_data);
16307
danakj1fd259a02016-04-16 03:17:0916308 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]043b68c82013-08-22 23:41:5216309
16310 // Start the SSL request.
16311 TestCompletionCallback ssl_callback;
bnc691fda62016-08-12 00:43:1616312 HttpNetworkTransaction ssl_trans(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:2016313 ASSERT_EQ(ERR_IO_PENDING,
16314 ssl_trans.Start(&ssl_request, ssl_callback.callback(),
16315 NetLogWithSource()));
[email protected]043b68c82013-08-22 23:41:5216316
16317 // Start the HTTP request. Pool should stall.
16318 TestCompletionCallback http_callback;
bnc691fda62016-08-12 00:43:1616319 HttpNetworkTransaction http_trans(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:2016320 ASSERT_EQ(ERR_IO_PENDING,
16321 http_trans.Start(&http_request, http_callback.callback(),
16322 NetLogWithSource()));
dcheng48459ac22014-08-26 00:46:4116323 EXPECT_TRUE(IsTransportSocketPoolStalled(session.get()));
[email protected]043b68c82013-08-22 23:41:5216324
16325 // Wait for response from SSL request.
robpercival214763f2016-07-01 23:27:0116326 ASSERT_THAT(ssl_callback.WaitForResult(), IsOk());
[email protected]043b68c82013-08-22 23:41:5216327 std::string response_data;
bnc691fda62016-08-12 00:43:1616328 ASSERT_THAT(ReadTransaction(&ssl_trans, &response_data), IsOk());
[email protected]043b68c82013-08-22 23:41:5216329 EXPECT_EQ("hello world", response_data);
16330
16331 // The SSL socket should automatically be closed, so the HTTP request can
16332 // start.
dcheng48459ac22014-08-26 00:46:4116333 EXPECT_EQ(0, GetIdleSocketCountInSSLSocketPool(session.get()));
16334 ASSERT_FALSE(IsTransportSocketPoolStalled(session.get()));
[email protected]043b68c82013-08-22 23:41:5216335
16336 // The HTTP request can now complete.
robpercival214763f2016-07-01 23:27:0116337 ASSERT_THAT(http_callback.WaitForResult(), IsOk());
bnc691fda62016-08-12 00:43:1616338 ASSERT_THAT(ReadTransaction(&http_trans, &response_data), IsOk());
[email protected]043b68c82013-08-22 23:41:5216339 EXPECT_EQ("falafel", response_data);
16340
dcheng48459ac22014-08-26 00:46:4116341 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]043b68c82013-08-22 23:41:5216342}
16343
16344// Tests that when a SSL connection is established but there's no corresponding
16345// request that needs it, the new socket is closed if the transport socket pool
16346// is stalled on the global socket limit.
bncd16676a2016-07-20 16:23:0116347TEST_F(HttpNetworkTransactionTest, CloseSSLSocketOnIdleForHttpRequest2) {
[email protected]043b68c82013-08-22 23:41:5216348 ClientSocketPoolManager::set_max_sockets_per_group(
16349 HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
16350 ClientSocketPoolManager::set_max_sockets_per_pool(
16351 HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
16352
16353 // Set up an ssl request.
16354
16355 HttpRequestInfo ssl_request;
16356 ssl_request.method = "GET";
16357 ssl_request.url = GURL("https://www.foopy.com/");
16358
16359 // No data will be sent on the SSL socket.
16360 StaticSocketDataProvider ssl_data;
16361 session_deps_.socket_factory->AddSocketDataProvider(&ssl_data);
16362
16363 SSLSocketDataProvider ssl(ASYNC, OK);
16364 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
16365
16366 // Set up HTTP request.
16367
16368 HttpRequestInfo http_request;
16369 http_request.method = "GET";
bncce36dca22015-04-21 22:11:2316370 http_request.url = GURL("http://www.example.org/");
[email protected]043b68c82013-08-22 23:41:5216371
16372 MockWrite http_writes[] = {
bncce36dca22015-04-21 22:11:2316373 MockWrite(
16374 "GET / HTTP/1.1\r\n"
16375 "Host: www.example.org\r\n"
16376 "Connection: keep-alive\r\n\r\n"),
[email protected]043b68c82013-08-22 23:41:5216377 };
16378 MockRead http_reads[] = {
16379 MockRead("HTTP/1.1 200 OK\r\n"),
16380 MockRead("Content-Length: 7\r\n\r\n"),
16381 MockRead("falafel"),
16382 MockRead(SYNCHRONOUS, OK),
16383 };
16384 StaticSocketDataProvider http_data(http_reads, arraysize(http_reads),
16385 http_writes, arraysize(http_writes));
16386 session_deps_.socket_factory->AddSocketDataProvider(&http_data);
16387
danakj1fd259a02016-04-16 03:17:0916388 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]043b68c82013-08-22 23:41:5216389
16390 // Preconnect an SSL socket. A preconnect is needed because connect jobs are
16391 // cancelled when a normal transaction is cancelled.
ttuttle859dc7a2015-04-23 19:42:2916392 HttpStreamFactory* http_stream_factory = session->http_stream_factory();
nharper8cdb0fb2016-04-22 21:34:5916393 http_stream_factory->PreconnectStreams(1, ssl_request);
dcheng48459ac22014-08-26 00:46:4116394 EXPECT_EQ(0, GetIdleSocketCountInSSLSocketPool(session.get()));
[email protected]043b68c82013-08-22 23:41:5216395
16396 // Start the HTTP request. Pool should stall.
16397 TestCompletionCallback http_callback;
bnc691fda62016-08-12 00:43:1616398 HttpNetworkTransaction http_trans(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:2016399 ASSERT_EQ(ERR_IO_PENDING,
16400 http_trans.Start(&http_request, http_callback.callback(),
16401 NetLogWithSource()));
dcheng48459ac22014-08-26 00:46:4116402 EXPECT_TRUE(IsTransportSocketPoolStalled(session.get()));
[email protected]043b68c82013-08-22 23:41:5216403
16404 // The SSL connection will automatically be closed once the connection is
16405 // established, to let the HTTP request start.
robpercival214763f2016-07-01 23:27:0116406 ASSERT_THAT(http_callback.WaitForResult(), IsOk());
[email protected]043b68c82013-08-22 23:41:5216407 std::string response_data;
bnc691fda62016-08-12 00:43:1616408 ASSERT_THAT(ReadTransaction(&http_trans, &response_data), IsOk());
[email protected]043b68c82013-08-22 23:41:5216409 EXPECT_EQ("falafel", response_data);
16410
dcheng48459ac22014-08-26 00:46:4116411 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]043b68c82013-08-22 23:41:5216412}
16413
bncd16676a2016-07-20 16:23:0116414TEST_F(HttpNetworkTransactionTest, PostReadsErrorResponseAfterReset) {
danakj1fd259a02016-04-16 03:17:0916415 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:2216416 element_readers.push_back(
Jeremy Roman0579ed62017-08-29 15:56:1916417 std::make_unique<UploadBytesElementReader>("foo", 3));
olli.raula6df48b2a2015-11-26 07:40:2216418 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]02d74a02014-04-23 18:10:5416419
16420 HttpRequestInfo request;
16421 request.method = "POST";
16422 request.url = GURL("http://www.foo.com/");
16423 request.upload_data_stream = &upload_data_stream;
[email protected]02d74a02014-04-23 18:10:5416424
danakj1fd259a02016-04-16 03:17:0916425 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1616426 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]02d74a02014-04-23 18:10:5416427 // Send headers successfully, but get an error while sending the body.
16428 MockWrite data_writes[] = {
16429 MockWrite("POST / HTTP/1.1\r\n"
16430 "Host: www.foo.com\r\n"
16431 "Connection: keep-alive\r\n"
16432 "Content-Length: 3\r\n\r\n"),
16433 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
16434 };
16435
16436 MockRead data_reads[] = {
16437 MockRead("HTTP/1.0 400 Not OK\r\n\r\n"),
16438 MockRead("hello world"),
16439 MockRead(SYNCHRONOUS, OK),
16440 };
16441 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
16442 arraysize(data_writes));
16443 session_deps_.socket_factory->AddSocketDataProvider(&data);
16444
16445 TestCompletionCallback callback;
16446
tfarina42834112016-09-22 13:38:2016447 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0116448 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]02d74a02014-04-23 18:10:5416449
16450 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0116451 EXPECT_THAT(rv, IsOk());
[email protected]02d74a02014-04-23 18:10:5416452
bnc691fda62016-08-12 00:43:1616453 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5216454 ASSERT_TRUE(response);
[email protected]02d74a02014-04-23 18:10:5416455
wezca1070932016-05-26 20:30:5216456 EXPECT_TRUE(response->headers);
[email protected]02d74a02014-04-23 18:10:5416457 EXPECT_EQ("HTTP/1.0 400 Not OK", response->headers->GetStatusLine());
16458
16459 std::string response_data;
bnc691fda62016-08-12 00:43:1616460 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:0116461 EXPECT_THAT(rv, IsOk());
[email protected]02d74a02014-04-23 18:10:5416462 EXPECT_EQ("hello world", response_data);
16463}
16464
16465// This test makes sure the retry logic doesn't trigger when reading an error
16466// response from a server that rejected a POST with a CONNECTION_RESET.
bncd16676a2016-07-20 16:23:0116467TEST_F(HttpNetworkTransactionTest,
[email protected]02d74a02014-04-23 18:10:5416468 PostReadsErrorResponseAfterResetOnReusedSocket) {
danakj1fd259a02016-04-16 03:17:0916469 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]02d74a02014-04-23 18:10:5416470 MockWrite data_writes[] = {
16471 MockWrite("GET / HTTP/1.1\r\n"
16472 "Host: www.foo.com\r\n"
16473 "Connection: keep-alive\r\n\r\n"),
16474 MockWrite("POST / HTTP/1.1\r\n"
16475 "Host: www.foo.com\r\n"
16476 "Connection: keep-alive\r\n"
16477 "Content-Length: 3\r\n\r\n"),
16478 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
16479 };
16480
16481 MockRead data_reads[] = {
16482 MockRead("HTTP/1.1 200 Peachy\r\n"
16483 "Content-Length: 14\r\n\r\n"),
16484 MockRead("first response"),
16485 MockRead("HTTP/1.1 400 Not OK\r\n"
16486 "Content-Length: 15\r\n\r\n"),
16487 MockRead("second response"),
16488 MockRead(SYNCHRONOUS, OK),
16489 };
16490 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
16491 arraysize(data_writes));
16492 session_deps_.socket_factory->AddSocketDataProvider(&data);
16493
16494 TestCompletionCallback callback;
16495 HttpRequestInfo request1;
16496 request1.method = "GET";
16497 request1.url = GURL("http://www.foo.com/");
16498 request1.load_flags = 0;
16499
bnc87dcefc2017-05-25 12:47:5816500 auto trans1 =
Jeremy Roman0579ed62017-08-29 15:56:1916501 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:2016502 int rv = trans1->Start(&request1, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0116503 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]02d74a02014-04-23 18:10:5416504
16505 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0116506 EXPECT_THAT(rv, IsOk());
[email protected]02d74a02014-04-23 18:10:5416507
16508 const HttpResponseInfo* response1 = trans1->GetResponseInfo();
wezca1070932016-05-26 20:30:5216509 ASSERT_TRUE(response1);
[email protected]02d74a02014-04-23 18:10:5416510
wezca1070932016-05-26 20:30:5216511 EXPECT_TRUE(response1->headers);
[email protected]02d74a02014-04-23 18:10:5416512 EXPECT_EQ("HTTP/1.1 200 Peachy", response1->headers->GetStatusLine());
16513
16514 std::string response_data1;
16515 rv = ReadTransaction(trans1.get(), &response_data1);
robpercival214763f2016-07-01 23:27:0116516 EXPECT_THAT(rv, IsOk());
[email protected]02d74a02014-04-23 18:10:5416517 EXPECT_EQ("first response", response_data1);
16518 // Delete the transaction to release the socket back into the socket pool.
16519 trans1.reset();
16520
danakj1fd259a02016-04-16 03:17:0916521 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:2216522 element_readers.push_back(
Jeremy Roman0579ed62017-08-29 15:56:1916523 std::make_unique<UploadBytesElementReader>("foo", 3));
olli.raula6df48b2a2015-11-26 07:40:2216524 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]02d74a02014-04-23 18:10:5416525
16526 HttpRequestInfo request2;
16527 request2.method = "POST";
16528 request2.url = GURL("http://www.foo.com/");
16529 request2.upload_data_stream = &upload_data_stream;
16530 request2.load_flags = 0;
16531
bnc691fda62016-08-12 00:43:1616532 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:2016533 rv = trans2.Start(&request2, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0116534 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]02d74a02014-04-23 18:10:5416535
16536 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0116537 EXPECT_THAT(rv, IsOk());
[email protected]02d74a02014-04-23 18:10:5416538
bnc691fda62016-08-12 00:43:1616539 const HttpResponseInfo* response2 = trans2.GetResponseInfo();
wezca1070932016-05-26 20:30:5216540 ASSERT_TRUE(response2);
[email protected]02d74a02014-04-23 18:10:5416541
wezca1070932016-05-26 20:30:5216542 EXPECT_TRUE(response2->headers);
[email protected]02d74a02014-04-23 18:10:5416543 EXPECT_EQ("HTTP/1.1 400 Not OK", response2->headers->GetStatusLine());
16544
16545 std::string response_data2;
bnc691fda62016-08-12 00:43:1616546 rv = ReadTransaction(&trans2, &response_data2);
robpercival214763f2016-07-01 23:27:0116547 EXPECT_THAT(rv, IsOk());
[email protected]02d74a02014-04-23 18:10:5416548 EXPECT_EQ("second response", response_data2);
16549}
16550
bncd16676a2016-07-20 16:23:0116551TEST_F(HttpNetworkTransactionTest,
[email protected]02d74a02014-04-23 18:10:5416552 PostReadsErrorResponseAfterResetPartialBodySent) {
danakj1fd259a02016-04-16 03:17:0916553 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:2216554 element_readers.push_back(
Jeremy Roman0579ed62017-08-29 15:56:1916555 std::make_unique<UploadBytesElementReader>("foo", 3));
olli.raula6df48b2a2015-11-26 07:40:2216556 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]02d74a02014-04-23 18:10:5416557
16558 HttpRequestInfo request;
16559 request.method = "POST";
16560 request.url = GURL("http://www.foo.com/");
16561 request.upload_data_stream = &upload_data_stream;
[email protected]02d74a02014-04-23 18:10:5416562
danakj1fd259a02016-04-16 03:17:0916563 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1616564 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]02d74a02014-04-23 18:10:5416565 // Send headers successfully, but get an error while sending the body.
16566 MockWrite data_writes[] = {
16567 MockWrite("POST / HTTP/1.1\r\n"
16568 "Host: www.foo.com\r\n"
16569 "Connection: keep-alive\r\n"
16570 "Content-Length: 3\r\n\r\n"
16571 "fo"),
16572 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
16573 };
16574
16575 MockRead data_reads[] = {
16576 MockRead("HTTP/1.0 400 Not OK\r\n\r\n"),
16577 MockRead("hello world"),
16578 MockRead(SYNCHRONOUS, OK),
16579 };
16580 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
16581 arraysize(data_writes));
16582 session_deps_.socket_factory->AddSocketDataProvider(&data);
16583
16584 TestCompletionCallback callback;
16585
tfarina42834112016-09-22 13:38:2016586 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0116587 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]02d74a02014-04-23 18:10:5416588
16589 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0116590 EXPECT_THAT(rv, IsOk());
[email protected]02d74a02014-04-23 18:10:5416591
bnc691fda62016-08-12 00:43:1616592 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5216593 ASSERT_TRUE(response);
[email protected]02d74a02014-04-23 18:10:5416594
wezca1070932016-05-26 20:30:5216595 EXPECT_TRUE(response->headers);
[email protected]02d74a02014-04-23 18:10:5416596 EXPECT_EQ("HTTP/1.0 400 Not OK", response->headers->GetStatusLine());
16597
16598 std::string response_data;
bnc691fda62016-08-12 00:43:1616599 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:0116600 EXPECT_THAT(rv, IsOk());
[email protected]02d74a02014-04-23 18:10:5416601 EXPECT_EQ("hello world", response_data);
16602}
16603
16604// This tests the more common case than the previous test, where headers and
16605// body are not merged into a single request.
bncd16676a2016-07-20 16:23:0116606TEST_F(HttpNetworkTransactionTest, ChunkedPostReadsErrorResponseAfterReset) {
mmenkecbc2b712014-10-09 20:29:0716607 ChunkedUploadDataStream upload_data_stream(0);
[email protected]02d74a02014-04-23 18:10:5416608
16609 HttpRequestInfo request;
16610 request.method = "POST";
16611 request.url = GURL("http://www.foo.com/");
16612 request.upload_data_stream = &upload_data_stream;
[email protected]02d74a02014-04-23 18:10:5416613
danakj1fd259a02016-04-16 03:17:0916614 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1616615 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]02d74a02014-04-23 18:10:5416616 // Send headers successfully, but get an error while sending the body.
16617 MockWrite data_writes[] = {
16618 MockWrite("POST / HTTP/1.1\r\n"
16619 "Host: www.foo.com\r\n"
16620 "Connection: keep-alive\r\n"
16621 "Transfer-Encoding: chunked\r\n\r\n"),
16622 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
16623 };
16624
16625 MockRead data_reads[] = {
16626 MockRead("HTTP/1.0 400 Not OK\r\n\r\n"),
16627 MockRead("hello world"),
16628 MockRead(SYNCHRONOUS, OK),
16629 };
16630 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
16631 arraysize(data_writes));
16632 session_deps_.socket_factory->AddSocketDataProvider(&data);
16633
16634 TestCompletionCallback callback;
16635
tfarina42834112016-09-22 13:38:2016636 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0116637 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]02d74a02014-04-23 18:10:5416638 // Make sure the headers are sent before adding a chunk. This ensures that
16639 // they can't be merged with the body in a single send. Not currently
16640 // necessary since a chunked body is never merged with headers, but this makes
16641 // the test more future proof.
16642 base::RunLoop().RunUntilIdle();
16643
mmenkecbc2b712014-10-09 20:29:0716644 upload_data_stream.AppendData("last chunk", 10, true);
[email protected]02d74a02014-04-23 18:10:5416645
16646 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0116647 EXPECT_THAT(rv, IsOk());
[email protected]02d74a02014-04-23 18:10:5416648
bnc691fda62016-08-12 00:43:1616649 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5216650 ASSERT_TRUE(response);
[email protected]02d74a02014-04-23 18:10:5416651
wezca1070932016-05-26 20:30:5216652 EXPECT_TRUE(response->headers);
[email protected]02d74a02014-04-23 18:10:5416653 EXPECT_EQ("HTTP/1.0 400 Not OK", response->headers->GetStatusLine());
16654
16655 std::string response_data;
bnc691fda62016-08-12 00:43:1616656 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:0116657 EXPECT_THAT(rv, IsOk());
[email protected]02d74a02014-04-23 18:10:5416658 EXPECT_EQ("hello world", response_data);
16659}
16660
bncd16676a2016-07-20 16:23:0116661TEST_F(HttpNetworkTransactionTest, PostReadsErrorResponseAfterResetAnd100) {
danakj1fd259a02016-04-16 03:17:0916662 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:2216663 element_readers.push_back(
Jeremy Roman0579ed62017-08-29 15:56:1916664 std::make_unique<UploadBytesElementReader>("foo", 3));
olli.raula6df48b2a2015-11-26 07:40:2216665 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]02d74a02014-04-23 18:10:5416666
16667 HttpRequestInfo request;
16668 request.method = "POST";
16669 request.url = GURL("http://www.foo.com/");
16670 request.upload_data_stream = &upload_data_stream;
[email protected]02d74a02014-04-23 18:10:5416671
danakj1fd259a02016-04-16 03:17:0916672 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1616673 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]02d74a02014-04-23 18:10:5416674
16675 MockWrite data_writes[] = {
16676 MockWrite("POST / HTTP/1.1\r\n"
16677 "Host: www.foo.com\r\n"
16678 "Connection: keep-alive\r\n"
16679 "Content-Length: 3\r\n\r\n"),
16680 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
16681 };
16682
16683 MockRead data_reads[] = {
16684 MockRead("HTTP/1.0 100 Continue\r\n\r\n"),
16685 MockRead("HTTP/1.0 400 Not OK\r\n\r\n"),
16686 MockRead("hello world"),
16687 MockRead(SYNCHRONOUS, OK),
16688 };
16689 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
16690 arraysize(data_writes));
16691 session_deps_.socket_factory->AddSocketDataProvider(&data);
16692
16693 TestCompletionCallback callback;
16694
tfarina42834112016-09-22 13:38:2016695 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0116696 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]02d74a02014-04-23 18:10:5416697
16698 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0116699 EXPECT_THAT(rv, IsOk());
[email protected]02d74a02014-04-23 18:10:5416700
bnc691fda62016-08-12 00:43:1616701 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5216702 ASSERT_TRUE(response);
[email protected]02d74a02014-04-23 18:10:5416703
wezca1070932016-05-26 20:30:5216704 EXPECT_TRUE(response->headers);
[email protected]02d74a02014-04-23 18:10:5416705 EXPECT_EQ("HTTP/1.0 400 Not OK", response->headers->GetStatusLine());
16706
16707 std::string response_data;
bnc691fda62016-08-12 00:43:1616708 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:0116709 EXPECT_THAT(rv, IsOk());
[email protected]02d74a02014-04-23 18:10:5416710 EXPECT_EQ("hello world", response_data);
16711}
16712
bncd16676a2016-07-20 16:23:0116713TEST_F(HttpNetworkTransactionTest, PostIgnoresNonErrorResponseAfterReset) {
danakj1fd259a02016-04-16 03:17:0916714 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:2216715 element_readers.push_back(
Jeremy Roman0579ed62017-08-29 15:56:1916716 std::make_unique<UploadBytesElementReader>("foo", 3));
olli.raula6df48b2a2015-11-26 07:40:2216717 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]02d74a02014-04-23 18:10:5416718
16719 HttpRequestInfo request;
16720 request.method = "POST";
16721 request.url = GURL("http://www.foo.com/");
16722 request.upload_data_stream = &upload_data_stream;
[email protected]02d74a02014-04-23 18:10:5416723
danakj1fd259a02016-04-16 03:17:0916724 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1616725 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]02d74a02014-04-23 18:10:5416726 // Send headers successfully, but get an error while sending the body.
16727 MockWrite data_writes[] = {
16728 MockWrite("POST / HTTP/1.1\r\n"
16729 "Host: www.foo.com\r\n"
16730 "Connection: keep-alive\r\n"
16731 "Content-Length: 3\r\n\r\n"),
16732 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
16733 };
16734
16735 MockRead data_reads[] = {
16736 MockRead("HTTP/1.0 200 Just Dandy\r\n\r\n"),
16737 MockRead("hello world"),
16738 MockRead(SYNCHRONOUS, OK),
16739 };
16740 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
16741 arraysize(data_writes));
16742 session_deps_.socket_factory->AddSocketDataProvider(&data);
16743
16744 TestCompletionCallback callback;
16745
tfarina42834112016-09-22 13:38:2016746 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0116747 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]02d74a02014-04-23 18:10:5416748
16749 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0116750 EXPECT_THAT(rv, IsError(ERR_CONNECTION_RESET));
[email protected]02d74a02014-04-23 18:10:5416751}
16752
bncd16676a2016-07-20 16:23:0116753TEST_F(HttpNetworkTransactionTest,
[email protected]02d74a02014-04-23 18:10:5416754 PostIgnoresNonErrorResponseAfterResetAnd100) {
danakj1fd259a02016-04-16 03:17:0916755 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:2216756 element_readers.push_back(
Jeremy Roman0579ed62017-08-29 15:56:1916757 std::make_unique<UploadBytesElementReader>("foo", 3));
olli.raula6df48b2a2015-11-26 07:40:2216758 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]02d74a02014-04-23 18:10:5416759
16760 HttpRequestInfo request;
16761 request.method = "POST";
16762 request.url = GURL("http://www.foo.com/");
16763 request.upload_data_stream = &upload_data_stream;
[email protected]02d74a02014-04-23 18:10:5416764
danakj1fd259a02016-04-16 03:17:0916765 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1616766 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]02d74a02014-04-23 18:10:5416767 // Send headers successfully, but get an error while sending the body.
16768 MockWrite data_writes[] = {
16769 MockWrite("POST / HTTP/1.1\r\n"
16770 "Host: www.foo.com\r\n"
16771 "Connection: keep-alive\r\n"
16772 "Content-Length: 3\r\n\r\n"),
16773 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
16774 };
16775
16776 MockRead data_reads[] = {
16777 MockRead("HTTP/1.0 100 Continue\r\n\r\n"),
16778 MockRead("HTTP/1.0 302 Redirect\r\n"),
16779 MockRead("Location: http://somewhere-else.com/\r\n"),
16780 MockRead("Content-Length: 0\r\n\r\n"),
16781 MockRead(SYNCHRONOUS, OK),
16782 };
16783 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
16784 arraysize(data_writes));
16785 session_deps_.socket_factory->AddSocketDataProvider(&data);
16786
16787 TestCompletionCallback callback;
16788
tfarina42834112016-09-22 13:38:2016789 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0116790 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]02d74a02014-04-23 18:10:5416791
16792 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0116793 EXPECT_THAT(rv, IsError(ERR_CONNECTION_RESET));
[email protected]02d74a02014-04-23 18:10:5416794}
16795
bncd16676a2016-07-20 16:23:0116796TEST_F(HttpNetworkTransactionTest, PostIgnoresHttp09ResponseAfterReset) {
danakj1fd259a02016-04-16 03:17:0916797 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:2216798 element_readers.push_back(
Jeremy Roman0579ed62017-08-29 15:56:1916799 std::make_unique<UploadBytesElementReader>("foo", 3));
olli.raula6df48b2a2015-11-26 07:40:2216800 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]02d74a02014-04-23 18:10:5416801
16802 HttpRequestInfo request;
16803 request.method = "POST";
16804 request.url = GURL("http://www.foo.com/");
16805 request.upload_data_stream = &upload_data_stream;
[email protected]02d74a02014-04-23 18:10:5416806
danakj1fd259a02016-04-16 03:17:0916807 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1616808 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]02d74a02014-04-23 18:10:5416809 // Send headers successfully, but get an error while sending the body.
16810 MockWrite data_writes[] = {
16811 MockWrite("POST / HTTP/1.1\r\n"
16812 "Host: www.foo.com\r\n"
16813 "Connection: keep-alive\r\n"
16814 "Content-Length: 3\r\n\r\n"),
16815 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
16816 };
16817
16818 MockRead data_reads[] = {
16819 MockRead("HTTP 0.9 rocks!"),
16820 MockRead(SYNCHRONOUS, OK),
16821 };
16822 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
16823 arraysize(data_writes));
16824 session_deps_.socket_factory->AddSocketDataProvider(&data);
16825
16826 TestCompletionCallback callback;
16827
tfarina42834112016-09-22 13:38:2016828 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0116829 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]02d74a02014-04-23 18:10:5416830
16831 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0116832 EXPECT_THAT(rv, IsError(ERR_CONNECTION_RESET));
[email protected]02d74a02014-04-23 18:10:5416833}
16834
bncd16676a2016-07-20 16:23:0116835TEST_F(HttpNetworkTransactionTest, PostIgnoresPartial400HeadersAfterReset) {
danakj1fd259a02016-04-16 03:17:0916836 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:2216837 element_readers.push_back(
Jeremy Roman0579ed62017-08-29 15:56:1916838 std::make_unique<UploadBytesElementReader>("foo", 3));
olli.raula6df48b2a2015-11-26 07:40:2216839 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]02d74a02014-04-23 18:10:5416840
16841 HttpRequestInfo request;
16842 request.method = "POST";
16843 request.url = GURL("http://www.foo.com/");
16844 request.upload_data_stream = &upload_data_stream;
[email protected]02d74a02014-04-23 18:10:5416845
danakj1fd259a02016-04-16 03:17:0916846 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1616847 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]02d74a02014-04-23 18:10:5416848 // Send headers successfully, but get an error while sending the body.
16849 MockWrite data_writes[] = {
16850 MockWrite("POST / HTTP/1.1\r\n"
16851 "Host: www.foo.com\r\n"
16852 "Connection: keep-alive\r\n"
16853 "Content-Length: 3\r\n\r\n"),
16854 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
16855 };
16856
16857 MockRead data_reads[] = {
16858 MockRead("HTTP/1.0 400 Not a Full Response\r\n"),
16859 MockRead(SYNCHRONOUS, OK),
16860 };
16861 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
16862 arraysize(data_writes));
16863 session_deps_.socket_factory->AddSocketDataProvider(&data);
16864
16865 TestCompletionCallback callback;
16866
tfarina42834112016-09-22 13:38:2016867 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0116868 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]02d74a02014-04-23 18:10:5416869
16870 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0116871 EXPECT_THAT(rv, IsError(ERR_CONNECTION_RESET));
[email protected]02d74a02014-04-23 18:10:5416872}
16873
Adam Rice425cf122015-01-19 06:18:2416874// Verify that proxy headers are not sent to the destination server when
16875// establishing a tunnel for a secure WebSocket connection.
bncd16676a2016-07-20 16:23:0116876TEST_F(HttpNetworkTransactionTest, ProxyHeadersNotSentOverWssTunnel) {
Adam Rice425cf122015-01-19 06:18:2416877 HttpRequestInfo request;
16878 request.method = "GET";
bncce36dca22015-04-21 22:11:2316879 request.url = GURL("wss://www.example.org/");
Adam Rice425cf122015-01-19 06:18:2416880 AddWebSocketHeaders(&request.extra_headers);
16881
16882 // Configure against proxy server "myproxy:70".
Lily Houghton8c2f97d2018-01-22 05:06:5916883 session_deps_.proxy_resolution_service =
16884 ProxyResolutionService::CreateFixedFromPacResult("PROXY myproxy:70");
Adam Rice425cf122015-01-19 06:18:2416885
danakj1fd259a02016-04-16 03:17:0916886 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
Adam Rice425cf122015-01-19 06:18:2416887
16888 // Since a proxy is configured, try to establish a tunnel.
16889 MockWrite data_writes[] = {
rsleevidb16bb02015-11-12 23:47:1716890 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
16891 "Host: www.example.org:443\r\n"
16892 "Proxy-Connection: keep-alive\r\n\r\n"),
Adam Rice425cf122015-01-19 06:18:2416893
16894 // After calling trans->RestartWithAuth(), this is the request we should
16895 // be issuing -- the final header line contains the credentials.
rsleevidb16bb02015-11-12 23:47:1716896 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
16897 "Host: www.example.org:443\r\n"
16898 "Proxy-Connection: keep-alive\r\n"
16899 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
Adam Rice425cf122015-01-19 06:18:2416900
rsleevidb16bb02015-11-12 23:47:1716901 MockWrite("GET / HTTP/1.1\r\n"
16902 "Host: www.example.org\r\n"
16903 "Connection: Upgrade\r\n"
16904 "Upgrade: websocket\r\n"
16905 "Origin: http://www.example.org\r\n"
16906 "Sec-WebSocket-Version: 13\r\n"
16907 "Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==\r\n\r\n"),
Adam Rice425cf122015-01-19 06:18:2416908 };
16909
16910 // The proxy responds to the connect with a 407, using a persistent
16911 // connection.
16912 MockRead data_reads[] = {
16913 // No credentials.
16914 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
16915 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
mmenkee71e15332015-10-07 16:39:5416916 MockRead("Content-Length: 0\r\n"),
16917 MockRead("Proxy-Connection: keep-alive\r\n\r\n"),
Adam Rice425cf122015-01-19 06:18:2416918
16919 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
16920
16921 MockRead("HTTP/1.1 101 Switching Protocols\r\n"),
16922 MockRead("Upgrade: websocket\r\n"),
16923 MockRead("Connection: Upgrade\r\n"),
16924 MockRead("Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=\r\n\r\n"),
16925 };
16926
16927 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
16928 arraysize(data_writes));
16929 session_deps_.socket_factory->AddSocketDataProvider(&data);
16930 SSLSocketDataProvider ssl(ASYNC, OK);
16931 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
16932
bnc87dcefc2017-05-25 12:47:5816933 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:1916934 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
Adam Rice425cf122015-01-19 06:18:2416935 FakeWebSocketStreamCreateHelper websocket_stream_create_helper;
16936 trans->SetWebSocketHandshakeStreamCreateHelper(
16937 &websocket_stream_create_helper);
16938
16939 {
16940 TestCompletionCallback callback;
16941
tfarina42834112016-09-22 13:38:2016942 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0116943 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
Adam Rice425cf122015-01-19 06:18:2416944
16945 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0116946 EXPECT_THAT(rv, IsOk());
Adam Rice425cf122015-01-19 06:18:2416947 }
16948
16949 const HttpResponseInfo* response = trans->GetResponseInfo();
16950 ASSERT_TRUE(response);
wezca1070932016-05-26 20:30:5216951 ASSERT_TRUE(response->headers);
Adam Rice425cf122015-01-19 06:18:2416952 EXPECT_EQ(407, response->headers->response_code());
16953
16954 {
16955 TestCompletionCallback callback;
16956
16957 int rv = trans->RestartWithAuth(AuthCredentials(kFoo, kBar),
16958 callback.callback());
robpercival214763f2016-07-01 23:27:0116959 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
Adam Rice425cf122015-01-19 06:18:2416960
16961 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0116962 EXPECT_THAT(rv, IsOk());
Adam Rice425cf122015-01-19 06:18:2416963 }
16964
16965 response = trans->GetResponseInfo();
16966 ASSERT_TRUE(response);
wezca1070932016-05-26 20:30:5216967 ASSERT_TRUE(response->headers);
Adam Rice425cf122015-01-19 06:18:2416968
16969 EXPECT_EQ(101, response->headers->response_code());
16970
16971 trans.reset();
16972 session->CloseAllConnections();
16973}
16974
16975// Verify that proxy headers are not sent to the destination server when
16976// establishing a tunnel for an insecure WebSocket connection.
16977// This requires the authentication info to be injected into the auth cache
16978// due to crbug.com/395064
16979// TODO(ricea): Change to use a 407 response once issue 395064 is fixed.
bncd16676a2016-07-20 16:23:0116980TEST_F(HttpNetworkTransactionTest, ProxyHeadersNotSentOverWsTunnel) {
Adam Rice425cf122015-01-19 06:18:2416981 HttpRequestInfo request;
16982 request.method = "GET";
bncce36dca22015-04-21 22:11:2316983 request.url = GURL("ws://www.example.org/");
Adam Rice425cf122015-01-19 06:18:2416984 AddWebSocketHeaders(&request.extra_headers);
16985
16986 // Configure against proxy server "myproxy:70".
Lily Houghton8c2f97d2018-01-22 05:06:5916987 session_deps_.proxy_resolution_service =
16988 ProxyResolutionService::CreateFixedFromPacResult("PROXY myproxy:70");
Adam Rice425cf122015-01-19 06:18:2416989
danakj1fd259a02016-04-16 03:17:0916990 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
Adam Rice425cf122015-01-19 06:18:2416991
16992 MockWrite data_writes[] = {
16993 // Try to establish a tunnel for the WebSocket connection, with
16994 // credentials. Because WebSockets have a separate set of socket pools,
16995 // they cannot and will not use the same TCP/IP connection as the
16996 // preflight HTTP request.
16997 MockWrite(
bncce36dca22015-04-21 22:11:2316998 "CONNECT www.example.org:80 HTTP/1.1\r\n"
16999 "Host: www.example.org:80\r\n"
Adam Rice425cf122015-01-19 06:18:2417000 "Proxy-Connection: keep-alive\r\n"
17001 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
17002
17003 MockWrite(
17004 "GET / HTTP/1.1\r\n"
bncce36dca22015-04-21 22:11:2317005 "Host: www.example.org\r\n"
Adam Rice425cf122015-01-19 06:18:2417006 "Connection: Upgrade\r\n"
17007 "Upgrade: websocket\r\n"
bncce36dca22015-04-21 22:11:2317008 "Origin: http://www.example.org\r\n"
Adam Rice425cf122015-01-19 06:18:2417009 "Sec-WebSocket-Version: 13\r\n"
17010 "Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==\r\n\r\n"),
17011 };
17012
17013 MockRead data_reads[] = {
17014 // HTTP CONNECT with credentials.
17015 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
17016
17017 // WebSocket connection established inside tunnel.
17018 MockRead("HTTP/1.1 101 Switching Protocols\r\n"),
17019 MockRead("Upgrade: websocket\r\n"),
17020 MockRead("Connection: Upgrade\r\n"),
17021 MockRead("Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=\r\n\r\n"),
17022 };
17023
17024 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
17025 arraysize(data_writes));
17026 session_deps_.socket_factory->AddSocketDataProvider(&data);
17027
17028 session->http_auth_cache()->Add(
17029 GURL("http://myproxy:70/"), "MyRealm1", HttpAuth::AUTH_SCHEME_BASIC,
17030 "Basic realm=MyRealm1", AuthCredentials(kFoo, kBar), "/");
17031
bnc87dcefc2017-05-25 12:47:5817032 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:1917033 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
Adam Rice425cf122015-01-19 06:18:2417034 FakeWebSocketStreamCreateHelper websocket_stream_create_helper;
17035 trans->SetWebSocketHandshakeStreamCreateHelper(
17036 &websocket_stream_create_helper);
17037
17038 TestCompletionCallback callback;
17039
tfarina42834112016-09-22 13:38:2017040 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0117041 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
Adam Rice425cf122015-01-19 06:18:2417042
17043 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0117044 EXPECT_THAT(rv, IsOk());
Adam Rice425cf122015-01-19 06:18:2417045
17046 const HttpResponseInfo* response = trans->GetResponseInfo();
17047 ASSERT_TRUE(response);
wezca1070932016-05-26 20:30:5217048 ASSERT_TRUE(response->headers);
Adam Rice425cf122015-01-19 06:18:2417049
17050 EXPECT_EQ(101, response->headers->response_code());
17051
17052 trans.reset();
17053 session->CloseAllConnections();
17054}
17055
bncd16676a2016-07-20 16:23:0117056TEST_F(HttpNetworkTransactionTest, TotalNetworkBytesPost) {
danakj1fd259a02016-04-16 03:17:0917057 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:2217058 element_readers.push_back(
Jeremy Roman0579ed62017-08-29 15:56:1917059 std::make_unique<UploadBytesElementReader>("foo", 3));
olli.raula6df48b2a2015-11-26 07:40:2217060 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
sclittlefb249892015-09-10 21:33:2217061
17062 HttpRequestInfo request;
17063 request.method = "POST";
17064 request.url = GURL("http://www.foo.com/");
17065 request.upload_data_stream = &upload_data_stream;
17066
danakj1fd259a02016-04-16 03:17:0917067 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1617068 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
sclittlefb249892015-09-10 21:33:2217069 MockWrite data_writes[] = {
17070 MockWrite("POST / HTTP/1.1\r\n"
17071 "Host: www.foo.com\r\n"
17072 "Connection: keep-alive\r\n"
17073 "Content-Length: 3\r\n\r\n"),
17074 MockWrite("foo"),
17075 };
17076
17077 MockRead data_reads[] = {
17078 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello world"),
17079 MockRead(SYNCHRONOUS, OK),
17080 };
17081 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
17082 arraysize(data_writes));
17083 session_deps_.socket_factory->AddSocketDataProvider(&data);
17084
17085 TestCompletionCallback callback;
17086
17087 EXPECT_EQ(ERR_IO_PENDING,
tfarina42834112016-09-22 13:38:2017088 trans.Start(&request, callback.callback(), NetLogWithSource()));
robpercival214763f2016-07-01 23:27:0117089 EXPECT_THAT(callback.WaitForResult(), IsOk());
sclittlefb249892015-09-10 21:33:2217090
17091 std::string response_data;
bnc691fda62016-08-12 00:43:1617092 EXPECT_THAT(ReadTransaction(&trans, &response_data), IsOk());
sclittlefb249892015-09-10 21:33:2217093
17094 EXPECT_EQ(CountWriteBytes(data_writes, arraysize(data_writes)),
bnc691fda62016-08-12 00:43:1617095 trans.GetTotalSentBytes());
sclittlefb249892015-09-10 21:33:2217096 EXPECT_EQ(CountReadBytes(data_reads, arraysize(data_reads)),
bnc691fda62016-08-12 00:43:1617097 trans.GetTotalReceivedBytes());
sclittlefb249892015-09-10 21:33:2217098}
17099
bncd16676a2016-07-20 16:23:0117100TEST_F(HttpNetworkTransactionTest, TotalNetworkBytesPost100Continue) {
danakj1fd259a02016-04-16 03:17:0917101 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:2217102 element_readers.push_back(
Jeremy Roman0579ed62017-08-29 15:56:1917103 std::make_unique<UploadBytesElementReader>("foo", 3));
olli.raula6df48b2a2015-11-26 07:40:2217104 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
sclittlefb249892015-09-10 21:33:2217105
17106 HttpRequestInfo request;
17107 request.method = "POST";
17108 request.url = GURL("http://www.foo.com/");
17109 request.upload_data_stream = &upload_data_stream;
17110
danakj1fd259a02016-04-16 03:17:0917111 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1617112 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
sclittlefb249892015-09-10 21:33:2217113 MockWrite data_writes[] = {
17114 MockWrite("POST / HTTP/1.1\r\n"
17115 "Host: www.foo.com\r\n"
17116 "Connection: keep-alive\r\n"
17117 "Content-Length: 3\r\n\r\n"),
17118 MockWrite("foo"),
17119 };
17120
17121 MockRead data_reads[] = {
17122 MockRead("HTTP/1.1 100 Continue\r\n\r\n"),
17123 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello world"),
17124 MockRead(SYNCHRONOUS, OK),
17125 };
17126 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
17127 arraysize(data_writes));
17128 session_deps_.socket_factory->AddSocketDataProvider(&data);
17129
17130 TestCompletionCallback callback;
17131
17132 EXPECT_EQ(ERR_IO_PENDING,
tfarina42834112016-09-22 13:38:2017133 trans.Start(&request, callback.callback(), NetLogWithSource()));
robpercival214763f2016-07-01 23:27:0117134 EXPECT_THAT(callback.WaitForResult(), IsOk());
sclittlefb249892015-09-10 21:33:2217135
17136 std::string response_data;
bnc691fda62016-08-12 00:43:1617137 EXPECT_THAT(ReadTransaction(&trans, &response_data), IsOk());
sclittlefb249892015-09-10 21:33:2217138
17139 EXPECT_EQ(CountWriteBytes(data_writes, arraysize(data_writes)),
bnc691fda62016-08-12 00:43:1617140 trans.GetTotalSentBytes());
sclittlefb249892015-09-10 21:33:2217141 EXPECT_EQ(CountReadBytes(data_reads, arraysize(data_reads)),
bnc691fda62016-08-12 00:43:1617142 trans.GetTotalReceivedBytes());
sclittlefb249892015-09-10 21:33:2217143}
17144
bncd16676a2016-07-20 16:23:0117145TEST_F(HttpNetworkTransactionTest, TotalNetworkBytesChunkedPost) {
sclittlefb249892015-09-10 21:33:2217146 ChunkedUploadDataStream upload_data_stream(0);
17147
17148 HttpRequestInfo request;
17149 request.method = "POST";
17150 request.url = GURL("http://www.foo.com/");
17151 request.upload_data_stream = &upload_data_stream;
17152
danakj1fd259a02016-04-16 03:17:0917153 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1617154 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
sclittlefb249892015-09-10 21:33:2217155 // Send headers successfully, but get an error while sending the body.
17156 MockWrite data_writes[] = {
17157 MockWrite("POST / HTTP/1.1\r\n"
17158 "Host: www.foo.com\r\n"
17159 "Connection: keep-alive\r\n"
17160 "Transfer-Encoding: chunked\r\n\r\n"),
17161 MockWrite("1\r\nf\r\n"), MockWrite("2\r\noo\r\n"), MockWrite("0\r\n\r\n"),
17162 };
17163
17164 MockRead data_reads[] = {
17165 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello world"),
17166 MockRead(SYNCHRONOUS, OK),
17167 };
17168 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
17169 arraysize(data_writes));
17170 session_deps_.socket_factory->AddSocketDataProvider(&data);
17171
17172 TestCompletionCallback callback;
17173
17174 EXPECT_EQ(ERR_IO_PENDING,
tfarina42834112016-09-22 13:38:2017175 trans.Start(&request, callback.callback(), NetLogWithSource()));
sclittlefb249892015-09-10 21:33:2217176
17177 base::RunLoop().RunUntilIdle();
17178 upload_data_stream.AppendData("f", 1, false);
17179
17180 base::RunLoop().RunUntilIdle();
17181 upload_data_stream.AppendData("oo", 2, true);
17182
robpercival214763f2016-07-01 23:27:0117183 EXPECT_THAT(callback.WaitForResult(), IsOk());
sclittlefb249892015-09-10 21:33:2217184
17185 std::string response_data;
bnc691fda62016-08-12 00:43:1617186 EXPECT_THAT(ReadTransaction(&trans, &response_data), IsOk());
sclittlefb249892015-09-10 21:33:2217187
17188 EXPECT_EQ(CountWriteBytes(data_writes, arraysize(data_writes)),
bnc691fda62016-08-12 00:43:1617189 trans.GetTotalSentBytes());
sclittlefb249892015-09-10 21:33:2217190 EXPECT_EQ(CountReadBytes(data_reads, arraysize(data_reads)),
bnc691fda62016-08-12 00:43:1617191 trans.GetTotalReceivedBytes());
sclittlefb249892015-09-10 21:33:2217192}
17193
rdsmith1d343be52016-10-21 20:37:5017194// Confirm that transactions whose throttle is created in (and stays in)
17195// the unthrottled state are not blocked.
17196TEST_F(HttpNetworkTransactionTest, ThrottlingUnthrottled) {
17197 TestNetworkStreamThrottler* throttler(nullptr);
17198 std::unique_ptr<HttpNetworkSession> session(
17199 CreateSessionWithThrottler(&session_deps_, &throttler));
17200
17201 // Send a simple request and make sure it goes through.
17202 HttpRequestInfo request;
17203 request.method = "GET";
17204 request.url = GURL("http://www.example.org/");
17205
bnc87dcefc2017-05-25 12:47:5817206 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:1917207 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
rdsmith1d343be52016-10-21 20:37:5017208
17209 MockWrite data_writes[] = {
17210 MockWrite("GET / HTTP/1.1\r\n"
17211 "Host: www.example.org\r\n"
17212 "Connection: keep-alive\r\n\r\n"),
17213 };
17214 MockRead data_reads[] = {
17215 MockRead("HTTP/1.0 200 OK\r\n\r\n"), MockRead("hello world"),
17216 MockRead(SYNCHRONOUS, OK),
17217 };
17218 StaticSocketDataProvider reads(data_reads, arraysize(data_reads), data_writes,
17219 arraysize(data_writes));
17220 session_deps_.socket_factory->AddSocketDataProvider(&reads);
17221
17222 TestCompletionCallback callback;
17223 trans->Start(&request, callback.callback(), NetLogWithSource());
17224 EXPECT_EQ(OK, callback.WaitForResult());
17225}
17226
17227// Confirm requests can be blocked by a throttler, and are resumed
17228// when the throttle is unblocked.
17229TEST_F(HttpNetworkTransactionTest, ThrottlingBasic) {
17230 TestNetworkStreamThrottler* throttler(nullptr);
17231 std::unique_ptr<HttpNetworkSession> session(
17232 CreateSessionWithThrottler(&session_deps_, &throttler));
17233
17234 // Send a simple request and make sure it goes through.
17235 HttpRequestInfo request;
17236 request.method = "GET";
17237 request.url = GURL("http://www.example.org/");
17238
17239 MockWrite data_writes[] = {
17240 MockWrite("GET / HTTP/1.1\r\n"
17241 "Host: www.example.org\r\n"
17242 "Connection: keep-alive\r\n\r\n"),
17243 };
17244 MockRead data_reads[] = {
17245 MockRead("HTTP/1.0 200 OK\r\n\r\n"), MockRead("hello world"),
17246 MockRead(SYNCHRONOUS, OK),
17247 };
17248 StaticSocketDataProvider reads(data_reads, arraysize(data_reads), data_writes,
17249 arraysize(data_writes));
17250 session_deps_.socket_factory->AddSocketDataProvider(&reads);
17251
17252 // Start a request that will be throttled at start; confirm it
17253 // doesn't complete.
17254 throttler->set_throttle_new_requests(true);
bnc87dcefc2017-05-25 12:47:5817255 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:1917256 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
rdsmith1d343be52016-10-21 20:37:5017257
17258 TestCompletionCallback callback;
17259 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
17260 EXPECT_EQ(ERR_IO_PENDING, rv);
17261
17262 base::RunLoop().RunUntilIdle();
17263 EXPECT_EQ(LOAD_STATE_THROTTLED, trans->GetLoadState());
17264 EXPECT_FALSE(callback.have_result());
17265
17266 // Confirm the request goes on to complete when unthrottled.
17267 throttler->UnthrottleAllRequests();
17268 base::RunLoop().RunUntilIdle();
17269 ASSERT_TRUE(callback.have_result());
17270 EXPECT_EQ(OK, callback.WaitForResult());
17271}
17272
17273// Destroy a request while it's throttled.
17274TEST_F(HttpNetworkTransactionTest, ThrottlingDestruction) {
17275 TestNetworkStreamThrottler* throttler(nullptr);
17276 std::unique_ptr<HttpNetworkSession> session(
17277 CreateSessionWithThrottler(&session_deps_, &throttler));
17278
17279 // Send a simple request and make sure it goes through.
17280 HttpRequestInfo request;
17281 request.method = "GET";
17282 request.url = GURL("http://www.example.org/");
17283
17284 MockWrite data_writes[] = {
17285 MockWrite("GET / HTTP/1.1\r\n"
17286 "Host: www.example.org\r\n"
17287 "Connection: keep-alive\r\n\r\n"),
17288 };
17289 MockRead data_reads[] = {
17290 MockRead("HTTP/1.0 200 OK\r\n\r\n"), MockRead("hello world"),
17291 MockRead(SYNCHRONOUS, OK),
17292 };
17293 StaticSocketDataProvider reads(data_reads, arraysize(data_reads), data_writes,
17294 arraysize(data_writes));
17295 session_deps_.socket_factory->AddSocketDataProvider(&reads);
17296
17297 // Start a request that will be throttled at start; confirm it
17298 // doesn't complete.
17299 throttler->set_throttle_new_requests(true);
bnc87dcefc2017-05-25 12:47:5817300 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:1917301 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
rdsmith1d343be52016-10-21 20:37:5017302
17303 TestCompletionCallback callback;
17304 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
17305 EXPECT_EQ(ERR_IO_PENDING, rv);
17306
17307 base::RunLoop().RunUntilIdle();
17308 EXPECT_EQ(LOAD_STATE_THROTTLED, trans->GetLoadState());
17309 EXPECT_FALSE(callback.have_result());
17310
17311 EXPECT_EQ(1u, throttler->num_outstanding_requests());
17312 trans.reset();
17313 EXPECT_EQ(0u, throttler->num_outstanding_requests());
17314}
17315
17316// Confirm the throttler receives SetPriority calls.
17317TEST_F(HttpNetworkTransactionTest, ThrottlingPrioritySet) {
17318 TestNetworkStreamThrottler* throttler(nullptr);
17319 std::unique_ptr<HttpNetworkSession> session(
17320 CreateSessionWithThrottler(&session_deps_, &throttler));
17321
17322 // Send a simple request and make sure it goes through.
17323 HttpRequestInfo request;
17324 request.method = "GET";
17325 request.url = GURL("http://www.example.org/");
17326
17327 MockWrite data_writes[] = {
17328 MockWrite("GET / HTTP/1.1\r\n"
17329 "Host: www.example.org\r\n"
17330 "Connection: keep-alive\r\n\r\n"),
17331 };
17332 MockRead data_reads[] = {
17333 MockRead("HTTP/1.0 200 OK\r\n\r\n"), MockRead("hello world"),
17334 MockRead(SYNCHRONOUS, OK),
17335 };
17336 StaticSocketDataProvider reads(data_reads, arraysize(data_reads), data_writes,
17337 arraysize(data_writes));
17338 session_deps_.socket_factory->AddSocketDataProvider(&reads);
17339
17340 throttler->set_throttle_new_requests(true);
Jeremy Roman0579ed62017-08-29 15:56:1917341 auto trans = std::make_unique<HttpNetworkTransaction>(IDLE, session.get());
rdsmith1d343be52016-10-21 20:37:5017342 // Start the transaction to associate a throttle with it.
17343 TestCompletionCallback callback;
17344 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
17345 EXPECT_EQ(ERR_IO_PENDING, rv);
17346
17347 EXPECT_EQ(0, throttler->num_set_priority_calls());
17348 trans->SetPriority(LOW);
17349 EXPECT_EQ(1, throttler->num_set_priority_calls());
17350 EXPECT_EQ(LOW, throttler->last_priority_set());
17351
17352 throttler->UnthrottleAllRequests();
17353 base::RunLoop().RunUntilIdle();
17354 ASSERT_TRUE(callback.have_result());
17355 EXPECT_EQ(OK, callback.WaitForResult());
17356}
17357
17358// Confirm that unthrottling from a SetPriority call by the
17359// throttler works properly.
17360TEST_F(HttpNetworkTransactionTest, ThrottlingPrioritySetUnthrottle) {
17361 TestNetworkStreamThrottler* throttler(nullptr);
17362 std::unique_ptr<HttpNetworkSession> session(
17363 CreateSessionWithThrottler(&session_deps_, &throttler));
17364
17365 // Send a simple request and make sure it goes through.
17366 HttpRequestInfo request;
17367 request.method = "GET";
17368 request.url = GURL("http://www.example.org/");
17369
17370 MockWrite data_writes[] = {
17371 MockWrite("GET / HTTP/1.1\r\n"
17372 "Host: www.example.org\r\n"
17373 "Connection: keep-alive\r\n\r\n"),
17374 };
17375 MockRead data_reads[] = {
17376 MockRead("HTTP/1.0 200 OK\r\n\r\n"), MockRead("hello world"),
17377 MockRead(SYNCHRONOUS, OK),
17378 };
17379 StaticSocketDataProvider reads(data_reads, arraysize(data_reads), data_writes,
17380 arraysize(data_writes));
17381 session_deps_.socket_factory->AddSocketDataProvider(&reads);
17382
17383 StaticSocketDataProvider reads1(data_reads, arraysize(data_reads),
17384 data_writes, arraysize(data_writes));
17385 session_deps_.socket_factory->AddSocketDataProvider(&reads1);
17386
17387 // Start a request that will be throttled at start; confirm it
17388 // doesn't complete.
17389 throttler->set_throttle_new_requests(true);
bnc87dcefc2017-05-25 12:47:5817390 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:1917391 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
rdsmith1d343be52016-10-21 20:37:5017392
17393 TestCompletionCallback callback;
17394 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
17395 EXPECT_EQ(ERR_IO_PENDING, rv);
17396
17397 base::RunLoop().RunUntilIdle();
17398 EXPECT_EQ(LOAD_STATE_THROTTLED, trans->GetLoadState());
17399 EXPECT_FALSE(callback.have_result());
17400
17401 // Create a new request, call SetPriority on it to unthrottle,
17402 // and make sure that allows the original request to complete.
Jeremy Roman0579ed62017-08-29 15:56:1917403 auto trans1 = std::make_unique<HttpNetworkTransaction>(LOW, session.get());
rdsmith1d343be52016-10-21 20:37:5017404 throttler->set_priority_change_closure(
17405 base::Bind(&TestNetworkStreamThrottler::UnthrottleAllRequests,
17406 base::Unretained(throttler)));
17407
17408 // Start the transaction to associate a throttle with it.
17409 TestCompletionCallback callback1;
17410 rv = trans1->Start(&request, callback1.callback(), NetLogWithSource());
17411 EXPECT_EQ(ERR_IO_PENDING, rv);
17412
17413 trans1->SetPriority(IDLE);
17414
17415 base::RunLoop().RunUntilIdle();
17416 ASSERT_TRUE(callback.have_result());
17417 EXPECT_EQ(OK, callback.WaitForResult());
17418 ASSERT_TRUE(callback1.have_result());
17419 EXPECT_EQ(OK, callback1.WaitForResult());
17420}
17421
17422// Transaction will be destroyed when the unique_ptr goes out of scope.
bnc87dcefc2017-05-25 12:47:5817423void DestroyTransaction(std::unique_ptr<HttpNetworkTransaction> transaction) {}
rdsmith1d343be52016-10-21 20:37:5017424
17425// Confirm that destroying a transaction from a SetPriority call by the
17426// throttler works properly.
17427TEST_F(HttpNetworkTransactionTest, ThrottlingPrioritySetDestroy) {
17428 TestNetworkStreamThrottler* throttler(nullptr);
17429 std::unique_ptr<HttpNetworkSession> session(
17430 CreateSessionWithThrottler(&session_deps_, &throttler));
17431
17432 // Send a simple request and make sure it goes through.
17433 HttpRequestInfo request;
17434 request.method = "GET";
17435 request.url = GURL("http://www.example.org/");
17436
17437 MockWrite data_writes[] = {
17438 MockWrite("GET / HTTP/1.1\r\n"
17439 "Host: www.example.org\r\n"
17440 "Connection: keep-alive\r\n\r\n"),
17441 };
17442 MockRead data_reads[] = {
17443 MockRead("HTTP/1.0 200 OK\r\n\r\n"), MockRead("hello world"),
17444 MockRead(SYNCHRONOUS, OK),
17445 };
17446 StaticSocketDataProvider reads(data_reads, arraysize(data_reads), data_writes,
17447 arraysize(data_writes));
17448 session_deps_.socket_factory->AddSocketDataProvider(&reads);
17449
17450 StaticSocketDataProvider reads1(data_reads, arraysize(data_reads),
17451 data_writes, arraysize(data_writes));
17452 session_deps_.socket_factory->AddSocketDataProvider(&reads1);
17453
17454 // Start a request that will be throttled at start; confirm it
17455 // doesn't complete.
17456 throttler->set_throttle_new_requests(true);
bnc87dcefc2017-05-25 12:47:5817457 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:1917458 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
rdsmith1d343be52016-10-21 20:37:5017459
17460 TestCompletionCallback callback;
17461 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
17462 EXPECT_EQ(ERR_IO_PENDING, rv);
17463
17464 base::RunLoop().RunUntilIdle();
17465 EXPECT_EQ(LOAD_STATE_THROTTLED, trans->GetLoadState());
17466 EXPECT_FALSE(callback.have_result());
17467
17468 // Arrange for the set priority call on the above transaction to delete
17469 // the transaction.
bnc87dcefc2017-05-25 12:47:5817470 HttpNetworkTransaction* trans_ptr(trans.get());
rdsmith1d343be52016-10-21 20:37:5017471 throttler->set_priority_change_closure(
17472 base::Bind(&DestroyTransaction, base::Passed(&trans)));
17473
17474 // Call it and check results (partially a "doesn't crash" test).
17475 trans_ptr->SetPriority(IDLE);
17476 trans_ptr = nullptr; // No longer a valid pointer.
17477
17478 base::RunLoop().RunUntilIdle();
17479 ASSERT_FALSE(callback.have_result());
17480}
17481
nharperb7441ef2016-01-25 23:54:1417482#if !defined(OS_IOS)
bncd16676a2016-07-20 16:23:0117483TEST_F(HttpNetworkTransactionTest, TokenBindingSpdy) {
nharperb7441ef2016-01-25 23:54:1417484 const std::string https_url = "https://www.example.com";
17485 HttpRequestInfo request;
17486 request.url = GURL(https_url);
17487 request.method = "GET";
17488
17489 SSLSocketDataProvider ssl(ASYNC, OK);
Ryan Sleevi4f832092017-11-21 23:25:4917490 ssl.ssl_info.token_binding_negotiated = true;
17491 ssl.ssl_info.token_binding_key_param = TB_PARAM_ECDSAP256;
bnc3cf2a592016-08-11 14:48:3617492 ssl.next_proto = kProtoHTTP2;
nharperb7441ef2016-01-25 23:54:1417493 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
17494
bnc42331402016-07-25 13:36:1517495 SpdySerializedFrame resp(spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
bncdf80d44fd2016-07-15 20:27:4117496 SpdySerializedFrame body(spdy_util_.ConstructSpdyDataFrame(1, true));
17497 MockRead reads[] = {CreateMockRead(resp), CreateMockRead(body),
nharperb7441ef2016-01-25 23:54:1417498 MockRead(ASYNC, ERR_IO_PENDING)};
17499 StaticSocketDataProvider data(reads, arraysize(reads), nullptr, 0);
17500 session_deps_.socket_factory->AddSocketDataProvider(&data);
bnc87dcefc2017-05-25 12:47:5817501 session_deps_.channel_id_service =
Jeremy Roman0579ed62017-08-29 15:56:1917502 std::make_unique<ChannelIDService>(new DefaultChannelIDStore(nullptr));
danakj1fd259a02016-04-16 03:17:0917503 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
nharperb7441ef2016-01-25 23:54:1417504
17505 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
17506 TestCompletionCallback callback;
17507 EXPECT_EQ(ERR_IO_PENDING,
tfarina42834112016-09-22 13:38:2017508 trans.Start(&request, callback.callback(), NetLogWithSource()));
fdorayf33fede2017-05-11 21:18:1017509
17510 NetTestSuite::GetScopedTaskEnvironment()->RunUntilIdle();
nharperb7441ef2016-01-25 23:54:1417511
17512 EXPECT_TRUE(trans.GetResponseInfo()->was_fetched_via_spdy);
17513 HttpRequestHeaders headers;
17514 ASSERT_TRUE(trans.GetFullRequestHeaders(&headers));
17515 EXPECT_TRUE(headers.HasHeader(HttpRequestHeaders::kTokenBinding));
17516}
17517#endif // !defined(OS_IOS)
17518
eustasc7d27da2017-04-06 10:33:2017519void CheckContentEncodingMatching(SpdySessionDependencies* session_deps,
17520 const std::string& accept_encoding,
17521 const std::string& content_encoding,
sky50576f32017-05-01 19:28:0317522 const std::string& location,
eustasc7d27da2017-04-06 10:33:2017523 bool should_match) {
17524 HttpRequestInfo request;
17525 request.method = "GET";
17526 request.url = GURL("http://www.foo.com/");
17527 request.extra_headers.SetHeader(HttpRequestHeaders::kAcceptEncoding,
17528 accept_encoding);
17529
17530 std::unique_ptr<HttpNetworkSession> session(CreateSession(session_deps));
17531 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
17532 // Send headers successfully, but get an error while sending the body.
17533 MockWrite data_writes[] = {
17534 MockWrite("GET / HTTP/1.1\r\n"
17535 "Host: www.foo.com\r\n"
17536 "Connection: keep-alive\r\n"
17537 "Accept-Encoding: "),
17538 MockWrite(accept_encoding.data()), MockWrite("\r\n\r\n"),
17539 };
17540
sky50576f32017-05-01 19:28:0317541 std::string response_code = "200 OK";
17542 std::string extra;
17543 if (!location.empty()) {
17544 response_code = "301 Redirect\r\nLocation: ";
17545 response_code.append(location);
17546 }
17547
eustasc7d27da2017-04-06 10:33:2017548 MockRead data_reads[] = {
sky50576f32017-05-01 19:28:0317549 MockRead("HTTP/1.0 "),
17550 MockRead(response_code.data()),
17551 MockRead("\r\nContent-Encoding: "),
17552 MockRead(content_encoding.data()),
17553 MockRead("\r\n\r\n"),
eustasc7d27da2017-04-06 10:33:2017554 MockRead(SYNCHRONOUS, OK),
17555 };
17556 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
17557 arraysize(data_writes));
17558 session_deps->socket_factory->AddSocketDataProvider(&data);
17559
17560 TestCompletionCallback callback;
17561
17562 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
17563 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
17564
17565 rv = callback.WaitForResult();
17566 if (should_match) {
17567 EXPECT_THAT(rv, IsOk());
17568 } else {
17569 EXPECT_THAT(rv, IsError(ERR_CONTENT_DECODING_FAILED));
17570 }
17571}
17572
17573TEST_F(HttpNetworkTransactionTest, MatchContentEncoding1) {
sky50576f32017-05-01 19:28:0317574 CheckContentEncodingMatching(&session_deps_, "gzip,sdch", "br", "", false);
eustasc7d27da2017-04-06 10:33:2017575}
17576
17577TEST_F(HttpNetworkTransactionTest, MatchContentEncoding2) {
sky50576f32017-05-01 19:28:0317578 CheckContentEncodingMatching(&session_deps_, "identity;q=1, *;q=0", "", "",
17579 true);
eustasc7d27da2017-04-06 10:33:2017580}
17581
17582TEST_F(HttpNetworkTransactionTest, MatchContentEncoding3) {
17583 CheckContentEncodingMatching(&session_deps_, "identity;q=1, *;q=0", "gzip",
sky50576f32017-05-01 19:28:0317584 "", false);
17585}
17586
17587TEST_F(HttpNetworkTransactionTest, MatchContentEncoding4) {
17588 CheckContentEncodingMatching(&session_deps_, "identity;q=1, *;q=0", "gzip",
17589 "www.foo.com/other", true);
eustasc7d27da2017-04-06 10:33:2017590}
17591
xunjieli96f2a402017-06-05 17:24:2717592TEST_F(HttpNetworkTransactionTest, ProxyResolutionFailsSync) {
17593 ProxyConfig proxy_config;
17594 proxy_config.set_pac_url(GURL("http://fooproxyurl"));
17595 proxy_config.set_pac_mandatory(true);
17596 MockAsyncProxyResolver resolver;
Lily Houghton8c2f97d2018-01-22 05:06:5917597 session_deps_.proxy_resolution_service.reset(new ProxyResolutionService(
Jeremy Roman0579ed62017-08-29 15:56:1917598 std::make_unique<ProxyConfigServiceFixed>(proxy_config),
Bence Béky8f9d7d3952017-10-09 19:58:0417599 std::make_unique<FailingProxyResolverFactory>(), nullptr));
xunjieli96f2a402017-06-05 17:24:2717600
17601 HttpRequestInfo request;
17602 request.method = "GET";
17603 request.url = GURL("http://www.example.org/");
17604
17605 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
17606 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
17607
17608 TestCompletionCallback callback;
17609
17610 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
17611 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
17612 EXPECT_THAT(callback.WaitForResult(),
17613 IsError(ERR_MANDATORY_PROXY_CONFIGURATION_FAILED));
17614}
17615
17616TEST_F(HttpNetworkTransactionTest, ProxyResolutionFailsAsync) {
17617 ProxyConfig proxy_config;
17618 proxy_config.set_pac_url(GURL("http://fooproxyurl"));
17619 proxy_config.set_pac_mandatory(true);
17620 MockAsyncProxyResolverFactory* proxy_resolver_factory =
17621 new MockAsyncProxyResolverFactory(false);
17622 MockAsyncProxyResolver resolver;
Lily Houghton8c2f97d2018-01-22 05:06:5917623 session_deps_.proxy_resolution_service.reset(new ProxyResolutionService(
17624 std::make_unique<ProxyConfigServiceFixed>(proxy_config),
17625 base::WrapUnique(proxy_resolver_factory), nullptr));
xunjieli96f2a402017-06-05 17:24:2717626 HttpRequestInfo request;
17627 request.method = "GET";
17628 request.url = GURL("http://www.example.org/");
17629
17630 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
17631 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
17632
17633 TestCompletionCallback callback;
17634 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
17635 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
17636
17637 proxy_resolver_factory->pending_requests()[0]->CompleteNowWithForwarder(
17638 ERR_FAILED, &resolver);
17639 EXPECT_THAT(callback.WaitForResult(),
17640 IsError(ERR_MANDATORY_PROXY_CONFIGURATION_FAILED));
17641}
17642
17643TEST_F(HttpNetworkTransactionTest, NoSupportedProxies) {
Lily Houghton8c2f97d2018-01-22 05:06:5917644 session_deps_.proxy_resolution_service =
17645 ProxyResolutionService::CreateFixedFromPacResult("QUIC myproxy.org:443");
xunjieli96f2a402017-06-05 17:24:2717646 session_deps_.enable_quic = false;
17647 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
17648
17649 HttpRequestInfo request;
17650 request.method = "GET";
17651 request.url = GURL("http://www.example.org/");
17652
17653 TestCompletionCallback callback;
17654 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
17655 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
17656 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
17657
17658 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_NO_SUPPORTED_PROXIES));
17659}
17660
[email protected]89ceba9a2009-03-21 03:46:0617661} // namespace net