blob: a8b1384ad2bcbfc1c9e90313aa58625d7ffef158 [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".
rdsmith82957ad2015-09-16 19:42:033034 session_deps_.proxy_service =
3035 ProxyService::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".
rdsmith82957ad2015-09-16 19:42:033159 session_deps_.proxy_service =
3160 ProxyService::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".
3288 session_deps_.proxy_service = ProxyService::CreateFixed("myproxy:70");
3289 BoundTestNetLog log;
3290 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:093291 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
ttuttle34f63b52015-03-05 04:33:013292
bnc691fda62016-08-12 00:43:163293 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
ttuttle34f63b52015-03-05 04:33:013294
mmenked39192ee2015-12-09 00:57:233295 // Since we have proxy, should try to establish tunnel.
3296 MockWrite data_writes1[] = {
3297 MockWrite(ASYNC, 0,
3298 "CONNECT www.example.org:443 HTTP/1.1\r\n"
3299 "Host: www.example.org:443\r\n"
3300 "Proxy-Connection: keep-alive\r\n\r\n"),
ttuttle34f63b52015-03-05 04:33:013301
bnc691fda62016-08-12 00:43:163302 // After calling trans.RestartWithAuth(), this is the request we should
mmenked39192ee2015-12-09 00:57:233303 // be issuing -- the final header line contains the credentials.
3304 MockWrite(ASYNC, 3,
3305 "CONNECT www.example.org:443 HTTP/1.1\r\n"
3306 "Host: www.example.org:443\r\n"
3307 "Proxy-Connection: keep-alive\r\n"
3308 "Proxy-Authorization: Basic Zm9vOmJheg==\r\n\r\n"),
3309 };
ttuttle34f63b52015-03-05 04:33:013310
mmenked39192ee2015-12-09 00:57:233311 // The proxy responds to the connect with a 407, using a persistent
3312 // connection. (Since it's HTTP/1.0, keep-alive has to be explicit.)
3313 MockRead data_reads1[] = {
3314 // No credentials.
3315 MockRead(ASYNC, 1,
3316 "HTTP/1.0 407 Proxy Authentication Required\r\n"
3317 "Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"
3318 "Proxy-Connection: keep-alive\r\n"
3319 "Content-Length: 10\r\n\r\n"),
3320 MockRead(i == 0 ? ASYNC : SYNCHRONOUS, 2, "0123456789"),
ttuttle34f63b52015-03-05 04:33:013321
mmenked39192ee2015-12-09 00:57:233322 // Wrong credentials (wrong password).
3323 MockRead(ASYNC, 4,
3324 "HTTP/1.0 407 Proxy Authentication Required\r\n"
3325 "Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"
3326 "Proxy-Connection: keep-alive\r\n"
3327 "Content-Length: 10\r\n\r\n"),
3328 // No response body because the test stops reading here.
3329 MockRead(SYNCHRONOUS, ERR_UNEXPECTED, 5),
3330 };
ttuttle34f63b52015-03-05 04:33:013331
mmenked39192ee2015-12-09 00:57:233332 SequencedSocketData data1(data_reads1, arraysize(data_reads1), data_writes1,
3333 arraysize(data_writes1));
3334 data1.set_busy_before_sync_reads(true);
3335 session_deps_.socket_factory->AddSocketDataProvider(&data1);
ttuttle34f63b52015-03-05 04:33:013336
mmenked39192ee2015-12-09 00:57:233337 TestCompletionCallback callback1;
ttuttle34f63b52015-03-05 04:33:013338
bnc691fda62016-08-12 00:43:163339 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:013340 EXPECT_THAT(callback1.GetResult(rv), IsOk());
ttuttle34f63b52015-03-05 04:33:013341
mmenked39192ee2015-12-09 00:57:233342 TestNetLogEntry::List entries;
3343 log.GetEntries(&entries);
3344 size_t pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:003345 entries, 0, NetLogEventType::HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
3346 NetLogEventPhase::NONE);
mmenked39192ee2015-12-09 00:57:233347 ExpectLogContainsSomewhere(
3348 entries, pos,
mikecirone8b85c432016-09-08 19:11:003349 NetLogEventType::HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
3350 NetLogEventPhase::NONE);
ttuttle34f63b52015-03-05 04:33:013351
bnc691fda62016-08-12 00:43:163352 const HttpResponseInfo* response = trans.GetResponseInfo();
mmenked39192ee2015-12-09 00:57:233353 ASSERT_TRUE(response);
3354 ASSERT_TRUE(response->headers);
3355 EXPECT_TRUE(response->headers->IsKeepAlive());
3356 EXPECT_EQ(407, response->headers->response_code());
3357 EXPECT_EQ(10, response->headers->GetContentLength());
3358 EXPECT_TRUE(HttpVersion(1, 0) == response->headers->GetHttpVersion());
3359 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
ttuttle34f63b52015-03-05 04:33:013360
mmenked39192ee2015-12-09 00:57:233361 TestCompletionCallback callback2;
ttuttle34f63b52015-03-05 04:33:013362
mmenked39192ee2015-12-09 00:57:233363 // Wrong password (should be "bar").
bnc691fda62016-08-12 00:43:163364 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBaz),
3365 callback2.callback());
robpercival214763f2016-07-01 23:27:013366 EXPECT_THAT(callback2.GetResult(rv), IsOk());
ttuttle34f63b52015-03-05 04:33:013367
bnc691fda62016-08-12 00:43:163368 response = trans.GetResponseInfo();
mmenked39192ee2015-12-09 00:57:233369 ASSERT_TRUE(response);
3370 ASSERT_TRUE(response->headers);
3371 EXPECT_TRUE(response->headers->IsKeepAlive());
3372 EXPECT_EQ(407, response->headers->response_code());
3373 EXPECT_EQ(10, response->headers->GetContentLength());
3374 EXPECT_TRUE(HttpVersion(1, 0) == response->headers->GetHttpVersion());
3375 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
ttuttle34f63b52015-03-05 04:33:013376
mmenked39192ee2015-12-09 00:57:233377 // Flush the idle socket before the NetLog and HttpNetworkTransaction go
3378 // out of scope.
3379 session->CloseAllConnections();
3380 }
ttuttle34f63b52015-03-05 04:33:013381}
3382
3383// Test the request-challenge-retry sequence for basic auth, over a keep-alive
3384// proxy connection with HTTP/1.1 responses, when setting up an SSL tunnel.
bncd16676a2016-07-20 16:23:013385TEST_F(HttpNetworkTransactionTest, BasicAuthProxyKeepAliveHttp11) {
mmenked39192ee2015-12-09 00:57:233386 // On the second pass, the body read of the auth challenge is synchronous, so
3387 // IsConnectedAndIdle returns false. The socket should still be drained and
3388 // reused. See http://crbug.com/544255.
3389 for (int i = 0; i < 2; ++i) {
3390 HttpRequestInfo request;
3391 request.method = "GET";
3392 request.url = GURL("https://www.example.org/");
3393 // Ensure that proxy authentication is attempted even
3394 // when the no authentication data flag is set.
3395 request.load_flags = LOAD_DO_NOT_SEND_AUTH_DATA;
3396
3397 // Configure against proxy server "myproxy:70".
3398 session_deps_.proxy_service = ProxyService::CreateFixed("myproxy:70");
3399 BoundTestNetLog log;
3400 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:093401 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
mmenked39192ee2015-12-09 00:57:233402
bnc691fda62016-08-12 00:43:163403 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
mmenked39192ee2015-12-09 00:57:233404
3405 // Since we have proxy, should try to establish tunnel.
3406 MockWrite data_writes1[] = {
3407 MockWrite(ASYNC, 0,
3408 "CONNECT www.example.org:443 HTTP/1.1\r\n"
3409 "Host: www.example.org:443\r\n"
3410 "Proxy-Connection: keep-alive\r\n\r\n"),
3411
bnc691fda62016-08-12 00:43:163412 // After calling trans.RestartWithAuth(), this is the request we should
mmenked39192ee2015-12-09 00:57:233413 // be issuing -- the final header line contains the credentials.
3414 MockWrite(ASYNC, 3,
3415 "CONNECT www.example.org:443 HTTP/1.1\r\n"
3416 "Host: www.example.org:443\r\n"
3417 "Proxy-Connection: keep-alive\r\n"
3418 "Proxy-Authorization: Basic Zm9vOmJheg==\r\n\r\n"),
3419 };
3420
3421 // The proxy responds to the connect with a 407, using a persistent
3422 // connection. (Since it's HTTP/1.0, keep-alive has to be explicit.)
3423 MockRead data_reads1[] = {
3424 // No credentials.
3425 MockRead(ASYNC, 1,
3426 "HTTP/1.1 407 Proxy Authentication Required\r\n"
3427 "Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"
3428 "Content-Length: 10\r\n\r\n"),
3429 MockRead(i == 0 ? ASYNC : SYNCHRONOUS, 2, "0123456789"),
3430
3431 // Wrong credentials (wrong password).
3432 MockRead(ASYNC, 4,
3433 "HTTP/1.1 407 Proxy Authentication Required\r\n"
3434 "Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"
3435 "Content-Length: 10\r\n\r\n"),
3436 // No response body because the test stops reading here.
3437 MockRead(SYNCHRONOUS, ERR_UNEXPECTED, 5),
3438 };
3439
3440 SequencedSocketData data1(data_reads1, arraysize(data_reads1), data_writes1,
3441 arraysize(data_writes1));
3442 data1.set_busy_before_sync_reads(true);
3443 session_deps_.socket_factory->AddSocketDataProvider(&data1);
3444
3445 TestCompletionCallback callback1;
3446
bnc691fda62016-08-12 00:43:163447 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:013448 EXPECT_THAT(callback1.GetResult(rv), IsOk());
mmenked39192ee2015-12-09 00:57:233449
3450 TestNetLogEntry::List entries;
3451 log.GetEntries(&entries);
3452 size_t pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:003453 entries, 0, NetLogEventType::HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
3454 NetLogEventPhase::NONE);
mmenked39192ee2015-12-09 00:57:233455 ExpectLogContainsSomewhere(
3456 entries, pos,
mikecirone8b85c432016-09-08 19:11:003457 NetLogEventType::HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
3458 NetLogEventPhase::NONE);
mmenked39192ee2015-12-09 00:57:233459
bnc691fda62016-08-12 00:43:163460 const HttpResponseInfo* response = trans.GetResponseInfo();
mmenked39192ee2015-12-09 00:57:233461 ASSERT_TRUE(response);
3462 ASSERT_TRUE(response->headers);
3463 EXPECT_TRUE(response->headers->IsKeepAlive());
3464 EXPECT_EQ(407, response->headers->response_code());
3465 EXPECT_EQ(10, response->headers->GetContentLength());
3466 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
3467 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
3468
3469 TestCompletionCallback callback2;
3470
3471 // Wrong password (should be "bar").
bnc691fda62016-08-12 00:43:163472 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBaz),
3473 callback2.callback());
robpercival214763f2016-07-01 23:27:013474 EXPECT_THAT(callback2.GetResult(rv), IsOk());
mmenked39192ee2015-12-09 00:57:233475
bnc691fda62016-08-12 00:43:163476 response = trans.GetResponseInfo();
mmenked39192ee2015-12-09 00:57:233477 ASSERT_TRUE(response);
3478 ASSERT_TRUE(response->headers);
3479 EXPECT_TRUE(response->headers->IsKeepAlive());
3480 EXPECT_EQ(407, response->headers->response_code());
3481 EXPECT_EQ(10, response->headers->GetContentLength());
3482 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
3483 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
3484
3485 // Flush the idle socket before the NetLog and HttpNetworkTransaction go
3486 // out of scope.
3487 session->CloseAllConnections();
3488 }
3489}
3490
3491// Test the request-challenge-retry sequence for basic auth, over a keep-alive
3492// proxy connection with HTTP/1.1 responses, when setting up an SSL tunnel, in
3493// the case the server sends extra data on the original socket, so it can't be
3494// reused.
bncd16676a2016-07-20 16:23:013495TEST_F(HttpNetworkTransactionTest, BasicAuthProxyKeepAliveExtraData) {
[email protected]cb9bf6ca2011-01-28 13:15:273496 HttpRequestInfo request;
3497 request.method = "GET";
bncce36dca22015-04-21 22:11:233498 request.url = GURL("https://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:273499 // when the no authentication data flag is set.
ttuttle859dc7a2015-04-23 19:42:293500 request.load_flags = LOAD_DO_NOT_SEND_AUTH_DATA;
[email protected]cb9bf6ca2011-01-28 13:15:273501
[email protected]2d2697f92009-02-18 21:00:323502 // Configure against proxy server "myproxy:70".
mmenked39192ee2015-12-09 00:57:233503 session_deps_.proxy_service =
3504 ProxyService::CreateFixedFromPacResult("PROXY myproxy:70");
vishal.b62985ca92015-04-17 08:45:513505 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:073506 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:093507 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]2d2697f92009-02-18 21:00:323508
[email protected]2d2697f92009-02-18 21:00:323509 // Since we have proxy, should try to establish tunnel.
3510 MockWrite data_writes1[] = {
mmenked39192ee2015-12-09 00:57:233511 MockWrite(ASYNC, 0,
3512 "CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:173513 "Host: www.example.org:443\r\n"
3514 "Proxy-Connection: keep-alive\r\n\r\n"),
mmenked39192ee2015-12-09 00:57:233515 };
[email protected]2d2697f92009-02-18 21:00:323516
mmenked39192ee2015-12-09 00:57:233517 // The proxy responds to the connect with a 407, using a persistent, but sends
3518 // extra data, so the socket cannot be reused.
3519 MockRead data_reads1[] = {
3520 // No credentials.
3521 MockRead(ASYNC, 1,
3522 "HTTP/1.1 407 Proxy Authentication Required\r\n"
3523 "Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"
3524 "Content-Length: 10\r\n\r\n"),
3525 MockRead(SYNCHRONOUS, 2, "0123456789"),
3526 MockRead(SYNCHRONOUS, 3, "I'm broken!"),
3527 };
3528
3529 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:233530 // After calling trans->RestartWithAuth(), this is the request we should
3531 // be issuing -- the final header line contains the credentials.
mmenked39192ee2015-12-09 00:57:233532 MockWrite(ASYNC, 0,
3533 "CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:173534 "Host: www.example.org:443\r\n"
3535 "Proxy-Connection: keep-alive\r\n"
mmenked39192ee2015-12-09 00:57:233536 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
3537
3538 MockWrite(ASYNC, 2,
3539 "GET / HTTP/1.1\r\n"
3540 "Host: www.example.org\r\n"
3541 "Connection: keep-alive\r\n\r\n"),
[email protected]2d2697f92009-02-18 21:00:323542 };
3543
mmenked39192ee2015-12-09 00:57:233544 MockRead data_reads2[] = {
3545 MockRead(ASYNC, 1, "HTTP/1.1 200 Connection Established\r\n\r\n"),
[email protected]2d2697f92009-02-18 21:00:323546
mmenked39192ee2015-12-09 00:57:233547 MockRead(ASYNC, 3,
3548 "HTTP/1.1 200 OK\r\n"
3549 "Content-Type: text/html; charset=iso-8859-1\r\n"
3550 "Content-Length: 5\r\n\r\n"),
3551 // No response body because the test stops reading here.
3552 MockRead(SYNCHRONOUS, ERR_UNEXPECTED, 4),
[email protected]2d2697f92009-02-18 21:00:323553 };
3554
mmenked39192ee2015-12-09 00:57:233555 SequencedSocketData data1(data_reads1, arraysize(data_reads1), data_writes1,
3556 arraysize(data_writes1));
3557 data1.set_busy_before_sync_reads(true);
[email protected]bb88e1d32013-05-03 23:11:073558 session_deps_.socket_factory->AddSocketDataProvider(&data1);
mmenked39192ee2015-12-09 00:57:233559 SequencedSocketData data2(data_reads2, arraysize(data_reads2), data_writes2,
3560 arraysize(data_writes2));
3561 session_deps_.socket_factory->AddSocketDataProvider(&data2);
3562 SSLSocketDataProvider ssl(ASYNC, OK);
3563 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]2d2697f92009-02-18 21:00:323564
[email protected]49639fa2011-12-20 23:22:413565 TestCompletionCallback callback1;
[email protected]2d2697f92009-02-18 21:00:323566
bnc87dcefc2017-05-25 12:47:583567 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:193568 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]2d2697f92009-02-18 21:00:323569
mmenked39192ee2015-12-09 00:57:233570 int rv = trans->Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:013571 EXPECT_THAT(callback1.GetResult(rv), IsOk());
mmenked39192ee2015-12-09 00:57:233572
mmenke43758e62015-05-04 21:09:463573 TestNetLogEntry::List entries;
[email protected]b2fcd0e2010-12-01 15:19:403574 log.GetEntries(&entries);
[email protected]dbb83db2010-05-11 18:13:393575 size_t pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:003576 entries, 0, NetLogEventType::HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
3577 NetLogEventPhase::NONE);
[email protected]dbb83db2010-05-11 18:13:393578 ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:403579 entries, pos,
mikecirone8b85c432016-09-08 19:11:003580 NetLogEventType::HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
3581 NetLogEventPhase::NONE);
[email protected]2d2697f92009-02-18 21:00:323582
[email protected]1c773ea12009-04-28 19:58:423583 const HttpResponseInfo* response = trans->GetResponseInfo();
ttuttle7933c112015-01-06 00:55:243584 ASSERT_TRUE(response);
3585 ASSERT_TRUE(response->headers);
[email protected]2d2697f92009-02-18 21:00:323586 EXPECT_TRUE(response->headers->IsKeepAlive());
3587 EXPECT_EQ(407, response->headers->response_code());
[email protected]1c773ea12009-04-28 19:58:423588 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
[email protected]79cb5c12011-09-12 13:12:043589 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
[email protected]2d2697f92009-02-18 21:00:323590
mmenked39192ee2015-12-09 00:57:233591 LoadTimingInfo load_timing_info;
3592 // CONNECT requests and responses are handled at the connect job level, so
3593 // the transaction does not yet have a connection.
3594 EXPECT_FALSE(trans->GetLoadTimingInfo(&load_timing_info));
3595
[email protected]49639fa2011-12-20 23:22:413596 TestCompletionCallback callback2;
[email protected]2d2697f92009-02-18 21:00:323597
mmenked39192ee2015-12-09 00:57:233598 rv =
3599 trans->RestartWithAuth(AuthCredentials(kFoo, kBar), callback2.callback());
robpercival214763f2016-07-01 23:27:013600 EXPECT_THAT(callback2.GetResult(rv), IsOk());
[email protected]2d2697f92009-02-18 21:00:323601
[email protected]2d2697f92009-02-18 21:00:323602 EXPECT_TRUE(response->headers->IsKeepAlive());
mmenked39192ee2015-12-09 00:57:233603 EXPECT_EQ(200, response->headers->response_code());
3604 EXPECT_EQ(5, response->headers->GetContentLength());
[email protected]1c773ea12009-04-28 19:58:423605 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
[email protected]e772db3f2010-07-12 18:11:133606
mmenked39192ee2015-12-09 00:57:233607 // The password prompt info should not be set.
3608 EXPECT_FALSE(response->auth_challenge);
3609
3610 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
3611 TestLoadTimingNotReusedWithPac(load_timing_info,
3612 CONNECT_TIMING_HAS_SSL_TIMES);
3613
3614 trans.reset();
[email protected]102e27c2011-02-23 01:01:313615 session->CloseAllConnections();
[email protected]2d2697f92009-02-18 21:00:323616}
3617
mmenkee71e15332015-10-07 16:39:543618// Test the case a proxy closes a socket while the challenge body is being
3619// drained.
bncd16676a2016-07-20 16:23:013620TEST_F(HttpNetworkTransactionTest, BasicAuthProxyKeepAliveHangupDuringBody) {
mmenkee71e15332015-10-07 16:39:543621 HttpRequestInfo request;
3622 request.method = "GET";
3623 request.url = GURL("https://www.example.org/");
3624 // Ensure that proxy authentication is attempted even
3625 // when the no authentication data flag is set.
3626 request.load_flags = LOAD_DO_NOT_SEND_AUTH_DATA;
3627
3628 // Configure against proxy server "myproxy:70".
3629 session_deps_.proxy_service = ProxyService::CreateFixed("myproxy:70");
danakj1fd259a02016-04-16 03:17:093630 std::unique_ptr<HttpNetworkSession> session = CreateSession(&session_deps_);
mmenkee71e15332015-10-07 16:39:543631
bnc691fda62016-08-12 00:43:163632 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
mmenkee71e15332015-10-07 16:39:543633
3634 // Since we have proxy, should try to establish tunnel.
3635 MockWrite data_writes1[] = {
3636 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:173637 "Host: www.example.org:443\r\n"
mmenkee71e15332015-10-07 16:39:543638 "Proxy-Connection: keep-alive\r\n\r\n"),
3639 };
3640
3641 // The proxy responds to the connect with a 407, using a persistent
3642 // connection.
3643 MockRead data_reads1[] = {
3644 // No credentials.
3645 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
3646 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
3647 MockRead("Content-Length: 10\r\n\r\n"), MockRead("spam!"),
3648 // Server hands up in the middle of the body.
3649 MockRead(ASYNC, ERR_CONNECTION_CLOSED),
3650 };
3651
3652 MockWrite data_writes2[] = {
bnc691fda62016-08-12 00:43:163653 // After calling trans.RestartWithAuth(), this is the request we should
mmenkee71e15332015-10-07 16:39:543654 // be issuing -- the final header line contains the credentials.
3655 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:173656 "Host: www.example.org:443\r\n"
mmenkee71e15332015-10-07 16:39:543657 "Proxy-Connection: keep-alive\r\n"
3658 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
3659
3660 MockWrite("GET / HTTP/1.1\r\n"
3661 "Host: www.example.org\r\n"
3662 "Connection: keep-alive\r\n\r\n"),
3663 };
3664
3665 MockRead data_reads2[] = {
3666 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
3667
3668 MockRead("HTTP/1.1 200 OK\r\n"),
3669 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
3670 MockRead("Content-Length: 5\r\n\r\n"),
3671 MockRead(SYNCHRONOUS, "hello"),
3672 };
3673
3674 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
3675 data_writes1, arraysize(data_writes1));
3676 session_deps_.socket_factory->AddSocketDataProvider(&data1);
3677 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
3678 data_writes2, arraysize(data_writes2));
3679 session_deps_.socket_factory->AddSocketDataProvider(&data2);
3680 SSLSocketDataProvider ssl(ASYNC, OK);
3681 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
3682
3683 TestCompletionCallback callback;
3684
tfarina42834112016-09-22 13:38:203685 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:013686 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenkee71e15332015-10-07 16:39:543687
bnc691fda62016-08-12 00:43:163688 const HttpResponseInfo* response = trans.GetResponseInfo();
mmenkee71e15332015-10-07 16:39:543689 ASSERT_TRUE(response);
3690 ASSERT_TRUE(response->headers);
3691 EXPECT_TRUE(response->headers->IsKeepAlive());
3692 EXPECT_EQ(407, response->headers->response_code());
3693 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
3694
bnc691fda62016-08-12 00:43:163695 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar), callback.callback());
robpercival214763f2016-07-01 23:27:013696 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenkee71e15332015-10-07 16:39:543697
bnc691fda62016-08-12 00:43:163698 response = trans.GetResponseInfo();
mmenkee71e15332015-10-07 16:39:543699 ASSERT_TRUE(response);
3700 ASSERT_TRUE(response->headers);
3701 EXPECT_TRUE(response->headers->IsKeepAlive());
3702 EXPECT_EQ(200, response->headers->response_code());
3703 std::string body;
bnc691fda62016-08-12 00:43:163704 EXPECT_THAT(ReadTransaction(&trans, &body), IsOk());
mmenkee71e15332015-10-07 16:39:543705 EXPECT_EQ("hello", body);
3706}
3707
[email protected]a8e9b162009-03-12 00:06:443708// Test that we don't read the response body when we fail to establish a tunnel,
3709// even if the user cancels the proxy's auth attempt.
bncd16676a2016-07-20 16:23:013710TEST_F(HttpNetworkTransactionTest, BasicAuthProxyCancelTunnel) {
[email protected]cb9bf6ca2011-01-28 13:15:273711 HttpRequestInfo request;
3712 request.method = "GET";
bncce36dca22015-04-21 22:11:233713 request.url = GURL("https://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:273714
[email protected]a8e9b162009-03-12 00:06:443715 // Configure against proxy server "myproxy:70".
rdsmith82957ad2015-09-16 19:42:033716 session_deps_.proxy_service = ProxyService::CreateFixed("myproxy:70");
[email protected]a8e9b162009-03-12 00:06:443717
danakj1fd259a02016-04-16 03:17:093718 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]a8e9b162009-03-12 00:06:443719
bnc691fda62016-08-12 00:43:163720 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]a8e9b162009-03-12 00:06:443721
[email protected]a8e9b162009-03-12 00:06:443722 // Since we have proxy, should try to establish tunnel.
3723 MockWrite data_writes[] = {
rsleevidb16bb02015-11-12 23:47:173724 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
3725 "Host: www.example.org:443\r\n"
3726 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]a8e9b162009-03-12 00:06:443727 };
3728
3729 // The proxy responds to the connect with a 407.
3730 MockRead data_reads[] = {
ttuttle7933c112015-01-06 00:55:243731 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
3732 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
3733 MockRead("Content-Length: 10\r\n\r\n"),
mmenked39192ee2015-12-09 00:57:233734 MockRead("0123456789"),
ttuttle7933c112015-01-06 00:55:243735 MockRead(SYNCHRONOUS, ERR_UNEXPECTED),
[email protected]a8e9b162009-03-12 00:06:443736 };
3737
[email protected]31a2bfe2010-02-09 08:03:393738 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
3739 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:073740 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]a8e9b162009-03-12 00:06:443741
[email protected]49639fa2011-12-20 23:22:413742 TestCompletionCallback callback;
[email protected]a8e9b162009-03-12 00:06:443743
tfarina42834112016-09-22 13:38:203744 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:013745 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]a8e9b162009-03-12 00:06:443746
3747 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:013748 EXPECT_THAT(rv, IsOk());
[email protected]a8e9b162009-03-12 00:06:443749
bnc691fda62016-08-12 00:43:163750 const HttpResponseInfo* response = trans.GetResponseInfo();
ttuttle7933c112015-01-06 00:55:243751 ASSERT_TRUE(response);
3752 ASSERT_TRUE(response->headers);
[email protected]a8e9b162009-03-12 00:06:443753 EXPECT_TRUE(response->headers->IsKeepAlive());
3754 EXPECT_EQ(407, response->headers->response_code());
[email protected]1c773ea12009-04-28 19:58:423755 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
[email protected]a8e9b162009-03-12 00:06:443756
3757 std::string response_data;
bnc691fda62016-08-12 00:43:163758 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:013759 EXPECT_THAT(rv, IsError(ERR_TUNNEL_CONNECTION_FAILED));
[email protected]e60e47a2010-07-14 03:37:183760
3761 // Flush the idle socket before the HttpNetworkTransaction goes out of scope.
[email protected]102e27c2011-02-23 01:01:313762 session->CloseAllConnections();
[email protected]a8e9b162009-03-12 00:06:443763}
3764
ttuttle7933c112015-01-06 00:55:243765// Test that we don't pass extraneous headers from the proxy's response to the
3766// caller when the proxy responds to CONNECT with 407.
bncd16676a2016-07-20 16:23:013767TEST_F(HttpNetworkTransactionTest, SanitizeProxyAuthHeaders) {
ttuttle7933c112015-01-06 00:55:243768 HttpRequestInfo request;
3769 request.method = "GET";
bncce36dca22015-04-21 22:11:233770 request.url = GURL("https://www.example.org/");
ttuttle7933c112015-01-06 00:55:243771
3772 // Configure against proxy server "myproxy:70".
rdsmith82957ad2015-09-16 19:42:033773 session_deps_.proxy_service = ProxyService::CreateFixed("myproxy:70");
ttuttle7933c112015-01-06 00:55:243774
danakj1fd259a02016-04-16 03:17:093775 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
ttuttle7933c112015-01-06 00:55:243776
bnc691fda62016-08-12 00:43:163777 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
ttuttle7933c112015-01-06 00:55:243778
3779 // Since we have proxy, should try to establish tunnel.
3780 MockWrite data_writes[] = {
rsleevidb16bb02015-11-12 23:47:173781 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
3782 "Host: www.example.org:443\r\n"
3783 "Proxy-Connection: keep-alive\r\n\r\n"),
ttuttle7933c112015-01-06 00:55:243784 };
3785
3786 // The proxy responds to the connect with a 407.
3787 MockRead data_reads[] = {
3788 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
3789 MockRead("X-Foo: bar\r\n"),
3790 MockRead("Set-Cookie: foo=bar\r\n"),
3791 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
3792 MockRead("Content-Length: 10\r\n\r\n"),
mmenked39192ee2015-12-09 00:57:233793 MockRead(SYNCHRONOUS, ERR_UNEXPECTED),
ttuttle7933c112015-01-06 00:55:243794 };
3795
3796 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
3797 arraysize(data_writes));
3798 session_deps_.socket_factory->AddSocketDataProvider(&data);
3799
3800 TestCompletionCallback callback;
3801
tfarina42834112016-09-22 13:38:203802 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:013803 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
ttuttle7933c112015-01-06 00:55:243804
3805 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:013806 EXPECT_THAT(rv, IsOk());
ttuttle7933c112015-01-06 00:55:243807
bnc691fda62016-08-12 00:43:163808 const HttpResponseInfo* response = trans.GetResponseInfo();
ttuttle7933c112015-01-06 00:55:243809 ASSERT_TRUE(response);
3810 ASSERT_TRUE(response->headers);
3811 EXPECT_TRUE(response->headers->IsKeepAlive());
3812 EXPECT_EQ(407, response->headers->response_code());
3813 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
3814 EXPECT_FALSE(response->headers->HasHeader("X-Foo"));
3815 EXPECT_FALSE(response->headers->HasHeader("Set-Cookie"));
3816
3817 std::string response_data;
bnc691fda62016-08-12 00:43:163818 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:013819 EXPECT_THAT(rv, IsError(ERR_TUNNEL_CONNECTION_FAILED));
ttuttle7933c112015-01-06 00:55:243820
3821 // Flush the idle socket before the HttpNetworkTransaction goes out of scope.
3822 session->CloseAllConnections();
3823}
3824
[email protected]8fdbcd22010-05-05 02:54:523825// Test when a server (non-proxy) returns a 407 (proxy-authenticate).
3826// The request should fail with ERR_UNEXPECTED_PROXY_AUTH.
bncd16676a2016-07-20 16:23:013827TEST_F(HttpNetworkTransactionTest, UnexpectedProxyAuth) {
[email protected]8fdbcd22010-05-05 02:54:523828 HttpRequestInfo request;
3829 request.method = "GET";
bncce36dca22015-04-21 22:11:233830 request.url = GURL("http://www.example.org/");
[email protected]8fdbcd22010-05-05 02:54:523831
[email protected]cb9bf6ca2011-01-28 13:15:273832 // We are using a DIRECT connection (i.e. no proxy) for this session.
danakj1fd259a02016-04-16 03:17:093833 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:163834 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:273835
[email protected]8fdbcd22010-05-05 02:54:523836 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:233837 MockWrite(
3838 "GET / HTTP/1.1\r\n"
3839 "Host: www.example.org\r\n"
3840 "Connection: keep-alive\r\n\r\n"),
[email protected]8fdbcd22010-05-05 02:54:523841 };
3842
3843 MockRead data_reads1[] = {
3844 MockRead("HTTP/1.0 407 Proxy Auth required\r\n"),
3845 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
3846 // Large content-length -- won't matter, as connection will be reset.
3847 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:063848 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]8fdbcd22010-05-05 02:54:523849 };
3850
3851 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
3852 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:073853 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8fdbcd22010-05-05 02:54:523854
[email protected]49639fa2011-12-20 23:22:413855 TestCompletionCallback callback;
[email protected]8fdbcd22010-05-05 02:54:523856
tfarina42834112016-09-22 13:38:203857 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:013858 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]8fdbcd22010-05-05 02:54:523859
3860 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:013861 EXPECT_THAT(rv, IsError(ERR_UNEXPECTED_PROXY_AUTH));
[email protected]8fdbcd22010-05-05 02:54:523862}
3863
[email protected]7a67a8152010-11-05 18:31:103864// Tests when an HTTPS server (non-proxy) returns a 407 (proxy-authentication)
3865// through a non-authenticating proxy. The request should fail with
3866// ERR_UNEXPECTED_PROXY_AUTH.
3867// Note that it is impossible to detect if an HTTP server returns a 407 through
3868// a non-authenticating proxy - there is nothing to indicate whether the
3869// response came from the proxy or the server, so it is treated as if the proxy
3870// issued the challenge.
bncd16676a2016-07-20 16:23:013871TEST_F(HttpNetworkTransactionTest, HttpsServerRequestsProxyAuthThroughProxy) {
[email protected]cb9bf6ca2011-01-28 13:15:273872 HttpRequestInfo request;
3873 request.method = "GET";
bncce36dca22015-04-21 22:11:233874 request.url = GURL("https://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:273875
rdsmith82957ad2015-09-16 19:42:033876 session_deps_.proxy_service = ProxyService::CreateFixed("myproxy:70");
vishal.b62985ca92015-04-17 08:45:513877 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:073878 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:093879 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]7a67a8152010-11-05 18:31:103880
[email protected]7a67a8152010-11-05 18:31:103881 // Since we have proxy, should try to establish tunnel.
3882 MockWrite data_writes1[] = {
rsleevidb16bb02015-11-12 23:47:173883 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
3884 "Host: www.example.org:443\r\n"
3885 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]7a67a8152010-11-05 18:31:103886
rsleevidb16bb02015-11-12 23:47:173887 MockWrite("GET / HTTP/1.1\r\n"
3888 "Host: www.example.org\r\n"
3889 "Connection: keep-alive\r\n\r\n"),
[email protected]7a67a8152010-11-05 18:31:103890 };
3891
3892 MockRead data_reads1[] = {
3893 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
3894
3895 MockRead("HTTP/1.1 407 Unauthorized\r\n"),
3896 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
3897 MockRead("\r\n"),
[email protected]8ddf8322012-02-23 18:08:063898 MockRead(SYNCHRONOUS, OK),
[email protected]7a67a8152010-11-05 18:31:103899 };
3900
3901 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
3902 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:073903 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8ddf8322012-02-23 18:08:063904 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:073905 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]7a67a8152010-11-05 18:31:103906
[email protected]49639fa2011-12-20 23:22:413907 TestCompletionCallback callback1;
[email protected]7a67a8152010-11-05 18:31:103908
bnc691fda62016-08-12 00:43:163909 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]7a67a8152010-11-05 18:31:103910
bnc691fda62016-08-12 00:43:163911 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:013912 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]7a67a8152010-11-05 18:31:103913
3914 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:013915 EXPECT_THAT(rv, IsError(ERR_UNEXPECTED_PROXY_AUTH));
mmenke43758e62015-05-04 21:09:463916 TestNetLogEntry::List entries;
[email protected]b2fcd0e2010-12-01 15:19:403917 log.GetEntries(&entries);
[email protected]7a67a8152010-11-05 18:31:103918 size_t pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:003919 entries, 0, NetLogEventType::HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
3920 NetLogEventPhase::NONE);
[email protected]7a67a8152010-11-05 18:31:103921 ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:403922 entries, pos,
mikecirone8b85c432016-09-08 19:11:003923 NetLogEventType::HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
3924 NetLogEventPhase::NONE);
[email protected]7a67a8152010-11-05 18:31:103925}
[email protected]2df19bb2010-08-25 20:13:463926
mmenke2a1781d2015-10-07 19:25:333927// Test a proxy auth scheme that allows default credentials and a proxy server
3928// that uses non-persistent connections.
bncd16676a2016-07-20 16:23:013929TEST_F(HttpNetworkTransactionTest,
mmenke2a1781d2015-10-07 19:25:333930 AuthAllowsDefaultCredentialsTunnelConnectionClose) {
3931 HttpRequestInfo request;
3932 request.method = "GET";
3933 request.url = GURL("https://www.example.org/");
3934
3935 // Configure against proxy server "myproxy:70".
3936 session_deps_.proxy_service =
3937 ProxyService::CreateFixedFromPacResult("PROXY myproxy:70");
3938
Jeremy Roman0579ed62017-08-29 15:56:193939 auto auth_handler_factory = std::make_unique<HttpAuthHandlerMock::Factory>();
mmenke2a1781d2015-10-07 19:25:333940 auth_handler_factory->set_do_init_from_challenge(true);
Jeremy Roman0579ed62017-08-29 15:56:193941 auto mock_handler = std::make_unique<HttpAuthHandlerMock>();
mmenke2a1781d2015-10-07 19:25:333942 mock_handler->set_allows_default_credentials(true);
3943 auth_handler_factory->AddMockHandler(mock_handler.release(),
3944 HttpAuth::AUTH_PROXY);
dchengc7eeda422015-12-26 03:56:483945 session_deps_.http_auth_handler_factory = std::move(auth_handler_factory);
mmenke2a1781d2015-10-07 19:25:333946
3947 // Add NetLog just so can verify load timing information gets a NetLog ID.
3948 NetLog net_log;
3949 session_deps_.net_log = &net_log;
danakj1fd259a02016-04-16 03:17:093950 std::unique_ptr<HttpNetworkSession> session = CreateSession(&session_deps_);
mmenke2a1781d2015-10-07 19:25:333951
3952 // Since we have proxy, should try to establish tunnel.
3953 MockWrite data_writes1[] = {
3954 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:173955 "Host: www.example.org:443\r\n"
mmenke2a1781d2015-10-07 19:25:333956 "Proxy-Connection: keep-alive\r\n\r\n"),
3957 };
3958
3959 // The proxy responds to the connect with a 407, using a non-persistent
3960 // connection.
3961 MockRead data_reads1[] = {
3962 // No credentials.
3963 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
3964 MockRead("Proxy-Authenticate: Mock\r\n"),
3965 MockRead("Proxy-Connection: close\r\n\r\n"),
3966 };
3967
3968 // Since the first connection couldn't be reused, need to establish another
3969 // once given credentials.
3970 MockWrite data_writes2[] = {
3971 // After calling trans->RestartWithAuth(), this is the request we should
3972 // be issuing -- the final header line contains the credentials.
3973 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:173974 "Host: www.example.org:443\r\n"
mmenke2a1781d2015-10-07 19:25:333975 "Proxy-Connection: keep-alive\r\n"
3976 "Proxy-Authorization: auth_token\r\n\r\n"),
3977
3978 MockWrite("GET / HTTP/1.1\r\n"
3979 "Host: www.example.org\r\n"
3980 "Connection: keep-alive\r\n\r\n"),
3981 };
3982
3983 MockRead data_reads2[] = {
3984 MockRead("HTTP/1.0 200 Connection Established\r\n\r\n"),
3985
3986 MockRead("HTTP/1.1 200 OK\r\n"),
3987 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
3988 MockRead("Content-Length: 5\r\n\r\n"),
3989 MockRead(SYNCHRONOUS, "hello"),
3990 };
3991
3992 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
3993 data_writes1, arraysize(data_writes1));
3994 session_deps_.socket_factory->AddSocketDataProvider(&data1);
3995 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
3996 data_writes2, arraysize(data_writes2));
3997 session_deps_.socket_factory->AddSocketDataProvider(&data2);
3998 SSLSocketDataProvider ssl(ASYNC, OK);
3999 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
4000
bnc87dcefc2017-05-25 12:47:584001 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:194002 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
mmenke2a1781d2015-10-07 19:25:334003
4004 TestCompletionCallback callback;
tfarina42834112016-09-22 13:38:204005 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:014006 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenke2a1781d2015-10-07 19:25:334007
4008 const HttpResponseInfo* response = trans->GetResponseInfo();
4009 ASSERT_TRUE(response);
4010 ASSERT_TRUE(response->headers);
4011 EXPECT_FALSE(response->headers->IsKeepAlive());
4012 EXPECT_EQ(407, response->headers->response_code());
4013 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
4014 EXPECT_TRUE(trans->IsReadyToRestartForAuth());
wezca1070932016-05-26 20:30:524015 EXPECT_FALSE(response->auth_challenge);
mmenke2a1781d2015-10-07 19:25:334016
4017 LoadTimingInfo load_timing_info;
4018 // CONNECT requests and responses are handled at the connect job level, so
4019 // the transaction does not yet have a connection.
4020 EXPECT_FALSE(trans->GetLoadTimingInfo(&load_timing_info));
4021
4022 rv = trans->RestartWithAuth(AuthCredentials(), callback.callback());
robpercival214763f2016-07-01 23:27:014023 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenke2a1781d2015-10-07 19:25:334024 response = trans->GetResponseInfo();
4025 ASSERT_TRUE(response);
4026 ASSERT_TRUE(response->headers);
4027 EXPECT_TRUE(response->headers->IsKeepAlive());
4028 EXPECT_EQ(200, response->headers->response_code());
4029 EXPECT_EQ(5, response->headers->GetContentLength());
4030 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
4031
4032 // The password prompt info should not be set.
4033 EXPECT_FALSE(response->auth_challenge);
4034
4035 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
4036 TestLoadTimingNotReusedWithPac(load_timing_info,
4037 CONNECT_TIMING_HAS_SSL_TIMES);
4038
4039 trans.reset();
4040 session->CloseAllConnections();
4041}
4042
4043// Test a proxy auth scheme that allows default credentials and a proxy server
4044// that hangs up when credentials are initially sent.
bncd16676a2016-07-20 16:23:014045TEST_F(HttpNetworkTransactionTest,
mmenke2a1781d2015-10-07 19:25:334046 AuthAllowsDefaultCredentialsTunnelServerClosesConnection) {
4047 HttpRequestInfo request;
4048 request.method = "GET";
4049 request.url = GURL("https://www.example.org/");
4050
4051 // Configure against proxy server "myproxy:70".
4052 session_deps_.proxy_service =
4053 ProxyService::CreateFixedFromPacResult("PROXY myproxy:70");
4054
Jeremy Roman0579ed62017-08-29 15:56:194055 auto auth_handler_factory = std::make_unique<HttpAuthHandlerMock::Factory>();
mmenke2a1781d2015-10-07 19:25:334056 auth_handler_factory->set_do_init_from_challenge(true);
Jeremy Roman0579ed62017-08-29 15:56:194057 auto mock_handler = std::make_unique<HttpAuthHandlerMock>();
mmenke2a1781d2015-10-07 19:25:334058 mock_handler->set_allows_default_credentials(true);
4059 auth_handler_factory->AddMockHandler(mock_handler.release(),
4060 HttpAuth::AUTH_PROXY);
dchengc7eeda422015-12-26 03:56:484061 session_deps_.http_auth_handler_factory = std::move(auth_handler_factory);
mmenke2a1781d2015-10-07 19:25:334062
4063 // Add NetLog just so can verify load timing information gets a NetLog ID.
4064 NetLog net_log;
4065 session_deps_.net_log = &net_log;
danakj1fd259a02016-04-16 03:17:094066 std::unique_ptr<HttpNetworkSession> session = CreateSession(&session_deps_);
mmenke2a1781d2015-10-07 19:25:334067
4068 // Should try to establish tunnel.
4069 MockWrite data_writes1[] = {
4070 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:174071 "Host: www.example.org:443\r\n"
mmenke2a1781d2015-10-07 19:25:334072 "Proxy-Connection: keep-alive\r\n\r\n"),
4073
4074 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:174075 "Host: www.example.org:443\r\n"
mmenke2a1781d2015-10-07 19:25:334076 "Proxy-Connection: keep-alive\r\n"
4077 "Proxy-Authorization: auth_token\r\n\r\n"),
4078 };
4079
4080 // The proxy responds to the connect with a 407, using a non-persistent
4081 // connection.
4082 MockRead data_reads1[] = {
4083 // No credentials.
4084 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
4085 MockRead("Proxy-Authenticate: Mock\r\n\r\n"),
4086 MockRead(SYNCHRONOUS, ERR_CONNECTION_CLOSED),
4087 };
4088
4089 // Since the first connection was closed, need to establish another once given
4090 // credentials.
4091 MockWrite data_writes2[] = {
4092 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:174093 "Host: www.example.org:443\r\n"
mmenke2a1781d2015-10-07 19:25:334094 "Proxy-Connection: keep-alive\r\n"
4095 "Proxy-Authorization: auth_token\r\n\r\n"),
4096
4097 MockWrite("GET / HTTP/1.1\r\n"
4098 "Host: www.example.org\r\n"
4099 "Connection: keep-alive\r\n\r\n"),
4100 };
4101
4102 MockRead data_reads2[] = {
4103 MockRead("HTTP/1.0 200 Connection Established\r\n\r\n"),
4104
4105 MockRead("HTTP/1.1 200 OK\r\n"),
4106 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
4107 MockRead("Content-Length: 5\r\n\r\n"),
4108 MockRead(SYNCHRONOUS, "hello"),
4109 };
4110
4111 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
4112 data_writes1, arraysize(data_writes1));
4113 session_deps_.socket_factory->AddSocketDataProvider(&data1);
4114 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
4115 data_writes2, arraysize(data_writes2));
4116 session_deps_.socket_factory->AddSocketDataProvider(&data2);
4117 SSLSocketDataProvider ssl(ASYNC, OK);
4118 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
4119
bnc87dcefc2017-05-25 12:47:584120 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:194121 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
mmenke2a1781d2015-10-07 19:25:334122
4123 TestCompletionCallback callback;
tfarina42834112016-09-22 13:38:204124 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:014125 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenke2a1781d2015-10-07 19:25:334126
4127 const HttpResponseInfo* response = trans->GetResponseInfo();
4128 ASSERT_TRUE(response);
4129 ASSERT_TRUE(response->headers);
4130 EXPECT_TRUE(response->headers->IsKeepAlive());
4131 EXPECT_EQ(407, response->headers->response_code());
4132 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
4133 EXPECT_TRUE(trans->IsReadyToRestartForAuth());
4134 EXPECT_FALSE(response->auth_challenge);
4135
4136 LoadTimingInfo load_timing_info;
4137 // CONNECT requests and responses are handled at the connect job level, so
4138 // the transaction does not yet have a connection.
4139 EXPECT_FALSE(trans->GetLoadTimingInfo(&load_timing_info));
4140
4141 rv = trans->RestartWithAuth(AuthCredentials(), callback.callback());
robpercival214763f2016-07-01 23:27:014142 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenke2a1781d2015-10-07 19:25:334143
4144 response = trans->GetResponseInfo();
4145 ASSERT_TRUE(response);
4146 ASSERT_TRUE(response->headers);
4147 EXPECT_TRUE(response->headers->IsKeepAlive());
4148 EXPECT_EQ(200, response->headers->response_code());
4149 EXPECT_EQ(5, response->headers->GetContentLength());
4150 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
4151
4152 // The password prompt info should not be set.
wezca1070932016-05-26 20:30:524153 EXPECT_FALSE(response->auth_challenge);
mmenke2a1781d2015-10-07 19:25:334154
4155 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
4156 TestLoadTimingNotReusedWithPac(load_timing_info,
4157 CONNECT_TIMING_HAS_SSL_TIMES);
4158
4159 trans.reset();
4160 session->CloseAllConnections();
4161}
4162
4163// Test a proxy auth scheme that allows default credentials and a proxy server
4164// that hangs up when credentials are initially sent, and hangs up again when
4165// they are retried.
bncd16676a2016-07-20 16:23:014166TEST_F(HttpNetworkTransactionTest,
mmenke2a1781d2015-10-07 19:25:334167 AuthAllowsDefaultCredentialsTunnelServerClosesConnectionTwice) {
4168 HttpRequestInfo request;
4169 request.method = "GET";
4170 request.url = GURL("https://www.example.org/");
4171
4172 // Configure against proxy server "myproxy:70".
4173 session_deps_.proxy_service =
4174 ProxyService::CreateFixedFromPacResult("PROXY myproxy:70");
4175
Jeremy Roman0579ed62017-08-29 15:56:194176 auto auth_handler_factory = std::make_unique<HttpAuthHandlerMock::Factory>();
mmenke2a1781d2015-10-07 19:25:334177 auth_handler_factory->set_do_init_from_challenge(true);
Jeremy Roman0579ed62017-08-29 15:56:194178 auto mock_handler = std::make_unique<HttpAuthHandlerMock>();
mmenke2a1781d2015-10-07 19:25:334179 mock_handler->set_allows_default_credentials(true);
4180 auth_handler_factory->AddMockHandler(mock_handler.release(),
4181 HttpAuth::AUTH_PROXY);
dchengc7eeda422015-12-26 03:56:484182 session_deps_.http_auth_handler_factory = std::move(auth_handler_factory);
mmenke2a1781d2015-10-07 19:25:334183
4184 // Add NetLog just so can verify load timing information gets a NetLog ID.
4185 NetLog net_log;
4186 session_deps_.net_log = &net_log;
danakj1fd259a02016-04-16 03:17:094187 std::unique_ptr<HttpNetworkSession> session = CreateSession(&session_deps_);
mmenke2a1781d2015-10-07 19:25:334188
4189 // Should try to establish tunnel.
4190 MockWrite data_writes1[] = {
4191 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:174192 "Host: www.example.org:443\r\n"
mmenke2a1781d2015-10-07 19:25:334193 "Proxy-Connection: keep-alive\r\n\r\n"),
4194
4195 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:174196 "Host: www.example.org:443\r\n"
mmenke2a1781d2015-10-07 19:25:334197 "Proxy-Connection: keep-alive\r\n"
4198 "Proxy-Authorization: auth_token\r\n\r\n"),
4199 };
4200
4201 // The proxy responds to the connect with a 407, and then hangs up after the
4202 // second request is sent.
4203 MockRead data_reads1[] = {
4204 // No credentials.
4205 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
4206 MockRead("Content-Length: 0\r\n"),
4207 MockRead("Proxy-Connection: keep-alive\r\n"),
4208 MockRead("Proxy-Authenticate: Mock\r\n\r\n"),
4209 MockRead(SYNCHRONOUS, ERR_CONNECTION_CLOSED),
4210 };
4211
4212 // HttpNetworkTransaction sees a reused connection that was closed with
4213 // ERR_CONNECTION_CLOSED, realized it might have been a race, so retries the
4214 // request.
4215 MockWrite data_writes2[] = {
4216 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:174217 "Host: www.example.org:443\r\n"
mmenke2a1781d2015-10-07 19:25:334218 "Proxy-Connection: keep-alive\r\n\r\n"),
4219 };
4220
4221 // The proxy, having had more than enough of us, just hangs up.
4222 MockRead data_reads2[] = {
4223 // No credentials.
4224 MockRead(SYNCHRONOUS, ERR_CONNECTION_CLOSED),
4225 };
4226
4227 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
4228 data_writes1, arraysize(data_writes1));
4229 session_deps_.socket_factory->AddSocketDataProvider(&data1);
4230 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
4231 data_writes2, arraysize(data_writes2));
4232 session_deps_.socket_factory->AddSocketDataProvider(&data2);
4233
bnc87dcefc2017-05-25 12:47:584234 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:194235 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
mmenke2a1781d2015-10-07 19:25:334236
4237 TestCompletionCallback callback;
tfarina42834112016-09-22 13:38:204238 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:014239 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenke2a1781d2015-10-07 19:25:334240
4241 const HttpResponseInfo* response = trans->GetResponseInfo();
4242 ASSERT_TRUE(response);
4243 ASSERT_TRUE(response->headers);
4244 EXPECT_TRUE(response->headers->IsKeepAlive());
4245 EXPECT_EQ(407, response->headers->response_code());
4246 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
4247 EXPECT_TRUE(trans->IsReadyToRestartForAuth());
4248 EXPECT_FALSE(response->auth_challenge);
4249
4250 LoadTimingInfo load_timing_info;
4251 EXPECT_FALSE(trans->GetLoadTimingInfo(&load_timing_info));
4252
4253 rv = trans->RestartWithAuth(AuthCredentials(), callback.callback());
robpercival214763f2016-07-01 23:27:014254 EXPECT_THAT(callback.GetResult(rv), IsError(ERR_EMPTY_RESPONSE));
mmenke2a1781d2015-10-07 19:25:334255
4256 trans.reset();
4257 session->CloseAllConnections();
4258}
4259
4260// Test a proxy auth scheme that allows default credentials and a proxy server
4261// that hangs up when credentials are initially sent, and sends a challenge
4262// again they are retried.
bncd16676a2016-07-20 16:23:014263TEST_F(HttpNetworkTransactionTest,
mmenke2a1781d2015-10-07 19:25:334264 AuthAllowsDefaultCredentialsTunnelServerChallengesTwice) {
4265 HttpRequestInfo request;
4266 request.method = "GET";
4267 request.url = GURL("https://www.example.org/");
4268
4269 // Configure against proxy server "myproxy:70".
4270 session_deps_.proxy_service =
4271 ProxyService::CreateFixedFromPacResult("PROXY myproxy:70");
4272
Jeremy Roman0579ed62017-08-29 15:56:194273 auto auth_handler_factory = std::make_unique<HttpAuthHandlerMock::Factory>();
mmenke2a1781d2015-10-07 19:25:334274 auth_handler_factory->set_do_init_from_challenge(true);
Jeremy Roman0579ed62017-08-29 15:56:194275 auto mock_handler = std::make_unique<HttpAuthHandlerMock>();
mmenke2a1781d2015-10-07 19:25:334276 mock_handler->set_allows_default_credentials(true);
4277 auth_handler_factory->AddMockHandler(mock_handler.release(),
4278 HttpAuth::AUTH_PROXY);
4279 // Add another handler for the second challenge. It supports default
4280 // credentials, but they shouldn't be used, since they were already tried.
Jeremy Roman0579ed62017-08-29 15:56:194281 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);
dchengc7eeda422015-12-26 03:56:484285 session_deps_.http_auth_handler_factory = std::move(auth_handler_factory);
mmenke2a1781d2015-10-07 19:25:334286
4287 // Add NetLog just so can verify load timing information gets a NetLog ID.
4288 NetLog net_log;
4289 session_deps_.net_log = &net_log;
danakj1fd259a02016-04-16 03:17:094290 std::unique_ptr<HttpNetworkSession> session = CreateSession(&session_deps_);
mmenke2a1781d2015-10-07 19:25:334291
4292 // Should try to establish tunnel.
4293 MockWrite data_writes1[] = {
4294 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:174295 "Host: www.example.org:443\r\n"
mmenke2a1781d2015-10-07 19:25:334296 "Proxy-Connection: keep-alive\r\n\r\n"),
4297 };
4298
4299 // The proxy responds to the connect with a 407, using a non-persistent
4300 // connection.
4301 MockRead data_reads1[] = {
4302 // No credentials.
4303 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
4304 MockRead("Proxy-Authenticate: Mock\r\n"),
4305 MockRead("Proxy-Connection: close\r\n\r\n"),
4306 };
4307
4308 // Since the first connection was closed, need to establish another once given
4309 // credentials.
4310 MockWrite data_writes2[] = {
4311 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:174312 "Host: www.example.org:443\r\n"
mmenke2a1781d2015-10-07 19:25:334313 "Proxy-Connection: keep-alive\r\n"
4314 "Proxy-Authorization: auth_token\r\n\r\n"),
4315 };
4316
4317 MockRead data_reads2[] = {
4318 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
4319 MockRead("Proxy-Authenticate: Mock\r\n"),
4320 MockRead("Proxy-Connection: close\r\n\r\n"),
4321 };
4322
4323 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
4324 data_writes1, arraysize(data_writes1));
4325 session_deps_.socket_factory->AddSocketDataProvider(&data1);
4326 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
4327 data_writes2, arraysize(data_writes2));
4328 session_deps_.socket_factory->AddSocketDataProvider(&data2);
4329 SSLSocketDataProvider ssl(ASYNC, OK);
4330 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
4331
bnc87dcefc2017-05-25 12:47:584332 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:194333 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
mmenke2a1781d2015-10-07 19:25:334334
4335 TestCompletionCallback callback;
tfarina42834112016-09-22 13:38:204336 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:014337 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenke2a1781d2015-10-07 19:25:334338
4339 const HttpResponseInfo* response = trans->GetResponseInfo();
4340 ASSERT_TRUE(response);
4341 ASSERT_TRUE(response->headers);
4342 EXPECT_EQ(407, response->headers->response_code());
4343 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
4344 EXPECT_TRUE(trans->IsReadyToRestartForAuth());
4345 EXPECT_FALSE(response->auth_challenge);
4346
4347 LoadTimingInfo load_timing_info;
4348 EXPECT_FALSE(trans->GetLoadTimingInfo(&load_timing_info));
4349
4350 rv = trans->RestartWithAuth(AuthCredentials(), callback.callback());
robpercival214763f2016-07-01 23:27:014351 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenke2a1781d2015-10-07 19:25:334352 response = trans->GetResponseInfo();
4353 ASSERT_TRUE(response);
4354 ASSERT_TRUE(response->headers);
4355 EXPECT_EQ(407, response->headers->response_code());
4356 EXPECT_FALSE(trans->IsReadyToRestartForAuth());
4357 EXPECT_TRUE(response->auth_challenge);
4358
4359 trans.reset();
4360 session->CloseAllConnections();
4361}
4362
asankae2257db2016-10-11 22:03:164363// A more nuanced test than GenerateAuthToken test which asserts that
4364// ERR_INVALID_AUTH_CREDENTIALS does not cause the auth scheme to be
4365// unnecessarily invalidated, and that if the server co-operates, the
4366// authentication handshake can continue with the same scheme but with a
4367// different identity.
4368TEST_F(HttpNetworkTransactionTest, NonPermanentGenerateAuthTokenError) {
4369 HttpRequestInfo request;
4370 request.method = "GET";
4371 request.url = GURL("http://www.example.org/");
4372
Jeremy Roman0579ed62017-08-29 15:56:194373 auto auth_handler_factory = std::make_unique<HttpAuthHandlerMock::Factory>();
asankae2257db2016-10-11 22:03:164374 auth_handler_factory->set_do_init_from_challenge(true);
4375
4376 // First handler. Uses default credentials, but barfs at generate auth token.
Jeremy Roman0579ed62017-08-29 15:56:194377 auto mock_handler = std::make_unique<HttpAuthHandlerMock>();
asankae2257db2016-10-11 22:03:164378 mock_handler->set_allows_default_credentials(true);
4379 mock_handler->set_allows_explicit_credentials(true);
4380 mock_handler->set_connection_based(true);
4381 mock_handler->SetGenerateExpectation(true, ERR_INVALID_AUTH_CREDENTIALS);
4382 auth_handler_factory->AddMockHandler(mock_handler.release(),
4383 HttpAuth::AUTH_SERVER);
4384
4385 // Add another handler for the second challenge. It supports default
4386 // credentials, but they shouldn't be used, since they were already tried.
Jeremy Roman0579ed62017-08-29 15:56:194387 mock_handler = std::make_unique<HttpAuthHandlerMock>();
asankae2257db2016-10-11 22:03:164388 mock_handler->set_allows_default_credentials(true);
4389 mock_handler->set_allows_explicit_credentials(true);
4390 mock_handler->set_connection_based(true);
4391 auth_handler_factory->AddMockHandler(mock_handler.release(),
4392 HttpAuth::AUTH_SERVER);
4393 session_deps_.http_auth_handler_factory = std::move(auth_handler_factory);
4394
4395 std::unique_ptr<HttpNetworkSession> session = CreateSession(&session_deps_);
4396
4397 MockWrite data_writes1[] = {
4398 MockWrite("GET / HTTP/1.1\r\n"
4399 "Host: www.example.org\r\n"
4400 "Connection: keep-alive\r\n\r\n"),
4401 };
4402
4403 MockRead data_reads1[] = {
4404 MockRead("HTTP/1.1 401 Authentication Required\r\n"
4405 "WWW-Authenticate: Mock\r\n"
4406 "Connection: keep-alive\r\n\r\n"),
4407 };
4408
4409 // Identical to data_writes1[]. The AuthHandler encounters a
4410 // ERR_INVALID_AUTH_CREDENTIALS during the GenerateAuthToken stage, so the
4411 // transaction procceds without an authorization header.
4412 MockWrite data_writes2[] = {
4413 MockWrite("GET / HTTP/1.1\r\n"
4414 "Host: www.example.org\r\n"
4415 "Connection: keep-alive\r\n\r\n"),
4416 };
4417
4418 MockRead data_reads2[] = {
4419 MockRead("HTTP/1.1 401 Authentication Required\r\n"
4420 "WWW-Authenticate: Mock\r\n"
4421 "Connection: keep-alive\r\n\r\n"),
4422 };
4423
4424 MockWrite data_writes3[] = {
4425 MockWrite("GET / HTTP/1.1\r\n"
4426 "Host: www.example.org\r\n"
4427 "Connection: keep-alive\r\n"
4428 "Authorization: auth_token\r\n\r\n"),
4429 };
4430
4431 MockRead data_reads3[] = {
4432 MockRead("HTTP/1.1 200 OK\r\n"
4433 "Content-Length: 5\r\n"
4434 "Content-Type: text/plain\r\n"
4435 "Connection: keep-alive\r\n\r\n"
4436 "Hello"),
4437 };
4438
4439 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
4440 data_writes1, arraysize(data_writes1));
4441 session_deps_.socket_factory->AddSocketDataProvider(&data1);
4442
4443 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
4444 data_writes2, arraysize(data_writes2));
4445 session_deps_.socket_factory->AddSocketDataProvider(&data2);
4446
4447 StaticSocketDataProvider data3(data_reads3, arraysize(data_reads3),
4448 data_writes3, arraysize(data_writes3));
4449 session_deps_.socket_factory->AddSocketDataProvider(&data3);
4450
bnc87dcefc2017-05-25 12:47:584451 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:194452 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
asankae2257db2016-10-11 22:03:164453
4454 TestCompletionCallback callback;
4455 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
4456 EXPECT_THAT(callback.GetResult(rv), IsOk());
4457
4458 const HttpResponseInfo* response = trans->GetResponseInfo();
4459 ASSERT_TRUE(response);
4460 ASSERT_TRUE(response->headers);
4461 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
4462
4463 // The following three tests assert that an authentication challenge was
4464 // received and that the stack is ready to respond to the challenge using
4465 // ambient credentials.
4466 EXPECT_EQ(401, response->headers->response_code());
4467 EXPECT_TRUE(trans->IsReadyToRestartForAuth());
4468 EXPECT_FALSE(response->auth_challenge);
4469
4470 rv = trans->RestartWithAuth(AuthCredentials(), callback.callback());
4471 EXPECT_THAT(callback.GetResult(rv), IsOk());
4472 response = trans->GetResponseInfo();
4473 ASSERT_TRUE(response);
4474 ASSERT_TRUE(response->headers);
4475
4476 // The following three tests assert that an authentication challenge was
4477 // received and that the stack needs explicit credentials before it is ready
4478 // to respond to the challenge.
4479 EXPECT_EQ(401, response->headers->response_code());
4480 EXPECT_FALSE(trans->IsReadyToRestartForAuth());
4481 EXPECT_TRUE(response->auth_challenge);
4482
4483 rv = trans->RestartWithAuth(AuthCredentials(), callback.callback());
4484 EXPECT_THAT(callback.GetResult(rv), IsOk());
4485 response = trans->GetResponseInfo();
4486 ASSERT_TRUE(response);
4487 ASSERT_TRUE(response->headers);
4488 EXPECT_EQ(200, response->headers->response_code());
4489
4490 trans.reset();
4491 session->CloseAllConnections();
4492}
4493
Matt Menked1eb6d42018-01-17 04:54:064494// Proxy resolver that returns a proxy with the same host and port for different
4495// schemes, based on the path of the URL being requests.
4496class SameProxyWithDifferentSchemesProxyResolver : public ProxyResolver {
4497 public:
4498 SameProxyWithDifferentSchemesProxyResolver() {}
4499 ~SameProxyWithDifferentSchemesProxyResolver() override {}
4500
4501 static std::string ProxyHostPortPairAsString() { return "proxy.test:10000"; }
4502
4503 static HostPortPair ProxyHostPortPair() {
4504 return HostPortPair::FromString(ProxyHostPortPairAsString());
4505 }
4506
4507 // ProxyResolver implementation.
4508 int GetProxyForURL(const GURL& url,
4509 ProxyInfo* results,
4510 const CompletionCallback& callback,
4511 std::unique_ptr<Request>* request,
4512 const NetLogWithSource& /*net_log*/) override {
4513 *results = ProxyInfo();
4514 if (url.path() == "/socks4") {
4515 results->UsePacString("SOCKS " + ProxyHostPortPairAsString());
4516 return OK;
4517 }
4518 if (url.path() == "/socks5") {
4519 results->UsePacString("SOCKS5 " + ProxyHostPortPairAsString());
4520 return OK;
4521 }
4522 if (url.path() == "/http") {
4523 results->UsePacString("PROXY " + ProxyHostPortPairAsString());
4524 return OK;
4525 }
4526 if (url.path() == "/https") {
4527 results->UsePacString("HTTPS " + ProxyHostPortPairAsString());
4528 return OK;
4529 }
4530 NOTREACHED();
4531 return ERR_NOT_IMPLEMENTED;
4532 }
4533
4534 private:
4535 DISALLOW_COPY_AND_ASSIGN(SameProxyWithDifferentSchemesProxyResolver);
4536};
4537
4538class SameProxyWithDifferentSchemesProxyResolverFactory
4539 : public ProxyResolverFactory {
4540 public:
4541 SameProxyWithDifferentSchemesProxyResolverFactory()
4542 : ProxyResolverFactory(false) {}
4543
4544 int CreateProxyResolver(
4545 const scoped_refptr<ProxyResolverScriptData>& pac_script,
4546 std::unique_ptr<ProxyResolver>* resolver,
4547 const CompletionCallback& callback,
4548 std::unique_ptr<Request>* request) override {
4549 *resolver = std::make_unique<SameProxyWithDifferentSchemesProxyResolver>();
4550 return OK;
4551 }
4552
4553 private:
4554 DISALLOW_COPY_AND_ASSIGN(SameProxyWithDifferentSchemesProxyResolverFactory);
4555};
4556
4557// Check that when different proxy schemes are all applied to a proxy at the
4558// same address, the sonnections are not grouped together. i.e., a request to
4559// foo.com using proxy.com as an HTTPS proxy won't use the same socket as a
4560// request to foo.com using proxy.com as an HTTP proxy.
4561TEST_F(HttpNetworkTransactionTest, SameDestinationForDifferentProxyTypes) {
4562 session_deps_.proxy_service = std::make_unique<ProxyService>(
4563 std::make_unique<ProxyConfigServiceFixed>(
4564 ProxyConfig::CreateAutoDetect()),
4565 std::make_unique<SameProxyWithDifferentSchemesProxyResolverFactory>(),
4566 nullptr);
4567
4568 std::unique_ptr<HttpNetworkSession> session = CreateSession(&session_deps_);
4569
4570 MockWrite socks_writes[] = {
4571 MockWrite(SYNCHRONOUS, kSOCKS4OkRequestLocalHostPort80,
4572 kSOCKS4OkRequestLocalHostPort80Length),
4573 MockWrite(SYNCHRONOUS,
4574 "GET /socks4 HTTP/1.1\r\n"
4575 "Host: test\r\n"
4576 "Connection: keep-alive\r\n\r\n"),
4577 };
4578 MockRead socks_reads[] = {
4579 MockRead(SYNCHRONOUS, kSOCKS4OkReply, kSOCKS4OkReplyLength),
4580 MockRead("HTTP/1.0 200 OK\r\n"
4581 "Connection: keep-alive\r\n"
4582 "Content-Length: 15\r\n\r\n"
4583 "SOCKS4 Response"),
4584 };
4585 StaticSocketDataProvider socks_data(socks_reads, arraysize(socks_reads),
4586 socks_writes, arraysize(socks_writes));
4587 session_deps_.socket_factory->AddSocketDataProvider(&socks_data);
4588
4589 const char kSOCKS5Request[] = {
4590 0x05, // Version
4591 0x01, // Command (CONNECT)
4592 0x00, // Reserved
4593 0x03, // Address type (DOMAINNAME)
4594 0x04, // Length of domain (4)
4595 't', 'e', 's', 't', // Domain string
4596 0x00, 0x50, // 16-bit port (80)
4597 };
4598 MockWrite socks5_writes[] = {
4599 MockWrite(ASYNC, kSOCKS5GreetRequest, kSOCKS5GreetRequestLength),
4600 MockWrite(ASYNC, kSOCKS5Request, arraysize(kSOCKS5Request)),
4601 MockWrite(SYNCHRONOUS,
4602 "GET /socks5 HTTP/1.1\r\n"
4603 "Host: test\r\n"
4604 "Connection: keep-alive\r\n\r\n"),
4605 };
4606 MockRead socks5_reads[] = {
4607 MockRead(ASYNC, kSOCKS5GreetResponse, kSOCKS5GreetResponseLength),
4608 MockRead(ASYNC, kSOCKS5OkResponse, kSOCKS5OkResponseLength),
4609 MockRead("HTTP/1.0 200 OK\r\n"
4610 "Connection: keep-alive\r\n"
4611 "Content-Length: 15\r\n\r\n"
4612 "SOCKS5 Response"),
4613 };
4614 StaticSocketDataProvider socks5_data(socks5_reads, arraysize(socks5_reads),
4615 socks5_writes, arraysize(socks5_writes));
4616 session_deps_.socket_factory->AddSocketDataProvider(&socks5_data);
4617
4618 MockWrite http_writes[] = {
4619 MockWrite(SYNCHRONOUS,
4620 "GET http://test/http HTTP/1.1\r\n"
4621 "Host: test\r\n"
4622 "Proxy-Connection: keep-alive\r\n\r\n"),
4623 };
4624 MockRead http_reads[] = {
4625 MockRead("HTTP/1.1 200 OK\r\n"
4626 "Proxy-Connection: keep-alive\r\n"
4627 "Content-Length: 13\r\n\r\n"
4628 "HTTP Response"),
4629 };
4630 StaticSocketDataProvider http_data(http_reads, arraysize(http_reads),
4631 http_writes, arraysize(http_writes));
4632 session_deps_.socket_factory->AddSocketDataProvider(&http_data);
4633
4634 MockWrite https_writes[] = {
4635 MockWrite(SYNCHRONOUS,
4636 "GET http://test/https HTTP/1.1\r\n"
4637 "Host: test\r\n"
4638 "Proxy-Connection: keep-alive\r\n\r\n"),
4639 };
4640 MockRead https_reads[] = {
4641 MockRead("HTTP/1.1 200 OK\r\n"
4642 "Proxy-Connection: keep-alive\r\n"
4643 "Content-Length: 14\r\n\r\n"
4644 "HTTPS Response"),
4645 };
4646 StaticSocketDataProvider https_data(https_reads, arraysize(https_reads),
4647 https_writes, arraysize(https_writes));
4648 session_deps_.socket_factory->AddSocketDataProvider(&https_data);
4649 SSLSocketDataProvider ssl(SYNCHRONOUS, OK);
4650 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
4651
4652 struct TestCase {
4653 GURL url;
4654 std::string expected_response;
4655 // How many idle sockets there should be in the SOCKS proxy socket pool
4656 // after the test.
4657 int expected_idle_socks_sockets;
4658 // How many idle sockets there should be in the HTTP proxy socket pool after
4659 // the test.
4660 int expected_idle_http_sockets;
4661 } const kTestCases[] = {
4662 {GURL("http://test/socks4"), "SOCKS4 Response", 1, 0},
4663 {GURL("http://test/socks5"), "SOCKS5 Response", 2, 0},
4664 {GURL("http://test/http"), "HTTP Response", 2, 1},
4665 {GURL("http://test/https"), "HTTPS Response", 2, 2},
4666 };
4667
4668 for (const auto& test_case : kTestCases) {
4669 HttpRequestInfo request;
4670 request.method = "GET";
4671 request.url = test_case.url;
4672 std::unique_ptr<HttpNetworkTransaction> trans =
4673 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY,
4674 session.get());
4675 TestCompletionCallback callback;
4676 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
4677 EXPECT_THAT(callback.GetResult(rv), IsOk());
4678
4679 const HttpResponseInfo* response = trans->GetResponseInfo();
4680 ASSERT_TRUE(response);
4681 ASSERT_TRUE(response->headers);
4682 EXPECT_EQ(200, response->headers->response_code());
4683 std::string response_data;
4684 EXPECT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
4685 EXPECT_EQ(test_case.expected_response, response_data);
4686
4687 // Return the socket to the socket pool, so can make sure it's not used for
4688 // the next requests.
4689 trans.reset();
4690 base::RunLoop().RunUntilIdle();
4691
4692 // Check the number of idle sockets in the pool, to make sure that used
4693 // sockets are indeed being returned to the socket pool. If each request
4694 // doesn't return an idle socket to the pool, the test would incorrectly
4695 // pass.
4696 EXPECT_EQ(
4697 test_case.expected_idle_socks_sockets,
4698 session
4699 ->GetSocketPoolForSOCKSProxy(
4700 HttpNetworkSession::NORMAL_SOCKET_POOL,
4701 SameProxyWithDifferentSchemesProxyResolver::ProxyHostPortPair())
4702 ->IdleSocketCount());
4703 EXPECT_EQ(
4704 test_case.expected_idle_http_sockets,
4705 session
4706 ->GetSocketPoolForHTTPProxy(
4707 HttpNetworkSession::NORMAL_SOCKET_POOL,
4708 SameProxyWithDifferentSchemesProxyResolver::ProxyHostPortPair())
4709 ->IdleSocketCount());
4710 }
4711}
4712
[email protected]029c83b62013-01-24 05:28:204713// Test the load timing for HTTPS requests with an HTTP proxy.
bncd16676a2016-07-20 16:23:014714TEST_F(HttpNetworkTransactionTest, HttpProxyLoadTimingNoPacTwoRequests) {
[email protected]029c83b62013-01-24 05:28:204715 HttpRequestInfo request1;
4716 request1.method = "GET";
bncce36dca22015-04-21 22:11:234717 request1.url = GURL("https://www.example.org/1");
[email protected]029c83b62013-01-24 05:28:204718
4719 HttpRequestInfo request2;
4720 request2.method = "GET";
bncce36dca22015-04-21 22:11:234721 request2.url = GURL("https://www.example.org/2");
[email protected]029c83b62013-01-24 05:28:204722
4723 // Configure against proxy server "myproxy:70".
brettwc1213d92016-11-12 03:41:134724 session_deps_.proxy_service = ProxyService::CreateFixed("myproxy:70");
vishal.b62985ca92015-04-17 08:45:514725 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:074726 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:094727 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]029c83b62013-01-24 05:28:204728
4729 // Since we have proxy, should try to establish tunnel.
4730 MockWrite data_writes1[] = {
rsleevidb16bb02015-11-12 23:47:174731 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
4732 "Host: www.example.org:443\r\n"
4733 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]029c83b62013-01-24 05:28:204734
rsleevidb16bb02015-11-12 23:47:174735 MockWrite("GET /1 HTTP/1.1\r\n"
4736 "Host: www.example.org\r\n"
4737 "Connection: keep-alive\r\n\r\n"),
[email protected]029c83b62013-01-24 05:28:204738
rsleevidb16bb02015-11-12 23:47:174739 MockWrite("GET /2 HTTP/1.1\r\n"
4740 "Host: www.example.org\r\n"
4741 "Connection: keep-alive\r\n\r\n"),
[email protected]029c83b62013-01-24 05:28:204742 };
4743
4744 // The proxy responds to the connect with a 407, using a persistent
4745 // connection.
4746 MockRead data_reads1[] = {
4747 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
4748
4749 MockRead("HTTP/1.1 200 OK\r\n"),
4750 MockRead("Content-Length: 1\r\n\r\n"),
4751 MockRead(SYNCHRONOUS, "1"),
4752
4753 MockRead("HTTP/1.1 200 OK\r\n"),
4754 MockRead("Content-Length: 2\r\n\r\n"),
4755 MockRead(SYNCHRONOUS, "22"),
4756 };
4757
4758 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
4759 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:074760 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]029c83b62013-01-24 05:28:204761 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:074762 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]029c83b62013-01-24 05:28:204763
4764 TestCompletionCallback callback1;
bnc87dcefc2017-05-25 12:47:584765 auto trans1 =
Jeremy Roman0579ed62017-08-29 15:56:194766 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]029c83b62013-01-24 05:28:204767
4768 int rv = trans1->Start(&request1, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:014769 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]029c83b62013-01-24 05:28:204770
4771 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:014772 EXPECT_THAT(rv, IsOk());
[email protected]029c83b62013-01-24 05:28:204773
4774 const HttpResponseInfo* response1 = trans1->GetResponseInfo();
wezca1070932016-05-26 20:30:524775 ASSERT_TRUE(response1);
tbansal2ecbbc72016-10-06 17:15:474776 EXPECT_TRUE(response1->proxy_server.is_http());
wezca1070932016-05-26 20:30:524777 ASSERT_TRUE(response1->headers);
[email protected]029c83b62013-01-24 05:28:204778 EXPECT_EQ(1, response1->headers->GetContentLength());
4779
4780 LoadTimingInfo load_timing_info1;
4781 EXPECT_TRUE(trans1->GetLoadTimingInfo(&load_timing_info1));
4782 TestLoadTimingNotReused(load_timing_info1, CONNECT_TIMING_HAS_SSL_TIMES);
4783
4784 trans1.reset();
4785
4786 TestCompletionCallback callback2;
bnc87dcefc2017-05-25 12:47:584787 auto trans2 =
Jeremy Roman0579ed62017-08-29 15:56:194788 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]029c83b62013-01-24 05:28:204789
4790 rv = trans2->Start(&request2, callback2.callback(), log.bound());
robpercival214763f2016-07-01 23:27:014791 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]029c83b62013-01-24 05:28:204792
4793 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:014794 EXPECT_THAT(rv, IsOk());
[email protected]029c83b62013-01-24 05:28:204795
4796 const HttpResponseInfo* response2 = trans2->GetResponseInfo();
wezca1070932016-05-26 20:30:524797 ASSERT_TRUE(response2);
tbansal2ecbbc72016-10-06 17:15:474798 EXPECT_TRUE(response2->proxy_server.is_http());
wezca1070932016-05-26 20:30:524799 ASSERT_TRUE(response2->headers);
[email protected]029c83b62013-01-24 05:28:204800 EXPECT_EQ(2, response2->headers->GetContentLength());
4801
4802 LoadTimingInfo load_timing_info2;
4803 EXPECT_TRUE(trans2->GetLoadTimingInfo(&load_timing_info2));
4804 TestLoadTimingReused(load_timing_info2);
4805
4806 EXPECT_EQ(load_timing_info1.socket_log_id, load_timing_info2.socket_log_id);
4807
4808 trans2.reset();
4809 session->CloseAllConnections();
4810}
4811
4812// Test the load timing for HTTPS requests with an HTTP proxy and a PAC script.
bncd16676a2016-07-20 16:23:014813TEST_F(HttpNetworkTransactionTest, HttpProxyLoadTimingWithPacTwoRequests) {
[email protected]029c83b62013-01-24 05:28:204814 HttpRequestInfo request1;
4815 request1.method = "GET";
bncce36dca22015-04-21 22:11:234816 request1.url = GURL("https://www.example.org/1");
[email protected]029c83b62013-01-24 05:28:204817
4818 HttpRequestInfo request2;
4819 request2.method = "GET";
bncce36dca22015-04-21 22:11:234820 request2.url = GURL("https://www.example.org/2");
[email protected]029c83b62013-01-24 05:28:204821
4822 // Configure against proxy server "myproxy:70".
rdsmith82957ad2015-09-16 19:42:034823 session_deps_.proxy_service =
4824 ProxyService::CreateFixedFromPacResult("PROXY myproxy:70");
vishal.b62985ca92015-04-17 08:45:514825 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:074826 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:094827 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]029c83b62013-01-24 05:28:204828
4829 // Since we have proxy, should try to establish tunnel.
4830 MockWrite data_writes1[] = {
rsleevidb16bb02015-11-12 23:47:174831 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
4832 "Host: www.example.org:443\r\n"
4833 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]029c83b62013-01-24 05:28:204834
rsleevidb16bb02015-11-12 23:47:174835 MockWrite("GET /1 HTTP/1.1\r\n"
4836 "Host: www.example.org\r\n"
4837 "Connection: keep-alive\r\n\r\n"),
[email protected]029c83b62013-01-24 05:28:204838
rsleevidb16bb02015-11-12 23:47:174839 MockWrite("GET /2 HTTP/1.1\r\n"
4840 "Host: www.example.org\r\n"
4841 "Connection: keep-alive\r\n\r\n"),
[email protected]029c83b62013-01-24 05:28:204842 };
4843
4844 // The proxy responds to the connect with a 407, using a persistent
4845 // connection.
4846 MockRead data_reads1[] = {
4847 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
4848
4849 MockRead("HTTP/1.1 200 OK\r\n"),
4850 MockRead("Content-Length: 1\r\n\r\n"),
4851 MockRead(SYNCHRONOUS, "1"),
4852
4853 MockRead("HTTP/1.1 200 OK\r\n"),
4854 MockRead("Content-Length: 2\r\n\r\n"),
4855 MockRead(SYNCHRONOUS, "22"),
4856 };
4857
4858 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
4859 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:074860 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]029c83b62013-01-24 05:28:204861 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:074862 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]029c83b62013-01-24 05:28:204863
4864 TestCompletionCallback callback1;
bnc87dcefc2017-05-25 12:47:584865 auto trans1 =
Jeremy Roman0579ed62017-08-29 15:56:194866 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]029c83b62013-01-24 05:28:204867
4868 int rv = trans1->Start(&request1, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:014869 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]029c83b62013-01-24 05:28:204870
4871 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:014872 EXPECT_THAT(rv, IsOk());
[email protected]029c83b62013-01-24 05:28:204873
4874 const HttpResponseInfo* response1 = trans1->GetResponseInfo();
wezca1070932016-05-26 20:30:524875 ASSERT_TRUE(response1);
4876 ASSERT_TRUE(response1->headers);
[email protected]029c83b62013-01-24 05:28:204877 EXPECT_EQ(1, response1->headers->GetContentLength());
4878
4879 LoadTimingInfo load_timing_info1;
4880 EXPECT_TRUE(trans1->GetLoadTimingInfo(&load_timing_info1));
4881 TestLoadTimingNotReusedWithPac(load_timing_info1,
4882 CONNECT_TIMING_HAS_SSL_TIMES);
4883
4884 trans1.reset();
4885
4886 TestCompletionCallback callback2;
bnc87dcefc2017-05-25 12:47:584887 auto trans2 =
Jeremy Roman0579ed62017-08-29 15:56:194888 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]029c83b62013-01-24 05:28:204889
4890 rv = trans2->Start(&request2, callback2.callback(), log.bound());
robpercival214763f2016-07-01 23:27:014891 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]029c83b62013-01-24 05:28:204892
4893 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:014894 EXPECT_THAT(rv, IsOk());
[email protected]029c83b62013-01-24 05:28:204895
4896 const HttpResponseInfo* response2 = trans2->GetResponseInfo();
wezca1070932016-05-26 20:30:524897 ASSERT_TRUE(response2);
4898 ASSERT_TRUE(response2->headers);
[email protected]029c83b62013-01-24 05:28:204899 EXPECT_EQ(2, response2->headers->GetContentLength());
4900
4901 LoadTimingInfo load_timing_info2;
4902 EXPECT_TRUE(trans2->GetLoadTimingInfo(&load_timing_info2));
4903 TestLoadTimingReusedWithPac(load_timing_info2);
4904
4905 EXPECT_EQ(load_timing_info1.socket_log_id, load_timing_info2.socket_log_id);
4906
4907 trans2.reset();
4908 session->CloseAllConnections();
4909}
4910
[email protected]2df19bb2010-08-25 20:13:464911// Test a simple get through an HTTPS Proxy.
bncd16676a2016-07-20 16:23:014912TEST_F(HttpNetworkTransactionTest, HttpsProxyGet) {
[email protected]cb9bf6ca2011-01-28 13:15:274913 HttpRequestInfo request;
4914 request.method = "GET";
bncce36dca22015-04-21 22:11:234915 request.url = GURL("http://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:274916
[email protected]2df19bb2010-08-25 20:13:464917 // Configure against https proxy server "proxy:70".
rdsmith82957ad2015-09-16 19:42:034918 session_deps_.proxy_service = ProxyService::CreateFixed("https://proxy:70");
vishal.b62985ca92015-04-17 08:45:514919 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:074920 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:094921 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]2df19bb2010-08-25 20:13:464922
[email protected]2df19bb2010-08-25 20:13:464923 // Since we have proxy, should use full url
4924 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:234925 MockWrite(
4926 "GET http://www.example.org/ HTTP/1.1\r\n"
4927 "Host: www.example.org\r\n"
4928 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]2df19bb2010-08-25 20:13:464929 };
4930
4931 MockRead data_reads1[] = {
4932 MockRead("HTTP/1.1 200 OK\r\n"),
4933 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
4934 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:064935 MockRead(SYNCHRONOUS, OK),
[email protected]2df19bb2010-08-25 20:13:464936 };
4937
4938 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
4939 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:074940 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8ddf8322012-02-23 18:08:064941 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:074942 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]2df19bb2010-08-25 20:13:464943
[email protected]49639fa2011-12-20 23:22:414944 TestCompletionCallback callback1;
[email protected]2df19bb2010-08-25 20:13:464945
bnc691fda62016-08-12 00:43:164946 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]0b0bf032010-09-21 18:08:504947
bnc691fda62016-08-12 00:43:164948 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:014949 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2df19bb2010-08-25 20:13:464950
4951 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:014952 EXPECT_THAT(rv, IsOk());
[email protected]2df19bb2010-08-25 20:13:464953
[email protected]58e32bb2013-01-21 18:23:254954 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:164955 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]58e32bb2013-01-21 18:23:254956 TestLoadTimingNotReused(load_timing_info,
4957 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
4958
bnc691fda62016-08-12 00:43:164959 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:524960 ASSERT_TRUE(response);
[email protected]2df19bb2010-08-25 20:13:464961
tbansal2ecbbc72016-10-06 17:15:474962 EXPECT_TRUE(response->proxy_server.is_https());
[email protected]2df19bb2010-08-25 20:13:464963 EXPECT_TRUE(response->headers->IsKeepAlive());
4964 EXPECT_EQ(200, response->headers->response_code());
4965 EXPECT_EQ(100, response->headers->GetContentLength());
4966 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
4967
4968 // The password prompt info should not be set.
wezca1070932016-05-26 20:30:524969 EXPECT_FALSE(response->auth_challenge);
[email protected]2df19bb2010-08-25 20:13:464970}
4971
[email protected]7642b5ae2010-09-01 20:55:174972// Test a SPDY get through an HTTPS Proxy.
bncd16676a2016-07-20 16:23:014973TEST_F(HttpNetworkTransactionTest, HttpsProxySpdyGet) {
[email protected]cb9bf6ca2011-01-28 13:15:274974 HttpRequestInfo request;
4975 request.method = "GET";
bncce36dca22015-04-21 22:11:234976 request.url = GURL("http://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:274977
[email protected]7642b5ae2010-09-01 20:55:174978 // Configure against https proxy server "proxy:70".
rdsmith82957ad2015-09-16 19:42:034979 session_deps_.proxy_service = ProxyService::CreateFixed("https://proxy:70");
vishal.b62985ca92015-04-17 08:45:514980 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:074981 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:094982 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]7642b5ae2010-09-01 20:55:174983
bncce36dca22015-04-21 22:11:234984 // fetch http://www.example.org/ via SPDY
bncdf80d44fd2016-07-15 20:27:414985 SpdySerializedFrame req(
bncb26024382016-06-29 02:39:454986 spdy_util_.ConstructSpdyGet("http://www.example.org/", 1, LOWEST));
bncdf80d44fd2016-07-15 20:27:414987 MockWrite spdy_writes[] = {CreateMockWrite(req, 0)};
[email protected]7642b5ae2010-09-01 20:55:174988
bnc42331402016-07-25 13:36:154989 SpdySerializedFrame resp(spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
bncdf80d44fd2016-07-15 20:27:414990 SpdySerializedFrame data(spdy_util_.ConstructSpdyDataFrame(1, true));
[email protected]7642b5ae2010-09-01 20:55:174991 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:414992 CreateMockRead(resp, 1), CreateMockRead(data, 2), MockRead(ASYNC, 0, 3),
[email protected]7642b5ae2010-09-01 20:55:174993 };
4994
rch8e6c6c42015-05-01 14:05:134995 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
4996 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:074997 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]7642b5ae2010-09-01 20:55:174998
[email protected]8ddf8322012-02-23 18:08:064999 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:365000 ssl.next_proto = kProtoHTTP2;
[email protected]bb88e1d32013-05-03 23:11:075001 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]7642b5ae2010-09-01 20:55:175002
[email protected]49639fa2011-12-20 23:22:415003 TestCompletionCallback callback1;
[email protected]7642b5ae2010-09-01 20:55:175004
bnc691fda62016-08-12 00:43:165005 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]0b0bf032010-09-21 18:08:505006
bnc691fda62016-08-12 00:43:165007 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:015008 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]7642b5ae2010-09-01 20:55:175009
5010 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:015011 EXPECT_THAT(rv, IsOk());
[email protected]7642b5ae2010-09-01 20:55:175012
[email protected]58e32bb2013-01-21 18:23:255013 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:165014 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]58e32bb2013-01-21 18:23:255015 TestLoadTimingNotReused(load_timing_info,
5016 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
5017
bnc691fda62016-08-12 00:43:165018 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:525019 ASSERT_TRUE(response);
tbansal2ecbbc72016-10-06 17:15:475020 EXPECT_TRUE(response->proxy_server.is_https());
wezca1070932016-05-26 20:30:525021 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:025022 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]7642b5ae2010-09-01 20:55:175023
5024 std::string response_data;
bnc691fda62016-08-12 00:43:165025 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
[email protected]448d4ca52012-03-04 04:12:235026 EXPECT_EQ(kUploadData, response_data);
[email protected]7642b5ae2010-09-01 20:55:175027}
5028
[email protected]1c173852014-06-19 12:51:505029// Verifies that a session which races and wins against the owning transaction
5030// (completing prior to host resolution), doesn't fail the transaction.
5031// Regression test for crbug.com/334413.
bncd16676a2016-07-20 16:23:015032TEST_F(HttpNetworkTransactionTest, HttpsProxySpdyGetWithSessionRace) {
[email protected]1c173852014-06-19 12:51:505033 HttpRequestInfo request;
5034 request.method = "GET";
bncce36dca22015-04-21 22:11:235035 request.url = GURL("http://www.example.org/");
[email protected]1c173852014-06-19 12:51:505036
5037 // Configure SPDY proxy server "proxy:70".
rdsmith82957ad2015-09-16 19:42:035038 session_deps_.proxy_service = ProxyService::CreateFixed("https://proxy:70");
vishal.b62985ca92015-04-17 08:45:515039 BoundTestNetLog log;
[email protected]1c173852014-06-19 12:51:505040 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:095041 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]1c173852014-06-19 12:51:505042
bncce36dca22015-04-21 22:11:235043 // Fetch http://www.example.org/ through the SPDY proxy.
bncdf80d44fd2016-07-15 20:27:415044 SpdySerializedFrame req(
bncb26024382016-06-29 02:39:455045 spdy_util_.ConstructSpdyGet("http://www.example.org/", 1, LOWEST));
bncdf80d44fd2016-07-15 20:27:415046 MockWrite spdy_writes[] = {CreateMockWrite(req, 0)};
[email protected]1c173852014-06-19 12:51:505047
bnc42331402016-07-25 13:36:155048 SpdySerializedFrame resp(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
bncdf80d44fd2016-07-15 20:27:415049 SpdySerializedFrame data(spdy_util_.ConstructSpdyDataFrame(1, true));
[email protected]1c173852014-06-19 12:51:505050 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:415051 CreateMockRead(resp, 1), CreateMockRead(data, 2), MockRead(ASYNC, 0, 3),
[email protected]1c173852014-06-19 12:51:505052 };
5053
rch8e6c6c42015-05-01 14:05:135054 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
5055 arraysize(spdy_writes));
[email protected]1c173852014-06-19 12:51:505056 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
5057
5058 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:365059 ssl.next_proto = kProtoHTTP2;
[email protected]1c173852014-06-19 12:51:505060 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
5061
5062 TestCompletionCallback callback1;
5063
bnc691fda62016-08-12 00:43:165064 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]1c173852014-06-19 12:51:505065
5066 // Stall the hostname resolution begun by the transaction.
5067 session_deps_.host_resolver->set_synchronous_mode(false);
5068 session_deps_.host_resolver->set_ondemand_mode(true);
5069
bnc691fda62016-08-12 00:43:165070 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:015071 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]1c173852014-06-19 12:51:505072
5073 // Race a session to the proxy, which completes first.
5074 session_deps_.host_resolver->set_ondemand_mode(false);
Paul Jensena457017a2018-01-19 23:52:045075 SpdySessionKey key(HostPortPair("proxy", 70), ProxyServer::Direct(),
5076 PRIVACY_MODE_DISABLED, SocketTag());
[email protected]1c173852014-06-19 12:51:505077 base::WeakPtr<SpdySession> spdy_session =
Bence Béky0ef1556e2017-06-30 19:52:525078 CreateSpdySession(session.get(), key, log.bound());
[email protected]1c173852014-06-19 12:51:505079
5080 // Unstall the resolution begun by the transaction.
5081 session_deps_.host_resolver->set_ondemand_mode(true);
5082 session_deps_.host_resolver->ResolveAllPending();
5083
5084 EXPECT_FALSE(callback1.have_result());
5085 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:015086 EXPECT_THAT(rv, IsOk());
[email protected]1c173852014-06-19 12:51:505087
bnc691fda62016-08-12 00:43:165088 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:525089 ASSERT_TRUE(response);
5090 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:025091 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]1c173852014-06-19 12:51:505092
5093 std::string response_data;
bnc691fda62016-08-12 00:43:165094 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
[email protected]1c173852014-06-19 12:51:505095 EXPECT_EQ(kUploadData, response_data);
5096}
5097
[email protected]dc7bd1c52010-11-12 00:01:135098// Test a SPDY get through an HTTPS Proxy.
bncd16676a2016-07-20 16:23:015099TEST_F(HttpNetworkTransactionTest, HttpsProxySpdyGetWithProxyAuth) {
[email protected]cb9bf6ca2011-01-28 13:15:275100 HttpRequestInfo request;
5101 request.method = "GET";
bncce36dca22015-04-21 22:11:235102 request.url = GURL("http://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:275103
[email protected]79cb5c12011-09-12 13:12:045104 // Configure against https proxy server "myproxy:70".
rdsmith82957ad2015-09-16 19:42:035105 session_deps_.proxy_service = ProxyService::CreateFixed("https://myproxy:70");
vishal.b62985ca92015-04-17 08:45:515106 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:075107 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:095108 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]dc7bd1c52010-11-12 00:01:135109
[email protected]dc7bd1c52010-11-12 00:01:135110 // The first request will be a bare GET, the second request will be a
5111 // GET with a Proxy-Authorization header.
bncb26024382016-06-29 02:39:455112 spdy_util_.set_default_url(request.url);
bncdf80d44fd2016-07-15 20:27:415113 SpdySerializedFrame req_get(
bnc38dcd392016-02-09 23:19:495114 spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST, false));
rdsmithebb50aa2015-11-12 03:44:385115 spdy_util_.UpdateWithStreamDestruction(1);
[email protected]dc7bd1c52010-11-12 00:01:135116 const char* const kExtraAuthorizationHeaders[] = {
[email protected]cdf8f7e72013-05-23 10:56:465117 "proxy-authorization", "Basic Zm9vOmJhcg=="
[email protected]dc7bd1c52010-11-12 00:01:135118 };
bncdf80d44fd2016-07-15 20:27:415119 SpdySerializedFrame req_get_authorization(spdy_util_.ConstructSpdyGet(
5120 kExtraAuthorizationHeaders, arraysize(kExtraAuthorizationHeaders) / 2, 3,
5121 LOWEST, false));
[email protected]dc7bd1c52010-11-12 00:01:135122 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:415123 CreateMockWrite(req_get, 0), CreateMockWrite(req_get_authorization, 3),
[email protected]dc7bd1c52010-11-12 00:01:135124 };
5125
5126 // The first response is a 407 proxy authentication challenge, and the second
5127 // response will be a 200 response since the second request includes a valid
5128 // Authorization header.
5129 const char* const kExtraAuthenticationHeaders[] = {
[email protected]cdf8f7e72013-05-23 10:56:465130 "proxy-authenticate", "Basic realm=\"MyRealm1\""
[email protected]dc7bd1c52010-11-12 00:01:135131 };
bnc42331402016-07-25 13:36:155132 SpdySerializedFrame resp_authentication(spdy_util_.ConstructSpdyReplyError(
bncc9f762a2016-12-06 20:38:235133 "407", kExtraAuthenticationHeaders,
bncdf80d44fd2016-07-15 20:27:415134 arraysize(kExtraAuthenticationHeaders) / 2, 1));
5135 SpdySerializedFrame body_authentication(
5136 spdy_util_.ConstructSpdyDataFrame(1, true));
bnc42331402016-07-25 13:36:155137 SpdySerializedFrame resp_data(spdy_util_.ConstructSpdyGetReply(NULL, 0, 3));
bncdf80d44fd2016-07-15 20:27:415138 SpdySerializedFrame body_data(spdy_util_.ConstructSpdyDataFrame(3, true));
[email protected]dc7bd1c52010-11-12 00:01:135139 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:415140 CreateMockRead(resp_authentication, 1),
bnceb9aa7112017-01-05 01:03:465141 CreateMockRead(body_authentication, 2, SYNCHRONOUS),
bncdf80d44fd2016-07-15 20:27:415142 CreateMockRead(resp_data, 4),
5143 CreateMockRead(body_data, 5),
rch8e6c6c42015-05-01 14:05:135144 MockRead(ASYNC, 0, 6),
[email protected]dc7bd1c52010-11-12 00:01:135145 };
5146
rch8e6c6c42015-05-01 14:05:135147 SequencedSocketData data(spdy_reads, arraysize(spdy_reads), spdy_writes,
5148 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:075149 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]dc7bd1c52010-11-12 00:01:135150
[email protected]8ddf8322012-02-23 18:08:065151 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:365152 ssl.next_proto = kProtoHTTP2;
[email protected]bb88e1d32013-05-03 23:11:075153 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]dc7bd1c52010-11-12 00:01:135154
[email protected]49639fa2011-12-20 23:22:415155 TestCompletionCallback callback1;
[email protected]dc7bd1c52010-11-12 00:01:135156
bnc691fda62016-08-12 00:43:165157 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]dc7bd1c52010-11-12 00:01:135158
bnc691fda62016-08-12 00:43:165159 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:015160 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]dc7bd1c52010-11-12 00:01:135161
5162 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:015163 EXPECT_THAT(rv, IsOk());
[email protected]dc7bd1c52010-11-12 00:01:135164
bnc691fda62016-08-12 00:43:165165 const HttpResponseInfo* const response = trans.GetResponseInfo();
[email protected]dc7bd1c52010-11-12 00:01:135166
wezca1070932016-05-26 20:30:525167 ASSERT_TRUE(response);
5168 ASSERT_TRUE(response->headers);
[email protected]dc7bd1c52010-11-12 00:01:135169 EXPECT_EQ(407, response->headers->response_code());
5170 EXPECT_TRUE(response->was_fetched_via_spdy);
asanka098c0092016-06-16 20:18:435171 EXPECT_TRUE(CheckBasicSecureProxyAuth(response->auth_challenge.get()));
[email protected]dc7bd1c52010-11-12 00:01:135172
[email protected]49639fa2011-12-20 23:22:415173 TestCompletionCallback callback2;
[email protected]dc7bd1c52010-11-12 00:01:135174
bnc691fda62016-08-12 00:43:165175 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar), callback2.callback());
robpercival214763f2016-07-01 23:27:015176 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]dc7bd1c52010-11-12 00:01:135177
5178 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:015179 EXPECT_THAT(rv, IsOk());
[email protected]dc7bd1c52010-11-12 00:01:135180
bnc691fda62016-08-12 00:43:165181 const HttpResponseInfo* const response_restart = trans.GetResponseInfo();
[email protected]dc7bd1c52010-11-12 00:01:135182
wezca1070932016-05-26 20:30:525183 ASSERT_TRUE(response_restart);
5184 ASSERT_TRUE(response_restart->headers);
[email protected]dc7bd1c52010-11-12 00:01:135185 EXPECT_EQ(200, response_restart->headers->response_code());
5186 // The password prompt info should not be set.
wezca1070932016-05-26 20:30:525187 EXPECT_FALSE(response_restart->auth_challenge);
[email protected]dc7bd1c52010-11-12 00:01:135188}
5189
[email protected]d9da5fe2010-10-13 22:37:165190// Test a SPDY CONNECT through an HTTPS Proxy to an HTTPS (non-SPDY) Server.
bncd16676a2016-07-20 16:23:015191TEST_F(HttpNetworkTransactionTest, HttpsProxySpdyConnectHttps) {
[email protected]cb9bf6ca2011-01-28 13:15:275192 HttpRequestInfo request;
5193 request.method = "GET";
bncce36dca22015-04-21 22:11:235194 request.url = GURL("https://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:275195
[email protected]d9da5fe2010-10-13 22:37:165196 // Configure against https proxy server "proxy:70".
rdsmith82957ad2015-09-16 19:42:035197 session_deps_.proxy_service = ProxyService::CreateFixed("https://proxy:70");
vishal.b62985ca92015-04-17 08:45:515198 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:075199 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:095200 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]d9da5fe2010-10-13 22:37:165201
bnc691fda62016-08-12 00:43:165202 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]d9da5fe2010-10-13 22:37:165203
bncce36dca22015-04-21 22:11:235204 // CONNECT to www.example.org:443 via SPDY
bncdf80d44fd2016-07-15 20:27:415205 SpdySerializedFrame connect(spdy_util_.ConstructSpdyConnect(
bncce36dca22015-04-21 22:11:235206 NULL, 0, 1, LOWEST, HostPortPair("www.example.org", 443)));
5207 // fetch https://www.example.org/ via HTTP
[email protected]d9da5fe2010-10-13 22:37:165208
bncce36dca22015-04-21 22:11:235209 const char get[] =
5210 "GET / HTTP/1.1\r\n"
5211 "Host: www.example.org\r\n"
5212 "Connection: keep-alive\r\n\r\n";
bncdf80d44fd2016-07-15 20:27:415213 SpdySerializedFrame wrapped_get(
5214 spdy_util_.ConstructSpdyDataFrame(1, get, strlen(get), false));
bnc42331402016-07-25 13:36:155215 SpdySerializedFrame conn_resp(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
[email protected]d9da5fe2010-10-13 22:37:165216 const char resp[] = "HTTP/1.1 200 OK\r\n"
5217 "Content-Length: 10\r\n\r\n";
bncdf80d44fd2016-07-15 20:27:415218 SpdySerializedFrame wrapped_get_resp(
5219 spdy_util_.ConstructSpdyDataFrame(1, resp, strlen(resp), false));
5220 SpdySerializedFrame wrapped_body(
5221 spdy_util_.ConstructSpdyDataFrame(1, "1234567890", 10, false));
5222 SpdySerializedFrame window_update(
5223 spdy_util_.ConstructSpdyWindowUpdate(1, wrapped_get_resp.size()));
[email protected]8d2f7012012-02-16 00:08:045224
5225 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:415226 CreateMockWrite(connect, 0), CreateMockWrite(wrapped_get, 2),
5227 CreateMockWrite(window_update, 6),
[email protected]8d2f7012012-02-16 00:08:045228 };
5229
[email protected]d9da5fe2010-10-13 22:37:165230 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:415231 CreateMockRead(conn_resp, 1, ASYNC),
5232 CreateMockRead(wrapped_get_resp, 3, ASYNC),
5233 CreateMockRead(wrapped_body, 4, ASYNC),
5234 CreateMockRead(wrapped_body, 5, ASYNC),
rch8e6c6c42015-05-01 14:05:135235 MockRead(ASYNC, 0, 7),
[email protected]d9da5fe2010-10-13 22:37:165236 };
5237
rch8e6c6c42015-05-01 14:05:135238 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
5239 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:075240 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]d9da5fe2010-10-13 22:37:165241
[email protected]8ddf8322012-02-23 18:08:065242 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:365243 ssl.next_proto = kProtoHTTP2;
[email protected]bb88e1d32013-05-03 23:11:075244 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]8ddf8322012-02-23 18:08:065245 SSLSocketDataProvider ssl2(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:075246 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
[email protected]d9da5fe2010-10-13 22:37:165247
[email protected]49639fa2011-12-20 23:22:415248 TestCompletionCallback callback1;
[email protected]d9da5fe2010-10-13 22:37:165249
bnc691fda62016-08-12 00:43:165250 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:015251 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]d9da5fe2010-10-13 22:37:165252
5253 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:015254 ASSERT_THAT(rv, IsOk());
[email protected]d9da5fe2010-10-13 22:37:165255
[email protected]58e32bb2013-01-21 18:23:255256 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:165257 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]58e32bb2013-01-21 18:23:255258 TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_SSL_TIMES);
5259
bnc691fda62016-08-12 00:43:165260 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:525261 ASSERT_TRUE(response);
5262 ASSERT_TRUE(response->headers);
[email protected]d9da5fe2010-10-13 22:37:165263 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
5264
5265 std::string response_data;
bnc691fda62016-08-12 00:43:165266 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
[email protected]d9da5fe2010-10-13 22:37:165267 EXPECT_EQ("1234567890", response_data);
5268}
5269
5270// Test a SPDY CONNECT through an HTTPS Proxy to a SPDY server.
bncd16676a2016-07-20 16:23:015271TEST_F(HttpNetworkTransactionTest, HttpsProxySpdyConnectSpdy) {
5272 SpdyTestUtil spdy_util_wrapped;
rdsmithebb50aa2015-11-12 03:44:385273
[email protected]cb9bf6ca2011-01-28 13:15:275274 HttpRequestInfo request;
5275 request.method = "GET";
bncce36dca22015-04-21 22:11:235276 request.url = GURL("https://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:275277
[email protected]d9da5fe2010-10-13 22:37:165278 // Configure against https proxy server "proxy:70".
rdsmith82957ad2015-09-16 19:42:035279 session_deps_.proxy_service = ProxyService::CreateFixed("https://proxy:70");
vishal.b62985ca92015-04-17 08:45:515280 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:075281 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:095282 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]d9da5fe2010-10-13 22:37:165283
bnc691fda62016-08-12 00:43:165284 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]d9da5fe2010-10-13 22:37:165285
bncce36dca22015-04-21 22:11:235286 // CONNECT to www.example.org:443 via SPDY
bncdf80d44fd2016-07-15 20:27:415287 SpdySerializedFrame connect(spdy_util_.ConstructSpdyConnect(
bncce36dca22015-04-21 22:11:235288 NULL, 0, 1, LOWEST, HostPortPair("www.example.org", 443)));
5289 // fetch https://www.example.org/ via SPDY
5290 const char kMyUrl[] = "https://www.example.org/";
bncdf80d44fd2016-07-15 20:27:415291 SpdySerializedFrame get(
bnc38dcd392016-02-09 23:19:495292 spdy_util_wrapped.ConstructSpdyGet(kMyUrl, 1, LOWEST));
bncdf80d44fd2016-07-15 20:27:415293 SpdySerializedFrame wrapped_get(spdy_util_.ConstructWrappedSpdyFrame(get, 1));
bnc42331402016-07-25 13:36:155294 SpdySerializedFrame conn_resp(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
bncdf80d44fd2016-07-15 20:27:415295 SpdySerializedFrame get_resp(
bnc42331402016-07-25 13:36:155296 spdy_util_wrapped.ConstructSpdyGetReply(NULL, 0, 1));
bncdf80d44fd2016-07-15 20:27:415297 SpdySerializedFrame wrapped_get_resp(
[email protected]23e482282013-06-14 16:08:025298 spdy_util_.ConstructWrappedSpdyFrame(get_resp, 1));
bncdf80d44fd2016-07-15 20:27:415299 SpdySerializedFrame body(spdy_util_wrapped.ConstructSpdyDataFrame(1, true));
5300 SpdySerializedFrame wrapped_body(
[email protected]23e482282013-06-14 16:08:025301 spdy_util_.ConstructWrappedSpdyFrame(body, 1));
bncdf80d44fd2016-07-15 20:27:415302 SpdySerializedFrame window_update_get_resp(
5303 spdy_util_.ConstructSpdyWindowUpdate(1, wrapped_get_resp.size()));
5304 SpdySerializedFrame window_update_body(
5305 spdy_util_.ConstructSpdyWindowUpdate(1, wrapped_body.size()));
[email protected]8d2f7012012-02-16 00:08:045306
5307 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:415308 CreateMockWrite(connect, 0), CreateMockWrite(wrapped_get, 2),
5309 CreateMockWrite(window_update_get_resp, 6),
5310 CreateMockWrite(window_update_body, 7),
[email protected]8d2f7012012-02-16 00:08:045311 };
5312
[email protected]d9da5fe2010-10-13 22:37:165313 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:415314 CreateMockRead(conn_resp, 1, ASYNC),
rch32320842015-05-16 15:57:095315 MockRead(ASYNC, ERR_IO_PENDING, 3),
bncdf80d44fd2016-07-15 20:27:415316 CreateMockRead(wrapped_get_resp, 4, ASYNC),
5317 CreateMockRead(wrapped_body, 5, ASYNC),
rch8e6c6c42015-05-01 14:05:135318 MockRead(ASYNC, 0, 8),
[email protected]d9da5fe2010-10-13 22:37:165319 };
5320
rch32320842015-05-16 15:57:095321 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
5322 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:075323 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]d9da5fe2010-10-13 22:37:165324
[email protected]8ddf8322012-02-23 18:08:065325 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:365326 ssl.next_proto = kProtoHTTP2;
[email protected]bb88e1d32013-05-03 23:11:075327 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]8ddf8322012-02-23 18:08:065328 SSLSocketDataProvider ssl2(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:365329 ssl2.next_proto = kProtoHTTP2;
[email protected]bb88e1d32013-05-03 23:11:075330 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
[email protected]d9da5fe2010-10-13 22:37:165331
[email protected]49639fa2011-12-20 23:22:415332 TestCompletionCallback callback1;
[email protected]d9da5fe2010-10-13 22:37:165333
bnc691fda62016-08-12 00:43:165334 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:015335 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]d9da5fe2010-10-13 22:37:165336
rch32320842015-05-16 15:57:095337 // Allow the SpdyProxyClientSocket's write callback to complete.
fdoray92e35a72016-06-10 15:54:555338 base::RunLoop().RunUntilIdle();
rch32320842015-05-16 15:57:095339 // Now allow the read of the response to complete.
mmenkee24011922015-12-17 22:12:595340 spdy_data.Resume();
[email protected]d9da5fe2010-10-13 22:37:165341 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:015342 EXPECT_THAT(rv, IsOk());
[email protected]d9da5fe2010-10-13 22:37:165343
[email protected]58e32bb2013-01-21 18:23:255344 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:165345 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]58e32bb2013-01-21 18:23:255346 TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_SSL_TIMES);
5347
bnc691fda62016-08-12 00:43:165348 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:525349 ASSERT_TRUE(response);
5350 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:025351 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]d9da5fe2010-10-13 22:37:165352
5353 std::string response_data;
bnc691fda62016-08-12 00:43:165354 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
[email protected]448d4ca52012-03-04 04:12:235355 EXPECT_EQ(kUploadData, response_data);
[email protected]d9da5fe2010-10-13 22:37:165356}
5357
5358// Test a SPDY CONNECT failure through an HTTPS Proxy.
bncd16676a2016-07-20 16:23:015359TEST_F(HttpNetworkTransactionTest, HttpsProxySpdyConnectFailure) {
[email protected]cb9bf6ca2011-01-28 13:15:275360 HttpRequestInfo request;
5361 request.method = "GET";
bncce36dca22015-04-21 22:11:235362 request.url = GURL("https://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:275363
[email protected]d9da5fe2010-10-13 22:37:165364 // Configure against https proxy server "proxy:70".
rdsmith82957ad2015-09-16 19:42:035365 session_deps_.proxy_service = ProxyService::CreateFixed("https://proxy:70");
vishal.b62985ca92015-04-17 08:45:515366 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:075367 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:095368 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]d9da5fe2010-10-13 22:37:165369
bnc691fda62016-08-12 00:43:165370 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]d9da5fe2010-10-13 22:37:165371
bncce36dca22015-04-21 22:11:235372 // CONNECT to www.example.org:443 via SPDY
bncdf80d44fd2016-07-15 20:27:415373 SpdySerializedFrame connect(spdy_util_.ConstructSpdyConnect(
bncce36dca22015-04-21 22:11:235374 NULL, 0, 1, LOWEST, HostPortPair("www.example.org", 443)));
bncdf80d44fd2016-07-15 20:27:415375 SpdySerializedFrame get(
diannahu9904e272017-02-03 14:40:085376 spdy_util_.ConstructSpdyRstStream(1, ERROR_CODE_CANCEL));
[email protected]d9da5fe2010-10-13 22:37:165377
5378 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:415379 CreateMockWrite(connect, 0), CreateMockWrite(get, 2),
[email protected]d9da5fe2010-10-13 22:37:165380 };
5381
bnc42331402016-07-25 13:36:155382 SpdySerializedFrame resp(spdy_util_.ConstructSpdyReplyError(1));
bncdf80d44fd2016-07-15 20:27:415383 SpdySerializedFrame data(spdy_util_.ConstructSpdyDataFrame(1, true));
[email protected]d9da5fe2010-10-13 22:37:165384 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:415385 CreateMockRead(resp, 1, ASYNC), MockRead(ASYNC, 0, 3),
[email protected]d9da5fe2010-10-13 22:37:165386 };
5387
rch8e6c6c42015-05-01 14:05:135388 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
5389 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:075390 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]d9da5fe2010-10-13 22:37:165391
[email protected]8ddf8322012-02-23 18:08:065392 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:365393 ssl.next_proto = kProtoHTTP2;
[email protected]bb88e1d32013-05-03 23:11:075394 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]8ddf8322012-02-23 18:08:065395 SSLSocketDataProvider ssl2(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:365396 ssl2.next_proto = kProtoHTTP2;
[email protected]bb88e1d32013-05-03 23:11:075397 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
[email protected]d9da5fe2010-10-13 22:37:165398
[email protected]49639fa2011-12-20 23:22:415399 TestCompletionCallback callback1;
[email protected]d9da5fe2010-10-13 22:37:165400
bnc691fda62016-08-12 00:43:165401 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:015402 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]d9da5fe2010-10-13 22:37:165403
5404 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:015405 EXPECT_THAT(rv, IsError(ERR_TUNNEL_CONNECTION_FAILED));
[email protected]d9da5fe2010-10-13 22:37:165406
ttuttle960fcbf2016-04-19 13:26:325407 // TODO(juliatuttle): Anything else to check here?
[email protected]d9da5fe2010-10-13 22:37:165408}
5409
[email protected]f6c63db52013-02-02 00:35:225410// Test load timing in the case of two HTTPS (non-SPDY) requests through a SPDY
5411// HTTPS Proxy to different servers.
bncd16676a2016-07-20 16:23:015412TEST_F(HttpNetworkTransactionTest,
[email protected]f6c63db52013-02-02 00:35:225413 HttpsProxySpdyConnectHttpsLoadTimingTwoRequestsTwoServers) {
5414 // Configure against https proxy server "proxy:70".
rdsmith82957ad2015-09-16 19:42:035415 session_deps_.proxy_service = ProxyService::CreateFixed("https://proxy:70");
vishal.b62985ca92015-04-17 08:45:515416 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:075417 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:095418 std::unique_ptr<HttpNetworkSession> session(
mmenke11eb5152015-06-09 14:50:505419 SpdySessionDependencies::SpdyCreateSession(&session_deps_));
[email protected]f6c63db52013-02-02 00:35:225420
5421 HttpRequestInfo request1;
5422 request1.method = "GET";
bncce36dca22015-04-21 22:11:235423 request1.url = GURL("https://www.example.org/");
[email protected]f6c63db52013-02-02 00:35:225424 request1.load_flags = 0;
5425
5426 HttpRequestInfo request2;
5427 request2.method = "GET";
bncce36dca22015-04-21 22:11:235428 request2.url = GURL("https://mail.example.org/");
[email protected]f6c63db52013-02-02 00:35:225429 request2.load_flags = 0;
5430
bncce36dca22015-04-21 22:11:235431 // CONNECT to www.example.org:443 via SPDY.
bncdf80d44fd2016-07-15 20:27:415432 SpdySerializedFrame connect1(spdy_util_.ConstructSpdyConnect(
bncce36dca22015-04-21 22:11:235433 NULL, 0, 1, LOWEST, HostPortPair("www.example.org", 443)));
bnc42331402016-07-25 13:36:155434 SpdySerializedFrame conn_resp1(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
[email protected]f6c63db52013-02-02 00:35:225435
bncce36dca22015-04-21 22:11:235436 // Fetch https://www.example.org/ via HTTP.
5437 const char get1[] =
5438 "GET / HTTP/1.1\r\n"
5439 "Host: www.example.org\r\n"
[email protected]f6c63db52013-02-02 00:35:225440 "Connection: keep-alive\r\n\r\n";
bncdf80d44fd2016-07-15 20:27:415441 SpdySerializedFrame wrapped_get1(
5442 spdy_util_.ConstructSpdyDataFrame(1, get1, strlen(get1), false));
[email protected]f6c63db52013-02-02 00:35:225443 const char resp1[] = "HTTP/1.1 200 OK\r\n"
5444 "Content-Length: 1\r\n\r\n";
bncdf80d44fd2016-07-15 20:27:415445 SpdySerializedFrame wrapped_get_resp1(
5446 spdy_util_.ConstructSpdyDataFrame(1, resp1, strlen(resp1), false));
5447 SpdySerializedFrame wrapped_body1(
5448 spdy_util_.ConstructSpdyDataFrame(1, "1", 1, false));
5449 SpdySerializedFrame window_update(
5450 spdy_util_.ConstructSpdyWindowUpdate(1, wrapped_get_resp1.size()));
[email protected]f6c63db52013-02-02 00:35:225451
bncce36dca22015-04-21 22:11:235452 // CONNECT to mail.example.org:443 via SPDY.
[email protected]745aa9c2014-06-27 02:21:295453 SpdyHeaderBlock connect2_block;
Bence Békybda82952017-10-02 17:35:275454 connect2_block[kHttp2MethodHeader] = "CONNECT";
5455 connect2_block[kHttp2AuthorityHeader] = "mail.example.org:443";
bnc42331402016-07-25 13:36:155456 SpdySerializedFrame connect2(spdy_util_.ConstructSpdyHeaders(
5457 3, std::move(connect2_block), LOWEST, false));
[email protected]601e03f12014-04-06 16:26:395458
bnc42331402016-07-25 13:36:155459 SpdySerializedFrame conn_resp2(spdy_util_.ConstructSpdyGetReply(NULL, 0, 3));
[email protected]f6c63db52013-02-02 00:35:225460
bncce36dca22015-04-21 22:11:235461 // Fetch https://mail.example.org/ via HTTP.
5462 const char get2[] =
5463 "GET / HTTP/1.1\r\n"
5464 "Host: mail.example.org\r\n"
[email protected]f6c63db52013-02-02 00:35:225465 "Connection: keep-alive\r\n\r\n";
bncdf80d44fd2016-07-15 20:27:415466 SpdySerializedFrame wrapped_get2(
5467 spdy_util_.ConstructSpdyDataFrame(3, get2, strlen(get2), false));
[email protected]f6c63db52013-02-02 00:35:225468 const char resp2[] = "HTTP/1.1 200 OK\r\n"
5469 "Content-Length: 2\r\n\r\n";
bncdf80d44fd2016-07-15 20:27:415470 SpdySerializedFrame wrapped_get_resp2(
5471 spdy_util_.ConstructSpdyDataFrame(3, resp2, strlen(resp2), false));
5472 SpdySerializedFrame wrapped_body2(
5473 spdy_util_.ConstructSpdyDataFrame(3, "22", 2, false));
[email protected]f6c63db52013-02-02 00:35:225474
5475 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:415476 CreateMockWrite(connect1, 0), CreateMockWrite(wrapped_get1, 2),
5477 CreateMockWrite(connect2, 5), CreateMockWrite(wrapped_get2, 7),
[email protected]f6c63db52013-02-02 00:35:225478 };
5479
5480 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:415481 CreateMockRead(conn_resp1, 1, ASYNC),
5482 CreateMockRead(wrapped_get_resp1, 3, ASYNC),
5483 CreateMockRead(wrapped_body1, 4, ASYNC),
5484 CreateMockRead(conn_resp2, 6, ASYNC),
5485 CreateMockRead(wrapped_get_resp2, 8, ASYNC),
5486 CreateMockRead(wrapped_body2, 9, ASYNC),
5487 MockRead(ASYNC, 0, 10),
[email protected]f6c63db52013-02-02 00:35:225488 };
5489
mmenke11eb5152015-06-09 14:50:505490 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
5491 arraysize(spdy_writes));
5492 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]f6c63db52013-02-02 00:35:225493
5494 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:365495 ssl.next_proto = kProtoHTTP2;
mmenke11eb5152015-06-09 14:50:505496 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]f6c63db52013-02-02 00:35:225497 SSLSocketDataProvider ssl2(ASYNC, OK);
mmenke11eb5152015-06-09 14:50:505498 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
[email protected]f6c63db52013-02-02 00:35:225499 SSLSocketDataProvider ssl3(ASYNC, OK);
mmenke11eb5152015-06-09 14:50:505500 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl3);
[email protected]f6c63db52013-02-02 00:35:225501
5502 TestCompletionCallback callback;
5503
bnc691fda62016-08-12 00:43:165504 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:205505 int rv = trans.Start(&request1, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:015506 EXPECT_THAT(callback.GetResult(rv), IsOk());
[email protected]f6c63db52013-02-02 00:35:225507
5508 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:165509 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]f6c63db52013-02-02 00:35:225510 TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_SSL_TIMES);
5511
bnc691fda62016-08-12 00:43:165512 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:525513 ASSERT_TRUE(response);
5514 ASSERT_TRUE(response->headers);
[email protected]f6c63db52013-02-02 00:35:225515 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
5516
5517 std::string response_data;
ttuttle859dc7a2015-04-23 19:42:295518 scoped_refptr<IOBuffer> buf(new IOBuffer(256));
bnc691fda62016-08-12 00:43:165519 rv = trans.Read(buf.get(), 256, callback.callback());
mmenke11eb5152015-06-09 14:50:505520 EXPECT_EQ(1, callback.GetResult(rv));
[email protected]f6c63db52013-02-02 00:35:225521
bnc691fda62016-08-12 00:43:165522 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:205523 rv = trans2.Start(&request2, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:015524 EXPECT_THAT(callback.GetResult(rv), IsOk());
[email protected]f6c63db52013-02-02 00:35:225525
5526 LoadTimingInfo load_timing_info2;
bnc691fda62016-08-12 00:43:165527 EXPECT_TRUE(trans2.GetLoadTimingInfo(&load_timing_info2));
[email protected]f6c63db52013-02-02 00:35:225528 // Even though the SPDY connection is reused, a new tunnelled connection has
5529 // to be created, so the socket's load timing looks like a fresh connection.
5530 TestLoadTimingNotReused(load_timing_info2, CONNECT_TIMING_HAS_SSL_TIMES);
5531
5532 // The requests should have different IDs, since they each are using their own
5533 // separate stream.
5534 EXPECT_NE(load_timing_info.socket_log_id, load_timing_info2.socket_log_id);
5535
bnc691fda62016-08-12 00:43:165536 rv = trans2.Read(buf.get(), 256, callback.callback());
mmenke11eb5152015-06-09 14:50:505537 EXPECT_EQ(2, callback.GetResult(rv));
[email protected]f6c63db52013-02-02 00:35:225538}
5539
5540// Test load timing in the case of two HTTPS (non-SPDY) requests through a SPDY
5541// HTTPS Proxy to the same server.
bncd16676a2016-07-20 16:23:015542TEST_F(HttpNetworkTransactionTest,
[email protected]f6c63db52013-02-02 00:35:225543 HttpsProxySpdyConnectHttpsLoadTimingTwoRequestsSameServer) {
5544 // Configure against https proxy server "proxy:70".
rdsmith82957ad2015-09-16 19:42:035545 session_deps_.proxy_service = ProxyService::CreateFixed("https://proxy:70");
vishal.b62985ca92015-04-17 08:45:515546 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:075547 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:095548 std::unique_ptr<HttpNetworkSession> session(
mmenke11eb5152015-06-09 14:50:505549 SpdySessionDependencies::SpdyCreateSession(&session_deps_));
[email protected]f6c63db52013-02-02 00:35:225550
5551 HttpRequestInfo request1;
5552 request1.method = "GET";
bncce36dca22015-04-21 22:11:235553 request1.url = GURL("https://www.example.org/");
[email protected]f6c63db52013-02-02 00:35:225554 request1.load_flags = 0;
5555
5556 HttpRequestInfo request2;
5557 request2.method = "GET";
bncce36dca22015-04-21 22:11:235558 request2.url = GURL("https://www.example.org/2");
[email protected]f6c63db52013-02-02 00:35:225559 request2.load_flags = 0;
5560
bncce36dca22015-04-21 22:11:235561 // CONNECT to www.example.org:443 via SPDY.
bncdf80d44fd2016-07-15 20:27:415562 SpdySerializedFrame connect1(spdy_util_.ConstructSpdyConnect(
bncce36dca22015-04-21 22:11:235563 NULL, 0, 1, LOWEST, HostPortPair("www.example.org", 443)));
bnc42331402016-07-25 13:36:155564 SpdySerializedFrame conn_resp1(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
[email protected]f6c63db52013-02-02 00:35:225565
bncce36dca22015-04-21 22:11:235566 // Fetch https://www.example.org/ via HTTP.
5567 const char get1[] =
5568 "GET / HTTP/1.1\r\n"
5569 "Host: www.example.org\r\n"
[email protected]f6c63db52013-02-02 00:35:225570 "Connection: keep-alive\r\n\r\n";
bncdf80d44fd2016-07-15 20:27:415571 SpdySerializedFrame wrapped_get1(
5572 spdy_util_.ConstructSpdyDataFrame(1, get1, strlen(get1), false));
[email protected]f6c63db52013-02-02 00:35:225573 const char resp1[] = "HTTP/1.1 200 OK\r\n"
5574 "Content-Length: 1\r\n\r\n";
bncdf80d44fd2016-07-15 20:27:415575 SpdySerializedFrame wrapped_get_resp1(
5576 spdy_util_.ConstructSpdyDataFrame(1, resp1, strlen(resp1), false));
5577 SpdySerializedFrame wrapped_body1(
5578 spdy_util_.ConstructSpdyDataFrame(1, "1", 1, false));
5579 SpdySerializedFrame window_update(
5580 spdy_util_.ConstructSpdyWindowUpdate(1, wrapped_get_resp1.size()));
[email protected]f6c63db52013-02-02 00:35:225581
bncce36dca22015-04-21 22:11:235582 // Fetch https://www.example.org/2 via HTTP.
5583 const char get2[] =
5584 "GET /2 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_get2(
5588 spdy_util_.ConstructSpdyDataFrame(1, get2, strlen(get2), false));
[email protected]f6c63db52013-02-02 00:35:225589 const char resp2[] = "HTTP/1.1 200 OK\r\n"
5590 "Content-Length: 2\r\n\r\n";
bncdf80d44fd2016-07-15 20:27:415591 SpdySerializedFrame wrapped_get_resp2(
5592 spdy_util_.ConstructSpdyDataFrame(1, resp2, strlen(resp2), false));
5593 SpdySerializedFrame wrapped_body2(
5594 spdy_util_.ConstructSpdyDataFrame(1, "22", 2, false));
[email protected]f6c63db52013-02-02 00:35:225595
5596 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:415597 CreateMockWrite(connect1, 0), CreateMockWrite(wrapped_get1, 2),
5598 CreateMockWrite(wrapped_get2, 5),
[email protected]f6c63db52013-02-02 00:35:225599 };
5600
5601 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:415602 CreateMockRead(conn_resp1, 1, ASYNC),
5603 CreateMockRead(wrapped_get_resp1, 3, ASYNC),
bnceb9aa7112017-01-05 01:03:465604 CreateMockRead(wrapped_body1, 4, SYNCHRONOUS),
bncdf80d44fd2016-07-15 20:27:415605 CreateMockRead(wrapped_get_resp2, 6, ASYNC),
bnceb9aa7112017-01-05 01:03:465606 CreateMockRead(wrapped_body2, 7, SYNCHRONOUS),
bncdf80d44fd2016-07-15 20:27:415607 MockRead(ASYNC, 0, 8),
[email protected]f6c63db52013-02-02 00:35:225608 };
5609
mmenke11eb5152015-06-09 14:50:505610 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
5611 arraysize(spdy_writes));
5612 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]f6c63db52013-02-02 00:35:225613
5614 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:365615 ssl.next_proto = kProtoHTTP2;
mmenke11eb5152015-06-09 14:50:505616 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]f6c63db52013-02-02 00:35:225617 SSLSocketDataProvider ssl2(ASYNC, OK);
mmenke11eb5152015-06-09 14:50:505618 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
[email protected]f6c63db52013-02-02 00:35:225619
5620 TestCompletionCallback callback;
5621
bnc87dcefc2017-05-25 12:47:585622 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:195623 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:205624 int rv = trans->Start(&request1, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:015625 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]f6c63db52013-02-02 00:35:225626
5627 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:015628 EXPECT_THAT(rv, IsOk());
[email protected]f6c63db52013-02-02 00:35:225629
5630 LoadTimingInfo load_timing_info;
5631 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
5632 TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_SSL_TIMES);
5633
5634 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:525635 ASSERT_TRUE(response);
5636 ASSERT_TRUE(response->headers);
[email protected]f6c63db52013-02-02 00:35:225637 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
5638
5639 std::string response_data;
ttuttle859dc7a2015-04-23 19:42:295640 scoped_refptr<IOBuffer> buf(new IOBuffer(256));
[email protected]90499482013-06-01 00:39:505641 EXPECT_EQ(1, trans->Read(buf.get(), 256, callback.callback()));
[email protected]f6c63db52013-02-02 00:35:225642 trans.reset();
5643
bnc87dcefc2017-05-25 12:47:585644 auto trans2 =
Jeremy Roman0579ed62017-08-29 15:56:195645 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:205646 rv = trans2->Start(&request2, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:015647 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]f6c63db52013-02-02 00:35:225648
[email protected]f6c63db52013-02-02 00:35:225649 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:015650 EXPECT_THAT(rv, IsOk());
[email protected]f6c63db52013-02-02 00:35:225651
5652 LoadTimingInfo load_timing_info2;
5653 EXPECT_TRUE(trans2->GetLoadTimingInfo(&load_timing_info2));
5654 TestLoadTimingReused(load_timing_info2);
5655
5656 // The requests should have the same ID.
5657 EXPECT_EQ(load_timing_info.socket_log_id, load_timing_info2.socket_log_id);
5658
[email protected]90499482013-06-01 00:39:505659 EXPECT_EQ(2, trans2->Read(buf.get(), 256, callback.callback()));
[email protected]f6c63db52013-02-02 00:35:225660}
5661
5662// Test load timing in the case of of two HTTP requests through a SPDY HTTPS
5663// Proxy to different servers.
bncd16676a2016-07-20 16:23:015664TEST_F(HttpNetworkTransactionTest, HttpsProxySpdyLoadTimingTwoHttpRequests) {
[email protected]f6c63db52013-02-02 00:35:225665 // Configure against https proxy server "proxy:70".
rdsmith82957ad2015-09-16 19:42:035666 session_deps_.proxy_service = ProxyService::CreateFixed("https://proxy:70");
vishal.b62985ca92015-04-17 08:45:515667 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:075668 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:095669 std::unique_ptr<HttpNetworkSession> session(
mmenke11eb5152015-06-09 14:50:505670 SpdySessionDependencies::SpdyCreateSession(&session_deps_));
[email protected]f6c63db52013-02-02 00:35:225671
5672 HttpRequestInfo request1;
5673 request1.method = "GET";
bncce36dca22015-04-21 22:11:235674 request1.url = GURL("http://www.example.org/");
[email protected]f6c63db52013-02-02 00:35:225675 request1.load_flags = 0;
5676
5677 HttpRequestInfo request2;
5678 request2.method = "GET";
bncce36dca22015-04-21 22:11:235679 request2.url = GURL("http://mail.example.org/");
[email protected]f6c63db52013-02-02 00:35:225680 request2.load_flags = 0;
5681
bncce36dca22015-04-21 22:11:235682 // http://www.example.org/
bnc086b39e12016-06-24 13:05:265683 SpdyHeaderBlock headers(
bncce36dca22015-04-21 22:11:235684 spdy_util_.ConstructGetHeaderBlockForProxy("http://www.example.org/"));
bncdf80d44fd2016-07-15 20:27:415685 SpdySerializedFrame get1(
bnc42331402016-07-25 13:36:155686 spdy_util_.ConstructSpdyHeaders(1, std::move(headers), LOWEST, true));
5687 SpdySerializedFrame get_resp1(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
bncdf80d44fd2016-07-15 20:27:415688 SpdySerializedFrame body1(spdy_util_.ConstructSpdyDataFrame(1, "1", 1, true));
rdsmithebb50aa2015-11-12 03:44:385689 spdy_util_.UpdateWithStreamDestruction(1);
[email protected]f6c63db52013-02-02 00:35:225690
bncce36dca22015-04-21 22:11:235691 // http://mail.example.org/
bnc086b39e12016-06-24 13:05:265692 SpdyHeaderBlock headers2(
bncce36dca22015-04-21 22:11:235693 spdy_util_.ConstructGetHeaderBlockForProxy("http://mail.example.org/"));
bncdf80d44fd2016-07-15 20:27:415694 SpdySerializedFrame get2(
bnc42331402016-07-25 13:36:155695 spdy_util_.ConstructSpdyHeaders(3, std::move(headers2), LOWEST, true));
5696 SpdySerializedFrame get_resp2(spdy_util_.ConstructSpdyGetReply(NULL, 0, 3));
bncdf80d44fd2016-07-15 20:27:415697 SpdySerializedFrame body2(
5698 spdy_util_.ConstructSpdyDataFrame(3, "22", 2, true));
[email protected]f6c63db52013-02-02 00:35:225699
5700 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:415701 CreateMockWrite(get1, 0), CreateMockWrite(get2, 3),
[email protected]f6c63db52013-02-02 00:35:225702 };
5703
5704 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:415705 CreateMockRead(get_resp1, 1, ASYNC),
5706 CreateMockRead(body1, 2, ASYNC),
5707 CreateMockRead(get_resp2, 4, ASYNC),
5708 CreateMockRead(body2, 5, ASYNC),
5709 MockRead(ASYNC, 0, 6),
[email protected]f6c63db52013-02-02 00:35:225710 };
5711
mmenke11eb5152015-06-09 14:50:505712 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
5713 arraysize(spdy_writes));
5714 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]f6c63db52013-02-02 00:35:225715
5716 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:365717 ssl.next_proto = kProtoHTTP2;
mmenke11eb5152015-06-09 14:50:505718 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]f6c63db52013-02-02 00:35:225719
5720 TestCompletionCallback callback;
5721
bnc87dcefc2017-05-25 12:47:585722 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:195723 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:205724 int rv = trans->Start(&request1, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:015725 EXPECT_THAT(callback.GetResult(rv), IsOk());
[email protected]f6c63db52013-02-02 00:35:225726
5727 LoadTimingInfo load_timing_info;
5728 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
5729 TestLoadTimingNotReused(load_timing_info,
5730 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
5731
5732 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:525733 ASSERT_TRUE(response);
5734 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:025735 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]f6c63db52013-02-02 00:35:225736
5737 std::string response_data;
ttuttle859dc7a2015-04-23 19:42:295738 scoped_refptr<IOBuffer> buf(new IOBuffer(256));
mmenke11eb5152015-06-09 14:50:505739 rv = trans->Read(buf.get(), 256, callback.callback());
5740 EXPECT_EQ(1, callback.GetResult(rv));
[email protected]f6c63db52013-02-02 00:35:225741 // Delete the first request, so the second one can reuse the socket.
5742 trans.reset();
5743
bnc691fda62016-08-12 00:43:165744 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:205745 rv = trans2.Start(&request2, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:015746 EXPECT_THAT(callback.GetResult(rv), IsOk());
[email protected]f6c63db52013-02-02 00:35:225747
5748 LoadTimingInfo load_timing_info2;
bnc691fda62016-08-12 00:43:165749 EXPECT_TRUE(trans2.GetLoadTimingInfo(&load_timing_info2));
[email protected]f6c63db52013-02-02 00:35:225750 TestLoadTimingReused(load_timing_info2);
5751
5752 // The requests should have the same ID.
5753 EXPECT_EQ(load_timing_info.socket_log_id, load_timing_info2.socket_log_id);
5754
bnc691fda62016-08-12 00:43:165755 rv = trans2.Read(buf.get(), 256, callback.callback());
mmenke11eb5152015-06-09 14:50:505756 EXPECT_EQ(2, callback.GetResult(rv));
[email protected]f6c63db52013-02-02 00:35:225757}
5758
[email protected]2df19bb2010-08-25 20:13:465759// Test the challenge-response-retry sequence through an HTTPS Proxy
bncd16676a2016-07-20 16:23:015760TEST_F(HttpNetworkTransactionTest, HttpsProxyAuthRetry) {
[email protected]2df19bb2010-08-25 20:13:465761 HttpRequestInfo request;
5762 request.method = "GET";
bncce36dca22015-04-21 22:11:235763 request.url = GURL("http://www.example.org/");
[email protected]2df19bb2010-08-25 20:13:465764 // when the no authentication data flag is set.
ttuttle859dc7a2015-04-23 19:42:295765 request.load_flags = LOAD_DO_NOT_SEND_AUTH_DATA;
[email protected]2df19bb2010-08-25 20:13:465766
[email protected]79cb5c12011-09-12 13:12:045767 // Configure against https proxy server "myproxy:70".
rdsmith82957ad2015-09-16 19:42:035768 session_deps_.proxy_service = ProxyService::CreateFixed("https://myproxy:70");
vishal.b62985ca92015-04-17 08:45:515769 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:075770 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:095771 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:275772
[email protected]2df19bb2010-08-25 20:13:465773 // Since we have proxy, should use full url
5774 MockWrite data_writes1[] = {
bnc691fda62016-08-12 00:43:165775 MockWrite("GET http://www.example.org/ HTTP/1.1\r\n"
5776 "Host: www.example.org\r\n"
5777 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]2df19bb2010-08-25 20:13:465778
bnc691fda62016-08-12 00:43:165779 // After calling trans.RestartWithAuth(), this is the request we should
bncce36dca22015-04-21 22:11:235780 // be issuing -- the final header line contains the credentials.
bnc691fda62016-08-12 00:43:165781 MockWrite("GET http://www.example.org/ HTTP/1.1\r\n"
5782 "Host: www.example.org\r\n"
5783 "Proxy-Connection: keep-alive\r\n"
5784 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]2df19bb2010-08-25 20:13:465785 };
5786
5787 // The proxy responds to the GET with a 407, using a persistent
5788 // connection.
5789 MockRead data_reads1[] = {
5790 // No credentials.
5791 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
5792 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
5793 MockRead("Proxy-Connection: keep-alive\r\n"),
5794 MockRead("Content-Length: 0\r\n\r\n"),
5795
5796 MockRead("HTTP/1.1 200 OK\r\n"),
5797 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
5798 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:065799 MockRead(SYNCHRONOUS, OK),
[email protected]2df19bb2010-08-25 20:13:465800 };
5801
5802 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
5803 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:075804 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8ddf8322012-02-23 18:08:065805 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:075806 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]2df19bb2010-08-25 20:13:465807
[email protected]49639fa2011-12-20 23:22:415808 TestCompletionCallback callback1;
[email protected]2df19bb2010-08-25 20:13:465809
bnc691fda62016-08-12 00:43:165810 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]0b0bf032010-09-21 18:08:505811
bnc691fda62016-08-12 00:43:165812 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:015813 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2df19bb2010-08-25 20:13:465814
5815 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:015816 EXPECT_THAT(rv, IsOk());
[email protected]2df19bb2010-08-25 20:13:465817
[email protected]58e32bb2013-01-21 18:23:255818 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:165819 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]58e32bb2013-01-21 18:23:255820 TestLoadTimingNotReused(load_timing_info,
5821 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
5822
bnc691fda62016-08-12 00:43:165823 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:525824 ASSERT_TRUE(response);
5825 ASSERT_TRUE(response->headers);
[email protected]2df19bb2010-08-25 20:13:465826 EXPECT_EQ(407, response->headers->response_code());
5827 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
asanka098c0092016-06-16 20:18:435828 EXPECT_TRUE(CheckBasicSecureProxyAuth(response->auth_challenge.get()));
[email protected]2df19bb2010-08-25 20:13:465829
[email protected]49639fa2011-12-20 23:22:415830 TestCompletionCallback callback2;
[email protected]2df19bb2010-08-25 20:13:465831
bnc691fda62016-08-12 00:43:165832 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar), callback2.callback());
robpercival214763f2016-07-01 23:27:015833 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2df19bb2010-08-25 20:13:465834
5835 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:015836 EXPECT_THAT(rv, IsOk());
[email protected]2df19bb2010-08-25 20:13:465837
[email protected]58e32bb2013-01-21 18:23:255838 load_timing_info = LoadTimingInfo();
bnc691fda62016-08-12 00:43:165839 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]58e32bb2013-01-21 18:23:255840 // Retrying with HTTP AUTH is considered to be reusing a socket.
5841 TestLoadTimingReused(load_timing_info);
5842
bnc691fda62016-08-12 00:43:165843 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:525844 ASSERT_TRUE(response);
[email protected]2df19bb2010-08-25 20:13:465845
5846 EXPECT_TRUE(response->headers->IsKeepAlive());
5847 EXPECT_EQ(200, response->headers->response_code());
5848 EXPECT_EQ(100, response->headers->GetContentLength());
5849 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
5850
5851 // The password prompt info should not be set.
wezca1070932016-05-26 20:30:525852 EXPECT_FALSE(response->auth_challenge);
[email protected]2df19bb2010-08-25 20:13:465853}
5854
[email protected]23e482282013-06-14 16:08:025855void HttpNetworkTransactionTest::ConnectStatusHelperWithExpectedStatus(
[email protected]c744cf22009-02-27 07:28:085856 const MockRead& status, int expected_status) {
[email protected]1c773ea12009-04-28 19:58:425857 HttpRequestInfo request;
[email protected]c744cf22009-02-27 07:28:085858 request.method = "GET";
bncce36dca22015-04-21 22:11:235859 request.url = GURL("https://www.example.org/");
[email protected]c744cf22009-02-27 07:28:085860
[email protected]cb9bf6ca2011-01-28 13:15:275861 // Configure against proxy server "myproxy:70".
rdsmith82957ad2015-09-16 19:42:035862 session_deps_.proxy_service = ProxyService::CreateFixed("myproxy:70");
danakj1fd259a02016-04-16 03:17:095863 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:275864
[email protected]c744cf22009-02-27 07:28:085865 // Since we have proxy, should try to establish tunnel.
5866 MockWrite data_writes[] = {
rsleevidb16bb02015-11-12 23:47:175867 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
5868 "Host: www.example.org:443\r\n"
5869 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]c744cf22009-02-27 07:28:085870 };
5871
5872 MockRead data_reads[] = {
mmenked39192ee2015-12-09 00:57:235873 status, MockRead("Content-Length: 10\r\n\r\n"),
5874 // No response body because the test stops reading here.
5875 MockRead(SYNCHRONOUS, ERR_UNEXPECTED),
[email protected]c744cf22009-02-27 07:28:085876 };
5877
[email protected]31a2bfe2010-02-09 08:03:395878 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
5879 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:075880 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]c744cf22009-02-27 07:28:085881
[email protected]49639fa2011-12-20 23:22:415882 TestCompletionCallback callback;
[email protected]c744cf22009-02-27 07:28:085883
bnc691fda62016-08-12 00:43:165884 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]0b0bf032010-09-21 18:08:505885
tfarina42834112016-09-22 13:38:205886 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:015887 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]c744cf22009-02-27 07:28:085888
5889 rv = callback.WaitForResult();
5890 EXPECT_EQ(expected_status, rv);
5891}
5892
[email protected]23e482282013-06-14 16:08:025893void HttpNetworkTransactionTest::ConnectStatusHelper(
[email protected]448d4ca52012-03-04 04:12:235894 const MockRead& status) {
[email protected]c744cf22009-02-27 07:28:085895 ConnectStatusHelperWithExpectedStatus(
[email protected]1c773ea12009-04-28 19:58:425896 status, ERR_TUNNEL_CONNECTION_FAILED);
[email protected]c744cf22009-02-27 07:28:085897}
5898
bncd16676a2016-07-20 16:23:015899TEST_F(HttpNetworkTransactionTest, ConnectStatus100) {
[email protected]c744cf22009-02-27 07:28:085900 ConnectStatusHelper(MockRead("HTTP/1.1 100 Continue\r\n"));
5901}
5902
bncd16676a2016-07-20 16:23:015903TEST_F(HttpNetworkTransactionTest, ConnectStatus101) {
[email protected]c744cf22009-02-27 07:28:085904 ConnectStatusHelper(MockRead("HTTP/1.1 101 Switching Protocols\r\n"));
5905}
5906
bncd16676a2016-07-20 16:23:015907TEST_F(HttpNetworkTransactionTest, ConnectStatus201) {
[email protected]c744cf22009-02-27 07:28:085908 ConnectStatusHelper(MockRead("HTTP/1.1 201 Created\r\n"));
5909}
5910
bncd16676a2016-07-20 16:23:015911TEST_F(HttpNetworkTransactionTest, ConnectStatus202) {
[email protected]c744cf22009-02-27 07:28:085912 ConnectStatusHelper(MockRead("HTTP/1.1 202 Accepted\r\n"));
5913}
5914
bncd16676a2016-07-20 16:23:015915TEST_F(HttpNetworkTransactionTest, ConnectStatus203) {
[email protected]c744cf22009-02-27 07:28:085916 ConnectStatusHelper(
5917 MockRead("HTTP/1.1 203 Non-Authoritative Information\r\n"));
5918}
5919
bncd16676a2016-07-20 16:23:015920TEST_F(HttpNetworkTransactionTest, ConnectStatus204) {
[email protected]c744cf22009-02-27 07:28:085921 ConnectStatusHelper(MockRead("HTTP/1.1 204 No Content\r\n"));
5922}
5923
bncd16676a2016-07-20 16:23:015924TEST_F(HttpNetworkTransactionTest, ConnectStatus205) {
[email protected]c744cf22009-02-27 07:28:085925 ConnectStatusHelper(MockRead("HTTP/1.1 205 Reset Content\r\n"));
5926}
5927
bncd16676a2016-07-20 16:23:015928TEST_F(HttpNetworkTransactionTest, ConnectStatus206) {
[email protected]c744cf22009-02-27 07:28:085929 ConnectStatusHelper(MockRead("HTTP/1.1 206 Partial Content\r\n"));
5930}
5931
bncd16676a2016-07-20 16:23:015932TEST_F(HttpNetworkTransactionTest, ConnectStatus300) {
[email protected]c744cf22009-02-27 07:28:085933 ConnectStatusHelper(MockRead("HTTP/1.1 300 Multiple Choices\r\n"));
5934}
5935
bncd16676a2016-07-20 16:23:015936TEST_F(HttpNetworkTransactionTest, ConnectStatus301) {
[email protected]c744cf22009-02-27 07:28:085937 ConnectStatusHelper(MockRead("HTTP/1.1 301 Moved Permanently\r\n"));
5938}
5939
bncd16676a2016-07-20 16:23:015940TEST_F(HttpNetworkTransactionTest, ConnectStatus302) {
[email protected]c744cf22009-02-27 07:28:085941 ConnectStatusHelper(MockRead("HTTP/1.1 302 Found\r\n"));
5942}
5943
bncd16676a2016-07-20 16:23:015944TEST_F(HttpNetworkTransactionTest, ConnectStatus303) {
[email protected]c744cf22009-02-27 07:28:085945 ConnectStatusHelper(MockRead("HTTP/1.1 303 See Other\r\n"));
5946}
5947
bncd16676a2016-07-20 16:23:015948TEST_F(HttpNetworkTransactionTest, ConnectStatus304) {
[email protected]c744cf22009-02-27 07:28:085949 ConnectStatusHelper(MockRead("HTTP/1.1 304 Not Modified\r\n"));
5950}
5951
bncd16676a2016-07-20 16:23:015952TEST_F(HttpNetworkTransactionTest, ConnectStatus305) {
[email protected]c744cf22009-02-27 07:28:085953 ConnectStatusHelper(MockRead("HTTP/1.1 305 Use Proxy\r\n"));
5954}
5955
bncd16676a2016-07-20 16:23:015956TEST_F(HttpNetworkTransactionTest, ConnectStatus306) {
[email protected]c744cf22009-02-27 07:28:085957 ConnectStatusHelper(MockRead("HTTP/1.1 306\r\n"));
5958}
5959
bncd16676a2016-07-20 16:23:015960TEST_F(HttpNetworkTransactionTest, ConnectStatus307) {
[email protected]c744cf22009-02-27 07:28:085961 ConnectStatusHelper(MockRead("HTTP/1.1 307 Temporary Redirect\r\n"));
5962}
5963
bncd16676a2016-07-20 16:23:015964TEST_F(HttpNetworkTransactionTest, ConnectStatus308) {
[email protected]0a17aab32014-04-24 03:32:375965 ConnectStatusHelper(MockRead("HTTP/1.1 308 Permanent Redirect\r\n"));
5966}
5967
bncd16676a2016-07-20 16:23:015968TEST_F(HttpNetworkTransactionTest, ConnectStatus400) {
[email protected]c744cf22009-02-27 07:28:085969 ConnectStatusHelper(MockRead("HTTP/1.1 400 Bad Request\r\n"));
5970}
5971
bncd16676a2016-07-20 16:23:015972TEST_F(HttpNetworkTransactionTest, ConnectStatus401) {
[email protected]c744cf22009-02-27 07:28:085973 ConnectStatusHelper(MockRead("HTTP/1.1 401 Unauthorized\r\n"));
5974}
5975
bncd16676a2016-07-20 16:23:015976TEST_F(HttpNetworkTransactionTest, ConnectStatus402) {
[email protected]c744cf22009-02-27 07:28:085977 ConnectStatusHelper(MockRead("HTTP/1.1 402 Payment Required\r\n"));
5978}
5979
bncd16676a2016-07-20 16:23:015980TEST_F(HttpNetworkTransactionTest, ConnectStatus403) {
[email protected]c744cf22009-02-27 07:28:085981 ConnectStatusHelper(MockRead("HTTP/1.1 403 Forbidden\r\n"));
5982}
5983
bncd16676a2016-07-20 16:23:015984TEST_F(HttpNetworkTransactionTest, ConnectStatus404) {
[email protected]c744cf22009-02-27 07:28:085985 ConnectStatusHelper(MockRead("HTTP/1.1 404 Not Found\r\n"));
5986}
5987
bncd16676a2016-07-20 16:23:015988TEST_F(HttpNetworkTransactionTest, ConnectStatus405) {
[email protected]c744cf22009-02-27 07:28:085989 ConnectStatusHelper(MockRead("HTTP/1.1 405 Method Not Allowed\r\n"));
5990}
5991
bncd16676a2016-07-20 16:23:015992TEST_F(HttpNetworkTransactionTest, ConnectStatus406) {
[email protected]c744cf22009-02-27 07:28:085993 ConnectStatusHelper(MockRead("HTTP/1.1 406 Not Acceptable\r\n"));
5994}
5995
bncd16676a2016-07-20 16:23:015996TEST_F(HttpNetworkTransactionTest, ConnectStatus407) {
[email protected]c744cf22009-02-27 07:28:085997 ConnectStatusHelperWithExpectedStatus(
5998 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
[email protected]a7ea8832010-07-12 17:54:545999 ERR_PROXY_AUTH_UNSUPPORTED);
[email protected]c744cf22009-02-27 07:28:086000}
6001
bncd16676a2016-07-20 16:23:016002TEST_F(HttpNetworkTransactionTest, ConnectStatus408) {
[email protected]c744cf22009-02-27 07:28:086003 ConnectStatusHelper(MockRead("HTTP/1.1 408 Request Timeout\r\n"));
6004}
6005
bncd16676a2016-07-20 16:23:016006TEST_F(HttpNetworkTransactionTest, ConnectStatus409) {
[email protected]c744cf22009-02-27 07:28:086007 ConnectStatusHelper(MockRead("HTTP/1.1 409 Conflict\r\n"));
6008}
6009
bncd16676a2016-07-20 16:23:016010TEST_F(HttpNetworkTransactionTest, ConnectStatus410) {
[email protected]c744cf22009-02-27 07:28:086011 ConnectStatusHelper(MockRead("HTTP/1.1 410 Gone\r\n"));
6012}
6013
bncd16676a2016-07-20 16:23:016014TEST_F(HttpNetworkTransactionTest, ConnectStatus411) {
[email protected]c744cf22009-02-27 07:28:086015 ConnectStatusHelper(MockRead("HTTP/1.1 411 Length Required\r\n"));
6016}
6017
bncd16676a2016-07-20 16:23:016018TEST_F(HttpNetworkTransactionTest, ConnectStatus412) {
[email protected]c744cf22009-02-27 07:28:086019 ConnectStatusHelper(MockRead("HTTP/1.1 412 Precondition Failed\r\n"));
6020}
6021
bncd16676a2016-07-20 16:23:016022TEST_F(HttpNetworkTransactionTest, ConnectStatus413) {
[email protected]c744cf22009-02-27 07:28:086023 ConnectStatusHelper(MockRead("HTTP/1.1 413 Request Entity Too Large\r\n"));
6024}
6025
bncd16676a2016-07-20 16:23:016026TEST_F(HttpNetworkTransactionTest, ConnectStatus414) {
[email protected]c744cf22009-02-27 07:28:086027 ConnectStatusHelper(MockRead("HTTP/1.1 414 Request-URI Too Long\r\n"));
6028}
6029
bncd16676a2016-07-20 16:23:016030TEST_F(HttpNetworkTransactionTest, ConnectStatus415) {
[email protected]c744cf22009-02-27 07:28:086031 ConnectStatusHelper(MockRead("HTTP/1.1 415 Unsupported Media Type\r\n"));
6032}
6033
bncd16676a2016-07-20 16:23:016034TEST_F(HttpNetworkTransactionTest, ConnectStatus416) {
[email protected]c744cf22009-02-27 07:28:086035 ConnectStatusHelper(
6036 MockRead("HTTP/1.1 416 Requested Range Not Satisfiable\r\n"));
6037}
6038
bncd16676a2016-07-20 16:23:016039TEST_F(HttpNetworkTransactionTest, ConnectStatus417) {
[email protected]c744cf22009-02-27 07:28:086040 ConnectStatusHelper(MockRead("HTTP/1.1 417 Expectation Failed\r\n"));
6041}
6042
bncd16676a2016-07-20 16:23:016043TEST_F(HttpNetworkTransactionTest, ConnectStatus500) {
[email protected]c744cf22009-02-27 07:28:086044 ConnectStatusHelper(MockRead("HTTP/1.1 500 Internal Server Error\r\n"));
6045}
6046
bncd16676a2016-07-20 16:23:016047TEST_F(HttpNetworkTransactionTest, ConnectStatus501) {
[email protected]c744cf22009-02-27 07:28:086048 ConnectStatusHelper(MockRead("HTTP/1.1 501 Not Implemented\r\n"));
6049}
6050
bncd16676a2016-07-20 16:23:016051TEST_F(HttpNetworkTransactionTest, ConnectStatus502) {
[email protected]c744cf22009-02-27 07:28:086052 ConnectStatusHelper(MockRead("HTTP/1.1 502 Bad Gateway\r\n"));
6053}
6054
bncd16676a2016-07-20 16:23:016055TEST_F(HttpNetworkTransactionTest, ConnectStatus503) {
[email protected]c744cf22009-02-27 07:28:086056 ConnectStatusHelper(MockRead("HTTP/1.1 503 Service Unavailable\r\n"));
6057}
6058
bncd16676a2016-07-20 16:23:016059TEST_F(HttpNetworkTransactionTest, ConnectStatus504) {
[email protected]c744cf22009-02-27 07:28:086060 ConnectStatusHelper(MockRead("HTTP/1.1 504 Gateway Timeout\r\n"));
6061}
6062
bncd16676a2016-07-20 16:23:016063TEST_F(HttpNetworkTransactionTest, ConnectStatus505) {
[email protected]c744cf22009-02-27 07:28:086064 ConnectStatusHelper(MockRead("HTTP/1.1 505 HTTP Version Not Supported\r\n"));
6065}
6066
[email protected]038e9a32008-10-08 22:40:166067// Test the flow when both the proxy server AND origin server require
6068// authentication. Again, this uses basic auth for both since that is
6069// the simplest to mock.
bncd16676a2016-07-20 16:23:016070TEST_F(HttpNetworkTransactionTest, BasicAuthProxyThenServer) {
[email protected]cb9bf6ca2011-01-28 13:15:276071 HttpRequestInfo request;
6072 request.method = "GET";
bncce36dca22015-04-21 22:11:236073 request.url = GURL("http://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:276074
[email protected]038e9a32008-10-08 22:40:166075 // Configure against proxy server "myproxy:70".
rdsmith82957ad2015-09-16 19:42:036076 session_deps_.proxy_service = ProxyService::CreateFixed("myproxy:70");
danakj1fd259a02016-04-16 03:17:096077 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]3fe8d2f82013-10-17 08:56:076078
bnc691fda62016-08-12 00:43:166079 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]038e9a32008-10-08 22:40:166080
[email protected]f9ee6b52008-11-08 06:46:236081 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:236082 MockWrite(
6083 "GET http://www.example.org/ HTTP/1.1\r\n"
6084 "Host: www.example.org\r\n"
6085 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:236086 };
6087
[email protected]038e9a32008-10-08 22:40:166088 MockRead data_reads1[] = {
6089 MockRead("HTTP/1.0 407 Unauthorized\r\n"),
6090 // Give a couple authenticate options (only the middle one is actually
6091 // supported).
[email protected]22927ad2009-09-21 19:56:196092 MockRead("Proxy-Authenticate: Basic invalid\r\n"), // Malformed.
[email protected]038e9a32008-10-08 22:40:166093 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
6094 MockRead("Proxy-Authenticate: UNSUPPORTED realm=\"FOO\"\r\n"),
6095 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
6096 // Large content-length -- won't matter, as connection will be reset.
6097 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:066098 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]038e9a32008-10-08 22:40:166099 };
6100
bnc691fda62016-08-12 00:43:166101 // After calling trans.RestartWithAuth() the first time, this is the
[email protected]038e9a32008-10-08 22:40:166102 // request we should be issuing -- the final header line contains the
6103 // proxy's credentials.
6104 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:236105 MockWrite(
6106 "GET http://www.example.org/ HTTP/1.1\r\n"
6107 "Host: www.example.org\r\n"
6108 "Proxy-Connection: keep-alive\r\n"
6109 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]038e9a32008-10-08 22:40:166110 };
6111
6112 // Now the proxy server lets the request pass through to origin server.
6113 // The origin server responds with a 401.
6114 MockRead data_reads2[] = {
6115 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
6116 // Note: We are using the same realm-name as the proxy server. This is
6117 // completely valid, as realms are unique across hosts.
6118 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
6119 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
6120 MockRead("Content-Length: 2000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:066121 MockRead(SYNCHRONOUS, ERR_FAILED), // Won't be reached.
[email protected]038e9a32008-10-08 22:40:166122 };
6123
bnc691fda62016-08-12 00:43:166124 // After calling trans.RestartWithAuth() the second time, we should send
[email protected]038e9a32008-10-08 22:40:166125 // the credentials for both the proxy and origin server.
6126 MockWrite data_writes3[] = {
bncce36dca22015-04-21 22:11:236127 MockWrite(
6128 "GET http://www.example.org/ HTTP/1.1\r\n"
6129 "Host: www.example.org\r\n"
6130 "Proxy-Connection: keep-alive\r\n"
6131 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n"
6132 "Authorization: Basic Zm9vMjpiYXIy\r\n\r\n"),
[email protected]038e9a32008-10-08 22:40:166133 };
6134
6135 // Lastly we get the desired content.
6136 MockRead data_reads3[] = {
6137 MockRead("HTTP/1.0 200 OK\r\n"),
6138 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
6139 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:066140 MockRead(SYNCHRONOUS, OK),
[email protected]038e9a32008-10-08 22:40:166141 };
6142
[email protected]31a2bfe2010-02-09 08:03:396143 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
6144 data_writes1, arraysize(data_writes1));
6145 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
6146 data_writes2, arraysize(data_writes2));
6147 StaticSocketDataProvider data3(data_reads3, arraysize(data_reads3),
6148 data_writes3, arraysize(data_writes3));
[email protected]bb88e1d32013-05-03 23:11:076149 session_deps_.socket_factory->AddSocketDataProvider(&data1);
6150 session_deps_.socket_factory->AddSocketDataProvider(&data2);
6151 session_deps_.socket_factory->AddSocketDataProvider(&data3);
[email protected]038e9a32008-10-08 22:40:166152
[email protected]49639fa2011-12-20 23:22:416153 TestCompletionCallback callback1;
[email protected]038e9a32008-10-08 22:40:166154
tfarina42834112016-09-22 13:38:206155 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:016156 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]038e9a32008-10-08 22:40:166157
6158 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:016159 EXPECT_THAT(rv, IsOk());
[email protected]038e9a32008-10-08 22:40:166160
bnc691fda62016-08-12 00:43:166161 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:526162 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:046163 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
[email protected]038e9a32008-10-08 22:40:166164
[email protected]49639fa2011-12-20 23:22:416165 TestCompletionCallback callback2;
[email protected]038e9a32008-10-08 22:40:166166
bnc691fda62016-08-12 00:43:166167 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar), callback2.callback());
robpercival214763f2016-07-01 23:27:016168 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]038e9a32008-10-08 22:40:166169
6170 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:016171 EXPECT_THAT(rv, IsOk());
[email protected]038e9a32008-10-08 22:40:166172
bnc691fda62016-08-12 00:43:166173 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:526174 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:046175 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]038e9a32008-10-08 22:40:166176
[email protected]49639fa2011-12-20 23:22:416177 TestCompletionCallback callback3;
[email protected]038e9a32008-10-08 22:40:166178
bnc691fda62016-08-12 00:43:166179 rv = trans.RestartWithAuth(AuthCredentials(kFoo2, kBar2),
6180 callback3.callback());
robpercival214763f2016-07-01 23:27:016181 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]038e9a32008-10-08 22:40:166182
6183 rv = callback3.WaitForResult();
robpercival214763f2016-07-01 23:27:016184 EXPECT_THAT(rv, IsOk());
[email protected]038e9a32008-10-08 22:40:166185
bnc691fda62016-08-12 00:43:166186 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:526187 EXPECT_FALSE(response->auth_challenge);
[email protected]038e9a32008-10-08 22:40:166188 EXPECT_EQ(100, response->headers->GetContentLength());
[email protected]038e9a32008-10-08 22:40:166189}
[email protected]4ddaf2502008-10-23 18:26:196190
[email protected]ea9dc9a2009-09-05 00:43:326191// For the NTLM implementation using SSPI, we skip the NTLM tests since we
6192// can't hook into its internals to cause it to generate predictable NTLM
6193// authorization headers.
6194#if defined(NTLM_PORTABLE)
Zentaro Kavanagh5b27a6e22017-09-25 23:00:376195// The NTLM authentication unit tests are based on known test data from the
6196// [MS-NLMP] Specification [1]. These tests are primarily of the authentication
6197// flow rather than the implementation of the NTLM protocol. See net/ntlm
6198// for the implementation and testing of the protocol.
6199//
6200// [1] https://msdn.microsoft.com/en-us/library/cc236621.aspx
[email protected]385a4672009-03-11 22:21:296201
6202// Enter the correct password and authenticate successfully.
Zentaro Kavanagh5b27a6e22017-09-25 23:00:376203TEST_F(HttpNetworkTransactionTest, NTLMAuthV1) {
[email protected]1c773ea12009-04-28 19:58:426204 HttpRequestInfo request;
[email protected]3f918782009-02-28 01:29:246205 request.method = "GET";
Bence Béky83eb3512017-09-05 12:56:096206 request.url = GURL("https://172.22.68.17/kids/login.aspx");
[email protected]2217aa22013-10-11 03:03:546207
6208 // Ensure load is not disrupted by flags which suppress behaviour specific
6209 // to other auth schemes.
6210 request.load_flags = LOAD_DO_NOT_USE_EMBEDDED_IDENTITY;
[email protected]3f918782009-02-28 01:29:246211
Zentaro Kavanagh6ccee512017-09-28 18:34:096212 HttpAuthHandlerNTLM::ScopedProcSetter proc_setter(
6213 MockGetMSTime, MockGenerateRandom, MockGetHostName);
danakj1fd259a02016-04-16 03:17:096214 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:276215
Zentaro Kavanagh5b27a6e22017-09-25 23:00:376216 // Generate the NTLM messages based on known test data.
6217 std::string negotiate_msg;
6218 std::string challenge_msg;
6219 std::string authenticate_msg;
6220 base::Base64Encode(
6221 base::StringPiece(
6222 reinterpret_cast<const char*>(ntlm::test::kExpectedNegotiateMsg),
6223 arraysize(ntlm::test::kExpectedNegotiateMsg)),
6224 &negotiate_msg);
6225 base::Base64Encode(base::StringPiece(reinterpret_cast<const char*>(
6226 ntlm::test::kChallengeMsgV1),
6227 arraysize(ntlm::test::kChallengeMsgV1)),
6228 &challenge_msg);
6229 base::Base64Encode(
6230 base::StringPiece(
Zentaro Kavanagh6ccee512017-09-28 18:34:096231 reinterpret_cast<const char*>(
6232 ntlm::test::kExpectedAuthenticateMsgSpecResponseV1),
6233 arraysize(ntlm::test::kExpectedAuthenticateMsgSpecResponseV1)),
Zentaro Kavanagh5b27a6e22017-09-25 23:00:376234 &authenticate_msg);
6235
[email protected]3f918782009-02-28 01:29:246236 MockWrite data_writes1[] = {
6237 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
6238 "Host: 172.22.68.17\r\n"
6239 "Connection: keep-alive\r\n\r\n"),
6240 };
6241
6242 MockRead data_reads1[] = {
6243 MockRead("HTTP/1.1 401 Access Denied\r\n"),
[email protected]aef04272010-06-28 18:03:046244 // Negotiate and NTLM are often requested together. However, we only want
6245 // to test NTLM. Since Negotiate is preferred over NTLM, we have to skip
6246 // the header that requests Negotiate for this test.
[email protected]3f918782009-02-28 01:29:246247 MockRead("WWW-Authenticate: NTLM\r\n"),
6248 MockRead("Connection: close\r\n"),
6249 MockRead("Content-Length: 42\r\n"),
[email protected]076c85082009-04-10 23:21:366250 MockRead("Content-Type: text/html\r\n\r\n"),
[email protected]3f918782009-02-28 01:29:246251 // Missing content -- won't matter, as connection will be reset.
[email protected]3f918782009-02-28 01:29:246252 };
6253
6254 MockWrite data_writes2[] = {
bnc691fda62016-08-12 00:43:166255 // After restarting with a null identity, this is the
6256 // request we should be issuing -- the final header line contains a Type
6257 // 1 message.
6258 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
6259 "Host: 172.22.68.17\r\n"
6260 "Connection: keep-alive\r\n"
Zentaro Kavanagh5b27a6e22017-09-25 23:00:376261 "Authorization: NTLM "),
6262 MockWrite(negotiate_msg.c_str()), MockWrite("\r\n\r\n"),
[email protected]3f918782009-02-28 01:29:246263
bnc691fda62016-08-12 00:43:166264 // After calling trans.RestartWithAuth(), we should send a Type 3 message
Zentaro Kavanagh5b27a6e22017-09-25 23:00:376265 // (using correct credentials). The second request continues on the
6266 // same connection.
bnc691fda62016-08-12 00:43:166267 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
6268 "Host: 172.22.68.17\r\n"
6269 "Connection: keep-alive\r\n"
Zentaro Kavanagh5b27a6e22017-09-25 23:00:376270 "Authorization: NTLM "),
6271 MockWrite(authenticate_msg.c_str()), MockWrite("\r\n\r\n"),
[email protected]3f918782009-02-28 01:29:246272 };
6273
6274 MockRead data_reads2[] = {
Bence Béky1e4ef192017-09-18 19:58:026275 // The origin server responds with a Type 2 message.
6276 MockRead("HTTP/1.1 401 Access Denied\r\n"),
Zentaro Kavanagh5b27a6e22017-09-25 23:00:376277 MockRead("WWW-Authenticate: NTLM "), MockRead(challenge_msg.c_str()),
6278 MockRead("\r\n"), MockRead("Content-Length: 42\r\n"),
Bence Béky1e4ef192017-09-18 19:58:026279 MockRead("Content-Type: text/html\r\n\r\n"),
6280 MockRead("You are not authorized to view this page\r\n"),
[email protected]3f918782009-02-28 01:29:246281
Bence Béky1e4ef192017-09-18 19:58:026282 // Lastly we get the desired content.
6283 MockRead("HTTP/1.1 200 OK\r\n"),
6284 MockRead("Content-Type: text/html; charset=utf-8\r\n"),
6285 MockRead("Content-Length: 14\r\n\r\n"), MockRead("Please Login\r\n"),
[email protected]3f918782009-02-28 01:29:246286 };
6287
[email protected]31a2bfe2010-02-09 08:03:396288 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
6289 data_writes1, arraysize(data_writes1));
6290 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
6291 data_writes2, arraysize(data_writes2));
[email protected]bb88e1d32013-05-03 23:11:076292 session_deps_.socket_factory->AddSocketDataProvider(&data1);
6293 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]3f918782009-02-28 01:29:246294
Bence Béky83eb3512017-09-05 12:56:096295 SSLSocketDataProvider ssl1(ASYNC, OK);
6296 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl1);
6297 SSLSocketDataProvider ssl2(ASYNC, OK);
6298 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
6299
[email protected]49639fa2011-12-20 23:22:416300 TestCompletionCallback callback1;
[email protected]3f918782009-02-28 01:29:246301
bnc691fda62016-08-12 00:43:166302 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]0b0bf032010-09-21 18:08:506303
tfarina42834112016-09-22 13:38:206304 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:016305 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]3f918782009-02-28 01:29:246306
6307 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:016308 EXPECT_THAT(rv, IsOk());
[email protected]3f918782009-02-28 01:29:246309
bnc691fda62016-08-12 00:43:166310 EXPECT_FALSE(trans.IsReadyToRestartForAuth());
[email protected]0757e7702009-03-27 04:00:226311
bnc691fda62016-08-12 00:43:166312 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:526313 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:046314 EXPECT_TRUE(CheckNTLMServerAuth(response->auth_challenge.get()));
[email protected]3f918782009-02-28 01:29:246315
[email protected]49639fa2011-12-20 23:22:416316 TestCompletionCallback callback2;
[email protected]10af5fe72011-01-31 16:17:256317
Zentaro Kavanagh5b27a6e22017-09-25 23:00:376318 rv = trans.RestartWithAuth(
6319 AuthCredentials(ntlm::test::kDomainUserCombined, ntlm::test::kPassword),
6320 callback2.callback());
robpercival214763f2016-07-01 23:27:016321 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]10af5fe72011-01-31 16:17:256322
6323 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:016324 EXPECT_THAT(rv, IsOk());
[email protected]10af5fe72011-01-31 16:17:256325
bnc691fda62016-08-12 00:43:166326 EXPECT_TRUE(trans.IsReadyToRestartForAuth());
[email protected]10af5fe72011-01-31 16:17:256327
bnc691fda62016-08-12 00:43:166328 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:526329 ASSERT_TRUE(response);
6330 EXPECT_FALSE(response->auth_challenge);
[email protected]10af5fe72011-01-31 16:17:256331
[email protected]49639fa2011-12-20 23:22:416332 TestCompletionCallback callback3;
[email protected]3f918782009-02-28 01:29:246333
bnc691fda62016-08-12 00:43:166334 rv = trans.RestartWithAuth(AuthCredentials(), callback3.callback());
robpercival214763f2016-07-01 23:27:016335 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]3f918782009-02-28 01:29:246336
[email protected]0757e7702009-03-27 04:00:226337 rv = callback3.WaitForResult();
robpercival214763f2016-07-01 23:27:016338 EXPECT_THAT(rv, IsOk());
[email protected]3f918782009-02-28 01:29:246339
bnc691fda62016-08-12 00:43:166340 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:526341 ASSERT_TRUE(response);
6342 EXPECT_FALSE(response->auth_challenge);
Bence Béky1e4ef192017-09-18 19:58:026343 EXPECT_EQ(14, response->headers->GetContentLength());
6344
6345 std::string response_data;
6346 rv = ReadTransaction(&trans, &response_data);
6347 EXPECT_THAT(rv, IsOk());
6348 EXPECT_EQ("Please Login\r\n", response_data);
6349
6350 EXPECT_TRUE(data1.AllReadDataConsumed());
6351 EXPECT_TRUE(data1.AllWriteDataConsumed());
6352 EXPECT_TRUE(data2.AllReadDataConsumed());
6353 EXPECT_TRUE(data2.AllWriteDataConsumed());
[email protected]3f918782009-02-28 01:29:246354}
6355
[email protected]385a4672009-03-11 22:21:296356// Enter a wrong password, and then the correct one.
Zentaro Kavanagh5b27a6e22017-09-25 23:00:376357TEST_F(HttpNetworkTransactionTest, NTLMAuthV1WrongThenRightPassword) {
[email protected]1c773ea12009-04-28 19:58:426358 HttpRequestInfo request;
[email protected]385a4672009-03-11 22:21:296359 request.method = "GET";
Bence Béky83eb3512017-09-05 12:56:096360 request.url = GURL("https://172.22.68.17/kids/login.aspx");
[email protected]385a4672009-03-11 22:21:296361
Zentaro Kavanagh6ccee512017-09-28 18:34:096362 HttpAuthHandlerNTLM::ScopedProcSetter proc_setter(
6363 MockGetMSTime, MockGenerateRandom, MockGetHostName);
danakj1fd259a02016-04-16 03:17:096364 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:276365
Zentaro Kavanagh5b27a6e22017-09-25 23:00:376366 // Generate the NTLM messages based on known test data.
6367 std::string negotiate_msg;
6368 std::string challenge_msg;
6369 std::string authenticate_msg;
6370 base::Base64Encode(
6371 base::StringPiece(
6372 reinterpret_cast<const char*>(ntlm::test::kExpectedNegotiateMsg),
6373 arraysize(ntlm::test::kExpectedNegotiateMsg)),
6374 &negotiate_msg);
6375 base::Base64Encode(base::StringPiece(reinterpret_cast<const char*>(
6376 ntlm::test::kChallengeMsgV1),
6377 arraysize(ntlm::test::kChallengeMsgV1)),
6378 &challenge_msg);
6379 base::Base64Encode(
6380 base::StringPiece(
Zentaro Kavanagh6ccee512017-09-28 18:34:096381 reinterpret_cast<const char*>(
6382 ntlm::test::kExpectedAuthenticateMsgSpecResponseV1),
6383 arraysize(ntlm::test::kExpectedAuthenticateMsgSpecResponseV1)),
Zentaro Kavanagh5b27a6e22017-09-25 23:00:376384 &authenticate_msg);
6385
6386 // The authenticate message when |kWrongPassword| is sent.
6387 std::string wrong_password_authenticate_msg(
6388 "TlRMTVNTUAADAAAAGAAYAEAAAAAYABgAWAAAAAwADABwAAAACAAIAHwAAAAQABAAhAAAAAAA"
6389 "AABAAAAAA4IIAKqqqqqqqqqqAAAAAAAAAAAAAAAAAAAAAF2npafgDxlql9qxEIhLlsuuJIEd"
6390 "NQHk7kQAbwBtAGEAaQBuAFUAcwBlAHIAQwBPAE0AUABVAFQARQBSAA==");
6391
6392 // Sanity check that this is the same as |authenticate_msg| except for the
6393 // 24 bytes (32 encoded chars) of the NTLM Response.
6394 ASSERT_EQ(authenticate_msg.length(),
6395 wrong_password_authenticate_msg.length());
Zentaro Kavanagh6ccee512017-09-28 18:34:096396 ASSERT_EQ(authenticate_msg.length(), 200u);
Zentaro Kavanagh5b27a6e22017-09-25 23:00:376397 ASSERT_EQ(base::StringPiece(authenticate_msg.data(), 117),
6398 base::StringPiece(wrong_password_authenticate_msg.data(), 117));
6399 ASSERT_EQ(
6400 base::StringPiece(authenticate_msg.data() + 149, 51),
6401 base::StringPiece(wrong_password_authenticate_msg.data() + 149, 51));
6402
[email protected]385a4672009-03-11 22:21:296403 MockWrite data_writes1[] = {
6404 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
6405 "Host: 172.22.68.17\r\n"
6406 "Connection: keep-alive\r\n\r\n"),
6407 };
6408
6409 MockRead data_reads1[] = {
6410 MockRead("HTTP/1.1 401 Access Denied\r\n"),
[email protected]aef04272010-06-28 18:03:046411 // Negotiate and NTLM are often requested together. However, we only want
6412 // to test NTLM. Since Negotiate is preferred over NTLM, we have to skip
6413 // the header that requests Negotiate for this test.
[email protected]385a4672009-03-11 22:21:296414 MockRead("WWW-Authenticate: NTLM\r\n"),
6415 MockRead("Connection: close\r\n"),
6416 MockRead("Content-Length: 42\r\n"),
[email protected]076c85082009-04-10 23:21:366417 MockRead("Content-Type: text/html\r\n\r\n"),
[email protected]385a4672009-03-11 22:21:296418 // Missing content -- won't matter, as connection will be reset.
[email protected]385a4672009-03-11 22:21:296419 };
6420
6421 MockWrite data_writes2[] = {
bnc691fda62016-08-12 00:43:166422 // After restarting with a null identity, this is the
6423 // request we should be issuing -- the final header line contains a Type
6424 // 1 message.
6425 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
6426 "Host: 172.22.68.17\r\n"
6427 "Connection: keep-alive\r\n"
Zentaro Kavanagh5b27a6e22017-09-25 23:00:376428 "Authorization: NTLM "),
6429 MockWrite(negotiate_msg.c_str()), MockWrite("\r\n\r\n"),
[email protected]385a4672009-03-11 22:21:296430
bnc691fda62016-08-12 00:43:166431 // After calling trans.RestartWithAuth(), we should send a Type 3 message
Zentaro Kavanagh5b27a6e22017-09-25 23:00:376432 // (using incorrect credentials). The second request continues on the
6433 // same connection.
bnc691fda62016-08-12 00:43:166434 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
6435 "Host: 172.22.68.17\r\n"
6436 "Connection: keep-alive\r\n"
Zentaro Kavanagh5b27a6e22017-09-25 23:00:376437 "Authorization: NTLM "),
6438 MockWrite(wrong_password_authenticate_msg.c_str()), MockWrite("\r\n\r\n"),
[email protected]385a4672009-03-11 22:21:296439 };
6440
6441 MockRead data_reads2[] = {
Zentaro Kavanagh5b27a6e22017-09-25 23:00:376442 // The origin server responds with a Type 2 message.
6443 MockRead("HTTP/1.1 401 Access Denied\r\n"),
6444 MockRead("WWW-Authenticate: NTLM "), MockRead(challenge_msg.c_str()),
6445 MockRead("\r\n"), MockRead("Content-Length: 42\r\n"),
6446 MockRead("Content-Type: text/html\r\n\r\n"),
6447 MockRead("You are not authorized to view this page\r\n"),
[email protected]385a4672009-03-11 22:21:296448
Zentaro Kavanagh5b27a6e22017-09-25 23:00:376449 // Wrong password.
6450 MockRead("HTTP/1.1 401 Access Denied\r\n"),
6451 MockRead("WWW-Authenticate: NTLM\r\n"), MockRead("Connection: close\r\n"),
6452 MockRead("Content-Length: 42\r\n"),
6453 MockRead("Content-Type: text/html\r\n\r\n"),
6454 // Missing content -- won't matter, as connection will be reset.
[email protected]385a4672009-03-11 22:21:296455 };
6456
6457 MockWrite data_writes3[] = {
bnc691fda62016-08-12 00:43:166458 // After restarting with a null identity, this is the
6459 // request we should be issuing -- the final header line contains a Type
6460 // 1 message.
6461 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
6462 "Host: 172.22.68.17\r\n"
6463 "Connection: keep-alive\r\n"
Zentaro Kavanagh5b27a6e22017-09-25 23:00:376464 "Authorization: NTLM "),
6465 MockWrite(negotiate_msg.c_str()), MockWrite("\r\n\r\n"),
[email protected]385a4672009-03-11 22:21:296466
bnc691fda62016-08-12 00:43:166467 // After calling trans.RestartWithAuth(), we should send a Type 3 message
6468 // (the credentials for the origin server). The second request continues
6469 // on the same connection.
6470 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
6471 "Host: 172.22.68.17\r\n"
6472 "Connection: keep-alive\r\n"
Zentaro Kavanagh5b27a6e22017-09-25 23:00:376473 "Authorization: NTLM "),
6474 MockWrite(authenticate_msg.c_str()), MockWrite("\r\n\r\n"),
[email protected]385a4672009-03-11 22:21:296475 };
6476
6477 MockRead data_reads3[] = {
Bence Béky1e4ef192017-09-18 19:58:026478 // The origin server responds with a Type 2 message.
6479 MockRead("HTTP/1.1 401 Access Denied\r\n"),
Zentaro Kavanagh5b27a6e22017-09-25 23:00:376480 MockRead("WWW-Authenticate: NTLM "), MockRead(challenge_msg.c_str()),
6481 MockRead("\r\n"), MockRead("Content-Length: 42\r\n"),
Bence Béky1e4ef192017-09-18 19:58:026482 MockRead("Content-Type: text/html\r\n\r\n"),
6483 MockRead("You are not authorized to view this page\r\n"),
[email protected]385a4672009-03-11 22:21:296484
Bence Béky1e4ef192017-09-18 19:58:026485 // Lastly we get the desired content.
6486 MockRead("HTTP/1.1 200 OK\r\n"),
6487 MockRead("Content-Type: text/html; charset=utf-8\r\n"),
6488 MockRead("Content-Length: 14\r\n\r\n"), MockRead("Please Login\r\n"),
[email protected]385a4672009-03-11 22:21:296489 };
6490
[email protected]31a2bfe2010-02-09 08:03:396491 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
6492 data_writes1, arraysize(data_writes1));
6493 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
6494 data_writes2, arraysize(data_writes2));
6495 StaticSocketDataProvider data3(data_reads3, arraysize(data_reads3),
6496 data_writes3, arraysize(data_writes3));
[email protected]bb88e1d32013-05-03 23:11:076497 session_deps_.socket_factory->AddSocketDataProvider(&data1);
6498 session_deps_.socket_factory->AddSocketDataProvider(&data2);
6499 session_deps_.socket_factory->AddSocketDataProvider(&data3);
[email protected]385a4672009-03-11 22:21:296500
Bence Béky83eb3512017-09-05 12:56:096501 SSLSocketDataProvider ssl1(ASYNC, OK);
6502 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl1);
6503 SSLSocketDataProvider ssl2(ASYNC, OK);
6504 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
6505 SSLSocketDataProvider ssl3(ASYNC, OK);
6506 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl3);
6507
[email protected]49639fa2011-12-20 23:22:416508 TestCompletionCallback callback1;
[email protected]385a4672009-03-11 22:21:296509
bnc691fda62016-08-12 00:43:166510 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]0b0bf032010-09-21 18:08:506511
tfarina42834112016-09-22 13:38:206512 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:016513 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]385a4672009-03-11 22:21:296514
6515 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:016516 EXPECT_THAT(rv, IsOk());
[email protected]385a4672009-03-11 22:21:296517
bnc691fda62016-08-12 00:43:166518 EXPECT_FALSE(trans.IsReadyToRestartForAuth());
[email protected]385a4672009-03-11 22:21:296519
bnc691fda62016-08-12 00:43:166520 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:526521 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:046522 EXPECT_TRUE(CheckNTLMServerAuth(response->auth_challenge.get()));
[email protected]385a4672009-03-11 22:21:296523
[email protected]49639fa2011-12-20 23:22:416524 TestCompletionCallback callback2;
[email protected]385a4672009-03-11 22:21:296525
[email protected]0757e7702009-03-27 04:00:226526 // Enter the wrong password.
Zentaro Kavanagh5b27a6e22017-09-25 23:00:376527 rv = trans.RestartWithAuth(
6528 AuthCredentials(ntlm::test::kDomainUserCombined, kWrongPassword),
6529 callback2.callback());
robpercival214763f2016-07-01 23:27:016530 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]385a4672009-03-11 22:21:296531
[email protected]10af5fe72011-01-31 16:17:256532 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:016533 EXPECT_THAT(rv, IsOk());
[email protected]385a4672009-03-11 22:21:296534
bnc691fda62016-08-12 00:43:166535 EXPECT_TRUE(trans.IsReadyToRestartForAuth());
[email protected]49639fa2011-12-20 23:22:416536 TestCompletionCallback callback3;
bnc691fda62016-08-12 00:43:166537 rv = trans.RestartWithAuth(AuthCredentials(), callback3.callback());
robpercival214763f2016-07-01 23:27:016538 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]10af5fe72011-01-31 16:17:256539 rv = callback3.WaitForResult();
robpercival214763f2016-07-01 23:27:016540 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:166541 EXPECT_FALSE(trans.IsReadyToRestartForAuth());
[email protected]0757e7702009-03-27 04:00:226542
bnc691fda62016-08-12 00:43:166543 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:526544 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:046545 EXPECT_TRUE(CheckNTLMServerAuth(response->auth_challenge.get()));
[email protected]0757e7702009-03-27 04:00:226546
[email protected]49639fa2011-12-20 23:22:416547 TestCompletionCallback callback4;
[email protected]0757e7702009-03-27 04:00:226548
6549 // Now enter the right password.
Zentaro Kavanagh5b27a6e22017-09-25 23:00:376550 rv = trans.RestartWithAuth(
6551 AuthCredentials(ntlm::test::kDomainUserCombined, ntlm::test::kPassword),
6552 callback4.callback());
robpercival214763f2016-07-01 23:27:016553 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]10af5fe72011-01-31 16:17:256554
6555 rv = callback4.WaitForResult();
robpercival214763f2016-07-01 23:27:016556 EXPECT_THAT(rv, IsOk());
[email protected]10af5fe72011-01-31 16:17:256557
bnc691fda62016-08-12 00:43:166558 EXPECT_TRUE(trans.IsReadyToRestartForAuth());
[email protected]10af5fe72011-01-31 16:17:256559
[email protected]49639fa2011-12-20 23:22:416560 TestCompletionCallback callback5;
[email protected]10af5fe72011-01-31 16:17:256561
6562 // One more roundtrip
bnc691fda62016-08-12 00:43:166563 rv = trans.RestartWithAuth(AuthCredentials(), callback5.callback());
robpercival214763f2016-07-01 23:27:016564 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]0757e7702009-03-27 04:00:226565
6566 rv = callback5.WaitForResult();
robpercival214763f2016-07-01 23:27:016567 EXPECT_THAT(rv, IsOk());
[email protected]0757e7702009-03-27 04:00:226568
bnc691fda62016-08-12 00:43:166569 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:526570 EXPECT_FALSE(response->auth_challenge);
Bence Béky1e4ef192017-09-18 19:58:026571 EXPECT_EQ(14, response->headers->GetContentLength());
6572
6573 std::string response_data;
6574 rv = ReadTransaction(&trans, &response_data);
6575 EXPECT_THAT(rv, IsOk());
6576 EXPECT_EQ("Please Login\r\n", response_data);
6577
6578 EXPECT_TRUE(data1.AllReadDataConsumed());
6579 EXPECT_TRUE(data1.AllWriteDataConsumed());
6580 EXPECT_TRUE(data2.AllReadDataConsumed());
6581 EXPECT_TRUE(data2.AllWriteDataConsumed());
6582 EXPECT_TRUE(data3.AllReadDataConsumed());
6583 EXPECT_TRUE(data3.AllWriteDataConsumed());
[email protected]385a4672009-03-11 22:21:296584}
Bence Béky83eb3512017-09-05 12:56:096585
Bence Béky3238f2e12017-09-22 22:44:496586// Server requests NTLM authentication, which is not supported over HTTP/2.
6587// Subsequent request with authorization header should be sent over HTTP/1.1.
Bence Béky83eb3512017-09-05 12:56:096588TEST_F(HttpNetworkTransactionTest, NTLMOverHttp2) {
Zentaro Kavanagh6ccee512017-09-28 18:34:096589 HttpAuthHandlerNTLM::ScopedProcSetter proc_setter(
6590 MockGetMSTime, MockGenerateRandom, MockGetHostName);
Bence Béky83eb3512017-09-05 12:56:096591
6592 const char* kUrl = "https://172.22.68.17/kids/login.aspx";
6593
6594 HttpRequestInfo request;
6595 request.method = "GET";
6596 request.url = GURL(kUrl);
6597
6598 // First request without credentials.
6599 SpdyHeaderBlock request_headers0(spdy_util_.ConstructGetHeaderBlock(kUrl));
6600 SpdySerializedFrame request0(spdy_util_.ConstructSpdyHeaders(
6601 1, std::move(request_headers0), LOWEST, true));
6602
6603 SpdyHeaderBlock response_headers0;
Bence Békybda82952017-10-02 17:35:276604 response_headers0[kHttp2StatusHeader] = "401";
Bence Béky83eb3512017-09-05 12:56:096605 response_headers0["www-authenticate"] = "NTLM";
6606 SpdySerializedFrame resp(spdy_util_.ConstructSpdyResponseHeaders(
6607 1, std::move(response_headers0), true));
6608
Zentaro Kavanagh5b27a6e22017-09-25 23:00:376609 // Stream 1 is closed.
6610 spdy_util_.UpdateWithStreamDestruction(1);
6611
6612 // Generate the NTLM messages based on known test data.
6613 std::string negotiate_msg;
6614 std::string challenge_msg;
6615 std::string authenticate_msg;
6616 base::Base64Encode(
6617 base::StringPiece(
6618 reinterpret_cast<const char*>(ntlm::test::kExpectedNegotiateMsg),
6619 arraysize(ntlm::test::kExpectedNegotiateMsg)),
6620 &negotiate_msg);
6621 base::Base64Encode(base::StringPiece(reinterpret_cast<const char*>(
6622 ntlm::test::kChallengeMsgV1),
6623 arraysize(ntlm::test::kChallengeMsgV1)),
6624 &challenge_msg);
6625 base::Base64Encode(
6626 base::StringPiece(
Zentaro Kavanagh6ccee512017-09-28 18:34:096627 reinterpret_cast<const char*>(
6628 ntlm::test::kExpectedAuthenticateMsgSpecResponseV1),
6629 arraysize(ntlm::test::kExpectedAuthenticateMsgSpecResponseV1)),
Zentaro Kavanagh5b27a6e22017-09-25 23:00:376630 &authenticate_msg);
6631
6632 // Retry with authorization header.
6633 SpdyHeaderBlock request_headers1(spdy_util_.ConstructGetHeaderBlock(kUrl));
6634 request_headers1["authorization"] = std::string("NTLM ") + negotiate_msg;
6635 SpdySerializedFrame request1(spdy_util_.ConstructSpdyHeaders(
6636 3, std::move(request_headers1), LOWEST, true));
6637
6638 SpdySerializedFrame rst(
6639 spdy_util_.ConstructSpdyRstStream(3, ERROR_CODE_HTTP_1_1_REQUIRED));
6640
Bence Béky3238f2e12017-09-22 22:44:496641 MockWrite writes0[] = {CreateMockWrite(request0, 0)};
6642 MockRead reads0[] = {CreateMockRead(resp, 1), MockRead(ASYNC, 0, 2)};
Bence Béky83eb3512017-09-05 12:56:096643
6644 // Retry yet again using HTTP/1.1.
6645 MockWrite writes1[] = {
6646 // After restarting with a null identity, this is the
6647 // request we should be issuing -- the final header line contains a Type
6648 // 1 message.
6649 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
6650 "Host: 172.22.68.17\r\n"
6651 "Connection: keep-alive\r\n"
Zentaro Kavanagh5b27a6e22017-09-25 23:00:376652 "Authorization: NTLM "),
6653 MockWrite(negotiate_msg.c_str()), MockWrite("\r\n\r\n"),
Bence Béky83eb3512017-09-05 12:56:096654
6655 // After calling trans.RestartWithAuth(), we should send a Type 3 message
6656 // (the credentials for the origin server). The second request continues
6657 // on the same connection.
6658 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
6659 "Host: 172.22.68.17\r\n"
6660 "Connection: keep-alive\r\n"
Zentaro Kavanagh5b27a6e22017-09-25 23:00:376661 "Authorization: NTLM "),
6662 MockWrite(authenticate_msg.c_str()), MockWrite("\r\n\r\n"),
Bence Béky83eb3512017-09-05 12:56:096663 };
6664
6665 MockRead reads1[] = {
6666 // The origin server responds with a Type 2 message.
6667 MockRead("HTTP/1.1 401 Access Denied\r\n"),
Zentaro Kavanagh5b27a6e22017-09-25 23:00:376668 MockRead("WWW-Authenticate: NTLM "), MockRead(challenge_msg.c_str()),
6669 MockRead("\r\n"), MockRead("Content-Length: 42\r\n"),
Bence Béky83eb3512017-09-05 12:56:096670 MockRead("Content-Type: text/html\r\n\r\n"),
6671 MockRead("You are not authorized to view this page\r\n"),
6672
6673 // Lastly we get the desired content.
6674 MockRead("HTTP/1.1 200 OK\r\n"),
6675 MockRead("Content-Type: text/html; charset=utf-8\r\n"),
Bence Béky1e4ef192017-09-18 19:58:026676 MockRead("Content-Length: 14\r\n\r\n"), MockRead("Please Login\r\n"),
Bence Béky83eb3512017-09-05 12:56:096677 };
6678 SequencedSocketData data0(reads0, arraysize(reads0), writes0,
6679 arraysize(writes0));
6680 StaticSocketDataProvider data1(reads1, arraysize(reads1), writes1,
6681 arraysize(writes1));
6682 session_deps_.socket_factory->AddSocketDataProvider(&data0);
6683 session_deps_.socket_factory->AddSocketDataProvider(&data1);
6684
6685 SSLSocketDataProvider ssl0(ASYNC, OK);
6686 ssl0.next_proto = kProtoHTTP2;
6687 SSLSocketDataProvider ssl1(ASYNC, OK);
6688 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl0);
6689 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl1);
6690
6691 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
6692 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
6693
6694 TestCompletionCallback callback1;
6695 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
6696 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
6697
6698 rv = callback1.WaitForResult();
6699 EXPECT_THAT(rv, IsOk());
6700
6701 EXPECT_FALSE(trans.IsReadyToRestartForAuth());
6702
6703 const HttpResponseInfo* response = trans.GetResponseInfo();
6704 ASSERT_TRUE(response);
6705 EXPECT_TRUE(CheckNTLMServerAuth(response->auth_challenge.get()));
6706
6707 TestCompletionCallback callback2;
6708
Zentaro Kavanagh5b27a6e22017-09-25 23:00:376709 rv = trans.RestartWithAuth(
6710 AuthCredentials(ntlm::test::kDomainUserCombined, ntlm::test::kPassword),
6711 callback2.callback());
Bence Béky83eb3512017-09-05 12:56:096712 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
6713
6714 rv = callback2.WaitForResult();
6715 EXPECT_THAT(rv, IsOk());
6716
6717 EXPECT_TRUE(trans.IsReadyToRestartForAuth());
6718
6719 response = trans.GetResponseInfo();
6720 ASSERT_TRUE(response);
6721 EXPECT_FALSE(response->auth_challenge);
6722
6723 TestCompletionCallback callback3;
6724
6725 rv = trans.RestartWithAuth(AuthCredentials(), callback3.callback());
6726 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
6727
6728 rv = callback3.WaitForResult();
6729 EXPECT_THAT(rv, IsOk());
6730
6731 response = trans.GetResponseInfo();
6732 ASSERT_TRUE(response);
6733 EXPECT_FALSE(response->auth_challenge);
Bence Béky1e4ef192017-09-18 19:58:026734 EXPECT_EQ(14, response->headers->GetContentLength());
6735
6736 std::string response_data;
6737 rv = ReadTransaction(&trans, &response_data);
6738 EXPECT_THAT(rv, IsOk());
6739 EXPECT_EQ("Please Login\r\n", response_data);
6740
6741 EXPECT_TRUE(data0.AllReadDataConsumed());
6742 EXPECT_TRUE(data0.AllWriteDataConsumed());
6743 EXPECT_TRUE(data1.AllReadDataConsumed());
6744 EXPECT_TRUE(data1.AllWriteDataConsumed());
Bence Béky83eb3512017-09-05 12:56:096745}
[email protected]ea9dc9a2009-09-05 00:43:326746#endif // NTLM_PORTABLE
[email protected]385a4672009-03-11 22:21:296747
[email protected]4ddaf2502008-10-23 18:26:196748// Test reading a server response which has only headers, and no body.
6749// After some maximum number of bytes is consumed, the transaction should
6750// fail with ERR_RESPONSE_HEADERS_TOO_BIG.
bncd16676a2016-07-20 16:23:016751TEST_F(HttpNetworkTransactionTest, LargeHeadersNoBody) {
[email protected]1c773ea12009-04-28 19:58:426752 HttpRequestInfo request;
[email protected]4ddaf2502008-10-23 18:26:196753 request.method = "GET";
bncce36dca22015-04-21 22:11:236754 request.url = GURL("http://www.example.org/");
[email protected]4ddaf2502008-10-23 18:26:196755
danakj1fd259a02016-04-16 03:17:096756 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:166757 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:276758
[email protected]b75b7b2f2009-10-06 00:54:536759 // Respond with 300 kb of headers (we should fail after 256 kb).
[email protected]15a5ccf82008-10-23 19:57:436760 std::string large_headers_string;
[email protected]b75b7b2f2009-10-06 00:54:536761 FillLargeHeadersString(&large_headers_string, 300 * 1024);
[email protected]4ddaf2502008-10-23 18:26:196762
6763 MockRead data_reads[] = {
6764 MockRead("HTTP/1.0 200 OK\r\n"),
[email protected]8ddf8322012-02-23 18:08:066765 MockRead(ASYNC, large_headers_string.data(), large_headers_string.size()),
[email protected]4ddaf2502008-10-23 18:26:196766 MockRead("\r\nBODY"),
[email protected]8ddf8322012-02-23 18:08:066767 MockRead(SYNCHRONOUS, OK),
[email protected]4ddaf2502008-10-23 18:26:196768 };
[email protected]31a2bfe2010-02-09 08:03:396769 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:076770 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]4ddaf2502008-10-23 18:26:196771
[email protected]49639fa2011-12-20 23:22:416772 TestCompletionCallback callback;
[email protected]4ddaf2502008-10-23 18:26:196773
tfarina42834112016-09-22 13:38:206774 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:016775 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]4ddaf2502008-10-23 18:26:196776
6777 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:016778 EXPECT_THAT(rv, IsError(ERR_RESPONSE_HEADERS_TOO_BIG));
[email protected]4ddaf2502008-10-23 18:26:196779}
[email protected]f4e426b2008-11-05 00:24:496780
6781// Make sure that we don't try to reuse a TCPClientSocket when failing to
6782// establish tunnel.
6783// http://code.google.com/p/chromium/issues/detail?id=3772
bncd16676a2016-07-20 16:23:016784TEST_F(HttpNetworkTransactionTest, DontRecycleTransportSocketForSSLTunnel) {
[email protected]cb9bf6ca2011-01-28 13:15:276785 HttpRequestInfo request;
6786 request.method = "GET";
bncce36dca22015-04-21 22:11:236787 request.url = GURL("https://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:276788
[email protected]f4e426b2008-11-05 00:24:496789 // Configure against proxy server "myproxy:70".
rdsmith82957ad2015-09-16 19:42:036790 session_deps_.proxy_service = ProxyService::CreateFixed("myproxy:70");
[email protected]db8f44c2008-12-13 04:52:016791
danakj1fd259a02016-04-16 03:17:096792 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]f4e426b2008-11-05 00:24:496793
bnc87dcefc2017-05-25 12:47:586794 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:196795 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]f4e426b2008-11-05 00:24:496796
[email protected]f4e426b2008-11-05 00:24:496797 // Since we have proxy, should try to establish tunnel.
6798 MockWrite data_writes1[] = {
rsleevidb16bb02015-11-12 23:47:176799 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
6800 "Host: www.example.org:443\r\n"
6801 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]f4e426b2008-11-05 00:24:496802 };
6803
[email protected]77848d12008-11-14 00:00:226804 // The proxy responds to the connect with a 404, using a persistent
[email protected]f4e426b2008-11-05 00:24:496805 // connection. Usually a proxy would return 501 (not implemented),
6806 // or 200 (tunnel established).
6807 MockRead data_reads1[] = {
mmenked39192ee2015-12-09 00:57:236808 MockRead("HTTP/1.1 404 Not Found\r\n"),
6809 MockRead("Content-Length: 10\r\n\r\n"),
6810 MockRead(SYNCHRONOUS, ERR_UNEXPECTED),
[email protected]f4e426b2008-11-05 00:24:496811 };
6812
[email protected]31a2bfe2010-02-09 08:03:396813 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
6814 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:076815 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]f4e426b2008-11-05 00:24:496816
[email protected]49639fa2011-12-20 23:22:416817 TestCompletionCallback callback1;
[email protected]f4e426b2008-11-05 00:24:496818
tfarina42834112016-09-22 13:38:206819 int rv = trans->Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:016820 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]f4e426b2008-11-05 00:24:496821
6822 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:016823 EXPECT_THAT(rv, IsError(ERR_TUNNEL_CONNECTION_FAILED));
[email protected]f4e426b2008-11-05 00:24:496824
[email protected]b4404c02009-04-10 16:38:526825 // Empty the current queue. This is necessary because idle sockets are
6826 // added to the connection pool asynchronously with a PostTask.
fdoray92e35a72016-06-10 15:54:556827 base::RunLoop().RunUntilIdle();
[email protected]b4404c02009-04-10 16:38:526828
[email protected]f4e426b2008-11-05 00:24:496829 // We now check to make sure the TCPClientSocket was not added back to
6830 // the pool.
[email protected]90499482013-06-01 00:39:506831 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]f4e426b2008-11-05 00:24:496832 trans.reset();
fdoray92e35a72016-06-10 15:54:556833 base::RunLoop().RunUntilIdle();
[email protected]f4e426b2008-11-05 00:24:496834 // Make sure that the socket didn't get recycled after calling the destructor.
[email protected]90499482013-06-01 00:39:506835 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]f4e426b2008-11-05 00:24:496836}
[email protected]372d34a2008-11-05 21:30:516837
[email protected]1b157c02009-04-21 01:55:406838// Make sure that we recycle a socket after reading all of the response body.
bncd16676a2016-07-20 16:23:016839TEST_F(HttpNetworkTransactionTest, RecycleSocket) {
[email protected]1c773ea12009-04-28 19:58:426840 HttpRequestInfo request;
[email protected]1b157c02009-04-21 01:55:406841 request.method = "GET";
bncce36dca22015-04-21 22:11:236842 request.url = GURL("http://www.example.org/");
[email protected]1b157c02009-04-21 01:55:406843
danakj1fd259a02016-04-16 03:17:096844 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:276845
bnc691fda62016-08-12 00:43:166846 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:276847
[email protected]1b157c02009-04-21 01:55:406848 MockRead data_reads[] = {
6849 // A part of the response body is received with the response headers.
6850 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 11\r\n\r\nhel"),
6851 // The rest of the response body is received in two parts.
6852 MockRead("lo"),
6853 MockRead(" world"),
6854 MockRead("junk"), // Should not be read!!
[email protected]8ddf8322012-02-23 18:08:066855 MockRead(SYNCHRONOUS, OK),
[email protected]1b157c02009-04-21 01:55:406856 };
6857
[email protected]31a2bfe2010-02-09 08:03:396858 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:076859 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1b157c02009-04-21 01:55:406860
[email protected]49639fa2011-12-20 23:22:416861 TestCompletionCallback callback;
[email protected]1b157c02009-04-21 01:55:406862
tfarina42834112016-09-22 13:38:206863 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:016864 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]1b157c02009-04-21 01:55:406865
6866 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:016867 EXPECT_THAT(rv, IsOk());
[email protected]1b157c02009-04-21 01:55:406868
bnc691fda62016-08-12 00:43:166869 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:526870 ASSERT_TRUE(response);
[email protected]1b157c02009-04-21 01:55:406871
wezca1070932016-05-26 20:30:526872 EXPECT_TRUE(response->headers);
[email protected]1b157c02009-04-21 01:55:406873 std::string status_line = response->headers->GetStatusLine();
6874 EXPECT_EQ("HTTP/1.1 200 OK", status_line);
6875
[email protected]90499482013-06-01 00:39:506876 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]1b157c02009-04-21 01:55:406877
6878 std::string response_data;
bnc691fda62016-08-12 00:43:166879 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:016880 EXPECT_THAT(rv, IsOk());
[email protected]1b157c02009-04-21 01:55:406881 EXPECT_EQ("hello world", response_data);
6882
6883 // Empty the current queue. This is necessary because idle sockets are
6884 // added to the connection pool asynchronously with a PostTask.
fdoray92e35a72016-06-10 15:54:556885 base::RunLoop().RunUntilIdle();
[email protected]1b157c02009-04-21 01:55:406886
6887 // We now check to make sure the socket was added back to the pool.
[email protected]90499482013-06-01 00:39:506888 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]1b157c02009-04-21 01:55:406889}
6890
[email protected]76a505b2010-08-25 06:23:006891// Make sure that we recycle a SSL socket after reading all of the response
6892// body.
bncd16676a2016-07-20 16:23:016893TEST_F(HttpNetworkTransactionTest, RecycleSSLSocket) {
[email protected]76a505b2010-08-25 06:23:006894 HttpRequestInfo request;
6895 request.method = "GET";
bncce36dca22015-04-21 22:11:236896 request.url = GURL("https://www.example.org/");
[email protected]76a505b2010-08-25 06:23:006897
6898 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:236899 MockWrite(
6900 "GET / HTTP/1.1\r\n"
6901 "Host: www.example.org\r\n"
6902 "Connection: keep-alive\r\n\r\n"),
[email protected]76a505b2010-08-25 06:23:006903 };
6904
6905 MockRead data_reads[] = {
6906 MockRead("HTTP/1.1 200 OK\r\n"),
6907 MockRead("Content-Length: 11\r\n\r\n"),
6908 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:066909 MockRead(SYNCHRONOUS, OK),
[email protected]76a505b2010-08-25 06:23:006910 };
6911
[email protected]8ddf8322012-02-23 18:08:066912 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:076913 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]76a505b2010-08-25 06:23:006914
6915 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
6916 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:076917 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]76a505b2010-08-25 06:23:006918
[email protected]49639fa2011-12-20 23:22:416919 TestCompletionCallback callback;
[email protected]76a505b2010-08-25 06:23:006920
danakj1fd259a02016-04-16 03:17:096921 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:166922 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]76a505b2010-08-25 06:23:006923
tfarina42834112016-09-22 13:38:206924 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
[email protected]76a505b2010-08-25 06:23:006925
robpercival214763f2016-07-01 23:27:016926 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
6927 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]76a505b2010-08-25 06:23:006928
bnc691fda62016-08-12 00:43:166929 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:526930 ASSERT_TRUE(response);
6931 ASSERT_TRUE(response->headers);
[email protected]76a505b2010-08-25 06:23:006932 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
6933
[email protected]90499482013-06-01 00:39:506934 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]76a505b2010-08-25 06:23:006935
6936 std::string response_data;
bnc691fda62016-08-12 00:43:166937 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:016938 EXPECT_THAT(rv, IsOk());
[email protected]76a505b2010-08-25 06:23:006939 EXPECT_EQ("hello world", response_data);
6940
6941 // Empty the current queue. This is necessary because idle sockets are
6942 // added to the connection pool asynchronously with a PostTask.
fdoray92e35a72016-06-10 15:54:556943 base::RunLoop().RunUntilIdle();
[email protected]76a505b2010-08-25 06:23:006944
6945 // We now check to make sure the socket was added back to the pool.
[email protected]90499482013-06-01 00:39:506946 EXPECT_EQ(1, GetIdleSocketCountInSSLSocketPool(session.get()));
[email protected]76a505b2010-08-25 06:23:006947}
6948
6949// Grab a SSL socket, use it, and put it back into the pool. Then, reuse it
6950// from the pool and make sure that we recover okay.
bncd16676a2016-07-20 16:23:016951TEST_F(HttpNetworkTransactionTest, RecycleDeadSSLSocket) {
[email protected]76a505b2010-08-25 06:23:006952 HttpRequestInfo request;
6953 request.method = "GET";
bncce36dca22015-04-21 22:11:236954 request.url = GURL("https://www.example.org/");
[email protected]76a505b2010-08-25 06:23:006955
6956 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:236957 MockWrite(
6958 "GET / HTTP/1.1\r\n"
6959 "Host: www.example.org\r\n"
6960 "Connection: keep-alive\r\n\r\n"),
6961 MockWrite(
6962 "GET / HTTP/1.1\r\n"
6963 "Host: www.example.org\r\n"
6964 "Connection: keep-alive\r\n\r\n"),
[email protected]76a505b2010-08-25 06:23:006965 };
6966
6967 MockRead data_reads[] = {
mmenke911ee0222015-12-04 03:58:426968 MockRead("HTTP/1.1 200 OK\r\n"), MockRead("Content-Length: 11\r\n\r\n"),
6969 MockRead("hello world"), MockRead(ASYNC, ERR_CONNECTION_CLOSED)};
[email protected]76a505b2010-08-25 06:23:006970
[email protected]8ddf8322012-02-23 18:08:066971 SSLSocketDataProvider ssl(ASYNC, OK);
6972 SSLSocketDataProvider ssl2(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:076973 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
6974 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
[email protected]76a505b2010-08-25 06:23:006975
6976 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
6977 data_writes, arraysize(data_writes));
6978 StaticSocketDataProvider data2(data_reads, arraysize(data_reads),
6979 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:076980 session_deps_.socket_factory->AddSocketDataProvider(&data);
6981 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]76a505b2010-08-25 06:23:006982
[email protected]49639fa2011-12-20 23:22:416983 TestCompletionCallback callback;
[email protected]76a505b2010-08-25 06:23:006984
danakj1fd259a02016-04-16 03:17:096985 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc87dcefc2017-05-25 12:47:586986 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:196987 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]76a505b2010-08-25 06:23:006988
tfarina42834112016-09-22 13:38:206989 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
[email protected]76a505b2010-08-25 06:23:006990
robpercival214763f2016-07-01 23:27:016991 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
6992 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]76a505b2010-08-25 06:23:006993
6994 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:526995 ASSERT_TRUE(response);
6996 ASSERT_TRUE(response->headers);
[email protected]76a505b2010-08-25 06:23:006997 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
6998
[email protected]90499482013-06-01 00:39:506999 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]76a505b2010-08-25 06:23:007000
7001 std::string response_data;
7002 rv = ReadTransaction(trans.get(), &response_data);
robpercival214763f2016-07-01 23:27:017003 EXPECT_THAT(rv, IsOk());
[email protected]76a505b2010-08-25 06:23:007004 EXPECT_EQ("hello world", response_data);
7005
7006 // Empty the current queue. This is necessary because idle sockets are
7007 // added to the connection pool asynchronously with a PostTask.
fdoray92e35a72016-06-10 15:54:557008 base::RunLoop().RunUntilIdle();
[email protected]76a505b2010-08-25 06:23:007009
7010 // We now check to make sure the socket was added back to the pool.
[email protected]90499482013-06-01 00:39:507011 EXPECT_EQ(1, GetIdleSocketCountInSSLSocketPool(session.get()));
[email protected]76a505b2010-08-25 06:23:007012
7013 // Now start the second transaction, which should reuse the previous socket.
7014
bnc87dcefc2017-05-25 12:47:587015 trans =
Jeremy Roman0579ed62017-08-29 15:56:197016 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]76a505b2010-08-25 06:23:007017
tfarina42834112016-09-22 13:38:207018 rv = trans->Start(&request, callback.callback(), NetLogWithSource());
[email protected]76a505b2010-08-25 06:23:007019
robpercival214763f2016-07-01 23:27:017020 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
7021 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]76a505b2010-08-25 06:23:007022
7023 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:527024 ASSERT_TRUE(response);
7025 ASSERT_TRUE(response->headers);
[email protected]76a505b2010-08-25 06:23:007026 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
7027
[email protected]90499482013-06-01 00:39:507028 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]76a505b2010-08-25 06:23:007029
7030 rv = ReadTransaction(trans.get(), &response_data);
robpercival214763f2016-07-01 23:27:017031 EXPECT_THAT(rv, IsOk());
[email protected]76a505b2010-08-25 06:23:007032 EXPECT_EQ("hello world", response_data);
7033
7034 // Empty the current queue. This is necessary because idle sockets are
7035 // added to the connection pool asynchronously with a PostTask.
fdoray92e35a72016-06-10 15:54:557036 base::RunLoop().RunUntilIdle();
[email protected]76a505b2010-08-25 06:23:007037
7038 // We now check to make sure the socket was added back to the pool.
[email protected]90499482013-06-01 00:39:507039 EXPECT_EQ(1, GetIdleSocketCountInSSLSocketPool(session.get()));
[email protected]76a505b2010-08-25 06:23:007040}
7041
maksim.sisov0adf8592016-07-15 06:25:567042// Grab a socket, use it, and put it back into the pool. Then, make
7043// low memory notification and ensure the socket pool is flushed.
bncd16676a2016-07-20 16:23:017044TEST_F(HttpNetworkTransactionTest, FlushSocketPoolOnLowMemoryNotifications) {
maksim.sisov0adf8592016-07-15 06:25:567045 HttpRequestInfo request;
7046 request.method = "GET";
7047 request.url = GURL("http://www.example.org/");
7048 request.load_flags = 0;
7049
7050 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
7051
bnc691fda62016-08-12 00:43:167052 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
maksim.sisov0adf8592016-07-15 06:25:567053
7054 MockRead data_reads[] = {
7055 // A part of the response body is received with the response headers.
7056 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 11\r\n\r\nhel"),
7057 // The rest of the response body is received in two parts.
7058 MockRead("lo"), MockRead(" world"),
7059 MockRead("junk"), // Should not be read!!
7060 MockRead(SYNCHRONOUS, OK),
7061 };
7062
7063 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
7064 session_deps_.socket_factory->AddSocketDataProvider(&data);
7065
7066 TestCompletionCallback callback;
7067
tfarina42834112016-09-22 13:38:207068 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
maksim.sisov0adf8592016-07-15 06:25:567069 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
7070
7071 EXPECT_THAT(callback.GetResult(rv), IsOk());
7072
bnc691fda62016-08-12 00:43:167073 const HttpResponseInfo* response = trans.GetResponseInfo();
maksim.sisov0adf8592016-07-15 06:25:567074 ASSERT_TRUE(response);
7075 EXPECT_TRUE(response->headers);
7076 std::string status_line = response->headers->GetStatusLine();
7077 EXPECT_EQ("HTTP/1.1 200 OK", status_line);
7078
7079 // Make memory critical notification and ensure the transaction still has been
7080 // operating right.
7081 base::MemoryPressureListener::NotifyMemoryPressure(
7082 base::MemoryPressureListener::MEMORY_PRESSURE_LEVEL_CRITICAL);
7083 base::RunLoop().RunUntilIdle();
7084
7085 // Socket should not be flushed as long as it is not idle.
7086 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
7087
7088 std::string response_data;
bnc691fda62016-08-12 00:43:167089 rv = ReadTransaction(&trans, &response_data);
maksim.sisov0adf8592016-07-15 06:25:567090 EXPECT_THAT(rv, IsOk());
7091 EXPECT_EQ("hello world", response_data);
7092
7093 // Empty the current queue. This is necessary because idle sockets are
7094 // added to the connection pool asynchronously with a PostTask.
7095 base::RunLoop().RunUntilIdle();
7096
7097 // We now check to make sure the socket was added back to the pool.
7098 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
7099
7100 // Idle sockets should be flushed now.
7101 base::MemoryPressureListener::NotifyMemoryPressure(
7102 base::MemoryPressureListener::MEMORY_PRESSURE_LEVEL_CRITICAL);
7103 base::RunLoop().RunUntilIdle();
7104
7105 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
7106}
7107
yucliu48f235d2018-01-11 00:59:557108// Disable idle socket closing on memory pressure.
7109// Grab a socket, use it, and put it back into the pool. Then, make
7110// low memory notification and ensure the socket pool is NOT flushed.
7111TEST_F(HttpNetworkTransactionTest, NoFlushSocketPoolOnLowMemoryNotifications) {
7112 HttpRequestInfo request;
7113 request.method = "GET";
7114 request.url = GURL("http://www.example.org/");
7115 request.load_flags = 0;
7116
7117 // Disable idle socket closing on memory pressure.
7118 session_deps_.disable_idle_sockets_close_on_memory_pressure = true;
7119 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
7120
7121 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
7122
7123 MockRead data_reads[] = {
7124 // A part of the response body is received with the response headers.
7125 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 11\r\n\r\nhel"),
7126 // The rest of the response body is received in two parts.
7127 MockRead("lo"), MockRead(" world"),
7128 MockRead("junk"), // Should not be read!!
7129 MockRead(SYNCHRONOUS, OK),
7130 };
7131
7132 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
7133 session_deps_.socket_factory->AddSocketDataProvider(&data);
7134
7135 TestCompletionCallback callback;
7136
7137 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
7138 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
7139
7140 EXPECT_THAT(callback.GetResult(rv), IsOk());
7141
7142 const HttpResponseInfo* response = trans.GetResponseInfo();
7143 ASSERT_TRUE(response);
7144 EXPECT_TRUE(response->headers);
7145 std::string status_line = response->headers->GetStatusLine();
7146 EXPECT_EQ("HTTP/1.1 200 OK", status_line);
7147
7148 // Make memory critical notification and ensure the transaction still has been
7149 // operating right.
7150 base::MemoryPressureListener::NotifyMemoryPressure(
7151 base::MemoryPressureListener::MEMORY_PRESSURE_LEVEL_CRITICAL);
7152 base::RunLoop().RunUntilIdle();
7153
7154 // Socket should not be flushed as long as it is not idle.
7155 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
7156
7157 std::string response_data;
7158 rv = ReadTransaction(&trans, &response_data);
7159 EXPECT_THAT(rv, IsOk());
7160 EXPECT_EQ("hello world", response_data);
7161
7162 // Empty the current queue. This is necessary because idle sockets are
7163 // added to the connection pool asynchronously with a PostTask.
7164 base::RunLoop().RunUntilIdle();
7165
7166 // We now check to make sure the socket was added back to the pool.
7167 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
7168
7169 // Idle sockets should NOT be flushed on moderate memory pressure.
7170 base::MemoryPressureListener::NotifyMemoryPressure(
7171 base::MemoryPressureListener::MEMORY_PRESSURE_LEVEL_MODERATE);
7172 base::RunLoop().RunUntilIdle();
7173
7174 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
7175
7176 // Idle sockets should NOT be flushed on critical memory pressure.
7177 base::MemoryPressureListener::NotifyMemoryPressure(
7178 base::MemoryPressureListener::MEMORY_PRESSURE_LEVEL_CRITICAL);
7179 base::RunLoop().RunUntilIdle();
7180
7181 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
7182}
7183
maksim.sisov0adf8592016-07-15 06:25:567184// Grab an SSL socket, use it, and put it back into the pool. Then, make
7185// low memory notification and ensure the socket pool is flushed.
bncd16676a2016-07-20 16:23:017186TEST_F(HttpNetworkTransactionTest, FlushSSLSocketPoolOnLowMemoryNotifications) {
maksim.sisov0adf8592016-07-15 06:25:567187 HttpRequestInfo request;
7188 request.method = "GET";
7189 request.url = GURL("https://www.example.org/");
7190 request.load_flags = 0;
7191
7192 MockWrite data_writes[] = {
7193 MockWrite("GET / HTTP/1.1\r\n"
7194 "Host: www.example.org\r\n"
7195 "Connection: keep-alive\r\n\r\n"),
7196 };
7197
7198 MockRead data_reads[] = {
7199 MockRead("HTTP/1.1 200 OK\r\n"), MockRead("Content-Length: 11\r\n\r\n"),
7200 MockRead("hello world"), MockRead(ASYNC, ERR_CONNECTION_CLOSED)};
7201
7202 SSLSocketDataProvider ssl(ASYNC, OK);
7203 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
7204
7205 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
7206 arraysize(data_writes));
7207 session_deps_.socket_factory->AddSocketDataProvider(&data);
7208
7209 TestCompletionCallback callback;
7210
7211 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:167212 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
maksim.sisov0adf8592016-07-15 06:25:567213
7214 EXPECT_EQ(0, GetIdleSocketCountInSSLSocketPool(session.get()));
tfarina42834112016-09-22 13:38:207215 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
maksim.sisov0adf8592016-07-15 06:25:567216
7217 EXPECT_THAT(callback.GetResult(rv), IsOk());
7218
bnc691fda62016-08-12 00:43:167219 const HttpResponseInfo* response = trans.GetResponseInfo();
maksim.sisov0adf8592016-07-15 06:25:567220 ASSERT_TRUE(response);
7221 ASSERT_TRUE(response->headers);
7222 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
7223
7224 // Make memory critical notification and ensure the transaction still has been
7225 // operating right.
7226 base::MemoryPressureListener::NotifyMemoryPressure(
7227 base::MemoryPressureListener::MEMORY_PRESSURE_LEVEL_CRITICAL);
7228 base::RunLoop().RunUntilIdle();
7229
7230 EXPECT_EQ(0, GetIdleSocketCountInSSLSocketPool(session.get()));
7231
7232 std::string response_data;
bnc691fda62016-08-12 00:43:167233 rv = ReadTransaction(&trans, &response_data);
maksim.sisov0adf8592016-07-15 06:25:567234 EXPECT_THAT(rv, IsOk());
7235 EXPECT_EQ("hello world", response_data);
7236
7237 // Empty the current queue. This is necessary because idle sockets are
7238 // added to the connection pool asynchronously with a PostTask.
7239 base::RunLoop().RunUntilIdle();
7240
7241 // We now check to make sure the socket was added back to the pool.
7242 EXPECT_EQ(1, GetIdleSocketCountInSSLSocketPool(session.get()));
7243
7244 // Make memory notification once again and ensure idle socket is closed.
7245 base::MemoryPressureListener::NotifyMemoryPressure(
7246 base::MemoryPressureListener::MEMORY_PRESSURE_LEVEL_CRITICAL);
7247 base::RunLoop().RunUntilIdle();
7248
7249 EXPECT_EQ(0, GetIdleSocketCountInSSLSocketPool(session.get()));
7250}
7251
[email protected]b4404c02009-04-10 16:38:527252// Make sure that we recycle a socket after a zero-length response.
7253// http://crbug.com/9880
bncd16676a2016-07-20 16:23:017254TEST_F(HttpNetworkTransactionTest, RecycleSocketAfterZeroContentLength) {
[email protected]1c773ea12009-04-28 19:58:427255 HttpRequestInfo request;
[email protected]b4404c02009-04-10 16:38:527256 request.method = "GET";
bncce36dca22015-04-21 22:11:237257 request.url = GURL(
7258 "http://www.example.org/csi?v=3&s=web&action=&"
7259 "tran=undefined&ei=mAXcSeegAo-SMurloeUN&"
7260 "e=17259,18167,19592,19773,19981,20133,20173,20233&"
7261 "rt=prt.2642,ol.2649,xjs.2951");
[email protected]b4404c02009-04-10 16:38:527262
danakj1fd259a02016-04-16 03:17:097263 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:277264
[email protected]b4404c02009-04-10 16:38:527265 MockRead data_reads[] = {
7266 MockRead("HTTP/1.1 204 No Content\r\n"
7267 "Content-Length: 0\r\n"
7268 "Content-Type: text/html\r\n\r\n"),
7269 MockRead("junk"), // Should not be read!!
[email protected]8ddf8322012-02-23 18:08:067270 MockRead(SYNCHRONOUS, OK),
[email protected]b4404c02009-04-10 16:38:527271 };
7272
[email protected]31a2bfe2010-02-09 08:03:397273 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:077274 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]b4404c02009-04-10 16:38:527275
mmenkecc2298e2015-12-07 18:20:187276 // Transaction must be created after the MockReads, so it's destroyed before
7277 // them.
bnc691fda62016-08-12 00:43:167278 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
mmenkecc2298e2015-12-07 18:20:187279
[email protected]49639fa2011-12-20 23:22:417280 TestCompletionCallback callback;
[email protected]b4404c02009-04-10 16:38:527281
tfarina42834112016-09-22 13:38:207282 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:017283 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]b4404c02009-04-10 16:38:527284
7285 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:017286 EXPECT_THAT(rv, IsOk());
[email protected]b4404c02009-04-10 16:38:527287
bnc691fda62016-08-12 00:43:167288 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:527289 ASSERT_TRUE(response);
[email protected]b4404c02009-04-10 16:38:527290
wezca1070932016-05-26 20:30:527291 EXPECT_TRUE(response->headers);
[email protected]b4404c02009-04-10 16:38:527292 std::string status_line = response->headers->GetStatusLine();
7293 EXPECT_EQ("HTTP/1.1 204 No Content", status_line);
7294
[email protected]90499482013-06-01 00:39:507295 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]b4404c02009-04-10 16:38:527296
7297 std::string response_data;
bnc691fda62016-08-12 00:43:167298 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:017299 EXPECT_THAT(rv, IsOk());
[email protected]b4404c02009-04-10 16:38:527300 EXPECT_EQ("", response_data);
7301
7302 // Empty the current queue. This is necessary because idle sockets are
7303 // added to the connection pool asynchronously with a PostTask.
fdoray92e35a72016-06-10 15:54:557304 base::RunLoop().RunUntilIdle();
[email protected]b4404c02009-04-10 16:38:527305
7306 // We now check to make sure the socket was added back to the pool.
[email protected]90499482013-06-01 00:39:507307 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]b4404c02009-04-10 16:38:527308}
7309
bncd16676a2016-07-20 16:23:017310TEST_F(HttpNetworkTransactionTest, ResendRequestOnWriteBodyError) {
danakj1fd259a02016-04-16 03:17:097311 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:227312 element_readers.push_back(
Jeremy Roman0579ed62017-08-29 15:56:197313 std::make_unique<UploadBytesElementReader>("foo", 3));
olli.raula6df48b2a2015-11-26 07:40:227314 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]329b68b2012-11-14 17:54:277315
[email protected]1c773ea12009-04-28 19:58:427316 HttpRequestInfo request[2];
[email protected]372d34a2008-11-05 21:30:517317 // Transaction 1: a GET request that succeeds. The socket is recycled
7318 // after use.
7319 request[0].method = "GET";
7320 request[0].url = GURL("http://www.google.com/");
7321 request[0].load_flags = 0;
7322 // Transaction 2: a POST request. Reuses the socket kept alive from
7323 // transaction 1. The first attempts fails when writing the POST data.
7324 // This causes the transaction to retry with a new socket. The second
7325 // attempt succeeds.
7326 request[1].method = "POST";
7327 request[1].url = GURL("http://www.google.com/login.cgi");
[email protected]329b68b2012-11-14 17:54:277328 request[1].upload_data_stream = &upload_data_stream;
[email protected]372d34a2008-11-05 21:30:517329 request[1].load_flags = 0;
7330
danakj1fd259a02016-04-16 03:17:097331 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]372d34a2008-11-05 21:30:517332
7333 // The first socket is used for transaction 1 and the first attempt of
7334 // transaction 2.
7335
7336 // The response of transaction 1.
7337 MockRead data_reads1[] = {
7338 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 11\r\n\r\n"),
7339 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:067340 MockRead(SYNCHRONOUS, OK),
[email protected]372d34a2008-11-05 21:30:517341 };
7342 // The mock write results of transaction 1 and the first attempt of
7343 // transaction 2.
7344 MockWrite data_writes1[] = {
[email protected]8ddf8322012-02-23 18:08:067345 MockWrite(SYNCHRONOUS, 64), // GET
7346 MockWrite(SYNCHRONOUS, 93), // POST
7347 MockWrite(SYNCHRONOUS, ERR_CONNECTION_ABORTED), // POST data
[email protected]372d34a2008-11-05 21:30:517348 };
[email protected]31a2bfe2010-02-09 08:03:397349 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
7350 data_writes1, arraysize(data_writes1));
[email protected]372d34a2008-11-05 21:30:517351
7352 // The second socket is used for the second attempt of transaction 2.
7353
7354 // The response of transaction 2.
7355 MockRead data_reads2[] = {
7356 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 7\r\n\r\n"),
7357 MockRead("welcome"),
[email protected]8ddf8322012-02-23 18:08:067358 MockRead(SYNCHRONOUS, OK),
[email protected]372d34a2008-11-05 21:30:517359 };
7360 // The mock write results of the second attempt of transaction 2.
7361 MockWrite data_writes2[] = {
[email protected]8ddf8322012-02-23 18:08:067362 MockWrite(SYNCHRONOUS, 93), // POST
7363 MockWrite(SYNCHRONOUS, 3), // POST data
[email protected]372d34a2008-11-05 21:30:517364 };
[email protected]31a2bfe2010-02-09 08:03:397365 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
7366 data_writes2, arraysize(data_writes2));
[email protected]372d34a2008-11-05 21:30:517367
[email protected]bb88e1d32013-05-03 23:11:077368 session_deps_.socket_factory->AddSocketDataProvider(&data1);
7369 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]372d34a2008-11-05 21:30:517370
thestig9d3bb0c2015-01-24 00:49:517371 const char* const kExpectedResponseData[] = {
[email protected]372d34a2008-11-05 21:30:517372 "hello world", "welcome"
7373 };
7374
7375 for (int i = 0; i < 2; ++i) {
bnc691fda62016-08-12 00:43:167376 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]372d34a2008-11-05 21:30:517377
[email protected]49639fa2011-12-20 23:22:417378 TestCompletionCallback callback;
[email protected]372d34a2008-11-05 21:30:517379
tfarina42834112016-09-22 13:38:207380 int rv = trans.Start(&request[i], callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:017381 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]372d34a2008-11-05 21:30:517382
7383 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:017384 EXPECT_THAT(rv, IsOk());
[email protected]372d34a2008-11-05 21:30:517385
bnc691fda62016-08-12 00:43:167386 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:527387 ASSERT_TRUE(response);
[email protected]372d34a2008-11-05 21:30:517388
wezca1070932016-05-26 20:30:527389 EXPECT_TRUE(response->headers);
[email protected]372d34a2008-11-05 21:30:517390 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
7391
7392 std::string response_data;
bnc691fda62016-08-12 00:43:167393 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:017394 EXPECT_THAT(rv, IsOk());
[email protected]372d34a2008-11-05 21:30:517395 EXPECT_EQ(kExpectedResponseData[i], response_data);
7396 }
7397}
[email protected]f9ee6b52008-11-08 06:46:237398
7399// Test the request-challenge-retry sequence for basic auth when there is
7400// an identity in the URL. The request should be sent as normal, but when
[email protected]2262e3a2012-05-22 16:08:167401// it fails the identity from the URL is used to answer the challenge.
bncd16676a2016-07-20 16:23:017402TEST_F(HttpNetworkTransactionTest, AuthIdentityInURL) {
[email protected]1c773ea12009-04-28 19:58:427403 HttpRequestInfo request;
[email protected]f9ee6b52008-11-08 06:46:237404 request.method = "GET";
bncce36dca22015-04-21 22:11:237405 request.url = GURL("http://foo:b@[email protected]/");
[email protected]7b08ba62012-02-10 20:19:417406 request.load_flags = LOAD_NORMAL;
[email protected]a97cca42009-08-14 01:00:297407
danakj1fd259a02016-04-16 03:17:097408 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:167409 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:277410
[email protected]a97cca42009-08-14 01:00:297411 // The password contains an escaped character -- for this test to pass it
7412 // will need to be unescaped by HttpNetworkTransaction.
7413 EXPECT_EQ("b%40r", request.url.password());
7414
[email protected]f9ee6b52008-11-08 06:46:237415 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:237416 MockWrite(
7417 "GET / HTTP/1.1\r\n"
7418 "Host: www.example.org\r\n"
7419 "Connection: keep-alive\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:237420 };
7421
7422 MockRead data_reads1[] = {
7423 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
7424 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
7425 MockRead("Content-Length: 10\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067426 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]f9ee6b52008-11-08 06:46:237427 };
7428
[email protected]2262e3a2012-05-22 16:08:167429 // After the challenge above, the transaction will be restarted using the
7430 // identity from the url (foo, b@r) to answer the challenge.
7431 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:237432 MockWrite(
7433 "GET / HTTP/1.1\r\n"
7434 "Host: www.example.org\r\n"
7435 "Connection: keep-alive\r\n"
7436 "Authorization: Basic Zm9vOmJAcg==\r\n\r\n"),
[email protected]2262e3a2012-05-22 16:08:167437 };
7438
7439 MockRead data_reads2[] = {
7440 MockRead("HTTP/1.0 200 OK\r\n"),
7441 MockRead("Content-Length: 100\r\n\r\n"),
7442 MockRead(SYNCHRONOUS, OK),
7443 };
7444
[email protected]31a2bfe2010-02-09 08:03:397445 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
7446 data_writes1, arraysize(data_writes1));
[email protected]2262e3a2012-05-22 16:08:167447 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
7448 data_writes2, arraysize(data_writes2));
[email protected]bb88e1d32013-05-03 23:11:077449 session_deps_.socket_factory->AddSocketDataProvider(&data1);
7450 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]f9ee6b52008-11-08 06:46:237451
[email protected]49639fa2011-12-20 23:22:417452 TestCompletionCallback callback1;
tfarina42834112016-09-22 13:38:207453 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:017454 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]f9ee6b52008-11-08 06:46:237455 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:017456 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:167457 EXPECT_TRUE(trans.IsReadyToRestartForAuth());
[email protected]2262e3a2012-05-22 16:08:167458
7459 TestCompletionCallback callback2;
bnc691fda62016-08-12 00:43:167460 rv = trans.RestartWithAuth(AuthCredentials(), callback2.callback());
robpercival214763f2016-07-01 23:27:017461 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2262e3a2012-05-22 16:08:167462 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:017463 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:167464 EXPECT_FALSE(trans.IsReadyToRestartForAuth());
[email protected]0757e7702009-03-27 04:00:227465
bnc691fda62016-08-12 00:43:167466 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:527467 ASSERT_TRUE(response);
[email protected]2262e3a2012-05-22 16:08:167468
7469 // There is no challenge info, since the identity in URL worked.
wezca1070932016-05-26 20:30:527470 EXPECT_FALSE(response->auth_challenge);
[email protected]2262e3a2012-05-22 16:08:167471
7472 EXPECT_EQ(100, response->headers->GetContentLength());
7473
7474 // Empty the current queue.
fdoray92e35a72016-06-10 15:54:557475 base::RunLoop().RunUntilIdle();
[email protected]2262e3a2012-05-22 16:08:167476}
7477
7478// Test the request-challenge-retry sequence for basic auth when there is an
7479// incorrect identity in the URL. The identity from the URL should be used only
7480// once.
bncd16676a2016-07-20 16:23:017481TEST_F(HttpNetworkTransactionTest, WrongAuthIdentityInURL) {
[email protected]2262e3a2012-05-22 16:08:167482 HttpRequestInfo request;
7483 request.method = "GET";
7484 // Note: the URL has a username:password in it. The password "baz" is
7485 // wrong (should be "bar").
bncce36dca22015-04-21 22:11:237486 request.url = GURL("http://foo:[email protected]/");
[email protected]2262e3a2012-05-22 16:08:167487
7488 request.load_flags = LOAD_NORMAL;
7489
danakj1fd259a02016-04-16 03:17:097490 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:167491 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]2262e3a2012-05-22 16:08:167492
7493 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:237494 MockWrite(
7495 "GET / HTTP/1.1\r\n"
7496 "Host: www.example.org\r\n"
7497 "Connection: keep-alive\r\n\r\n"),
[email protected]2262e3a2012-05-22 16:08:167498 };
7499
7500 MockRead data_reads1[] = {
7501 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
7502 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
7503 MockRead("Content-Length: 10\r\n\r\n"),
7504 MockRead(SYNCHRONOUS, ERR_FAILED),
7505 };
7506
7507 // After the challenge above, the transaction will be restarted using the
7508 // identity from the url (foo, baz) to answer the challenge.
7509 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:237510 MockWrite(
7511 "GET / HTTP/1.1\r\n"
7512 "Host: www.example.org\r\n"
7513 "Connection: keep-alive\r\n"
7514 "Authorization: Basic Zm9vOmJheg==\r\n\r\n"),
[email protected]2262e3a2012-05-22 16:08:167515 };
7516
7517 MockRead data_reads2[] = {
7518 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
7519 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
7520 MockRead("Content-Length: 10\r\n\r\n"),
7521 MockRead(SYNCHRONOUS, ERR_FAILED),
7522 };
7523
7524 // After the challenge above, the transaction will be restarted using the
7525 // identity supplied by the user (foo, bar) to answer the challenge.
7526 MockWrite data_writes3[] = {
bncce36dca22015-04-21 22:11:237527 MockWrite(
7528 "GET / HTTP/1.1\r\n"
7529 "Host: www.example.org\r\n"
7530 "Connection: keep-alive\r\n"
7531 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]2262e3a2012-05-22 16:08:167532 };
7533
7534 MockRead data_reads3[] = {
7535 MockRead("HTTP/1.0 200 OK\r\n"),
7536 MockRead("Content-Length: 100\r\n\r\n"),
7537 MockRead(SYNCHRONOUS, OK),
7538 };
7539
7540 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
7541 data_writes1, arraysize(data_writes1));
7542 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
7543 data_writes2, arraysize(data_writes2));
7544 StaticSocketDataProvider data3(data_reads3, arraysize(data_reads3),
7545 data_writes3, arraysize(data_writes3));
[email protected]bb88e1d32013-05-03 23:11:077546 session_deps_.socket_factory->AddSocketDataProvider(&data1);
7547 session_deps_.socket_factory->AddSocketDataProvider(&data2);
7548 session_deps_.socket_factory->AddSocketDataProvider(&data3);
[email protected]2262e3a2012-05-22 16:08:167549
7550 TestCompletionCallback callback1;
7551
tfarina42834112016-09-22 13:38:207552 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:017553 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2262e3a2012-05-22 16:08:167554
7555 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:017556 EXPECT_THAT(rv, IsOk());
[email protected]2262e3a2012-05-22 16:08:167557
bnc691fda62016-08-12 00:43:167558 EXPECT_TRUE(trans.IsReadyToRestartForAuth());
[email protected]2262e3a2012-05-22 16:08:167559 TestCompletionCallback callback2;
bnc691fda62016-08-12 00:43:167560 rv = trans.RestartWithAuth(AuthCredentials(), callback2.callback());
robpercival214763f2016-07-01 23:27:017561 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2262e3a2012-05-22 16:08:167562 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:017563 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:167564 EXPECT_FALSE(trans.IsReadyToRestartForAuth());
[email protected]2262e3a2012-05-22 16:08:167565
bnc691fda62016-08-12 00:43:167566 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:527567 ASSERT_TRUE(response);
[email protected]2262e3a2012-05-22 16:08:167568 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
7569
7570 TestCompletionCallback callback3;
bnc691fda62016-08-12 00:43:167571 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar), callback3.callback());
robpercival214763f2016-07-01 23:27:017572 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2262e3a2012-05-22 16:08:167573 rv = callback3.WaitForResult();
robpercival214763f2016-07-01 23:27:017574 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:167575 EXPECT_FALSE(trans.IsReadyToRestartForAuth());
[email protected]2262e3a2012-05-22 16:08:167576
bnc691fda62016-08-12 00:43:167577 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:527578 ASSERT_TRUE(response);
[email protected]2262e3a2012-05-22 16:08:167579
7580 // There is no challenge info, since the identity worked.
wezca1070932016-05-26 20:30:527581 EXPECT_FALSE(response->auth_challenge);
[email protected]2262e3a2012-05-22 16:08:167582
7583 EXPECT_EQ(100, response->headers->GetContentLength());
7584
[email protected]ea9dc9a2009-09-05 00:43:327585 // Empty the current queue.
fdoray92e35a72016-06-10 15:54:557586 base::RunLoop().RunUntilIdle();
[email protected]ea9dc9a2009-09-05 00:43:327587}
7588
[email protected]2217aa22013-10-11 03:03:547589
7590// Test the request-challenge-retry sequence for basic auth when there is a
7591// correct identity in the URL, but its use is being suppressed. The identity
7592// from the URL should never be used.
bncd16676a2016-07-20 16:23:017593TEST_F(HttpNetworkTransactionTest, AuthIdentityInURLSuppressed) {
[email protected]2217aa22013-10-11 03:03:547594 HttpRequestInfo request;
7595 request.method = "GET";
bncce36dca22015-04-21 22:11:237596 request.url = GURL("http://foo:[email protected]/");
[email protected]2217aa22013-10-11 03:03:547597 request.load_flags = LOAD_DO_NOT_USE_EMBEDDED_IDENTITY;
7598
danakj1fd259a02016-04-16 03:17:097599 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:167600 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]2217aa22013-10-11 03:03:547601
7602 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:237603 MockWrite(
7604 "GET / HTTP/1.1\r\n"
7605 "Host: www.example.org\r\n"
7606 "Connection: keep-alive\r\n\r\n"),
[email protected]2217aa22013-10-11 03:03:547607 };
7608
7609 MockRead data_reads1[] = {
7610 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
7611 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
7612 MockRead("Content-Length: 10\r\n\r\n"),
7613 MockRead(SYNCHRONOUS, ERR_FAILED),
7614 };
7615
7616 // After the challenge above, the transaction will be restarted using the
7617 // identity supplied by the user, not the one in the URL, to answer the
7618 // challenge.
7619 MockWrite data_writes3[] = {
bncce36dca22015-04-21 22:11:237620 MockWrite(
7621 "GET / HTTP/1.1\r\n"
7622 "Host: www.example.org\r\n"
7623 "Connection: keep-alive\r\n"
7624 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]2217aa22013-10-11 03:03:547625 };
7626
7627 MockRead data_reads3[] = {
7628 MockRead("HTTP/1.0 200 OK\r\n"),
7629 MockRead("Content-Length: 100\r\n\r\n"),
7630 MockRead(SYNCHRONOUS, OK),
7631 };
7632
7633 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
7634 data_writes1, arraysize(data_writes1));
7635 StaticSocketDataProvider data3(data_reads3, arraysize(data_reads3),
7636 data_writes3, arraysize(data_writes3));
7637 session_deps_.socket_factory->AddSocketDataProvider(&data1);
7638 session_deps_.socket_factory->AddSocketDataProvider(&data3);
7639
7640 TestCompletionCallback callback1;
tfarina42834112016-09-22 13:38:207641 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:017642 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2217aa22013-10-11 03:03:547643 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:017644 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:167645 EXPECT_FALSE(trans.IsReadyToRestartForAuth());
[email protected]2217aa22013-10-11 03:03:547646
bnc691fda62016-08-12 00:43:167647 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:527648 ASSERT_TRUE(response);
[email protected]2217aa22013-10-11 03:03:547649 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
7650
7651 TestCompletionCallback callback3;
bnc691fda62016-08-12 00:43:167652 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar), callback3.callback());
robpercival214763f2016-07-01 23:27:017653 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2217aa22013-10-11 03:03:547654 rv = callback3.WaitForResult();
robpercival214763f2016-07-01 23:27:017655 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:167656 EXPECT_FALSE(trans.IsReadyToRestartForAuth());
[email protected]2217aa22013-10-11 03:03:547657
bnc691fda62016-08-12 00:43:167658 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:527659 ASSERT_TRUE(response);
[email protected]2217aa22013-10-11 03:03:547660
7661 // There is no challenge info, since the identity worked.
wezca1070932016-05-26 20:30:527662 EXPECT_FALSE(response->auth_challenge);
[email protected]2217aa22013-10-11 03:03:547663 EXPECT_EQ(100, response->headers->GetContentLength());
7664
7665 // Empty the current queue.
fdoray92e35a72016-06-10 15:54:557666 base::RunLoop().RunUntilIdle();
[email protected]2217aa22013-10-11 03:03:547667}
7668
[email protected]f9ee6b52008-11-08 06:46:237669// Test that previously tried username/passwords for a realm get re-used.
bncd16676a2016-07-20 16:23:017670TEST_F(HttpNetworkTransactionTest, BasicAuthCacheAndPreauth) {
danakj1fd259a02016-04-16 03:17:097671 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]f9ee6b52008-11-08 06:46:237672
7673 // Transaction 1: authenticate (foo, bar) on MyRealm1
7674 {
[email protected]1c773ea12009-04-28 19:58:427675 HttpRequestInfo request;
[email protected]f9ee6b52008-11-08 06:46:237676 request.method = "GET";
bncce36dca22015-04-21 22:11:237677 request.url = GURL("http://www.example.org/x/y/z");
[email protected]f9ee6b52008-11-08 06:46:237678
bnc691fda62016-08-12 00:43:167679 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:277680
[email protected]f9ee6b52008-11-08 06:46:237681 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:237682 MockWrite(
7683 "GET /x/y/z HTTP/1.1\r\n"
7684 "Host: www.example.org\r\n"
7685 "Connection: keep-alive\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:237686 };
7687
7688 MockRead data_reads1[] = {
7689 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
7690 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
7691 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067692 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]f9ee6b52008-11-08 06:46:237693 };
7694
7695 // Resend with authorization (username=foo, password=bar)
7696 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:237697 MockWrite(
7698 "GET /x/y/z HTTP/1.1\r\n"
7699 "Host: www.example.org\r\n"
7700 "Connection: keep-alive\r\n"
7701 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:237702 };
7703
7704 // Sever accepts the authorization.
7705 MockRead data_reads2[] = {
7706 MockRead("HTTP/1.0 200 OK\r\n"),
7707 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067708 MockRead(SYNCHRONOUS, OK),
[email protected]f9ee6b52008-11-08 06:46:237709 };
7710
[email protected]31a2bfe2010-02-09 08:03:397711 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
7712 data_writes1, arraysize(data_writes1));
7713 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
7714 data_writes2, arraysize(data_writes2));
[email protected]bb88e1d32013-05-03 23:11:077715 session_deps_.socket_factory->AddSocketDataProvider(&data1);
7716 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]f9ee6b52008-11-08 06:46:237717
[email protected]49639fa2011-12-20 23:22:417718 TestCompletionCallback callback1;
[email protected]f9ee6b52008-11-08 06:46:237719
tfarina42834112016-09-22 13:38:207720 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:017721 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]f9ee6b52008-11-08 06:46:237722
7723 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:017724 EXPECT_THAT(rv, IsOk());
[email protected]f9ee6b52008-11-08 06:46:237725
bnc691fda62016-08-12 00:43:167726 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:527727 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:047728 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]f9ee6b52008-11-08 06:46:237729
[email protected]49639fa2011-12-20 23:22:417730 TestCompletionCallback callback2;
[email protected]f9ee6b52008-11-08 06:46:237731
bnc691fda62016-08-12 00:43:167732 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar),
7733 callback2.callback());
robpercival214763f2016-07-01 23:27:017734 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]f9ee6b52008-11-08 06:46:237735
7736 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:017737 EXPECT_THAT(rv, IsOk());
[email protected]f9ee6b52008-11-08 06:46:237738
bnc691fda62016-08-12 00:43:167739 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:527740 ASSERT_TRUE(response);
7741 EXPECT_FALSE(response->auth_challenge);
[email protected]f9ee6b52008-11-08 06:46:237742 EXPECT_EQ(100, response->headers->GetContentLength());
7743 }
7744
7745 // ------------------------------------------------------------------------
7746
7747 // Transaction 2: authenticate (foo2, bar2) on MyRealm2
7748 {
[email protected]1c773ea12009-04-28 19:58:427749 HttpRequestInfo request;
[email protected]f9ee6b52008-11-08 06:46:237750 request.method = "GET";
7751 // Note that Transaction 1 was at /x/y/z, so this is in the same
7752 // protection space as MyRealm1.
bncce36dca22015-04-21 22:11:237753 request.url = GURL("http://www.example.org/x/y/a/b");
[email protected]f9ee6b52008-11-08 06:46:237754
bnc691fda62016-08-12 00:43:167755 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:277756
[email protected]f9ee6b52008-11-08 06:46:237757 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:237758 MockWrite(
7759 "GET /x/y/a/b HTTP/1.1\r\n"
7760 "Host: www.example.org\r\n"
7761 "Connection: keep-alive\r\n"
7762 // Send preemptive authorization for MyRealm1
7763 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:237764 };
7765
7766 // The server didn't like the preemptive authorization, and
7767 // challenges us for a different realm (MyRealm2).
7768 MockRead data_reads1[] = {
7769 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
7770 MockRead("WWW-Authenticate: Basic realm=\"MyRealm2\"\r\n"),
7771 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067772 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]f9ee6b52008-11-08 06:46:237773 };
7774
7775 // Resend with authorization for MyRealm2 (username=foo2, password=bar2)
7776 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:237777 MockWrite(
7778 "GET /x/y/a/b HTTP/1.1\r\n"
7779 "Host: www.example.org\r\n"
7780 "Connection: keep-alive\r\n"
7781 "Authorization: Basic Zm9vMjpiYXIy\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:237782 };
7783
7784 // Sever accepts the authorization.
7785 MockRead data_reads2[] = {
7786 MockRead("HTTP/1.0 200 OK\r\n"),
7787 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067788 MockRead(SYNCHRONOUS, OK),
[email protected]f9ee6b52008-11-08 06:46:237789 };
7790
[email protected]31a2bfe2010-02-09 08:03:397791 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
7792 data_writes1, arraysize(data_writes1));
7793 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
7794 data_writes2, arraysize(data_writes2));
[email protected]bb88e1d32013-05-03 23:11:077795 session_deps_.socket_factory->AddSocketDataProvider(&data1);
7796 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]f9ee6b52008-11-08 06:46:237797
[email protected]49639fa2011-12-20 23:22:417798 TestCompletionCallback callback1;
[email protected]f9ee6b52008-11-08 06:46:237799
tfarina42834112016-09-22 13:38:207800 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:017801 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]f9ee6b52008-11-08 06:46:237802
7803 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:017804 EXPECT_THAT(rv, IsOk());
[email protected]f9ee6b52008-11-08 06:46:237805
bnc691fda62016-08-12 00:43:167806 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:527807 ASSERT_TRUE(response);
7808 ASSERT_TRUE(response->auth_challenge);
[email protected]79cb5c12011-09-12 13:12:047809 EXPECT_FALSE(response->auth_challenge->is_proxy);
asanka098c0092016-06-16 20:18:437810 EXPECT_EQ("http://www.example.org",
7811 response->auth_challenge->challenger.Serialize());
[email protected]79cb5c12011-09-12 13:12:047812 EXPECT_EQ("MyRealm2", response->auth_challenge->realm);
aberentbba302d2015-12-03 10:20:197813 EXPECT_EQ(kBasicAuthScheme, response->auth_challenge->scheme);
[email protected]f9ee6b52008-11-08 06:46:237814
[email protected]49639fa2011-12-20 23:22:417815 TestCompletionCallback callback2;
[email protected]f9ee6b52008-11-08 06:46:237816
bnc691fda62016-08-12 00:43:167817 rv = trans.RestartWithAuth(AuthCredentials(kFoo2, kBar2),
7818 callback2.callback());
robpercival214763f2016-07-01 23:27:017819 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]f9ee6b52008-11-08 06:46:237820
7821 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:017822 EXPECT_THAT(rv, IsOk());
[email protected]f9ee6b52008-11-08 06:46:237823
bnc691fda62016-08-12 00:43:167824 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:527825 ASSERT_TRUE(response);
7826 EXPECT_FALSE(response->auth_challenge);
[email protected]f9ee6b52008-11-08 06:46:237827 EXPECT_EQ(100, response->headers->GetContentLength());
7828 }
7829
7830 // ------------------------------------------------------------------------
7831
7832 // Transaction 3: Resend a request in MyRealm's protection space --
7833 // succeed with preemptive authorization.
7834 {
[email protected]1c773ea12009-04-28 19:58:427835 HttpRequestInfo request;
[email protected]f9ee6b52008-11-08 06:46:237836 request.method = "GET";
bncce36dca22015-04-21 22:11:237837 request.url = GURL("http://www.example.org/x/y/z2");
[email protected]f9ee6b52008-11-08 06:46:237838
bnc691fda62016-08-12 00:43:167839 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:277840
[email protected]f9ee6b52008-11-08 06:46:237841 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:237842 MockWrite(
7843 "GET /x/y/z2 HTTP/1.1\r\n"
7844 "Host: www.example.org\r\n"
7845 "Connection: keep-alive\r\n"
7846 // The authorization for MyRealm1 gets sent preemptively
7847 // (since the url is in the same protection space)
7848 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:237849 };
7850
7851 // Sever accepts the preemptive authorization
7852 MockRead data_reads1[] = {
7853 MockRead("HTTP/1.0 200 OK\r\n"),
7854 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067855 MockRead(SYNCHRONOUS, OK),
[email protected]f9ee6b52008-11-08 06:46:237856 };
7857
[email protected]31a2bfe2010-02-09 08:03:397858 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
7859 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:077860 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]f9ee6b52008-11-08 06:46:237861
[email protected]49639fa2011-12-20 23:22:417862 TestCompletionCallback callback1;
[email protected]f9ee6b52008-11-08 06:46:237863
tfarina42834112016-09-22 13:38:207864 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:017865 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]f9ee6b52008-11-08 06:46:237866
7867 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:017868 EXPECT_THAT(rv, IsOk());
[email protected]f9ee6b52008-11-08 06:46:237869
bnc691fda62016-08-12 00:43:167870 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:527871 ASSERT_TRUE(response);
[email protected]f9ee6b52008-11-08 06:46:237872
wezca1070932016-05-26 20:30:527873 EXPECT_FALSE(response->auth_challenge);
[email protected]f9ee6b52008-11-08 06:46:237874 EXPECT_EQ(100, response->headers->GetContentLength());
7875 }
7876
7877 // ------------------------------------------------------------------------
7878
7879 // Transaction 4: request another URL in MyRealm (however the
7880 // url is not known to belong to the protection space, so no pre-auth).
7881 {
[email protected]1c773ea12009-04-28 19:58:427882 HttpRequestInfo request;
[email protected]f9ee6b52008-11-08 06:46:237883 request.method = "GET";
bncce36dca22015-04-21 22:11:237884 request.url = GURL("http://www.example.org/x/1");
[email protected]f9ee6b52008-11-08 06:46:237885
bnc691fda62016-08-12 00:43:167886 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:277887
[email protected]f9ee6b52008-11-08 06:46:237888 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:237889 MockWrite(
7890 "GET /x/1 HTTP/1.1\r\n"
7891 "Host: www.example.org\r\n"
7892 "Connection: keep-alive\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:237893 };
7894
7895 MockRead data_reads1[] = {
7896 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
7897 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
7898 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067899 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]f9ee6b52008-11-08 06:46:237900 };
7901
7902 // Resend with authorization from MyRealm's cache.
7903 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:237904 MockWrite(
7905 "GET /x/1 HTTP/1.1\r\n"
7906 "Host: www.example.org\r\n"
7907 "Connection: keep-alive\r\n"
7908 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:237909 };
7910
7911 // Sever accepts the authorization.
7912 MockRead data_reads2[] = {
7913 MockRead("HTTP/1.0 200 OK\r\n"),
7914 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067915 MockRead(SYNCHRONOUS, OK),
[email protected]f9ee6b52008-11-08 06:46:237916 };
7917
[email protected]31a2bfe2010-02-09 08:03:397918 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
7919 data_writes1, arraysize(data_writes1));
7920 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
7921 data_writes2, arraysize(data_writes2));
[email protected]bb88e1d32013-05-03 23:11:077922 session_deps_.socket_factory->AddSocketDataProvider(&data1);
7923 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]f9ee6b52008-11-08 06:46:237924
[email protected]49639fa2011-12-20 23:22:417925 TestCompletionCallback callback1;
[email protected]f9ee6b52008-11-08 06:46:237926
tfarina42834112016-09-22 13:38:207927 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:017928 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]f9ee6b52008-11-08 06:46:237929
7930 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:017931 EXPECT_THAT(rv, IsOk());
[email protected]f9ee6b52008-11-08 06:46:237932
bnc691fda62016-08-12 00:43:167933 EXPECT_TRUE(trans.IsReadyToRestartForAuth());
[email protected]49639fa2011-12-20 23:22:417934 TestCompletionCallback callback2;
bnc691fda62016-08-12 00:43:167935 rv = trans.RestartWithAuth(AuthCredentials(), callback2.callback());
robpercival214763f2016-07-01 23:27:017936 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]0757e7702009-03-27 04:00:227937 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:017938 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:167939 EXPECT_FALSE(trans.IsReadyToRestartForAuth());
[email protected]0757e7702009-03-27 04:00:227940
bnc691fda62016-08-12 00:43:167941 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:527942 ASSERT_TRUE(response);
7943 EXPECT_FALSE(response->auth_challenge);
[email protected]f9ee6b52008-11-08 06:46:237944 EXPECT_EQ(100, response->headers->GetContentLength());
7945 }
7946
7947 // ------------------------------------------------------------------------
7948
7949 // Transaction 5: request a URL in MyRealm, but the server rejects the
7950 // cached identity. Should invalidate and re-prompt.
7951 {
[email protected]1c773ea12009-04-28 19:58:427952 HttpRequestInfo request;
[email protected]f9ee6b52008-11-08 06:46:237953 request.method = "GET";
bncce36dca22015-04-21 22:11:237954 request.url = GURL("http://www.example.org/p/q/t");
[email protected]f9ee6b52008-11-08 06:46:237955
bnc691fda62016-08-12 00:43:167956 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:277957
[email protected]f9ee6b52008-11-08 06:46:237958 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:237959 MockWrite(
7960 "GET /p/q/t HTTP/1.1\r\n"
7961 "Host: www.example.org\r\n"
7962 "Connection: keep-alive\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:237963 };
7964
7965 MockRead data_reads1[] = {
7966 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
7967 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
7968 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067969 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]f9ee6b52008-11-08 06:46:237970 };
7971
7972 // Resend with authorization from cache for MyRealm.
7973 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:237974 MockWrite(
7975 "GET /p/q/t HTTP/1.1\r\n"
7976 "Host: www.example.org\r\n"
7977 "Connection: keep-alive\r\n"
7978 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:237979 };
7980
7981 // Sever rejects the authorization.
7982 MockRead data_reads2[] = {
7983 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
7984 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
7985 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067986 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]f9ee6b52008-11-08 06:46:237987 };
7988
7989 // At this point we should prompt for new credentials for MyRealm.
7990 // Restart with username=foo3, password=foo4.
7991 MockWrite data_writes3[] = {
bncce36dca22015-04-21 22:11:237992 MockWrite(
7993 "GET /p/q/t HTTP/1.1\r\n"
7994 "Host: www.example.org\r\n"
7995 "Connection: keep-alive\r\n"
7996 "Authorization: Basic Zm9vMzpiYXIz\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:237997 };
7998
7999 // Sever accepts the authorization.
8000 MockRead data_reads3[] = {
8001 MockRead("HTTP/1.0 200 OK\r\n"),
8002 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:068003 MockRead(SYNCHRONOUS, OK),
[email protected]f9ee6b52008-11-08 06:46:238004 };
8005
[email protected]31a2bfe2010-02-09 08:03:398006 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
8007 data_writes1, arraysize(data_writes1));
8008 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
8009 data_writes2, arraysize(data_writes2));
8010 StaticSocketDataProvider data3(data_reads3, arraysize(data_reads3),
8011 data_writes3, arraysize(data_writes3));
[email protected]bb88e1d32013-05-03 23:11:078012 session_deps_.socket_factory->AddSocketDataProvider(&data1);
8013 session_deps_.socket_factory->AddSocketDataProvider(&data2);
8014 session_deps_.socket_factory->AddSocketDataProvider(&data3);
[email protected]f9ee6b52008-11-08 06:46:238015
[email protected]49639fa2011-12-20 23:22:418016 TestCompletionCallback callback1;
[email protected]f9ee6b52008-11-08 06:46:238017
tfarina42834112016-09-22 13:38:208018 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:018019 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]f9ee6b52008-11-08 06:46:238020
8021 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:018022 EXPECT_THAT(rv, IsOk());
[email protected]f9ee6b52008-11-08 06:46:238023
bnc691fda62016-08-12 00:43:168024 EXPECT_TRUE(trans.IsReadyToRestartForAuth());
[email protected]49639fa2011-12-20 23:22:418025 TestCompletionCallback callback2;
bnc691fda62016-08-12 00:43:168026 rv = trans.RestartWithAuth(AuthCredentials(), callback2.callback());
robpercival214763f2016-07-01 23:27:018027 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]0757e7702009-03-27 04:00:228028 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:018029 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:168030 EXPECT_FALSE(trans.IsReadyToRestartForAuth());
[email protected]0757e7702009-03-27 04:00:228031
bnc691fda62016-08-12 00:43:168032 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:528033 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:048034 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]f9ee6b52008-11-08 06:46:238035
[email protected]49639fa2011-12-20 23:22:418036 TestCompletionCallback callback3;
[email protected]f9ee6b52008-11-08 06:46:238037
bnc691fda62016-08-12 00:43:168038 rv = trans.RestartWithAuth(AuthCredentials(kFoo3, kBar3),
8039 callback3.callback());
robpercival214763f2016-07-01 23:27:018040 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]f9ee6b52008-11-08 06:46:238041
[email protected]0757e7702009-03-27 04:00:228042 rv = callback3.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 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:528046 ASSERT_TRUE(response);
8047 EXPECT_FALSE(response->auth_challenge);
[email protected]f9ee6b52008-11-08 06:46:238048 EXPECT_EQ(100, response->headers->GetContentLength());
8049 }
8050}
[email protected]89ceba9a2009-03-21 03:46:068051
[email protected]3c32c5f2010-05-18 15:18:128052// Tests that nonce count increments when multiple auth attempts
8053// are started with the same nonce.
bncd16676a2016-07-20 16:23:018054TEST_F(HttpNetworkTransactionTest, DigestPreAuthNonceCount) {
[email protected]54fea2562010-11-17 14:40:448055 HttpAuthHandlerDigest::Factory* digest_factory =
8056 new HttpAuthHandlerDigest::Factory();
8057 HttpAuthHandlerDigest::FixedNonceGenerator* nonce_generator =
8058 new HttpAuthHandlerDigest::FixedNonceGenerator("0123456789abcdef");
8059 digest_factory->set_nonce_generator(nonce_generator);
[email protected]bb88e1d32013-05-03 23:11:078060 session_deps_.http_auth_handler_factory.reset(digest_factory);
danakj1fd259a02016-04-16 03:17:098061 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]3c32c5f2010-05-18 15:18:128062
8063 // Transaction 1: authenticate (foo, bar) on MyRealm1
8064 {
[email protected]3c32c5f2010-05-18 15:18:128065 HttpRequestInfo request;
8066 request.method = "GET";
bncce36dca22015-04-21 22:11:238067 request.url = GURL("http://www.example.org/x/y/z");
[email protected]3c32c5f2010-05-18 15:18:128068
bnc691fda62016-08-12 00:43:168069 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:278070
[email protected]3c32c5f2010-05-18 15:18:128071 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:238072 MockWrite(
8073 "GET /x/y/z HTTP/1.1\r\n"
8074 "Host: www.example.org\r\n"
8075 "Connection: keep-alive\r\n\r\n"),
[email protected]3c32c5f2010-05-18 15:18:128076 };
8077
8078 MockRead data_reads1[] = {
8079 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
8080 MockRead("WWW-Authenticate: Digest realm=\"digestive\", nonce=\"OU812\", "
8081 "algorithm=MD5, qop=\"auth\"\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:068082 MockRead(SYNCHRONOUS, OK),
[email protected]3c32c5f2010-05-18 15:18:128083 };
8084
8085 // Resend with authorization (username=foo, password=bar)
8086 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:238087 MockWrite(
8088 "GET /x/y/z HTTP/1.1\r\n"
8089 "Host: www.example.org\r\n"
8090 "Connection: keep-alive\r\n"
8091 "Authorization: Digest username=\"foo\", realm=\"digestive\", "
8092 "nonce=\"OU812\", uri=\"/x/y/z\", algorithm=MD5, "
8093 "response=\"03ffbcd30add722589c1de345d7a927f\", qop=auth, "
8094 "nc=00000001, cnonce=\"0123456789abcdef\"\r\n\r\n"),
[email protected]3c32c5f2010-05-18 15:18:128095 };
8096
8097 // Sever accepts the authorization.
8098 MockRead data_reads2[] = {
zmo9528c9f42015-08-04 22:12:088099 MockRead("HTTP/1.0 200 OK\r\n"),
8100 MockRead(SYNCHRONOUS, OK),
[email protected]3c32c5f2010-05-18 15:18:128101 };
8102
8103 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
8104 data_writes1, arraysize(data_writes1));
8105 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
8106 data_writes2, arraysize(data_writes2));
[email protected]bb88e1d32013-05-03 23:11:078107 session_deps_.socket_factory->AddSocketDataProvider(&data1);
8108 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]3c32c5f2010-05-18 15:18:128109
[email protected]49639fa2011-12-20 23:22:418110 TestCompletionCallback callback1;
[email protected]3c32c5f2010-05-18 15:18:128111
tfarina42834112016-09-22 13:38:208112 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:018113 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]3c32c5f2010-05-18 15:18:128114
8115 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:018116 EXPECT_THAT(rv, IsOk());
[email protected]3c32c5f2010-05-18 15:18:128117
bnc691fda62016-08-12 00:43:168118 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:528119 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:048120 EXPECT_TRUE(CheckDigestServerAuth(response->auth_challenge.get()));
[email protected]3c32c5f2010-05-18 15:18:128121
[email protected]49639fa2011-12-20 23:22:418122 TestCompletionCallback callback2;
[email protected]3c32c5f2010-05-18 15:18:128123
bnc691fda62016-08-12 00:43:168124 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar),
8125 callback2.callback());
robpercival214763f2016-07-01 23:27:018126 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]3c32c5f2010-05-18 15:18:128127
8128 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:018129 EXPECT_THAT(rv, IsOk());
[email protected]3c32c5f2010-05-18 15:18:128130
bnc691fda62016-08-12 00:43:168131 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:528132 ASSERT_TRUE(response);
8133 EXPECT_FALSE(response->auth_challenge);
[email protected]3c32c5f2010-05-18 15:18:128134 }
8135
8136 // ------------------------------------------------------------------------
8137
8138 // Transaction 2: Request another resource in digestive's protection space.
8139 // This will preemptively add an Authorization header which should have an
8140 // "nc" value of 2 (as compared to 1 in the first use.
8141 {
[email protected]3c32c5f2010-05-18 15:18:128142 HttpRequestInfo request;
8143 request.method = "GET";
8144 // Note that Transaction 1 was at /x/y/z, so this is in the same
8145 // protection space as digest.
bncce36dca22015-04-21 22:11:238146 request.url = GURL("http://www.example.org/x/y/a/b");
[email protected]3c32c5f2010-05-18 15:18:128147
bnc691fda62016-08-12 00:43:168148 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:278149
[email protected]3c32c5f2010-05-18 15:18:128150 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:238151 MockWrite(
8152 "GET /x/y/a/b HTTP/1.1\r\n"
8153 "Host: www.example.org\r\n"
8154 "Connection: keep-alive\r\n"
8155 "Authorization: Digest username=\"foo\", realm=\"digestive\", "
8156 "nonce=\"OU812\", uri=\"/x/y/a/b\", algorithm=MD5, "
8157 "response=\"d6f9a2c07d1c5df7b89379dca1269b35\", qop=auth, "
8158 "nc=00000002, cnonce=\"0123456789abcdef\"\r\n\r\n"),
[email protected]3c32c5f2010-05-18 15:18:128159 };
8160
8161 // Sever accepts the authorization.
8162 MockRead data_reads1[] = {
8163 MockRead("HTTP/1.0 200 OK\r\n"),
8164 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:068165 MockRead(SYNCHRONOUS, OK),
[email protected]3c32c5f2010-05-18 15:18:128166 };
8167
8168 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
8169 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:078170 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]3c32c5f2010-05-18 15:18:128171
[email protected]49639fa2011-12-20 23:22:418172 TestCompletionCallback callback1;
[email protected]3c32c5f2010-05-18 15:18:128173
tfarina42834112016-09-22 13:38:208174 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:018175 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]3c32c5f2010-05-18 15:18:128176
8177 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:018178 EXPECT_THAT(rv, IsOk());
[email protected]3c32c5f2010-05-18 15:18:128179
bnc691fda62016-08-12 00:43:168180 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:528181 ASSERT_TRUE(response);
8182 EXPECT_FALSE(response->auth_challenge);
[email protected]3c32c5f2010-05-18 15:18:128183 }
8184}
8185
[email protected]89ceba9a2009-03-21 03:46:068186// Test the ResetStateForRestart() private method.
bncd16676a2016-07-20 16:23:018187TEST_F(HttpNetworkTransactionTest, ResetStateForRestart) {
[email protected]89ceba9a2009-03-21 03:46:068188 // Create a transaction (the dependencies aren't important).
danakj1fd259a02016-04-16 03:17:098189 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:168190 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]89ceba9a2009-03-21 03:46:068191
8192 // Setup some state (which we expect ResetStateForRestart() will clear).
bnc691fda62016-08-12 00:43:168193 trans.read_buf_ = new IOBuffer(15);
8194 trans.read_buf_len_ = 15;
8195 trans.request_headers_.SetHeader("Authorization", "NTLM");
[email protected]89ceba9a2009-03-21 03:46:068196
8197 // Setup state in response_
bnc691fda62016-08-12 00:43:168198 HttpResponseInfo* response = &trans.response_;
[email protected]0877e3d2009-10-17 22:29:578199 response->auth_challenge = new AuthChallengeInfo();
[email protected]70d66502011-09-23 00:55:088200 response->ssl_info.cert_status = static_cast<CertStatus>(-1); // Nonsensical.
[email protected]0877e3d2009-10-17 22:29:578201 response->response_time = base::Time::Now();
8202 response->was_cached = true; // (Wouldn't ever actually be true...)
[email protected]89ceba9a2009-03-21 03:46:068203
8204 { // Setup state for response_.vary_data
8205 HttpRequestInfo request;
8206 std::string temp("HTTP/1.1 200 OK\nVary: foo, bar\n\n");
8207 std::replace(temp.begin(), temp.end(), '\n', '\0');
[email protected]ad8e04a2010-11-01 04:16:278208 scoped_refptr<HttpResponseHeaders> headers(new HttpResponseHeaders(temp));
[email protected]8c76ae22010-04-20 22:15:438209 request.extra_headers.SetHeader("Foo", "1");
8210 request.extra_headers.SetHeader("bar", "23");
[email protected]90499482013-06-01 00:39:508211 EXPECT_TRUE(response->vary_data.Init(request, *headers.get()));
[email protected]89ceba9a2009-03-21 03:46:068212 }
8213
8214 // Cause the above state to be reset.
bnc691fda62016-08-12 00:43:168215 trans.ResetStateForRestart();
[email protected]89ceba9a2009-03-21 03:46:068216
8217 // Verify that the state that needed to be reset, has been reset.
bnc691fda62016-08-12 00:43:168218 EXPECT_FALSE(trans.read_buf_);
8219 EXPECT_EQ(0, trans.read_buf_len_);
8220 EXPECT_TRUE(trans.request_headers_.IsEmpty());
wezca1070932016-05-26 20:30:528221 EXPECT_FALSE(response->auth_challenge);
8222 EXPECT_FALSE(response->headers);
[email protected]34f40942010-10-04 00:34:048223 EXPECT_FALSE(response->was_cached);
[email protected]70d66502011-09-23 00:55:088224 EXPECT_EQ(0U, response->ssl_info.cert_status);
[email protected]0877e3d2009-10-17 22:29:578225 EXPECT_FALSE(response->vary_data.is_valid());
[email protected]89ceba9a2009-03-21 03:46:068226}
8227
[email protected]bacff652009-03-31 17:50:338228// Test HTTPS connections to a site with a bad certificate
bncd16676a2016-07-20 16:23:018229TEST_F(HttpNetworkTransactionTest, HTTPSBadCertificate) {
[email protected]bacff652009-03-31 17:50:338230 HttpRequestInfo request;
8231 request.method = "GET";
bncce36dca22015-04-21 22:11:238232 request.url = GURL("https://www.example.org/");
[email protected]bacff652009-03-31 17:50:338233
danakj1fd259a02016-04-16 03:17:098234 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:168235 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:278236
[email protected]bacff652009-03-31 17:50:338237 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:238238 MockWrite(
8239 "GET / HTTP/1.1\r\n"
8240 "Host: www.example.org\r\n"
8241 "Connection: keep-alive\r\n\r\n"),
[email protected]bacff652009-03-31 17:50:338242 };
8243
8244 MockRead data_reads[] = {
8245 MockRead("HTTP/1.0 200 OK\r\n"),
8246 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
8247 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:068248 MockRead(SYNCHRONOUS, OK),
[email protected]bacff652009-03-31 17:50:338249 };
8250
[email protected]5ecc992a42009-11-11 01:41:598251 StaticSocketDataProvider ssl_bad_certificate;
[email protected]31a2bfe2010-02-09 08:03:398252 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
8253 data_writes, arraysize(data_writes));
[email protected]8ddf8322012-02-23 18:08:068254 SSLSocketDataProvider ssl_bad(ASYNC, ERR_CERT_AUTHORITY_INVALID);
8255 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bacff652009-03-31 17:50:338256
[email protected]bb88e1d32013-05-03 23:11:078257 session_deps_.socket_factory->AddSocketDataProvider(&ssl_bad_certificate);
8258 session_deps_.socket_factory->AddSocketDataProvider(&data);
8259 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_bad);
8260 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]bacff652009-03-31 17:50:338261
[email protected]49639fa2011-12-20 23:22:418262 TestCompletionCallback callback;
[email protected]bacff652009-03-31 17:50:338263
tfarina42834112016-09-22 13:38:208264 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:018265 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]bacff652009-03-31 17:50:338266
8267 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:018268 EXPECT_THAT(rv, IsError(ERR_CERT_AUTHORITY_INVALID));
[email protected]bacff652009-03-31 17:50:338269
bnc691fda62016-08-12 00:43:168270 rv = trans.RestartIgnoringLastError(callback.callback());
robpercival214763f2016-07-01 23:27:018271 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]bacff652009-03-31 17:50:338272
8273 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:018274 EXPECT_THAT(rv, IsOk());
[email protected]bacff652009-03-31 17:50:338275
bnc691fda62016-08-12 00:43:168276 const HttpResponseInfo* response = trans.GetResponseInfo();
[email protected]bacff652009-03-31 17:50:338277
wezca1070932016-05-26 20:30:528278 ASSERT_TRUE(response);
[email protected]bacff652009-03-31 17:50:338279 EXPECT_EQ(100, response->headers->GetContentLength());
8280}
8281
8282// Test HTTPS connections to a site with a bad certificate, going through a
8283// proxy
bncd16676a2016-07-20 16:23:018284TEST_F(HttpNetworkTransactionTest, HTTPSBadCertificateViaProxy) {
rdsmith82957ad2015-09-16 19:42:038285 session_deps_.proxy_service = ProxyService::CreateFixed("myproxy:70");
[email protected]bacff652009-03-31 17:50:338286
8287 HttpRequestInfo request;
8288 request.method = "GET";
bncce36dca22015-04-21 22:11:238289 request.url = GURL("https://www.example.org/");
[email protected]bacff652009-03-31 17:50:338290
8291 MockWrite proxy_writes[] = {
rsleevidb16bb02015-11-12 23:47:178292 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
8293 "Host: www.example.org:443\r\n"
8294 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]bacff652009-03-31 17:50:338295 };
8296
8297 MockRead proxy_reads[] = {
8298 MockRead("HTTP/1.0 200 Connected\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:068299 MockRead(SYNCHRONOUS, OK)
[email protected]bacff652009-03-31 17:50:338300 };
8301
8302 MockWrite data_writes[] = {
rsleevidb16bb02015-11-12 23:47:178303 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
8304 "Host: www.example.org:443\r\n"
8305 "Proxy-Connection: keep-alive\r\n\r\n"),
8306 MockWrite("GET / HTTP/1.1\r\n"
8307 "Host: www.example.org\r\n"
8308 "Connection: keep-alive\r\n\r\n"),
[email protected]bacff652009-03-31 17:50:338309 };
8310
8311 MockRead data_reads[] = {
8312 MockRead("HTTP/1.0 200 Connected\r\n\r\n"),
8313 MockRead("HTTP/1.0 200 OK\r\n"),
8314 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
8315 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:068316 MockRead(SYNCHRONOUS, OK),
[email protected]bacff652009-03-31 17:50:338317 };
8318
[email protected]31a2bfe2010-02-09 08:03:398319 StaticSocketDataProvider ssl_bad_certificate(
8320 proxy_reads, arraysize(proxy_reads),
8321 proxy_writes, arraysize(proxy_writes));
8322 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
8323 data_writes, arraysize(data_writes));
[email protected]8ddf8322012-02-23 18:08:068324 SSLSocketDataProvider ssl_bad(ASYNC, ERR_CERT_AUTHORITY_INVALID);
8325 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bacff652009-03-31 17:50:338326
[email protected]bb88e1d32013-05-03 23:11:078327 session_deps_.socket_factory->AddSocketDataProvider(&ssl_bad_certificate);
8328 session_deps_.socket_factory->AddSocketDataProvider(&data);
8329 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_bad);
8330 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]bacff652009-03-31 17:50:338331
[email protected]49639fa2011-12-20 23:22:418332 TestCompletionCallback callback;
[email protected]bacff652009-03-31 17:50:338333
8334 for (int i = 0; i < 2; i++) {
[email protected]bb88e1d32013-05-03 23:11:078335 session_deps_.socket_factory->ResetNextMockIndexes();
[email protected]bacff652009-03-31 17:50:338336
danakj1fd259a02016-04-16 03:17:098337 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:168338 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]bacff652009-03-31 17:50:338339
tfarina42834112016-09-22 13:38:208340 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:018341 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]bacff652009-03-31 17:50:338342
8343 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:018344 EXPECT_THAT(rv, IsError(ERR_CERT_AUTHORITY_INVALID));
[email protected]bacff652009-03-31 17:50:338345
bnc691fda62016-08-12 00:43:168346 rv = trans.RestartIgnoringLastError(callback.callback());
robpercival214763f2016-07-01 23:27:018347 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]bacff652009-03-31 17:50:338348
8349 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:018350 EXPECT_THAT(rv, IsOk());
[email protected]bacff652009-03-31 17:50:338351
bnc691fda62016-08-12 00:43:168352 const HttpResponseInfo* response = trans.GetResponseInfo();
[email protected]bacff652009-03-31 17:50:338353
wezca1070932016-05-26 20:30:528354 ASSERT_TRUE(response);
[email protected]bacff652009-03-31 17:50:338355 EXPECT_EQ(100, response->headers->GetContentLength());
8356 }
8357}
8358
[email protected]2df19bb2010-08-25 20:13:468359
8360// Test HTTPS connections to a site, going through an HTTPS proxy
bncd16676a2016-07-20 16:23:018361TEST_F(HttpNetworkTransactionTest, HTTPSViaHttpsProxy) {
rdsmith82957ad2015-09-16 19:42:038362 session_deps_.proxy_service =
8363 ProxyService::CreateFixedFromPacResult("HTTPS proxy:70");
vishal.b62985ca92015-04-17 08:45:518364 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:078365 session_deps_.net_log = &net_log;
[email protected]2df19bb2010-08-25 20:13:468366
8367 HttpRequestInfo request;
8368 request.method = "GET";
bncce36dca22015-04-21 22:11:238369 request.url = GURL("https://www.example.org/");
[email protected]2df19bb2010-08-25 20:13:468370
8371 MockWrite data_writes[] = {
rsleevidb16bb02015-11-12 23:47:178372 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
8373 "Host: www.example.org:443\r\n"
8374 "Proxy-Connection: keep-alive\r\n\r\n"),
8375 MockWrite("GET / HTTP/1.1\r\n"
8376 "Host: www.example.org\r\n"
8377 "Connection: keep-alive\r\n\r\n"),
[email protected]2df19bb2010-08-25 20:13:468378 };
8379
8380 MockRead data_reads[] = {
8381 MockRead("HTTP/1.0 200 Connected\r\n\r\n"),
8382 MockRead("HTTP/1.1 200 OK\r\n"),
8383 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
8384 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:068385 MockRead(SYNCHRONOUS, OK),
[email protected]2df19bb2010-08-25 20:13:468386 };
8387
8388 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
8389 data_writes, arraysize(data_writes));
[email protected]8ddf8322012-02-23 18:08:068390 SSLSocketDataProvider proxy_ssl(ASYNC, OK); // SSL to the proxy
8391 SSLSocketDataProvider tunnel_ssl(ASYNC, OK); // SSL through the tunnel
[email protected]2df19bb2010-08-25 20:13:468392
[email protected]bb88e1d32013-05-03 23:11:078393 session_deps_.socket_factory->AddSocketDataProvider(&data);
8394 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy_ssl);
8395 session_deps_.socket_factory->AddSSLSocketDataProvider(&tunnel_ssl);
[email protected]2df19bb2010-08-25 20:13:468396
[email protected]49639fa2011-12-20 23:22:418397 TestCompletionCallback callback;
[email protected]2df19bb2010-08-25 20:13:468398
danakj1fd259a02016-04-16 03:17:098399 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:168400 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]2df19bb2010-08-25 20:13:468401
tfarina42834112016-09-22 13:38:208402 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:018403 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2df19bb2010-08-25 20:13:468404
8405 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:018406 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:168407 const HttpResponseInfo* response = trans.GetResponseInfo();
[email protected]2df19bb2010-08-25 20:13:468408
wezca1070932016-05-26 20:30:528409 ASSERT_TRUE(response);
[email protected]2df19bb2010-08-25 20:13:468410
tbansal2ecbbc72016-10-06 17:15:478411 EXPECT_TRUE(response->proxy_server.is_https());
[email protected]2df19bb2010-08-25 20:13:468412 EXPECT_TRUE(response->headers->IsKeepAlive());
8413 EXPECT_EQ(200, response->headers->response_code());
8414 EXPECT_EQ(100, response->headers->GetContentLength());
8415 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
[email protected]029c83b62013-01-24 05:28:208416
8417 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:168418 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]029c83b62013-01-24 05:28:208419 TestLoadTimingNotReusedWithPac(load_timing_info,
8420 CONNECT_TIMING_HAS_SSL_TIMES);
[email protected]2df19bb2010-08-25 20:13:468421}
8422
[email protected]511f6f52010-12-17 03:58:298423// Test an HTTPS Proxy's ability to redirect a CONNECT request
bncd16676a2016-07-20 16:23:018424TEST_F(HttpNetworkTransactionTest, RedirectOfHttpsConnectViaHttpsProxy) {
rdsmith82957ad2015-09-16 19:42:038425 session_deps_.proxy_service =
8426 ProxyService::CreateFixedFromPacResult("HTTPS proxy:70");
vishal.b62985ca92015-04-17 08:45:518427 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:078428 session_deps_.net_log = &net_log;
[email protected]511f6f52010-12-17 03:58:298429
8430 HttpRequestInfo request;
8431 request.method = "GET";
bncce36dca22015-04-21 22:11:238432 request.url = GURL("https://www.example.org/");
[email protected]511f6f52010-12-17 03:58:298433
8434 MockWrite data_writes[] = {
rsleevidb16bb02015-11-12 23:47:178435 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
8436 "Host: www.example.org:443\r\n"
8437 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]511f6f52010-12-17 03:58:298438 };
8439
8440 MockRead data_reads[] = {
8441 MockRead("HTTP/1.1 302 Redirect\r\n"),
8442 MockRead("Location: http://login.example.com/\r\n"),
8443 MockRead("Content-Length: 0\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:068444 MockRead(SYNCHRONOUS, OK),
[email protected]511f6f52010-12-17 03:58:298445 };
8446
8447 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
8448 data_writes, arraysize(data_writes));
[email protected]8ddf8322012-02-23 18:08:068449 SSLSocketDataProvider proxy_ssl(ASYNC, OK); // SSL to the proxy
[email protected]511f6f52010-12-17 03:58:298450
[email protected]bb88e1d32013-05-03 23:11:078451 session_deps_.socket_factory->AddSocketDataProvider(&data);
8452 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy_ssl);
[email protected]511f6f52010-12-17 03:58:298453
[email protected]49639fa2011-12-20 23:22:418454 TestCompletionCallback callback;
[email protected]511f6f52010-12-17 03:58:298455
danakj1fd259a02016-04-16 03:17:098456 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:168457 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]511f6f52010-12-17 03:58:298458
tfarina42834112016-09-22 13:38:208459 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:018460 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]511f6f52010-12-17 03:58:298461
8462 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:018463 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:168464 const HttpResponseInfo* response = trans.GetResponseInfo();
[email protected]511f6f52010-12-17 03:58:298465
wezca1070932016-05-26 20:30:528466 ASSERT_TRUE(response);
[email protected]511f6f52010-12-17 03:58:298467
8468 EXPECT_EQ(302, response->headers->response_code());
8469 std::string url;
8470 EXPECT_TRUE(response->headers->IsRedirect(&url));
8471 EXPECT_EQ("http://login.example.com/", url);
[email protected]029c83b62013-01-24 05:28:208472
8473 // In the case of redirects from proxies, HttpNetworkTransaction returns
8474 // timing for the proxy connection instead of the connection to the host,
8475 // and no send / receive times.
8476 // See HttpNetworkTransaction::OnHttpsProxyTunnelResponse.
8477 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:168478 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]029c83b62013-01-24 05:28:208479
8480 EXPECT_FALSE(load_timing_info.socket_reused);
mikecironef22f9812016-10-04 03:40:198481 EXPECT_NE(NetLogSource::kInvalidId, load_timing_info.socket_log_id);
[email protected]029c83b62013-01-24 05:28:208482
8483 EXPECT_FALSE(load_timing_info.proxy_resolve_start.is_null());
8484 EXPECT_LE(load_timing_info.proxy_resolve_start,
8485 load_timing_info.proxy_resolve_end);
8486 EXPECT_LE(load_timing_info.proxy_resolve_end,
8487 load_timing_info.connect_timing.connect_start);
8488 ExpectConnectTimingHasTimes(
8489 load_timing_info.connect_timing,
8490 CONNECT_TIMING_HAS_DNS_TIMES | CONNECT_TIMING_HAS_SSL_TIMES);
8491
8492 EXPECT_TRUE(load_timing_info.send_start.is_null());
8493 EXPECT_TRUE(load_timing_info.send_end.is_null());
8494 EXPECT_TRUE(load_timing_info.receive_headers_end.is_null());
[email protected]511f6f52010-12-17 03:58:298495}
8496
8497// Test an HTTPS (SPDY) Proxy's ability to redirect a CONNECT request
bncd16676a2016-07-20 16:23:018498TEST_F(HttpNetworkTransactionTest, RedirectOfHttpsConnectViaSpdyProxy) {
rdsmith82957ad2015-09-16 19:42:038499 session_deps_.proxy_service = ProxyService::CreateFixed("https://proxy:70");
[email protected]511f6f52010-12-17 03:58:298500
8501 HttpRequestInfo request;
8502 request.method = "GET";
bncce36dca22015-04-21 22:11:238503 request.url = GURL("https://www.example.org/");
[email protected]511f6f52010-12-17 03:58:298504
bncdf80d44fd2016-07-15 20:27:418505 SpdySerializedFrame conn(spdy_util_.ConstructSpdyConnect(
bncce36dca22015-04-21 22:11:238506 NULL, 0, 1, LOWEST, HostPortPair("www.example.org", 443)));
bncdf80d44fd2016-07-15 20:27:418507 SpdySerializedFrame goaway(
diannahu9904e272017-02-03 14:40:088508 spdy_util_.ConstructSpdyRstStream(1, ERROR_CODE_CANCEL));
[email protected]511f6f52010-12-17 03:58:298509 MockWrite data_writes[] = {
bncdf80d44fd2016-07-15 20:27:418510 CreateMockWrite(conn, 0, SYNCHRONOUS),
8511 CreateMockWrite(goaway, 2, SYNCHRONOUS),
[email protected]511f6f52010-12-17 03:58:298512 };
8513
8514 static const char* const kExtraHeaders[] = {
8515 "location",
8516 "http://login.example.com/",
8517 };
bnc42331402016-07-25 13:36:158518 SpdySerializedFrame resp(spdy_util_.ConstructSpdyReplyError(
bncc9f762a2016-12-06 20:38:238519 "302", kExtraHeaders, arraysize(kExtraHeaders) / 2, 1));
[email protected]511f6f52010-12-17 03:58:298520 MockRead data_reads[] = {
bncdf80d44fd2016-07-15 20:27:418521 CreateMockRead(resp, 1), MockRead(ASYNC, 0, 3), // EOF
[email protected]511f6f52010-12-17 03:58:298522 };
8523
rch8e6c6c42015-05-01 14:05:138524 SequencedSocketData data(data_reads, arraysize(data_reads), data_writes,
8525 arraysize(data_writes));
[email protected]8ddf8322012-02-23 18:08:068526 SSLSocketDataProvider proxy_ssl(ASYNC, OK); // SSL to the proxy
bnc3cf2a592016-08-11 14:48:368527 proxy_ssl.next_proto = kProtoHTTP2;
[email protected]511f6f52010-12-17 03:58:298528
[email protected]bb88e1d32013-05-03 23:11:078529 session_deps_.socket_factory->AddSocketDataProvider(&data);
8530 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy_ssl);
[email protected]511f6f52010-12-17 03:58:298531
[email protected]49639fa2011-12-20 23:22:418532 TestCompletionCallback callback;
[email protected]511f6f52010-12-17 03:58:298533
danakj1fd259a02016-04-16 03:17:098534 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:168535 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]511f6f52010-12-17 03:58:298536
tfarina42834112016-09-22 13:38:208537 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:018538 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]511f6f52010-12-17 03:58:298539
8540 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:018541 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:168542 const HttpResponseInfo* response = trans.GetResponseInfo();
[email protected]511f6f52010-12-17 03:58:298543
wezca1070932016-05-26 20:30:528544 ASSERT_TRUE(response);
[email protected]511f6f52010-12-17 03:58:298545
8546 EXPECT_EQ(302, response->headers->response_code());
8547 std::string url;
8548 EXPECT_TRUE(response->headers->IsRedirect(&url));
8549 EXPECT_EQ("http://login.example.com/", url);
8550}
8551
[email protected]4eddbc732012-08-09 05:40:178552// Test that an HTTPS proxy's response to a CONNECT request is filtered.
bncd16676a2016-07-20 16:23:018553TEST_F(HttpNetworkTransactionTest, ErrorResponseToHttpsConnectViaHttpsProxy) {
rdsmith82957ad2015-09-16 19:42:038554 session_deps_.proxy_service = ProxyService::CreateFixed("https://proxy:70");
[email protected]511f6f52010-12-17 03:58:298555
8556 HttpRequestInfo request;
8557 request.method = "GET";
bncce36dca22015-04-21 22:11:238558 request.url = GURL("https://www.example.org/");
[email protected]511f6f52010-12-17 03:58:298559
8560 MockWrite data_writes[] = {
rsleevidb16bb02015-11-12 23:47:178561 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
8562 "Host: www.example.org:443\r\n"
8563 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]511f6f52010-12-17 03:58:298564 };
8565
8566 MockRead data_reads[] = {
8567 MockRead("HTTP/1.1 404 Not Found\r\n"),
8568 MockRead("Content-Length: 23\r\n\r\n"),
8569 MockRead("The host does not exist"),
[email protected]8ddf8322012-02-23 18:08:068570 MockRead(SYNCHRONOUS, OK),
[email protected]511f6f52010-12-17 03:58:298571 };
8572
8573 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
8574 data_writes, arraysize(data_writes));
[email protected]8ddf8322012-02-23 18:08:068575 SSLSocketDataProvider proxy_ssl(ASYNC, OK); // SSL to the proxy
[email protected]511f6f52010-12-17 03:58:298576
[email protected]bb88e1d32013-05-03 23:11:078577 session_deps_.socket_factory->AddSocketDataProvider(&data);
8578 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy_ssl);
[email protected]511f6f52010-12-17 03:58:298579
[email protected]49639fa2011-12-20 23:22:418580 TestCompletionCallback callback;
[email protected]511f6f52010-12-17 03:58:298581
danakj1fd259a02016-04-16 03:17:098582 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:168583 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]511f6f52010-12-17 03:58:298584
tfarina42834112016-09-22 13:38:208585 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:018586 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]511f6f52010-12-17 03:58:298587
8588 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:018589 EXPECT_THAT(rv, IsError(ERR_TUNNEL_CONNECTION_FAILED));
[email protected]511f6f52010-12-17 03:58:298590
ttuttle960fcbf2016-04-19 13:26:328591 // TODO(juliatuttle): Anything else to check here?
[email protected]511f6f52010-12-17 03:58:298592}
8593
[email protected]4eddbc732012-08-09 05:40:178594// Test that a SPDY proxy's response to a CONNECT request is filtered.
bncd16676a2016-07-20 16:23:018595TEST_F(HttpNetworkTransactionTest, ErrorResponseToHttpsConnectViaSpdyProxy) {
rdsmith82957ad2015-09-16 19:42:038596 session_deps_.proxy_service = ProxyService::CreateFixed("https://proxy:70");
[email protected]511f6f52010-12-17 03:58:298597
8598 HttpRequestInfo request;
8599 request.method = "GET";
bncce36dca22015-04-21 22:11:238600 request.url = GURL("https://www.example.org/");
[email protected]511f6f52010-12-17 03:58:298601
bncdf80d44fd2016-07-15 20:27:418602 SpdySerializedFrame conn(spdy_util_.ConstructSpdyConnect(
bncce36dca22015-04-21 22:11:238603 NULL, 0, 1, LOWEST, HostPortPair("www.example.org", 443)));
bncdf80d44fd2016-07-15 20:27:418604 SpdySerializedFrame rst(
diannahu9904e272017-02-03 14:40:088605 spdy_util_.ConstructSpdyRstStream(1, ERROR_CODE_CANCEL));
[email protected]511f6f52010-12-17 03:58:298606 MockWrite data_writes[] = {
bncdf80d44fd2016-07-15 20:27:418607 CreateMockWrite(conn, 0), CreateMockWrite(rst, 3),
[email protected]511f6f52010-12-17 03:58:298608 };
8609
8610 static const char* const kExtraHeaders[] = {
8611 "location",
8612 "http://login.example.com/",
8613 };
bnc42331402016-07-25 13:36:158614 SpdySerializedFrame resp(spdy_util_.ConstructSpdyReplyError(
bncc9f762a2016-12-06 20:38:238615 "404", kExtraHeaders, arraysize(kExtraHeaders) / 2, 1));
bncdf80d44fd2016-07-15 20:27:418616 SpdySerializedFrame body(spdy_util_.ConstructSpdyDataFrame(
bncb03b1092016-04-06 11:19:558617 1, "The host does not exist", 23, true));
[email protected]511f6f52010-12-17 03:58:298618 MockRead data_reads[] = {
bncdf80d44fd2016-07-15 20:27:418619 CreateMockRead(resp, 1), CreateMockRead(body, 2),
rch8e6c6c42015-05-01 14:05:138620 MockRead(ASYNC, 0, 4), // EOF
[email protected]511f6f52010-12-17 03:58:298621 };
8622
rch8e6c6c42015-05-01 14:05:138623 SequencedSocketData data(data_reads, arraysize(data_reads), data_writes,
8624 arraysize(data_writes));
[email protected]8ddf8322012-02-23 18:08:068625 SSLSocketDataProvider proxy_ssl(ASYNC, OK); // SSL to the proxy
bnc3cf2a592016-08-11 14:48:368626 proxy_ssl.next_proto = kProtoHTTP2;
[email protected]511f6f52010-12-17 03:58:298627
[email protected]bb88e1d32013-05-03 23:11:078628 session_deps_.socket_factory->AddSocketDataProvider(&data);
8629 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy_ssl);
[email protected]511f6f52010-12-17 03:58:298630
[email protected]49639fa2011-12-20 23:22:418631 TestCompletionCallback callback;
[email protected]511f6f52010-12-17 03:58:298632
danakj1fd259a02016-04-16 03:17:098633 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:168634 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]511f6f52010-12-17 03:58:298635
tfarina42834112016-09-22 13:38:208636 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:018637 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]511f6f52010-12-17 03:58:298638
8639 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:018640 EXPECT_THAT(rv, IsError(ERR_TUNNEL_CONNECTION_FAILED));
[email protected]511f6f52010-12-17 03:58:298641
ttuttle960fcbf2016-04-19 13:26:328642 // TODO(juliatuttle): Anything else to check here?
[email protected]511f6f52010-12-17 03:58:298643}
8644
[email protected]0c5fb722012-02-28 11:50:358645// Test the request-challenge-retry sequence for basic auth, through
8646// a SPDY proxy over a single SPDY session.
bncd16676a2016-07-20 16:23:018647TEST_F(HttpNetworkTransactionTest, BasicAuthSpdyProxy) {
[email protected]0c5fb722012-02-28 11:50:358648 HttpRequestInfo request;
8649 request.method = "GET";
bncce36dca22015-04-21 22:11:238650 request.url = GURL("https://www.example.org/");
[email protected]0c5fb722012-02-28 11:50:358651 // when the no authentication data flag is set.
ttuttle859dc7a2015-04-23 19:42:298652 request.load_flags = LOAD_DO_NOT_SEND_AUTH_DATA;
[email protected]0c5fb722012-02-28 11:50:358653
8654 // Configure against https proxy server "myproxy:70".
rdsmith82957ad2015-09-16 19:42:038655 session_deps_.proxy_service =
8656 ProxyService::CreateFixedFromPacResult("HTTPS myproxy:70");
vishal.b62985ca92015-04-17 08:45:518657 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:078658 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:098659 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]0c5fb722012-02-28 11:50:358660
8661 // Since we have proxy, should try to establish tunnel.
bncdf80d44fd2016-07-15 20:27:418662 SpdySerializedFrame req(spdy_util_.ConstructSpdyConnect(
bncce36dca22015-04-21 22:11:238663 NULL, 0, 1, LOWEST, HostPortPair("www.example.org", 443)));
bncdf80d44fd2016-07-15 20:27:418664 SpdySerializedFrame rst(
diannahu9904e272017-02-03 14:40:088665 spdy_util_.ConstructSpdyRstStream(1, ERROR_CODE_CANCEL));
rdsmithebb50aa2015-11-12 03:44:388666 spdy_util_.UpdateWithStreamDestruction(1);
[email protected]0c5fb722012-02-28 11:50:358667
bnc691fda62016-08-12 00:43:168668 // After calling trans.RestartWithAuth(), this is the request we should
[email protected]0c5fb722012-02-28 11:50:358669 // be issuing -- the final header line contains the credentials.
8670 const char* const kAuthCredentials[] = {
8671 "proxy-authorization", "Basic Zm9vOmJhcg==",
8672 };
bncdf80d44fd2016-07-15 20:27:418673 SpdySerializedFrame connect2(spdy_util_.ConstructSpdyConnect(
lgarrona91df87f2014-12-05 00:51:348674 kAuthCredentials, arraysize(kAuthCredentials) / 2, 3, LOWEST,
bncce36dca22015-04-21 22:11:238675 HostPortPair("www.example.org", 443)));
8676 // fetch https://www.example.org/ via HTTP
8677 const char get[] =
8678 "GET / HTTP/1.1\r\n"
8679 "Host: www.example.org\r\n"
8680 "Connection: keep-alive\r\n\r\n";
bncdf80d44fd2016-07-15 20:27:418681 SpdySerializedFrame wrapped_get(
8682 spdy_util_.ConstructSpdyDataFrame(3, get, strlen(get), false));
[email protected]0c5fb722012-02-28 11:50:358683
8684 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:418685 CreateMockWrite(req, 0, ASYNC), CreateMockWrite(rst, 2, ASYNC),
8686 CreateMockWrite(connect2, 3), CreateMockWrite(wrapped_get, 5),
[email protected]0c5fb722012-02-28 11:50:358687 };
8688
8689 // The proxy responds to the connect with a 407, using a persistent
8690 // connection.
thestig9d3bb0c2015-01-24 00:49:518691 const char kAuthStatus[] = "407";
[email protected]0c5fb722012-02-28 11:50:358692 const char* const kAuthChallenge[] = {
[email protected]0c5fb722012-02-28 11:50:358693 "proxy-authenticate", "Basic realm=\"MyRealm1\"",
8694 };
bnc42331402016-07-25 13:36:158695 SpdySerializedFrame conn_auth_resp(spdy_util_.ConstructSpdyReplyError(
bncdf80d44fd2016-07-15 20:27:418696 kAuthStatus, kAuthChallenge, arraysize(kAuthChallenge) / 2, 1));
[email protected]0c5fb722012-02-28 11:50:358697
bnc42331402016-07-25 13:36:158698 SpdySerializedFrame conn_resp(spdy_util_.ConstructSpdyGetReply(NULL, 0, 3));
[email protected]0c5fb722012-02-28 11:50:358699 const char resp[] = "HTTP/1.1 200 OK\r\n"
8700 "Content-Length: 5\r\n\r\n";
8701
bncdf80d44fd2016-07-15 20:27:418702 SpdySerializedFrame wrapped_get_resp(
8703 spdy_util_.ConstructSpdyDataFrame(3, resp, strlen(resp), false));
8704 SpdySerializedFrame wrapped_body(
8705 spdy_util_.ConstructSpdyDataFrame(3, "hello", 5, false));
[email protected]0c5fb722012-02-28 11:50:358706 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:418707 CreateMockRead(conn_auth_resp, 1, ASYNC),
8708 CreateMockRead(conn_resp, 4, ASYNC),
8709 CreateMockRead(wrapped_get_resp, 6, ASYNC),
8710 CreateMockRead(wrapped_body, 7, ASYNC),
rch8e6c6c42015-05-01 14:05:138711 MockRead(ASYNC, OK, 8), // EOF. May or may not be read.
[email protected]0c5fb722012-02-28 11:50:358712 };
8713
rch8e6c6c42015-05-01 14:05:138714 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
8715 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:078716 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]0c5fb722012-02-28 11:50:358717 // Negotiate SPDY to the proxy
8718 SSLSocketDataProvider proxy(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:368719 proxy.next_proto = kProtoHTTP2;
[email protected]bb88e1d32013-05-03 23:11:078720 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy);
[email protected]0c5fb722012-02-28 11:50:358721 // Vanilla SSL to the server
8722 SSLSocketDataProvider server(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:078723 session_deps_.socket_factory->AddSSLSocketDataProvider(&server);
[email protected]0c5fb722012-02-28 11:50:358724
8725 TestCompletionCallback callback1;
8726
bnc87dcefc2017-05-25 12:47:588727 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:198728 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]0c5fb722012-02-28 11:50:358729
8730 int rv = trans->Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:018731 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]0c5fb722012-02-28 11:50:358732
8733 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:018734 EXPECT_THAT(rv, IsOk());
mmenke43758e62015-05-04 21:09:468735 TestNetLogEntry::List entries;
[email protected]0c5fb722012-02-28 11:50:358736 log.GetEntries(&entries);
8737 size_t pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:008738 entries, 0, NetLogEventType::HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
8739 NetLogEventPhase::NONE);
[email protected]0c5fb722012-02-28 11:50:358740 ExpectLogContainsSomewhere(
8741 entries, pos,
mikecirone8b85c432016-09-08 19:11:008742 NetLogEventType::HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
8743 NetLogEventPhase::NONE);
[email protected]0c5fb722012-02-28 11:50:358744
8745 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:528746 ASSERT_TRUE(response);
8747 ASSERT_TRUE(response->headers);
[email protected]0c5fb722012-02-28 11:50:358748 EXPECT_EQ(407, response->headers->response_code());
8749 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
wezca1070932016-05-26 20:30:528750 EXPECT_TRUE(response->auth_challenge);
asanka098c0092016-06-16 20:18:438751 EXPECT_TRUE(CheckBasicSecureProxyAuth(response->auth_challenge.get()));
[email protected]0c5fb722012-02-28 11:50:358752
8753 TestCompletionCallback callback2;
8754
8755 rv = trans->RestartWithAuth(AuthCredentials(kFoo, kBar),
8756 callback2.callback());
robpercival214763f2016-07-01 23:27:018757 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]0c5fb722012-02-28 11:50:358758
8759 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:018760 EXPECT_THAT(rv, IsOk());
[email protected]0c5fb722012-02-28 11:50:358761
8762 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:528763 ASSERT_TRUE(response);
[email protected]0c5fb722012-02-28 11:50:358764
8765 EXPECT_TRUE(response->headers->IsKeepAlive());
8766 EXPECT_EQ(200, response->headers->response_code());
8767 EXPECT_EQ(5, response->headers->GetContentLength());
8768 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
8769
8770 // The password prompt info should not be set.
wezca1070932016-05-26 20:30:528771 EXPECT_FALSE(response->auth_challenge);
[email protected]0c5fb722012-02-28 11:50:358772
[email protected]029c83b62013-01-24 05:28:208773 LoadTimingInfo load_timing_info;
8774 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
8775 TestLoadTimingNotReusedWithPac(load_timing_info,
8776 CONNECT_TIMING_HAS_SSL_TIMES);
8777
[email protected]0c5fb722012-02-28 11:50:358778 trans.reset();
8779 session->CloseAllConnections();
8780}
8781
[email protected]7c6f7ba2012-04-03 04:09:298782// Test that an explicitly trusted SPDY proxy can push a resource from an
8783// origin that is different from that of its associated resource.
bncd16676a2016-07-20 16:23:018784TEST_F(HttpNetworkTransactionTest, CrossOriginSPDYProxyPush) {
tbansal28e68f82016-02-04 02:56:158785 // Configure the proxy delegate to allow cross-origin SPDY pushes.
Jeremy Roman0579ed62017-08-29 15:56:198786 auto proxy_delegate = std::make_unique<TestProxyDelegate>();
tbansal28e68f82016-02-04 02:56:158787 proxy_delegate->set_trusted_spdy_proxy(net::ProxyServer::FromURI(
8788 "https://myproxy:443", net::ProxyServer::SCHEME_HTTP));
[email protected]7c6f7ba2012-04-03 04:09:298789 HttpRequestInfo request;
8790 HttpRequestInfo push_request;
8791
[email protected]7c6f7ba2012-04-03 04:09:298792 request.method = "GET";
bncce36dca22015-04-21 22:11:238793 request.url = GURL("http://www.example.org/");
[email protected]7c6f7ba2012-04-03 04:09:298794 push_request.method = "GET";
8795 push_request.url = GURL("http://www.another-origin.com/foo.dat");
8796
tbansal28e68f82016-02-04 02:56:158797 // Configure against https proxy server "myproxy:443".
rdsmith82957ad2015-09-16 19:42:038798 session_deps_.proxy_service =
tbansal28e68f82016-02-04 02:56:158799 ProxyService::CreateFixedFromPacResult("HTTPS myproxy:443");
vishal.b62985ca92015-04-17 08:45:518800 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:078801 session_deps_.net_log = log.bound().net_log();
[email protected]61b4efc2012-04-27 18:12:508802
inlinechan894515af2016-12-09 02:40:108803 session_deps_.proxy_delegate = std::move(proxy_delegate);
[email protected]61b4efc2012-04-27 18:12:508804
danakj1fd259a02016-04-16 03:17:098805 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]7c6f7ba2012-04-03 04:09:298806
bncdf80d44fd2016-07-15 20:27:418807 SpdySerializedFrame stream1_syn(
bncb26024382016-06-29 02:39:458808 spdy_util_.ConstructSpdyGet("http://www.example.org/", 1, LOWEST));
tombergan5d22c182017-01-11 02:05:358809 SpdySerializedFrame stream2_priority(
8810 spdy_util_.ConstructSpdyPriority(2, 1, IDLE, true));
[email protected]7c6f7ba2012-04-03 04:09:298811
8812 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:418813 CreateMockWrite(stream1_syn, 0, ASYNC),
tombergan5d22c182017-01-11 02:05:358814 CreateMockWrite(stream2_priority, 3, ASYNC),
[email protected]7c6f7ba2012-04-03 04:09:298815 };
8816
Bence Béky7bf94362018-01-10 13:19:368817 SpdySerializedFrame stream2_syn(spdy_util_.ConstructSpdyPush(
8818 NULL, 0, 2, 1, "http://www.another-origin.com/foo.dat"));
8819
bncdf80d44fd2016-07-15 20:27:418820 SpdySerializedFrame stream1_reply(
bnc42331402016-07-25 13:36:158821 spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
[email protected]7c6f7ba2012-04-03 04:09:298822
bncdf80d44fd2016-07-15 20:27:418823 SpdySerializedFrame stream1_body(spdy_util_.ConstructSpdyDataFrame(1, true));
[email protected]7c6f7ba2012-04-03 04:09:298824
[email protected]8a0fc822013-06-27 20:52:438825 const char kPushedData[] = "pushed";
bncdf80d44fd2016-07-15 20:27:418826 SpdySerializedFrame stream2_body(spdy_util_.ConstructSpdyDataFrame(
8827 2, kPushedData, strlen(kPushedData), true));
[email protected]7c6f7ba2012-04-03 04:09:298828
8829 MockRead spdy_reads[] = {
Bence Béky7bf94362018-01-10 13:19:368830 CreateMockRead(stream2_syn, 1, ASYNC),
8831 CreateMockRead(stream1_reply, 2, ASYNC),
tombergan5d22c182017-01-11 02:05:358832 CreateMockRead(stream1_body, 4, ASYNC),
8833 CreateMockRead(stream2_body, 5, ASYNC),
8834 MockRead(SYNCHRONOUS, ERR_IO_PENDING, 6), // Force a hang
[email protected]7c6f7ba2012-04-03 04:09:298835 };
8836
rch8e6c6c42015-05-01 14:05:138837 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
8838 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:078839 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]7c6f7ba2012-04-03 04:09:298840 // Negotiate SPDY to the proxy
8841 SSLSocketDataProvider proxy(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:368842 proxy.next_proto = kProtoHTTP2;
[email protected]bb88e1d32013-05-03 23:11:078843 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy);
[email protected]7c6f7ba2012-04-03 04:09:298844
bnc87dcefc2017-05-25 12:47:588845 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:198846 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]7c6f7ba2012-04-03 04:09:298847 TestCompletionCallback callback;
8848 int rv = trans->Start(&request, callback.callback(), log.bound());
robpercival214763f2016-07-01 23:27:018849 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]7c6f7ba2012-04-03 04:09:298850
8851 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:018852 EXPECT_THAT(rv, IsOk());
[email protected]7c6f7ba2012-04-03 04:09:298853 const HttpResponseInfo* response = trans->GetResponseInfo();
8854
bnc87dcefc2017-05-25 12:47:588855 auto push_trans =
Jeremy Roman0579ed62017-08-29 15:56:198856 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]90499482013-06-01 00:39:508857 rv = push_trans->Start(&push_request, callback.callback(), log.bound());
robpercival214763f2016-07-01 23:27:018858 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]7c6f7ba2012-04-03 04:09:298859
8860 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:018861 EXPECT_THAT(rv, IsOk());
[email protected]7c6f7ba2012-04-03 04:09:298862 const HttpResponseInfo* push_response = push_trans->GetResponseInfo();
8863
wezca1070932016-05-26 20:30:528864 ASSERT_TRUE(response);
[email protected]7c6f7ba2012-04-03 04:09:298865 EXPECT_TRUE(response->headers->IsKeepAlive());
8866
8867 EXPECT_EQ(200, response->headers->response_code());
8868 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
8869
8870 std::string response_data;
8871 rv = ReadTransaction(trans.get(), &response_data);
robpercival214763f2016-07-01 23:27:018872 EXPECT_THAT(rv, IsOk());
[email protected]7c6f7ba2012-04-03 04:09:298873 EXPECT_EQ("hello!", response_data);
8874
[email protected]029c83b62013-01-24 05:28:208875 LoadTimingInfo load_timing_info;
8876 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
8877 TestLoadTimingNotReusedWithPac(load_timing_info,
8878 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
8879
[email protected]7c6f7ba2012-04-03 04:09:298880 // Verify the pushed stream.
wezca1070932016-05-26 20:30:528881 EXPECT_TRUE(push_response->headers);
[email protected]7c6f7ba2012-04-03 04:09:298882 EXPECT_EQ(200, push_response->headers->response_code());
8883
8884 rv = ReadTransaction(push_trans.get(), &response_data);
robpercival214763f2016-07-01 23:27:018885 EXPECT_THAT(rv, IsOk());
[email protected]7c6f7ba2012-04-03 04:09:298886 EXPECT_EQ("pushed", response_data);
8887
[email protected]029c83b62013-01-24 05:28:208888 LoadTimingInfo push_load_timing_info;
8889 EXPECT_TRUE(push_trans->GetLoadTimingInfo(&push_load_timing_info));
8890 TestLoadTimingReusedWithPac(push_load_timing_info);
8891 // The transactions should share a socket ID, despite being for different
8892 // origins.
8893 EXPECT_EQ(load_timing_info.socket_log_id,
8894 push_load_timing_info.socket_log_id);
8895
[email protected]7c6f7ba2012-04-03 04:09:298896 trans.reset();
8897 push_trans.reset();
8898 session->CloseAllConnections();
8899}
8900
[email protected]8c843192012-04-05 07:15:008901// Test that an explicitly trusted SPDY proxy cannot push HTTPS content.
bncd16676a2016-07-20 16:23:018902TEST_F(HttpNetworkTransactionTest, CrossOriginProxyPushCorrectness) {
tbansal28e68f82016-02-04 02:56:158903 // Configure the proxy delegate to allow cross-origin SPDY pushes.
Jeremy Roman0579ed62017-08-29 15:56:198904 auto proxy_delegate = std::make_unique<TestProxyDelegate>();
tbansal28e68f82016-02-04 02:56:158905 proxy_delegate->set_trusted_spdy_proxy(net::ProxyServer::FromURI(
8906 "https://myproxy:443", net::ProxyServer::SCHEME_HTTP));
[email protected]8c843192012-04-05 07:15:008907 HttpRequestInfo request;
8908
8909 request.method = "GET";
bncce36dca22015-04-21 22:11:238910 request.url = GURL("http://www.example.org/");
[email protected]8c843192012-04-05 07:15:008911
tbansal28e68f82016-02-04 02:56:158912 session_deps_.proxy_service =
8913 ProxyService::CreateFixed("https://myproxy:443");
vishal.b62985ca92015-04-17 08:45:518914 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:078915 session_deps_.net_log = log.bound().net_log();
[email protected]61b4efc2012-04-27 18:12:508916
8917 // Enable cross-origin push.
inlinechan894515af2016-12-09 02:40:108918 session_deps_.proxy_delegate = std::move(proxy_delegate);
[email protected]61b4efc2012-04-27 18:12:508919
danakj1fd259a02016-04-16 03:17:098920 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]8c843192012-04-05 07:15:008921
bncdf80d44fd2016-07-15 20:27:418922 SpdySerializedFrame stream1_syn(
bncb26024382016-06-29 02:39:458923 spdy_util_.ConstructSpdyGet("http://www.example.org/", 1, LOWEST));
[email protected]8c843192012-04-05 07:15:008924
bncdf80d44fd2016-07-15 20:27:418925 SpdySerializedFrame push_rst(
diannahu9904e272017-02-03 14:40:088926 spdy_util_.ConstructSpdyRstStream(2, ERROR_CODE_REFUSED_STREAM));
[email protected]8c843192012-04-05 07:15:008927
8928 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:418929 CreateMockWrite(stream1_syn, 0, ASYNC), CreateMockWrite(push_rst, 3),
[email protected]8c843192012-04-05 07:15:008930 };
8931
bncdf80d44fd2016-07-15 20:27:418932 SpdySerializedFrame stream1_reply(
bnc42331402016-07-25 13:36:158933 spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
[email protected]8c843192012-04-05 07:15:008934
bncdf80d44fd2016-07-15 20:27:418935 SpdySerializedFrame stream1_body(spdy_util_.ConstructSpdyDataFrame(1, true));
[email protected]8c843192012-04-05 07:15:008936
bncdf80d44fd2016-07-15 20:27:418937 SpdySerializedFrame stream2_syn(spdy_util_.ConstructSpdyPush(
bncb03b1092016-04-06 11:19:558938 NULL, 0, 2, 1, "https://www.another-origin.com/foo.dat"));
[email protected]8c843192012-04-05 07:15:008939
8940 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:418941 CreateMockRead(stream1_reply, 1, ASYNC),
8942 CreateMockRead(stream2_syn, 2, ASYNC),
8943 CreateMockRead(stream1_body, 4, ASYNC),
mmenkee24011922015-12-17 22:12:598944 MockRead(SYNCHRONOUS, ERR_IO_PENDING, 5), // Force a hang
[email protected]8c843192012-04-05 07:15:008945 };
8946
rch8e6c6c42015-05-01 14:05:138947 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
8948 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:078949 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]8c843192012-04-05 07:15:008950 // Negotiate SPDY to the proxy
8951 SSLSocketDataProvider proxy(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:368952 proxy.next_proto = kProtoHTTP2;
[email protected]bb88e1d32013-05-03 23:11:078953 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy);
[email protected]8c843192012-04-05 07:15:008954
bnc87dcefc2017-05-25 12:47:588955 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:198956 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]8c843192012-04-05 07:15:008957 TestCompletionCallback callback;
8958 int rv = trans->Start(&request, callback.callback(), log.bound());
robpercival214763f2016-07-01 23:27:018959 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]8c843192012-04-05 07:15:008960
8961 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:018962 EXPECT_THAT(rv, IsOk());
[email protected]8c843192012-04-05 07:15:008963 const HttpResponseInfo* response = trans->GetResponseInfo();
8964
wezca1070932016-05-26 20:30:528965 ASSERT_TRUE(response);
[email protected]8c843192012-04-05 07:15:008966 EXPECT_TRUE(response->headers->IsKeepAlive());
8967
8968 EXPECT_EQ(200, response->headers->response_code());
8969 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
8970
8971 std::string response_data;
8972 rv = ReadTransaction(trans.get(), &response_data);
robpercival214763f2016-07-01 23:27:018973 EXPECT_THAT(rv, IsOk());
[email protected]8c843192012-04-05 07:15:008974 EXPECT_EQ("hello!", response_data);
8975
8976 trans.reset();
8977 session->CloseAllConnections();
8978}
8979
tbansal8ef1d3e2016-02-03 04:05:428980// Test that an explicitly trusted SPDY proxy can push same-origin HTTPS
8981// resources.
bncd16676a2016-07-20 16:23:018982TEST_F(HttpNetworkTransactionTest, SameOriginProxyPushCorrectness) {
tbansal28e68f82016-02-04 02:56:158983 // Configure the proxy delegate to allow cross-origin SPDY pushes.
Jeremy Roman0579ed62017-08-29 15:56:198984 auto proxy_delegate = std::make_unique<TestProxyDelegate>();
tbansal28e68f82016-02-04 02:56:158985 proxy_delegate->set_trusted_spdy_proxy(
8986 net::ProxyServer::FromURI("myproxy:70", net::ProxyServer::SCHEME_HTTP));
8987
tbansal8ef1d3e2016-02-03 04:05:428988 HttpRequestInfo request;
8989
8990 request.method = "GET";
8991 request.url = GURL("http://www.example.org/");
8992
8993 // Configure against https proxy server "myproxy:70".
8994 session_deps_.proxy_service = ProxyService::CreateFixed("https://myproxy:70");
8995 BoundTestNetLog log;
8996 session_deps_.net_log = log.bound().net_log();
8997
8998 // Enable cross-origin push.
inlinechan894515af2016-12-09 02:40:108999 session_deps_.proxy_delegate = std::move(proxy_delegate);
tbansal8ef1d3e2016-02-03 04:05:429000
danakj1fd259a02016-04-16 03:17:099001 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
tbansal8ef1d3e2016-02-03 04:05:429002
bncdf80d44fd2016-07-15 20:27:419003 SpdySerializedFrame stream1_syn(
bncb26024382016-06-29 02:39:459004 spdy_util_.ConstructSpdyGet("http://www.example.org/", 1, LOWEST));
tombergan5d22c182017-01-11 02:05:359005 SpdySerializedFrame stream2_priority(
9006 spdy_util_.ConstructSpdyPriority(2, 1, IDLE, true));
tbansal8ef1d3e2016-02-03 04:05:429007
9008 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:419009 CreateMockWrite(stream1_syn, 0, ASYNC),
tombergan5d22c182017-01-11 02:05:359010 CreateMockWrite(stream2_priority, 3, ASYNC),
tbansal8ef1d3e2016-02-03 04:05:429011 };
9012
bncdf80d44fd2016-07-15 20:27:419013 SpdySerializedFrame stream1_reply(
bnc42331402016-07-25 13:36:159014 spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
tbansal8ef1d3e2016-02-03 04:05:429015
bncdf80d44fd2016-07-15 20:27:419016 SpdySerializedFrame stream2_syn(spdy_util_.ConstructSpdyPush(
Bence Béky096cf052017-08-08 23:55:339017 nullptr, 0, 2, 1, "http://www.example.org/foo.dat"));
bnc38dcd392016-02-09 23:19:499018
bncdf80d44fd2016-07-15 20:27:419019 SpdySerializedFrame stream1_body(spdy_util_.ConstructSpdyDataFrame(1, true));
tbansal8ef1d3e2016-02-03 04:05:429020
bncdf80d44fd2016-07-15 20:27:419021 SpdySerializedFrame stream2_reply(
bnc42331402016-07-25 13:36:159022 spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
tbansal8ef1d3e2016-02-03 04:05:429023
bncdf80d44fd2016-07-15 20:27:419024 SpdySerializedFrame stream2_body(spdy_util_.ConstructSpdyDataFrame(1, true));
tbansal8ef1d3e2016-02-03 04:05:429025
9026 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:419027 CreateMockRead(stream1_reply, 1, ASYNC),
9028 CreateMockRead(stream2_syn, 2, ASYNC),
tombergan5d22c182017-01-11 02:05:359029 CreateMockRead(stream1_body, 4, ASYNC),
9030 CreateMockRead(stream2_body, 5, ASYNC),
9031 MockRead(SYNCHRONOUS, ERR_IO_PENDING, 6), // Force a hang
tbansal8ef1d3e2016-02-03 04:05:429032 };
9033
9034 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
9035 arraysize(spdy_writes));
9036 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
9037 // Negotiate SPDY to the proxy
9038 SSLSocketDataProvider proxy(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:369039 proxy.next_proto = kProtoHTTP2;
tbansal8ef1d3e2016-02-03 04:05:429040 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy);
9041
bnc87dcefc2017-05-25 12:47:589042 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:199043 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
tbansal8ef1d3e2016-02-03 04:05:429044 TestCompletionCallback callback;
9045 int rv = trans->Start(&request, callback.callback(), log.bound());
robpercival214763f2016-07-01 23:27:019046 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
tbansal8ef1d3e2016-02-03 04:05:429047
9048 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:019049 EXPECT_THAT(rv, IsOk());
tbansal8ef1d3e2016-02-03 04:05:429050 const HttpResponseInfo* response = trans->GetResponseInfo();
9051
wezca1070932016-05-26 20:30:529052 ASSERT_TRUE(response);
tbansal8ef1d3e2016-02-03 04:05:429053 EXPECT_TRUE(response->headers->IsKeepAlive());
9054
9055 EXPECT_EQ(200, response->headers->response_code());
9056 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
9057
9058 std::string response_data;
9059 rv = ReadTransaction(trans.get(), &response_data);
robpercival214763f2016-07-01 23:27:019060 EXPECT_THAT(rv, IsOk());
tbansal8ef1d3e2016-02-03 04:05:429061 EXPECT_EQ("hello!", response_data);
9062
9063 trans.reset();
9064 session->CloseAllConnections();
9065}
9066
[email protected]2df19bb2010-08-25 20:13:469067// Test HTTPS connections to a site with a bad certificate, going through an
9068// HTTPS proxy
bncd16676a2016-07-20 16:23:019069TEST_F(HttpNetworkTransactionTest, HTTPSBadCertificateViaHttpsProxy) {
rdsmith82957ad2015-09-16 19:42:039070 session_deps_.proxy_service = ProxyService::CreateFixed("https://proxy:70");
[email protected]2df19bb2010-08-25 20:13:469071
9072 HttpRequestInfo request;
9073 request.method = "GET";
bncce36dca22015-04-21 22:11:239074 request.url = GURL("https://www.example.org/");
[email protected]2df19bb2010-08-25 20:13:469075
9076 // Attempt to fetch the URL from a server with a bad cert
9077 MockWrite bad_cert_writes[] = {
rsleevidb16bb02015-11-12 23:47:179078 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
9079 "Host: www.example.org:443\r\n"
9080 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]2df19bb2010-08-25 20:13:469081 };
9082
9083 MockRead bad_cert_reads[] = {
9084 MockRead("HTTP/1.0 200 Connected\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:069085 MockRead(SYNCHRONOUS, OK)
[email protected]2df19bb2010-08-25 20:13:469086 };
9087
9088 // Attempt to fetch the URL with a good cert
9089 MockWrite good_data_writes[] = {
rsleevidb16bb02015-11-12 23:47:179090 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
9091 "Host: www.example.org:443\r\n"
9092 "Proxy-Connection: keep-alive\r\n\r\n"),
9093 MockWrite("GET / HTTP/1.1\r\n"
9094 "Host: www.example.org\r\n"
9095 "Connection: keep-alive\r\n\r\n"),
[email protected]2df19bb2010-08-25 20:13:469096 };
9097
9098 MockRead good_cert_reads[] = {
9099 MockRead("HTTP/1.0 200 Connected\r\n\r\n"),
9100 MockRead("HTTP/1.0 200 OK\r\n"),
9101 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
9102 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:069103 MockRead(SYNCHRONOUS, OK),
[email protected]2df19bb2010-08-25 20:13:469104 };
9105
9106 StaticSocketDataProvider ssl_bad_certificate(
9107 bad_cert_reads, arraysize(bad_cert_reads),
9108 bad_cert_writes, arraysize(bad_cert_writes));
9109 StaticSocketDataProvider data(good_cert_reads, arraysize(good_cert_reads),
9110 good_data_writes, arraysize(good_data_writes));
[email protected]8ddf8322012-02-23 18:08:069111 SSLSocketDataProvider ssl_bad(ASYNC, ERR_CERT_AUTHORITY_INVALID);
9112 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]2df19bb2010-08-25 20:13:469113
9114 // SSL to the proxy, then CONNECT request, then SSL with bad certificate
[email protected]bb88e1d32013-05-03 23:11:079115 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
9116 session_deps_.socket_factory->AddSocketDataProvider(&ssl_bad_certificate);
9117 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_bad);
[email protected]2df19bb2010-08-25 20:13:469118
9119 // SSL to the proxy, then CONNECT request, then valid SSL certificate
[email protected]bb88e1d32013-05-03 23:11:079120 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
9121 session_deps_.socket_factory->AddSocketDataProvider(&data);
9122 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]2df19bb2010-08-25 20:13:469123
[email protected]49639fa2011-12-20 23:22:419124 TestCompletionCallback callback;
[email protected]2df19bb2010-08-25 20:13:469125
danakj1fd259a02016-04-16 03:17:099126 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:169127 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]2df19bb2010-08-25 20:13:469128
tfarina42834112016-09-22 13:38:209129 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:019130 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2df19bb2010-08-25 20:13:469131
9132 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:019133 EXPECT_THAT(rv, IsError(ERR_CERT_AUTHORITY_INVALID));
[email protected]2df19bb2010-08-25 20:13:469134
bnc691fda62016-08-12 00:43:169135 rv = trans.RestartIgnoringLastError(callback.callback());
robpercival214763f2016-07-01 23:27:019136 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2df19bb2010-08-25 20:13:469137
9138 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:019139 EXPECT_THAT(rv, IsOk());
[email protected]2df19bb2010-08-25 20:13:469140
bnc691fda62016-08-12 00:43:169141 const HttpResponseInfo* response = trans.GetResponseInfo();
[email protected]2df19bb2010-08-25 20:13:469142
wezca1070932016-05-26 20:30:529143 ASSERT_TRUE(response);
[email protected]2df19bb2010-08-25 20:13:469144 EXPECT_EQ(100, response->headers->GetContentLength());
9145}
9146
bncd16676a2016-07-20 16:23:019147TEST_F(HttpNetworkTransactionTest, BuildRequest_UserAgent) {
[email protected]1c773ea12009-04-28 19:58:429148 HttpRequestInfo request;
9149 request.method = "GET";
bncce36dca22015-04-21 22:11:239150 request.url = GURL("http://www.example.org/");
[email protected]8c76ae22010-04-20 22:15:439151 request.extra_headers.SetHeader(HttpRequestHeaders::kUserAgent,
9152 "Chromium Ultra Awesome X Edition");
[email protected]1c773ea12009-04-28 19:58:429153
danakj1fd259a02016-04-16 03:17:099154 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:169155 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:279156
[email protected]1c773ea12009-04-28 19:58:429157 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:239158 MockWrite(
9159 "GET / HTTP/1.1\r\n"
9160 "Host: www.example.org\r\n"
9161 "Connection: keep-alive\r\n"
9162 "User-Agent: Chromium Ultra Awesome X Edition\r\n\r\n"),
[email protected]1c773ea12009-04-28 19:58:429163 };
9164
9165 // Lastly, the server responds with the actual content.
9166 MockRead data_reads[] = {
9167 MockRead("HTTP/1.0 200 OK\r\n"),
9168 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
9169 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:069170 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:429171 };
9172
[email protected]31a2bfe2010-02-09 08:03:399173 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
9174 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:079175 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:429176
[email protected]49639fa2011-12-20 23:22:419177 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:429178
tfarina42834112016-09-22 13:38:209179 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:019180 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]1c773ea12009-04-28 19:58:429181
9182 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:019183 EXPECT_THAT(rv, IsOk());
[email protected]1c773ea12009-04-28 19:58:429184}
9185
bncd16676a2016-07-20 16:23:019186TEST_F(HttpNetworkTransactionTest, BuildRequest_UserAgentOverTunnel) {
[email protected]da81f132010-08-18 23:39:299187 HttpRequestInfo request;
9188 request.method = "GET";
bncce36dca22015-04-21 22:11:239189 request.url = GURL("https://www.example.org/");
[email protected]da81f132010-08-18 23:39:299190 request.extra_headers.SetHeader(HttpRequestHeaders::kUserAgent,
9191 "Chromium Ultra Awesome X Edition");
9192
rdsmith82957ad2015-09-16 19:42:039193 session_deps_.proxy_service = ProxyService::CreateFixed("myproxy:70");
danakj1fd259a02016-04-16 03:17:099194 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:169195 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:279196
[email protected]da81f132010-08-18 23:39:299197 MockWrite data_writes[] = {
rsleevidb16bb02015-11-12 23:47:179198 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
9199 "Host: www.example.org:443\r\n"
9200 "Proxy-Connection: keep-alive\r\n"
9201 "User-Agent: Chromium Ultra Awesome X Edition\r\n\r\n"),
[email protected]da81f132010-08-18 23:39:299202 };
9203 MockRead data_reads[] = {
9204 // Return an error, so the transaction stops here (this test isn't
9205 // interested in the rest).
9206 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
9207 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
9208 MockRead("Proxy-Connection: close\r\n\r\n"),
9209 };
9210
9211 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
9212 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:079213 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]da81f132010-08-18 23:39:299214
[email protected]49639fa2011-12-20 23:22:419215 TestCompletionCallback callback;
[email protected]da81f132010-08-18 23:39:299216
tfarina42834112016-09-22 13:38:209217 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:019218 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]da81f132010-08-18 23:39:299219
9220 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:019221 EXPECT_THAT(rv, IsOk());
[email protected]da81f132010-08-18 23:39:299222}
9223
bncd16676a2016-07-20 16:23:019224TEST_F(HttpNetworkTransactionTest, BuildRequest_Referer) {
[email protected]1c773ea12009-04-28 19:58:429225 HttpRequestInfo request;
9226 request.method = "GET";
bncce36dca22015-04-21 22:11:239227 request.url = GURL("http://www.example.org/");
[email protected]c10450102011-06-27 09:06:169228 request.extra_headers.SetHeader(HttpRequestHeaders::kReferer,
9229 "http://the.previous.site.com/");
[email protected]1c773ea12009-04-28 19:58:429230
danakj1fd259a02016-04-16 03:17:099231 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:169232 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:279233
[email protected]1c773ea12009-04-28 19:58:429234 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:239235 MockWrite(
9236 "GET / HTTP/1.1\r\n"
9237 "Host: www.example.org\r\n"
9238 "Connection: keep-alive\r\n"
9239 "Referer: http://the.previous.site.com/\r\n\r\n"),
[email protected]1c773ea12009-04-28 19:58:429240 };
9241
9242 // Lastly, the server responds with the actual content.
9243 MockRead data_reads[] = {
9244 MockRead("HTTP/1.0 200 OK\r\n"),
9245 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
9246 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:069247 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:429248 };
9249
[email protected]31a2bfe2010-02-09 08:03:399250 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
9251 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:079252 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:429253
[email protected]49639fa2011-12-20 23:22:419254 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:429255
tfarina42834112016-09-22 13:38:209256 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:019257 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]1c773ea12009-04-28 19:58:429258
9259 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:019260 EXPECT_THAT(rv, IsOk());
[email protected]1c773ea12009-04-28 19:58:429261}
9262
bncd16676a2016-07-20 16:23:019263TEST_F(HttpNetworkTransactionTest, BuildRequest_PostContentLengthZero) {
[email protected]1c773ea12009-04-28 19:58:429264 HttpRequestInfo request;
9265 request.method = "POST";
bncce36dca22015-04-21 22:11:239266 request.url = GURL("http://www.example.org/");
[email protected]1c773ea12009-04-28 19:58:429267
danakj1fd259a02016-04-16 03:17:099268 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:169269 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:279270
[email protected]1c773ea12009-04-28 19:58:429271 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:239272 MockWrite(
9273 "POST / HTTP/1.1\r\n"
9274 "Host: www.example.org\r\n"
9275 "Connection: keep-alive\r\n"
9276 "Content-Length: 0\r\n\r\n"),
[email protected]1c773ea12009-04-28 19:58:429277 };
9278
9279 // Lastly, the server responds with the actual content.
9280 MockRead data_reads[] = {
9281 MockRead("HTTP/1.0 200 OK\r\n"),
9282 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
9283 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:069284 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:429285 };
9286
[email protected]31a2bfe2010-02-09 08:03:399287 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
9288 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:079289 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:429290
[email protected]49639fa2011-12-20 23:22:419291 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:429292
tfarina42834112016-09-22 13:38:209293 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:019294 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]1c773ea12009-04-28 19:58:429295
9296 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:019297 EXPECT_THAT(rv, IsOk());
[email protected]1c773ea12009-04-28 19:58:429298}
9299
bncd16676a2016-07-20 16:23:019300TEST_F(HttpNetworkTransactionTest, BuildRequest_PutContentLengthZero) {
[email protected]1c773ea12009-04-28 19:58:429301 HttpRequestInfo request;
9302 request.method = "PUT";
bncce36dca22015-04-21 22:11:239303 request.url = GURL("http://www.example.org/");
[email protected]1c773ea12009-04-28 19:58:429304
danakj1fd259a02016-04-16 03:17:099305 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:169306 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:279307
[email protected]1c773ea12009-04-28 19:58:429308 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:239309 MockWrite(
9310 "PUT / HTTP/1.1\r\n"
9311 "Host: www.example.org\r\n"
9312 "Connection: keep-alive\r\n"
9313 "Content-Length: 0\r\n\r\n"),
[email protected]1c773ea12009-04-28 19:58:429314 };
9315
9316 // Lastly, the server responds with the actual content.
9317 MockRead data_reads[] = {
9318 MockRead("HTTP/1.0 200 OK\r\n"),
9319 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
9320 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:069321 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:429322 };
9323
[email protected]31a2bfe2010-02-09 08:03:399324 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
9325 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:079326 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:429327
[email protected]49639fa2011-12-20 23:22:419328 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:429329
tfarina42834112016-09-22 13:38:209330 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:019331 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]1c773ea12009-04-28 19:58:429332
9333 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:019334 EXPECT_THAT(rv, IsOk());
[email protected]1c773ea12009-04-28 19:58:429335}
9336
bncd16676a2016-07-20 16:23:019337TEST_F(HttpNetworkTransactionTest, BuildRequest_HeadContentLengthZero) {
[email protected]1c773ea12009-04-28 19:58:429338 HttpRequestInfo request;
9339 request.method = "HEAD";
bncce36dca22015-04-21 22:11:239340 request.url = GURL("http://www.example.org/");
[email protected]1c773ea12009-04-28 19:58:429341
danakj1fd259a02016-04-16 03:17:099342 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:169343 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:279344
[email protected]1c773ea12009-04-28 19:58:429345 MockWrite data_writes[] = {
csharrisonf473dd192015-08-18 13:54:139346 MockWrite("HEAD / HTTP/1.1\r\n"
9347 "Host: www.example.org\r\n"
9348 "Connection: keep-alive\r\n\r\n"),
[email protected]1c773ea12009-04-28 19:58:429349 };
9350
9351 // Lastly, the server responds with the actual content.
9352 MockRead data_reads[] = {
9353 MockRead("HTTP/1.0 200 OK\r\n"),
9354 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
9355 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:069356 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:429357 };
9358
[email protected]31a2bfe2010-02-09 08:03:399359 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
9360 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:079361 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:429362
[email protected]49639fa2011-12-20 23:22:419363 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:429364
tfarina42834112016-09-22 13:38:209365 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:019366 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]1c773ea12009-04-28 19:58:429367
9368 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:019369 EXPECT_THAT(rv, IsOk());
[email protected]1c773ea12009-04-28 19:58:429370}
9371
bncd16676a2016-07-20 16:23:019372TEST_F(HttpNetworkTransactionTest, BuildRequest_CacheControlNoCache) {
[email protected]1c773ea12009-04-28 19:58:429373 HttpRequestInfo request;
9374 request.method = "GET";
bncce36dca22015-04-21 22:11:239375 request.url = GURL("http://www.example.org/");
[email protected]1c773ea12009-04-28 19:58:429376 request.load_flags = LOAD_BYPASS_CACHE;
9377
danakj1fd259a02016-04-16 03:17:099378 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:169379 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:279380
[email protected]1c773ea12009-04-28 19:58:429381 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:239382 MockWrite(
9383 "GET / HTTP/1.1\r\n"
9384 "Host: www.example.org\r\n"
9385 "Connection: keep-alive\r\n"
9386 "Pragma: no-cache\r\n"
9387 "Cache-Control: no-cache\r\n\r\n"),
[email protected]1c773ea12009-04-28 19:58:429388 };
9389
9390 // Lastly, the server responds with the actual content.
9391 MockRead data_reads[] = {
9392 MockRead("HTTP/1.0 200 OK\r\n"),
9393 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
9394 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:069395 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:429396 };
9397
[email protected]31a2bfe2010-02-09 08:03:399398 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
9399 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:079400 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:429401
[email protected]49639fa2011-12-20 23:22:419402 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:429403
tfarina42834112016-09-22 13:38:209404 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:019405 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]1c773ea12009-04-28 19:58:429406
9407 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:019408 EXPECT_THAT(rv, IsOk());
[email protected]1c773ea12009-04-28 19:58:429409}
9410
bncd16676a2016-07-20 16:23:019411TEST_F(HttpNetworkTransactionTest, BuildRequest_CacheControlValidateCache) {
[email protected]1c773ea12009-04-28 19:58:429412 HttpRequestInfo request;
9413 request.method = "GET";
bncce36dca22015-04-21 22:11:239414 request.url = GURL("http://www.example.org/");
[email protected]1c773ea12009-04-28 19:58:429415 request.load_flags = LOAD_VALIDATE_CACHE;
9416
danakj1fd259a02016-04-16 03:17:099417 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:169418 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:279419
[email protected]1c773ea12009-04-28 19:58:429420 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:239421 MockWrite(
9422 "GET / HTTP/1.1\r\n"
9423 "Host: www.example.org\r\n"
9424 "Connection: keep-alive\r\n"
9425 "Cache-Control: max-age=0\r\n\r\n"),
[email protected]1c773ea12009-04-28 19:58:429426 };
9427
9428 // Lastly, the server responds with the actual content.
9429 MockRead data_reads[] = {
9430 MockRead("HTTP/1.0 200 OK\r\n"),
9431 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
9432 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:069433 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:429434 };
9435
[email protected]31a2bfe2010-02-09 08:03:399436 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
9437 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:079438 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:429439
[email protected]49639fa2011-12-20 23:22:419440 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:429441
tfarina42834112016-09-22 13:38:209442 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:019443 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]1c773ea12009-04-28 19:58:429444
9445 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:019446 EXPECT_THAT(rv, IsOk());
[email protected]1c773ea12009-04-28 19:58:429447}
9448
bncd16676a2016-07-20 16:23:019449TEST_F(HttpNetworkTransactionTest, BuildRequest_ExtraHeaders) {
[email protected]1c773ea12009-04-28 19:58:429450 HttpRequestInfo request;
9451 request.method = "GET";
bncce36dca22015-04-21 22:11:239452 request.url = GURL("http://www.example.org/");
[email protected]8c76ae22010-04-20 22:15:439453 request.extra_headers.SetHeader("FooHeader", "Bar");
[email protected]1c773ea12009-04-28 19:58:429454
danakj1fd259a02016-04-16 03:17:099455 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:169456 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:279457
[email protected]1c773ea12009-04-28 19:58:429458 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:239459 MockWrite(
9460 "GET / HTTP/1.1\r\n"
9461 "Host: www.example.org\r\n"
9462 "Connection: keep-alive\r\n"
9463 "FooHeader: Bar\r\n\r\n"),
[email protected]1c773ea12009-04-28 19:58:429464 };
9465
9466 // Lastly, the server responds with the actual content.
9467 MockRead data_reads[] = {
9468 MockRead("HTTP/1.0 200 OK\r\n"),
9469 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
9470 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:069471 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:429472 };
9473
[email protected]31a2bfe2010-02-09 08:03:399474 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
9475 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:079476 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:429477
[email protected]49639fa2011-12-20 23:22:419478 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:429479
tfarina42834112016-09-22 13:38:209480 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:019481 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]1c773ea12009-04-28 19:58:429482
9483 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:019484 EXPECT_THAT(rv, IsOk());
[email protected]1c773ea12009-04-28 19:58:429485}
9486
bncd16676a2016-07-20 16:23:019487TEST_F(HttpNetworkTransactionTest, BuildRequest_ExtraHeadersStripped) {
[email protected]270c6412010-03-29 22:02:479488 HttpRequestInfo request;
9489 request.method = "GET";
bncce36dca22015-04-21 22:11:239490 request.url = GURL("http://www.example.org/");
[email protected]8c76ae22010-04-20 22:15:439491 request.extra_headers.SetHeader("referer", "www.foo.com");
9492 request.extra_headers.SetHeader("hEllo", "Kitty");
9493 request.extra_headers.SetHeader("FoO", "bar");
[email protected]270c6412010-03-29 22:02:479494
danakj1fd259a02016-04-16 03:17:099495 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:169496 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:279497
[email protected]270c6412010-03-29 22:02:479498 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:239499 MockWrite(
9500 "GET / HTTP/1.1\r\n"
9501 "Host: www.example.org\r\n"
9502 "Connection: keep-alive\r\n"
9503 "referer: www.foo.com\r\n"
9504 "hEllo: Kitty\r\n"
9505 "FoO: bar\r\n\r\n"),
[email protected]270c6412010-03-29 22:02:479506 };
9507
9508 // Lastly, the server responds with the actual content.
9509 MockRead data_reads[] = {
9510 MockRead("HTTP/1.0 200 OK\r\n"),
9511 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
9512 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:069513 MockRead(SYNCHRONOUS, OK),
[email protected]270c6412010-03-29 22:02:479514 };
9515
9516 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
9517 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:079518 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]270c6412010-03-29 22:02:479519
[email protected]49639fa2011-12-20 23:22:419520 TestCompletionCallback callback;
[email protected]270c6412010-03-29 22:02:479521
tfarina42834112016-09-22 13:38:209522 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:019523 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]270c6412010-03-29 22:02:479524
9525 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:019526 EXPECT_THAT(rv, IsOk());
[email protected]270c6412010-03-29 22:02:479527}
9528
bncd16676a2016-07-20 16:23:019529TEST_F(HttpNetworkTransactionTest, SOCKS4_HTTP_GET) {
[email protected]cb9bf6ca2011-01-28 13:15:279530 HttpRequestInfo request;
9531 request.method = "GET";
bncce36dca22015-04-21 22:11:239532 request.url = GURL("http://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:279533
rdsmith82957ad2015-09-16 19:42:039534 session_deps_.proxy_service =
9535 ProxyService::CreateFixedFromPacResult("SOCKS myproxy:1080");
vishal.b62985ca92015-04-17 08:45:519536 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:079537 session_deps_.net_log = &net_log;
[email protected]3cd17242009-06-23 02:59:029538
danakj1fd259a02016-04-16 03:17:099539 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:169540 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]3cd17242009-06-23 02:59:029541
[email protected]3cd17242009-06-23 02:59:029542 char write_buffer[] = { 0x04, 0x01, 0x00, 0x50, 127, 0, 0, 1, 0 };
9543 char read_buffer[] = { 0x00, 0x5A, 0x00, 0x00, 0, 0, 0, 0 };
9544
9545 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:239546 MockWrite(ASYNC, write_buffer, arraysize(write_buffer)),
9547 MockWrite(
9548 "GET / HTTP/1.1\r\n"
9549 "Host: www.example.org\r\n"
9550 "Connection: keep-alive\r\n\r\n")};
[email protected]3cd17242009-06-23 02:59:029551
9552 MockRead data_reads[] = {
[email protected]8ddf8322012-02-23 18:08:069553 MockRead(ASYNC, read_buffer, arraysize(read_buffer)),
[email protected]3cd17242009-06-23 02:59:029554 MockRead("HTTP/1.0 200 OK\r\n"),
9555 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n\r\n"),
9556 MockRead("Payload"),
[email protected]8ddf8322012-02-23 18:08:069557 MockRead(SYNCHRONOUS, OK)
[email protected]3cd17242009-06-23 02:59:029558 };
9559
[email protected]31a2bfe2010-02-09 08:03:399560 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
9561 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:079562 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]3cd17242009-06-23 02:59:029563
[email protected]49639fa2011-12-20 23:22:419564 TestCompletionCallback callback;
[email protected]3cd17242009-06-23 02:59:029565
tfarina42834112016-09-22 13:38:209566 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:019567 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]3cd17242009-06-23 02:59:029568
9569 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:019570 EXPECT_THAT(rv, IsOk());
[email protected]3cd17242009-06-23 02:59:029571
bnc691fda62016-08-12 00:43:169572 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:529573 ASSERT_TRUE(response);
[email protected]3cd17242009-06-23 02:59:029574
tbansal2ecbbc72016-10-06 17:15:479575 EXPECT_EQ(ProxyServer::SCHEME_SOCKS4, response->proxy_server.scheme());
[email protected]029c83b62013-01-24 05:28:209576 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:169577 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]029c83b62013-01-24 05:28:209578 TestLoadTimingNotReusedWithPac(load_timing_info,
9579 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
9580
[email protected]3cd17242009-06-23 02:59:029581 std::string response_text;
bnc691fda62016-08-12 00:43:169582 rv = ReadTransaction(&trans, &response_text);
robpercival214763f2016-07-01 23:27:019583 EXPECT_THAT(rv, IsOk());
[email protected]3cd17242009-06-23 02:59:029584 EXPECT_EQ("Payload", response_text);
9585}
9586
bncd16676a2016-07-20 16:23:019587TEST_F(HttpNetworkTransactionTest, SOCKS4_SSL_GET) {
[email protected]cb9bf6ca2011-01-28 13:15:279588 HttpRequestInfo request;
9589 request.method = "GET";
bncce36dca22015-04-21 22:11:239590 request.url = GURL("https://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:279591
rdsmith82957ad2015-09-16 19:42:039592 session_deps_.proxy_service =
9593 ProxyService::CreateFixedFromPacResult("SOCKS myproxy:1080");
vishal.b62985ca92015-04-17 08:45:519594 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:079595 session_deps_.net_log = &net_log;
[email protected]3cd17242009-06-23 02:59:029596
danakj1fd259a02016-04-16 03:17:099597 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:169598 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]3cd17242009-06-23 02:59:029599
[email protected]3cd17242009-06-23 02:59:029600 unsigned char write_buffer[] = { 0x04, 0x01, 0x01, 0xBB, 127, 0, 0, 1, 0 };
9601 unsigned char read_buffer[] = { 0x00, 0x5A, 0x00, 0x00, 0, 0, 0, 0 };
9602
9603 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:239604 MockWrite(ASYNC, reinterpret_cast<char*>(write_buffer),
9605 arraysize(write_buffer)),
9606 MockWrite(
9607 "GET / HTTP/1.1\r\n"
9608 "Host: www.example.org\r\n"
9609 "Connection: keep-alive\r\n\r\n")};
[email protected]3cd17242009-06-23 02:59:029610
9611 MockRead data_reads[] = {
[email protected]f871ee152012-07-27 19:02:019612 MockRead(ASYNC, reinterpret_cast<char*>(read_buffer),
9613 arraysize(read_buffer)),
[email protected]e0c27be2009-07-15 13:09:359614 MockRead("HTTP/1.0 200 OK\r\n"),
9615 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n\r\n"),
9616 MockRead("Payload"),
[email protected]8ddf8322012-02-23 18:08:069617 MockRead(SYNCHRONOUS, OK)
[email protected]e0c27be2009-07-15 13:09:359618 };
9619
[email protected]31a2bfe2010-02-09 08:03:399620 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
9621 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:079622 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]e0c27be2009-07-15 13:09:359623
[email protected]8ddf8322012-02-23 18:08:069624 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:079625 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]e0c27be2009-07-15 13:09:359626
[email protected]49639fa2011-12-20 23:22:419627 TestCompletionCallback callback;
[email protected]e0c27be2009-07-15 13:09:359628
tfarina42834112016-09-22 13:38:209629 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:019630 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]e0c27be2009-07-15 13:09:359631
9632 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:019633 EXPECT_THAT(rv, IsOk());
[email protected]e0c27be2009-07-15 13:09:359634
[email protected]029c83b62013-01-24 05:28:209635 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:169636 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]029c83b62013-01-24 05:28:209637 TestLoadTimingNotReusedWithPac(load_timing_info,
9638 CONNECT_TIMING_HAS_SSL_TIMES);
9639
bnc691fda62016-08-12 00:43:169640 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:529641 ASSERT_TRUE(response);
tbansal2ecbbc72016-10-06 17:15:479642 EXPECT_EQ(ProxyServer::SCHEME_SOCKS4, response->proxy_server.scheme());
[email protected]e0c27be2009-07-15 13:09:359643
9644 std::string response_text;
bnc691fda62016-08-12 00:43:169645 rv = ReadTransaction(&trans, &response_text);
robpercival214763f2016-07-01 23:27:019646 EXPECT_THAT(rv, IsOk());
[email protected]e0c27be2009-07-15 13:09:359647 EXPECT_EQ("Payload", response_text);
9648}
9649
bncd16676a2016-07-20 16:23:019650TEST_F(HttpNetworkTransactionTest, SOCKS4_HTTP_GET_no_PAC) {
[email protected]029c83b62013-01-24 05:28:209651 HttpRequestInfo request;
9652 request.method = "GET";
bncce36dca22015-04-21 22:11:239653 request.url = GURL("http://www.example.org/");
[email protected]029c83b62013-01-24 05:28:209654
rdsmith82957ad2015-09-16 19:42:039655 session_deps_.proxy_service =
9656 ProxyService::CreateFixed("socks4://myproxy:1080");
vishal.b62985ca92015-04-17 08:45:519657 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:079658 session_deps_.net_log = &net_log;
[email protected]029c83b62013-01-24 05:28:209659
danakj1fd259a02016-04-16 03:17:099660 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:169661 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]029c83b62013-01-24 05:28:209662
9663 char write_buffer[] = { 0x04, 0x01, 0x00, 0x50, 127, 0, 0, 1, 0 };
9664 char read_buffer[] = { 0x00, 0x5A, 0x00, 0x00, 0, 0, 0, 0 };
9665
9666 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:239667 MockWrite(ASYNC, write_buffer, arraysize(write_buffer)),
9668 MockWrite(
9669 "GET / HTTP/1.1\r\n"
9670 "Host: www.example.org\r\n"
9671 "Connection: keep-alive\r\n\r\n")};
[email protected]029c83b62013-01-24 05:28:209672
9673 MockRead data_reads[] = {
9674 MockRead(ASYNC, read_buffer, arraysize(read_buffer)),
9675 MockRead("HTTP/1.0 200 OK\r\n"),
9676 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n\r\n"),
9677 MockRead("Payload"),
9678 MockRead(SYNCHRONOUS, OK)
9679 };
9680
9681 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
9682 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:079683 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]029c83b62013-01-24 05:28:209684
9685 TestCompletionCallback callback;
9686
tfarina42834112016-09-22 13:38:209687 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:019688 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]029c83b62013-01-24 05:28:209689
9690 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:019691 EXPECT_THAT(rv, IsOk());
[email protected]029c83b62013-01-24 05:28:209692
bnc691fda62016-08-12 00:43:169693 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:529694 ASSERT_TRUE(response);
[email protected]029c83b62013-01-24 05:28:209695
9696 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:169697 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]029c83b62013-01-24 05:28:209698 TestLoadTimingNotReused(load_timing_info,
9699 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
9700
9701 std::string response_text;
bnc691fda62016-08-12 00:43:169702 rv = ReadTransaction(&trans, &response_text);
robpercival214763f2016-07-01 23:27:019703 EXPECT_THAT(rv, IsOk());
[email protected]029c83b62013-01-24 05:28:209704 EXPECT_EQ("Payload", response_text);
9705}
9706
bncd16676a2016-07-20 16:23:019707TEST_F(HttpNetworkTransactionTest, SOCKS5_HTTP_GET) {
[email protected]cb9bf6ca2011-01-28 13:15:279708 HttpRequestInfo request;
9709 request.method = "GET";
bncce36dca22015-04-21 22:11:239710 request.url = GURL("http://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:279711
rdsmith82957ad2015-09-16 19:42:039712 session_deps_.proxy_service =
9713 ProxyService::CreateFixedFromPacResult("SOCKS5 myproxy:1080");
vishal.b62985ca92015-04-17 08:45:519714 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:079715 session_deps_.net_log = &net_log;
[email protected]e0c27be2009-07-15 13:09:359716
danakj1fd259a02016-04-16 03:17:099717 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:169718 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]e0c27be2009-07-15 13:09:359719
[email protected]e0c27be2009-07-15 13:09:359720 const char kSOCKS5GreetRequest[] = { 0x05, 0x01, 0x00 };
9721 const char kSOCKS5GreetResponse[] = { 0x05, 0x00 };
[email protected]f209dba2009-12-18 00:24:379722 const char kSOCKS5OkRequest[] = {
bncce36dca22015-04-21 22:11:239723 0x05, // Version
9724 0x01, // Command (CONNECT)
9725 0x00, // Reserved.
9726 0x03, // Address type (DOMAINNAME).
9727 0x0F, // Length of domain (15)
9728 'w', 'w', 'w', '.', 'e', 'x', 'a', 'm', 'p', 'l', 'e', // Domain string
9729 '.', 'o', 'r', 'g', 0x00, 0x50, // 16-bit port (80)
[email protected]f209dba2009-12-18 00:24:379730 };
[email protected]e0c27be2009-07-15 13:09:359731 const char kSOCKS5OkResponse[] =
9732 { 0x05, 0x00, 0x00, 0x01, 127, 0, 0, 1, 0x00, 0x50 };
9733
9734 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:239735 MockWrite(ASYNC, kSOCKS5GreetRequest, arraysize(kSOCKS5GreetRequest)),
9736 MockWrite(ASYNC, kSOCKS5OkRequest, arraysize(kSOCKS5OkRequest)),
9737 MockWrite(
9738 "GET / HTTP/1.1\r\n"
9739 "Host: www.example.org\r\n"
9740 "Connection: keep-alive\r\n\r\n")};
[email protected]e0c27be2009-07-15 13:09:359741
9742 MockRead data_reads[] = {
[email protected]f871ee152012-07-27 19:02:019743 MockRead(ASYNC, kSOCKS5GreetResponse, arraysize(kSOCKS5GreetResponse)),
9744 MockRead(ASYNC, kSOCKS5OkResponse, arraysize(kSOCKS5OkResponse)),
[email protected]e0c27be2009-07-15 13:09:359745 MockRead("HTTP/1.0 200 OK\r\n"),
9746 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n\r\n"),
9747 MockRead("Payload"),
[email protected]8ddf8322012-02-23 18:08:069748 MockRead(SYNCHRONOUS, OK)
[email protected]e0c27be2009-07-15 13:09:359749 };
9750
[email protected]31a2bfe2010-02-09 08:03:399751 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
9752 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:079753 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]e0c27be2009-07-15 13:09:359754
[email protected]49639fa2011-12-20 23:22:419755 TestCompletionCallback callback;
[email protected]e0c27be2009-07-15 13:09:359756
tfarina42834112016-09-22 13:38:209757 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:019758 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]e0c27be2009-07-15 13:09:359759
9760 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:019761 EXPECT_THAT(rv, IsOk());
[email protected]e0c27be2009-07-15 13:09:359762
bnc691fda62016-08-12 00:43:169763 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:529764 ASSERT_TRUE(response);
tbansal2ecbbc72016-10-06 17:15:479765 EXPECT_EQ(ProxyServer::SCHEME_SOCKS5, response->proxy_server.scheme());
[email protected]e0c27be2009-07-15 13:09:359766
[email protected]029c83b62013-01-24 05:28:209767 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:169768 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]029c83b62013-01-24 05:28:209769 TestLoadTimingNotReusedWithPac(load_timing_info,
9770 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
9771
[email protected]e0c27be2009-07-15 13:09:359772 std::string response_text;
bnc691fda62016-08-12 00:43:169773 rv = ReadTransaction(&trans, &response_text);
robpercival214763f2016-07-01 23:27:019774 EXPECT_THAT(rv, IsOk());
[email protected]e0c27be2009-07-15 13:09:359775 EXPECT_EQ("Payload", response_text);
9776}
9777
bncd16676a2016-07-20 16:23:019778TEST_F(HttpNetworkTransactionTest, SOCKS5_SSL_GET) {
[email protected]cb9bf6ca2011-01-28 13:15:279779 HttpRequestInfo request;
9780 request.method = "GET";
bncce36dca22015-04-21 22:11:239781 request.url = GURL("https://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:279782
rdsmith82957ad2015-09-16 19:42:039783 session_deps_.proxy_service =
9784 ProxyService::CreateFixedFromPacResult("SOCKS5 myproxy:1080");
vishal.b62985ca92015-04-17 08:45:519785 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:079786 session_deps_.net_log = &net_log;
[email protected]e0c27be2009-07-15 13:09:359787
danakj1fd259a02016-04-16 03:17:099788 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:169789 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]e0c27be2009-07-15 13:09:359790
[email protected]e0c27be2009-07-15 13:09:359791 const char kSOCKS5GreetRequest[] = { 0x05, 0x01, 0x00 };
9792 const char kSOCKS5GreetResponse[] = { 0x05, 0x00 };
[email protected]f209dba2009-12-18 00:24:379793 const unsigned char kSOCKS5OkRequest[] = {
bncce36dca22015-04-21 22:11:239794 0x05, // Version
9795 0x01, // Command (CONNECT)
9796 0x00, // Reserved.
9797 0x03, // Address type (DOMAINNAME).
9798 0x0F, // Length of domain (15)
9799 'w', 'w', 'w', '.', 'e', 'x', 'a', 'm', 'p', 'l', 'e', // Domain string
9800 '.', 'o', 'r', 'g', 0x01, 0xBB, // 16-bit port (443)
[email protected]f209dba2009-12-18 00:24:379801 };
9802
[email protected]e0c27be2009-07-15 13:09:359803 const char kSOCKS5OkResponse[] =
9804 { 0x05, 0x00, 0x00, 0x01, 0, 0, 0, 0, 0x00, 0x00 };
9805
9806 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:239807 MockWrite(ASYNC, kSOCKS5GreetRequest, arraysize(kSOCKS5GreetRequest)),
9808 MockWrite(ASYNC, reinterpret_cast<const char*>(kSOCKS5OkRequest),
9809 arraysize(kSOCKS5OkRequest)),
9810 MockWrite(
9811 "GET / HTTP/1.1\r\n"
9812 "Host: www.example.org\r\n"
9813 "Connection: keep-alive\r\n\r\n")};
[email protected]e0c27be2009-07-15 13:09:359814
9815 MockRead data_reads[] = {
[email protected]f871ee152012-07-27 19:02:019816 MockRead(ASYNC, kSOCKS5GreetResponse, arraysize(kSOCKS5GreetResponse)),
9817 MockRead(ASYNC, kSOCKS5OkResponse, arraysize(kSOCKS5OkResponse)),
[email protected]3cd17242009-06-23 02:59:029818 MockRead("HTTP/1.0 200 OK\r\n"),
9819 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n\r\n"),
9820 MockRead("Payload"),
[email protected]8ddf8322012-02-23 18:08:069821 MockRead(SYNCHRONOUS, OK)
[email protected]3cd17242009-06-23 02:59:029822 };
9823
[email protected]31a2bfe2010-02-09 08:03:399824 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
9825 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:079826 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]3cd17242009-06-23 02:59:029827
[email protected]8ddf8322012-02-23 18:08:069828 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:079829 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]3cd17242009-06-23 02:59:029830
[email protected]49639fa2011-12-20 23:22:419831 TestCompletionCallback callback;
[email protected]3cd17242009-06-23 02:59:029832
tfarina42834112016-09-22 13:38:209833 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:019834 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]3cd17242009-06-23 02:59:029835
9836 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:019837 EXPECT_THAT(rv, IsOk());
[email protected]3cd17242009-06-23 02:59:029838
bnc691fda62016-08-12 00:43:169839 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:529840 ASSERT_TRUE(response);
tbansal2ecbbc72016-10-06 17:15:479841 EXPECT_EQ(ProxyServer::SCHEME_SOCKS5, response->proxy_server.scheme());
[email protected]3cd17242009-06-23 02:59:029842
[email protected]029c83b62013-01-24 05:28:209843 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:169844 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]029c83b62013-01-24 05:28:209845 TestLoadTimingNotReusedWithPac(load_timing_info,
9846 CONNECT_TIMING_HAS_SSL_TIMES);
9847
[email protected]3cd17242009-06-23 02:59:029848 std::string response_text;
bnc691fda62016-08-12 00:43:169849 rv = ReadTransaction(&trans, &response_text);
robpercival214763f2016-07-01 23:27:019850 EXPECT_THAT(rv, IsOk());
[email protected]3cd17242009-06-23 02:59:029851 EXPECT_EQ("Payload", response_text);
9852}
9853
[email protected]448d4ca52012-03-04 04:12:239854namespace {
9855
[email protected]04e5be32009-06-26 20:00:319856// Tests that for connection endpoints the group names are correctly set.
[email protected]2d731a32010-04-29 01:04:069857
9858struct GroupNameTest {
9859 std::string proxy_server;
9860 std::string url;
9861 std::string expected_group_name;
[email protected]e60e47a2010-07-14 03:37:189862 bool ssl;
[email protected]2d731a32010-04-29 01:04:069863};
9864
danakj1fd259a02016-04-16 03:17:099865std::unique_ptr<HttpNetworkSession> SetupSessionForGroupNameTests(
[email protected]bb88e1d32013-05-03 23:11:079866 SpdySessionDependencies* session_deps_) {
danakj1fd259a02016-04-16 03:17:099867 std::unique_ptr<HttpNetworkSession> session(CreateSession(session_deps_));
[email protected]2d731a32010-04-29 01:04:069868
bnc525e175a2016-06-20 12:36:409869 HttpServerProperties* http_server_properties =
[email protected]17291a022011-10-10 07:32:539870 session->http_server_properties();
bnc3472afd2016-11-17 15:27:219871 AlternativeService alternative_service(kProtoHTTP2, "", 444);
bnc7dc7e1b42015-07-28 14:43:129872 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:219873 http_server_properties->SetHttp2AlternativeService(
bncaa60ff402016-06-22 19:12:429874 url::SchemeHostPort("https", "host.with.alternate", 443),
zhongyi3d4a55e72016-04-22 20:36:469875 alternative_service, expiration);
[email protected]2d731a32010-04-29 01:04:069876
9877 return session;
9878}
9879
mmenkee65e7af2015-10-13 17:16:429880int GroupNameTransactionHelper(const std::string& url,
9881 HttpNetworkSession* session) {
[email protected]2d731a32010-04-29 01:04:069882 HttpRequestInfo request;
9883 request.method = "GET";
9884 request.url = GURL(url);
[email protected]2d731a32010-04-29 01:04:069885
bnc691fda62016-08-12 00:43:169886 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session);
[email protected]cb9bf6ca2011-01-28 13:15:279887
[email protected]49639fa2011-12-20 23:22:419888 TestCompletionCallback callback;
[email protected]2d731a32010-04-29 01:04:069889
9890 // We do not complete this request, the dtor will clean the transaction up.
tfarina42834112016-09-22 13:38:209891 return trans.Start(&request, callback.callback(), NetLogWithSource());
[email protected]2d731a32010-04-29 01:04:069892}
9893
[email protected]448d4ca52012-03-04 04:12:239894} // namespace
9895
bncd16676a2016-07-20 16:23:019896TEST_F(HttpNetworkTransactionTest, GroupNameForDirectConnections) {
[email protected]2d731a32010-04-29 01:04:069897 const GroupNameTest tests[] = {
bncce36dca22015-04-21 22:11:239898 {
9899 "", // unused
9900 "http://www.example.org/direct",
9901 "www.example.org:80",
9902 false,
9903 },
9904 {
9905 "", // unused
9906 "http://[2001:1418:13:1::25]/direct",
9907 "[2001:1418:13:1::25]:80",
9908 false,
9909 },
[email protected]04e5be32009-06-26 20:00:319910
bncce36dca22015-04-21 22:11:239911 // SSL Tests
9912 {
9913 "", // unused
9914 "https://www.example.org/direct_ssl",
9915 "ssl/www.example.org:443",
9916 true,
9917 },
9918 {
9919 "", // unused
9920 "https://[2001:1418:13:1::25]/direct",
9921 "ssl/[2001:1418:13:1::25]:443",
9922 true,
9923 },
9924 {
9925 "", // unused
bncaa60ff402016-06-22 19:12:429926 "https://host.with.alternate/direct",
bncce36dca22015-04-21 22:11:239927 "ssl/host.with.alternate:443",
9928 true,
9929 },
[email protected]2d731a32010-04-29 01:04:069930 };
[email protected]2ff8b312010-04-26 22:20:549931
viettrungluue4a8b882014-10-16 06:17:389932 for (size_t i = 0; i < arraysize(tests); ++i) {
rdsmith82957ad2015-09-16 19:42:039933 session_deps_.proxy_service =
9934 ProxyService::CreateFixed(tests[i].proxy_server);
danakj1fd259a02016-04-16 03:17:099935 std::unique_ptr<HttpNetworkSession> session(
bnca9b9e222016-07-11 20:10:409936 SetupSessionForGroupNameTests(&session_deps_));
[email protected]2d731a32010-04-29 01:04:069937
mmenkee65e7af2015-10-13 17:16:429938 HttpNetworkSessionPeer peer(session.get());
[email protected]ab739042011-04-07 15:22:289939 CaptureGroupNameTransportSocketPool* transport_conn_pool =
bnc87dcefc2017-05-25 12:47:589940 new CaptureGroupNameTransportSocketPool(nullptr, nullptr);
[email protected]2431756e2010-09-29 20:26:139941 CaptureGroupNameSSLSocketPool* ssl_conn_pool =
bnc87dcefc2017-05-25 12:47:589942 new CaptureGroupNameSSLSocketPool(nullptr, nullptr);
Jeremy Roman0579ed62017-08-29 15:56:199943 auto mock_pool_manager = std::make_unique<MockClientSocketPoolManager>();
[email protected]a42dbd142011-11-17 16:42:029944 mock_pool_manager->SetTransportSocketPool(transport_conn_pool);
9945 mock_pool_manager->SetSSLSocketPool(ssl_conn_pool);
dchengc7eeda422015-12-26 03:56:489946 peer.SetClientSocketPoolManager(std::move(mock_pool_manager));
[email protected]2d731a32010-04-29 01:04:069947
9948 EXPECT_EQ(ERR_IO_PENDING,
mmenkee65e7af2015-10-13 17:16:429949 GroupNameTransactionHelper(tests[i].url, session.get()));
Tarun Bansal162eabe52018-01-20 01:16:399950 if (tests[i].ssl) {
[email protected]e60e47a2010-07-14 03:37:189951 EXPECT_EQ(tests[i].expected_group_name,
9952 ssl_conn_pool->last_group_name_received());
Tarun Bansal162eabe52018-01-20 01:16:399953 } else {
[email protected]e60e47a2010-07-14 03:37:189954 EXPECT_EQ(tests[i].expected_group_name,
[email protected]ab739042011-04-07 15:22:289955 transport_conn_pool->last_group_name_received());
Tarun Bansal162eabe52018-01-20 01:16:399956 }
9957 // When SSL proxy is in use, socket must be requested from |ssl_conn_pool|.
9958 EXPECT_EQ(tests[i].ssl, ssl_conn_pool->socket_requested());
9959 // When SSL proxy is not in use, socket must be requested from
9960 // |transport_conn_pool|.
9961 EXPECT_EQ(!tests[i].ssl, transport_conn_pool->socket_requested());
[email protected]2d731a32010-04-29 01:04:069962 }
[email protected]2d731a32010-04-29 01:04:069963}
9964
bncd16676a2016-07-20 16:23:019965TEST_F(HttpNetworkTransactionTest, GroupNameForHTTPProxyConnections) {
[email protected]2d731a32010-04-29 01:04:069966 const GroupNameTest tests[] = {
bncce36dca22015-04-21 22:11:239967 {
Matt Menked1eb6d42018-01-17 04:54:069968 "http_proxy", "http://www.example.org/http_proxy_normal",
9969 "http_proxy/www.example.org:80", false,
bncce36dca22015-04-21 22:11:239970 },
[email protected]2d731a32010-04-29 01:04:069971
bncce36dca22015-04-21 22:11:239972 // SSL Tests
9973 {
Matt Menked1eb6d42018-01-17 04:54:069974 "http_proxy", "https://www.example.org/http_connect_ssl",
9975 "http_proxy/ssl/www.example.org:443", true,
bncce36dca22015-04-21 22:11:239976 },
[email protected]af3490e2010-10-16 21:02:299977
bncce36dca22015-04-21 22:11:239978 {
Matt Menked1eb6d42018-01-17 04:54:069979 "http_proxy", "https://host.with.alternate/direct",
9980 "http_proxy/ssl/host.with.alternate:443", true,
bncce36dca22015-04-21 22:11:239981 },
[email protected]45499252013-01-23 17:12:569982
bncce36dca22015-04-21 22:11:239983 {
Matt Menked1eb6d42018-01-17 04:54:069984 "http_proxy", "ftp://ftp.google.com/http_proxy_normal",
9985 "http_proxy/ftp/ftp.google.com:21", false,
bncce36dca22015-04-21 22:11:239986 },
[email protected]2d731a32010-04-29 01:04:069987 };
9988
viettrungluue4a8b882014-10-16 06:17:389989 for (size_t i = 0; i < arraysize(tests); ++i) {
rdsmith82957ad2015-09-16 19:42:039990 session_deps_.proxy_service =
9991 ProxyService::CreateFixed(tests[i].proxy_server);
danakj1fd259a02016-04-16 03:17:099992 std::unique_ptr<HttpNetworkSession> session(
bnca9b9e222016-07-11 20:10:409993 SetupSessionForGroupNameTests(&session_deps_));
[email protected]2d731a32010-04-29 01:04:069994
mmenkee65e7af2015-10-13 17:16:429995 HttpNetworkSessionPeer peer(session.get());
[email protected]2d731a32010-04-29 01:04:069996
[email protected]e60e47a2010-07-14 03:37:189997 HostPortPair proxy_host("http_proxy", 80);
[email protected]2431756e2010-09-29 20:26:139998 CaptureGroupNameHttpProxySocketPool* http_proxy_pool =
[email protected]9e1bdd32011-02-03 21:48:349999 new CaptureGroupNameHttpProxySocketPool(NULL, NULL);
[email protected]2431756e2010-09-29 20:26:1310000 CaptureGroupNameSSLSocketPool* ssl_conn_pool =
[email protected]9e1bdd32011-02-03 21:48:3410001 new CaptureGroupNameSSLSocketPool(NULL, NULL);
Jeremy Roman0579ed62017-08-29 15:56:1910002 auto mock_pool_manager = std::make_unique<MockClientSocketPoolManager>();
aviadef3442016-10-03 18:50:3910003 mock_pool_manager->SetSocketPoolForHTTPProxy(
10004 proxy_host, base::WrapUnique(http_proxy_pool));
10005 mock_pool_manager->SetSocketPoolForSSLWithProxy(
10006 proxy_host, base::WrapUnique(ssl_conn_pool));
dchengc7eeda422015-12-26 03:56:4810007 peer.SetClientSocketPoolManager(std::move(mock_pool_manager));
[email protected]2d731a32010-04-29 01:04:0610008
10009 EXPECT_EQ(ERR_IO_PENDING,
mmenkee65e7af2015-10-13 17:16:4210010 GroupNameTransactionHelper(tests[i].url, session.get()));
[email protected]e60e47a2010-07-14 03:37:1810011 if (tests[i].ssl)
10012 EXPECT_EQ(tests[i].expected_group_name,
10013 ssl_conn_pool->last_group_name_received());
10014 else
10015 EXPECT_EQ(tests[i].expected_group_name,
10016 http_proxy_pool->last_group_name_received());
[email protected]2d731a32010-04-29 01:04:0610017 }
[email protected]2d731a32010-04-29 01:04:0610018}
10019
bncd16676a2016-07-20 16:23:0110020TEST_F(HttpNetworkTransactionTest, GroupNameForSOCKSConnections) {
[email protected]2d731a32010-04-29 01:04:0610021 const GroupNameTest tests[] = {
bncce36dca22015-04-21 22:11:2310022 {
10023 "socks4://socks_proxy:1080",
10024 "http://www.example.org/socks4_direct",
10025 "socks4/www.example.org:80",
10026 false,
10027 },
10028 {
10029 "socks5://socks_proxy:1080",
10030 "http://www.example.org/socks5_direct",
10031 "socks5/www.example.org:80",
10032 false,
10033 },
[email protected]2d731a32010-04-29 01:04:0610034
bncce36dca22015-04-21 22:11:2310035 // SSL Tests
10036 {
10037 "socks4://socks_proxy:1080",
10038 "https://www.example.org/socks4_ssl",
10039 "socks4/ssl/www.example.org:443",
10040 true,
10041 },
10042 {
10043 "socks5://socks_proxy:1080",
10044 "https://www.example.org/socks5_ssl",
10045 "socks5/ssl/www.example.org:443",
10046 true,
10047 },
[email protected]af3490e2010-10-16 21:02:2910048
bncce36dca22015-04-21 22:11:2310049 {
10050 "socks4://socks_proxy:1080",
bncaa60ff402016-06-22 19:12:4210051 "https://host.with.alternate/direct",
bncce36dca22015-04-21 22:11:2310052 "socks4/ssl/host.with.alternate:443",
10053 true,
10054 },
[email protected]04e5be32009-06-26 20:00:3110055 };
10056
viettrungluue4a8b882014-10-16 06:17:3810057 for (size_t i = 0; i < arraysize(tests); ++i) {
rdsmith82957ad2015-09-16 19:42:0310058 session_deps_.proxy_service =
10059 ProxyService::CreateFixed(tests[i].proxy_server);
danakj1fd259a02016-04-16 03:17:0910060 std::unique_ptr<HttpNetworkSession> session(
bnca9b9e222016-07-11 20:10:4010061 SetupSessionForGroupNameTests(&session_deps_));
[email protected]8b114dd72011-03-25 05:33:0210062
mmenkee65e7af2015-10-13 17:16:4210063 HttpNetworkSessionPeer peer(session.get());
[email protected]04e5be32009-06-26 20:00:3110064
[email protected]e60e47a2010-07-14 03:37:1810065 HostPortPair proxy_host("socks_proxy", 1080);
[email protected]2431756e2010-09-29 20:26:1310066 CaptureGroupNameSOCKSSocketPool* socks_conn_pool =
[email protected]9e1bdd32011-02-03 21:48:3410067 new CaptureGroupNameSOCKSSocketPool(NULL, NULL);
[email protected]2431756e2010-09-29 20:26:1310068 CaptureGroupNameSSLSocketPool* ssl_conn_pool =
[email protected]9e1bdd32011-02-03 21:48:3410069 new CaptureGroupNameSSLSocketPool(NULL, NULL);
Jeremy Roman0579ed62017-08-29 15:56:1910070 auto mock_pool_manager = std::make_unique<MockClientSocketPoolManager>();
aviadef3442016-10-03 18:50:3910071 mock_pool_manager->SetSocketPoolForSOCKSProxy(
10072 proxy_host, base::WrapUnique(socks_conn_pool));
10073 mock_pool_manager->SetSocketPoolForSSLWithProxy(
10074 proxy_host, base::WrapUnique(ssl_conn_pool));
dchengc7eeda422015-12-26 03:56:4810075 peer.SetClientSocketPoolManager(std::move(mock_pool_manager));
[email protected]04e5be32009-06-26 20:00:3110076
bnc691fda62016-08-12 00:43:1610077 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]04e5be32009-06-26 20:00:3110078
[email protected]2d731a32010-04-29 01:04:0610079 EXPECT_EQ(ERR_IO_PENDING,
mmenkee65e7af2015-10-13 17:16:4210080 GroupNameTransactionHelper(tests[i].url, session.get()));
[email protected]e60e47a2010-07-14 03:37:1810081 if (tests[i].ssl)
10082 EXPECT_EQ(tests[i].expected_group_name,
10083 ssl_conn_pool->last_group_name_received());
10084 else
10085 EXPECT_EQ(tests[i].expected_group_name,
10086 socks_conn_pool->last_group_name_received());
[email protected]04e5be32009-06-26 20:00:3110087 }
10088}
10089
bncd16676a2016-07-20 16:23:0110090TEST_F(HttpNetworkTransactionTest, ReconsiderProxyAfterFailedConnection) {
[email protected]cb9bf6ca2011-01-28 13:15:2710091 HttpRequestInfo request;
10092 request.method = "GET";
bncce36dca22015-04-21 22:11:2310093 request.url = GURL("http://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:2710094
rdsmith82957ad2015-09-16 19:42:0310095 session_deps_.proxy_service =
10096 ProxyService::CreateFixed("myproxy:70;foobar:80");
[email protected]b59ff372009-07-15 22:04:3210097
[email protected]69719062010-01-05 20:09:2110098 // This simulates failure resolving all hostnames; that means we will fail
10099 // connecting to both proxies (myproxy:70 and foobar:80).
[email protected]bb88e1d32013-05-03 23:11:0710100 session_deps_.host_resolver->rules()->AddSimulatedFailure("*");
[email protected]b59ff372009-07-15 22:04:3210101
danakj1fd259a02016-04-16 03:17:0910102 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1610103 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]9172a982009-06-06 00:30:2510104
[email protected]49639fa2011-12-20 23:22:4110105 TestCompletionCallback callback;
[email protected]9172a982009-06-06 00:30:2510106
tfarina42834112016-09-22 13:38:2010107 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110108 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]9172a982009-06-06 00:30:2510109
[email protected]9172a982009-06-06 00:30:2510110 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0110111 EXPECT_THAT(rv, IsError(ERR_PROXY_CONNECTION_FAILED));
[email protected]9172a982009-06-06 00:30:2510112}
10113
[email protected]685af592010-05-11 19:31:2410114// Base test to make sure that when the load flags for a request specify to
10115// bypass the cache, the DNS cache is not used.
[email protected]23e482282013-06-14 16:08:0210116void HttpNetworkTransactionTest::BypassHostCacheOnRefreshHelper(
[email protected]bb88e1d32013-05-03 23:11:0710117 int load_flags) {
[email protected]cb9bf6ca2011-01-28 13:15:2710118 // Issue a request, asking to bypass the cache(s).
maksim.sisov31452af2016-07-27 06:38:1010119 HttpRequestInfo request_info;
10120 request_info.method = "GET";
10121 request_info.load_flags = load_flags;
10122 request_info.url = GURL("http://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:2710123
[email protected]a2c2fb92009-07-18 07:31:0410124 // Select a host resolver that does caching.
Jeremy Roman0579ed62017-08-29 15:56:1910125 session_deps_.host_resolver = std::make_unique<MockCachingHostResolver>();
[email protected]b59ff372009-07-15 22:04:3210126
danakj1fd259a02016-04-16 03:17:0910127 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1610128 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]3b9cca42009-06-16 01:08:2810129
bncce36dca22015-04-21 22:11:2310130 // Warm up the host cache so it has an entry for "www.example.org".
[email protected]3b9cca42009-06-16 01:08:2810131 AddressList addrlist;
[email protected]aa22b242011-11-16 18:58:2910132 TestCompletionCallback callback;
maksim.sisov31452af2016-07-27 06:38:1010133 std::unique_ptr<HostResolver::Request> request1;
[email protected]bb88e1d32013-05-03 23:11:0710134 int rv = session_deps_.host_resolver->Resolve(
bncce36dca22015-04-21 22:11:2310135 HostResolver::RequestInfo(HostPortPair("www.example.org", 80)),
maksim.sisov31452af2016-07-27 06:38:1010136 DEFAULT_PRIORITY, &addrlist, callback.callback(), &request1,
tfarina42834112016-09-22 13:38:2010137 NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110138 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]6e78dfb2011-07-28 21:34:4710139 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0110140 EXPECT_THAT(rv, IsOk());
[email protected]3b9cca42009-06-16 01:08:2810141
10142 // Verify that it was added to host cache, by doing a subsequent async lookup
10143 // and confirming it completes synchronously.
maksim.sisov31452af2016-07-27 06:38:1010144 std::unique_ptr<HostResolver::Request> request2;
[email protected]bb88e1d32013-05-03 23:11:0710145 rv = session_deps_.host_resolver->Resolve(
bncce36dca22015-04-21 22:11:2310146 HostResolver::RequestInfo(HostPortPair("www.example.org", 80)),
maksim.sisov31452af2016-07-27 06:38:1010147 DEFAULT_PRIORITY, &addrlist, callback.callback(), &request2,
tfarina42834112016-09-22 13:38:2010148 NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110149 ASSERT_THAT(rv, IsOk());
[email protected]3b9cca42009-06-16 01:08:2810150
bncce36dca22015-04-21 22:11:2310151 // Inject a failure the next time that "www.example.org" is resolved. This way
[email protected]3b9cca42009-06-16 01:08:2810152 // we can tell if the next lookup hit the cache, or the "network".
10153 // (cache --> success, "network" --> failure).
bncce36dca22015-04-21 22:11:2310154 session_deps_.host_resolver->rules()->AddSimulatedFailure("www.example.org");
[email protected]3b9cca42009-06-16 01:08:2810155
10156 // Connect up a mock socket which will fail with ERR_UNEXPECTED during the
10157 // first read -- this won't be reached as the host resolution will fail first.
[email protected]8ddf8322012-02-23 18:08:0610158 MockRead data_reads[] = { MockRead(SYNCHRONOUS, ERR_UNEXPECTED) };
[email protected]31a2bfe2010-02-09 08:03:3910159 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0710160 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]3b9cca42009-06-16 01:08:2810161
[email protected]3b9cca42009-06-16 01:08:2810162 // Run the request.
tfarina42834112016-09-22 13:38:2010163 rv = trans.Start(&request_info, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110164 ASSERT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]49639fa2011-12-20 23:22:4110165 rv = callback.WaitForResult();
[email protected]3b9cca42009-06-16 01:08:2810166
10167 // If we bypassed the cache, we would have gotten a failure while resolving
bncce36dca22015-04-21 22:11:2310168 // "www.example.org".
robpercival214763f2016-07-01 23:27:0110169 EXPECT_THAT(rv, IsError(ERR_NAME_NOT_RESOLVED));
[email protected]3b9cca42009-06-16 01:08:2810170}
10171
[email protected]685af592010-05-11 19:31:2410172// There are multiple load flags that should trigger the host cache bypass.
10173// Test each in isolation:
bncd16676a2016-07-20 16:23:0110174TEST_F(HttpNetworkTransactionTest, BypassHostCacheOnRefresh1) {
[email protected]685af592010-05-11 19:31:2410175 BypassHostCacheOnRefreshHelper(LOAD_BYPASS_CACHE);
10176}
10177
bncd16676a2016-07-20 16:23:0110178TEST_F(HttpNetworkTransactionTest, BypassHostCacheOnRefresh2) {
[email protected]685af592010-05-11 19:31:2410179 BypassHostCacheOnRefreshHelper(LOAD_VALIDATE_CACHE);
10180}
10181
bncd16676a2016-07-20 16:23:0110182TEST_F(HttpNetworkTransactionTest, BypassHostCacheOnRefresh3) {
[email protected]685af592010-05-11 19:31:2410183 BypassHostCacheOnRefreshHelper(LOAD_DISABLE_CACHE);
10184}
10185
[email protected]0877e3d2009-10-17 22:29:5710186// Make sure we can handle an error when writing the request.
bncd16676a2016-07-20 16:23:0110187TEST_F(HttpNetworkTransactionTest, RequestWriteError) {
[email protected]0877e3d2009-10-17 22:29:5710188 HttpRequestInfo request;
10189 request.method = "GET";
10190 request.url = GURL("http://www.foo.com/");
[email protected]0877e3d2009-10-17 22:29:5710191
10192 MockWrite write_failure[] = {
[email protected]8ddf8322012-02-23 18:08:0610193 MockWrite(ASYNC, ERR_CONNECTION_RESET),
[email protected]0877e3d2009-10-17 22:29:5710194 };
[email protected]31a2bfe2010-02-09 08:03:3910195 StaticSocketDataProvider data(NULL, 0,
10196 write_failure, arraysize(write_failure));
[email protected]bb88e1d32013-05-03 23:11:0710197 session_deps_.socket_factory->AddSocketDataProvider(&data);
danakj1fd259a02016-04-16 03:17:0910198 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]0877e3d2009-10-17 22:29:5710199
[email protected]49639fa2011-12-20 23:22:4110200 TestCompletionCallback callback;
[email protected]0877e3d2009-10-17 22:29:5710201
bnc691fda62016-08-12 00:43:1610202 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]0877e3d2009-10-17 22:29:5710203
tfarina42834112016-09-22 13:38:2010204 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110205 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]0877e3d2009-10-17 22:29:5710206
10207 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0110208 EXPECT_THAT(rv, IsError(ERR_CONNECTION_RESET));
ttuttled9dbc652015-09-29 20:00:5910209
10210 IPEndPoint endpoint;
bnc691fda62016-08-12 00:43:1610211 EXPECT_TRUE(trans.GetRemoteEndpoint(&endpoint));
ttuttled9dbc652015-09-29 20:00:5910212 EXPECT_LT(0u, endpoint.address().size());
[email protected]0877e3d2009-10-17 22:29:5710213}
10214
zmo9528c9f42015-08-04 22:12:0810215// Check that a connection closed after the start of the headers finishes ok.
bncd16676a2016-07-20 16:23:0110216TEST_F(HttpNetworkTransactionTest, ConnectionClosedAfterStartOfHeaders) {
[email protected]0877e3d2009-10-17 22:29:5710217 HttpRequestInfo request;
10218 request.method = "GET";
10219 request.url = GURL("http://www.foo.com/");
[email protected]0877e3d2009-10-17 22:29:5710220
10221 MockRead data_reads[] = {
10222 MockRead("HTTP/1."),
[email protected]8ddf8322012-02-23 18:08:0610223 MockRead(SYNCHRONOUS, OK),
[email protected]0877e3d2009-10-17 22:29:5710224 };
10225
[email protected]31a2bfe2010-02-09 08:03:3910226 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0710227 session_deps_.socket_factory->AddSocketDataProvider(&data);
danakj1fd259a02016-04-16 03:17:0910228 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]0877e3d2009-10-17 22:29:5710229
[email protected]49639fa2011-12-20 23:22:4110230 TestCompletionCallback callback;
[email protected]0877e3d2009-10-17 22:29:5710231
bnc691fda62016-08-12 00:43:1610232 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]0877e3d2009-10-17 22:29:5710233
tfarina42834112016-09-22 13:38:2010234 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110235 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]0877e3d2009-10-17 22:29:5710236
10237 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0110238 EXPECT_THAT(rv, IsOk());
zmo9528c9f42015-08-04 22:12:0810239
bnc691fda62016-08-12 00:43:1610240 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5210241 ASSERT_TRUE(response);
zmo9528c9f42015-08-04 22:12:0810242
wezca1070932016-05-26 20:30:5210243 EXPECT_TRUE(response->headers);
zmo9528c9f42015-08-04 22:12:0810244 EXPECT_EQ("HTTP/1.0 200 OK", response->headers->GetStatusLine());
10245
10246 std::string response_data;
bnc691fda62016-08-12 00:43:1610247 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:0110248 EXPECT_THAT(rv, IsOk());
zmo9528c9f42015-08-04 22:12:0810249 EXPECT_EQ("", response_data);
ttuttled9dbc652015-09-29 20:00:5910250
10251 IPEndPoint endpoint;
bnc691fda62016-08-12 00:43:1610252 EXPECT_TRUE(trans.GetRemoteEndpoint(&endpoint));
ttuttled9dbc652015-09-29 20:00:5910253 EXPECT_LT(0u, endpoint.address().size());
[email protected]0877e3d2009-10-17 22:29:5710254}
10255
10256// Make sure that a dropped connection while draining the body for auth
10257// restart does the right thing.
bncd16676a2016-07-20 16:23:0110258TEST_F(HttpNetworkTransactionTest, DrainResetOK) {
[email protected]0877e3d2009-10-17 22:29:5710259 HttpRequestInfo request;
10260 request.method = "GET";
bncce36dca22015-04-21 22:11:2310261 request.url = GURL("http://www.example.org/");
[email protected]0877e3d2009-10-17 22:29:5710262
10263 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:2310264 MockWrite(
10265 "GET / HTTP/1.1\r\n"
10266 "Host: www.example.org\r\n"
10267 "Connection: keep-alive\r\n\r\n"),
[email protected]0877e3d2009-10-17 22:29:5710268 };
10269
10270 MockRead data_reads1[] = {
10271 MockRead("HTTP/1.1 401 Unauthorized\r\n"),
10272 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
10273 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
10274 MockRead("Content-Length: 14\r\n\r\n"),
10275 MockRead("Unauth"),
[email protected]8ddf8322012-02-23 18:08:0610276 MockRead(ASYNC, ERR_CONNECTION_RESET),
[email protected]0877e3d2009-10-17 22:29:5710277 };
10278
[email protected]31a2bfe2010-02-09 08:03:3910279 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
10280 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:0710281 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]0877e3d2009-10-17 22:29:5710282
bnc691fda62016-08-12 00:43:1610283 // After calling trans.RestartWithAuth(), this is the request we should
[email protected]0877e3d2009-10-17 22:29:5710284 // be issuing -- the final header line contains the credentials.
10285 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:2310286 MockWrite(
10287 "GET / HTTP/1.1\r\n"
10288 "Host: www.example.org\r\n"
10289 "Connection: keep-alive\r\n"
10290 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]0877e3d2009-10-17 22:29:5710291 };
10292
10293 // Lastly, the server responds with the actual content.
10294 MockRead data_reads2[] = {
10295 MockRead("HTTP/1.1 200 OK\r\n"),
10296 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
10297 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:0610298 MockRead(SYNCHRONOUS, OK),
[email protected]0877e3d2009-10-17 22:29:5710299 };
10300
[email protected]31a2bfe2010-02-09 08:03:3910301 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
10302 data_writes2, arraysize(data_writes2));
[email protected]bb88e1d32013-05-03 23:11:0710303 session_deps_.socket_factory->AddSocketDataProvider(&data2);
danakj1fd259a02016-04-16 03:17:0910304 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]0877e3d2009-10-17 22:29:5710305
[email protected]49639fa2011-12-20 23:22:4110306 TestCompletionCallback callback1;
[email protected]0877e3d2009-10-17 22:29:5710307
bnc691fda62016-08-12 00:43:1610308 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]0b0bf032010-09-21 18:08:5010309
tfarina42834112016-09-22 13:38:2010310 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110311 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]0877e3d2009-10-17 22:29:5710312
10313 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:0110314 EXPECT_THAT(rv, IsOk());
[email protected]0877e3d2009-10-17 22:29:5710315
bnc691fda62016-08-12 00:43:1610316 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5210317 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:0410318 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]0877e3d2009-10-17 22:29:5710319
[email protected]49639fa2011-12-20 23:22:4110320 TestCompletionCallback callback2;
[email protected]0877e3d2009-10-17 22:29:5710321
bnc691fda62016-08-12 00:43:1610322 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar), callback2.callback());
robpercival214763f2016-07-01 23:27:0110323 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]0877e3d2009-10-17 22:29:5710324
10325 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:0110326 EXPECT_THAT(rv, IsOk());
[email protected]0877e3d2009-10-17 22:29:5710327
bnc691fda62016-08-12 00:43:1610328 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5210329 ASSERT_TRUE(response);
10330 EXPECT_FALSE(response->auth_challenge);
[email protected]0877e3d2009-10-17 22:29:5710331 EXPECT_EQ(100, response->headers->GetContentLength());
10332}
10333
10334// Test HTTPS connections going through a proxy that sends extra data.
bncd16676a2016-07-20 16:23:0110335TEST_F(HttpNetworkTransactionTest, HTTPSViaProxyWithExtraData) {
rdsmith82957ad2015-09-16 19:42:0310336 session_deps_.proxy_service = ProxyService::CreateFixed("myproxy:70");
[email protected]0877e3d2009-10-17 22:29:5710337
10338 HttpRequestInfo request;
10339 request.method = "GET";
bncce36dca22015-04-21 22:11:2310340 request.url = GURL("https://www.example.org/");
[email protected]0877e3d2009-10-17 22:29:5710341
10342 MockRead proxy_reads[] = {
10343 MockRead("HTTP/1.0 200 Connected\r\n\r\nExtra data"),
[email protected]8ddf8322012-02-23 18:08:0610344 MockRead(SYNCHRONOUS, OK)
[email protected]0877e3d2009-10-17 22:29:5710345 };
10346
[email protected]31a2bfe2010-02-09 08:03:3910347 StaticSocketDataProvider data(proxy_reads, arraysize(proxy_reads), NULL, 0);
[email protected]8ddf8322012-02-23 18:08:0610348 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]0877e3d2009-10-17 22:29:5710349
[email protected]bb88e1d32013-05-03 23:11:0710350 session_deps_.socket_factory->AddSocketDataProvider(&data);
10351 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]0877e3d2009-10-17 22:29:5710352
[email protected]49639fa2011-12-20 23:22:4110353 TestCompletionCallback callback;
[email protected]0877e3d2009-10-17 22:29:5710354
[email protected]bb88e1d32013-05-03 23:11:0710355 session_deps_.socket_factory->ResetNextMockIndexes();
[email protected]0877e3d2009-10-17 22:29:5710356
danakj1fd259a02016-04-16 03:17:0910357 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1610358 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]0877e3d2009-10-17 22:29:5710359
tfarina42834112016-09-22 13:38:2010360 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110361 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]0877e3d2009-10-17 22:29:5710362
10363 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0110364 EXPECT_THAT(rv, IsError(ERR_TUNNEL_CONNECTION_FAILED));
[email protected]0877e3d2009-10-17 22:29:5710365}
10366
bncd16676a2016-07-20 16:23:0110367TEST_F(HttpNetworkTransactionTest, LargeContentLengthThenClose) {
[email protected]9492e4a2010-02-24 00:58:4610368 HttpRequestInfo request;
10369 request.method = "GET";
bncce36dca22015-04-21 22:11:2310370 request.url = GURL("http://www.example.org/");
[email protected]9492e4a2010-02-24 00:58:4610371
danakj1fd259a02016-04-16 03:17:0910372 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1610373 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:2710374
[email protected]e22e1362009-11-23 21:31:1210375 MockRead data_reads[] = {
10376 MockRead("HTTP/1.0 200 OK\r\nContent-Length:6719476739\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:0610377 MockRead(SYNCHRONOUS, OK),
[email protected]e22e1362009-11-23 21:31:1210378 };
[email protected]9492e4a2010-02-24 00:58:4610379
10380 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0710381 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]9492e4a2010-02-24 00:58:4610382
[email protected]49639fa2011-12-20 23:22:4110383 TestCompletionCallback callback;
[email protected]9492e4a2010-02-24 00:58:4610384
tfarina42834112016-09-22 13:38:2010385 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110386 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]9492e4a2010-02-24 00:58:4610387
robpercival214763f2016-07-01 23:27:0110388 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]9492e4a2010-02-24 00:58:4610389
bnc691fda62016-08-12 00:43:1610390 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5210391 ASSERT_TRUE(response);
[email protected]9492e4a2010-02-24 00:58:4610392
wezca1070932016-05-26 20:30:5210393 EXPECT_TRUE(response->headers);
[email protected]9492e4a2010-02-24 00:58:4610394 EXPECT_EQ("HTTP/1.0 200 OK", response->headers->GetStatusLine());
10395
10396 std::string response_data;
bnc691fda62016-08-12 00:43:1610397 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:0110398 EXPECT_THAT(rv, IsError(ERR_CONTENT_LENGTH_MISMATCH));
[email protected]e22e1362009-11-23 21:31:1210399}
10400
bncd16676a2016-07-20 16:23:0110401TEST_F(HttpNetworkTransactionTest, UploadFileSmallerThanLength) {
[email protected]6cdfd7f2013-02-08 20:40:1510402 base::FilePath temp_file_path;
[email protected]03d9afc02013-12-03 17:55:5210403 ASSERT_TRUE(base::CreateTemporaryFile(&temp_file_path));
avibf0746c2015-12-09 19:53:1410404 const uint64_t kFakeSize = 100000; // file is actually blank
[email protected]d98961652012-09-11 20:27:2110405 UploadFileElementReader::ScopedOverridingContentLengthForTests
10406 overriding_content_length(kFakeSize);
[email protected]95d88ffe2010-02-04 21:25:3310407
danakj1fd259a02016-04-16 03:17:0910408 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
Jeremy Roman0579ed62017-08-29 15:56:1910409 element_readers.push_back(std::make_unique<UploadFileElementReader>(
avibf0746c2015-12-09 19:53:1410410 base::ThreadTaskRunnerHandle::Get().get(), temp_file_path, 0,
ricea2deef682016-09-09 08:04:0710411 std::numeric_limits<uint64_t>::max(), base::Time()));
olli.raula6df48b2a2015-11-26 07:40:2210412 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]329b68b2012-11-14 17:54:2710413
10414 HttpRequestInfo request;
10415 request.method = "POST";
bncce36dca22015-04-21 22:11:2310416 request.url = GURL("http://www.example.org/upload");
[email protected]329b68b2012-11-14 17:54:2710417 request.upload_data_stream = &upload_data_stream;
[email protected]329b68b2012-11-14 17:54:2710418
danakj1fd259a02016-04-16 03:17:0910419 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1610420 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]95d88ffe2010-02-04 21:25:3310421
10422 MockRead data_reads[] = {
10423 MockRead("HTTP/1.0 200 OK\r\n\r\n"),
10424 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:0610425 MockRead(SYNCHRONOUS, OK),
[email protected]95d88ffe2010-02-04 21:25:3310426 };
[email protected]31a2bfe2010-02-09 08:03:3910427 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0710428 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]95d88ffe2010-02-04 21:25:3310429
[email protected]49639fa2011-12-20 23:22:4110430 TestCompletionCallback callback;
[email protected]95d88ffe2010-02-04 21:25:3310431
tfarina42834112016-09-22 13:38:2010432 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110433 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]95d88ffe2010-02-04 21:25:3310434
10435 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0110436 EXPECT_THAT(rv, IsError(ERR_UPLOAD_FILE_CHANGED));
[email protected]95d88ffe2010-02-04 21:25:3310437
bnc691fda62016-08-12 00:43:1610438 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5210439 ASSERT_TRUE(response);
[email protected]95d88ffe2010-02-04 21:25:3310440
maksim.sisove869bf52016-06-23 17:11:5210441 EXPECT_FALSE(response->headers);
[email protected]95d88ffe2010-02-04 21:25:3310442
[email protected]dd3aa792013-07-16 19:10:2310443 base::DeleteFile(temp_file_path, false);
[email protected]95d88ffe2010-02-04 21:25:3310444}
10445
bncd16676a2016-07-20 16:23:0110446TEST_F(HttpNetworkTransactionTest, UploadUnreadableFile) {
[email protected]6cdfd7f2013-02-08 20:40:1510447 base::FilePath temp_file;
[email protected]03d9afc02013-12-03 17:55:5210448 ASSERT_TRUE(base::CreateTemporaryFile(&temp_file));
[email protected]6624b4622010-03-29 19:58:3610449 std::string temp_file_content("Unreadable file.");
lazyboy8df84fc2017-04-12 02:12:4810450 ASSERT_EQ(static_cast<int>(temp_file_content.length()),
10451 base::WriteFile(temp_file, temp_file_content.c_str(),
10452 temp_file_content.length()));
[email protected]92be8eb2014-08-07 22:57:1110453 ASSERT_TRUE(base::MakeFileUnreadable(temp_file));
[email protected]6624b4622010-03-29 19:58:3610454
danakj1fd259a02016-04-16 03:17:0910455 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
Jeremy Roman0579ed62017-08-29 15:56:1910456 element_readers.push_back(std::make_unique<UploadFileElementReader>(
avibf0746c2015-12-09 19:53:1410457 base::ThreadTaskRunnerHandle::Get().get(), temp_file, 0,
ricea2deef682016-09-09 08:04:0710458 std::numeric_limits<uint64_t>::max(), base::Time()));
olli.raula6df48b2a2015-11-26 07:40:2210459 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]329b68b2012-11-14 17:54:2710460
10461 HttpRequestInfo request;
10462 request.method = "POST";
bncce36dca22015-04-21 22:11:2310463 request.url = GURL("http://www.example.org/upload");
[email protected]329b68b2012-11-14 17:54:2710464 request.upload_data_stream = &upload_data_stream;
[email protected]329b68b2012-11-14 17:54:2710465
[email protected]999dd8c2013-11-12 06:45:5410466 // If we try to upload an unreadable file, the transaction should fail.
danakj1fd259a02016-04-16 03:17:0910467 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1610468 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]6624b4622010-03-29 19:58:3610469
[email protected]999dd8c2013-11-12 06:45:5410470 StaticSocketDataProvider data(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0710471 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]6624b4622010-03-29 19:58:3610472
[email protected]49639fa2011-12-20 23:22:4110473 TestCompletionCallback callback;
[email protected]6624b4622010-03-29 19:58:3610474
tfarina42834112016-09-22 13:38:2010475 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110476 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]6624b4622010-03-29 19:58:3610477
10478 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0110479 EXPECT_THAT(rv, IsError(ERR_ACCESS_DENIED));
[email protected]6624b4622010-03-29 19:58:3610480
[email protected]dd3aa792013-07-16 19:10:2310481 base::DeleteFile(temp_file, false);
[email protected]6624b4622010-03-29 19:58:3610482}
10483
bncd16676a2016-07-20 16:23:0110484TEST_F(HttpNetworkTransactionTest, CancelDuringInitRequestBody) {
[email protected]02cad5d2013-10-02 08:14:0310485 class FakeUploadElementReader : public UploadElementReader {
10486 public:
Chris Watkins7a41d3552017-12-01 02:13:2710487 FakeUploadElementReader() = default;
10488 ~FakeUploadElementReader() override = default;
[email protected]02cad5d2013-10-02 08:14:0310489
10490 const CompletionCallback& callback() const { return callback_; }
10491
10492 // UploadElementReader overrides:
dchengb03027d2014-10-21 12:00:2010493 int Init(const CompletionCallback& callback) override {
[email protected]02cad5d2013-10-02 08:14:0310494 callback_ = callback;
10495 return ERR_IO_PENDING;
10496 }
avibf0746c2015-12-09 19:53:1410497 uint64_t GetContentLength() const override { return 0; }
10498 uint64_t BytesRemaining() const override { return 0; }
dchengb03027d2014-10-21 12:00:2010499 int Read(IOBuffer* buf,
10500 int buf_length,
10501 const CompletionCallback& callback) override {
[email protected]02cad5d2013-10-02 08:14:0310502 return ERR_FAILED;
10503 }
10504
10505 private:
10506 CompletionCallback callback_;
10507 };
10508
10509 FakeUploadElementReader* fake_reader = new FakeUploadElementReader;
danakj1fd259a02016-04-16 03:17:0910510 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
10511 element_readers.push_back(base::WrapUnique(fake_reader));
olli.raula6df48b2a2015-11-26 07:40:2210512 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]02cad5d2013-10-02 08:14:0310513
10514 HttpRequestInfo request;
10515 request.method = "POST";
bncce36dca22015-04-21 22:11:2310516 request.url = GURL("http://www.example.org/upload");
[email protected]02cad5d2013-10-02 08:14:0310517 request.upload_data_stream = &upload_data_stream;
[email protected]02cad5d2013-10-02 08:14:0310518
danakj1fd259a02016-04-16 03:17:0910519 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc87dcefc2017-05-25 12:47:5810520 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:1910521 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]02cad5d2013-10-02 08:14:0310522
10523 StaticSocketDataProvider data;
10524 session_deps_.socket_factory->AddSocketDataProvider(&data);
10525
10526 TestCompletionCallback callback;
tfarina42834112016-09-22 13:38:2010527 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110528 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
fdoray92e35a72016-06-10 15:54:5510529 base::RunLoop().RunUntilIdle();
[email protected]02cad5d2013-10-02 08:14:0310530
10531 // Transaction is pending on request body initialization.
10532 ASSERT_FALSE(fake_reader->callback().is_null());
10533
10534 // Return Init()'s result after the transaction gets destroyed.
10535 trans.reset();
10536 fake_reader->callback().Run(OK); // Should not crash.
10537}
10538
[email protected]aeefc9e82010-02-19 16:18:2710539// Tests that changes to Auth realms are treated like auth rejections.
bncd16676a2016-07-20 16:23:0110540TEST_F(HttpNetworkTransactionTest, ChangeAuthRealms) {
[email protected]aeefc9e82010-02-19 16:18:2710541 HttpRequestInfo request;
10542 request.method = "GET";
bncce36dca22015-04-21 22:11:2310543 request.url = GURL("http://www.example.org/");
[email protected]aeefc9e82010-02-19 16:18:2710544
10545 // First transaction will request a resource and receive a Basic challenge
10546 // with realm="first_realm".
10547 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:2310548 MockWrite(
10549 "GET / HTTP/1.1\r\n"
10550 "Host: www.example.org\r\n"
10551 "Connection: keep-alive\r\n"
10552 "\r\n"),
[email protected]aeefc9e82010-02-19 16:18:2710553 };
10554 MockRead data_reads1[] = {
10555 MockRead("HTTP/1.1 401 Unauthorized\r\n"
10556 "WWW-Authenticate: Basic realm=\"first_realm\"\r\n"
10557 "\r\n"),
10558 };
10559
bnc691fda62016-08-12 00:43:1610560 // After calling trans.RestartWithAuth(), provide an Authentication header
[email protected]aeefc9e82010-02-19 16:18:2710561 // for first_realm. The server will reject and provide a challenge with
10562 // second_realm.
10563 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:2310564 MockWrite(
10565 "GET / HTTP/1.1\r\n"
10566 "Host: www.example.org\r\n"
10567 "Connection: keep-alive\r\n"
10568 "Authorization: Basic Zmlyc3Q6YmF6\r\n"
10569 "\r\n"),
[email protected]aeefc9e82010-02-19 16:18:2710570 };
10571 MockRead data_reads2[] = {
10572 MockRead("HTTP/1.1 401 Unauthorized\r\n"
10573 "WWW-Authenticate: Basic realm=\"second_realm\"\r\n"
10574 "\r\n"),
10575 };
10576
10577 // This again fails, and goes back to first_realm. Make sure that the
10578 // entry is removed from cache.
10579 MockWrite data_writes3[] = {
bncce36dca22015-04-21 22:11:2310580 MockWrite(
10581 "GET / HTTP/1.1\r\n"
10582 "Host: www.example.org\r\n"
10583 "Connection: keep-alive\r\n"
10584 "Authorization: Basic c2Vjb25kOmZvdQ==\r\n"
10585 "\r\n"),
[email protected]aeefc9e82010-02-19 16:18:2710586 };
10587 MockRead data_reads3[] = {
10588 MockRead("HTTP/1.1 401 Unauthorized\r\n"
10589 "WWW-Authenticate: Basic realm=\"first_realm\"\r\n"
10590 "\r\n"),
10591 };
10592
10593 // Try one last time (with the correct password) and get the resource.
10594 MockWrite data_writes4[] = {
bncce36dca22015-04-21 22:11:2310595 MockWrite(
10596 "GET / HTTP/1.1\r\n"
10597 "Host: www.example.org\r\n"
10598 "Connection: keep-alive\r\n"
10599 "Authorization: Basic Zmlyc3Q6YmFy\r\n"
10600 "\r\n"),
[email protected]aeefc9e82010-02-19 16:18:2710601 };
10602 MockRead data_reads4[] = {
10603 MockRead("HTTP/1.1 200 OK\r\n"
10604 "Content-Type: text/html; charset=iso-8859-1\r\n"
[email protected]0b0bf032010-09-21 18:08:5010605 "Content-Length: 5\r\n"
10606 "\r\n"
10607 "hello"),
[email protected]aeefc9e82010-02-19 16:18:2710608 };
10609
10610 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
10611 data_writes1, arraysize(data_writes1));
10612 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
10613 data_writes2, arraysize(data_writes2));
10614 StaticSocketDataProvider data3(data_reads3, arraysize(data_reads3),
10615 data_writes3, arraysize(data_writes3));
10616 StaticSocketDataProvider data4(data_reads4, arraysize(data_reads4),
10617 data_writes4, arraysize(data_writes4));
[email protected]bb88e1d32013-05-03 23:11:0710618 session_deps_.socket_factory->AddSocketDataProvider(&data1);
10619 session_deps_.socket_factory->AddSocketDataProvider(&data2);
10620 session_deps_.socket_factory->AddSocketDataProvider(&data3);
10621 session_deps_.socket_factory->AddSocketDataProvider(&data4);
[email protected]aeefc9e82010-02-19 16:18:2710622
[email protected]49639fa2011-12-20 23:22:4110623 TestCompletionCallback callback1;
[email protected]aeefc9e82010-02-19 16:18:2710624
danakj1fd259a02016-04-16 03:17:0910625 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1610626 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]0b0bf032010-09-21 18:08:5010627
[email protected]aeefc9e82010-02-19 16:18:2710628 // Issue the first request with Authorize headers. There should be a
10629 // password prompt for first_realm waiting to be filled in after the
10630 // transaction completes.
tfarina42834112016-09-22 13:38:2010631 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110632 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]aeefc9e82010-02-19 16:18:2710633 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:0110634 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:1610635 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5210636 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:0410637 const AuthChallengeInfo* challenge = response->auth_challenge.get();
wezca1070932016-05-26 20:30:5210638 ASSERT_TRUE(challenge);
[email protected]79cb5c12011-09-12 13:12:0410639 EXPECT_FALSE(challenge->is_proxy);
asanka098c0092016-06-16 20:18:4310640 EXPECT_EQ("http://www.example.org", challenge->challenger.Serialize());
[email protected]79cb5c12011-09-12 13:12:0410641 EXPECT_EQ("first_realm", challenge->realm);
aberentbba302d2015-12-03 10:20:1910642 EXPECT_EQ(kBasicAuthScheme, challenge->scheme);
[email protected]aeefc9e82010-02-19 16:18:2710643
10644 // Issue the second request with an incorrect password. There should be a
10645 // password prompt for second_realm waiting to be filled in after the
10646 // transaction completes.
[email protected]49639fa2011-12-20 23:22:4110647 TestCompletionCallback callback2;
bnc691fda62016-08-12 00:43:1610648 rv = trans.RestartWithAuth(AuthCredentials(kFirst, kBaz),
10649 callback2.callback());
robpercival214763f2016-07-01 23:27:0110650 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]aeefc9e82010-02-19 16:18:2710651 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:0110652 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:1610653 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5210654 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:0410655 challenge = response->auth_challenge.get();
wezca1070932016-05-26 20:30:5210656 ASSERT_TRUE(challenge);
[email protected]79cb5c12011-09-12 13:12:0410657 EXPECT_FALSE(challenge->is_proxy);
asanka098c0092016-06-16 20:18:4310658 EXPECT_EQ("http://www.example.org", challenge->challenger.Serialize());
[email protected]79cb5c12011-09-12 13:12:0410659 EXPECT_EQ("second_realm", challenge->realm);
aberentbba302d2015-12-03 10:20:1910660 EXPECT_EQ(kBasicAuthScheme, challenge->scheme);
[email protected]aeefc9e82010-02-19 16:18:2710661
10662 // Issue the third request with another incorrect password. There should be
10663 // a password prompt for first_realm waiting to be filled in. If the password
10664 // prompt is not present, it indicates that the HttpAuthCacheEntry for
10665 // first_realm was not correctly removed.
[email protected]49639fa2011-12-20 23:22:4110666 TestCompletionCallback callback3;
bnc691fda62016-08-12 00:43:1610667 rv = trans.RestartWithAuth(AuthCredentials(kSecond, kFou),
10668 callback3.callback());
robpercival214763f2016-07-01 23:27:0110669 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]aeefc9e82010-02-19 16:18:2710670 rv = callback3.WaitForResult();
robpercival214763f2016-07-01 23:27:0110671 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:1610672 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5210673 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:0410674 challenge = response->auth_challenge.get();
wezca1070932016-05-26 20:30:5210675 ASSERT_TRUE(challenge);
[email protected]79cb5c12011-09-12 13:12:0410676 EXPECT_FALSE(challenge->is_proxy);
asanka098c0092016-06-16 20:18:4310677 EXPECT_EQ("http://www.example.org", challenge->challenger.Serialize());
[email protected]79cb5c12011-09-12 13:12:0410678 EXPECT_EQ("first_realm", challenge->realm);
aberentbba302d2015-12-03 10:20:1910679 EXPECT_EQ(kBasicAuthScheme, challenge->scheme);
[email protected]aeefc9e82010-02-19 16:18:2710680
10681 // Issue the fourth request with the correct password and username.
[email protected]49639fa2011-12-20 23:22:4110682 TestCompletionCallback callback4;
bnc691fda62016-08-12 00:43:1610683 rv = trans.RestartWithAuth(AuthCredentials(kFirst, kBar),
10684 callback4.callback());
robpercival214763f2016-07-01 23:27:0110685 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]aeefc9e82010-02-19 16:18:2710686 rv = callback4.WaitForResult();
robpercival214763f2016-07-01 23:27:0110687 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:1610688 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5210689 ASSERT_TRUE(response);
10690 EXPECT_FALSE(response->auth_challenge);
[email protected]aeefc9e82010-02-19 16:18:2710691}
10692
Bence Béky230ac612017-08-30 19:17:0810693// Regression test for https://crbug.com/754395.
10694TEST_F(HttpNetworkTransactionTest, IgnoreAltSvcWithInvalidCert) {
10695 MockRead data_reads[] = {
10696 MockRead("HTTP/1.1 200 OK\r\n"),
10697 MockRead(kAlternativeServiceHttpHeader),
10698 MockRead("\r\n"),
10699 MockRead("hello world"),
10700 MockRead(SYNCHRONOUS, OK),
10701 };
10702
10703 HttpRequestInfo request;
10704 request.method = "GET";
10705 request.url = GURL("https://www.example.org/");
10706
10707 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
10708 session_deps_.socket_factory->AddSocketDataProvider(&data);
10709
10710 SSLSocketDataProvider ssl(ASYNC, OK);
Ryan Sleevi4f832092017-11-21 23:25:4910711 ssl.ssl_info.cert =
10712 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem");
10713 ASSERT_TRUE(ssl.ssl_info.cert);
10714 ssl.ssl_info.cert_status = CERT_STATUS_COMMON_NAME_INVALID;
Bence Béky230ac612017-08-30 19:17:0810715 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
10716
10717 TestCompletionCallback callback;
10718
10719 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
10720 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
10721
10722 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
10723 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
10724
10725 url::SchemeHostPort test_server(request.url);
10726 HttpServerProperties* http_server_properties =
10727 session->http_server_properties();
10728 EXPECT_TRUE(
10729 http_server_properties->GetAlternativeServiceInfos(test_server).empty());
10730
10731 EXPECT_THAT(callback.WaitForResult(), IsOk());
10732
10733 const HttpResponseInfo* response = trans.GetResponseInfo();
10734 ASSERT_TRUE(response);
10735 ASSERT_TRUE(response->headers);
10736 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
10737 EXPECT_FALSE(response->was_fetched_via_spdy);
10738 EXPECT_FALSE(response->was_alpn_negotiated);
10739
10740 std::string response_data;
10741 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
10742 EXPECT_EQ("hello world", response_data);
10743
10744 EXPECT_TRUE(
10745 http_server_properties->GetAlternativeServiceInfos(test_server).empty());
10746}
10747
bncd16676a2016-07-20 16:23:0110748TEST_F(HttpNetworkTransactionTest, HonorAlternativeServiceHeader) {
bncc958faa2015-07-31 18:14:5210749 MockRead data_reads[] = {
10750 MockRead("HTTP/1.1 200 OK\r\n"),
bnc2df4b522016-07-08 18:17:4310751 MockRead(kAlternativeServiceHttpHeader),
bncc958faa2015-07-31 18:14:5210752 MockRead("\r\n"),
10753 MockRead("hello world"),
10754 MockRead(SYNCHRONOUS, OK),
10755 };
10756
10757 HttpRequestInfo request;
10758 request.method = "GET";
bncb26024382016-06-29 02:39:4510759 request.url = GURL("https://www.example.org/");
bncc958faa2015-07-31 18:14:5210760
10761 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
bncc958faa2015-07-31 18:14:5210762 session_deps_.socket_factory->AddSocketDataProvider(&data);
10763
bncb26024382016-06-29 02:39:4510764 SSLSocketDataProvider ssl(ASYNC, OK);
Ryan Sleevi4f832092017-11-21 23:25:4910765 ssl.ssl_info.cert =
10766 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem");
10767 ASSERT_TRUE(ssl.ssl_info.cert);
bncb26024382016-06-29 02:39:4510768 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
10769
bncc958faa2015-07-31 18:14:5210770 TestCompletionCallback callback;
10771
danakj1fd259a02016-04-16 03:17:0910772 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1610773 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
bncc958faa2015-07-31 18:14:5210774
tfarina42834112016-09-22 13:38:2010775 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110776 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
bncc958faa2015-07-31 18:14:5210777
bncb26024382016-06-29 02:39:4510778 url::SchemeHostPort test_server(request.url);
bnc525e175a2016-06-20 12:36:4010779 HttpServerProperties* http_server_properties =
10780 session->http_server_properties();
zhongyic4de03032017-05-19 04:07:3410781 EXPECT_TRUE(
10782 http_server_properties->GetAlternativeServiceInfos(test_server).empty());
bncc958faa2015-07-31 18:14:5210783
robpercival214763f2016-07-01 23:27:0110784 EXPECT_THAT(callback.WaitForResult(), IsOk());
bncc958faa2015-07-31 18:14:5210785
bnc691fda62016-08-12 00:43:1610786 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5210787 ASSERT_TRUE(response);
10788 ASSERT_TRUE(response->headers);
bncc958faa2015-07-31 18:14:5210789 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
10790 EXPECT_FALSE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5210791 EXPECT_FALSE(response->was_alpn_negotiated);
bncc958faa2015-07-31 18:14:5210792
10793 std::string response_data;
bnc691fda62016-08-12 00:43:1610794 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
bncc958faa2015-07-31 18:14:5210795 EXPECT_EQ("hello world", response_data);
10796
zhongyic4de03032017-05-19 04:07:3410797 AlternativeServiceInfoVector alternative_service_info_vector =
10798 http_server_properties->GetAlternativeServiceInfos(test_server);
10799 ASSERT_EQ(1u, alternative_service_info_vector.size());
10800 AlternativeService alternative_service(kProtoHTTP2, "mail.example.org", 443);
10801 EXPECT_EQ(alternative_service,
zhongyi422ce352017-06-09 23:28:5410802 alternative_service_info_vector[0].alternative_service());
bncc958faa2015-07-31 18:14:5210803}
10804
bnce3dd56f2016-06-01 10:37:1110805// Regression test for https://crbug.com/615497.
bncd16676a2016-07-20 16:23:0110806TEST_F(HttpNetworkTransactionTest,
bnce3dd56f2016-06-01 10:37:1110807 DoNotParseAlternativeServiceHeaderOnInsecureRequest) {
bnce3dd56f2016-06-01 10:37:1110808 MockRead data_reads[] = {
10809 MockRead("HTTP/1.1 200 OK\r\n"),
bnc2df4b522016-07-08 18:17:4310810 MockRead(kAlternativeServiceHttpHeader),
bnce3dd56f2016-06-01 10:37:1110811 MockRead("\r\n"),
10812 MockRead("hello world"),
10813 MockRead(SYNCHRONOUS, OK),
10814 };
10815
10816 HttpRequestInfo request;
10817 request.method = "GET";
10818 request.url = GURL("http://www.example.org/");
10819 request.load_flags = 0;
10820
10821 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
10822 session_deps_.socket_factory->AddSocketDataProvider(&data);
10823
10824 TestCompletionCallback callback;
10825
10826 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1610827 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
bnce3dd56f2016-06-01 10:37:1110828
10829 url::SchemeHostPort test_server(request.url);
bnc525e175a2016-06-20 12:36:4010830 HttpServerProperties* http_server_properties =
10831 session->http_server_properties();
zhongyic4de03032017-05-19 04:07:3410832 EXPECT_TRUE(
10833 http_server_properties->GetAlternativeServiceInfos(test_server).empty());
bnce3dd56f2016-06-01 10:37:1110834
tfarina42834112016-09-22 13:38:2010835 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110836 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
10837 EXPECT_THAT(callback.WaitForResult(), IsOk());
bnce3dd56f2016-06-01 10:37:1110838
bnc691fda62016-08-12 00:43:1610839 const HttpResponseInfo* response = trans.GetResponseInfo();
bnce3dd56f2016-06-01 10:37:1110840 ASSERT_TRUE(response);
10841 ASSERT_TRUE(response->headers);
10842 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
10843 EXPECT_FALSE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5210844 EXPECT_FALSE(response->was_alpn_negotiated);
bnce3dd56f2016-06-01 10:37:1110845
10846 std::string response_data;
bnc691fda62016-08-12 00:43:1610847 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
bnce3dd56f2016-06-01 10:37:1110848 EXPECT_EQ("hello world", response_data);
10849
zhongyic4de03032017-05-19 04:07:3410850 EXPECT_TRUE(
10851 http_server_properties->GetAlternativeServiceInfos(test_server).empty());
bnce3dd56f2016-06-01 10:37:1110852}
10853
bnca86731e2017-04-17 12:31:2810854// HTTP/2 Alternative Services should be disabled by default.
bnc8bef8da22016-05-30 01:28:2510855// TODO(bnc): Remove when https://crbug.com/615413 is fixed.
bncd16676a2016-07-20 16:23:0110856TEST_F(HttpNetworkTransactionTest,
bnc8bef8da22016-05-30 01:28:2510857 DisableHTTP2AlternativeServicesWithDifferentHost) {
bnca86731e2017-04-17 12:31:2810858 session_deps_.enable_http2_alternative_service = false;
bncb26024382016-06-29 02:39:4510859
bnc8bef8da22016-05-30 01:28:2510860 HttpRequestInfo request;
10861 request.method = "GET";
bncb26024382016-06-29 02:39:4510862 request.url = GURL("https://www.example.org/");
bnc8bef8da22016-05-30 01:28:2510863 request.load_flags = 0;
10864
10865 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
10866 StaticSocketDataProvider first_data;
10867 first_data.set_connect_data(mock_connect);
10868 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
bncb26024382016-06-29 02:39:4510869 SSLSocketDataProvider ssl_http11(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3610870 ssl_http11.next_proto = kProtoHTTP11;
bncb26024382016-06-29 02:39:4510871 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_http11);
bnc8bef8da22016-05-30 01:28:2510872
10873 MockRead data_reads[] = {
10874 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello world"),
10875 MockRead(ASYNC, OK),
10876 };
10877 StaticSocketDataProvider second_data(data_reads, arraysize(data_reads), NULL,
10878 0);
10879 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
10880
10881 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
10882
bnc525e175a2016-06-20 12:36:4010883 HttpServerProperties* http_server_properties =
bnc8bef8da22016-05-30 01:28:2510884 session->http_server_properties();
bnc3472afd2016-11-17 15:27:2110885 AlternativeService alternative_service(kProtoHTTP2, "different.example.org",
10886 444);
bnc8bef8da22016-05-30 01:28:2510887 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:2110888 http_server_properties->SetHttp2AlternativeService(
bnc8bef8da22016-05-30 01:28:2510889 url::SchemeHostPort(request.url), alternative_service, expiration);
10890
bnc691fda62016-08-12 00:43:1610891 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
bnc8bef8da22016-05-30 01:28:2510892 TestCompletionCallback callback;
10893
tfarina42834112016-09-22 13:38:2010894 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
bnc8bef8da22016-05-30 01:28:2510895 // Alternative service is not used, request fails.
robpercival214763f2016-07-01 23:27:0110896 EXPECT_THAT(callback.GetResult(rv), IsError(ERR_CONNECTION_REFUSED));
bnc8bef8da22016-05-30 01:28:2510897}
10898
bnce3dd56f2016-06-01 10:37:1110899// Regression test for https://crbug.com/615497:
10900// Alternative Services should be disabled for http origin.
bncd16676a2016-07-20 16:23:0110901TEST_F(HttpNetworkTransactionTest,
bnce3dd56f2016-06-01 10:37:1110902 DisableAlternativeServicesForInsecureOrigin) {
bnce3dd56f2016-06-01 10:37:1110903 HttpRequestInfo request;
10904 request.method = "GET";
10905 request.url = GURL("http://www.example.org/");
10906 request.load_flags = 0;
10907
10908 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
10909 StaticSocketDataProvider first_data;
10910 first_data.set_connect_data(mock_connect);
10911 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
10912
10913 MockRead data_reads[] = {
10914 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello world"),
10915 MockRead(ASYNC, OK),
10916 };
10917 StaticSocketDataProvider second_data(data_reads, arraysize(data_reads), NULL,
10918 0);
10919 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
10920
10921 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
10922
bnc525e175a2016-06-20 12:36:4010923 HttpServerProperties* http_server_properties =
bnce3dd56f2016-06-01 10:37:1110924 session->http_server_properties();
bnc3472afd2016-11-17 15:27:2110925 AlternativeService alternative_service(kProtoHTTP2, "", 444);
bnce3dd56f2016-06-01 10:37:1110926 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:2110927 http_server_properties->SetHttp2AlternativeService(
bnce3dd56f2016-06-01 10:37:1110928 url::SchemeHostPort(request.url), alternative_service, expiration);
10929
bnc691fda62016-08-12 00:43:1610930 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
bnce3dd56f2016-06-01 10:37:1110931 TestCompletionCallback callback;
10932
tfarina42834112016-09-22 13:38:2010933 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
bnce3dd56f2016-06-01 10:37:1110934 // Alternative service is not used, request fails.
robpercival214763f2016-07-01 23:27:0110935 EXPECT_THAT(callback.GetResult(rv), IsError(ERR_CONNECTION_REFUSED));
bnce3dd56f2016-06-01 10:37:1110936}
10937
bncd16676a2016-07-20 16:23:0110938TEST_F(HttpNetworkTransactionTest, ClearAlternativeServices) {
bnc4f575852015-10-14 18:35:0810939 // Set an alternative service for origin.
danakj1fd259a02016-04-16 03:17:0910940 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc525e175a2016-06-20 12:36:4010941 HttpServerProperties* http_server_properties =
10942 session->http_server_properties();
bncb26024382016-06-29 02:39:4510943 url::SchemeHostPort test_server("https", "www.example.org", 443);
bnc3472afd2016-11-17 15:27:2110944 AlternativeService alternative_service(kProtoQUIC, "", 80);
bnc4f575852015-10-14 18:35:0810945 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:2110946 http_server_properties->SetQuicAlternativeService(
10947 test_server, alternative_service, expiration,
10948 session->params().quic_supported_versions);
zhongyic4de03032017-05-19 04:07:3410949 EXPECT_EQ(
10950 1u,
10951 http_server_properties->GetAlternativeServiceInfos(test_server).size());
bnc4f575852015-10-14 18:35:0810952
10953 // Send a clear header.
10954 MockRead data_reads[] = {
10955 MockRead("HTTP/1.1 200 OK\r\n"),
10956 MockRead("Alt-Svc: clear\r\n"),
10957 MockRead("\r\n"),
10958 MockRead("hello world"),
10959 MockRead(SYNCHRONOUS, OK),
10960 };
10961 StaticSocketDataProvider data(data_reads, arraysize(data_reads), nullptr, 0);
10962 session_deps_.socket_factory->AddSocketDataProvider(&data);
10963
bncb26024382016-06-29 02:39:4510964 SSLSocketDataProvider ssl(ASYNC, OK);
Ryan Sleevi4f832092017-11-21 23:25:4910965 ssl.ssl_info.cert =
10966 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem");
10967 ASSERT_TRUE(ssl.ssl_info.cert);
bncb26024382016-06-29 02:39:4510968 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
10969
bnc4f575852015-10-14 18:35:0810970 HttpRequestInfo request;
10971 request.method = "GET";
bncb26024382016-06-29 02:39:4510972 request.url = GURL("https://www.example.org/");
bnc4f575852015-10-14 18:35:0810973
10974 TestCompletionCallback callback;
10975
bnc691fda62016-08-12 00:43:1610976 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
bnc4f575852015-10-14 18:35:0810977
tfarina42834112016-09-22 13:38:2010978 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110979 EXPECT_THAT(callback.GetResult(rv), IsOk());
bnc4f575852015-10-14 18:35:0810980
bnc691fda62016-08-12 00:43:1610981 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5210982 ASSERT_TRUE(response);
10983 ASSERT_TRUE(response->headers);
bnc4f575852015-10-14 18:35:0810984 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
10985 EXPECT_FALSE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5210986 EXPECT_FALSE(response->was_alpn_negotiated);
bnc4f575852015-10-14 18:35:0810987
10988 std::string response_data;
bnc691fda62016-08-12 00:43:1610989 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
bnc4f575852015-10-14 18:35:0810990 EXPECT_EQ("hello world", response_data);
10991
zhongyic4de03032017-05-19 04:07:3410992 EXPECT_TRUE(
10993 http_server_properties->GetAlternativeServiceInfos(test_server).empty());
bnc4f575852015-10-14 18:35:0810994}
10995
bncd16676a2016-07-20 16:23:0110996TEST_F(HttpNetworkTransactionTest, HonorMultipleAlternativeServiceHeaders) {
bncc958faa2015-07-31 18:14:5210997 MockRead data_reads[] = {
10998 MockRead("HTTP/1.1 200 OK\r\n"),
bnc2df4b522016-07-08 18:17:4310999 MockRead("Alt-Svc: h2=\"www.example.com:443\","),
11000 MockRead("h2=\":1234\"\r\n\r\n"),
bncc958faa2015-07-31 18:14:5211001 MockRead("hello world"),
11002 MockRead(SYNCHRONOUS, OK),
11003 };
11004
11005 HttpRequestInfo request;
11006 request.method = "GET";
bncb26024382016-06-29 02:39:4511007 request.url = GURL("https://www.example.org/");
bncc958faa2015-07-31 18:14:5211008
11009 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
bncc958faa2015-07-31 18:14:5211010 session_deps_.socket_factory->AddSocketDataProvider(&data);
11011
bncb26024382016-06-29 02:39:4511012 SSLSocketDataProvider ssl(ASYNC, OK);
Ryan Sleevi4f832092017-11-21 23:25:4911013 ssl.ssl_info.cert =
11014 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem");
11015 ASSERT_TRUE(ssl.ssl_info.cert);
bncb26024382016-06-29 02:39:4511016 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
11017
bncc958faa2015-07-31 18:14:5211018 TestCompletionCallback callback;
11019
danakj1fd259a02016-04-16 03:17:0911020 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1611021 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
bncc958faa2015-07-31 18:14:5211022
tfarina42834112016-09-22 13:38:2011023 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0111024 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
bncc958faa2015-07-31 18:14:5211025
bncb26024382016-06-29 02:39:4511026 url::SchemeHostPort test_server("https", "www.example.org", 443);
bnc525e175a2016-06-20 12:36:4011027 HttpServerProperties* http_server_properties =
11028 session->http_server_properties();
zhongyic4de03032017-05-19 04:07:3411029 EXPECT_TRUE(
11030 http_server_properties->GetAlternativeServiceInfos(test_server).empty());
bncc958faa2015-07-31 18:14:5211031
robpercival214763f2016-07-01 23:27:0111032 EXPECT_THAT(callback.WaitForResult(), IsOk());
bncc958faa2015-07-31 18:14:5211033
bnc691fda62016-08-12 00:43:1611034 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5211035 ASSERT_TRUE(response);
11036 ASSERT_TRUE(response->headers);
bncc958faa2015-07-31 18:14:5211037 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
11038 EXPECT_FALSE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5211039 EXPECT_FALSE(response->was_alpn_negotiated);
bncc958faa2015-07-31 18:14:5211040
11041 std::string response_data;
bnc691fda62016-08-12 00:43:1611042 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
bncc958faa2015-07-31 18:14:5211043 EXPECT_EQ("hello world", response_data);
11044
zhongyic4de03032017-05-19 04:07:3411045 AlternativeServiceInfoVector alternative_service_info_vector =
11046 http_server_properties->GetAlternativeServiceInfos(test_server);
11047 ASSERT_EQ(2u, alternative_service_info_vector.size());
11048
11049 AlternativeService alternative_service(kProtoHTTP2, "www.example.com", 443);
11050 EXPECT_EQ(alternative_service,
zhongyi422ce352017-06-09 23:28:5411051 alternative_service_info_vector[0].alternative_service());
zhongyic4de03032017-05-19 04:07:3411052 AlternativeService alternative_service_2(kProtoHTTP2, "www.example.org",
11053 1234);
11054 EXPECT_EQ(alternative_service_2,
zhongyi422ce352017-06-09 23:28:5411055 alternative_service_info_vector[1].alternative_service());
bncc958faa2015-07-31 18:14:5211056}
11057
bncd16676a2016-07-20 16:23:0111058TEST_F(HttpNetworkTransactionTest, IdentifyQuicBroken) {
zhongyi3d4a55e72016-04-22 20:36:4611059 url::SchemeHostPort server("https", "origin.example.org", 443);
zhongyi48704c182015-12-07 07:52:0211060 HostPortPair alternative("alternative.example.org", 443);
11061 std::string origin_url = "https://origin.example.org:443";
11062 std::string alternative_url = "https://alternative.example.org:443";
11063
11064 // Negotiate HTTP/1.1 with alternative.example.org.
11065 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3611066 ssl.next_proto = kProtoHTTP11;
zhongyi48704c182015-12-07 07:52:0211067 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
11068
11069 // HTTP/1.1 data for request.
11070 MockWrite http_writes[] = {
11071 MockWrite("GET / HTTP/1.1\r\n"
11072 "Host: alternative.example.org\r\n"
11073 "Connection: keep-alive\r\n\r\n"),
11074 };
11075
11076 MockRead http_reads[] = {
11077 MockRead("HTTP/1.1 200 OK\r\n"
11078 "Content-Type: text/html; charset=iso-8859-1\r\n"
11079 "Content-Length: 40\r\n\r\n"
11080 "first HTTP/1.1 response from alternative"),
11081 };
11082 StaticSocketDataProvider http_data(http_reads, arraysize(http_reads),
11083 http_writes, arraysize(http_writes));
11084 session_deps_.socket_factory->AddSocketDataProvider(&http_data);
11085
11086 StaticSocketDataProvider data_refused;
11087 data_refused.set_connect_data(MockConnect(ASYNC, ERR_CONNECTION_REFUSED));
11088 session_deps_.socket_factory->AddSocketDataProvider(&data_refused);
11089
zhongyi3d4a55e72016-04-22 20:36:4611090 // Set up a QUIC alternative service for server.
danakj1fd259a02016-04-16 03:17:0911091 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc525e175a2016-06-20 12:36:4011092 HttpServerProperties* http_server_properties =
zhongyi48704c182015-12-07 07:52:0211093 session->http_server_properties();
bnc3472afd2016-11-17 15:27:2111094 AlternativeService alternative_service(kProtoQUIC, alternative);
zhongyi48704c182015-12-07 07:52:0211095 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:2111096 http_server_properties->SetQuicAlternativeService(
11097 server, alternative_service, expiration,
11098 HttpNetworkSession::Params().quic_supported_versions);
zhongyi48704c182015-12-07 07:52:0211099 // Mark the QUIC alternative service as broken.
11100 http_server_properties->MarkAlternativeServiceBroken(alternative_service);
11101
zhongyi48704c182015-12-07 07:52:0211102 HttpRequestInfo request;
krasinc06a72a2016-12-21 03:42:4611103 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
zhongyi48704c182015-12-07 07:52:0211104 request.method = "GET";
11105 request.url = GURL(origin_url);
zhongyi48704c182015-12-07 07:52:0211106 TestCompletionCallback callback;
11107 NetErrorDetails details;
11108 EXPECT_FALSE(details.quic_broken);
11109
tfarina42834112016-09-22 13:38:2011110 trans.Start(&request, callback.callback(), NetLogWithSource());
bnc691fda62016-08-12 00:43:1611111 trans.PopulateNetErrorDetails(&details);
zhongyi48704c182015-12-07 07:52:0211112 EXPECT_TRUE(details.quic_broken);
11113}
11114
bncd16676a2016-07-20 16:23:0111115TEST_F(HttpNetworkTransactionTest, IdentifyQuicNotBroken) {
zhongyi3d4a55e72016-04-22 20:36:4611116 url::SchemeHostPort server("https", "origin.example.org", 443);
zhongyi48704c182015-12-07 07:52:0211117 HostPortPair alternative1("alternative1.example.org", 443);
11118 HostPortPair alternative2("alternative2.example.org", 443);
11119 std::string origin_url = "https://origin.example.org:443";
11120 std::string alternative_url1 = "https://alternative1.example.org:443";
11121 std::string alternative_url2 = "https://alternative2.example.org:443";
11122
11123 // Negotiate HTTP/1.1 with alternative1.example.org.
11124 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3611125 ssl.next_proto = kProtoHTTP11;
zhongyi48704c182015-12-07 07:52:0211126 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
11127
11128 // HTTP/1.1 data for request.
11129 MockWrite http_writes[] = {
11130 MockWrite("GET / HTTP/1.1\r\n"
11131 "Host: alternative1.example.org\r\n"
11132 "Connection: keep-alive\r\n\r\n"),
11133 };
11134
11135 MockRead http_reads[] = {
11136 MockRead("HTTP/1.1 200 OK\r\n"
11137 "Content-Type: text/html; charset=iso-8859-1\r\n"
11138 "Content-Length: 40\r\n\r\n"
11139 "first HTTP/1.1 response from alternative1"),
11140 };
11141 StaticSocketDataProvider http_data(http_reads, arraysize(http_reads),
11142 http_writes, arraysize(http_writes));
11143 session_deps_.socket_factory->AddSocketDataProvider(&http_data);
11144
11145 StaticSocketDataProvider data_refused;
11146 data_refused.set_connect_data(MockConnect(ASYNC, ERR_CONNECTION_REFUSED));
11147 session_deps_.socket_factory->AddSocketDataProvider(&data_refused);
11148
danakj1fd259a02016-04-16 03:17:0911149 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc525e175a2016-06-20 12:36:4011150 HttpServerProperties* http_server_properties =
zhongyi48704c182015-12-07 07:52:0211151 session->http_server_properties();
11152
zhongyi3d4a55e72016-04-22 20:36:4611153 // Set up two QUIC alternative services for server.
zhongyi48704c182015-12-07 07:52:0211154 AlternativeServiceInfoVector alternative_service_info_vector;
11155 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
11156
bnc3472afd2016-11-17 15:27:2111157 AlternativeService alternative_service1(kProtoQUIC, alternative1);
zhongyie537a002017-06-27 16:48:2111158 alternative_service_info_vector.push_back(
11159 AlternativeServiceInfo::CreateQuicAlternativeServiceInfo(
11160 alternative_service1, expiration,
11161 session->params().quic_supported_versions));
bnc3472afd2016-11-17 15:27:2111162 AlternativeService alternative_service2(kProtoQUIC, alternative2);
zhongyie537a002017-06-27 16:48:2111163 alternative_service_info_vector.push_back(
11164 AlternativeServiceInfo::CreateQuicAlternativeServiceInfo(
11165 alternative_service2, expiration,
11166 session->params().quic_supported_versions));
zhongyi48704c182015-12-07 07:52:0211167
11168 http_server_properties->SetAlternativeServices(
zhongyi3d4a55e72016-04-22 20:36:4611169 server, alternative_service_info_vector);
zhongyi48704c182015-12-07 07:52:0211170
11171 // Mark one of the QUIC alternative service as broken.
11172 http_server_properties->MarkAlternativeServiceBroken(alternative_service1);
zhongyic4de03032017-05-19 04:07:3411173 EXPECT_EQ(2u,
11174 http_server_properties->GetAlternativeServiceInfos(server).size());
zhongyi48704c182015-12-07 07:52:0211175
zhongyi48704c182015-12-07 07:52:0211176 HttpRequestInfo request;
krasinc06a72a2016-12-21 03:42:4611177 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
zhongyi48704c182015-12-07 07:52:0211178 request.method = "GET";
11179 request.url = GURL(origin_url);
zhongyi48704c182015-12-07 07:52:0211180 TestCompletionCallback callback;
11181 NetErrorDetails details;
11182 EXPECT_FALSE(details.quic_broken);
11183
tfarina42834112016-09-22 13:38:2011184 trans.Start(&request, callback.callback(), NetLogWithSource());
bnc691fda62016-08-12 00:43:1611185 trans.PopulateNetErrorDetails(&details);
zhongyi48704c182015-12-07 07:52:0211186 EXPECT_FALSE(details.quic_broken);
11187}
11188
bncd16676a2016-07-20 16:23:0111189TEST_F(HttpNetworkTransactionTest, MarkBrokenAlternateProtocolAndFallback) {
[email protected]564b4912010-03-09 16:30:4211190 HttpRequestInfo request;
11191 request.method = "GET";
bncb26024382016-06-29 02:39:4511192 request.url = GURL("https://www.example.org/");
[email protected]564b4912010-03-09 16:30:4211193
[email protected]d973e99a2012-02-17 21:02:3611194 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
[email protected]564b4912010-03-09 16:30:4211195 StaticSocketDataProvider first_data;
11196 first_data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:0711197 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
bncb26024382016-06-29 02:39:4511198 SSLSocketDataProvider ssl_http11(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3611199 ssl_http11.next_proto = kProtoHTTP11;
bncb26024382016-06-29 02:39:4511200 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_http11);
[email protected]564b4912010-03-09 16:30:4211201
11202 MockRead data_reads[] = {
11203 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
11204 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:0611205 MockRead(ASYNC, OK),
[email protected]564b4912010-03-09 16:30:4211206 };
11207 StaticSocketDataProvider second_data(
11208 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0711209 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
[email protected]564b4912010-03-09 16:30:4211210
danakj1fd259a02016-04-16 03:17:0911211 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]564b4912010-03-09 16:30:4211212
bnc525e175a2016-06-20 12:36:4011213 HttpServerProperties* http_server_properties =
[email protected]17291a022011-10-10 07:32:5311214 session->http_server_properties();
zhongyi3d4a55e72016-04-22 20:36:4611215 const url::SchemeHostPort server(request.url);
[email protected]3912662a32011-10-04 00:51:1111216 // Port must be < 1024, or the header will be ignored (since initial port was
11217 // port 80 (another restricted port).
zhongyie537a002017-06-27 16:48:2111218 // Port is ignored by MockConnect anyway.
11219 const AlternativeService alternative_service(kProtoHTTP2, "www.example.org",
11220 666);
bnc7dc7e1b42015-07-28 14:43:1211221 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:2111222 http_server_properties->SetHttp2AlternativeService(
11223 server, alternative_service, expiration);
[email protected]564b4912010-03-09 16:30:4211224
bnc691fda62016-08-12 00:43:1611225 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]49639fa2011-12-20 23:22:4111226 TestCompletionCallback callback;
[email protected]564b4912010-03-09 16:30:4211227
tfarina42834112016-09-22 13:38:2011228 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0111229 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
11230 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]564b4912010-03-09 16:30:4211231
bnc691fda62016-08-12 00:43:1611232 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5211233 ASSERT_TRUE(response);
11234 ASSERT_TRUE(response->headers);
[email protected]564b4912010-03-09 16:30:4211235 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
11236
11237 std::string response_data;
bnc691fda62016-08-12 00:43:1611238 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
[email protected]564b4912010-03-09 16:30:4211239 EXPECT_EQ("hello world", response_data);
11240
zhongyic4de03032017-05-19 04:07:3411241 const AlternativeServiceInfoVector alternative_service_info_vector =
11242 http_server_properties->GetAlternativeServiceInfos(server);
11243 ASSERT_EQ(1u, alternative_service_info_vector.size());
11244 EXPECT_EQ(alternative_service,
zhongyi422ce352017-06-09 23:28:5411245 alternative_service_info_vector[0].alternative_service());
zhongyic4de03032017-05-19 04:07:3411246 EXPECT_TRUE(
11247 http_server_properties->IsAlternativeServiceBroken(alternative_service));
[email protected]564b4912010-03-09 16:30:4211248}
11249
bnc55ff9da2015-08-19 18:42:3511250// Ensure that we are not allowed to redirect traffic via an alternate protocol
11251// to an unrestricted (port >= 1024) when the original traffic was on a
11252// restricted port (port < 1024). Ensure that we can redirect in all other
11253// cases.
bncd16676a2016-07-20 16:23:0111254TEST_F(HttpNetworkTransactionTest, AlternateProtocolPortRestrictedBlocked) {
[email protected]3912662a32011-10-04 00:51:1111255 HttpRequestInfo restricted_port_request;
11256 restricted_port_request.method = "GET";
bncb26024382016-06-29 02:39:4511257 restricted_port_request.url = GURL("https://www.example.org:1023/");
[email protected]3912662a32011-10-04 00:51:1111258 restricted_port_request.load_flags = 0;
11259
[email protected]d973e99a2012-02-17 21:02:3611260 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
[email protected]3912662a32011-10-04 00:51:1111261 StaticSocketDataProvider first_data;
11262 first_data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:0711263 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
[email protected]3912662a32011-10-04 00:51:1111264
11265 MockRead data_reads[] = {
11266 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
11267 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:0611268 MockRead(ASYNC, OK),
[email protected]3912662a32011-10-04 00:51:1111269 };
11270 StaticSocketDataProvider second_data(
11271 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0711272 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
bncb26024382016-06-29 02:39:4511273 SSLSocketDataProvider ssl_http11(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3611274 ssl_http11.next_proto = kProtoHTTP11;
bncb26024382016-06-29 02:39:4511275 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_http11);
[email protected]3912662a32011-10-04 00:51:1111276
danakj1fd259a02016-04-16 03:17:0911277 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]3912662a32011-10-04 00:51:1111278
bnc525e175a2016-06-20 12:36:4011279 HttpServerProperties* http_server_properties =
[email protected]17291a022011-10-10 07:32:5311280 session->http_server_properties();
[email protected]3912662a32011-10-04 00:51:1111281 const int kUnrestrictedAlternatePort = 1024;
bnc3472afd2016-11-17 15:27:2111282 AlternativeService alternative_service(kProtoHTTP2, "www.example.org",
11283 kUnrestrictedAlternatePort);
bnc7dc7e1b42015-07-28 14:43:1211284 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:2111285 http_server_properties->SetHttp2AlternativeService(
zhongyi3d4a55e72016-04-22 20:36:4611286 url::SchemeHostPort(restricted_port_request.url), alternative_service,
rchdc7b9052016-03-17 20:51:5011287 expiration);
[email protected]3912662a32011-10-04 00:51:1111288
bnc691fda62016-08-12 00:43:1611289 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]49639fa2011-12-20 23:22:4111290 TestCompletionCallback callback;
[email protected]3912662a32011-10-04 00:51:1111291
tfarina42834112016-09-22 13:38:2011292 int rv = trans.Start(&restricted_port_request, callback.callback(),
11293 NetLogWithSource());
robpercival214763f2016-07-01 23:27:0111294 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]3912662a32011-10-04 00:51:1111295 // Invalid change to unrestricted port should fail.
robpercival214763f2016-07-01 23:27:0111296 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_CONNECTION_REFUSED));
[email protected]c54c6962013-02-01 04:53:1911297}
[email protected]3912662a32011-10-04 00:51:1111298
bnc55ff9da2015-08-19 18:42:3511299// Ensure that we are allowed to redirect traffic via an alternate protocol to
11300// an unrestricted (port >= 1024) when the original traffic was on a restricted
11301// port (port < 1024) if we set |enable_user_alternate_protocol_ports|.
bncd16676a2016-07-20 16:23:0111302TEST_F(HttpNetworkTransactionTest, AlternateProtocolPortRestrictedPermitted) {
[email protected]bb88e1d32013-05-03 23:11:0711303 session_deps_.enable_user_alternate_protocol_ports = true;
[email protected]c54c6962013-02-01 04:53:1911304
11305 HttpRequestInfo restricted_port_request;
11306 restricted_port_request.method = "GET";
bncb26024382016-06-29 02:39:4511307 restricted_port_request.url = GURL("https://www.example.org:1023/");
[email protected]c54c6962013-02-01 04:53:1911308 restricted_port_request.load_flags = 0;
11309
11310 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
11311 StaticSocketDataProvider first_data;
11312 first_data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:0711313 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
[email protected]c54c6962013-02-01 04:53:1911314
11315 MockRead data_reads[] = {
11316 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
11317 MockRead("hello world"),
11318 MockRead(ASYNC, OK),
11319 };
11320 StaticSocketDataProvider second_data(
11321 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0711322 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
bncb26024382016-06-29 02:39:4511323 SSLSocketDataProvider ssl_http11(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3611324 ssl_http11.next_proto = kProtoHTTP11;
bncb26024382016-06-29 02:39:4511325 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_http11);
[email protected]c54c6962013-02-01 04:53:1911326
danakj1fd259a02016-04-16 03:17:0911327 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]c54c6962013-02-01 04:53:1911328
bnc525e175a2016-06-20 12:36:4011329 HttpServerProperties* http_server_properties =
[email protected]c54c6962013-02-01 04:53:1911330 session->http_server_properties();
11331 const int kUnrestrictedAlternatePort = 1024;
bnc3472afd2016-11-17 15:27:2111332 AlternativeService alternative_service(kProtoHTTP2, "www.example.org",
11333 kUnrestrictedAlternatePort);
bnc7dc7e1b42015-07-28 14:43:1211334 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:2111335 http_server_properties->SetHttp2AlternativeService(
zhongyi3d4a55e72016-04-22 20:36:4611336 url::SchemeHostPort(restricted_port_request.url), alternative_service,
rchdc7b9052016-03-17 20:51:5011337 expiration);
[email protected]c54c6962013-02-01 04:53:1911338
bnc691fda62016-08-12 00:43:1611339 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]c54c6962013-02-01 04:53:1911340 TestCompletionCallback callback;
11341
tfarina42834112016-09-22 13:38:2011342 EXPECT_EQ(ERR_IO_PENDING,
11343 trans.Start(&restricted_port_request, callback.callback(),
11344 NetLogWithSource()));
[email protected]c54c6962013-02-01 04:53:1911345 // Change to unrestricted port should succeed.
robpercival214763f2016-07-01 23:27:0111346 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]3912662a32011-10-04 00:51:1111347}
11348
bnc55ff9da2015-08-19 18:42:3511349// Ensure that we are not allowed to redirect traffic via an alternate protocol
11350// to an unrestricted (port >= 1024) when the original traffic was on a
11351// restricted port (port < 1024). Ensure that we can redirect in all other
11352// cases.
bncd16676a2016-07-20 16:23:0111353TEST_F(HttpNetworkTransactionTest, AlternateProtocolPortRestrictedAllowed) {
[email protected]3912662a32011-10-04 00:51:1111354 HttpRequestInfo restricted_port_request;
11355 restricted_port_request.method = "GET";
bncb26024382016-06-29 02:39:4511356 restricted_port_request.url = GURL("https://www.example.org:1023/");
[email protected]3912662a32011-10-04 00:51:1111357 restricted_port_request.load_flags = 0;
11358
[email protected]d973e99a2012-02-17 21:02:3611359 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
[email protected]3912662a32011-10-04 00:51:1111360 StaticSocketDataProvider first_data;
11361 first_data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:0711362 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
[email protected]3912662a32011-10-04 00:51:1111363
11364 MockRead data_reads[] = {
11365 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
11366 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:0611367 MockRead(ASYNC, OK),
[email protected]3912662a32011-10-04 00:51:1111368 };
11369 StaticSocketDataProvider second_data(
11370 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0711371 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
[email protected]3912662a32011-10-04 00:51:1111372
bncb26024382016-06-29 02:39:4511373 SSLSocketDataProvider ssl(ASYNC, OK);
11374 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
11375
danakj1fd259a02016-04-16 03:17:0911376 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]3912662a32011-10-04 00:51:1111377
bnc525e175a2016-06-20 12:36:4011378 HttpServerProperties* http_server_properties =
[email protected]17291a022011-10-10 07:32:5311379 session->http_server_properties();
[email protected]3912662a32011-10-04 00:51:1111380 const int kRestrictedAlternatePort = 80;
bnc3472afd2016-11-17 15:27:2111381 AlternativeService alternative_service(kProtoHTTP2, "www.example.org",
11382 kRestrictedAlternatePort);
bnc7dc7e1b42015-07-28 14:43:1211383 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:2111384 http_server_properties->SetHttp2AlternativeService(
zhongyi3d4a55e72016-04-22 20:36:4611385 url::SchemeHostPort(restricted_port_request.url), alternative_service,
rchdc7b9052016-03-17 20:51:5011386 expiration);
[email protected]3912662a32011-10-04 00:51:1111387
bnc691fda62016-08-12 00:43:1611388 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]49639fa2011-12-20 23:22:4111389 TestCompletionCallback callback;
[email protected]3912662a32011-10-04 00:51:1111390
tfarina42834112016-09-22 13:38:2011391 int rv = trans.Start(&restricted_port_request, callback.callback(),
11392 NetLogWithSource());
robpercival214763f2016-07-01 23:27:0111393 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]3912662a32011-10-04 00:51:1111394 // Valid change to restricted port should pass.
robpercival214763f2016-07-01 23:27:0111395 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]3912662a32011-10-04 00:51:1111396}
11397
bnc55ff9da2015-08-19 18:42:3511398// Ensure that we are not allowed to redirect traffic via an alternate protocol
11399// to an unrestricted (port >= 1024) when the original traffic was on a
11400// restricted port (port < 1024). Ensure that we can redirect in all other
11401// cases.
bncd16676a2016-07-20 16:23:0111402TEST_F(HttpNetworkTransactionTest, AlternateProtocolPortUnrestrictedAllowed1) {
[email protected]3912662a32011-10-04 00:51:1111403 HttpRequestInfo unrestricted_port_request;
11404 unrestricted_port_request.method = "GET";
bncb26024382016-06-29 02:39:4511405 unrestricted_port_request.url = GURL("https://www.example.org:1024/");
[email protected]3912662a32011-10-04 00:51:1111406 unrestricted_port_request.load_flags = 0;
11407
[email protected]d973e99a2012-02-17 21:02:3611408 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
[email protected]3912662a32011-10-04 00:51:1111409 StaticSocketDataProvider first_data;
11410 first_data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:0711411 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
[email protected]3912662a32011-10-04 00:51:1111412
11413 MockRead data_reads[] = {
11414 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
11415 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:0611416 MockRead(ASYNC, OK),
[email protected]3912662a32011-10-04 00:51:1111417 };
11418 StaticSocketDataProvider second_data(
11419 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0711420 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
bncb26024382016-06-29 02:39:4511421 SSLSocketDataProvider ssl_http11(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3611422 ssl_http11.next_proto = kProtoHTTP11;
bncb26024382016-06-29 02:39:4511423 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_http11);
[email protected]3912662a32011-10-04 00:51:1111424
danakj1fd259a02016-04-16 03:17:0911425 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]3912662a32011-10-04 00:51:1111426
bnc525e175a2016-06-20 12:36:4011427 HttpServerProperties* http_server_properties =
[email protected]17291a022011-10-10 07:32:5311428 session->http_server_properties();
[email protected]3912662a32011-10-04 00:51:1111429 const int kRestrictedAlternatePort = 80;
bnc3472afd2016-11-17 15:27:2111430 AlternativeService alternative_service(kProtoHTTP2, "www.example.org",
11431 kRestrictedAlternatePort);
bnc7dc7e1b42015-07-28 14:43:1211432 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:2111433 http_server_properties->SetHttp2AlternativeService(
zhongyi3d4a55e72016-04-22 20:36:4611434 url::SchemeHostPort(unrestricted_port_request.url), alternative_service,
rchdc7b9052016-03-17 20:51:5011435 expiration);
[email protected]3912662a32011-10-04 00:51:1111436
bnc691fda62016-08-12 00:43:1611437 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]49639fa2011-12-20 23:22:4111438 TestCompletionCallback callback;
[email protected]3912662a32011-10-04 00:51:1111439
bnc691fda62016-08-12 00:43:1611440 int rv = trans.Start(&unrestricted_port_request, callback.callback(),
tfarina42834112016-09-22 13:38:2011441 NetLogWithSource());
robpercival214763f2016-07-01 23:27:0111442 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]3912662a32011-10-04 00:51:1111443 // Valid change to restricted port should pass.
robpercival214763f2016-07-01 23:27:0111444 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]3912662a32011-10-04 00:51:1111445}
11446
bnc55ff9da2015-08-19 18:42:3511447// Ensure that we are not allowed to redirect traffic via an alternate protocol
11448// to an unrestricted (port >= 1024) when the original traffic was on a
11449// restricted port (port < 1024). Ensure that we can redirect in all other
11450// cases.
bncd16676a2016-07-20 16:23:0111451TEST_F(HttpNetworkTransactionTest, AlternateProtocolPortUnrestrictedAllowed2) {
[email protected]3912662a32011-10-04 00:51:1111452 HttpRequestInfo unrestricted_port_request;
11453 unrestricted_port_request.method = "GET";
bncb26024382016-06-29 02:39:4511454 unrestricted_port_request.url = GURL("https://www.example.org:1024/");
[email protected]3912662a32011-10-04 00:51:1111455 unrestricted_port_request.load_flags = 0;
11456
[email protected]d973e99a2012-02-17 21:02:3611457 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
[email protected]3912662a32011-10-04 00:51:1111458 StaticSocketDataProvider first_data;
11459 first_data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:0711460 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
[email protected]3912662a32011-10-04 00:51:1111461
11462 MockRead data_reads[] = {
11463 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
11464 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:0611465 MockRead(ASYNC, OK),
[email protected]3912662a32011-10-04 00:51:1111466 };
11467 StaticSocketDataProvider second_data(
11468 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0711469 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
[email protected]3912662a32011-10-04 00:51:1111470
bncb26024382016-06-29 02:39:4511471 SSLSocketDataProvider ssl(ASYNC, OK);
11472 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
11473
danakj1fd259a02016-04-16 03:17:0911474 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]3912662a32011-10-04 00:51:1111475
bnc525e175a2016-06-20 12:36:4011476 HttpServerProperties* http_server_properties =
[email protected]17291a022011-10-10 07:32:5311477 session->http_server_properties();
bnc0bbb02622015-07-23 10:06:2211478 const int kUnrestrictedAlternatePort = 1025;
bnc3472afd2016-11-17 15:27:2111479 AlternativeService alternative_service(kProtoHTTP2, "www.example.org",
11480 kUnrestrictedAlternatePort);
bnc7dc7e1b42015-07-28 14:43:1211481 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:2111482 http_server_properties->SetHttp2AlternativeService(
zhongyi3d4a55e72016-04-22 20:36:4611483 url::SchemeHostPort(unrestricted_port_request.url), alternative_service,
rchdc7b9052016-03-17 20:51:5011484 expiration);
[email protected]3912662a32011-10-04 00:51:1111485
bnc691fda62016-08-12 00:43:1611486 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]49639fa2011-12-20 23:22:4111487 TestCompletionCallback callback;
[email protected]3912662a32011-10-04 00:51:1111488
bnc691fda62016-08-12 00:43:1611489 int rv = trans.Start(&unrestricted_port_request, callback.callback(),
tfarina42834112016-09-22 13:38:2011490 NetLogWithSource());
robpercival214763f2016-07-01 23:27:0111491 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]3912662a32011-10-04 00:51:1111492 // Valid change to an unrestricted port should pass.
robpercival214763f2016-07-01 23:27:0111493 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]3912662a32011-10-04 00:51:1111494}
11495
bnc55ff9da2015-08-19 18:42:3511496// Ensure that we are not allowed to redirect traffic via an alternate protocol
11497// to an unsafe port, and that we resume the second HttpStreamFactoryImpl::Job
11498// once the alternate protocol request fails.
bncd16676a2016-07-20 16:23:0111499TEST_F(HttpNetworkTransactionTest, AlternateProtocolUnsafeBlocked) {
[email protected]eb6234e2012-01-19 01:50:0211500 HttpRequestInfo request;
11501 request.method = "GET";
bncce36dca22015-04-21 22:11:2311502 request.url = GURL("http://www.example.org/");
[email protected]eb6234e2012-01-19 01:50:0211503
11504 // The alternate protocol request will error out before we attempt to connect,
11505 // so only the standard HTTP request will try to connect.
11506 MockRead data_reads[] = {
11507 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
11508 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:0611509 MockRead(ASYNC, OK),
[email protected]eb6234e2012-01-19 01:50:0211510 };
11511 StaticSocketDataProvider data(
11512 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0711513 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]eb6234e2012-01-19 01:50:0211514
danakj1fd259a02016-04-16 03:17:0911515 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]eb6234e2012-01-19 01:50:0211516
bnc525e175a2016-06-20 12:36:4011517 HttpServerProperties* http_server_properties =
[email protected]eb6234e2012-01-19 01:50:0211518 session->http_server_properties();
11519 const int kUnsafePort = 7;
bnc3472afd2016-11-17 15:27:2111520 AlternativeService alternative_service(kProtoHTTP2, "www.example.org",
11521 kUnsafePort);
bnc7dc7e1b42015-07-28 14:43:1211522 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:2111523 http_server_properties->SetHttp2AlternativeService(
zhongyi3d4a55e72016-04-22 20:36:4611524 url::SchemeHostPort(request.url), alternative_service, expiration);
[email protected]eb6234e2012-01-19 01:50:0211525
bnc691fda62016-08-12 00:43:1611526 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]eb6234e2012-01-19 01:50:0211527 TestCompletionCallback callback;
11528
tfarina42834112016-09-22 13:38:2011529 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0111530 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]eb6234e2012-01-19 01:50:0211531 // The HTTP request should succeed.
robpercival214763f2016-07-01 23:27:0111532 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]eb6234e2012-01-19 01:50:0211533
bnc691fda62016-08-12 00:43:1611534 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5211535 ASSERT_TRUE(response);
11536 ASSERT_TRUE(response->headers);
[email protected]eb6234e2012-01-19 01:50:0211537 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
11538
11539 std::string response_data;
bnc691fda62016-08-12 00:43:1611540 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
[email protected]eb6234e2012-01-19 01:50:0211541 EXPECT_EQ("hello world", response_data);
11542}
11543
bncd16676a2016-07-20 16:23:0111544TEST_F(HttpNetworkTransactionTest, UseAlternateProtocolForNpnSpdy) {
[email protected]2ff8b312010-04-26 22:20:5411545 HttpRequestInfo request;
11546 request.method = "GET";
bncb26024382016-06-29 02:39:4511547 request.url = GURL("https://www.example.org/");
[email protected]2ff8b312010-04-26 22:20:5411548
11549 MockRead data_reads[] = {
bncc958faa2015-07-31 18:14:5211550 MockRead("HTTP/1.1 200 OK\r\n"),
bnc2df4b522016-07-08 18:17:4311551 MockRead(kAlternativeServiceHttpHeader),
bncc958faa2015-07-31 18:14:5211552 MockRead("\r\n"),
11553 MockRead("hello world"),
11554 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
11555 MockRead(ASYNC, OK)};
[email protected]2ff8b312010-04-26 22:20:5411556
11557 StaticSocketDataProvider first_transaction(
11558 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0711559 session_deps_.socket_factory->AddSocketDataProvider(&first_transaction);
bncb26024382016-06-29 02:39:4511560 SSLSocketDataProvider ssl_http11(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3611561 ssl_http11.next_proto = kProtoHTTP11;
bncb26024382016-06-29 02:39:4511562 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_http11);
[email protected]2ff8b312010-04-26 22:20:5411563
bnc032658ba2016-09-26 18:17:1511564 AddSSLSocketData();
[email protected]2ff8b312010-04-26 22:20:5411565
bncdf80d44fd2016-07-15 20:27:4111566 SpdySerializedFrame req(
bncb26024382016-06-29 02:39:4511567 spdy_util_.ConstructSpdyGet("https://www.example.org/", 1, LOWEST));
bncdf80d44fd2016-07-15 20:27:4111568 MockWrite spdy_writes[] = {CreateMockWrite(req, 0)};
[email protected]2ff8b312010-04-26 22:20:5411569
bnc42331402016-07-25 13:36:1511570 SpdySerializedFrame resp(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
bncdf80d44fd2016-07-15 20:27:4111571 SpdySerializedFrame data(spdy_util_.ConstructSpdyDataFrame(1, true));
[email protected]2ff8b312010-04-26 22:20:5411572 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:4111573 CreateMockRead(resp, 1), CreateMockRead(data, 2), MockRead(ASYNC, 0, 3),
[email protected]2ff8b312010-04-26 22:20:5411574 };
11575
rch8e6c6c42015-05-01 14:05:1311576 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
11577 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:0711578 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]2ff8b312010-04-26 22:20:5411579
[email protected]d973e99a2012-02-17 21:02:3611580 MockConnect never_finishing_connect(SYNCHRONOUS, ERR_IO_PENDING);
[email protected]2d6728692011-03-12 01:39:5511581 StaticSocketDataProvider hanging_non_alternate_protocol_socket(
11582 NULL, 0, NULL, 0);
11583 hanging_non_alternate_protocol_socket.set_connect_data(
11584 never_finishing_connect);
[email protected]bb88e1d32013-05-03 23:11:0711585 session_deps_.socket_factory->AddSocketDataProvider(
[email protected]2d6728692011-03-12 01:39:5511586 &hanging_non_alternate_protocol_socket);
11587
[email protected]49639fa2011-12-20 23:22:4111588 TestCompletionCallback callback;
[email protected]2ff8b312010-04-26 22:20:5411589
danakj1fd259a02016-04-16 03:17:0911590 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc87dcefc2017-05-25 12:47:5811591 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:1911592 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]2ff8b312010-04-26 22:20:5411593
tfarina42834112016-09-22 13:38:2011594 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0111595 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
11596 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]2ff8b312010-04-26 22:20:5411597
11598 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5211599 ASSERT_TRUE(response);
11600 ASSERT_TRUE(response->headers);
[email protected]2ff8b312010-04-26 22:20:5411601 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
11602
11603 std::string response_data;
robpercival214763f2016-07-01 23:27:0111604 ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
[email protected]2ff8b312010-04-26 22:20:5411605 EXPECT_EQ("hello world", response_data);
11606
bnc87dcefc2017-05-25 12:47:5811607 trans =
Jeremy Roman0579ed62017-08-29 15:56:1911608 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]2ff8b312010-04-26 22:20:5411609
tfarina42834112016-09-22 13:38:2011610 rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0111611 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
11612 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]2ff8b312010-04-26 22:20:5411613
11614 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5211615 ASSERT_TRUE(response);
11616 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0211617 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]65041fa2010-05-21 06:56:5311618 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5211619 EXPECT_TRUE(response->was_alpn_negotiated);
[email protected]2ff8b312010-04-26 22:20:5411620
robpercival214763f2016-07-01 23:27:0111621 ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
[email protected]2ff8b312010-04-26 22:20:5411622 EXPECT_EQ("hello!", response_data);
[email protected]2ff8b312010-04-26 22:20:5411623}
11624
bncd16676a2016-07-20 16:23:0111625TEST_F(HttpNetworkTransactionTest, AlternateProtocolWithSpdyLateBinding) {
[email protected]2d6728692011-03-12 01:39:5511626 HttpRequestInfo request;
11627 request.method = "GET";
bncb26024382016-06-29 02:39:4511628 request.url = GURL("https://www.example.org/");
[email protected]2d6728692011-03-12 01:39:5511629
bncb26024382016-06-29 02:39:4511630 // First transaction receives Alt-Svc header over HTTP/1.1.
[email protected]2d6728692011-03-12 01:39:5511631 MockRead data_reads[] = {
bncc958faa2015-07-31 18:14:5211632 MockRead("HTTP/1.1 200 OK\r\n"),
bnc2df4b522016-07-08 18:17:4311633 MockRead(kAlternativeServiceHttpHeader),
bncc958faa2015-07-31 18:14:5211634 MockRead("\r\n"),
11635 MockRead("hello world"),
11636 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
11637 MockRead(ASYNC, OK),
[email protected]2d6728692011-03-12 01:39:5511638 };
11639
bncb26024382016-06-29 02:39:4511640 StaticSocketDataProvider http11_data(data_reads, arraysize(data_reads), NULL,
11641 0);
11642 session_deps_.socket_factory->AddSocketDataProvider(&http11_data);
[email protected]2d6728692011-03-12 01:39:5511643
bncb26024382016-06-29 02:39:4511644 SSLSocketDataProvider ssl_http11(ASYNC, OK);
Ryan Sleevi4f832092017-11-21 23:25:4911645 ssl_http11.ssl_info.cert =
11646 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem");
11647 ASSERT_TRUE(ssl_http11.ssl_info.cert);
bncb26024382016-06-29 02:39:4511648 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_http11);
11649
11650 // Second transaction starts an alternative and a non-alternative Job.
11651 // Both sockets hang.
[email protected]d973e99a2012-02-17 21:02:3611652 MockConnect never_finishing_connect(SYNCHRONOUS, ERR_IO_PENDING);
mmenkecc2298e2015-12-07 18:20:1811653 StaticSocketDataProvider hanging_socket1(NULL, 0, NULL, 0);
11654 hanging_socket1.set_connect_data(never_finishing_connect);
mmenkecc2298e2015-12-07 18:20:1811655 session_deps_.socket_factory->AddSocketDataProvider(&hanging_socket1);
11656
11657 StaticSocketDataProvider hanging_socket2(NULL, 0, NULL, 0);
11658 hanging_socket2.set_connect_data(never_finishing_connect);
11659 session_deps_.socket_factory->AddSocketDataProvider(&hanging_socket2);
[email protected]2d6728692011-03-12 01:39:5511660
bncb26024382016-06-29 02:39:4511661 // Third transaction starts an alternative and a non-alternative job.
11662 // The non-alternative job hangs, but the alternative one succeeds.
11663 // The second transaction, still pending, binds to this socket.
bncdf80d44fd2016-07-15 20:27:4111664 SpdySerializedFrame req1(
bncb26024382016-06-29 02:39:4511665 spdy_util_.ConstructSpdyGet("https://www.example.org/", 1, LOWEST));
bncdf80d44fd2016-07-15 20:27:4111666 SpdySerializedFrame req2(
bncb26024382016-06-29 02:39:4511667 spdy_util_.ConstructSpdyGet("https://www.example.org/", 3, LOWEST));
[email protected]2d6728692011-03-12 01:39:5511668 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:4111669 CreateMockWrite(req1, 0), CreateMockWrite(req2, 1),
[email protected]2d6728692011-03-12 01:39:5511670 };
bnc42331402016-07-25 13:36:1511671 SpdySerializedFrame resp1(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
bncdf80d44fd2016-07-15 20:27:4111672 SpdySerializedFrame data1(spdy_util_.ConstructSpdyDataFrame(1, true));
bnc42331402016-07-25 13:36:1511673 SpdySerializedFrame resp2(spdy_util_.ConstructSpdyGetReply(NULL, 0, 3));
bncdf80d44fd2016-07-15 20:27:4111674 SpdySerializedFrame data2(spdy_util_.ConstructSpdyDataFrame(3, true));
[email protected]2d6728692011-03-12 01:39:5511675 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:4111676 CreateMockRead(resp1, 2), CreateMockRead(data1, 3),
11677 CreateMockRead(resp2, 4), CreateMockRead(data2, 5),
rch8e6c6c42015-05-01 14:05:1311678 MockRead(ASYNC, 0, 6),
[email protected]2d6728692011-03-12 01:39:5511679 };
11680
rch8e6c6c42015-05-01 14:05:1311681 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
11682 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:0711683 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]2d6728692011-03-12 01:39:5511684
bnc032658ba2016-09-26 18:17:1511685 AddSSLSocketData();
bncb26024382016-06-29 02:39:4511686
mmenkecc2298e2015-12-07 18:20:1811687 StaticSocketDataProvider hanging_socket3(NULL, 0, NULL, 0);
11688 hanging_socket3.set_connect_data(never_finishing_connect);
11689 session_deps_.socket_factory->AddSocketDataProvider(&hanging_socket3);
[email protected]2d6728692011-03-12 01:39:5511690
danakj1fd259a02016-04-16 03:17:0911691 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]49639fa2011-12-20 23:22:4111692 TestCompletionCallback callback1;
[email protected]90499482013-06-01 00:39:5011693 HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
[email protected]2d6728692011-03-12 01:39:5511694
tfarina42834112016-09-22 13:38:2011695 int rv = trans1.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0111696 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
11697 EXPECT_THAT(callback1.WaitForResult(), IsOk());
[email protected]2d6728692011-03-12 01:39:5511698
11699 const HttpResponseInfo* response = trans1.GetResponseInfo();
wezca1070932016-05-26 20:30:5211700 ASSERT_TRUE(response);
11701 ASSERT_TRUE(response->headers);
[email protected]2d6728692011-03-12 01:39:5511702 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
11703
11704 std::string response_data;
robpercival214763f2016-07-01 23:27:0111705 ASSERT_THAT(ReadTransaction(&trans1, &response_data), IsOk());
[email protected]2d6728692011-03-12 01:39:5511706 EXPECT_EQ("hello world", response_data);
11707
[email protected]49639fa2011-12-20 23:22:4111708 TestCompletionCallback callback2;
[email protected]90499482013-06-01 00:39:5011709 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:2011710 rv = trans2.Start(&request, callback2.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0111711 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2d6728692011-03-12 01:39:5511712
[email protected]49639fa2011-12-20 23:22:4111713 TestCompletionCallback callback3;
[email protected]90499482013-06-01 00:39:5011714 HttpNetworkTransaction trans3(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:2011715 rv = trans3.Start(&request, callback3.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0111716 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2d6728692011-03-12 01:39:5511717
robpercival214763f2016-07-01 23:27:0111718 EXPECT_THAT(callback2.WaitForResult(), IsOk());
11719 EXPECT_THAT(callback3.WaitForResult(), IsOk());
[email protected]2d6728692011-03-12 01:39:5511720
11721 response = trans2.GetResponseInfo();
wezca1070932016-05-26 20:30:5211722 ASSERT_TRUE(response);
11723 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0211724 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]2d6728692011-03-12 01:39:5511725 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5211726 EXPECT_TRUE(response->was_alpn_negotiated);
robpercival214763f2016-07-01 23:27:0111727 ASSERT_THAT(ReadTransaction(&trans2, &response_data), IsOk());
[email protected]2d6728692011-03-12 01:39:5511728 EXPECT_EQ("hello!", response_data);
11729
11730 response = trans3.GetResponseInfo();
wezca1070932016-05-26 20:30:5211731 ASSERT_TRUE(response);
11732 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0211733 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]2d6728692011-03-12 01:39:5511734 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5211735 EXPECT_TRUE(response->was_alpn_negotiated);
robpercival214763f2016-07-01 23:27:0111736 ASSERT_THAT(ReadTransaction(&trans3, &response_data), IsOk());
[email protected]2d6728692011-03-12 01:39:5511737 EXPECT_EQ("hello!", response_data);
[email protected]2d6728692011-03-12 01:39:5511738}
11739
bncd16676a2016-07-20 16:23:0111740TEST_F(HttpNetworkTransactionTest, StallAlternativeServiceForNpnSpdy) {
[email protected]2d6728692011-03-12 01:39:5511741 HttpRequestInfo request;
11742 request.method = "GET";
bncb26024382016-06-29 02:39:4511743 request.url = GURL("https://www.example.org/");
[email protected]2d6728692011-03-12 01:39:5511744
11745 MockRead data_reads[] = {
bncc958faa2015-07-31 18:14:5211746 MockRead("HTTP/1.1 200 OK\r\n"),
bnc2df4b522016-07-08 18:17:4311747 MockRead(kAlternativeServiceHttpHeader),
bncc958faa2015-07-31 18:14:5211748 MockRead("\r\n"),
11749 MockRead("hello world"),
11750 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
11751 MockRead(ASYNC, OK),
[email protected]2d6728692011-03-12 01:39:5511752 };
11753
11754 StaticSocketDataProvider first_transaction(
11755 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0711756 session_deps_.socket_factory->AddSocketDataProvider(&first_transaction);
[email protected]2d6728692011-03-12 01:39:5511757
[email protected]8ddf8322012-02-23 18:08:0611758 SSLSocketDataProvider ssl(ASYNC, OK);
Ryan Sleevi4f832092017-11-21 23:25:4911759 ssl.ssl_info.cert =
11760 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem");
11761 ASSERT_TRUE(ssl.ssl_info.cert);
[email protected]bb88e1d32013-05-03 23:11:0711762 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]2d6728692011-03-12 01:39:5511763
[email protected]d973e99a2012-02-17 21:02:3611764 MockConnect never_finishing_connect(SYNCHRONOUS, ERR_IO_PENDING);
[email protected]2d6728692011-03-12 01:39:5511765 StaticSocketDataProvider hanging_alternate_protocol_socket(
11766 NULL, 0, NULL, 0);
11767 hanging_alternate_protocol_socket.set_connect_data(
11768 never_finishing_connect);
[email protected]bb88e1d32013-05-03 23:11:0711769 session_deps_.socket_factory->AddSocketDataProvider(
[email protected]2d6728692011-03-12 01:39:5511770 &hanging_alternate_protocol_socket);
11771
bncb26024382016-06-29 02:39:4511772 // 2nd request is just a copy of the first one, over HTTP/1.1 again.
mmenkecc2298e2015-12-07 18:20:1811773 StaticSocketDataProvider second_transaction(data_reads, arraysize(data_reads),
11774 NULL, 0);
11775 session_deps_.socket_factory->AddSocketDataProvider(&second_transaction);
bncb26024382016-06-29 02:39:4511776 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]2d6728692011-03-12 01:39:5511777
[email protected]49639fa2011-12-20 23:22:4111778 TestCompletionCallback callback;
[email protected]2d6728692011-03-12 01:39:5511779
danakj1fd259a02016-04-16 03:17:0911780 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc87dcefc2017-05-25 12:47:5811781 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:1911782 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]2d6728692011-03-12 01:39:5511783
tfarina42834112016-09-22 13:38:2011784 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0111785 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
11786 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]2d6728692011-03-12 01:39:5511787
11788 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5211789 ASSERT_TRUE(response);
11790 ASSERT_TRUE(response->headers);
[email protected]2d6728692011-03-12 01:39:5511791 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
11792
11793 std::string response_data;
robpercival214763f2016-07-01 23:27:0111794 ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
[email protected]2d6728692011-03-12 01:39:5511795 EXPECT_EQ("hello world", response_data);
11796
bnc87dcefc2017-05-25 12:47:5811797 trans =
Jeremy Roman0579ed62017-08-29 15:56:1911798 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]2d6728692011-03-12 01:39:5511799
tfarina42834112016-09-22 13:38:2011800 rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0111801 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
11802 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]2d6728692011-03-12 01:39:5511803
11804 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5211805 ASSERT_TRUE(response);
11806 ASSERT_TRUE(response->headers);
[email protected]2d6728692011-03-12 01:39:5511807 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
11808 EXPECT_FALSE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5211809 EXPECT_FALSE(response->was_alpn_negotiated);
[email protected]2d6728692011-03-12 01:39:5511810
robpercival214763f2016-07-01 23:27:0111811 ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
[email protected]2d6728692011-03-12 01:39:5511812 EXPECT_EQ("hello world", response_data);
[email protected]2d6728692011-03-12 01:39:5511813}
11814
[email protected]631f1322010-04-30 17:59:1111815class CapturingProxyResolver : public ProxyResolver {
11816 public:
Chris Watkins7a41d3552017-12-01 02:13:2711817 CapturingProxyResolver() = default;
11818 ~CapturingProxyResolver() override = default;
[email protected]631f1322010-04-30 17:59:1111819
dchengb03027d2014-10-21 12:00:2011820 int GetProxyForURL(const GURL& url,
11821 ProxyInfo* results,
11822 const CompletionCallback& callback,
maksim.sisov7e157262016-10-20 11:19:5511823 std::unique_ptr<Request>* request,
tfarina42834112016-09-22 13:38:2011824 const NetLogWithSource& net_log) override {
[email protected]fae7669f2010-08-02 21:49:4011825 ProxyServer proxy_server(ProxyServer::SCHEME_HTTP,
11826 HostPortPair("myproxy", 80));
[email protected]d911f1b2010-05-05 22:39:4211827 results->UseProxyServer(proxy_server);
[email protected]631f1322010-04-30 17:59:1111828 resolved_.push_back(url);
[email protected]d911f1b2010-05-05 22:39:4211829 return OK;
[email protected]631f1322010-04-30 17:59:1111830 }
11831
[email protected]24476402010-07-20 20:55:1711832 const std::vector<GURL>& resolved() const { return resolved_; }
11833
11834 private:
[email protected]631f1322010-04-30 17:59:1111835 std::vector<GURL> resolved_;
11836
11837 DISALLOW_COPY_AND_ASSIGN(CapturingProxyResolver);
11838};
11839
sammce64b2362015-04-29 03:50:2311840class CapturingProxyResolverFactory : public ProxyResolverFactory {
11841 public:
11842 explicit CapturingProxyResolverFactory(CapturingProxyResolver* resolver)
11843 : ProxyResolverFactory(false), resolver_(resolver) {}
11844
11845 int CreateProxyResolver(
11846 const scoped_refptr<ProxyResolverScriptData>& pac_script,
danakj1fd259a02016-04-16 03:17:0911847 std::unique_ptr<ProxyResolver>* resolver,
sammce64b2362015-04-29 03:50:2311848 const net::CompletionCallback& callback,
danakj1fd259a02016-04-16 03:17:0911849 std::unique_ptr<Request>* request) override {
Jeremy Roman0579ed62017-08-29 15:56:1911850 *resolver = std::make_unique<ForwardingProxyResolver>(resolver_);
sammce64b2362015-04-29 03:50:2311851 return OK;
11852 }
11853
11854 private:
11855 ProxyResolver* resolver_;
11856};
11857
bnc2e884782016-08-11 19:45:1911858// Test that proxy is resolved using the origin url,
11859// regardless of the alternative server.
11860TEST_F(HttpNetworkTransactionTest, UseOriginNotAlternativeForProxy) {
11861 // Configure proxy to bypass www.example.org, which is the origin URL.
11862 ProxyConfig proxy_config;
11863 proxy_config.proxy_rules().ParseFromString("myproxy:70");
11864 proxy_config.proxy_rules().bypass_rules.AddRuleFromString("www.example.org");
11865 auto proxy_config_service =
Jeremy Roman0579ed62017-08-29 15:56:1911866 std::make_unique<ProxyConfigServiceFixed>(proxy_config);
bnc2e884782016-08-11 19:45:1911867
11868 CapturingProxyResolver capturing_proxy_resolver;
Jeremy Roman0579ed62017-08-29 15:56:1911869 auto proxy_resolver_factory = std::make_unique<CapturingProxyResolverFactory>(
bnc2e884782016-08-11 19:45:1911870 &capturing_proxy_resolver);
11871
11872 TestNetLog net_log;
11873
Jeremy Roman0579ed62017-08-29 15:56:1911874 session_deps_.proxy_service = std::make_unique<ProxyService>(
bnc2e884782016-08-11 19:45:1911875 std::move(proxy_config_service), std::move(proxy_resolver_factory),
11876 &net_log);
11877
11878 session_deps_.net_log = &net_log;
11879
11880 // Configure alternative service with a hostname that is not bypassed by the
11881 // proxy.
11882 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
11883 HttpServerProperties* http_server_properties =
11884 session->http_server_properties();
11885 url::SchemeHostPort server("https", "www.example.org", 443);
11886 HostPortPair alternative("www.example.com", 443);
bnc3472afd2016-11-17 15:27:2111887 AlternativeService alternative_service(kProtoHTTP2, alternative);
bnc2e884782016-08-11 19:45:1911888 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:2111889 http_server_properties->SetHttp2AlternativeService(
11890 server, alternative_service, expiration);
bnc2e884782016-08-11 19:45:1911891
11892 // Non-alternative job should hang.
11893 MockConnect never_finishing_connect(SYNCHRONOUS, ERR_IO_PENDING);
11894 StaticSocketDataProvider hanging_alternate_protocol_socket(nullptr, 0,
11895 nullptr, 0);
11896 hanging_alternate_protocol_socket.set_connect_data(never_finishing_connect);
11897 session_deps_.socket_factory->AddSocketDataProvider(
11898 &hanging_alternate_protocol_socket);
11899
bnc032658ba2016-09-26 18:17:1511900 AddSSLSocketData();
bnc2e884782016-08-11 19:45:1911901
11902 HttpRequestInfo request;
11903 request.method = "GET";
11904 request.url = GURL("https://www.example.org/");
11905 request.load_flags = 0;
11906
11907 SpdySerializedFrame req(
11908 spdy_util_.ConstructSpdyGet("https://www.example.org/", 1, LOWEST));
11909
11910 MockWrite spdy_writes[] = {CreateMockWrite(req, 0)};
11911
11912 SpdySerializedFrame resp(spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
11913 SpdySerializedFrame data(spdy_util_.ConstructSpdyDataFrame(1, true));
11914 MockRead spdy_reads[] = {
11915 CreateMockRead(resp, 1), CreateMockRead(data, 2), MockRead(ASYNC, 0, 3),
11916 };
11917
11918 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
11919 arraysize(spdy_writes));
11920 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
11921
11922 TestCompletionCallback callback;
11923
11924 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
11925
tfarina42834112016-09-22 13:38:2011926 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
bnc2e884782016-08-11 19:45:1911927 EXPECT_THAT(callback.GetResult(rv), IsOk());
11928
11929 const HttpResponseInfo* response = trans.GetResponseInfo();
11930 ASSERT_TRUE(response);
11931 ASSERT_TRUE(response->headers);
11932 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
11933 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5211934 EXPECT_TRUE(response->was_alpn_negotiated);
bnc2e884782016-08-11 19:45:1911935
11936 std::string response_data;
11937 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
11938 EXPECT_EQ("hello!", response_data);
11939
11940 // Origin host bypasses proxy, no resolution should have happened.
11941 ASSERT_TRUE(capturing_proxy_resolver.resolved().empty());
11942}
11943
bncd16676a2016-07-20 16:23:0111944TEST_F(HttpNetworkTransactionTest, UseAlternativeServiceForTunneledNpnSpdy) {
[email protected]631f1322010-04-30 17:59:1111945 ProxyConfig proxy_config;
[email protected]d911f1b2010-05-05 22:39:4211946 proxy_config.set_auto_detect(true);
11947 proxy_config.set_pac_url(GURL("http://fooproxyurl"));
[email protected]2227c692010-05-04 15:36:1111948
sammc5dd160c2015-04-02 02:43:1311949 CapturingProxyResolver capturing_proxy_resolver;
Jeremy Roman0579ed62017-08-29 15:56:1911950 session_deps_.proxy_service = std::make_unique<ProxyService>(
11951 std::make_unique<ProxyConfigServiceFixed>(proxy_config),
11952 std::make_unique<CapturingProxyResolverFactory>(
bnc87dcefc2017-05-25 12:47:5811953 &capturing_proxy_resolver),
11954 nullptr);
vishal.b62985ca92015-04-17 08:45:5111955 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:0711956 session_deps_.net_log = &net_log;
[email protected]631f1322010-04-30 17:59:1111957
11958 HttpRequestInfo request;
11959 request.method = "GET";
bncb26024382016-06-29 02:39:4511960 request.url = GURL("https://www.example.org/");
[email protected]631f1322010-04-30 17:59:1111961
11962 MockRead data_reads[] = {
bncc958faa2015-07-31 18:14:5211963 MockRead("HTTP/1.1 200 OK\r\n"),
bnc2df4b522016-07-08 18:17:4311964 MockRead(kAlternativeServiceHttpHeader),
bncc958faa2015-07-31 18:14:5211965 MockRead("\r\n"),
11966 MockRead("hello world"),
11967 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
11968 MockRead(ASYNC, OK),
[email protected]631f1322010-04-30 17:59:1111969 };
11970
11971 StaticSocketDataProvider first_transaction(
11972 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0711973 session_deps_.socket_factory->AddSocketDataProvider(&first_transaction);
bncb26024382016-06-29 02:39:4511974 SSLSocketDataProvider ssl_http11(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3611975 ssl_http11.next_proto = kProtoHTTP11;
bncb26024382016-06-29 02:39:4511976 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_http11);
[email protected]631f1322010-04-30 17:59:1111977
bnc032658ba2016-09-26 18:17:1511978 AddSSLSocketData();
[email protected]631f1322010-04-30 17:59:1111979
bncdf80d44fd2016-07-15 20:27:4111980 SpdySerializedFrame req(
bncb26024382016-06-29 02:39:4511981 spdy_util_.ConstructSpdyGet("https://www.example.org/", 1, LOWEST));
[email protected]631f1322010-04-30 17:59:1111982 MockWrite spdy_writes[] = {
rch8e6c6c42015-05-01 14:05:1311983 MockWrite(ASYNC, 0,
bnc8bef8da22016-05-30 01:28:2511984 "CONNECT www.example.org:443 HTTP/1.1\r\n"
11985 "Host: www.example.org:443\r\n"
rch8e6c6c42015-05-01 14:05:1311986 "Proxy-Connection: keep-alive\r\n\r\n"),
bncdf80d44fd2016-07-15 20:27:4111987 CreateMockWrite(req, 2),
[email protected]631f1322010-04-30 17:59:1111988 };
11989
[email protected]d911f1b2010-05-05 22:39:4211990 const char kCONNECTResponse[] = "HTTP/1.1 200 Connected\r\n\r\n";
11991
bnc42331402016-07-25 13:36:1511992 SpdySerializedFrame resp(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
bncdf80d44fd2016-07-15 20:27:4111993 SpdySerializedFrame data(spdy_util_.ConstructSpdyDataFrame(1, true));
[email protected]631f1322010-04-30 17:59:1111994 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:4111995 MockRead(ASYNC, 1, kCONNECTResponse), CreateMockRead(resp, 3),
11996 CreateMockRead(data, 4), MockRead(SYNCHRONOUS, ERR_IO_PENDING, 5),
[email protected]631f1322010-04-30 17:59:1111997 };
11998
rch8e6c6c42015-05-01 14:05:1311999 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
12000 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:0712001 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]631f1322010-04-30 17:59:1112002
[email protected]d973e99a2012-02-17 21:02:3612003 MockConnect never_finishing_connect(SYNCHRONOUS, ERR_IO_PENDING);
[email protected]2d6728692011-03-12 01:39:5512004 StaticSocketDataProvider hanging_non_alternate_protocol_socket(
12005 NULL, 0, NULL, 0);
12006 hanging_non_alternate_protocol_socket.set_connect_data(
12007 never_finishing_connect);
[email protected]bb88e1d32013-05-03 23:11:0712008 session_deps_.socket_factory->AddSocketDataProvider(
[email protected]2d6728692011-03-12 01:39:5512009 &hanging_non_alternate_protocol_socket);
12010
[email protected]49639fa2011-12-20 23:22:4112011 TestCompletionCallback callback;
[email protected]631f1322010-04-30 17:59:1112012
danakj1fd259a02016-04-16 03:17:0912013 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc87dcefc2017-05-25 12:47:5812014 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:1912015 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]631f1322010-04-30 17:59:1112016
tfarina42834112016-09-22 13:38:2012017 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
mmenkea2dcd3bf2016-08-16 21:49:4112018 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
12019 EXPECT_THAT(callback.WaitForResult(), IsOk());
12020
12021 const HttpResponseInfo* response = trans->GetResponseInfo();
12022 ASSERT_TRUE(response);
12023 ASSERT_TRUE(response->headers);
12024 EXPECT_EQ("HTTP/0.9 200 OK", response->headers->GetStatusLine());
12025 EXPECT_FALSE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5212026 EXPECT_TRUE(response->was_alpn_negotiated);
mmenkea2dcd3bf2016-08-16 21:49:4112027
12028 std::string response_data;
12029 ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
12030 EXPECT_EQ("hello world", response_data);
[email protected]631f1322010-04-30 17:59:1112031
bnc87dcefc2017-05-25 12:47:5812032 trans =
Jeremy Roman0579ed62017-08-29 15:56:1912033 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]631f1322010-04-30 17:59:1112034
tfarina42834112016-09-22 13:38:2012035 rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0112036 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
12037 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]631f1322010-04-30 17:59:1112038
mmenkea2dcd3bf2016-08-16 21:49:4112039 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5212040 ASSERT_TRUE(response);
12041 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0212042 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]65041fa2010-05-21 06:56:5312043 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5212044 EXPECT_TRUE(response->was_alpn_negotiated);
[email protected]631f1322010-04-30 17:59:1112045
robpercival214763f2016-07-01 23:27:0112046 ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
[email protected]631f1322010-04-30 17:59:1112047 EXPECT_EQ("hello!", response_data);
bncb26024382016-06-29 02:39:4512048 ASSERT_EQ(2u, capturing_proxy_resolver.resolved().size());
12049 EXPECT_EQ("https://www.example.org/",
sammc5dd160c2015-04-02 02:43:1312050 capturing_proxy_resolver.resolved()[0].spec());
bncce36dca22015-04-21 22:11:2312051 EXPECT_EQ("https://www.example.org/",
sammc5dd160c2015-04-02 02:43:1312052 capturing_proxy_resolver.resolved()[1].spec());
[email protected]631f1322010-04-30 17:59:1112053
[email protected]029c83b62013-01-24 05:28:2012054 LoadTimingInfo load_timing_info;
12055 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
12056 TestLoadTimingNotReusedWithPac(load_timing_info,
12057 CONNECT_TIMING_HAS_SSL_TIMES);
[email protected]631f1322010-04-30 17:59:1112058}
[email protected]631f1322010-04-30 17:59:1112059
bncd16676a2016-07-20 16:23:0112060TEST_F(HttpNetworkTransactionTest,
bnc1c196c6e2016-05-28 13:51:4812061 UseAlternativeServiceForNpnSpdyWithExistingSpdySession) {
[email protected]2ff8b312010-04-26 22:20:5412062 HttpRequestInfo request;
12063 request.method = "GET";
bncb26024382016-06-29 02:39:4512064 request.url = GURL("https://www.example.org/");
[email protected]2ff8b312010-04-26 22:20:5412065
12066 MockRead data_reads[] = {
bncc958faa2015-07-31 18:14:5212067 MockRead("HTTP/1.1 200 OK\r\n"),
bnc2df4b522016-07-08 18:17:4312068 MockRead(kAlternativeServiceHttpHeader),
bncc958faa2015-07-31 18:14:5212069 MockRead("\r\n"),
12070 MockRead("hello world"),
12071 MockRead(ASYNC, OK),
[email protected]2ff8b312010-04-26 22:20:5412072 };
12073
12074 StaticSocketDataProvider first_transaction(
12075 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0712076 session_deps_.socket_factory->AddSocketDataProvider(&first_transaction);
bncb26024382016-06-29 02:39:4512077 SSLSocketDataProvider ssl_http11(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3612078 ssl_http11.next_proto = kProtoHTTP11;
bncb26024382016-06-29 02:39:4512079 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_http11);
[email protected]2ff8b312010-04-26 22:20:5412080
bnc032658ba2016-09-26 18:17:1512081 AddSSLSocketData();
[email protected]2ff8b312010-04-26 22:20:5412082
bncdf80d44fd2016-07-15 20:27:4112083 SpdySerializedFrame req(
bncb26024382016-06-29 02:39:4512084 spdy_util_.ConstructSpdyGet("https://www.example.org/", 1, LOWEST));
bncdf80d44fd2016-07-15 20:27:4112085 MockWrite spdy_writes[] = {CreateMockWrite(req, 0)};
[email protected]2ff8b312010-04-26 22:20:5412086
bnc42331402016-07-25 13:36:1512087 SpdySerializedFrame resp(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
bncdf80d44fd2016-07-15 20:27:4112088 SpdySerializedFrame data(spdy_util_.ConstructSpdyDataFrame(1, true));
[email protected]2ff8b312010-04-26 22:20:5412089 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:4112090 CreateMockRead(resp, 1), CreateMockRead(data, 2), MockRead(ASYNC, 0, 3),
[email protected]2ff8b312010-04-26 22:20:5412091 };
12092
rch8e6c6c42015-05-01 14:05:1312093 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
12094 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:0712095 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]2ff8b312010-04-26 22:20:5412096
[email protected]83039bb2011-12-09 18:43:5512097 TestCompletionCallback callback;
[email protected]2ff8b312010-04-26 22:20:5412098
danakj1fd259a02016-04-16 03:17:0912099 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]2ff8b312010-04-26 22:20:5412100
bnc87dcefc2017-05-25 12:47:5812101 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:1912102 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]2ff8b312010-04-26 22:20:5412103
tfarina42834112016-09-22 13:38:2012104 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0112105 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
12106 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]2ff8b312010-04-26 22:20:5412107
12108 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5212109 ASSERT_TRUE(response);
12110 ASSERT_TRUE(response->headers);
[email protected]2ff8b312010-04-26 22:20:5412111 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
12112
12113 std::string response_data;
robpercival214763f2016-07-01 23:27:0112114 ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
[email protected]2ff8b312010-04-26 22:20:5412115 EXPECT_EQ("hello world", response_data);
12116
12117 // Set up an initial SpdySession in the pool to reuse.
bnc8bef8da22016-05-30 01:28:2512118 HostPortPair host_port_pair("www.example.org", 443);
[email protected]e6d017652013-05-17 18:01:4012119 SpdySessionKey key(host_port_pair, ProxyServer::Direct(),
Paul Jensena457017a2018-01-19 23:52:0412120 PRIVACY_MODE_DISABLED, SocketTag());
[email protected]795cbf82013-07-22 09:37:2712121 base::WeakPtr<SpdySession> spdy_session =
Bence Béky0ef1556e2017-06-30 19:52:5212122 CreateSpdySession(session.get(), key, NetLogWithSource());
[email protected]02b0c342010-09-25 21:09:3812123
bnc87dcefc2017-05-25 12:47:5812124 trans =
Jeremy Roman0579ed62017-08-29 15:56:1912125 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]2ff8b312010-04-26 22:20:5412126
tfarina42834112016-09-22 13:38:2012127 rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0112128 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
12129 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]2ff8b312010-04-26 22:20:5412130
12131 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5212132 ASSERT_TRUE(response);
12133 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0212134 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]65041fa2010-05-21 06:56:5312135 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5212136 EXPECT_TRUE(response->was_alpn_negotiated);
[email protected]2ff8b312010-04-26 22:20:5412137
robpercival214763f2016-07-01 23:27:0112138 ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
[email protected]2ff8b312010-04-26 22:20:5412139 EXPECT_EQ("hello!", response_data);
[email protected]564b4912010-03-09 16:30:4212140}
12141
[email protected]044de0642010-06-17 10:42:1512142// GenerateAuthToken is a mighty big test.
12143// It tests all permutation of GenerateAuthToken behavior:
12144// - Synchronous and Asynchronous completion.
12145// - OK or error on completion.
12146// - Direct connection, non-authenticating proxy, and authenticating proxy.
12147// - HTTP or HTTPS backend (to include proxy tunneling).
12148// - Non-authenticating and authenticating backend.
12149//
[email protected]fe3b7dc2012-02-03 19:52:0912150// In all, there are 44 reasonable permuations (for example, if there are
[email protected]044de0642010-06-17 10:42:1512151// problems generating an auth token for an authenticating proxy, we don't
12152// need to test all permutations of the backend server).
12153//
12154// The test proceeds by going over each of the configuration cases, and
12155// potentially running up to three rounds in each of the tests. The TestConfig
12156// specifies both the configuration for the test as well as the expectations
12157// for the results.
bncd16676a2016-07-20 16:23:0112158TEST_F(HttpNetworkTransactionTest, GenerateAuthToken) {
[email protected]0b0bf032010-09-21 18:08:5012159 static const char kServer[] = "http://www.example.com";
12160 static const char kSecureServer[] = "https://www.example.com";
12161 static const char kProxy[] = "myproxy:70";
[email protected]044de0642010-06-17 10:42:1512162
12163 enum AuthTiming {
12164 AUTH_NONE,
12165 AUTH_SYNC,
12166 AUTH_ASYNC,
12167 };
12168
12169 const MockWrite kGet(
12170 "GET / HTTP/1.1\r\n"
12171 "Host: www.example.com\r\n"
12172 "Connection: keep-alive\r\n\r\n");
12173 const MockWrite kGetProxy(
12174 "GET http://www.example.com/ HTTP/1.1\r\n"
12175 "Host: www.example.com\r\n"
12176 "Proxy-Connection: keep-alive\r\n\r\n");
12177 const MockWrite kGetAuth(
12178 "GET / HTTP/1.1\r\n"
12179 "Host: www.example.com\r\n"
12180 "Connection: keep-alive\r\n"
12181 "Authorization: auth_token\r\n\r\n");
12182 const MockWrite kGetProxyAuth(
12183 "GET http://www.example.com/ HTTP/1.1\r\n"
12184 "Host: www.example.com\r\n"
12185 "Proxy-Connection: keep-alive\r\n"
12186 "Proxy-Authorization: auth_token\r\n\r\n");
12187 const MockWrite kGetAuthThroughProxy(
12188 "GET http://www.example.com/ HTTP/1.1\r\n"
12189 "Host: www.example.com\r\n"
12190 "Proxy-Connection: keep-alive\r\n"
12191 "Authorization: auth_token\r\n\r\n");
12192 const MockWrite kGetAuthWithProxyAuth(
12193 "GET http://www.example.com/ HTTP/1.1\r\n"
12194 "Host: www.example.com\r\n"
12195 "Proxy-Connection: keep-alive\r\n"
12196 "Proxy-Authorization: auth_token\r\n"
12197 "Authorization: auth_token\r\n\r\n");
12198 const MockWrite kConnect(
12199 "CONNECT www.example.com:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:1712200 "Host: www.example.com:443\r\n"
[email protected]044de0642010-06-17 10:42:1512201 "Proxy-Connection: keep-alive\r\n\r\n");
12202 const MockWrite kConnectProxyAuth(
12203 "CONNECT www.example.com:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:1712204 "Host: www.example.com:443\r\n"
[email protected]044de0642010-06-17 10:42:1512205 "Proxy-Connection: keep-alive\r\n"
12206 "Proxy-Authorization: auth_token\r\n\r\n");
12207
12208 const MockRead kSuccess(
12209 "HTTP/1.1 200 OK\r\n"
12210 "Content-Type: text/html; charset=iso-8859-1\r\n"
12211 "Content-Length: 3\r\n\r\n"
12212 "Yes");
12213 const MockRead kFailure(
12214 "Should not be called.");
12215 const MockRead kServerChallenge(
12216 "HTTP/1.1 401 Unauthorized\r\n"
12217 "WWW-Authenticate: Mock realm=server\r\n"
12218 "Content-Type: text/html; charset=iso-8859-1\r\n"
12219 "Content-Length: 14\r\n\r\n"
12220 "Unauthorized\r\n");
12221 const MockRead kProxyChallenge(
12222 "HTTP/1.1 407 Unauthorized\r\n"
12223 "Proxy-Authenticate: Mock realm=proxy\r\n"
12224 "Proxy-Connection: close\r\n"
12225 "Content-Type: text/html; charset=iso-8859-1\r\n"
12226 "Content-Length: 14\r\n\r\n"
12227 "Unauthorized\r\n");
12228 const MockRead kProxyConnected(
12229 "HTTP/1.1 200 Connection Established\r\n\r\n");
12230
12231 // NOTE(cbentzel): I wanted TestReadWriteRound to be a simple struct with
12232 // no constructors, but the C++ compiler on Windows warns about
12233 // unspecified data in compound literals. So, moved to using constructors,
12234 // and TestRound's created with the default constructor should not be used.
12235 struct TestRound {
12236 TestRound()
12237 : expected_rv(ERR_UNEXPECTED),
12238 extra_write(NULL),
12239 extra_read(NULL) {
12240 }
12241 TestRound(const MockWrite& write_arg, const MockRead& read_arg,
12242 int expected_rv_arg)
12243 : write(write_arg),
12244 read(read_arg),
12245 expected_rv(expected_rv_arg),
12246 extra_write(NULL),
12247 extra_read(NULL) {
12248 }
12249 TestRound(const MockWrite& write_arg, const MockRead& read_arg,
12250 int expected_rv_arg, const MockWrite* extra_write_arg,
[email protected]f871ee152012-07-27 19:02:0112251 const MockRead* extra_read_arg)
[email protected]044de0642010-06-17 10:42:1512252 : write(write_arg),
12253 read(read_arg),
12254 expected_rv(expected_rv_arg),
12255 extra_write(extra_write_arg),
12256 extra_read(extra_read_arg) {
12257 }
12258 MockWrite write;
12259 MockRead read;
12260 int expected_rv;
12261 const MockWrite* extra_write;
12262 const MockRead* extra_read;
12263 };
12264
12265 static const int kNoSSL = 500;
12266
12267 struct TestConfig {
asanka463ca4262016-11-16 02:34:3112268 int line_number;
thestig9d3bb0c2015-01-24 00:49:5112269 const char* const proxy_url;
[email protected]044de0642010-06-17 10:42:1512270 AuthTiming proxy_auth_timing;
asanka463ca4262016-11-16 02:34:3112271 int first_generate_proxy_token_rv;
thestig9d3bb0c2015-01-24 00:49:5112272 const char* const server_url;
[email protected]044de0642010-06-17 10:42:1512273 AuthTiming server_auth_timing;
asanka463ca4262016-11-16 02:34:3112274 int first_generate_server_token_rv;
[email protected]044de0642010-06-17 10:42:1512275 int num_auth_rounds;
12276 int first_ssl_round;
asankae2257db2016-10-11 22:03:1612277 TestRound rounds[4];
[email protected]044de0642010-06-17 10:42:1512278 } test_configs[] = {
asankac93076192016-10-03 15:46:0212279 // Non-authenticating HTTP server with a direct connection.
asanka463ca4262016-11-16 02:34:3112280 {__LINE__,
12281 nullptr,
asankac93076192016-10-03 15:46:0212282 AUTH_NONE,
12283 OK,
12284 kServer,
12285 AUTH_NONE,
12286 OK,
12287 1,
12288 kNoSSL,
12289 {TestRound(kGet, kSuccess, OK)}},
12290 // Authenticating HTTP server with a direct connection.
asanka463ca4262016-11-16 02:34:3112291 {__LINE__,
12292 nullptr,
asankac93076192016-10-03 15:46:0212293 AUTH_NONE,
12294 OK,
12295 kServer,
12296 AUTH_SYNC,
12297 OK,
12298 2,
12299 kNoSSL,
12300 {TestRound(kGet, kServerChallenge, OK),
[email protected]044de0642010-06-17 10:42:1512301 TestRound(kGetAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112302 {__LINE__,
12303 nullptr,
asankac93076192016-10-03 15:46:0212304 AUTH_NONE,
12305 OK,
12306 kServer,
12307 AUTH_SYNC,
12308 ERR_INVALID_AUTH_CREDENTIALS,
asankae2257db2016-10-11 22:03:1612309 3,
12310 kNoSSL,
12311 {TestRound(kGet, kServerChallenge, OK),
12312 TestRound(kGet, kServerChallenge, OK),
12313 TestRound(kGetAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112314 {__LINE__,
12315 nullptr,
asankae2257db2016-10-11 22:03:1612316 AUTH_NONE,
12317 OK,
12318 kServer,
12319 AUTH_SYNC,
12320 ERR_UNSUPPORTED_AUTH_SCHEME,
12321 2,
12322 kNoSSL,
12323 {TestRound(kGet, kServerChallenge, OK), TestRound(kGet, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112324 {__LINE__,
12325 nullptr,
asankae2257db2016-10-11 22:03:1612326 AUTH_NONE,
12327 OK,
12328 kServer,
12329 AUTH_SYNC,
12330 ERR_UNDOCUMENTED_SECURITY_LIBRARY_STATUS,
12331 2,
12332 kNoSSL,
12333 {TestRound(kGet, kServerChallenge, OK), TestRound(kGet, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112334 {__LINE__,
12335 kProxy,
asankae2257db2016-10-11 22:03:1612336 AUTH_SYNC,
12337 ERR_FAILED,
12338 kServer,
12339 AUTH_NONE,
12340 OK,
12341 2,
12342 kNoSSL,
12343 {TestRound(kGetProxy, kProxyChallenge, OK),
12344 TestRound(kGetProxy, kFailure, ERR_FAILED)}},
asanka463ca4262016-11-16 02:34:3112345 {__LINE__,
12346 kProxy,
asankae2257db2016-10-11 22:03:1612347 AUTH_ASYNC,
12348 ERR_FAILED,
12349 kServer,
12350 AUTH_NONE,
12351 OK,
12352 2,
12353 kNoSSL,
12354 {TestRound(kGetProxy, kProxyChallenge, OK),
12355 TestRound(kGetProxy, kFailure, ERR_FAILED)}},
asanka463ca4262016-11-16 02:34:3112356 {__LINE__,
12357 nullptr,
asankae2257db2016-10-11 22:03:1612358 AUTH_NONE,
12359 OK,
12360 kServer,
12361 AUTH_SYNC,
12362 ERR_FAILED,
asankac93076192016-10-03 15:46:0212363 2,
12364 kNoSSL,
12365 {TestRound(kGet, kServerChallenge, OK),
asankae2257db2016-10-11 22:03:1612366 TestRound(kGet, kFailure, ERR_FAILED)}},
asanka463ca4262016-11-16 02:34:3112367 {__LINE__,
12368 nullptr,
asankae2257db2016-10-11 22:03:1612369 AUTH_NONE,
12370 OK,
12371 kServer,
12372 AUTH_ASYNC,
12373 ERR_FAILED,
12374 2,
12375 kNoSSL,
12376 {TestRound(kGet, kServerChallenge, OK),
12377 TestRound(kGet, kFailure, ERR_FAILED)}},
asanka463ca4262016-11-16 02:34:3112378 {__LINE__,
12379 nullptr,
asankac93076192016-10-03 15:46:0212380 AUTH_NONE,
12381 OK,
12382 kServer,
12383 AUTH_ASYNC,
12384 OK,
12385 2,
12386 kNoSSL,
12387 {TestRound(kGet, kServerChallenge, OK),
[email protected]044de0642010-06-17 10:42:1512388 TestRound(kGetAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112389 {__LINE__,
12390 nullptr,
asankac93076192016-10-03 15:46:0212391 AUTH_NONE,
12392 OK,
12393 kServer,
12394 AUTH_ASYNC,
12395 ERR_INVALID_AUTH_CREDENTIALS,
asankae2257db2016-10-11 22:03:1612396 3,
asankac93076192016-10-03 15:46:0212397 kNoSSL,
12398 {TestRound(kGet, kServerChallenge, OK),
asankae2257db2016-10-11 22:03:1612399 // The second round uses a HttpAuthHandlerMock that always succeeds.
12400 TestRound(kGet, kServerChallenge, OK),
12401 TestRound(kGetAuth, kSuccess, OK)}},
asankac93076192016-10-03 15:46:0212402 // Non-authenticating HTTP server through a non-authenticating proxy.
asanka463ca4262016-11-16 02:34:3112403 {__LINE__,
12404 kProxy,
asankac93076192016-10-03 15:46:0212405 AUTH_NONE,
12406 OK,
12407 kServer,
12408 AUTH_NONE,
12409 OK,
12410 1,
12411 kNoSSL,
12412 {TestRound(kGetProxy, kSuccess, OK)}},
12413 // Authenticating HTTP server through a non-authenticating proxy.
asanka463ca4262016-11-16 02:34:3112414 {__LINE__,
12415 kProxy,
asankac93076192016-10-03 15:46:0212416 AUTH_NONE,
12417 OK,
12418 kServer,
12419 AUTH_SYNC,
12420 OK,
12421 2,
12422 kNoSSL,
12423 {TestRound(kGetProxy, kServerChallenge, OK),
[email protected]044de0642010-06-17 10:42:1512424 TestRound(kGetAuthThroughProxy, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112425 {__LINE__,
12426 kProxy,
asankac93076192016-10-03 15:46:0212427 AUTH_NONE,
12428 OK,
12429 kServer,
12430 AUTH_SYNC,
12431 ERR_INVALID_AUTH_CREDENTIALS,
asankae2257db2016-10-11 22:03:1612432 3,
asankac93076192016-10-03 15:46:0212433 kNoSSL,
12434 {TestRound(kGetProxy, kServerChallenge, OK),
asankae2257db2016-10-11 22:03:1612435 TestRound(kGetProxy, kServerChallenge, OK),
12436 TestRound(kGetAuthThroughProxy, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112437 {__LINE__,
12438 kProxy,
asankac93076192016-10-03 15:46:0212439 AUTH_NONE,
12440 OK,
12441 kServer,
12442 AUTH_ASYNC,
12443 OK,
12444 2,
12445 kNoSSL,
12446 {TestRound(kGetProxy, kServerChallenge, OK),
[email protected]044de0642010-06-17 10:42:1512447 TestRound(kGetAuthThroughProxy, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112448 {__LINE__,
12449 kProxy,
asankac93076192016-10-03 15:46:0212450 AUTH_NONE,
12451 OK,
12452 kServer,
12453 AUTH_ASYNC,
12454 ERR_INVALID_AUTH_CREDENTIALS,
12455 2,
12456 kNoSSL,
12457 {TestRound(kGetProxy, kServerChallenge, OK),
asankae2257db2016-10-11 22:03:1612458 TestRound(kGetProxy, kSuccess, OK)}},
asankac93076192016-10-03 15:46:0212459 // Non-authenticating HTTP server through an authenticating proxy.
asanka463ca4262016-11-16 02:34:3112460 {__LINE__,
12461 kProxy,
asankac93076192016-10-03 15:46:0212462 AUTH_SYNC,
12463 OK,
12464 kServer,
12465 AUTH_NONE,
12466 OK,
12467 2,
12468 kNoSSL,
12469 {TestRound(kGetProxy, kProxyChallenge, OK),
[email protected]044de0642010-06-17 10:42:1512470 TestRound(kGetProxyAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112471 {__LINE__,
12472 kProxy,
asankac93076192016-10-03 15:46:0212473 AUTH_SYNC,
12474 ERR_INVALID_AUTH_CREDENTIALS,
12475 kServer,
12476 AUTH_NONE,
12477 OK,
12478 2,
12479 kNoSSL,
12480 {TestRound(kGetProxy, kProxyChallenge, OK),
asankae2257db2016-10-11 22:03:1612481 TestRound(kGetProxy, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112482 {__LINE__,
12483 kProxy,
asankac93076192016-10-03 15:46:0212484 AUTH_ASYNC,
12485 OK,
12486 kServer,
12487 AUTH_NONE,
12488 OK,
12489 2,
12490 kNoSSL,
12491 {TestRound(kGetProxy, kProxyChallenge, OK),
[email protected]044de0642010-06-17 10:42:1512492 TestRound(kGetProxyAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112493 {__LINE__,
12494 kProxy,
asankac93076192016-10-03 15:46:0212495 AUTH_ASYNC,
12496 ERR_INVALID_AUTH_CREDENTIALS,
12497 kServer,
12498 AUTH_NONE,
12499 OK,
12500 2,
12501 kNoSSL,
12502 {TestRound(kGetProxy, kProxyChallenge, OK),
asankae2257db2016-10-11 22:03:1612503 TestRound(kGetProxy, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112504 {__LINE__,
12505 kProxy,
12506 AUTH_ASYNC,
12507 ERR_INVALID_AUTH_CREDENTIALS,
12508 kServer,
12509 AUTH_NONE,
12510 OK,
12511 3,
12512 kNoSSL,
12513 {TestRound(kGetProxy, kProxyChallenge, OK),
12514 TestRound(kGetProxy, kProxyChallenge, OK),
12515 TestRound(kGetProxyAuth, kSuccess, OK)}},
asankac93076192016-10-03 15:46:0212516 // Authenticating HTTP server through an authenticating proxy.
asanka463ca4262016-11-16 02:34:3112517 {__LINE__,
12518 kProxy,
asankac93076192016-10-03 15:46:0212519 AUTH_SYNC,
12520 OK,
12521 kServer,
12522 AUTH_SYNC,
12523 OK,
12524 3,
12525 kNoSSL,
12526 {TestRound(kGetProxy, kProxyChallenge, OK),
[email protected]044de0642010-06-17 10:42:1512527 TestRound(kGetProxyAuth, kServerChallenge, OK),
12528 TestRound(kGetAuthWithProxyAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112529 {__LINE__,
12530 kProxy,
asankac93076192016-10-03 15:46:0212531 AUTH_SYNC,
12532 OK,
12533 kServer,
12534 AUTH_SYNC,
12535 ERR_INVALID_AUTH_CREDENTIALS,
12536 3,
12537 kNoSSL,
12538 {TestRound(kGetProxy, kProxyChallenge, OK),
[email protected]044de0642010-06-17 10:42:1512539 TestRound(kGetProxyAuth, kServerChallenge, OK),
asankae2257db2016-10-11 22:03:1612540 TestRound(kGetProxyAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112541 {__LINE__,
12542 kProxy,
asankac93076192016-10-03 15:46:0212543 AUTH_ASYNC,
12544 OK,
12545 kServer,
12546 AUTH_SYNC,
12547 OK,
12548 3,
12549 kNoSSL,
12550 {TestRound(kGetProxy, kProxyChallenge, OK),
[email protected]044de0642010-06-17 10:42:1512551 TestRound(kGetProxyAuth, kServerChallenge, OK),
12552 TestRound(kGetAuthWithProxyAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112553 {__LINE__,
12554 kProxy,
asankac93076192016-10-03 15:46:0212555 AUTH_ASYNC,
12556 OK,
12557 kServer,
12558 AUTH_SYNC,
12559 ERR_INVALID_AUTH_CREDENTIALS,
12560 3,
12561 kNoSSL,
12562 {TestRound(kGetProxy, kProxyChallenge, OK),
[email protected]044de0642010-06-17 10:42:1512563 TestRound(kGetProxyAuth, kServerChallenge, OK),
asankae2257db2016-10-11 22:03:1612564 TestRound(kGetProxyAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112565 {__LINE__,
12566 kProxy,
asankac93076192016-10-03 15:46:0212567 AUTH_SYNC,
12568 OK,
12569 kServer,
12570 AUTH_ASYNC,
12571 OK,
12572 3,
12573 kNoSSL,
12574 {TestRound(kGetProxy, kProxyChallenge, OK),
[email protected]044de0642010-06-17 10:42:1512575 TestRound(kGetProxyAuth, kServerChallenge, OK),
12576 TestRound(kGetAuthWithProxyAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112577 {__LINE__,
12578 kProxy,
12579 AUTH_SYNC,
12580 ERR_INVALID_AUTH_CREDENTIALS,
12581 kServer,
12582 AUTH_ASYNC,
12583 OK,
12584 4,
12585 kNoSSL,
12586 {TestRound(kGetProxy, kProxyChallenge, OK),
12587 TestRound(kGetProxy, kProxyChallenge, OK),
12588 TestRound(kGetProxyAuth, kServerChallenge, OK),
12589 TestRound(kGetAuthWithProxyAuth, kSuccess, OK)}},
12590 {__LINE__,
12591 kProxy,
asankac93076192016-10-03 15:46:0212592 AUTH_SYNC,
12593 OK,
12594 kServer,
12595 AUTH_ASYNC,
12596 ERR_INVALID_AUTH_CREDENTIALS,
12597 3,
12598 kNoSSL,
12599 {TestRound(kGetProxy, kProxyChallenge, OK),
[email protected]044de0642010-06-17 10:42:1512600 TestRound(kGetProxyAuth, kServerChallenge, OK),
asankae2257db2016-10-11 22:03:1612601 TestRound(kGetProxyAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112602 {__LINE__,
12603 kProxy,
asankac93076192016-10-03 15:46:0212604 AUTH_ASYNC,
12605 OK,
12606 kServer,
12607 AUTH_ASYNC,
12608 OK,
12609 3,
12610 kNoSSL,
12611 {TestRound(kGetProxy, kProxyChallenge, OK),
[email protected]044de0642010-06-17 10:42:1512612 TestRound(kGetProxyAuth, kServerChallenge, OK),
12613 TestRound(kGetAuthWithProxyAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112614 {__LINE__,
12615 kProxy,
asankac93076192016-10-03 15:46:0212616 AUTH_ASYNC,
12617 OK,
12618 kServer,
12619 AUTH_ASYNC,
12620 ERR_INVALID_AUTH_CREDENTIALS,
12621 3,
12622 kNoSSL,
12623 {TestRound(kGetProxy, kProxyChallenge, OK),
[email protected]044de0642010-06-17 10:42:1512624 TestRound(kGetProxyAuth, kServerChallenge, OK),
asankae2257db2016-10-11 22:03:1612625 TestRound(kGetProxyAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112626 {__LINE__,
12627 kProxy,
12628 AUTH_ASYNC,
12629 ERR_INVALID_AUTH_CREDENTIALS,
12630 kServer,
12631 AUTH_ASYNC,
12632 ERR_INVALID_AUTH_CREDENTIALS,
12633 4,
12634 kNoSSL,
12635 {TestRound(kGetProxy, kProxyChallenge, OK),
12636 TestRound(kGetProxy, kProxyChallenge, OK),
12637 TestRound(kGetProxyAuth, kServerChallenge, OK),
12638 TestRound(kGetProxyAuth, kSuccess, OK)}},
asankac93076192016-10-03 15:46:0212639 // Non-authenticating HTTPS server with a direct connection.
asanka463ca4262016-11-16 02:34:3112640 {__LINE__,
12641 nullptr,
asankac93076192016-10-03 15:46:0212642 AUTH_NONE,
12643 OK,
12644 kSecureServer,
12645 AUTH_NONE,
12646 OK,
12647 1,
12648 0,
12649 {TestRound(kGet, kSuccess, OK)}},
12650 // Authenticating HTTPS server with a direct connection.
asanka463ca4262016-11-16 02:34:3112651 {__LINE__,
12652 nullptr,
asankac93076192016-10-03 15:46:0212653 AUTH_NONE,
12654 OK,
12655 kSecureServer,
12656 AUTH_SYNC,
12657 OK,
12658 2,
12659 0,
12660 {TestRound(kGet, kServerChallenge, OK),
[email protected]044de0642010-06-17 10:42:1512661 TestRound(kGetAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112662 {__LINE__,
12663 nullptr,
asankac93076192016-10-03 15:46:0212664 AUTH_NONE,
12665 OK,
12666 kSecureServer,
12667 AUTH_SYNC,
12668 ERR_INVALID_AUTH_CREDENTIALS,
12669 2,
12670 0,
asankae2257db2016-10-11 22:03:1612671 {TestRound(kGet, kServerChallenge, OK), TestRound(kGet, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112672 {__LINE__,
12673 nullptr,
asankac93076192016-10-03 15:46:0212674 AUTH_NONE,
12675 OK,
12676 kSecureServer,
12677 AUTH_ASYNC,
12678 OK,
12679 2,
12680 0,
12681 {TestRound(kGet, kServerChallenge, OK),
[email protected]044de0642010-06-17 10:42:1512682 TestRound(kGetAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112683 {__LINE__,
12684 nullptr,
asankac93076192016-10-03 15:46:0212685 AUTH_NONE,
12686 OK,
12687 kSecureServer,
12688 AUTH_ASYNC,
12689 ERR_INVALID_AUTH_CREDENTIALS,
12690 2,
12691 0,
asankae2257db2016-10-11 22:03:1612692 {TestRound(kGet, kServerChallenge, OK), TestRound(kGet, kSuccess, OK)}},
asankac93076192016-10-03 15:46:0212693 // Non-authenticating HTTPS server with a non-authenticating proxy.
asanka463ca4262016-11-16 02:34:3112694 {__LINE__,
12695 kProxy,
asankac93076192016-10-03 15:46:0212696 AUTH_NONE,
12697 OK,
12698 kSecureServer,
12699 AUTH_NONE,
12700 OK,
12701 1,
12702 0,
12703 {TestRound(kConnect, kProxyConnected, OK, &kGet, &kSuccess)}},
12704 // Authenticating HTTPS server through a non-authenticating proxy.
asanka463ca4262016-11-16 02:34:3112705 {__LINE__,
12706 kProxy,
asankac93076192016-10-03 15:46:0212707 AUTH_NONE,
12708 OK,
12709 kSecureServer,
12710 AUTH_SYNC,
12711 OK,
12712 2,
12713 0,
12714 {TestRound(kConnect, kProxyConnected, OK, &kGet, &kServerChallenge),
[email protected]044de0642010-06-17 10:42:1512715 TestRound(kGetAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112716 {__LINE__,
12717 kProxy,
asankac93076192016-10-03 15:46:0212718 AUTH_NONE,
12719 OK,
12720 kSecureServer,
12721 AUTH_SYNC,
12722 ERR_INVALID_AUTH_CREDENTIALS,
12723 2,
12724 0,
12725 {TestRound(kConnect, kProxyConnected, OK, &kGet, &kServerChallenge),
asankae2257db2016-10-11 22:03:1612726 TestRound(kGet, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112727 {__LINE__,
12728 kProxy,
asankac93076192016-10-03 15:46:0212729 AUTH_NONE,
12730 OK,
12731 kSecureServer,
12732 AUTH_ASYNC,
12733 OK,
12734 2,
12735 0,
12736 {TestRound(kConnect, kProxyConnected, OK, &kGet, &kServerChallenge),
[email protected]044de0642010-06-17 10:42:1512737 TestRound(kGetAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112738 {__LINE__,
12739 kProxy,
asankac93076192016-10-03 15:46:0212740 AUTH_NONE,
12741 OK,
12742 kSecureServer,
12743 AUTH_ASYNC,
12744 ERR_INVALID_AUTH_CREDENTIALS,
12745 2,
12746 0,
12747 {TestRound(kConnect, kProxyConnected, OK, &kGet, &kServerChallenge),
asankae2257db2016-10-11 22:03:1612748 TestRound(kGet, kSuccess, OK)}},
asankac93076192016-10-03 15:46:0212749 // Non-Authenticating HTTPS server through an authenticating proxy.
asanka463ca4262016-11-16 02:34:3112750 {__LINE__,
12751 kProxy,
asankac93076192016-10-03 15:46:0212752 AUTH_SYNC,
12753 OK,
12754 kSecureServer,
12755 AUTH_NONE,
12756 OK,
12757 2,
12758 1,
12759 {TestRound(kConnect, kProxyChallenge, OK),
[email protected]044de0642010-06-17 10:42:1512760 TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet, &kSuccess)}},
asanka463ca4262016-11-16 02:34:3112761 {__LINE__,
12762 kProxy,
asankac93076192016-10-03 15:46:0212763 AUTH_SYNC,
12764 ERR_INVALID_AUTH_CREDENTIALS,
12765 kSecureServer,
12766 AUTH_NONE,
12767 OK,
12768 2,
12769 kNoSSL,
12770 {TestRound(kConnect, kProxyChallenge, OK),
asankae2257db2016-10-11 22:03:1612771 TestRound(kConnect, kProxyConnected, OK, &kGet, &kSuccess)}},
asanka463ca4262016-11-16 02:34:3112772 {__LINE__,
12773 kProxy,
asankae2257db2016-10-11 22:03:1612774 AUTH_SYNC,
12775 ERR_UNSUPPORTED_AUTH_SCHEME,
12776 kSecureServer,
12777 AUTH_NONE,
12778 OK,
12779 2,
12780 kNoSSL,
12781 {TestRound(kConnect, kProxyChallenge, OK),
12782 TestRound(kConnect, kProxyConnected, OK, &kGet, &kSuccess)}},
asanka463ca4262016-11-16 02:34:3112783 {__LINE__,
12784 kProxy,
asankae2257db2016-10-11 22:03:1612785 AUTH_SYNC,
12786 ERR_UNEXPECTED,
12787 kSecureServer,
12788 AUTH_NONE,
12789 OK,
12790 2,
12791 kNoSSL,
12792 {TestRound(kConnect, kProxyChallenge, OK),
12793 TestRound(kConnect, kProxyConnected, ERR_UNEXPECTED)}},
asanka463ca4262016-11-16 02:34:3112794 {__LINE__,
12795 kProxy,
asankac93076192016-10-03 15:46:0212796 AUTH_ASYNC,
12797 OK,
12798 kSecureServer,
12799 AUTH_NONE,
12800 OK,
12801 2,
12802 1,
12803 {TestRound(kConnect, kProxyChallenge, OK),
[email protected]044de0642010-06-17 10:42:1512804 TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet, &kSuccess)}},
asanka463ca4262016-11-16 02:34:3112805 {__LINE__,
12806 kProxy,
asankac93076192016-10-03 15:46:0212807 AUTH_ASYNC,
12808 ERR_INVALID_AUTH_CREDENTIALS,
12809 kSecureServer,
12810 AUTH_NONE,
12811 OK,
12812 2,
12813 kNoSSL,
12814 {TestRound(kConnect, kProxyChallenge, OK),
asankae2257db2016-10-11 22:03:1612815 TestRound(kConnect, kProxyConnected, OK, &kGet, &kSuccess)}},
asankac93076192016-10-03 15:46:0212816 // Authenticating HTTPS server through an authenticating proxy.
asanka463ca4262016-11-16 02:34:3112817 {__LINE__,
12818 kProxy,
asankac93076192016-10-03 15:46:0212819 AUTH_SYNC,
12820 OK,
12821 kSecureServer,
12822 AUTH_SYNC,
12823 OK,
12824 3,
12825 1,
12826 {TestRound(kConnect, kProxyChallenge, OK),
12827 TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet,
12828 &kServerChallenge),
[email protected]044de0642010-06-17 10:42:1512829 TestRound(kGetAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112830 {__LINE__,
12831 kProxy,
asankac93076192016-10-03 15:46:0212832 AUTH_SYNC,
12833 OK,
12834 kSecureServer,
12835 AUTH_SYNC,
12836 ERR_INVALID_AUTH_CREDENTIALS,
12837 3,
12838 1,
12839 {TestRound(kConnect, kProxyChallenge, OK),
12840 TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet,
12841 &kServerChallenge),
asankae2257db2016-10-11 22:03:1612842 TestRound(kGet, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112843 {__LINE__,
12844 kProxy,
asankac93076192016-10-03 15:46:0212845 AUTH_ASYNC,
12846 OK,
12847 kSecureServer,
12848 AUTH_SYNC,
12849 OK,
12850 3,
12851 1,
12852 {TestRound(kConnect, kProxyChallenge, OK),
12853 TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet,
12854 &kServerChallenge),
[email protected]044de0642010-06-17 10:42:1512855 TestRound(kGetAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112856 {__LINE__,
12857 kProxy,
asankac93076192016-10-03 15:46:0212858 AUTH_ASYNC,
12859 OK,
12860 kSecureServer,
12861 AUTH_SYNC,
12862 ERR_INVALID_AUTH_CREDENTIALS,
12863 3,
12864 1,
12865 {TestRound(kConnect, kProxyChallenge, OK),
12866 TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet,
12867 &kServerChallenge),
asankae2257db2016-10-11 22:03:1612868 TestRound(kGet, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112869 {__LINE__,
12870 kProxy,
asankac93076192016-10-03 15:46:0212871 AUTH_SYNC,
12872 OK,
12873 kSecureServer,
12874 AUTH_ASYNC,
12875 OK,
12876 3,
12877 1,
12878 {TestRound(kConnect, kProxyChallenge, OK),
12879 TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet,
12880 &kServerChallenge),
[email protected]044de0642010-06-17 10:42:1512881 TestRound(kGetAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112882 {__LINE__,
12883 kProxy,
asankac93076192016-10-03 15:46:0212884 AUTH_SYNC,
12885 OK,
12886 kSecureServer,
12887 AUTH_ASYNC,
12888 ERR_INVALID_AUTH_CREDENTIALS,
12889 3,
12890 1,
12891 {TestRound(kConnect, kProxyChallenge, OK),
12892 TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet,
12893 &kServerChallenge),
asankae2257db2016-10-11 22:03:1612894 TestRound(kGet, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112895 {__LINE__,
12896 kProxy,
asankac93076192016-10-03 15:46:0212897 AUTH_ASYNC,
12898 OK,
12899 kSecureServer,
12900 AUTH_ASYNC,
12901 OK,
12902 3,
12903 1,
12904 {TestRound(kConnect, kProxyChallenge, OK),
12905 TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet,
12906 &kServerChallenge),
[email protected]044de0642010-06-17 10:42:1512907 TestRound(kGetAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112908 {__LINE__,
12909 kProxy,
asankac93076192016-10-03 15:46:0212910 AUTH_ASYNC,
12911 OK,
12912 kSecureServer,
12913 AUTH_ASYNC,
12914 ERR_INVALID_AUTH_CREDENTIALS,
12915 3,
12916 1,
12917 {TestRound(kConnect, kProxyChallenge, OK),
12918 TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet,
12919 &kServerChallenge),
asankae2257db2016-10-11 22:03:1612920 TestRound(kGet, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112921 {__LINE__,
12922 kProxy,
12923 AUTH_ASYNC,
12924 ERR_INVALID_AUTH_CREDENTIALS,
12925 kSecureServer,
12926 AUTH_ASYNC,
12927 ERR_INVALID_AUTH_CREDENTIALS,
12928 4,
12929 2,
12930 {TestRound(kConnect, kProxyChallenge, OK),
12931 TestRound(kConnect, kProxyChallenge, OK),
12932 TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet,
12933 &kServerChallenge),
12934 TestRound(kGet, kSuccess, OK)}},
[email protected]044de0642010-06-17 10:42:1512935 };
12936
asanka463ca4262016-11-16 02:34:3112937 for (const auto& test_config : test_configs) {
12938 SCOPED_TRACE(::testing::Message() << "Test config at "
12939 << test_config.line_number);
[email protected]2d01c262011-08-11 23:07:0812940 HttpAuthHandlerMock::Factory* auth_factory(
12941 new HttpAuthHandlerMock::Factory());
[email protected]bb88e1d32013-05-03 23:11:0712942 session_deps_.http_auth_handler_factory.reset(auth_factory);
asanka5ffd5d72016-03-23 16:20:4912943 SSLInfo empty_ssl_info;
[email protected]65d34382010-07-01 18:12:2612944
12945 // Set up authentication handlers as necessary.
[email protected]044de0642010-06-17 10:42:1512946 if (test_config.proxy_auth_timing != AUTH_NONE) {
asanka463ca4262016-11-16 02:34:3112947 for (int n = 0; n < 3; n++) {
[email protected]2d01c262011-08-11 23:07:0812948 HttpAuthHandlerMock* auth_handler(new HttpAuthHandlerMock());
12949 std::string auth_challenge = "Mock realm=proxy";
12950 GURL origin(test_config.proxy_url);
[email protected]df41d0d82014-03-13 00:43:2412951 HttpAuthChallengeTokenizer tokenizer(auth_challenge.begin(),
12952 auth_challenge.end());
[email protected]2d01c262011-08-11 23:07:0812953 auth_handler->InitFromChallenge(&tokenizer, HttpAuth::AUTH_PROXY,
tfarina42834112016-09-22 13:38:2012954 empty_ssl_info, origin,
12955 NetLogWithSource());
[email protected]2d01c262011-08-11 23:07:0812956 auth_handler->SetGenerateExpectation(
12957 test_config.proxy_auth_timing == AUTH_ASYNC,
asanka463ca4262016-11-16 02:34:3112958 n == 0 ? test_config.first_generate_proxy_token_rv : OK);
[email protected]2d01c262011-08-11 23:07:0812959 auth_factory->AddMockHandler(auth_handler, HttpAuth::AUTH_PROXY);
12960 }
[email protected]044de0642010-06-17 10:42:1512961 }
12962 if (test_config.server_auth_timing != AUTH_NONE) {
[email protected]3fd9dae2010-06-21 11:39:0012963 HttpAuthHandlerMock* auth_handler(new HttpAuthHandlerMock());
[email protected]044de0642010-06-17 10:42:1512964 std::string auth_challenge = "Mock realm=server";
12965 GURL origin(test_config.server_url);
[email protected]df41d0d82014-03-13 00:43:2412966 HttpAuthChallengeTokenizer tokenizer(auth_challenge.begin(),
12967 auth_challenge.end());
[email protected]044de0642010-06-17 10:42:1512968 auth_handler->InitFromChallenge(&tokenizer, HttpAuth::AUTH_SERVER,
tfarina42834112016-09-22 13:38:2012969 empty_ssl_info, origin,
12970 NetLogWithSource());
[email protected]044de0642010-06-17 10:42:1512971 auth_handler->SetGenerateExpectation(
12972 test_config.server_auth_timing == AUTH_ASYNC,
asanka463ca4262016-11-16 02:34:3112973 test_config.first_generate_server_token_rv);
[email protected]2d01c262011-08-11 23:07:0812974 auth_factory->AddMockHandler(auth_handler, HttpAuth::AUTH_SERVER);
asankae2257db2016-10-11 22:03:1612975
12976 // The second handler always succeeds. It should only be used where there
12977 // are multiple auth sessions for server auth in the same network
12978 // transaction using the same auth scheme.
12979 std::unique_ptr<HttpAuthHandlerMock> second_handler =
Jeremy Roman0579ed62017-08-29 15:56:1912980 std::make_unique<HttpAuthHandlerMock>();
asankae2257db2016-10-11 22:03:1612981 second_handler->InitFromChallenge(&tokenizer, HttpAuth::AUTH_SERVER,
12982 empty_ssl_info, origin,
12983 NetLogWithSource());
12984 second_handler->SetGenerateExpectation(true, OK);
12985 auth_factory->AddMockHandler(second_handler.release(),
12986 HttpAuth::AUTH_SERVER);
[email protected]044de0642010-06-17 10:42:1512987 }
12988 if (test_config.proxy_url) {
rdsmith82957ad2015-09-16 19:42:0312989 session_deps_.proxy_service =
12990 ProxyService::CreateFixed(test_config.proxy_url);
[email protected]044de0642010-06-17 10:42:1512991 } else {
rdsmith82957ad2015-09-16 19:42:0312992 session_deps_.proxy_service = ProxyService::CreateDirect();
[email protected]044de0642010-06-17 10:42:1512993 }
12994
12995 HttpRequestInfo request;
12996 request.method = "GET";
12997 request.url = GURL(test_config.server_url);
[email protected]044de0642010-06-17 10:42:1512998
danakj1fd259a02016-04-16 03:17:0912999 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]044de0642010-06-17 10:42:1513000
rchcb68dc62015-05-21 04:45:3613001 SSLSocketDataProvider ssl_socket_data_provider(SYNCHRONOUS, OK);
13002
13003 std::vector<std::vector<MockRead>> mock_reads(1);
13004 std::vector<std::vector<MockWrite>> mock_writes(1);
[email protected]044de0642010-06-17 10:42:1513005 for (int round = 0; round < test_config.num_auth_rounds; ++round) {
davidben8c7089a2017-04-17 20:38:2213006 SCOPED_TRACE(round);
[email protected]044de0642010-06-17 10:42:1513007 const TestRound& read_write_round = test_config.rounds[round];
13008
13009 // Set up expected reads and writes.
rchcb68dc62015-05-21 04:45:3613010 mock_reads.back().push_back(read_write_round.read);
13011 mock_writes.back().push_back(read_write_round.write);
13012
13013 // kProxyChallenge uses Proxy-Connection: close which means that the
13014 // socket is closed and a new one will be created for the next request.
mmenkee71e15332015-10-07 16:39:5413015 if (read_write_round.read.data == kProxyChallenge.data) {
rchcb68dc62015-05-21 04:45:3613016 mock_reads.push_back(std::vector<MockRead>());
13017 mock_writes.push_back(std::vector<MockWrite>());
[email protected]044de0642010-06-17 10:42:1513018 }
13019
rchcb68dc62015-05-21 04:45:3613020 if (read_write_round.extra_read) {
13021 mock_reads.back().push_back(*read_write_round.extra_read);
[email protected]044de0642010-06-17 10:42:1513022 }
rchcb68dc62015-05-21 04:45:3613023 if (read_write_round.extra_write) {
13024 mock_writes.back().push_back(*read_write_round.extra_write);
13025 }
[email protected]044de0642010-06-17 10:42:1513026
13027 // Add an SSL sequence if necessary.
[email protected]044de0642010-06-17 10:42:1513028 if (round >= test_config.first_ssl_round)
[email protected]bb88e1d32013-05-03 23:11:0713029 session_deps_.socket_factory->AddSSLSocketDataProvider(
[email protected]044de0642010-06-17 10:42:1513030 &ssl_socket_data_provider);
rchcb68dc62015-05-21 04:45:3613031 }
[email protected]044de0642010-06-17 10:42:1513032
danakj1fd259a02016-04-16 03:17:0913033 std::vector<std::unique_ptr<StaticSocketDataProvider>> data_providers;
rchcb68dc62015-05-21 04:45:3613034 for (size_t i = 0; i < mock_reads.size(); ++i) {
Jeremy Roman0579ed62017-08-29 15:56:1913035 data_providers.push_back(std::make_unique<StaticSocketDataProvider>(
davidben5f8b6bc2015-11-25 03:19:5413036 mock_reads[i].data(), mock_reads[i].size(), mock_writes[i].data(),
bnc87dcefc2017-05-25 12:47:5813037 mock_writes[i].size()));
rchcb68dc62015-05-21 04:45:3613038 session_deps_.socket_factory->AddSocketDataProvider(
olli.raula525048c2015-12-10 07:38:3213039 data_providers.back().get());
rchcb68dc62015-05-21 04:45:3613040 }
13041
mmenkecc2298e2015-12-07 18:20:1813042 // Transaction must be created after DataProviders, so it's destroyed before
13043 // they are as well.
13044 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
13045
rchcb68dc62015-05-21 04:45:3613046 for (int round = 0; round < test_config.num_auth_rounds; ++round) {
davidben8c7089a2017-04-17 20:38:2213047 SCOPED_TRACE(round);
rchcb68dc62015-05-21 04:45:3613048 const TestRound& read_write_round = test_config.rounds[round];
[email protected]044de0642010-06-17 10:42:1513049 // Start or restart the transaction.
[email protected]49639fa2011-12-20 23:22:4113050 TestCompletionCallback callback;
[email protected]044de0642010-06-17 10:42:1513051 int rv;
13052 if (round == 0) {
tfarina42834112016-09-22 13:38:2013053 rv = trans.Start(&request, callback.callback(), NetLogWithSource());
[email protected]044de0642010-06-17 10:42:1513054 } else {
[email protected]49639fa2011-12-20 23:22:4113055 rv = trans.RestartWithAuth(
13056 AuthCredentials(kFoo, kBar), callback.callback());
[email protected]044de0642010-06-17 10:42:1513057 }
13058 if (rv == ERR_IO_PENDING)
13059 rv = callback.WaitForResult();
13060
13061 // Compare results with expected data.
asankae2257db2016-10-11 22:03:1613062 EXPECT_THAT(rv, IsError(read_write_round.expected_rv));
[email protected]0b0bf032010-09-21 18:08:5013063 const HttpResponseInfo* response = trans.GetResponseInfo();
ttuttlec0c828492015-05-15 01:25:5513064 if (read_write_round.expected_rv != OK) {
[email protected]044de0642010-06-17 10:42:1513065 EXPECT_EQ(round + 1, test_config.num_auth_rounds);
13066 continue;
13067 }
13068 if (round + 1 < test_config.num_auth_rounds) {
wezca1070932016-05-26 20:30:5213069 EXPECT_TRUE(response->auth_challenge);
[email protected]044de0642010-06-17 10:42:1513070 } else {
wezca1070932016-05-26 20:30:5213071 EXPECT_FALSE(response->auth_challenge);
asankae2257db2016-10-11 22:03:1613072 EXPECT_FALSE(trans.IsReadyToRestartForAuth());
[email protected]044de0642010-06-17 10:42:1513073 }
13074 }
[email protected]e5ae96a2010-04-14 20:12:4513075 }
13076}
13077
bncd16676a2016-07-20 16:23:0113078TEST_F(HttpNetworkTransactionTest, MultiRoundAuth) {
[email protected]c871bce92010-07-15 21:51:1413079 // Do multi-round authentication and make sure it works correctly.
[email protected]c871bce92010-07-15 21:51:1413080 HttpAuthHandlerMock::Factory* auth_factory(
13081 new HttpAuthHandlerMock::Factory());
[email protected]bb88e1d32013-05-03 23:11:0713082 session_deps_.http_auth_handler_factory.reset(auth_factory);
rdsmith82957ad2015-09-16 19:42:0313083 session_deps_.proxy_service = ProxyService::CreateDirect();
[email protected]bb88e1d32013-05-03 23:11:0713084 session_deps_.host_resolver->rules()->AddRule("www.example.com", "10.0.0.1");
13085 session_deps_.host_resolver->set_synchronous_mode(true);
[email protected]c871bce92010-07-15 21:51:1413086
13087 HttpAuthHandlerMock* auth_handler(new HttpAuthHandlerMock());
13088 auth_handler->set_connection_based(true);
13089 std::string auth_challenge = "Mock realm=server";
13090 GURL origin("http://www.example.com");
[email protected]df41d0d82014-03-13 00:43:2413091 HttpAuthChallengeTokenizer tokenizer(auth_challenge.begin(),
13092 auth_challenge.end());
asanka5ffd5d72016-03-23 16:20:4913093 SSLInfo empty_ssl_info;
[email protected]c871bce92010-07-15 21:51:1413094 auth_handler->InitFromChallenge(&tokenizer, HttpAuth::AUTH_SERVER,
tfarina42834112016-09-22 13:38:2013095 empty_ssl_info, origin, NetLogWithSource());
[email protected]2d01c262011-08-11 23:07:0813096 auth_factory->AddMockHandler(auth_handler, HttpAuth::AUTH_SERVER);
[email protected]c871bce92010-07-15 21:51:1413097
[email protected]c871bce92010-07-15 21:51:1413098 int rv = OK;
13099 const HttpResponseInfo* response = NULL;
13100 HttpRequestInfo request;
13101 request.method = "GET";
13102 request.url = origin;
[email protected]cb9bf6ca2011-01-28 13:15:2713103
danakj1fd259a02016-04-16 03:17:0913104 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]7ef4cbbb2011-02-06 11:19:1013105
13106 // Use a TCP Socket Pool with only one connection per group. This is used
13107 // to validate that the TCP socket is not released to the pool between
13108 // each round of multi-round authentication.
mmenkee65e7af2015-10-13 17:16:4213109 HttpNetworkSessionPeer session_peer(session.get());
[email protected]ab739042011-04-07 15:22:2813110 TransportClientSocketPool* transport_pool = new TransportClientSocketPool(
[email protected]7ef4cbbb2011-02-06 11:19:1013111 50, // Max sockets for pool
13112 1, // Max sockets per group
tbansal7b403bcc2016-04-13 22:33:2113113 session_deps_.host_resolver.get(), session_deps_.socket_factory.get(),
13114 NULL, session_deps_.net_log);
Jeremy Roman0579ed62017-08-29 15:56:1913115 auto mock_pool_manager = std::make_unique<MockClientSocketPoolManager>();
[email protected]a42dbd142011-11-17 16:42:0213116 mock_pool_manager->SetTransportSocketPool(transport_pool);
dchengc7eeda422015-12-26 03:56:4813117 session_peer.SetClientSocketPoolManager(std::move(mock_pool_manager));
[email protected]7ef4cbbb2011-02-06 11:19:1013118
bnc691fda62016-08-12 00:43:1613119 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]49639fa2011-12-20 23:22:4113120 TestCompletionCallback callback;
[email protected]c871bce92010-07-15 21:51:1413121
13122 const MockWrite kGet(
13123 "GET / HTTP/1.1\r\n"
13124 "Host: www.example.com\r\n"
13125 "Connection: keep-alive\r\n\r\n");
13126 const MockWrite kGetAuth(
13127 "GET / HTTP/1.1\r\n"
13128 "Host: www.example.com\r\n"
13129 "Connection: keep-alive\r\n"
13130 "Authorization: auth_token\r\n\r\n");
13131
13132 const MockRead kServerChallenge(
13133 "HTTP/1.1 401 Unauthorized\r\n"
13134 "WWW-Authenticate: Mock realm=server\r\n"
13135 "Content-Type: text/html; charset=iso-8859-1\r\n"
13136 "Content-Length: 14\r\n\r\n"
13137 "Unauthorized\r\n");
13138 const MockRead kSuccess(
13139 "HTTP/1.1 200 OK\r\n"
13140 "Content-Type: text/html; charset=iso-8859-1\r\n"
13141 "Content-Length: 3\r\n\r\n"
13142 "Yes");
13143
13144 MockWrite writes[] = {
13145 // First round
13146 kGet,
13147 // Second round
13148 kGetAuth,
13149 // Third round
13150 kGetAuth,
[email protected]eca50e122010-09-11 14:03:3013151 // Fourth round
[email protected]7ef4cbbb2011-02-06 11:19:1013152 kGetAuth,
13153 // Competing request
13154 kGet,
[email protected]c871bce92010-07-15 21:51:1413155 };
13156 MockRead reads[] = {
13157 // First round
13158 kServerChallenge,
13159 // Second round
13160 kServerChallenge,
13161 // Third round
[email protected]eca50e122010-09-11 14:03:3013162 kServerChallenge,
13163 // Fourth round
[email protected]c871bce92010-07-15 21:51:1413164 kSuccess,
[email protected]7ef4cbbb2011-02-06 11:19:1013165 // Competing response
13166 kSuccess,
[email protected]c871bce92010-07-15 21:51:1413167 };
13168 StaticSocketDataProvider data_provider(reads, arraysize(reads),
13169 writes, arraysize(writes));
[email protected]bb88e1d32013-05-03 23:11:0713170 session_deps_.socket_factory->AddSocketDataProvider(&data_provider);
[email protected]c871bce92010-07-15 21:51:1413171
thestig9d3bb0c2015-01-24 00:49:5113172 const char kSocketGroup[] = "www.example.com:80";
[email protected]7ef4cbbb2011-02-06 11:19:1013173
13174 // First round of authentication.
[email protected]c871bce92010-07-15 21:51:1413175 auth_handler->SetGenerateExpectation(false, OK);
tfarina42834112016-09-22 13:38:2013176 rv = trans.Start(&request, callback.callback(), NetLogWithSource());
[email protected]c871bce92010-07-15 21:51:1413177 if (rv == ERR_IO_PENDING)
13178 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0113179 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:1613180 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5213181 ASSERT_TRUE(response);
13182 EXPECT_TRUE(response->auth_challenge);
[email protected]ab739042011-04-07 15:22:2813183 EXPECT_EQ(0, transport_pool->IdleSocketCountInGroup(kSocketGroup));
asanka463ca4262016-11-16 02:34:3113184 EXPECT_EQ(HttpAuthHandlerMock::State::WAIT_FOR_GENERATE_AUTH_TOKEN,
13185 auth_handler->state());
[email protected]c871bce92010-07-15 21:51:1413186
[email protected]7ef4cbbb2011-02-06 11:19:1013187 // In between rounds, another request comes in for the same domain.
13188 // It should not be able to grab the TCP socket that trans has already
13189 // claimed.
bnc691fda62016-08-12 00:43:1613190 HttpNetworkTransaction trans_compete(DEFAULT_PRIORITY, session.get());
[email protected]49639fa2011-12-20 23:22:4113191 TestCompletionCallback callback_compete;
tfarina42834112016-09-22 13:38:2013192 rv = trans_compete.Start(&request, callback_compete.callback(),
13193 NetLogWithSource());
robpercival214763f2016-07-01 23:27:0113194 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]7ef4cbbb2011-02-06 11:19:1013195 // callback_compete.WaitForResult at this point would stall forever,
13196 // since the HttpNetworkTransaction does not release the request back to
13197 // the pool until after authentication completes.
13198
13199 // Second round of authentication.
[email protected]c871bce92010-07-15 21:51:1413200 auth_handler->SetGenerateExpectation(false, OK);
bnc691fda62016-08-12 00:43:1613201 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar), callback.callback());
[email protected]c871bce92010-07-15 21:51:1413202 if (rv == ERR_IO_PENDING)
13203 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0113204 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:1613205 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5213206 ASSERT_TRUE(response);
13207 EXPECT_FALSE(response->auth_challenge);
[email protected]ab739042011-04-07 15:22:2813208 EXPECT_EQ(0, transport_pool->IdleSocketCountInGroup(kSocketGroup));
asanka463ca4262016-11-16 02:34:3113209 EXPECT_EQ(HttpAuthHandlerMock::State::WAIT_FOR_GENERATE_AUTH_TOKEN,
13210 auth_handler->state());
[email protected]c871bce92010-07-15 21:51:1413211
[email protected]7ef4cbbb2011-02-06 11:19:1013212 // Third round of authentication.
[email protected]c871bce92010-07-15 21:51:1413213 auth_handler->SetGenerateExpectation(false, OK);
bnc691fda62016-08-12 00:43:1613214 rv = trans.RestartWithAuth(AuthCredentials(), callback.callback());
[email protected]c871bce92010-07-15 21:51:1413215 if (rv == ERR_IO_PENDING)
13216 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0113217 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:1613218 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5213219 ASSERT_TRUE(response);
13220 EXPECT_FALSE(response->auth_challenge);
[email protected]ab739042011-04-07 15:22:2813221 EXPECT_EQ(0, transport_pool->IdleSocketCountInGroup(kSocketGroup));
asanka463ca4262016-11-16 02:34:3113222 EXPECT_EQ(HttpAuthHandlerMock::State::WAIT_FOR_GENERATE_AUTH_TOKEN,
13223 auth_handler->state());
[email protected]eca50e122010-09-11 14:03:3013224
[email protected]7ef4cbbb2011-02-06 11:19:1013225 // Fourth round of authentication, which completes successfully.
[email protected]eca50e122010-09-11 14:03:3013226 auth_handler->SetGenerateExpectation(false, OK);
bnc691fda62016-08-12 00:43:1613227 rv = trans.RestartWithAuth(AuthCredentials(), callback.callback());
[email protected]eca50e122010-09-11 14:03:3013228 if (rv == ERR_IO_PENDING)
13229 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0113230 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:1613231 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5213232 ASSERT_TRUE(response);
13233 EXPECT_FALSE(response->auth_challenge);
[email protected]ab739042011-04-07 15:22:2813234 EXPECT_EQ(0, transport_pool->IdleSocketCountInGroup(kSocketGroup));
[email protected]7ef4cbbb2011-02-06 11:19:1013235
asanka463ca4262016-11-16 02:34:3113236 // In WAIT_FOR_CHALLENGE, although in reality the auth handler is done. A real
13237 // auth handler should transition to a DONE state in concert with the remote
13238 // server. But that's not something we can test here with a mock handler.
13239 EXPECT_EQ(HttpAuthHandlerMock::State::WAIT_FOR_CHALLENGE,
13240 auth_handler->state());
13241
[email protected]7ef4cbbb2011-02-06 11:19:1013242 // Read the body since the fourth round was successful. This will also
13243 // release the socket back to the pool.
13244 scoped_refptr<IOBufferWithSize> io_buf(new IOBufferWithSize(50));
bnc691fda62016-08-12 00:43:1613245 rv = trans.Read(io_buf.get(), io_buf->size(), callback.callback());
[email protected]7ef4cbbb2011-02-06 11:19:1013246 if (rv == ERR_IO_PENDING)
13247 rv = callback.WaitForResult();
13248 EXPECT_EQ(3, rv);
bnc691fda62016-08-12 00:43:1613249 rv = trans.Read(io_buf.get(), io_buf->size(), callback.callback());
[email protected]7ef4cbbb2011-02-06 11:19:1013250 EXPECT_EQ(0, rv);
13251 // There are still 0 idle sockets, since the trans_compete transaction
13252 // will be handed it immediately after trans releases it to the group.
[email protected]ab739042011-04-07 15:22:2813253 EXPECT_EQ(0, transport_pool->IdleSocketCountInGroup(kSocketGroup));
[email protected]7ef4cbbb2011-02-06 11:19:1013254
13255 // The competing request can now finish. Wait for the headers and then
13256 // read the body.
13257 rv = callback_compete.WaitForResult();
robpercival214763f2016-07-01 23:27:0113258 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:1613259 rv = trans_compete.Read(io_buf.get(), io_buf->size(), callback.callback());
[email protected]7ef4cbbb2011-02-06 11:19:1013260 if (rv == ERR_IO_PENDING)
13261 rv = callback.WaitForResult();
13262 EXPECT_EQ(3, rv);
bnc691fda62016-08-12 00:43:1613263 rv = trans_compete.Read(io_buf.get(), io_buf->size(), callback.callback());
[email protected]7ef4cbbb2011-02-06 11:19:1013264 EXPECT_EQ(0, rv);
13265
13266 // Finally, the socket is released to the group.
[email protected]ab739042011-04-07 15:22:2813267 EXPECT_EQ(1, transport_pool->IdleSocketCountInGroup(kSocketGroup));
[email protected]c871bce92010-07-15 21:51:1413268}
13269
[email protected]65041fa2010-05-21 06:56:5313270// This tests the case that a request is issued via http instead of spdy after
13271// npn is negotiated.
bncd16676a2016-07-20 16:23:0113272TEST_F(HttpNetworkTransactionTest, NpnWithHttpOverSSL) {
[email protected]65041fa2010-05-21 06:56:5313273 HttpRequestInfo request;
13274 request.method = "GET";
bncce36dca22015-04-21 22:11:2313275 request.url = GURL("https://www.example.org/");
[email protected]65041fa2010-05-21 06:56:5313276
13277 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:2313278 MockWrite(
13279 "GET / HTTP/1.1\r\n"
13280 "Host: www.example.org\r\n"
13281 "Connection: keep-alive\r\n\r\n"),
[email protected]65041fa2010-05-21 06:56:5313282 };
13283
13284 MockRead data_reads[] = {
bncc958faa2015-07-31 18:14:5213285 MockRead("HTTP/1.1 200 OK\r\n"),
bnc2df4b522016-07-08 18:17:4313286 MockRead(kAlternativeServiceHttpHeader),
bncc958faa2015-07-31 18:14:5213287 MockRead("\r\n"),
13288 MockRead("hello world"),
13289 MockRead(SYNCHRONOUS, OK),
[email protected]65041fa2010-05-21 06:56:5313290 };
13291
[email protected]8ddf8322012-02-23 18:08:0613292 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3613293 ssl.next_proto = kProtoHTTP11;
[email protected]65041fa2010-05-21 06:56:5313294
[email protected]bb88e1d32013-05-03 23:11:0713295 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]65041fa2010-05-21 06:56:5313296
13297 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
13298 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:0713299 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]65041fa2010-05-21 06:56:5313300
[email protected]49639fa2011-12-20 23:22:4113301 TestCompletionCallback callback;
[email protected]65041fa2010-05-21 06:56:5313302
danakj1fd259a02016-04-16 03:17:0913303 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1613304 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]65041fa2010-05-21 06:56:5313305
tfarina42834112016-09-22 13:38:2013306 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
[email protected]65041fa2010-05-21 06:56:5313307
robpercival214763f2016-07-01 23:27:0113308 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
13309 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]65041fa2010-05-21 06:56:5313310
bnc691fda62016-08-12 00:43:1613311 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5213312 ASSERT_TRUE(response);
13313 ASSERT_TRUE(response->headers);
[email protected]65041fa2010-05-21 06:56:5313314 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
13315
13316 std::string response_data;
bnc691fda62016-08-12 00:43:1613317 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
[email protected]65041fa2010-05-21 06:56:5313318 EXPECT_EQ("hello world", response_data);
13319
13320 EXPECT_FALSE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5213321 EXPECT_TRUE(response->was_alpn_negotiated);
[email protected]65041fa2010-05-21 06:56:5313322}
[email protected]26ef6582010-06-24 02:30:4713323
bnc55ff9da2015-08-19 18:42:3513324// Simulate the SSL handshake completing with an NPN negotiation followed by an
13325// immediate server closing of the socket.
13326// Regression test for https://crbug.com/46369.
bncd16676a2016-07-20 16:23:0113327TEST_F(HttpNetworkTransactionTest, SpdyPostNPNServerHangup) {
[email protected]26ef6582010-06-24 02:30:4713328 HttpRequestInfo request;
13329 request.method = "GET";
bncce36dca22015-04-21 22:11:2313330 request.url = GURL("https://www.example.org/");
[email protected]26ef6582010-06-24 02:30:4713331
[email protected]8ddf8322012-02-23 18:08:0613332 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3613333 ssl.next_proto = kProtoHTTP2;
[email protected]bb88e1d32013-05-03 23:11:0713334 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]26ef6582010-06-24 02:30:4713335
bncdf80d44fd2016-07-15 20:27:4113336 SpdySerializedFrame req(
bnc38dcd392016-02-09 23:19:4913337 spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST, true));
bncdf80d44fd2016-07-15 20:27:4113338 MockWrite spdy_writes[] = {CreateMockWrite(req, 1)};
[email protected]26ef6582010-06-24 02:30:4713339
13340 MockRead spdy_reads[] = {
[email protected]8ddf8322012-02-23 18:08:0613341 MockRead(SYNCHRONOUS, 0, 0) // Not async - return 0 immediately.
[email protected]26ef6582010-06-24 02:30:4713342 };
13343
rch8e6c6c42015-05-01 14:05:1313344 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
13345 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:0713346 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]26ef6582010-06-24 02:30:4713347
[email protected]49639fa2011-12-20 23:22:4113348 TestCompletionCallback callback;
[email protected]26ef6582010-06-24 02:30:4713349
danakj1fd259a02016-04-16 03:17:0913350 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1613351 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]26ef6582010-06-24 02:30:4713352
tfarina42834112016-09-22 13:38:2013353 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0113354 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
13355 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_CONNECTION_CLOSED));
[email protected]26ef6582010-06-24 02:30:4713356}
[email protected]65d34382010-07-01 18:12:2613357
[email protected]795cbf82013-07-22 09:37:2713358// A subclass of HttpAuthHandlerMock that records the request URL when
13359// it gets it. This is needed since the auth handler may get destroyed
13360// before we get a chance to query it.
13361class UrlRecordingHttpAuthHandlerMock : public HttpAuthHandlerMock {
13362 public:
13363 explicit UrlRecordingHttpAuthHandlerMock(GURL* url) : url_(url) {}
13364
Chris Watkins7a41d3552017-12-01 02:13:2713365 ~UrlRecordingHttpAuthHandlerMock() override = default;
[email protected]795cbf82013-07-22 09:37:2713366
13367 protected:
dchengb03027d2014-10-21 12:00:2013368 int GenerateAuthTokenImpl(const AuthCredentials* credentials,
13369 const HttpRequestInfo* request,
13370 const CompletionCallback& callback,
13371 std::string* auth_token) override {
[email protected]795cbf82013-07-22 09:37:2713372 *url_ = request->url;
13373 return HttpAuthHandlerMock::GenerateAuthTokenImpl(
13374 credentials, request, callback, auth_token);
13375 }
13376
13377 private:
13378 GURL* url_;
13379};
13380
[email protected]8e6441ca2010-08-19 05:56:3813381// Test that if we cancel the transaction as the connection is completing, that
13382// everything tears down correctly.
bncd16676a2016-07-20 16:23:0113383TEST_F(HttpNetworkTransactionTest, SimpleCancel) {
[email protected]8e6441ca2010-08-19 05:56:3813384 // Setup everything about the connection to complete synchronously, so that
13385 // after calling HttpNetworkTransaction::Start, the only thing we're waiting
13386 // for is the callback from the HttpStreamRequest.
13387 // Then cancel the transaction.
13388 // Verify that we don't crash.
[email protected]d973e99a2012-02-17 21:02:3613389 MockConnect mock_connect(SYNCHRONOUS, OK);
[email protected]8e6441ca2010-08-19 05:56:3813390 MockRead data_reads[] = {
[email protected]8ddf8322012-02-23 18:08:0613391 MockRead(SYNCHRONOUS, "HTTP/1.0 200 OK\r\n\r\n"),
13392 MockRead(SYNCHRONOUS, "hello world"),
13393 MockRead(SYNCHRONOUS, OK),
[email protected]8e6441ca2010-08-19 05:56:3813394 };
13395
[email protected]8e6441ca2010-08-19 05:56:3813396 HttpRequestInfo request;
13397 request.method = "GET";
bncce36dca22015-04-21 22:11:2313398 request.url = GURL("http://www.example.org/");
[email protected]8e6441ca2010-08-19 05:56:3813399
[email protected]bb88e1d32013-05-03 23:11:0713400 session_deps_.host_resolver->set_synchronous_mode(true);
danakj1fd259a02016-04-16 03:17:0913401 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc87dcefc2017-05-25 12:47:5813402 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:1913403 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:2713404
[email protected]8e6441ca2010-08-19 05:56:3813405 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
13406 data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:0713407 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]8e6441ca2010-08-19 05:56:3813408
[email protected]49639fa2011-12-20 23:22:4113409 TestCompletionCallback callback;
[email protected]8e6441ca2010-08-19 05:56:3813410
vishal.b62985ca92015-04-17 08:45:5113411 BoundTestNetLog log;
[email protected]49639fa2011-12-20 23:22:4113412 int rv = trans->Start(&request, callback.callback(), log.bound());
robpercival214763f2016-07-01 23:27:0113413 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]8e6441ca2010-08-19 05:56:3813414 trans.reset(); // Cancel the transaction here.
13415
fdoray92e35a72016-06-10 15:54:5513416 base::RunLoop().RunUntilIdle();
[email protected]f45c1ee2010-08-03 00:54:3013417}
13418
[email protected]ecab6e052014-05-16 14:58:1213419// Test that if a transaction is cancelled after receiving the headers, the
13420// stream is drained properly and added back to the socket pool. The main
13421// purpose of this test is to make sure that an HttpStreamParser can be read
13422// from after the HttpNetworkTransaction and the objects it owns have been
13423// deleted.
13424// See http://crbug.com/368418
bncd16676a2016-07-20 16:23:0113425TEST_F(HttpNetworkTransactionTest, CancelAfterHeaders) {
[email protected]ecab6e052014-05-16 14:58:1213426 MockRead data_reads[] = {
13427 MockRead(ASYNC, "HTTP/1.1 200 OK\r\n"),
13428 MockRead(ASYNC, "Content-Length: 2\r\n"),
13429 MockRead(ASYNC, "Connection: Keep-Alive\r\n\r\n"),
13430 MockRead(ASYNC, "1"),
13431 // 2 async reads are necessary to trigger a ReadResponseBody call after the
13432 // HttpNetworkTransaction has been deleted.
13433 MockRead(ASYNC, "2"),
13434 MockRead(SYNCHRONOUS, ERR_IO_PENDING), // Should never read this.
13435 };
13436 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
13437 session_deps_.socket_factory->AddSocketDataProvider(&data);
13438
danakj1fd259a02016-04-16 03:17:0913439 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]ecab6e052014-05-16 14:58:1213440
13441 {
13442 HttpRequestInfo request;
13443 request.method = "GET";
bncce36dca22015-04-21 22:11:2313444 request.url = GURL("http://www.example.org/");
[email protected]ecab6e052014-05-16 14:58:1213445
dcheng48459ac22014-08-26 00:46:4113446 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]ecab6e052014-05-16 14:58:1213447 TestCompletionCallback callback;
13448
tfarina42834112016-09-22 13:38:2013449 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0113450 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]ecab6e052014-05-16 14:58:1213451 callback.WaitForResult();
13452
13453 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5213454 ASSERT_TRUE(response);
13455 EXPECT_TRUE(response->headers);
[email protected]ecab6e052014-05-16 14:58:1213456 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
13457
13458 // The transaction and HttpRequestInfo are deleted.
13459 }
13460
13461 // Let the HttpResponseBodyDrainer drain the socket.
fdoray92e35a72016-06-10 15:54:5513462 base::RunLoop().RunUntilIdle();
[email protected]ecab6e052014-05-16 14:58:1213463
13464 // Socket should now be idle, waiting to be reused.
dcheng48459ac22014-08-26 00:46:4113465 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]ecab6e052014-05-16 14:58:1213466}
13467
[email protected]76a505b2010-08-25 06:23:0013468// Test a basic GET request through a proxy.
bncd16676a2016-07-20 16:23:0113469TEST_F(HttpNetworkTransactionTest, ProxyGet) {
rdsmith82957ad2015-09-16 19:42:0313470 session_deps_.proxy_service =
13471 ProxyService::CreateFixedFromPacResult("PROXY myproxy:70");
vishal.b62985ca92015-04-17 08:45:5113472 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:0713473 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:0913474 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]76a505b2010-08-25 06:23:0013475
[email protected]76a505b2010-08-25 06:23:0013476 HttpRequestInfo request;
13477 request.method = "GET";
bncce36dca22015-04-21 22:11:2313478 request.url = GURL("http://www.example.org/");
[email protected]76a505b2010-08-25 06:23:0013479
13480 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:2313481 MockWrite(
13482 "GET http://www.example.org/ HTTP/1.1\r\n"
13483 "Host: www.example.org\r\n"
13484 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]76a505b2010-08-25 06:23:0013485 };
13486
13487 MockRead data_reads1[] = {
13488 MockRead("HTTP/1.1 200 OK\r\n"),
13489 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
13490 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:0613491 MockRead(SYNCHRONOUS, OK),
[email protected]76a505b2010-08-25 06:23:0013492 };
13493
13494 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
13495 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:0713496 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]76a505b2010-08-25 06:23:0013497
[email protected]49639fa2011-12-20 23:22:4113498 TestCompletionCallback callback1;
[email protected]76a505b2010-08-25 06:23:0013499
bnc691fda62016-08-12 00:43:1613500 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
ryansturm49a8cb12016-06-15 16:51:0913501 BeforeHeadersSentHandler headers_handler;
bnc691fda62016-08-12 00:43:1613502 trans.SetBeforeHeadersSentCallback(
ryansturm49a8cb12016-06-15 16:51:0913503 base::Bind(&BeforeHeadersSentHandler::OnBeforeHeadersSent,
13504 base::Unretained(&headers_handler)));
[email protected]0b0bf032010-09-21 18:08:5013505
bnc691fda62016-08-12 00:43:1613506 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:0113507 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]76a505b2010-08-25 06:23:0013508
13509 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:0113510 EXPECT_THAT(rv, IsOk());
[email protected]76a505b2010-08-25 06:23:0013511
bnc691fda62016-08-12 00:43:1613512 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5213513 ASSERT_TRUE(response);
[email protected]76a505b2010-08-25 06:23:0013514
13515 EXPECT_TRUE(response->headers->IsKeepAlive());
13516 EXPECT_EQ(200, response->headers->response_code());
13517 EXPECT_EQ(100, response->headers->GetContentLength());
13518 EXPECT_TRUE(response->was_fetched_via_proxy);
tbansal2ecbbc72016-10-06 17:15:4713519 EXPECT_EQ(ProxyServer(ProxyServer::SCHEME_HTTP,
13520 HostPortPair::FromString("myproxy:70")),
13521 response->proxy_server);
ryansturm49a8cb12016-06-15 16:51:0913522 EXPECT_TRUE(headers_handler.observed_before_headers_sent());
13523 EXPECT_TRUE(headers_handler.observed_before_headers_sent_with_proxy());
13524 EXPECT_EQ("myproxy:70", headers_handler.observed_proxy_server_uri());
[email protected]76a505b2010-08-25 06:23:0013525 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
[email protected]029c83b62013-01-24 05:28:2013526
13527 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:1613528 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]029c83b62013-01-24 05:28:2013529 TestLoadTimingNotReusedWithPac(load_timing_info,
13530 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
[email protected]76a505b2010-08-25 06:23:0013531}
13532
13533// Test a basic HTTPS GET request through a proxy.
bncd16676a2016-07-20 16:23:0113534TEST_F(HttpNetworkTransactionTest, ProxyTunnelGet) {
rdsmith82957ad2015-09-16 19:42:0313535 session_deps_.proxy_service =
13536 ProxyService::CreateFixedFromPacResult("PROXY myproxy:70");
vishal.b62985ca92015-04-17 08:45:5113537 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:0713538 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:0913539 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]76a505b2010-08-25 06:23:0013540
[email protected]76a505b2010-08-25 06:23:0013541 HttpRequestInfo request;
13542 request.method = "GET";
bncce36dca22015-04-21 22:11:2313543 request.url = GURL("https://www.example.org/");
[email protected]76a505b2010-08-25 06:23:0013544
13545 // Since we have proxy, should try to establish tunnel.
13546 MockWrite data_writes1[] = {
rsleevidb16bb02015-11-12 23:47:1713547 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
13548 "Host: www.example.org:443\r\n"
13549 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]76a505b2010-08-25 06:23:0013550
rsleevidb16bb02015-11-12 23:47:1713551 MockWrite("GET / HTTP/1.1\r\n"
13552 "Host: www.example.org\r\n"
13553 "Connection: keep-alive\r\n\r\n"),
[email protected]76a505b2010-08-25 06:23:0013554 };
13555
13556 MockRead data_reads1[] = {
13557 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
13558
13559 MockRead("HTTP/1.1 200 OK\r\n"),
13560 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
13561 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:0613562 MockRead(SYNCHRONOUS, OK),
[email protected]76a505b2010-08-25 06:23:0013563 };
13564
13565 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
13566 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:0713567 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8ddf8322012-02-23 18:08:0613568 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:0713569 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]76a505b2010-08-25 06:23:0013570
[email protected]49639fa2011-12-20 23:22:4113571 TestCompletionCallback callback1;
[email protected]76a505b2010-08-25 06:23:0013572
bnc691fda62016-08-12 00:43:1613573 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
ryansturm49a8cb12016-06-15 16:51:0913574 BeforeHeadersSentHandler headers_handler;
bnc691fda62016-08-12 00:43:1613575 trans.SetBeforeHeadersSentCallback(
ryansturm49a8cb12016-06-15 16:51:0913576 base::Bind(&BeforeHeadersSentHandler::OnBeforeHeadersSent,
13577 base::Unretained(&headers_handler)));
[email protected]0b0bf032010-09-21 18:08:5013578
bnc691fda62016-08-12 00:43:1613579 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:0113580 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]76a505b2010-08-25 06:23:0013581
13582 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:0113583 EXPECT_THAT(rv, IsOk());
mmenke43758e62015-05-04 21:09:4613584 TestNetLogEntry::List entries;
[email protected]b2fcd0e2010-12-01 15:19:4013585 log.GetEntries(&entries);
[email protected]76a505b2010-08-25 06:23:0013586 size_t pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:0013587 entries, 0, NetLogEventType::HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
13588 NetLogEventPhase::NONE);
[email protected]76a505b2010-08-25 06:23:0013589 ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:4013590 entries, pos,
mikecirone8b85c432016-09-08 19:11:0013591 NetLogEventType::HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
13592 NetLogEventPhase::NONE);
[email protected]76a505b2010-08-25 06:23:0013593
bnc691fda62016-08-12 00:43:1613594 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5213595 ASSERT_TRUE(response);
[email protected]76a505b2010-08-25 06:23:0013596
13597 EXPECT_TRUE(response->headers->IsKeepAlive());
13598 EXPECT_EQ(200, response->headers->response_code());
13599 EXPECT_EQ(100, response->headers->GetContentLength());
13600 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
13601 EXPECT_TRUE(response->was_fetched_via_proxy);
tbansal2ecbbc72016-10-06 17:15:4713602 EXPECT_EQ(ProxyServer(ProxyServer::SCHEME_HTTP,
13603 HostPortPair::FromString("myproxy:70")),
13604 response->proxy_server);
ryansturm49a8cb12016-06-15 16:51:0913605 EXPECT_TRUE(headers_handler.observed_before_headers_sent());
13606 EXPECT_TRUE(headers_handler.observed_before_headers_sent_with_proxy());
13607 EXPECT_EQ("myproxy:70", headers_handler.observed_proxy_server_uri());
[email protected]029c83b62013-01-24 05:28:2013608
13609 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:1613610 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]029c83b62013-01-24 05:28:2013611 TestLoadTimingNotReusedWithPac(load_timing_info,
13612 CONNECT_TIMING_HAS_SSL_TIMES);
[email protected]76a505b2010-08-25 06:23:0013613}
13614
rsleevidb16bb02015-11-12 23:47:1713615// Test a basic HTTPS GET request through a proxy, connecting to an IPv6
13616// literal host.
bncd16676a2016-07-20 16:23:0113617TEST_F(HttpNetworkTransactionTest, ProxyTunnelGetIPv6) {
rsleevidb16bb02015-11-12 23:47:1713618 session_deps_.proxy_service =
13619 ProxyService::CreateFixedFromPacResult("PROXY myproxy:70");
13620 BoundTestNetLog log;
13621 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:0913622 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
rsleevidb16bb02015-11-12 23:47:1713623
13624 HttpRequestInfo request;
13625 request.method = "GET";
13626 request.url = GURL("https://[::1]:443/");
13627
13628 // Since we have proxy, should try to establish tunnel.
13629 MockWrite data_writes1[] = {
13630 MockWrite("CONNECT [::1]:443 HTTP/1.1\r\n"
13631 "Host: [::1]:443\r\n"
13632 "Proxy-Connection: keep-alive\r\n\r\n"),
13633
13634 MockWrite("GET / HTTP/1.1\r\n"
13635 "Host: [::1]\r\n"
13636 "Connection: keep-alive\r\n\r\n"),
13637 };
13638
13639 MockRead data_reads1[] = {
13640 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
13641
13642 MockRead("HTTP/1.1 200 OK\r\n"),
13643 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
13644 MockRead("Content-Length: 100\r\n\r\n"),
13645 MockRead(SYNCHRONOUS, OK),
13646 };
13647
13648 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
13649 data_writes1, arraysize(data_writes1));
13650 session_deps_.socket_factory->AddSocketDataProvider(&data1);
13651 SSLSocketDataProvider ssl(ASYNC, OK);
13652 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
13653
13654 TestCompletionCallback callback1;
13655
bnc691fda62016-08-12 00:43:1613656 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
rsleevidb16bb02015-11-12 23:47:1713657
bnc691fda62016-08-12 00:43:1613658 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:0113659 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
rsleevidb16bb02015-11-12 23:47:1713660
13661 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:0113662 EXPECT_THAT(rv, IsOk());
rsleevidb16bb02015-11-12 23:47:1713663 TestNetLogEntry::List entries;
13664 log.GetEntries(&entries);
13665 size_t pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:0013666 entries, 0, NetLogEventType::HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
13667 NetLogEventPhase::NONE);
rsleevidb16bb02015-11-12 23:47:1713668 ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:0013669 entries, pos,
13670 NetLogEventType::HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
13671 NetLogEventPhase::NONE);
rsleevidb16bb02015-11-12 23:47:1713672
bnc691fda62016-08-12 00:43:1613673 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5213674 ASSERT_TRUE(response);
rsleevidb16bb02015-11-12 23:47:1713675
13676 EXPECT_TRUE(response->headers->IsKeepAlive());
13677 EXPECT_EQ(200, response->headers->response_code());
13678 EXPECT_EQ(100, response->headers->GetContentLength());
13679 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
13680 EXPECT_TRUE(response->was_fetched_via_proxy);
tbansal2ecbbc72016-10-06 17:15:4713681 EXPECT_EQ(ProxyServer(ProxyServer::SCHEME_HTTP,
13682 HostPortPair::FromString("myproxy:70")),
13683 response->proxy_server);
rsleevidb16bb02015-11-12 23:47:1713684
13685 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:1613686 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
rsleevidb16bb02015-11-12 23:47:1713687 TestLoadTimingNotReusedWithPac(load_timing_info,
13688 CONNECT_TIMING_HAS_SSL_TIMES);
13689}
13690
[email protected]76a505b2010-08-25 06:23:0013691// Test a basic HTTPS GET request through a proxy, but the server hangs up
13692// while establishing the tunnel.
bncd16676a2016-07-20 16:23:0113693TEST_F(HttpNetworkTransactionTest, ProxyTunnelGetHangup) {
rdsmith82957ad2015-09-16 19:42:0313694 session_deps_.proxy_service = ProxyService::CreateFixed("myproxy:70");
vishal.b62985ca92015-04-17 08:45:5113695 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:0713696 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:0913697 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]76a505b2010-08-25 06:23:0013698
[email protected]76a505b2010-08-25 06:23:0013699 HttpRequestInfo request;
13700 request.method = "GET";
bncce36dca22015-04-21 22:11:2313701 request.url = GURL("https://www.example.org/");
[email protected]76a505b2010-08-25 06:23:0013702
13703 // Since we have proxy, should try to establish tunnel.
13704 MockWrite data_writes1[] = {
rsleevidb16bb02015-11-12 23:47:1713705 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
13706 "Host: www.example.org:443\r\n"
13707 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]76a505b2010-08-25 06:23:0013708
rsleevidb16bb02015-11-12 23:47:1713709 MockWrite("GET / HTTP/1.1\r\n"
13710 "Host: www.example.org\r\n"
13711 "Connection: keep-alive\r\n\r\n"),
[email protected]76a505b2010-08-25 06:23:0013712 };
13713
13714 MockRead data_reads1[] = {
[email protected]76a505b2010-08-25 06:23:0013715 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:0613716 MockRead(ASYNC, 0, 0), // EOF
[email protected]76a505b2010-08-25 06:23:0013717 };
13718
13719 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
13720 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:0713721 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8ddf8322012-02-23 18:08:0613722 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:0713723 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]76a505b2010-08-25 06:23:0013724
[email protected]49639fa2011-12-20 23:22:4113725 TestCompletionCallback callback1;
[email protected]76a505b2010-08-25 06:23:0013726
bnc691fda62016-08-12 00:43:1613727 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]0b0bf032010-09-21 18:08:5013728
bnc691fda62016-08-12 00:43:1613729 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:0113730 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]76a505b2010-08-25 06:23:0013731
13732 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:0113733 EXPECT_THAT(rv, IsError(ERR_EMPTY_RESPONSE));
mmenke43758e62015-05-04 21:09:4613734 TestNetLogEntry::List entries;
[email protected]b2fcd0e2010-12-01 15:19:4013735 log.GetEntries(&entries);
[email protected]76a505b2010-08-25 06:23:0013736 size_t pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:0013737 entries, 0, NetLogEventType::HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
13738 NetLogEventPhase::NONE);
[email protected]76a505b2010-08-25 06:23:0013739 ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:4013740 entries, pos,
mikecirone8b85c432016-09-08 19:11:0013741 NetLogEventType::HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
13742 NetLogEventPhase::NONE);
[email protected]76a505b2010-08-25 06:23:0013743}
13744
[email protected]749eefa82010-09-13 22:14:0313745// Test for crbug.com/55424.
bncd16676a2016-07-20 16:23:0113746TEST_F(HttpNetworkTransactionTest, PreconnectWithExistingSpdySession) {
bncdf80d44fd2016-07-15 20:27:4113747 SpdySerializedFrame req(
bnc38dcd392016-02-09 23:19:4913748 spdy_util_.ConstructSpdyGet("https://www.example.org", 1, LOWEST));
bncdf80d44fd2016-07-15 20:27:4113749 MockWrite spdy_writes[] = {CreateMockWrite(req, 0)};
[email protected]749eefa82010-09-13 22:14:0313750
bnc42331402016-07-25 13:36:1513751 SpdySerializedFrame resp(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
bncdf80d44fd2016-07-15 20:27:4113752 SpdySerializedFrame data(spdy_util_.ConstructSpdyDataFrame(1, true));
[email protected]749eefa82010-09-13 22:14:0313753 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:4113754 CreateMockRead(resp, 1), CreateMockRead(data, 2), MockRead(ASYNC, 0, 3),
[email protected]749eefa82010-09-13 22:14:0313755 };
13756
rch8e6c6c42015-05-01 14:05:1313757 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
13758 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:0713759 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]749eefa82010-09-13 22:14:0313760
[email protected]8ddf8322012-02-23 18:08:0613761 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3613762 ssl.next_proto = kProtoHTTP2;
[email protected]bb88e1d32013-05-03 23:11:0713763 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]749eefa82010-09-13 22:14:0313764
danakj1fd259a02016-04-16 03:17:0913765 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]749eefa82010-09-13 22:14:0313766
13767 // Set up an initial SpdySession in the pool to reuse.
bncce36dca22015-04-21 22:11:2313768 HostPortPair host_port_pair("www.example.org", 443);
[email protected]e6d017652013-05-17 18:01:4013769 SpdySessionKey key(host_port_pair, ProxyServer::Direct(),
Paul Jensena457017a2018-01-19 23:52:0413770 PRIVACY_MODE_DISABLED, SocketTag());
[email protected]795cbf82013-07-22 09:37:2713771 base::WeakPtr<SpdySession> spdy_session =
Bence Béky0ef1556e2017-06-30 19:52:5213772 CreateSpdySession(session.get(), key, NetLogWithSource());
[email protected]749eefa82010-09-13 22:14:0313773
13774 HttpRequestInfo request;
13775 request.method = "GET";
bncce36dca22015-04-21 22:11:2313776 request.url = GURL("https://www.example.org/");
[email protected]749eefa82010-09-13 22:14:0313777
13778 // This is the important line that marks this as a preconnect.
13779 request.motivation = HttpRequestInfo::PRECONNECT_MOTIVATED;
13780
bnc691fda62016-08-12 00:43:1613781 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]749eefa82010-09-13 22:14:0313782
[email protected]41d64e82013-07-03 22:44:2613783 TestCompletionCallback callback;
tfarina42834112016-09-22 13:38:2013784 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0113785 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
13786 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]749eefa82010-09-13 22:14:0313787}
13788
[email protected]73b8dd222010-11-11 19:55:2413789// Given a net error, cause that error to be returned from the first Write()
bnc691fda62016-08-12 00:43:1613790// call and verify that the HttpNetworkTransaction fails with that error.
[email protected]23e482282013-06-14 16:08:0213791void HttpNetworkTransactionTest::CheckErrorIsPassedBack(
[email protected]bb88e1d32013-05-03 23:11:0713792 int error, IoMode mode) {
ttuttle859dc7a2015-04-23 19:42:2913793 HttpRequestInfo request_info;
[email protected]cb9bf6ca2011-01-28 13:15:2713794 request_info.url = GURL("https://www.example.com/");
13795 request_info.method = "GET";
ttuttle859dc7a2015-04-23 19:42:2913796 request_info.load_flags = LOAD_NORMAL;
[email protected]cb9bf6ca2011-01-28 13:15:2713797
[email protected]8ddf8322012-02-23 18:08:0613798 SSLSocketDataProvider ssl_data(mode, OK);
ttuttle859dc7a2015-04-23 19:42:2913799 MockWrite data_writes[] = {
13800 MockWrite(mode, error),
[email protected]73b8dd222010-11-11 19:55:2413801 };
ttuttle859dc7a2015-04-23 19:42:2913802 StaticSocketDataProvider data(NULL, 0, data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:0713803 session_deps_.socket_factory->AddSocketDataProvider(&data);
13804 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data);
[email protected]73b8dd222010-11-11 19:55:2413805
danakj1fd259a02016-04-16 03:17:0913806 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1613807 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]73b8dd222010-11-11 19:55:2413808
[email protected]49639fa2011-12-20 23:22:4113809 TestCompletionCallback callback;
tfarina42834112016-09-22 13:38:2013810 int rv = trans.Start(&request_info, callback.callback(), NetLogWithSource());
ttuttle859dc7a2015-04-23 19:42:2913811 if (rv == ERR_IO_PENDING)
[email protected]73b8dd222010-11-11 19:55:2413812 rv = callback.WaitForResult();
13813 ASSERT_EQ(error, rv);
13814}
13815
bncd16676a2016-07-20 16:23:0113816TEST_F(HttpNetworkTransactionTest, SSLWriteCertError) {
[email protected]73b8dd222010-11-11 19:55:2413817 // Just check a grab bag of cert errors.
13818 static const int kErrors[] = {
13819 ERR_CERT_COMMON_NAME_INVALID,
13820 ERR_CERT_AUTHORITY_INVALID,
13821 ERR_CERT_DATE_INVALID,
13822 };
13823 for (size_t i = 0; i < arraysize(kErrors); i++) {
[email protected]8ddf8322012-02-23 18:08:0613824 CheckErrorIsPassedBack(kErrors[i], ASYNC);
13825 CheckErrorIsPassedBack(kErrors[i], SYNCHRONOUS);
[email protected]73b8dd222010-11-11 19:55:2413826 }
13827}
13828
[email protected]bd0b6772011-01-11 19:59:3013829// Ensure that a client certificate is removed from the SSL client auth
13830// cache when:
13831// 1) No proxy is involved.
13832// 2) TLS False Start is disabled.
13833// 3) The initial TLS handshake requests a client certificate.
13834// 4) The client supplies an invalid/unacceptable certificate.
bncd16676a2016-07-20 16:23:0113835TEST_F(HttpNetworkTransactionTest, ClientAuthCertCache_Direct_NoFalseStart) {
ttuttle859dc7a2015-04-23 19:42:2913836 HttpRequestInfo request_info;
[email protected]cb9bf6ca2011-01-28 13:15:2713837 request_info.url = GURL("https://www.example.com/");
13838 request_info.method = "GET";
ttuttle859dc7a2015-04-23 19:42:2913839 request_info.load_flags = LOAD_NORMAL;
[email protected]cb9bf6ca2011-01-28 13:15:2713840
[email protected]bd0b6772011-01-11 19:59:3013841 scoped_refptr<SSLCertRequestInfo> cert_request(new SSLCertRequestInfo());
[email protected]791879c2013-12-17 07:22:4113842 cert_request->host_and_port = HostPortPair("www.example.com", 443);
[email protected]bd0b6772011-01-11 19:59:3013843
13844 // [ssl_]data1 contains the data for the first SSL handshake. When a
13845 // CertificateRequest is received for the first time, the handshake will
13846 // be aborted to allow the caller to provide a certificate.
ttuttle859dc7a2015-04-23 19:42:2913847 SSLSocketDataProvider ssl_data1(ASYNC, ERR_SSL_CLIENT_AUTH_CERT_NEEDED);
[email protected]bd0b6772011-01-11 19:59:3013848 ssl_data1.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0713849 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data1);
ttuttle859dc7a2015-04-23 19:42:2913850 StaticSocketDataProvider data1(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0713851 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]bd0b6772011-01-11 19:59:3013852
13853 // [ssl_]data2 contains the data for the second SSL handshake. When TLS
13854 // False Start is not being used, the result of the SSL handshake will be
13855 // returned as part of the SSLClientSocket::Connect() call. This test
13856 // matches the result of a server sending a handshake_failure alert,
13857 // rather than a Finished message, because it requires a client
13858 // certificate and none was supplied.
ttuttle859dc7a2015-04-23 19:42:2913859 SSLSocketDataProvider ssl_data2(ASYNC, ERR_SSL_PROTOCOL_ERROR);
[email protected]bd0b6772011-01-11 19:59:3013860 ssl_data2.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0713861 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data2);
ttuttle859dc7a2015-04-23 19:42:2913862 StaticSocketDataProvider data2(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0713863 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]bd0b6772011-01-11 19:59:3013864
13865 // [ssl_]data3 contains the data for the third SSL handshake. When a
13866 // connection to a server fails during an SSL handshake,
davidbenb937d6c2015-05-14 04:53:4213867 // HttpNetworkTransaction will attempt to fallback to TLSv1.1 if the previous
13868 // connection was attempted with TLSv1.2. This is transparent to the caller
[email protected]bd0b6772011-01-11 19:59:3013869 // of the HttpNetworkTransaction. Because this test failure is due to
13870 // requiring a client certificate, this fallback handshake should also
13871 // fail.
ttuttle859dc7a2015-04-23 19:42:2913872 SSLSocketDataProvider ssl_data3(ASYNC, ERR_SSL_PROTOCOL_ERROR);
[email protected]bd0b6772011-01-11 19:59:3013873 ssl_data3.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0713874 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data3);
ttuttle859dc7a2015-04-23 19:42:2913875 StaticSocketDataProvider data3(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0713876 session_deps_.socket_factory->AddSocketDataProvider(&data3);
[email protected]bd0b6772011-01-11 19:59:3013877
[email protected]80c75f682012-05-26 16:22:1713878 // [ssl_]data4 contains the data for the fourth SSL handshake. When a
13879 // connection to a server fails during an SSL handshake,
davidbenb937d6c2015-05-14 04:53:4213880 // HttpNetworkTransaction will attempt to fallback to TLSv1 if the previous
13881 // connection was attempted with TLSv1.1. This is transparent to the caller
[email protected]80c75f682012-05-26 16:22:1713882 // of the HttpNetworkTransaction. Because this test failure is due to
13883 // requiring a client certificate, this fallback handshake should also
13884 // fail.
ttuttle859dc7a2015-04-23 19:42:2913885 SSLSocketDataProvider ssl_data4(ASYNC, ERR_SSL_PROTOCOL_ERROR);
[email protected]80c75f682012-05-26 16:22:1713886 ssl_data4.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0713887 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data4);
ttuttle859dc7a2015-04-23 19:42:2913888 StaticSocketDataProvider data4(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0713889 session_deps_.socket_factory->AddSocketDataProvider(&data4);
[email protected]80c75f682012-05-26 16:22:1713890
danakj1fd259a02016-04-16 03:17:0913891 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1613892 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]bd0b6772011-01-11 19:59:3013893
[email protected]bd0b6772011-01-11 19:59:3013894 // Begin the SSL handshake with the peer. This consumes ssl_data1.
[email protected]49639fa2011-12-20 23:22:4113895 TestCompletionCallback callback;
tfarina42834112016-09-22 13:38:2013896 int rv = trans.Start(&request_info, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0113897 ASSERT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]bd0b6772011-01-11 19:59:3013898
13899 // Complete the SSL handshake, which should abort due to requiring a
13900 // client certificate.
13901 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0113902 ASSERT_THAT(rv, IsError(ERR_SSL_CLIENT_AUTH_CERT_NEEDED));
[email protected]bd0b6772011-01-11 19:59:3013903
13904 // Indicate that no certificate should be supplied. From the perspective
13905 // of SSLClientCertCache, NULL is just as meaningful as a real
13906 // certificate, so this is the same as supply a
13907 // legitimate-but-unacceptable certificate.
bnc691fda62016-08-12 00:43:1613908 rv = trans.RestartWithCertificate(NULL, NULL, callback.callback());
robpercival214763f2016-07-01 23:27:0113909 ASSERT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]bd0b6772011-01-11 19:59:3013910
13911 // Ensure the certificate was added to the client auth cache before
13912 // allowing the connection to continue restarting.
13913 scoped_refptr<X509Certificate> client_cert;
svaldez7872fd02015-11-19 21:10:5413914 scoped_refptr<SSLPrivateKey> client_private_key;
[email protected]791879c2013-12-17 07:22:4113915 ASSERT_TRUE(session->ssl_client_auth_cache()->Lookup(
svaldez7872fd02015-11-19 21:10:5413916 HostPortPair("www.example.com", 443), &client_cert, &client_private_key));
wezca1070932016-05-26 20:30:5213917 ASSERT_FALSE(client_cert);
[email protected]bd0b6772011-01-11 19:59:3013918
13919 // Restart the handshake. This will consume ssl_data2, which fails, and
[email protected]80c75f682012-05-26 16:22:1713920 // then consume ssl_data3 and ssl_data4, both of which should also fail.
13921 // The result code is checked against what ssl_data4 should return.
[email protected]bd0b6772011-01-11 19:59:3013922 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0113923 ASSERT_THAT(rv, IsError(ERR_SSL_PROTOCOL_ERROR));
[email protected]bd0b6772011-01-11 19:59:3013924
13925 // Ensure that the client certificate is removed from the cache on a
13926 // handshake failure.
[email protected]791879c2013-12-17 07:22:4113927 ASSERT_FALSE(session->ssl_client_auth_cache()->Lookup(
svaldez7872fd02015-11-19 21:10:5413928 HostPortPair("www.example.com", 443), &client_cert, &client_private_key));
[email protected]bd0b6772011-01-11 19:59:3013929}
13930
13931// Ensure that a client certificate is removed from the SSL client auth
13932// cache when:
13933// 1) No proxy is involved.
13934// 2) TLS False Start is enabled.
13935// 3) The initial TLS handshake requests a client certificate.
13936// 4) The client supplies an invalid/unacceptable certificate.
bncd16676a2016-07-20 16:23:0113937TEST_F(HttpNetworkTransactionTest, ClientAuthCertCache_Direct_FalseStart) {
ttuttle859dc7a2015-04-23 19:42:2913938 HttpRequestInfo request_info;
[email protected]cb9bf6ca2011-01-28 13:15:2713939 request_info.url = GURL("https://www.example.com/");
13940 request_info.method = "GET";
ttuttle859dc7a2015-04-23 19:42:2913941 request_info.load_flags = LOAD_NORMAL;
[email protected]cb9bf6ca2011-01-28 13:15:2713942
[email protected]bd0b6772011-01-11 19:59:3013943 scoped_refptr<SSLCertRequestInfo> cert_request(new SSLCertRequestInfo());
[email protected]791879c2013-12-17 07:22:4113944 cert_request->host_and_port = HostPortPair("www.example.com", 443);
[email protected]bd0b6772011-01-11 19:59:3013945
13946 // When TLS False Start is used, SSLClientSocket::Connect() calls will
13947 // return successfully after reading up to the peer's Certificate message.
13948 // This is to allow the caller to call SSLClientSocket::Write(), which can
13949 // enqueue application data to be sent in the same packet as the
13950 // ChangeCipherSpec and Finished messages.
13951 // The actual handshake will be finished when SSLClientSocket::Read() is
13952 // called, which expects to process the peer's ChangeCipherSpec and
13953 // Finished messages. If there was an error negotiating with the peer,
13954 // such as due to the peer requiring a client certificate when none was
13955 // supplied, the alert sent by the peer won't be processed until Read() is
13956 // called.
13957
13958 // Like the non-False Start case, when a client certificate is requested by
13959 // the peer, the handshake is aborted during the Connect() call.
13960 // [ssl_]data1 represents the initial SSL handshake with the peer.
ttuttle859dc7a2015-04-23 19:42:2913961 SSLSocketDataProvider ssl_data1(ASYNC, ERR_SSL_CLIENT_AUTH_CERT_NEEDED);
[email protected]bd0b6772011-01-11 19:59:3013962 ssl_data1.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0713963 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data1);
ttuttle859dc7a2015-04-23 19:42:2913964 StaticSocketDataProvider data1(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0713965 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]bd0b6772011-01-11 19:59:3013966
13967 // When a client certificate is supplied, Connect() will not be aborted
13968 // when the peer requests the certificate. Instead, the handshake will
13969 // artificially succeed, allowing the caller to write the HTTP request to
13970 // the socket. The handshake messages are not processed until Read() is
13971 // called, which then detects that the handshake was aborted, due to the
13972 // peer sending a handshake_failure because it requires a client
13973 // certificate.
ttuttle859dc7a2015-04-23 19:42:2913974 SSLSocketDataProvider ssl_data2(ASYNC, OK);
[email protected]bd0b6772011-01-11 19:59:3013975 ssl_data2.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0713976 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data2);
ttuttle859dc7a2015-04-23 19:42:2913977 MockRead data2_reads[] = {
13978 MockRead(ASYNC /* async */, ERR_SSL_PROTOCOL_ERROR),
[email protected]bd0b6772011-01-11 19:59:3013979 };
ttuttle859dc7a2015-04-23 19:42:2913980 StaticSocketDataProvider data2(data2_reads, arraysize(data2_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0713981 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]bd0b6772011-01-11 19:59:3013982
13983 // As described in ClientAuthCertCache_Direct_NoFalseStart, [ssl_]data3 is
[email protected]80c75f682012-05-26 16:22:1713984 // the data for the SSL handshake once the TLSv1.1 connection falls back to
13985 // TLSv1. It has the same behaviour as [ssl_]data2.
ttuttle859dc7a2015-04-23 19:42:2913986 SSLSocketDataProvider ssl_data3(ASYNC, OK);
[email protected]bd0b6772011-01-11 19:59:3013987 ssl_data3.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0713988 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data3);
ttuttle859dc7a2015-04-23 19:42:2913989 StaticSocketDataProvider data3(data2_reads, arraysize(data2_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0713990 session_deps_.socket_factory->AddSocketDataProvider(&data3);
[email protected]bd0b6772011-01-11 19:59:3013991
[email protected]80c75f682012-05-26 16:22:1713992 // [ssl_]data4 is the data for the SSL handshake once the TLSv1 connection
13993 // falls back to SSLv3. It has the same behaviour as [ssl_]data2.
ttuttle859dc7a2015-04-23 19:42:2913994 SSLSocketDataProvider ssl_data4(ASYNC, OK);
[email protected]80c75f682012-05-26 16:22:1713995 ssl_data4.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0713996 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data4);
ttuttle859dc7a2015-04-23 19:42:2913997 StaticSocketDataProvider data4(data2_reads, arraysize(data2_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0713998 session_deps_.socket_factory->AddSocketDataProvider(&data4);
[email protected]80c75f682012-05-26 16:22:1713999
[email protected]7799de12013-05-30 05:52:5114000 // Need one more if TLSv1.2 is enabled.
ttuttle859dc7a2015-04-23 19:42:2914001 SSLSocketDataProvider ssl_data5(ASYNC, OK);
[email protected]7799de12013-05-30 05:52:5114002 ssl_data5.cert_request_info = cert_request.get();
14003 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data5);
ttuttle859dc7a2015-04-23 19:42:2914004 StaticSocketDataProvider data5(data2_reads, arraysize(data2_reads), NULL, 0);
[email protected]7799de12013-05-30 05:52:5114005 session_deps_.socket_factory->AddSocketDataProvider(&data5);
14006
danakj1fd259a02016-04-16 03:17:0914007 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1614008 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]bd0b6772011-01-11 19:59:3014009
[email protected]bd0b6772011-01-11 19:59:3014010 // Begin the initial SSL handshake.
[email protected]49639fa2011-12-20 23:22:4114011 TestCompletionCallback callback;
tfarina42834112016-09-22 13:38:2014012 int rv = trans.Start(&request_info, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0114013 ASSERT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]bd0b6772011-01-11 19:59:3014014
14015 // Complete the SSL handshake, which should abort due to requiring a
14016 // client certificate.
14017 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0114018 ASSERT_THAT(rv, IsError(ERR_SSL_CLIENT_AUTH_CERT_NEEDED));
[email protected]bd0b6772011-01-11 19:59:3014019
14020 // Indicate that no certificate should be supplied. From the perspective
14021 // of SSLClientCertCache, NULL is just as meaningful as a real
14022 // certificate, so this is the same as supply a
14023 // legitimate-but-unacceptable certificate.
bnc691fda62016-08-12 00:43:1614024 rv = trans.RestartWithCertificate(NULL, NULL, callback.callback());
robpercival214763f2016-07-01 23:27:0114025 ASSERT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]bd0b6772011-01-11 19:59:3014026
14027 // Ensure the certificate was added to the client auth cache before
14028 // allowing the connection to continue restarting.
14029 scoped_refptr<X509Certificate> client_cert;
svaldez7872fd02015-11-19 21:10:5414030 scoped_refptr<SSLPrivateKey> client_private_key;
[email protected]791879c2013-12-17 07:22:4114031 ASSERT_TRUE(session->ssl_client_auth_cache()->Lookup(
svaldez7872fd02015-11-19 21:10:5414032 HostPortPair("www.example.com", 443), &client_cert, &client_private_key));
wezca1070932016-05-26 20:30:5214033 ASSERT_FALSE(client_cert);
[email protected]bd0b6772011-01-11 19:59:3014034
[email protected]bd0b6772011-01-11 19:59:3014035 // Restart the handshake. This will consume ssl_data2, which fails, and
[email protected]80c75f682012-05-26 16:22:1714036 // then consume ssl_data3 and ssl_data4, both of which should also fail.
14037 // The result code is checked against what ssl_data4 should return.
[email protected]bd0b6772011-01-11 19:59:3014038 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0114039 ASSERT_THAT(rv, IsError(ERR_SSL_PROTOCOL_ERROR));
[email protected]bd0b6772011-01-11 19:59:3014040
14041 // Ensure that the client certificate is removed from the cache on a
14042 // handshake failure.
[email protected]791879c2013-12-17 07:22:4114043 ASSERT_FALSE(session->ssl_client_auth_cache()->Lookup(
svaldez7872fd02015-11-19 21:10:5414044 HostPortPair("www.example.com", 443), &client_cert, &client_private_key));
[email protected]bd0b6772011-01-11 19:59:3014045}
14046
[email protected]8c405132011-01-11 22:03:1814047// Ensure that a client certificate is removed from the SSL client auth
14048// cache when:
14049// 1) An HTTPS proxy is involved.
14050// 3) The HTTPS proxy requests a client certificate.
14051// 4) The client supplies an invalid/unacceptable certificate for the
14052// proxy.
14053// The test is repeated twice, first for connecting to an HTTPS endpoint,
14054// then for connecting to an HTTP endpoint.
bncd16676a2016-07-20 16:23:0114055TEST_F(HttpNetworkTransactionTest, ClientAuthCertCache_Proxy_Fail) {
rdsmith82957ad2015-09-16 19:42:0314056 session_deps_.proxy_service = ProxyService::CreateFixed("https://proxy:70");
vishal.b62985ca92015-04-17 08:45:5114057 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:0714058 session_deps_.net_log = log.bound().net_log();
[email protected]8c405132011-01-11 22:03:1814059
14060 scoped_refptr<SSLCertRequestInfo> cert_request(new SSLCertRequestInfo());
[email protected]791879c2013-12-17 07:22:4114061 cert_request->host_and_port = HostPortPair("proxy", 70);
[email protected]8c405132011-01-11 22:03:1814062
14063 // See ClientAuthCertCache_Direct_NoFalseStart for the explanation of
14064 // [ssl_]data[1-3]. Rather than represending the endpoint
14065 // (www.example.com:443), they represent failures with the HTTPS proxy
14066 // (proxy:70).
ttuttle859dc7a2015-04-23 19:42:2914067 SSLSocketDataProvider ssl_data1(ASYNC, ERR_SSL_CLIENT_AUTH_CERT_NEEDED);
[email protected]8c405132011-01-11 22:03:1814068 ssl_data1.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0714069 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data1);
ttuttle859dc7a2015-04-23 19:42:2914070 StaticSocketDataProvider data1(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0714071 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8c405132011-01-11 22:03:1814072
ttuttle859dc7a2015-04-23 19:42:2914073 SSLSocketDataProvider ssl_data2(ASYNC, ERR_SSL_PROTOCOL_ERROR);
[email protected]8c405132011-01-11 22:03:1814074 ssl_data2.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0714075 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data2);
ttuttle859dc7a2015-04-23 19:42:2914076 StaticSocketDataProvider data2(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0714077 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]8c405132011-01-11 22:03:1814078
[email protected]80c75f682012-05-26 16:22:1714079 // TODO(wtc): find out why this unit test doesn't need [ssl_]data3.
14080#if 0
ttuttle859dc7a2015-04-23 19:42:2914081 SSLSocketDataProvider ssl_data3(ASYNC, ERR_SSL_PROTOCOL_ERROR);
[email protected]8c405132011-01-11 22:03:1814082 ssl_data3.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0714083 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data3);
ttuttle859dc7a2015-04-23 19:42:2914084 StaticSocketDataProvider data3(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0714085 session_deps_.socket_factory->AddSocketDataProvider(&data3);
[email protected]80c75f682012-05-26 16:22:1714086#endif
[email protected]8c405132011-01-11 22:03:1814087
ttuttle859dc7a2015-04-23 19:42:2914088 HttpRequestInfo requests[2];
[email protected]8c405132011-01-11 22:03:1814089 requests[0].url = GURL("https://www.example.com/");
14090 requests[0].method = "GET";
ttuttle859dc7a2015-04-23 19:42:2914091 requests[0].load_flags = LOAD_NORMAL;
[email protected]8c405132011-01-11 22:03:1814092
14093 requests[1].url = GURL("http://www.example.com/");
14094 requests[1].method = "GET";
ttuttle859dc7a2015-04-23 19:42:2914095 requests[1].load_flags = LOAD_NORMAL;
[email protected]8c405132011-01-11 22:03:1814096
14097 for (size_t i = 0; i < arraysize(requests); ++i) {
[email protected]bb88e1d32013-05-03 23:11:0714098 session_deps_.socket_factory->ResetNextMockIndexes();
danakj1fd259a02016-04-16 03:17:0914099 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1614100 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]8c405132011-01-11 22:03:1814101
14102 // Begin the SSL handshake with the proxy.
[email protected]49639fa2011-12-20 23:22:4114103 TestCompletionCallback callback;
tfarina42834112016-09-22 13:38:2014104 int rv = trans.Start(&requests[i], callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0114105 ASSERT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]8c405132011-01-11 22:03:1814106
14107 // Complete the SSL handshake, which should abort due to requiring a
14108 // client certificate.
14109 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0114110 ASSERT_THAT(rv, IsError(ERR_SSL_CLIENT_AUTH_CERT_NEEDED));
[email protected]8c405132011-01-11 22:03:1814111
14112 // Indicate that no certificate should be supplied. From the perspective
14113 // of SSLClientCertCache, NULL is just as meaningful as a real
14114 // certificate, so this is the same as supply a
14115 // legitimate-but-unacceptable certificate.
bnc691fda62016-08-12 00:43:1614116 rv = trans.RestartWithCertificate(NULL, NULL, callback.callback());
robpercival214763f2016-07-01 23:27:0114117 ASSERT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]8c405132011-01-11 22:03:1814118
14119 // Ensure the certificate was added to the client auth cache before
14120 // allowing the connection to continue restarting.
14121 scoped_refptr<X509Certificate> client_cert;
svaldez7872fd02015-11-19 21:10:5414122 scoped_refptr<SSLPrivateKey> client_private_key;
[email protected]791879c2013-12-17 07:22:4114123 ASSERT_TRUE(session->ssl_client_auth_cache()->Lookup(
svaldez7872fd02015-11-19 21:10:5414124 HostPortPair("proxy", 70), &client_cert, &client_private_key));
wezca1070932016-05-26 20:30:5214125 ASSERT_FALSE(client_cert);
[email protected]8c405132011-01-11 22:03:1814126 // Ensure the certificate was NOT cached for the endpoint. This only
14127 // applies to HTTPS requests, but is fine to check for HTTP requests.
[email protected]791879c2013-12-17 07:22:4114128 ASSERT_FALSE(session->ssl_client_auth_cache()->Lookup(
svaldez7872fd02015-11-19 21:10:5414129 HostPortPair("www.example.com", 443), &client_cert,
14130 &client_private_key));
[email protected]8c405132011-01-11 22:03:1814131
14132 // Restart the handshake. This will consume ssl_data2, which fails, and
14133 // then consume ssl_data3, which should also fail. The result code is
14134 // checked against what ssl_data3 should return.
14135 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0114136 ASSERT_THAT(rv, IsError(ERR_PROXY_CONNECTION_FAILED));
[email protected]8c405132011-01-11 22:03:1814137
14138 // Now that the new handshake has failed, ensure that the client
14139 // certificate was removed from the client auth cache.
[email protected]791879c2013-12-17 07:22:4114140 ASSERT_FALSE(session->ssl_client_auth_cache()->Lookup(
svaldez7872fd02015-11-19 21:10:5414141 HostPortPair("proxy", 70), &client_cert, &client_private_key));
[email protected]791879c2013-12-17 07:22:4114142 ASSERT_FALSE(session->ssl_client_auth_cache()->Lookup(
svaldez7872fd02015-11-19 21:10:5414143 HostPortPair("www.example.com", 443), &client_cert,
14144 &client_private_key));
[email protected]8c405132011-01-11 22:03:1814145 }
14146}
14147
bncd16676a2016-07-20 16:23:0114148TEST_F(HttpNetworkTransactionTest, UseIPConnectionPooling) {
[email protected]e3ceb682011-06-28 23:55:4614149 // Set up a special HttpNetworkSession with a MockCachingHostResolver.
Jeremy Roman0579ed62017-08-29 15:56:1914150 session_deps_.host_resolver = std::make_unique<MockCachingHostResolver>();
danakj1fd259a02016-04-16 03:17:0914151 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]e3ceb682011-06-28 23:55:4614152
bnc032658ba2016-09-26 18:17:1514153 AddSSLSocketData();
[email protected]e3ceb682011-06-28 23:55:4614154
bncdf80d44fd2016-07-15 20:27:4114155 SpdySerializedFrame host1_req(
bnc38dcd392016-02-09 23:19:4914156 spdy_util_.ConstructSpdyGet("https://www.example.org", 1, LOWEST));
rdsmithebb50aa2015-11-12 03:44:3814157 spdy_util_.UpdateWithStreamDestruction(1);
bncdf80d44fd2016-07-15 20:27:4114158 SpdySerializedFrame host2_req(
bnca4d611d2016-09-22 19:55:3714159 spdy_util_.ConstructSpdyGet("https://mail.example.com", 3, LOWEST));
[email protected]e3ceb682011-06-28 23:55:4614160 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:4114161 CreateMockWrite(host1_req, 0), CreateMockWrite(host2_req, 3),
[email protected]e3ceb682011-06-28 23:55:4614162 };
bnc42331402016-07-25 13:36:1514163 SpdySerializedFrame host1_resp(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
bncdf80d44fd2016-07-15 20:27:4114164 SpdySerializedFrame host1_resp_body(
14165 spdy_util_.ConstructSpdyDataFrame(1, true));
bnc42331402016-07-25 13:36:1514166 SpdySerializedFrame host2_resp(spdy_util_.ConstructSpdyGetReply(NULL, 0, 3));
bncdf80d44fd2016-07-15 20:27:4114167 SpdySerializedFrame host2_resp_body(
14168 spdy_util_.ConstructSpdyDataFrame(3, true));
[email protected]e3ceb682011-06-28 23:55:4614169 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:4114170 CreateMockRead(host1_resp, 1), CreateMockRead(host1_resp_body, 2),
14171 CreateMockRead(host2_resp, 4), CreateMockRead(host2_resp_body, 5),
rch8e6c6c42015-05-01 14:05:1314172 MockRead(ASYNC, 0, 6),
[email protected]e3ceb682011-06-28 23:55:4614173 };
14174
eroman36d84e54432016-03-17 03:23:0214175 IPEndPoint peer_addr(IPAddress::IPv4Localhost(), 443);
[email protected]d2b5f092012-06-08 23:55:0214176 MockConnect connect(ASYNC, OK, peer_addr);
rch8e6c6c42015-05-01 14:05:1314177 SequencedSocketData spdy_data(connect, spdy_reads, arraysize(spdy_reads),
14178 spdy_writes, arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:0714179 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]e3ceb682011-06-28 23:55:4614180
[email protected]aa22b242011-11-16 18:58:2914181 TestCompletionCallback callback;
[email protected]e3ceb682011-06-28 23:55:4614182 HttpRequestInfo request1;
14183 request1.method = "GET";
bncce36dca22015-04-21 22:11:2314184 request1.url = GURL("https://www.example.org/");
[email protected]e3ceb682011-06-28 23:55:4614185 request1.load_flags = 0;
[email protected]90499482013-06-01 00:39:5014186 HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
[email protected]e3ceb682011-06-28 23:55:4614187
tfarina42834112016-09-22 13:38:2014188 int rv = trans1.Start(&request1, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0114189 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
14190 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]e3ceb682011-06-28 23:55:4614191
14192 const HttpResponseInfo* response = trans1.GetResponseInfo();
wezca1070932016-05-26 20:30:5214193 ASSERT_TRUE(response);
14194 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0214195 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]e3ceb682011-06-28 23:55:4614196
14197 std::string response_data;
robpercival214763f2016-07-01 23:27:0114198 ASSERT_THAT(ReadTransaction(&trans1, &response_data), IsOk());
[email protected]e3ceb682011-06-28 23:55:4614199 EXPECT_EQ("hello!", response_data);
14200
bnca4d611d2016-09-22 19:55:3714201 // Preload mail.example.com into HostCache.
14202 HostPortPair host_port("mail.example.com", 443);
[email protected]5109c1952013-08-20 18:44:1014203 HostResolver::RequestInfo resolve_info(host_port);
[email protected]e3ceb682011-06-28 23:55:4614204 AddressList ignored;
maksim.sisov31452af2016-07-27 06:38:1014205 std::unique_ptr<HostResolver::Request> request;
14206 rv = session_deps_.host_resolver->Resolve(resolve_info, DEFAULT_PRIORITY,
14207 &ignored, callback.callback(),
tfarina42834112016-09-22 13:38:2014208 &request, NetLogWithSource());
robpercival214763f2016-07-01 23:27:0114209 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]6e78dfb2011-07-28 21:34:4714210 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0114211 EXPECT_THAT(rv, IsOk());
[email protected]e3ceb682011-06-28 23:55:4614212
14213 HttpRequestInfo request2;
14214 request2.method = "GET";
bnca4d611d2016-09-22 19:55:3714215 request2.url = GURL("https://mail.example.com/");
[email protected]e3ceb682011-06-28 23:55:4614216 request2.load_flags = 0;
[email protected]90499482013-06-01 00:39:5014217 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
[email protected]e3ceb682011-06-28 23:55:4614218
tfarina42834112016-09-22 13:38:2014219 rv = trans2.Start(&request2, 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 response = trans2.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 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5214228 EXPECT_TRUE(response->was_alpn_negotiated);
robpercival214763f2016-07-01 23:27:0114229 ASSERT_THAT(ReadTransaction(&trans2, &response_data), IsOk());
[email protected]e3ceb682011-06-28 23:55:4614230 EXPECT_EQ("hello!", response_data);
[email protected]e3ceb682011-06-28 23:55:4614231}
14232
bncd16676a2016-07-20 16:23:0114233TEST_F(HttpNetworkTransactionTest, UseIPConnectionPoolingAfterResolution) {
[email protected]d2b5f092012-06-08 23:55:0214234 // Set up a special HttpNetworkSession with a MockCachingHostResolver.
Jeremy Roman0579ed62017-08-29 15:56:1914235 session_deps_.host_resolver = std::make_unique<MockCachingHostResolver>();
danakj1fd259a02016-04-16 03:17:0914236 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]d2b5f092012-06-08 23:55:0214237
bnc032658ba2016-09-26 18:17:1514238 AddSSLSocketData();
[email protected]d2b5f092012-06-08 23:55:0214239
bncdf80d44fd2016-07-15 20:27:4114240 SpdySerializedFrame host1_req(
bnc38dcd392016-02-09 23:19:4914241 spdy_util_.ConstructSpdyGet("https://www.example.org", 1, LOWEST));
rdsmithebb50aa2015-11-12 03:44:3814242 spdy_util_.UpdateWithStreamDestruction(1);
bncdf80d44fd2016-07-15 20:27:4114243 SpdySerializedFrame host2_req(
bnca4d611d2016-09-22 19:55:3714244 spdy_util_.ConstructSpdyGet("https://mail.example.com", 3, LOWEST));
[email protected]d2b5f092012-06-08 23:55:0214245 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:4114246 CreateMockWrite(host1_req, 0), CreateMockWrite(host2_req, 3),
[email protected]d2b5f092012-06-08 23:55:0214247 };
bnc42331402016-07-25 13:36:1514248 SpdySerializedFrame host1_resp(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
bncdf80d44fd2016-07-15 20:27:4114249 SpdySerializedFrame host1_resp_body(
14250 spdy_util_.ConstructSpdyDataFrame(1, true));
bnc42331402016-07-25 13:36:1514251 SpdySerializedFrame host2_resp(spdy_util_.ConstructSpdyGetReply(NULL, 0, 3));
bncdf80d44fd2016-07-15 20:27:4114252 SpdySerializedFrame host2_resp_body(
14253 spdy_util_.ConstructSpdyDataFrame(3, true));
[email protected]d2b5f092012-06-08 23:55:0214254 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:4114255 CreateMockRead(host1_resp, 1), CreateMockRead(host1_resp_body, 2),
14256 CreateMockRead(host2_resp, 4), CreateMockRead(host2_resp_body, 5),
rch8e6c6c42015-05-01 14:05:1314257 MockRead(ASYNC, 0, 6),
[email protected]d2b5f092012-06-08 23:55:0214258 };
14259
eroman36d84e54432016-03-17 03:23:0214260 IPEndPoint peer_addr(IPAddress::IPv4Localhost(), 443);
[email protected]d2b5f092012-06-08 23:55:0214261 MockConnect connect(ASYNC, OK, peer_addr);
rch8e6c6c42015-05-01 14:05:1314262 SequencedSocketData spdy_data(connect, spdy_reads, arraysize(spdy_reads),
14263 spdy_writes, arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:0714264 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]d2b5f092012-06-08 23:55:0214265
14266 TestCompletionCallback callback;
14267 HttpRequestInfo request1;
14268 request1.method = "GET";
bncce36dca22015-04-21 22:11:2314269 request1.url = GURL("https://www.example.org/");
[email protected]d2b5f092012-06-08 23:55:0214270 request1.load_flags = 0;
[email protected]90499482013-06-01 00:39:5014271 HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
[email protected]d2b5f092012-06-08 23:55:0214272
tfarina42834112016-09-22 13:38:2014273 int rv = trans1.Start(&request1, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0114274 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
14275 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]d2b5f092012-06-08 23:55:0214276
14277 const HttpResponseInfo* response = trans1.GetResponseInfo();
wezca1070932016-05-26 20:30:5214278 ASSERT_TRUE(response);
14279 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0214280 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]d2b5f092012-06-08 23:55:0214281
14282 std::string response_data;
robpercival214763f2016-07-01 23:27:0114283 ASSERT_THAT(ReadTransaction(&trans1, &response_data), IsOk());
[email protected]d2b5f092012-06-08 23:55:0214284 EXPECT_EQ("hello!", response_data);
14285
14286 HttpRequestInfo request2;
14287 request2.method = "GET";
bnca4d611d2016-09-22 19:55:3714288 request2.url = GURL("https://mail.example.com/");
[email protected]d2b5f092012-06-08 23:55:0214289 request2.load_flags = 0;
[email protected]90499482013-06-01 00:39:5014290 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
[email protected]d2b5f092012-06-08 23:55:0214291
tfarina42834112016-09-22 13:38:2014292 rv = trans2.Start(&request2, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0114293 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
14294 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]d2b5f092012-06-08 23:55:0214295
14296 response = trans2.GetResponseInfo();
wezca1070932016-05-26 20:30:5214297 ASSERT_TRUE(response);
14298 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0214299 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]d2b5f092012-06-08 23:55:0214300 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5214301 EXPECT_TRUE(response->was_alpn_negotiated);
robpercival214763f2016-07-01 23:27:0114302 ASSERT_THAT(ReadTransaction(&trans2, &response_data), IsOk());
[email protected]d2b5f092012-06-08 23:55:0214303 EXPECT_EQ("hello!", response_data);
[email protected]d2b5f092012-06-08 23:55:0214304}
14305
bnc8016c1f2017-03-31 02:11:2914306// Regression test for https://crbug.com/546991.
14307// The server might not be able to serve an IP pooled request, and might send a
14308// 421 Misdirected Request response status to indicate this.
14309// HttpNetworkTransaction should reset the request and retry without IP pooling.
14310TEST_F(HttpNetworkTransactionTest, RetryWithoutConnectionPooling) {
14311 // Two hosts resolve to the same IP address.
14312 const std::string ip_addr = "1.2.3.4";
14313 IPAddress ip;
14314 ASSERT_TRUE(ip.AssignFromIPLiteral(ip_addr));
14315 IPEndPoint peer_addr = IPEndPoint(ip, 443);
14316
Jeremy Roman0579ed62017-08-29 15:56:1914317 session_deps_.host_resolver = std::make_unique<MockCachingHostResolver>();
bnc8016c1f2017-03-31 02:11:2914318 session_deps_.host_resolver->rules()->AddRule("www.example.org", ip_addr);
14319 session_deps_.host_resolver->rules()->AddRule("mail.example.org", ip_addr);
14320
14321 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
14322
14323 // Two requests on the first connection.
14324 SpdySerializedFrame req1(
14325 spdy_util_.ConstructSpdyGet("https://www.example.org", 1, LOWEST));
14326 spdy_util_.UpdateWithStreamDestruction(1);
14327 SpdySerializedFrame req2(
14328 spdy_util_.ConstructSpdyGet("https://mail.example.org", 3, LOWEST));
14329 SpdySerializedFrame rst(
14330 spdy_util_.ConstructSpdyRstStream(3, ERROR_CODE_CANCEL));
14331 MockWrite writes1[] = {
14332 CreateMockWrite(req1, 0), CreateMockWrite(req2, 3),
14333 CreateMockWrite(rst, 6),
14334 };
14335
14336 // The first one succeeds, the second gets error 421 Misdirected Request.
14337 SpdySerializedFrame resp1(spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
14338 SpdySerializedFrame body1(spdy_util_.ConstructSpdyDataFrame(1, true));
14339 SpdyHeaderBlock response_headers;
Bence Békybda82952017-10-02 17:35:2714340 response_headers[kHttp2StatusHeader] = "421";
bnc8016c1f2017-03-31 02:11:2914341 SpdySerializedFrame resp2(
14342 spdy_util_.ConstructSpdyReply(3, std::move(response_headers)));
14343 MockRead reads1[] = {CreateMockRead(resp1, 1), CreateMockRead(body1, 2),
14344 CreateMockRead(resp2, 4), MockRead(ASYNC, 0, 5)};
14345
14346 MockConnect connect1(ASYNC, OK, peer_addr);
14347 SequencedSocketData data1(connect1, reads1, arraysize(reads1), writes1,
14348 arraysize(writes1));
14349 session_deps_.socket_factory->AddSocketDataProvider(&data1);
14350
14351 AddSSLSocketData();
14352
14353 // Retry the second request on a second connection.
14354 SpdyTestUtil spdy_util2;
14355 SpdySerializedFrame req3(
14356 spdy_util2.ConstructSpdyGet("https://mail.example.org", 1, LOWEST));
14357 MockWrite writes2[] = {
14358 CreateMockWrite(req3, 0),
14359 };
14360
14361 SpdySerializedFrame resp3(spdy_util2.ConstructSpdyGetReply(nullptr, 0, 1));
14362 SpdySerializedFrame body3(spdy_util2.ConstructSpdyDataFrame(1, true));
14363 MockRead reads2[] = {CreateMockRead(resp3, 1), CreateMockRead(body3, 2),
14364 MockRead(ASYNC, 0, 3)};
14365
14366 MockConnect connect2(ASYNC, OK, peer_addr);
14367 SequencedSocketData data2(connect2, reads2, arraysize(reads2), writes2,
14368 arraysize(writes2));
14369 session_deps_.socket_factory->AddSocketDataProvider(&data2);
14370
14371 AddSSLSocketData();
14372
14373 // Preload mail.example.org into HostCache.
14374 HostPortPair host_port("mail.example.org", 443);
14375 HostResolver::RequestInfo resolve_info(host_port);
14376 AddressList ignored;
14377 std::unique_ptr<HostResolver::Request> request;
14378 TestCompletionCallback callback;
14379 int rv = session_deps_.host_resolver->Resolve(resolve_info, DEFAULT_PRIORITY,
14380 &ignored, callback.callback(),
14381 &request, NetLogWithSource());
14382 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
14383 rv = callback.WaitForResult();
14384 EXPECT_THAT(rv, IsOk());
14385
14386 HttpRequestInfo request1;
14387 request1.method = "GET";
14388 request1.url = GURL("https://www.example.org/");
14389 request1.load_flags = 0;
14390 HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
14391
14392 rv = trans1.Start(&request1, callback.callback(), NetLogWithSource());
14393 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
14394 rv = callback.WaitForResult();
14395 EXPECT_THAT(rv, IsOk());
14396
14397 const HttpResponseInfo* response = trans1.GetResponseInfo();
14398 ASSERT_TRUE(response);
14399 ASSERT_TRUE(response->headers);
14400 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
14401 EXPECT_TRUE(response->was_fetched_via_spdy);
14402 EXPECT_TRUE(response->was_alpn_negotiated);
14403 std::string response_data;
14404 ASSERT_THAT(ReadTransaction(&trans1, &response_data), IsOk());
14405 EXPECT_EQ("hello!", response_data);
14406
14407 HttpRequestInfo request2;
14408 request2.method = "GET";
14409 request2.url = GURL("https://mail.example.org/");
14410 request2.load_flags = 0;
14411 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
14412
14413 BoundTestNetLog log;
14414 rv = trans2.Start(&request2, callback.callback(), log.bound());
14415 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
14416 rv = callback.WaitForResult();
14417 EXPECT_THAT(rv, IsOk());
14418
14419 response = trans2.GetResponseInfo();
14420 ASSERT_TRUE(response);
14421 ASSERT_TRUE(response->headers);
14422 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
14423 EXPECT_TRUE(response->was_fetched_via_spdy);
14424 EXPECT_TRUE(response->was_alpn_negotiated);
14425 ASSERT_THAT(ReadTransaction(&trans2, &response_data), IsOk());
14426 EXPECT_EQ("hello!", response_data);
14427
14428 TestNetLogEntry::List entries;
14429 log.GetEntries(&entries);
davidbence688ae2017-05-04 15:12:5914430 ExpectLogContainsSomewhere(
14431 entries, 0, NetLogEventType::HTTP_TRANSACTION_RESTART_MISDIRECTED_REQUEST,
bnc8016c1f2017-03-31 02:11:2914432 NetLogEventPhase::NONE);
davidbence688ae2017-05-04 15:12:5914433}
14434
14435// Test that HTTP 421 responses are properly returned to the caller if received
14436// on the retry as well. HttpNetworkTransaction should not infinite loop or lose
14437// portions of the response.
14438TEST_F(HttpNetworkTransactionTest, ReturnHTTP421OnRetry) {
14439 // Two hosts resolve to the same IP address.
14440 const std::string ip_addr = "1.2.3.4";
14441 IPAddress ip;
14442 ASSERT_TRUE(ip.AssignFromIPLiteral(ip_addr));
14443 IPEndPoint peer_addr = IPEndPoint(ip, 443);
14444
Jeremy Roman0579ed62017-08-29 15:56:1914445 session_deps_.host_resolver = std::make_unique<MockCachingHostResolver>();
davidbence688ae2017-05-04 15:12:5914446 session_deps_.host_resolver->rules()->AddRule("www.example.org", ip_addr);
14447 session_deps_.host_resolver->rules()->AddRule("mail.example.org", ip_addr);
14448
14449 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
14450
14451 // Two requests on the first connection.
14452 SpdySerializedFrame req1(
14453 spdy_util_.ConstructSpdyGet("https://www.example.org", 1, LOWEST));
14454 spdy_util_.UpdateWithStreamDestruction(1);
14455 SpdySerializedFrame req2(
14456 spdy_util_.ConstructSpdyGet("https://mail.example.org", 3, LOWEST));
14457 SpdySerializedFrame rst(
14458 spdy_util_.ConstructSpdyRstStream(3, ERROR_CODE_CANCEL));
14459 MockWrite writes1[] = {
14460 CreateMockWrite(req1, 0), CreateMockWrite(req2, 3),
14461 CreateMockWrite(rst, 6),
14462 };
14463
14464 // The first one succeeds, the second gets error 421 Misdirected Request.
14465 SpdySerializedFrame resp1(spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
14466 SpdySerializedFrame body1(spdy_util_.ConstructSpdyDataFrame(1, true));
14467 SpdyHeaderBlock response_headers;
Bence Békybda82952017-10-02 17:35:2714468 response_headers[kHttp2StatusHeader] = "421";
davidbence688ae2017-05-04 15:12:5914469 SpdySerializedFrame resp2(
14470 spdy_util_.ConstructSpdyReply(3, response_headers.Clone()));
14471 MockRead reads1[] = {CreateMockRead(resp1, 1), CreateMockRead(body1, 2),
14472 CreateMockRead(resp2, 4), MockRead(ASYNC, 0, 5)};
14473
14474 MockConnect connect1(ASYNC, OK, peer_addr);
14475 SequencedSocketData data1(connect1, reads1, arraysize(reads1), writes1,
14476 arraysize(writes1));
14477 session_deps_.socket_factory->AddSocketDataProvider(&data1);
14478
14479 AddSSLSocketData();
14480
14481 // Retry the second request on a second connection. It returns 421 Misdirected
14482 // Retry again.
14483 SpdyTestUtil spdy_util2;
14484 SpdySerializedFrame req3(
14485 spdy_util2.ConstructSpdyGet("https://mail.example.org", 1, LOWEST));
14486 MockWrite writes2[] = {
14487 CreateMockWrite(req3, 0),
14488 };
14489
14490 SpdySerializedFrame resp3(
14491 spdy_util2.ConstructSpdyReply(1, std::move(response_headers)));
14492 SpdySerializedFrame body3(spdy_util2.ConstructSpdyDataFrame(1, true));
14493 MockRead reads2[] = {CreateMockRead(resp3, 1), CreateMockRead(body3, 2),
14494 MockRead(ASYNC, 0, 3)};
14495
14496 MockConnect connect2(ASYNC, OK, peer_addr);
14497 SequencedSocketData data2(connect2, reads2, arraysize(reads2), writes2,
14498 arraysize(writes2));
14499 session_deps_.socket_factory->AddSocketDataProvider(&data2);
14500
14501 AddSSLSocketData();
14502
14503 // Preload mail.example.org into HostCache.
14504 HostPortPair host_port("mail.example.org", 443);
14505 HostResolver::RequestInfo resolve_info(host_port);
14506 AddressList ignored;
14507 std::unique_ptr<HostResolver::Request> request;
14508 TestCompletionCallback callback;
14509 int rv = session_deps_.host_resolver->Resolve(resolve_info, DEFAULT_PRIORITY,
14510 &ignored, callback.callback(),
14511 &request, NetLogWithSource());
14512 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
14513 rv = callback.WaitForResult();
14514 EXPECT_THAT(rv, IsOk());
14515
14516 HttpRequestInfo request1;
14517 request1.method = "GET";
14518 request1.url = GURL("https://www.example.org/");
14519 request1.load_flags = 0;
14520 HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
14521
14522 rv = trans1.Start(&request1, callback.callback(), NetLogWithSource());
14523 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
14524 rv = callback.WaitForResult();
14525 EXPECT_THAT(rv, IsOk());
14526
14527 const HttpResponseInfo* response = trans1.GetResponseInfo();
14528 ASSERT_TRUE(response);
14529 ASSERT_TRUE(response->headers);
14530 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
14531 EXPECT_TRUE(response->was_fetched_via_spdy);
14532 EXPECT_TRUE(response->was_alpn_negotiated);
14533 std::string response_data;
14534 ASSERT_THAT(ReadTransaction(&trans1, &response_data), IsOk());
14535 EXPECT_EQ("hello!", response_data);
14536
14537 HttpRequestInfo request2;
14538 request2.method = "GET";
14539 request2.url = GURL("https://mail.example.org/");
14540 request2.load_flags = 0;
14541 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
14542
14543 BoundTestNetLog log;
14544 rv = trans2.Start(&request2, callback.callback(), log.bound());
14545 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
14546 rv = callback.WaitForResult();
14547 EXPECT_THAT(rv, IsOk());
14548
14549 // After a retry, the 421 Misdirected Request is reported back up to the
14550 // caller.
14551 response = trans2.GetResponseInfo();
14552 ASSERT_TRUE(response);
14553 ASSERT_TRUE(response->headers);
14554 EXPECT_EQ("HTTP/1.1 421", response->headers->GetStatusLine());
14555 EXPECT_TRUE(response->was_fetched_via_spdy);
14556 EXPECT_TRUE(response->was_alpn_negotiated);
14557 EXPECT_TRUE(response->ssl_info.cert);
14558 ASSERT_THAT(ReadTransaction(&trans2, &response_data), IsOk());
14559 EXPECT_EQ("hello!", response_data);
bnc8016c1f2017-03-31 02:11:2914560}
14561
bnc6dcd8192017-05-25 20:11:5014562class OneTimeCachingHostResolver : public MockHostResolverBase {
[email protected]e3ceb682011-06-28 23:55:4614563 public:
14564 explicit OneTimeCachingHostResolver(const HostPortPair& host_port)
bnc6dcd8192017-05-25 20:11:5014565 : MockHostResolverBase(/* use_caching = */ true), host_port_(host_port) {}
Chris Watkins7a41d3552017-12-01 02:13:2714566 ~OneTimeCachingHostResolver() override = default;
[email protected]e3ceb682011-06-28 23:55:4614567
dchengb03027d2014-10-21 12:00:2014568 int ResolveFromCache(const RequestInfo& info,
14569 AddressList* addresses,
tfarina42834112016-09-22 13:38:2014570 const NetLogWithSource& net_log) override {
bnc6dcd8192017-05-25 20:11:5014571 int rv = MockHostResolverBase::ResolveFromCache(info, addresses, net_log);
[email protected]95a214c2011-08-04 21:50:4014572 if (rv == OK && info.host_port_pair().Equals(host_port_))
bnc6dcd8192017-05-25 20:11:5014573 GetHostCache()->clear();
[email protected]e3ceb682011-06-28 23:55:4614574 return rv;
14575 }
14576
[email protected]e3ceb682011-06-28 23:55:4614577 private:
[email protected]e3ceb682011-06-28 23:55:4614578 const HostPortPair host_port_;
14579};
14580
bncd16676a2016-07-20 16:23:0114581TEST_F(HttpNetworkTransactionTest,
mmenke5c642132015-06-02 16:05:1314582 UseIPConnectionPoolingWithHostCacheExpiration) {
[email protected]e3ceb682011-06-28 23:55:4614583 // Set up a special HttpNetworkSession with a OneTimeCachingHostResolver.
Jeremy Roman0579ed62017-08-29 15:56:1914584 session_deps_.host_resolver = std::make_unique<OneTimeCachingHostResolver>(
bnca4d611d2016-09-22 19:55:3714585 HostPortPair("mail.example.com", 443));
danakj1fd259a02016-04-16 03:17:0914586 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]e3ceb682011-06-28 23:55:4614587
bnc032658ba2016-09-26 18:17:1514588 AddSSLSocketData();
[email protected]e3ceb682011-06-28 23:55:4614589
bncdf80d44fd2016-07-15 20:27:4114590 SpdySerializedFrame host1_req(
bnc38dcd392016-02-09 23:19:4914591 spdy_util_.ConstructSpdyGet("https://www.example.org", 1, LOWEST));
rdsmithebb50aa2015-11-12 03:44:3814592 spdy_util_.UpdateWithStreamDestruction(1);
bncdf80d44fd2016-07-15 20:27:4114593 SpdySerializedFrame host2_req(
bnca4d611d2016-09-22 19:55:3714594 spdy_util_.ConstructSpdyGet("https://mail.example.com", 3, LOWEST));
[email protected]e3ceb682011-06-28 23:55:4614595 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:4114596 CreateMockWrite(host1_req, 0), CreateMockWrite(host2_req, 3),
[email protected]e3ceb682011-06-28 23:55:4614597 };
bnc42331402016-07-25 13:36:1514598 SpdySerializedFrame host1_resp(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
bncdf80d44fd2016-07-15 20:27:4114599 SpdySerializedFrame host1_resp_body(
14600 spdy_util_.ConstructSpdyDataFrame(1, true));
bnc42331402016-07-25 13:36:1514601 SpdySerializedFrame host2_resp(spdy_util_.ConstructSpdyGetReply(NULL, 0, 3));
bncdf80d44fd2016-07-15 20:27:4114602 SpdySerializedFrame host2_resp_body(
14603 spdy_util_.ConstructSpdyDataFrame(3, true));
[email protected]e3ceb682011-06-28 23:55:4614604 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:4114605 CreateMockRead(host1_resp, 1), CreateMockRead(host1_resp_body, 2),
14606 CreateMockRead(host2_resp, 4), CreateMockRead(host2_resp_body, 5),
rch8e6c6c42015-05-01 14:05:1314607 MockRead(ASYNC, 0, 6),
[email protected]e3ceb682011-06-28 23:55:4614608 };
14609
eroman36d84e54432016-03-17 03:23:0214610 IPEndPoint peer_addr(IPAddress::IPv4Localhost(), 443);
[email protected]d2b5f092012-06-08 23:55:0214611 MockConnect connect(ASYNC, OK, peer_addr);
rch8e6c6c42015-05-01 14:05:1314612 SequencedSocketData spdy_data(connect, spdy_reads, arraysize(spdy_reads),
14613 spdy_writes, arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:0714614 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]e3ceb682011-06-28 23:55:4614615
[email protected]aa22b242011-11-16 18:58:2914616 TestCompletionCallback callback;
[email protected]e3ceb682011-06-28 23:55:4614617 HttpRequestInfo request1;
14618 request1.method = "GET";
bncce36dca22015-04-21 22:11:2314619 request1.url = GURL("https://www.example.org/");
[email protected]e3ceb682011-06-28 23:55:4614620 request1.load_flags = 0;
[email protected]90499482013-06-01 00:39:5014621 HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
[email protected]e3ceb682011-06-28 23:55:4614622
tfarina42834112016-09-22 13:38:2014623 int rv = trans1.Start(&request1, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0114624 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
14625 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]e3ceb682011-06-28 23:55:4614626
14627 const HttpResponseInfo* response = trans1.GetResponseInfo();
wezca1070932016-05-26 20:30:5214628 ASSERT_TRUE(response);
14629 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0214630 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]e3ceb682011-06-28 23:55:4614631
14632 std::string response_data;
robpercival214763f2016-07-01 23:27:0114633 ASSERT_THAT(ReadTransaction(&trans1, &response_data), IsOk());
[email protected]e3ceb682011-06-28 23:55:4614634 EXPECT_EQ("hello!", response_data);
14635
14636 // Preload cache entries into HostCache.
bnca4d611d2016-09-22 19:55:3714637 HostResolver::RequestInfo resolve_info(HostPortPair("mail.example.com", 443));
[email protected]e3ceb682011-06-28 23:55:4614638 AddressList ignored;
maksim.sisov31452af2016-07-27 06:38:1014639 std::unique_ptr<HostResolver::Request> request;
bnc6dcd8192017-05-25 20:11:5014640 rv = session_deps_.host_resolver->Resolve(resolve_info, DEFAULT_PRIORITY,
14641 &ignored, callback.callback(),
14642 &request, NetLogWithSource());
robpercival214763f2016-07-01 23:27:0114643 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]6e78dfb2011-07-28 21:34:4714644 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0114645 EXPECT_THAT(rv, IsOk());
[email protected]e3ceb682011-06-28 23:55:4614646
14647 HttpRequestInfo request2;
14648 request2.method = "GET";
bnca4d611d2016-09-22 19:55:3714649 request2.url = GURL("https://mail.example.com/");
[email protected]e3ceb682011-06-28 23:55:4614650 request2.load_flags = 0;
[email protected]90499482013-06-01 00:39:5014651 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
[email protected]e3ceb682011-06-28 23:55:4614652
tfarina42834112016-09-22 13:38:2014653 rv = trans2.Start(&request2, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0114654 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
14655 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]e3ceb682011-06-28 23:55:4614656
14657 response = trans2.GetResponseInfo();
wezca1070932016-05-26 20:30:5214658 ASSERT_TRUE(response);
14659 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0214660 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]e3ceb682011-06-28 23:55:4614661 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5214662 EXPECT_TRUE(response->was_alpn_negotiated);
robpercival214763f2016-07-01 23:27:0114663 ASSERT_THAT(ReadTransaction(&trans2, &response_data), IsOk());
[email protected]e3ceb682011-06-28 23:55:4614664 EXPECT_EQ("hello!", response_data);
[email protected]e3ceb682011-06-28 23:55:4614665}
14666
bncd16676a2016-07-20 16:23:0114667TEST_F(HttpNetworkTransactionTest, DoNotUseSpdySessionForHttp) {
bncce36dca22015-04-21 22:11:2314668 const std::string https_url = "https://www.example.org:8080/";
14669 const std::string http_url = "http://www.example.org:8080/";
[email protected]8450d722012-07-02 19:14:0414670
14671 // SPDY GET for HTTPS URL
bncdf80d44fd2016-07-15 20:27:4114672 SpdySerializedFrame req1(
bnc38dcd392016-02-09 23:19:4914673 spdy_util_.ConstructSpdyGet(https_url.c_str(), 1, LOWEST));
[email protected]8450d722012-07-02 19:14:0414674
14675 MockWrite writes1[] = {
bncdf80d44fd2016-07-15 20:27:4114676 CreateMockWrite(req1, 0),
[email protected]8450d722012-07-02 19:14:0414677 };
14678
bnc42331402016-07-25 13:36:1514679 SpdySerializedFrame resp1(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
bncdf80d44fd2016-07-15 20:27:4114680 SpdySerializedFrame body1(spdy_util_.ConstructSpdyDataFrame(1, true));
14681 MockRead reads1[] = {CreateMockRead(resp1, 1), CreateMockRead(body1, 2),
mmenkee24011922015-12-17 22:12:5914682 MockRead(SYNCHRONOUS, ERR_IO_PENDING, 3)};
[email protected]8450d722012-07-02 19:14:0414683
rch8e6c6c42015-05-01 14:05:1314684 SequencedSocketData data1(reads1, arraysize(reads1), writes1,
14685 arraysize(writes1));
[email protected]8450d722012-07-02 19:14:0414686 MockConnect connect_data1(ASYNC, OK);
[email protected]dd54bd82012-07-19 23:44:5714687 data1.set_connect_data(connect_data1);
[email protected]8450d722012-07-02 19:14:0414688
14689 // HTTP GET for the HTTP URL
14690 MockWrite writes2[] = {
rch8e6c6c42015-05-01 14:05:1314691 MockWrite(ASYNC, 0,
lgarrona91df87f2014-12-05 00:51:3414692 "GET / HTTP/1.1\r\n"
bncce36dca22015-04-21 22:11:2314693 "Host: www.example.org:8080\r\n"
lgarrona91df87f2014-12-05 00:51:3414694 "Connection: keep-alive\r\n\r\n"),
[email protected]8450d722012-07-02 19:14:0414695 };
14696
14697 MockRead reads2[] = {
rch8e6c6c42015-05-01 14:05:1314698 MockRead(ASYNC, 1, "HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
14699 MockRead(ASYNC, 2, "hello"),
14700 MockRead(ASYNC, OK, 3),
[email protected]8450d722012-07-02 19:14:0414701 };
14702
rch8e6c6c42015-05-01 14:05:1314703 SequencedSocketData data2(reads2, arraysize(reads2), writes2,
14704 arraysize(writes2));
[email protected]8450d722012-07-02 19:14:0414705
[email protected]8450d722012-07-02 19:14:0414706 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3614707 ssl.next_proto = kProtoHTTP2;
[email protected]bb88e1d32013-05-03 23:11:0714708 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
14709 session_deps_.socket_factory->AddSocketDataProvider(&data1);
14710 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]8450d722012-07-02 19:14:0414711
danakj1fd259a02016-04-16 03:17:0914712 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]8450d722012-07-02 19:14:0414713
14714 // Start the first transaction to set up the SpdySession
14715 HttpRequestInfo request1;
14716 request1.method = "GET";
14717 request1.url = GURL(https_url);
[email protected]8450d722012-07-02 19:14:0414718 request1.load_flags = 0;
[email protected]90499482013-06-01 00:39:5014719 HttpNetworkTransaction trans1(LOWEST, session.get());
[email protected]8450d722012-07-02 19:14:0414720 TestCompletionCallback callback1;
14721 EXPECT_EQ(ERR_IO_PENDING,
tfarina42834112016-09-22 13:38:2014722 trans1.Start(&request1, callback1.callback(), NetLogWithSource()));
fdoray92e35a72016-06-10 15:54:5514723 base::RunLoop().RunUntilIdle();
[email protected]8450d722012-07-02 19:14:0414724
robpercival214763f2016-07-01 23:27:0114725 EXPECT_THAT(callback1.WaitForResult(), IsOk());
[email protected]8450d722012-07-02 19:14:0414726 EXPECT_TRUE(trans1.GetResponseInfo()->was_fetched_via_spdy);
14727
14728 // Now, start the HTTP request
14729 HttpRequestInfo request2;
14730 request2.method = "GET";
14731 request2.url = GURL(http_url);
[email protected]8450d722012-07-02 19:14:0414732 request2.load_flags = 0;
[email protected]90499482013-06-01 00:39:5014733 HttpNetworkTransaction trans2(MEDIUM, session.get());
[email protected]8450d722012-07-02 19:14:0414734 TestCompletionCallback callback2;
14735 EXPECT_EQ(ERR_IO_PENDING,
tfarina42834112016-09-22 13:38:2014736 trans2.Start(&request2, callback2.callback(), NetLogWithSource()));
fdoray92e35a72016-06-10 15:54:5514737 base::RunLoop().RunUntilIdle();
[email protected]8450d722012-07-02 19:14:0414738
robpercival214763f2016-07-01 23:27:0114739 EXPECT_THAT(callback2.WaitForResult(), IsOk());
[email protected]8450d722012-07-02 19:14:0414740 EXPECT_FALSE(trans2.GetResponseInfo()->was_fetched_via_spdy);
14741}
14742
bnc5452e2a2015-05-08 16:27:4214743// Alternative service requires HTTP/2 (or SPDY), but HTTP/1.1 is negotiated
14744// with the alternative server. That connection should not be used.
bncd16676a2016-07-20 16:23:0114745TEST_F(HttpNetworkTransactionTest, AlternativeServiceNotOnHttp11) {
bnc8bef8da22016-05-30 01:28:2514746 url::SchemeHostPort server("https", "www.example.org", 443);
14747 HostPortPair alternative("www.example.org", 444);
bnc5452e2a2015-05-08 16:27:4214748
bnc8bef8da22016-05-30 01:28:2514749 // Negotiate HTTP/1.1 with alternative.
bnc5452e2a2015-05-08 16:27:4214750 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3614751 ssl.next_proto = kProtoHTTP11;
bnc5452e2a2015-05-08 16:27:4214752 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
14753
14754 // No data should be read from the alternative, because HTTP/1.1 is
14755 // negotiated.
14756 StaticSocketDataProvider data;
14757 session_deps_.socket_factory->AddSocketDataProvider(&data);
14758
14759 // This test documents that an alternate Job should not be used if HTTP/1.1 is
zhongyi3d4a55e72016-04-22 20:36:4614760 // negotiated. In order to test this, a failed connection to the server is
bnc5452e2a2015-05-08 16:27:4214761 // mocked. This way the request relies on the alternate Job.
14762 StaticSocketDataProvider data_refused;
14763 data_refused.set_connect_data(MockConnect(ASYNC, ERR_CONNECTION_REFUSED));
14764 session_deps_.socket_factory->AddSocketDataProvider(&data_refused);
14765
zhongyi3d4a55e72016-04-22 20:36:4614766 // Set up alternative service for server.
danakj1fd259a02016-04-16 03:17:0914767 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc525e175a2016-06-20 12:36:4014768 HttpServerProperties* http_server_properties =
bnc5452e2a2015-05-08 16:27:4214769 session->http_server_properties();
bnc3472afd2016-11-17 15:27:2114770 AlternativeService alternative_service(kProtoHTTP2, alternative);
bnc7dc7e1b42015-07-28 14:43:1214771 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:2114772 http_server_properties->SetHttp2AlternativeService(
14773 server, alternative_service, expiration);
bnc5452e2a2015-05-08 16:27:4214774
bnc5452e2a2015-05-08 16:27:4214775 HttpRequestInfo request;
krasinc06a72a2016-12-21 03:42:4614776 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
bnc5452e2a2015-05-08 16:27:4214777 request.method = "GET";
bnc8bef8da22016-05-30 01:28:2514778 request.url = GURL("https://www.example.org:443");
bnc5452e2a2015-05-08 16:27:4214779 TestCompletionCallback callback;
14780
14781 // HTTP/2 (or SPDY) is required for alternative service, if HTTP/1.1 is
bnc94c92842016-09-21 15:22:5214782 // negotiated, the alternate Job should fail with ERR_ALPN_NEGOTIATION_FAILED.
tfarina42834112016-09-22 13:38:2014783 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
bnc94c92842016-09-21 15:22:5214784 EXPECT_THAT(callback.GetResult(rv), IsError(ERR_ALPN_NEGOTIATION_FAILED));
bnc5452e2a2015-05-08 16:27:4214785}
14786
bnc40448a532015-05-11 19:13:1414787// A request to a server with an alternative service fires two Jobs: one to the
zhongyi3d4a55e72016-04-22 20:36:4614788// server, and an alternate one to the alternative server. If the former
bnc40448a532015-05-11 19:13:1414789// succeeds, the request should succeed, even if the latter fails because
14790// HTTP/1.1 is negotiated which is insufficient for alternative service.
bncd16676a2016-07-20 16:23:0114791TEST_F(HttpNetworkTransactionTest, FailedAlternativeServiceIsNotUserVisible) {
bnc8bef8da22016-05-30 01:28:2514792 url::SchemeHostPort server("https", "www.example.org", 443);
14793 HostPortPair alternative("www.example.org", 444);
bnc40448a532015-05-11 19:13:1414794
14795 // Negotiate HTTP/1.1 with alternative.
14796 SSLSocketDataProvider alternative_ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3614797 alternative_ssl.next_proto = kProtoHTTP11;
bnc40448a532015-05-11 19:13:1414798 session_deps_.socket_factory->AddSSLSocketDataProvider(&alternative_ssl);
14799
14800 // No data should be read from the alternative, because HTTP/1.1 is
14801 // negotiated.
14802 StaticSocketDataProvider data;
14803 session_deps_.socket_factory->AddSocketDataProvider(&data);
14804
zhongyi3d4a55e72016-04-22 20:36:4614805 // Negotiate HTTP/1.1 with server.
bnc40448a532015-05-11 19:13:1414806 SSLSocketDataProvider origin_ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3614807 origin_ssl.next_proto = kProtoHTTP11;
bnc40448a532015-05-11 19:13:1414808 session_deps_.socket_factory->AddSSLSocketDataProvider(&origin_ssl);
14809
14810 MockWrite http_writes[] = {
bnc8bef8da22016-05-30 01:28:2514811 MockWrite("GET / HTTP/1.1\r\n"
14812 "Host: www.example.org\r\n"
14813 "Connection: keep-alive\r\n\r\n"),
14814 MockWrite("GET /second HTTP/1.1\r\n"
14815 "Host: www.example.org\r\n"
14816 "Connection: keep-alive\r\n\r\n"),
bnc40448a532015-05-11 19:13:1414817 };
14818
14819 MockRead http_reads[] = {
14820 MockRead("HTTP/1.1 200 OK\r\n"),
14821 MockRead("Content-Type: text/html\r\n"),
14822 MockRead("Content-Length: 6\r\n\r\n"),
14823 MockRead("foobar"),
14824 MockRead("HTTP/1.1 200 OK\r\n"),
14825 MockRead("Content-Type: text/html\r\n"),
14826 MockRead("Content-Length: 7\r\n\r\n"),
14827 MockRead("another"),
14828 };
14829 StaticSocketDataProvider http_data(http_reads, arraysize(http_reads),
14830 http_writes, arraysize(http_writes));
14831 session_deps_.socket_factory->AddSocketDataProvider(&http_data);
14832
zhongyi3d4a55e72016-04-22 20:36:4614833 // Set up alternative service for server.
danakj1fd259a02016-04-16 03:17:0914834 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc525e175a2016-06-20 12:36:4014835 HttpServerProperties* http_server_properties =
bnc40448a532015-05-11 19:13:1414836 session->http_server_properties();
bnc3472afd2016-11-17 15:27:2114837 AlternativeService alternative_service(kProtoHTTP2, alternative);
bnc7dc7e1b42015-07-28 14:43:1214838 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:2114839 http_server_properties->SetHttp2AlternativeService(
14840 server, alternative_service, expiration);
bnc40448a532015-05-11 19:13:1414841
14842 HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
14843 HttpRequestInfo request1;
14844 request1.method = "GET";
bnc8bef8da22016-05-30 01:28:2514845 request1.url = GURL("https://www.example.org:443");
bnc40448a532015-05-11 19:13:1414846 request1.load_flags = 0;
14847 TestCompletionCallback callback1;
14848
tfarina42834112016-09-22 13:38:2014849 int rv = trans1.Start(&request1, callback1.callback(), NetLogWithSource());
bnc40448a532015-05-11 19:13:1414850 rv = callback1.GetResult(rv);
robpercival214763f2016-07-01 23:27:0114851 EXPECT_THAT(rv, IsOk());
bnc40448a532015-05-11 19:13:1414852
14853 const HttpResponseInfo* response1 = trans1.GetResponseInfo();
wezca1070932016-05-26 20:30:5214854 ASSERT_TRUE(response1);
14855 ASSERT_TRUE(response1->headers);
bnc40448a532015-05-11 19:13:1414856 EXPECT_EQ("HTTP/1.1 200 OK", response1->headers->GetStatusLine());
14857
14858 std::string response_data1;
robpercival214763f2016-07-01 23:27:0114859 ASSERT_THAT(ReadTransaction(&trans1, &response_data1), IsOk());
bnc40448a532015-05-11 19:13:1414860 EXPECT_EQ("foobar", response_data1);
14861
14862 // Alternative should be marked as broken, because HTTP/1.1 is not sufficient
14863 // for alternative service.
14864 EXPECT_TRUE(
14865 http_server_properties->IsAlternativeServiceBroken(alternative_service));
14866
zhongyi3d4a55e72016-04-22 20:36:4614867 // Since |alternative_service| is broken, a second transaction to server
bnc40448a532015-05-11 19:13:1414868 // should not start an alternate Job. It should pool to existing connection
zhongyi3d4a55e72016-04-22 20:36:4614869 // to server.
bnc40448a532015-05-11 19:13:1414870 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
14871 HttpRequestInfo request2;
14872 request2.method = "GET";
bnc8bef8da22016-05-30 01:28:2514873 request2.url = GURL("https://www.example.org:443/second");
bnc40448a532015-05-11 19:13:1414874 request2.load_flags = 0;
14875 TestCompletionCallback callback2;
14876
tfarina42834112016-09-22 13:38:2014877 rv = trans2.Start(&request2, callback2.callback(), NetLogWithSource());
bnc40448a532015-05-11 19:13:1414878 rv = callback2.GetResult(rv);
robpercival214763f2016-07-01 23:27:0114879 EXPECT_THAT(rv, IsOk());
bnc40448a532015-05-11 19:13:1414880
14881 const HttpResponseInfo* response2 = trans2.GetResponseInfo();
wezca1070932016-05-26 20:30:5214882 ASSERT_TRUE(response2);
14883 ASSERT_TRUE(response2->headers);
bnc40448a532015-05-11 19:13:1414884 EXPECT_EQ("HTTP/1.1 200 OK", response2->headers->GetStatusLine());
14885
14886 std::string response_data2;
robpercival214763f2016-07-01 23:27:0114887 ASSERT_THAT(ReadTransaction(&trans2, &response_data2), IsOk());
bnc40448a532015-05-11 19:13:1414888 EXPECT_EQ("another", response_data2);
14889}
14890
bnc5452e2a2015-05-08 16:27:4214891// Alternative service requires HTTP/2 (or SPDY), but there is already a
14892// HTTP/1.1 socket open to the alternative server. That socket should not be
14893// used.
bncd16676a2016-07-20 16:23:0114894TEST_F(HttpNetworkTransactionTest, AlternativeServiceShouldNotPoolToHttp11) {
zhongyi3d4a55e72016-04-22 20:36:4614895 url::SchemeHostPort server("https", "origin.example.org", 443);
bnc5452e2a2015-05-08 16:27:4214896 HostPortPair alternative("alternative.example.org", 443);
14897 std::string origin_url = "https://origin.example.org:443";
14898 std::string alternative_url = "https://alternative.example.org:443";
14899
14900 // Negotiate HTTP/1.1 with alternative.example.org.
14901 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3614902 ssl.next_proto = kProtoHTTP11;
bnc5452e2a2015-05-08 16:27:4214903 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
14904
14905 // HTTP/1.1 data for |request1| and |request2|.
14906 MockWrite http_writes[] = {
14907 MockWrite(
14908 "GET / HTTP/1.1\r\n"
14909 "Host: alternative.example.org\r\n"
14910 "Connection: keep-alive\r\n\r\n"),
14911 MockWrite(
14912 "GET / HTTP/1.1\r\n"
14913 "Host: alternative.example.org\r\n"
14914 "Connection: keep-alive\r\n\r\n"),
14915 };
14916
14917 MockRead http_reads[] = {
14918 MockRead(
14919 "HTTP/1.1 200 OK\r\n"
14920 "Content-Type: text/html; charset=iso-8859-1\r\n"
14921 "Content-Length: 40\r\n\r\n"
14922 "first HTTP/1.1 response from alternative"),
14923 MockRead(
14924 "HTTP/1.1 200 OK\r\n"
14925 "Content-Type: text/html; charset=iso-8859-1\r\n"
14926 "Content-Length: 41\r\n\r\n"
14927 "second HTTP/1.1 response from alternative"),
14928 };
14929 StaticSocketDataProvider http_data(http_reads, arraysize(http_reads),
14930 http_writes, arraysize(http_writes));
14931 session_deps_.socket_factory->AddSocketDataProvider(&http_data);
14932
14933 // This test documents that an alternate Job should not pool to an already
14934 // existing HTTP/1.1 connection. In order to test this, a failed connection
zhongyi3d4a55e72016-04-22 20:36:4614935 // to the server is mocked. This way |request2| relies on the alternate Job.
bnc5452e2a2015-05-08 16:27:4214936 StaticSocketDataProvider data_refused;
14937 data_refused.set_connect_data(MockConnect(ASYNC, ERR_CONNECTION_REFUSED));
14938 session_deps_.socket_factory->AddSocketDataProvider(&data_refused);
14939
zhongyi3d4a55e72016-04-22 20:36:4614940 // Set up alternative service for server.
danakj1fd259a02016-04-16 03:17:0914941 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc525e175a2016-06-20 12:36:4014942 HttpServerProperties* http_server_properties =
bnc5452e2a2015-05-08 16:27:4214943 session->http_server_properties();
bnc3472afd2016-11-17 15:27:2114944 AlternativeService alternative_service(kProtoHTTP2, alternative);
bnc7dc7e1b42015-07-28 14:43:1214945 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:2114946 http_server_properties->SetHttp2AlternativeService(
14947 server, alternative_service, expiration);
bnc5452e2a2015-05-08 16:27:4214948
14949 // First transaction to alternative to open an HTTP/1.1 socket.
bnc5452e2a2015-05-08 16:27:4214950 HttpRequestInfo request1;
krasinc06a72a2016-12-21 03:42:4614951 HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
bnc5452e2a2015-05-08 16:27:4214952 request1.method = "GET";
14953 request1.url = GURL(alternative_url);
14954 request1.load_flags = 0;
14955 TestCompletionCallback callback1;
14956
tfarina42834112016-09-22 13:38:2014957 int rv = trans1.Start(&request1, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0114958 EXPECT_THAT(callback1.GetResult(rv), IsOk());
bnc691fda62016-08-12 00:43:1614959 const HttpResponseInfo* response1 = trans1.GetResponseInfo();
bnc5452e2a2015-05-08 16:27:4214960 ASSERT_TRUE(response1);
wezca1070932016-05-26 20:30:5214961 ASSERT_TRUE(response1->headers);
bnc5452e2a2015-05-08 16:27:4214962 EXPECT_EQ("HTTP/1.1 200 OK", response1->headers->GetStatusLine());
bnc94c92842016-09-21 15:22:5214963 EXPECT_TRUE(response1->was_alpn_negotiated);
bnc5452e2a2015-05-08 16:27:4214964 EXPECT_FALSE(response1->was_fetched_via_spdy);
14965 std::string response_data1;
bnc691fda62016-08-12 00:43:1614966 ASSERT_THAT(ReadTransaction(&trans1, &response_data1), IsOk());
bnc5452e2a2015-05-08 16:27:4214967 EXPECT_EQ("first HTTP/1.1 response from alternative", response_data1);
14968
14969 // Request for origin.example.org, which has an alternative service. This
14970 // will start two Jobs: the alternative looks for connections to pool to,
14971 // finds one which is HTTP/1.1, and should ignore it, and should not try to
zhongyi3d4a55e72016-04-22 20:36:4614972 // open other connections to alternative server. The Job to server fails, so
bnc5452e2a2015-05-08 16:27:4214973 // this request fails.
bnc5452e2a2015-05-08 16:27:4214974 HttpRequestInfo request2;
krasinc06a72a2016-12-21 03:42:4614975 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
bnc5452e2a2015-05-08 16:27:4214976 request2.method = "GET";
14977 request2.url = GURL(origin_url);
14978 request2.load_flags = 0;
14979 TestCompletionCallback callback2;
14980
tfarina42834112016-09-22 13:38:2014981 rv = trans2.Start(&request2, callback2.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0114982 EXPECT_THAT(callback2.GetResult(rv), IsError(ERR_CONNECTION_REFUSED));
bnc5452e2a2015-05-08 16:27:4214983
14984 // Another transaction to alternative. This is to test that the HTTP/1.1
14985 // socket is still open and in the pool.
bnc5452e2a2015-05-08 16:27:4214986 HttpRequestInfo request3;
krasinc06a72a2016-12-21 03:42:4614987 HttpNetworkTransaction trans3(DEFAULT_PRIORITY, session.get());
bnc5452e2a2015-05-08 16:27:4214988 request3.method = "GET";
14989 request3.url = GURL(alternative_url);
14990 request3.load_flags = 0;
14991 TestCompletionCallback callback3;
14992
tfarina42834112016-09-22 13:38:2014993 rv = trans3.Start(&request3, callback3.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0114994 EXPECT_THAT(callback3.GetResult(rv), IsOk());
bnc691fda62016-08-12 00:43:1614995 const HttpResponseInfo* response3 = trans3.GetResponseInfo();
bnc5452e2a2015-05-08 16:27:4214996 ASSERT_TRUE(response3);
wezca1070932016-05-26 20:30:5214997 ASSERT_TRUE(response3->headers);
bnc5452e2a2015-05-08 16:27:4214998 EXPECT_EQ("HTTP/1.1 200 OK", response3->headers->GetStatusLine());
bnc94c92842016-09-21 15:22:5214999 EXPECT_TRUE(response3->was_alpn_negotiated);
bnc5452e2a2015-05-08 16:27:4215000 EXPECT_FALSE(response3->was_fetched_via_spdy);
15001 std::string response_data3;
bnc691fda62016-08-12 00:43:1615002 ASSERT_THAT(ReadTransaction(&trans3, &response_data3), IsOk());
bnc5452e2a2015-05-08 16:27:4215003 EXPECT_EQ("second HTTP/1.1 response from alternative", response_data3);
15004}
15005
bncd16676a2016-07-20 16:23:0115006TEST_F(HttpNetworkTransactionTest, DoNotUseSpdySessionForHttpOverTunnel) {
bncce36dca22015-04-21 22:11:2315007 const std::string https_url = "https://www.example.org:8080/";
15008 const std::string http_url = "http://www.example.org:8080/";
[email protected]8450d722012-07-02 19:14:0415009
rdsmithebb50aa2015-11-12 03:44:3815010 // Separate SPDY util instance for naked and wrapped requests.
bncd16676a2016-07-20 16:23:0115011 SpdyTestUtil spdy_util_wrapped;
rdsmithebb50aa2015-11-12 03:44:3815012
[email protected]8450d722012-07-02 19:14:0415013 // SPDY GET for HTTPS URL (through CONNECT tunnel)
bncce36dca22015-04-21 22:11:2315014 const HostPortPair host_port_pair("www.example.org", 8080);
bncdf80d44fd2016-07-15 20:27:4115015 SpdySerializedFrame connect(
lgarrona91df87f2014-12-05 00:51:3415016 spdy_util_.ConstructSpdyConnect(NULL, 0, 1, LOWEST, host_port_pair));
bncdf80d44fd2016-07-15 20:27:4115017 SpdySerializedFrame req1(
bnc38dcd392016-02-09 23:19:4915018 spdy_util_wrapped.ConstructSpdyGet(https_url.c_str(), 1, LOWEST));
bncdf80d44fd2016-07-15 20:27:4115019 SpdySerializedFrame wrapped_req1(
[email protected]23e482282013-06-14 16:08:0215020 spdy_util_.ConstructWrappedSpdyFrame(req1, 1));
[email protected]601e03f12014-04-06 16:26:3915021
15022 // SPDY GET for HTTP URL (through the proxy, but not the tunnel).
[email protected]745aa9c2014-06-27 02:21:2915023 SpdyHeaderBlock req2_block;
Bence Békybda82952017-10-02 17:35:2715024 req2_block[kHttp2MethodHeader] = "GET";
15025 req2_block[kHttp2AuthorityHeader] = "www.example.org:8080";
15026 req2_block[kHttp2SchemeHeader] = "http";
15027 req2_block[kHttp2PathHeader] = "/";
bncdf80d44fd2016-07-15 20:27:4115028 SpdySerializedFrame req2(
bnc42331402016-07-25 13:36:1515029 spdy_util_.ConstructSpdyHeaders(3, std::move(req2_block), MEDIUM, true));
[email protected]8450d722012-07-02 19:14:0415030
15031 MockWrite writes1[] = {
bncdf80d44fd2016-07-15 20:27:4115032 CreateMockWrite(connect, 0), CreateMockWrite(wrapped_req1, 2),
15033 CreateMockWrite(req2, 6),
[email protected]8450d722012-07-02 19:14:0415034 };
15035
bncdf80d44fd2016-07-15 20:27:4115036 SpdySerializedFrame conn_resp(
bnc42331402016-07-25 13:36:1515037 spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
bncdf80d44fd2016-07-15 20:27:4115038 SpdySerializedFrame resp1(
bnc42331402016-07-25 13:36:1515039 spdy_util_wrapped.ConstructSpdyGetReply(nullptr, 0, 1));
bncdf80d44fd2016-07-15 20:27:4115040 SpdySerializedFrame body1(spdy_util_wrapped.ConstructSpdyDataFrame(1, true));
15041 SpdySerializedFrame wrapped_resp1(
rdsmithebb50aa2015-11-12 03:44:3815042 spdy_util_wrapped.ConstructWrappedSpdyFrame(resp1, 1));
bncdf80d44fd2016-07-15 20:27:4115043 SpdySerializedFrame wrapped_body1(
rdsmithebb50aa2015-11-12 03:44:3815044 spdy_util_wrapped.ConstructWrappedSpdyFrame(body1, 1));
bnc42331402016-07-25 13:36:1515045 SpdySerializedFrame resp2(spdy_util_.ConstructSpdyGetReply(NULL, 0, 3));
bncdf80d44fd2016-07-15 20:27:4115046 SpdySerializedFrame body2(spdy_util_.ConstructSpdyDataFrame(3, true));
mmenke666a6fea2015-12-19 04:16:3315047 MockRead reads1[] = {
bncdf80d44fd2016-07-15 20:27:4115048 CreateMockRead(conn_resp, 1),
mmenke666a6fea2015-12-19 04:16:3315049 MockRead(ASYNC, ERR_IO_PENDING, 3),
bncdf80d44fd2016-07-15 20:27:4115050 CreateMockRead(wrapped_resp1, 4),
15051 CreateMockRead(wrapped_body1, 5),
mmenke666a6fea2015-12-19 04:16:3315052 MockRead(ASYNC, ERR_IO_PENDING, 7),
bncdf80d44fd2016-07-15 20:27:4115053 CreateMockRead(resp2, 8),
15054 CreateMockRead(body2, 9),
mmenke666a6fea2015-12-19 04:16:3315055 MockRead(SYNCHRONOUS, ERR_IO_PENDING, 10),
15056 };
[email protected]8450d722012-07-02 19:14:0415057
mmenke666a6fea2015-12-19 04:16:3315058 SequencedSocketData data1(reads1, arraysize(reads1), writes1,
15059 arraysize(writes1));
[email protected]8450d722012-07-02 19:14:0415060 MockConnect connect_data1(ASYNC, OK);
[email protected]dd54bd82012-07-19 23:44:5715061 data1.set_connect_data(connect_data1);
[email protected]8450d722012-07-02 19:14:0415062
rdsmith82957ad2015-09-16 19:42:0315063 session_deps_.proxy_service =
15064 ProxyService::CreateFixedFromPacResult("HTTPS proxy:70");
vishal.b62985ca92015-04-17 08:45:5115065 TestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:0715066 session_deps_.net_log = &log;
[email protected]8450d722012-07-02 19:14:0415067 SSLSocketDataProvider ssl1(ASYNC, OK); // to the proxy
bnc3cf2a592016-08-11 14:48:3615068 ssl1.next_proto = kProtoHTTP2;
mmenke666a6fea2015-12-19 04:16:3315069 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl1);
[email protected]8450d722012-07-02 19:14:0415070 SSLSocketDataProvider ssl2(ASYNC, OK); // to the server
bnc3cf2a592016-08-11 14:48:3615071 ssl2.next_proto = kProtoHTTP2;
mmenke666a6fea2015-12-19 04:16:3315072 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
15073 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8450d722012-07-02 19:14:0415074
danakj1fd259a02016-04-16 03:17:0915075 std::unique_ptr<HttpNetworkSession> session = CreateSession(&session_deps_);
[email protected]8450d722012-07-02 19:14:0415076
15077 // Start the first transaction to set up the SpdySession
15078 HttpRequestInfo request1;
15079 request1.method = "GET";
15080 request1.url = GURL(https_url);
[email protected]8450d722012-07-02 19:14:0415081 request1.load_flags = 0;
[email protected]90499482013-06-01 00:39:5015082 HttpNetworkTransaction trans1(LOWEST, session.get());
[email protected]8450d722012-07-02 19:14:0415083 TestCompletionCallback callback1;
tfarina42834112016-09-22 13:38:2015084 int rv = trans1.Start(&request1, callback1.callback(), NetLogWithSource());
[email protected]8450d722012-07-02 19:14:0415085
mmenke666a6fea2015-12-19 04:16:3315086 // This pause is a hack to avoid running into https://crbug.com/497228.
15087 data1.RunUntilPaused();
15088 base::RunLoop().RunUntilIdle();
15089 data1.Resume();
robpercival214763f2016-07-01 23:27:0115090 EXPECT_THAT(callback1.GetResult(rv), IsOk());
[email protected]8450d722012-07-02 19:14:0415091 EXPECT_TRUE(trans1.GetResponseInfo()->was_fetched_via_spdy);
15092
[email protected]f6c63db52013-02-02 00:35:2215093 LoadTimingInfo load_timing_info1;
15094 EXPECT_TRUE(trans1.GetLoadTimingInfo(&load_timing_info1));
15095 TestLoadTimingNotReusedWithPac(load_timing_info1,
15096 CONNECT_TIMING_HAS_SSL_TIMES);
15097
mmenke666a6fea2015-12-19 04:16:3315098 // Now, start the HTTP request.
[email protected]8450d722012-07-02 19:14:0415099 HttpRequestInfo request2;
15100 request2.method = "GET";
15101 request2.url = GURL(http_url);
[email protected]8450d722012-07-02 19:14:0415102 request2.load_flags = 0;
[email protected]90499482013-06-01 00:39:5015103 HttpNetworkTransaction trans2(MEDIUM, session.get());
[email protected]8450d722012-07-02 19:14:0415104 TestCompletionCallback callback2;
tfarina42834112016-09-22 13:38:2015105 rv = trans2.Start(&request2, callback2.callback(), NetLogWithSource());
[email protected]8450d722012-07-02 19:14:0415106
mmenke666a6fea2015-12-19 04:16:3315107 // This pause is a hack to avoid running into https://crbug.com/497228.
15108 data1.RunUntilPaused();
15109 base::RunLoop().RunUntilIdle();
15110 data1.Resume();
robpercival214763f2016-07-01 23:27:0115111 EXPECT_THAT(callback2.GetResult(rv), IsOk());
mmenke666a6fea2015-12-19 04:16:3315112
[email protected]8450d722012-07-02 19:14:0415113 EXPECT_TRUE(trans2.GetResponseInfo()->was_fetched_via_spdy);
[email protected]f6c63db52013-02-02 00:35:2215114
15115 LoadTimingInfo load_timing_info2;
15116 EXPECT_TRUE(trans2.GetLoadTimingInfo(&load_timing_info2));
15117 // The established SPDY sessions is considered reused by the HTTP request.
15118 TestLoadTimingReusedWithPac(load_timing_info2);
15119 // HTTP requests over a SPDY session should have a different connection
15120 // socket_log_id than requests over a tunnel.
15121 EXPECT_NE(load_timing_info1.socket_log_id, load_timing_info2.socket_log_id);
[email protected]8450d722012-07-02 19:14:0415122}
15123
[email protected]2d88e7d2012-07-19 17:55:1715124// Test that in the case where we have a SPDY session to a SPDY proxy
15125// that we do not pool other origins that resolve to the same IP when
15126// the certificate does not match the new origin.
15127// http://crbug.com/134690
bncd16676a2016-07-20 16:23:0115128TEST_F(HttpNetworkTransactionTest, DoNotUseSpdySessionIfCertDoesNotMatch) {
bncce36dca22015-04-21 22:11:2315129 const std::string url1 = "http://www.example.org/";
15130 const std::string url2 = "https://news.example.org/";
[email protected]2d88e7d2012-07-19 17:55:1715131 const std::string ip_addr = "1.2.3.4";
15132
rdsmithebb50aa2015-11-12 03:44:3815133 // Second SpdyTestUtil instance for the second socket.
bncd16676a2016-07-20 16:23:0115134 SpdyTestUtil spdy_util_secure;
rdsmithebb50aa2015-11-12 03:44:3815135
[email protected]2d88e7d2012-07-19 17:55:1715136 // SPDY GET for HTTP URL (through SPDY proxy)
bnc086b39e12016-06-24 13:05:2615137 SpdyHeaderBlock headers(
bncce36dca22015-04-21 22:11:2315138 spdy_util_.ConstructGetHeaderBlockForProxy("http://www.example.org/"));
bncdf80d44fd2016-07-15 20:27:4115139 SpdySerializedFrame req1(
bnc42331402016-07-25 13:36:1515140 spdy_util_.ConstructSpdyHeaders(1, std::move(headers), LOWEST, true));
[email protected]2d88e7d2012-07-19 17:55:1715141
15142 MockWrite writes1[] = {
bncdf80d44fd2016-07-15 20:27:4115143 CreateMockWrite(req1, 0),
[email protected]2d88e7d2012-07-19 17:55:1715144 };
15145
bnc42331402016-07-25 13:36:1515146 SpdySerializedFrame resp1(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
bncdf80d44fd2016-07-15 20:27:4115147 SpdySerializedFrame body1(spdy_util_.ConstructSpdyDataFrame(1, true));
[email protected]2d88e7d2012-07-19 17:55:1715148 MockRead reads1[] = {
bncdf80d44fd2016-07-15 20:27:4115149 MockRead(ASYNC, ERR_IO_PENDING, 1), CreateMockRead(resp1, 2),
15150 CreateMockRead(body1, 3), MockRead(ASYNC, OK, 4), // EOF
[email protected]2d88e7d2012-07-19 17:55:1715151 };
15152
mmenke666a6fea2015-12-19 04:16:3315153 SequencedSocketData data1(reads1, arraysize(reads1), writes1,
15154 arraysize(writes1));
martijnfe9636e2016-02-06 14:33:3215155 IPAddress ip;
martijn654c8c42016-02-10 22:10:5915156 ASSERT_TRUE(ip.AssignFromIPLiteral(ip_addr));
[email protected]2d88e7d2012-07-19 17:55:1715157 IPEndPoint peer_addr = IPEndPoint(ip, 443);
15158 MockConnect connect_data1(ASYNC, OK, peer_addr);
mmenke666a6fea2015-12-19 04:16:3315159 data1.set_connect_data(connect_data1);
[email protected]2d88e7d2012-07-19 17:55:1715160
15161 // SPDY GET for HTTPS URL (direct)
bncdf80d44fd2016-07-15 20:27:4115162 SpdySerializedFrame req2(
bnc38dcd392016-02-09 23:19:4915163 spdy_util_secure.ConstructSpdyGet(url2.c_str(), 1, MEDIUM));
[email protected]2d88e7d2012-07-19 17:55:1715164
15165 MockWrite writes2[] = {
bncdf80d44fd2016-07-15 20:27:4115166 CreateMockWrite(req2, 0),
[email protected]2d88e7d2012-07-19 17:55:1715167 };
15168
bnc42331402016-07-25 13:36:1515169 SpdySerializedFrame resp2(spdy_util_secure.ConstructSpdyGetReply(NULL, 0, 1));
bncdf80d44fd2016-07-15 20:27:4115170 SpdySerializedFrame body2(spdy_util_secure.ConstructSpdyDataFrame(1, true));
15171 MockRead reads2[] = {CreateMockRead(resp2, 1), CreateMockRead(body2, 2),
mmenke666a6fea2015-12-19 04:16:3315172 MockRead(ASYNC, OK, 3)};
[email protected]2d88e7d2012-07-19 17:55:1715173
mmenke666a6fea2015-12-19 04:16:3315174 SequencedSocketData data2(reads2, arraysize(reads2), writes2,
15175 arraysize(writes2));
[email protected]2d88e7d2012-07-19 17:55:1715176 MockConnect connect_data2(ASYNC, OK);
mmenke666a6fea2015-12-19 04:16:3315177 data2.set_connect_data(connect_data2);
[email protected]2d88e7d2012-07-19 17:55:1715178
15179 // Set up a proxy config that sends HTTP requests to a proxy, and
15180 // all others direct.
15181 ProxyConfig proxy_config;
15182 proxy_config.proxy_rules().ParseFromString("http=https://proxy:443");
Jeremy Roman0579ed62017-08-29 15:56:1915183 session_deps_.proxy_service = std::make_unique<ProxyService>(
15184 std::make_unique<ProxyConfigServiceFixed>(proxy_config), nullptr,
bnc87dcefc2017-05-25 12:47:5815185 nullptr);
[email protected]2d88e7d2012-07-19 17:55:1715186
bncce36dca22015-04-21 22:11:2315187 SSLSocketDataProvider ssl1(ASYNC, OK); // to the proxy
bnc3cf2a592016-08-11 14:48:3615188 ssl1.next_proto = kProtoHTTP2;
[email protected]2d88e7d2012-07-19 17:55:1715189 // Load a valid cert. Note, that this does not need to
15190 // be valid for proxy because the MockSSLClientSocket does
15191 // not actually verify it. But SpdySession will use this
15192 // to see if it is valid for the new origin
Ryan Sleevi4f832092017-11-21 23:25:4915193 ssl1.ssl_info.cert =
15194 ImportCertFromFile(GetTestCertsDirectory(), "ok_cert.pem");
15195 ASSERT_TRUE(ssl1.ssl_info.cert);
mmenke666a6fea2015-12-19 04:16:3315196 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl1);
15197 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]2d88e7d2012-07-19 17:55:1715198
15199 SSLSocketDataProvider ssl2(ASYNC, OK); // to the server
bnc3cf2a592016-08-11 14:48:3615200 ssl2.next_proto = kProtoHTTP2;
mmenke666a6fea2015-12-19 04:16:3315201 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
15202 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]2d88e7d2012-07-19 17:55:1715203
Jeremy Roman0579ed62017-08-29 15:56:1915204 session_deps_.host_resolver = std::make_unique<MockCachingHostResolver>();
bncce36dca22015-04-21 22:11:2315205 session_deps_.host_resolver->rules()->AddRule("news.example.org", ip_addr);
[email protected]bb88e1d32013-05-03 23:11:0715206 session_deps_.host_resolver->rules()->AddRule("proxy", ip_addr);
[email protected]2d88e7d2012-07-19 17:55:1715207
danakj1fd259a02016-04-16 03:17:0915208 std::unique_ptr<HttpNetworkSession> session = CreateSession(&session_deps_);
[email protected]2d88e7d2012-07-19 17:55:1715209
15210 // Start the first transaction to set up the SpdySession
15211 HttpRequestInfo request1;
15212 request1.method = "GET";
15213 request1.url = GURL(url1);
[email protected]2d88e7d2012-07-19 17:55:1715214 request1.load_flags = 0;
[email protected]90499482013-06-01 00:39:5015215 HttpNetworkTransaction trans1(LOWEST, session.get());
[email protected]2d88e7d2012-07-19 17:55:1715216 TestCompletionCallback callback1;
15217 ASSERT_EQ(ERR_IO_PENDING,
tfarina42834112016-09-22 13:38:2015218 trans1.Start(&request1, callback1.callback(), NetLogWithSource()));
mmenke666a6fea2015-12-19 04:16:3315219 // This pause is a hack to avoid running into https://crbug.com/497228.
15220 data1.RunUntilPaused();
15221 base::RunLoop().RunUntilIdle();
15222 data1.Resume();
[email protected]2d88e7d2012-07-19 17:55:1715223
robpercival214763f2016-07-01 23:27:0115224 EXPECT_THAT(callback1.WaitForResult(), IsOk());
[email protected]2d88e7d2012-07-19 17:55:1715225 EXPECT_TRUE(trans1.GetResponseInfo()->was_fetched_via_spdy);
15226
15227 // Now, start the HTTP request
15228 HttpRequestInfo request2;
15229 request2.method = "GET";
15230 request2.url = GURL(url2);
[email protected]2d88e7d2012-07-19 17:55:1715231 request2.load_flags = 0;
[email protected]90499482013-06-01 00:39:5015232 HttpNetworkTransaction trans2(MEDIUM, session.get());
[email protected]2d88e7d2012-07-19 17:55:1715233 TestCompletionCallback callback2;
15234 EXPECT_EQ(ERR_IO_PENDING,
tfarina42834112016-09-22 13:38:2015235 trans2.Start(&request2, callback2.callback(), NetLogWithSource()));
fdoray92e35a72016-06-10 15:54:5515236 base::RunLoop().RunUntilIdle();
[email protected]2d88e7d2012-07-19 17:55:1715237
15238 ASSERT_TRUE(callback2.have_result());
robpercival214763f2016-07-01 23:27:0115239 EXPECT_THAT(callback2.WaitForResult(), IsOk());
[email protected]2d88e7d2012-07-19 17:55:1715240 EXPECT_TRUE(trans2.GetResponseInfo()->was_fetched_via_spdy);
15241}
15242
[email protected]85f97342013-04-17 06:12:2415243// Test to verify that a failed socket read (due to an ERR_CONNECTION_CLOSED
15244// error) in SPDY session, removes the socket from pool and closes the SPDY
15245// session. Verify that new url's from the same HttpNetworkSession (and a new
15246// SpdySession) do work. http://crbug.com/224701
bncd16676a2016-07-20 16:23:0115247TEST_F(HttpNetworkTransactionTest, ErrorSocketNotConnected) {
bncce36dca22015-04-21 22:11:2315248 const std::string https_url = "https://www.example.org/";
[email protected]85f97342013-04-17 06:12:2415249
15250 MockRead reads1[] = {
15251 MockRead(SYNCHRONOUS, ERR_CONNECTION_CLOSED, 0)
15252 };
15253
mmenke11eb5152015-06-09 14:50:5015254 SequencedSocketData data1(reads1, arraysize(reads1), NULL, 0);
[email protected]85f97342013-04-17 06:12:2415255
bncdf80d44fd2016-07-15 20:27:4115256 SpdySerializedFrame req2(
bnc38dcd392016-02-09 23:19:4915257 spdy_util_.ConstructSpdyGet(https_url.c_str(), 1, MEDIUM));
[email protected]85f97342013-04-17 06:12:2415258 MockWrite writes2[] = {
bncdf80d44fd2016-07-15 20:27:4115259 CreateMockWrite(req2, 0),
[email protected]85f97342013-04-17 06:12:2415260 };
15261
bnc42331402016-07-25 13:36:1515262 SpdySerializedFrame resp2(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
bncdf80d44fd2016-07-15 20:27:4115263 SpdySerializedFrame body2(spdy_util_.ConstructSpdyDataFrame(1, true));
[email protected]85f97342013-04-17 06:12:2415264 MockRead reads2[] = {
bncdf80d44fd2016-07-15 20:27:4115265 CreateMockRead(resp2, 1), CreateMockRead(body2, 2),
15266 MockRead(ASYNC, OK, 3) // EOF
[email protected]85f97342013-04-17 06:12:2415267 };
15268
mmenke11eb5152015-06-09 14:50:5015269 SequencedSocketData data2(reads2, arraysize(reads2), writes2,
15270 arraysize(writes2));
[email protected]85f97342013-04-17 06:12:2415271
[email protected]85f97342013-04-17 06:12:2415272 SSLSocketDataProvider ssl1(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3615273 ssl1.next_proto = kProtoHTTP2;
mmenke11eb5152015-06-09 14:50:5015274 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl1);
15275 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]85f97342013-04-17 06:12:2415276
15277 SSLSocketDataProvider ssl2(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3615278 ssl2.next_proto = kProtoHTTP2;
mmenke11eb5152015-06-09 14:50:5015279 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
15280 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]85f97342013-04-17 06:12:2415281
danakj1fd259a02016-04-16 03:17:0915282 std::unique_ptr<HttpNetworkSession> session(
mmenke11eb5152015-06-09 14:50:5015283 SpdySessionDependencies::SpdyCreateSession(&session_deps_));
[email protected]85f97342013-04-17 06:12:2415284
15285 // Start the first transaction to set up the SpdySession and verify that
15286 // connection was closed.
15287 HttpRequestInfo request1;
15288 request1.method = "GET";
15289 request1.url = GURL(https_url);
15290 request1.load_flags = 0;
[email protected]90499482013-06-01 00:39:5015291 HttpNetworkTransaction trans1(MEDIUM, session.get());
[email protected]85f97342013-04-17 06:12:2415292 TestCompletionCallback callback1;
15293 EXPECT_EQ(ERR_IO_PENDING,
tfarina42834112016-09-22 13:38:2015294 trans1.Start(&request1, callback1.callback(), NetLogWithSource()));
robpercival214763f2016-07-01 23:27:0115295 EXPECT_THAT(callback1.WaitForResult(), IsError(ERR_CONNECTION_CLOSED));
[email protected]85f97342013-04-17 06:12:2415296
15297 // Now, start the second request and make sure it succeeds.
15298 HttpRequestInfo request2;
15299 request2.method = "GET";
15300 request2.url = GURL(https_url);
15301 request2.load_flags = 0;
[email protected]90499482013-06-01 00:39:5015302 HttpNetworkTransaction trans2(MEDIUM, session.get());
[email protected]85f97342013-04-17 06:12:2415303 TestCompletionCallback callback2;
15304 EXPECT_EQ(ERR_IO_PENDING,
tfarina42834112016-09-22 13:38:2015305 trans2.Start(&request2, callback2.callback(), NetLogWithSource()));
[email protected]85f97342013-04-17 06:12:2415306
robpercival214763f2016-07-01 23:27:0115307 ASSERT_THAT(callback2.WaitForResult(), IsOk());
[email protected]85f97342013-04-17 06:12:2415308 EXPECT_TRUE(trans2.GetResponseInfo()->was_fetched_via_spdy);
15309}
15310
bncd16676a2016-07-20 16:23:0115311TEST_F(HttpNetworkTransactionTest, CloseIdleSpdySessionToOpenNewOne) {
[email protected]483fa202013-05-14 01:07:0315312 ClientSocketPoolManager::set_max_sockets_per_group(
15313 HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
15314 ClientSocketPoolManager::set_max_sockets_per_pool(
15315 HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
15316
15317 // Use two different hosts with different IPs so they don't get pooled.
15318 session_deps_.host_resolver->rules()->AddRule("www.a.com", "10.0.0.1");
15319 session_deps_.host_resolver->rules()->AddRule("www.b.com", "10.0.0.2");
danakj1fd259a02016-04-16 03:17:0915320 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]483fa202013-05-14 01:07:0315321
15322 SSLSocketDataProvider ssl1(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3615323 ssl1.next_proto = kProtoHTTP2;
[email protected]483fa202013-05-14 01:07:0315324 SSLSocketDataProvider ssl2(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3615325 ssl2.next_proto = kProtoHTTP2;
[email protected]483fa202013-05-14 01:07:0315326 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl1);
15327 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
15328
bncdf80d44fd2016-07-15 20:27:4115329 SpdySerializedFrame host1_req(
bnc38dcd392016-02-09 23:19:4915330 spdy_util_.ConstructSpdyGet("https://www.a.com", 1, DEFAULT_PRIORITY));
[email protected]483fa202013-05-14 01:07:0315331 MockWrite spdy1_writes[] = {
bncdf80d44fd2016-07-15 20:27:4115332 CreateMockWrite(host1_req, 0),
[email protected]483fa202013-05-14 01:07:0315333 };
bnc42331402016-07-25 13:36:1515334 SpdySerializedFrame host1_resp(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
bncdf80d44fd2016-07-15 20:27:4115335 SpdySerializedFrame host1_resp_body(
15336 spdy_util_.ConstructSpdyDataFrame(1, true));
[email protected]483fa202013-05-14 01:07:0315337 MockRead spdy1_reads[] = {
bncdf80d44fd2016-07-15 20:27:4115338 CreateMockRead(host1_resp, 1), CreateMockRead(host1_resp_body, 2),
mmenkee24011922015-12-17 22:12:5915339 MockRead(SYNCHRONOUS, ERR_IO_PENDING, 3),
[email protected]483fa202013-05-14 01:07:0315340 };
15341
rdsmithebb50aa2015-11-12 03:44:3815342 // Use a separate test instance for the separate SpdySession that will be
15343 // created.
bncd16676a2016-07-20 16:23:0115344 SpdyTestUtil spdy_util_2;
Jeremy Roman0579ed62017-08-29 15:56:1915345 auto spdy1_data = std::make_unique<SequencedSocketData>(
bnc87dcefc2017-05-25 12:47:5815346 spdy1_reads, arraysize(spdy1_reads), spdy1_writes,
15347 arraysize(spdy1_writes));
[email protected]483fa202013-05-14 01:07:0315348 session_deps_.socket_factory->AddSocketDataProvider(spdy1_data.get());
15349
bncdf80d44fd2016-07-15 20:27:4115350 SpdySerializedFrame host2_req(
bnc38dcd392016-02-09 23:19:4915351 spdy_util_2.ConstructSpdyGet("https://www.b.com", 1, DEFAULT_PRIORITY));
[email protected]483fa202013-05-14 01:07:0315352 MockWrite spdy2_writes[] = {
bncdf80d44fd2016-07-15 20:27:4115353 CreateMockWrite(host2_req, 0),
[email protected]483fa202013-05-14 01:07:0315354 };
bnc42331402016-07-25 13:36:1515355 SpdySerializedFrame host2_resp(spdy_util_2.ConstructSpdyGetReply(NULL, 0, 1));
bncdf80d44fd2016-07-15 20:27:4115356 SpdySerializedFrame host2_resp_body(
15357 spdy_util_2.ConstructSpdyDataFrame(1, true));
[email protected]483fa202013-05-14 01:07:0315358 MockRead spdy2_reads[] = {
bncdf80d44fd2016-07-15 20:27:4115359 CreateMockRead(host2_resp, 1), CreateMockRead(host2_resp_body, 2),
mmenkee24011922015-12-17 22:12:5915360 MockRead(SYNCHRONOUS, ERR_IO_PENDING, 3),
[email protected]483fa202013-05-14 01:07:0315361 };
15362
Jeremy Roman0579ed62017-08-29 15:56:1915363 auto spdy2_data = std::make_unique<SequencedSocketData>(
bnc87dcefc2017-05-25 12:47:5815364 spdy2_reads, arraysize(spdy2_reads), spdy2_writes,
15365 arraysize(spdy2_writes));
[email protected]483fa202013-05-14 01:07:0315366 session_deps_.socket_factory->AddSocketDataProvider(spdy2_data.get());
15367
15368 MockWrite http_write[] = {
15369 MockWrite("GET / HTTP/1.1\r\n"
15370 "Host: www.a.com\r\n"
15371 "Connection: keep-alive\r\n\r\n"),
15372 };
15373
15374 MockRead http_read[] = {
15375 MockRead("HTTP/1.1 200 OK\r\n"),
15376 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
15377 MockRead("Content-Length: 6\r\n\r\n"),
15378 MockRead("hello!"),
15379 };
15380 StaticSocketDataProvider http_data(http_read, arraysize(http_read),
15381 http_write, arraysize(http_write));
15382 session_deps_.socket_factory->AddSocketDataProvider(&http_data);
15383
15384 HostPortPair host_port_pair_a("www.a.com", 443);
Paul Jensena457017a2018-01-19 23:52:0415385 SpdySessionKey spdy_session_key_a(host_port_pair_a, ProxyServer::Direct(),
15386 PRIVACY_MODE_DISABLED, SocketTag());
[email protected]483fa202013-05-14 01:07:0315387 EXPECT_FALSE(
[email protected]41d64e82013-07-03 22:44:2615388 HasSpdySession(session->spdy_session_pool(), spdy_session_key_a));
[email protected]483fa202013-05-14 01:07:0315389
15390 TestCompletionCallback callback;
15391 HttpRequestInfo request1;
15392 request1.method = "GET";
15393 request1.url = GURL("https://www.a.com/");
15394 request1.load_flags = 0;
bnc87dcefc2017-05-25 12:47:5815395 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:1915396 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]483fa202013-05-14 01:07:0315397
tfarina42834112016-09-22 13:38:2015398 int rv = trans->Start(&request1, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0115399 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
15400 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]483fa202013-05-14 01:07:0315401
15402 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5215403 ASSERT_TRUE(response);
15404 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0215405 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]483fa202013-05-14 01:07:0315406 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5215407 EXPECT_TRUE(response->was_alpn_negotiated);
[email protected]483fa202013-05-14 01:07:0315408
15409 std::string response_data;
robpercival214763f2016-07-01 23:27:0115410 ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
[email protected]483fa202013-05-14 01:07:0315411 EXPECT_EQ("hello!", response_data);
15412 trans.reset();
15413 EXPECT_TRUE(
[email protected]41d64e82013-07-03 22:44:2615414 HasSpdySession(session->spdy_session_pool(), spdy_session_key_a));
[email protected]483fa202013-05-14 01:07:0315415
15416 HostPortPair host_port_pair_b("www.b.com", 443);
Paul Jensena457017a2018-01-19 23:52:0415417 SpdySessionKey spdy_session_key_b(host_port_pair_b, ProxyServer::Direct(),
15418 PRIVACY_MODE_DISABLED, SocketTag());
[email protected]483fa202013-05-14 01:07:0315419 EXPECT_FALSE(
[email protected]41d64e82013-07-03 22:44:2615420 HasSpdySession(session->spdy_session_pool(), spdy_session_key_b));
[email protected]483fa202013-05-14 01:07:0315421 HttpRequestInfo request2;
15422 request2.method = "GET";
15423 request2.url = GURL("https://www.b.com/");
15424 request2.load_flags = 0;
bnc87dcefc2017-05-25 12:47:5815425 trans =
Jeremy Roman0579ed62017-08-29 15:56:1915426 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]483fa202013-05-14 01:07:0315427
tfarina42834112016-09-22 13:38:2015428 rv = trans->Start(&request2, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0115429 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
15430 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]483fa202013-05-14 01:07:0315431
15432 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5215433 ASSERT_TRUE(response);
15434 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0215435 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]483fa202013-05-14 01:07:0315436 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5215437 EXPECT_TRUE(response->was_alpn_negotiated);
robpercival214763f2016-07-01 23:27:0115438 ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
[email protected]483fa202013-05-14 01:07:0315439 EXPECT_EQ("hello!", response_data);
15440 EXPECT_FALSE(
[email protected]41d64e82013-07-03 22:44:2615441 HasSpdySession(session->spdy_session_pool(), spdy_session_key_a));
[email protected]483fa202013-05-14 01:07:0315442 EXPECT_TRUE(
[email protected]41d64e82013-07-03 22:44:2615443 HasSpdySession(session->spdy_session_pool(), spdy_session_key_b));
[email protected]483fa202013-05-14 01:07:0315444
15445 HostPortPair host_port_pair_a1("www.a.com", 80);
Paul Jensena457017a2018-01-19 23:52:0415446 SpdySessionKey spdy_session_key_a1(host_port_pair_a1, ProxyServer::Direct(),
15447 PRIVACY_MODE_DISABLED, SocketTag());
[email protected]483fa202013-05-14 01:07:0315448 EXPECT_FALSE(
[email protected]41d64e82013-07-03 22:44:2615449 HasSpdySession(session->spdy_session_pool(), spdy_session_key_a1));
[email protected]483fa202013-05-14 01:07:0315450 HttpRequestInfo request3;
15451 request3.method = "GET";
15452 request3.url = GURL("http://www.a.com/");
15453 request3.load_flags = 0;
bnc87dcefc2017-05-25 12:47:5815454 trans =
Jeremy Roman0579ed62017-08-29 15:56:1915455 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]483fa202013-05-14 01:07:0315456
tfarina42834112016-09-22 13:38:2015457 rv = trans->Start(&request3, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0115458 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
15459 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]483fa202013-05-14 01:07:0315460
15461 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5215462 ASSERT_TRUE(response);
15463 ASSERT_TRUE(response->headers);
[email protected]483fa202013-05-14 01:07:0315464 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
15465 EXPECT_FALSE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5215466 EXPECT_FALSE(response->was_alpn_negotiated);
robpercival214763f2016-07-01 23:27:0115467 ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
[email protected]483fa202013-05-14 01:07:0315468 EXPECT_EQ("hello!", response_data);
15469 EXPECT_FALSE(
[email protected]41d64e82013-07-03 22:44:2615470 HasSpdySession(session->spdy_session_pool(), spdy_session_key_a));
[email protected]483fa202013-05-14 01:07:0315471 EXPECT_FALSE(
[email protected]41d64e82013-07-03 22:44:2615472 HasSpdySession(session->spdy_session_pool(), spdy_session_key_b));
[email protected]483fa202013-05-14 01:07:0315473}
15474
bncd16676a2016-07-20 16:23:0115475TEST_F(HttpNetworkTransactionTest, HttpSyncConnectError) {
[email protected]79e1fd62013-06-20 06:50:0415476 HttpRequestInfo request;
15477 request.method = "GET";
bncce36dca22015-04-21 22:11:2315478 request.url = GURL("http://www.example.org/");
[email protected]79e1fd62013-06-20 06:50:0415479
danakj1fd259a02016-04-16 03:17:0915480 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1615481 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]79e1fd62013-06-20 06:50:0415482
ttuttled9dbc652015-09-29 20:00:5915483 MockConnect mock_connect(SYNCHRONOUS, ERR_NAME_NOT_RESOLVED);
[email protected]79e1fd62013-06-20 06:50:0415484 StaticSocketDataProvider data;
15485 data.set_connect_data(mock_connect);
15486 session_deps_.socket_factory->AddSocketDataProvider(&data);
15487
15488 TestCompletionCallback callback;
15489
tfarina42834112016-09-22 13:38:2015490 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0115491 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]79e1fd62013-06-20 06:50:0415492
15493 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0115494 EXPECT_THAT(rv, IsError(ERR_NAME_NOT_RESOLVED));
[email protected]79e1fd62013-06-20 06:50:0415495
[email protected]79e1fd62013-06-20 06:50:0415496 // We don't care whether this succeeds or fails, but it shouldn't crash.
15497 HttpRequestHeaders request_headers;
bnc691fda62016-08-12 00:43:1615498 trans.GetFullRequestHeaders(&request_headers);
ttuttle1f2d7e92015-04-28 16:17:4715499
15500 ConnectionAttempts attempts;
bnc691fda62016-08-12 00:43:1615501 trans.GetConnectionAttempts(&attempts);
ttuttle1f2d7e92015-04-28 16:17:4715502 ASSERT_EQ(1u, attempts.size());
robpercival214763f2016-07-01 23:27:0115503 EXPECT_THAT(attempts[0].result, IsError(ERR_NAME_NOT_RESOLVED));
ttuttled9dbc652015-09-29 20:00:5915504
15505 IPEndPoint endpoint;
bnc691fda62016-08-12 00:43:1615506 EXPECT_FALSE(trans.GetRemoteEndpoint(&endpoint));
ttuttled9dbc652015-09-29 20:00:5915507 EXPECT_TRUE(endpoint.address().empty());
[email protected]79e1fd62013-06-20 06:50:0415508}
15509
bncd16676a2016-07-20 16:23:0115510TEST_F(HttpNetworkTransactionTest, HttpAsyncConnectError) {
[email protected]79e1fd62013-06-20 06:50:0415511 HttpRequestInfo request;
15512 request.method = "GET";
bncce36dca22015-04-21 22:11:2315513 request.url = GURL("http://www.example.org/");
[email protected]79e1fd62013-06-20 06:50:0415514
danakj1fd259a02016-04-16 03:17:0915515 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1615516 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]79e1fd62013-06-20 06:50:0415517
ttuttled9dbc652015-09-29 20:00:5915518 MockConnect mock_connect(ASYNC, ERR_NAME_NOT_RESOLVED);
[email protected]79e1fd62013-06-20 06:50:0415519 StaticSocketDataProvider data;
15520 data.set_connect_data(mock_connect);
15521 session_deps_.socket_factory->AddSocketDataProvider(&data);
15522
15523 TestCompletionCallback callback;
15524
tfarina42834112016-09-22 13:38:2015525 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0115526 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]79e1fd62013-06-20 06:50:0415527
15528 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0115529 EXPECT_THAT(rv, IsError(ERR_NAME_NOT_RESOLVED));
[email protected]79e1fd62013-06-20 06:50:0415530
[email protected]79e1fd62013-06-20 06:50:0415531 // We don't care whether this succeeds or fails, but it shouldn't crash.
15532 HttpRequestHeaders request_headers;
bnc691fda62016-08-12 00:43:1615533 trans.GetFullRequestHeaders(&request_headers);
ttuttle1f2d7e92015-04-28 16:17:4715534
15535 ConnectionAttempts attempts;
bnc691fda62016-08-12 00:43:1615536 trans.GetConnectionAttempts(&attempts);
ttuttle1f2d7e92015-04-28 16:17:4715537 ASSERT_EQ(1u, attempts.size());
robpercival214763f2016-07-01 23:27:0115538 EXPECT_THAT(attempts[0].result, IsError(ERR_NAME_NOT_RESOLVED));
ttuttled9dbc652015-09-29 20:00:5915539
15540 IPEndPoint endpoint;
bnc691fda62016-08-12 00:43:1615541 EXPECT_FALSE(trans.GetRemoteEndpoint(&endpoint));
ttuttled9dbc652015-09-29 20:00:5915542 EXPECT_TRUE(endpoint.address().empty());
[email protected]79e1fd62013-06-20 06:50:0415543}
15544
bncd16676a2016-07-20 16:23:0115545TEST_F(HttpNetworkTransactionTest, HttpSyncWriteError) {
[email protected]79e1fd62013-06-20 06:50:0415546 HttpRequestInfo request;
15547 request.method = "GET";
bncce36dca22015-04-21 22:11:2315548 request.url = GURL("http://www.example.org/");
[email protected]79e1fd62013-06-20 06:50:0415549
danakj1fd259a02016-04-16 03:17:0915550 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1615551 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]79e1fd62013-06-20 06:50:0415552
15553 MockWrite data_writes[] = {
15554 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
15555 };
15556 MockRead data_reads[] = {
15557 MockRead(SYNCHRONOUS, ERR_UNEXPECTED), // Should not be reached.
15558 };
15559
15560 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
15561 data_writes, arraysize(data_writes));
15562 session_deps_.socket_factory->AddSocketDataProvider(&data);
15563
15564 TestCompletionCallback callback;
15565
tfarina42834112016-09-22 13:38:2015566 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0115567 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]79e1fd62013-06-20 06:50:0415568
15569 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0115570 EXPECT_THAT(rv, IsError(ERR_CONNECTION_RESET));
[email protected]79e1fd62013-06-20 06:50:0415571
[email protected]79e1fd62013-06-20 06:50:0415572 HttpRequestHeaders request_headers;
bnc691fda62016-08-12 00:43:1615573 EXPECT_TRUE(trans.GetFullRequestHeaders(&request_headers));
[email protected]79e1fd62013-06-20 06:50:0415574 EXPECT_TRUE(request_headers.HasHeader("Host"));
15575}
15576
bncd16676a2016-07-20 16:23:0115577TEST_F(HttpNetworkTransactionTest, HttpAsyncWriteError) {
[email protected]79e1fd62013-06-20 06:50:0415578 HttpRequestInfo request;
15579 request.method = "GET";
bncce36dca22015-04-21 22:11:2315580 request.url = GURL("http://www.example.org/");
[email protected]79e1fd62013-06-20 06:50:0415581
danakj1fd259a02016-04-16 03:17:0915582 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1615583 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]79e1fd62013-06-20 06:50:0415584
15585 MockWrite data_writes[] = {
15586 MockWrite(ASYNC, ERR_CONNECTION_RESET),
15587 };
15588 MockRead data_reads[] = {
15589 MockRead(SYNCHRONOUS, ERR_UNEXPECTED), // Should not be reached.
15590 };
15591
15592 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
15593 data_writes, arraysize(data_writes));
15594 session_deps_.socket_factory->AddSocketDataProvider(&data);
15595
15596 TestCompletionCallback callback;
15597
tfarina42834112016-09-22 13:38:2015598 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0115599 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]79e1fd62013-06-20 06:50:0415600
15601 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0115602 EXPECT_THAT(rv, IsError(ERR_CONNECTION_RESET));
[email protected]79e1fd62013-06-20 06:50:0415603
[email protected]79e1fd62013-06-20 06:50:0415604 HttpRequestHeaders request_headers;
bnc691fda62016-08-12 00:43:1615605 EXPECT_TRUE(trans.GetFullRequestHeaders(&request_headers));
[email protected]79e1fd62013-06-20 06:50:0415606 EXPECT_TRUE(request_headers.HasHeader("Host"));
15607}
15608
bncd16676a2016-07-20 16:23:0115609TEST_F(HttpNetworkTransactionTest, HttpSyncReadError) {
[email protected]79e1fd62013-06-20 06:50:0415610 HttpRequestInfo request;
15611 request.method = "GET";
bncce36dca22015-04-21 22:11:2315612 request.url = GURL("http://www.example.org/");
[email protected]79e1fd62013-06-20 06:50:0415613
danakj1fd259a02016-04-16 03:17:0915614 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1615615 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]79e1fd62013-06-20 06:50:0415616
15617 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:2315618 MockWrite(
15619 "GET / HTTP/1.1\r\n"
15620 "Host: www.example.org\r\n"
15621 "Connection: keep-alive\r\n\r\n"),
[email protected]79e1fd62013-06-20 06:50:0415622 };
15623 MockRead data_reads[] = {
15624 MockRead(SYNCHRONOUS, ERR_CONNECTION_RESET),
15625 };
15626
15627 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
15628 data_writes, arraysize(data_writes));
15629 session_deps_.socket_factory->AddSocketDataProvider(&data);
15630
15631 TestCompletionCallback callback;
15632
tfarina42834112016-09-22 13:38:2015633 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0115634 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]79e1fd62013-06-20 06:50:0415635
15636 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0115637 EXPECT_THAT(rv, IsError(ERR_CONNECTION_RESET));
[email protected]79e1fd62013-06-20 06:50:0415638
[email protected]79e1fd62013-06-20 06:50:0415639 HttpRequestHeaders request_headers;
bnc691fda62016-08-12 00:43:1615640 EXPECT_TRUE(trans.GetFullRequestHeaders(&request_headers));
[email protected]79e1fd62013-06-20 06:50:0415641 EXPECT_TRUE(request_headers.HasHeader("Host"));
15642}
15643
bncd16676a2016-07-20 16:23:0115644TEST_F(HttpNetworkTransactionTest, HttpAsyncReadError) {
[email protected]79e1fd62013-06-20 06:50:0415645 HttpRequestInfo request;
15646 request.method = "GET";
bncce36dca22015-04-21 22:11:2315647 request.url = GURL("http://www.example.org/");
[email protected]79e1fd62013-06-20 06:50:0415648
danakj1fd259a02016-04-16 03:17:0915649 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1615650 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]79e1fd62013-06-20 06:50:0415651
15652 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:2315653 MockWrite(
15654 "GET / HTTP/1.1\r\n"
15655 "Host: www.example.org\r\n"
15656 "Connection: keep-alive\r\n\r\n"),
[email protected]79e1fd62013-06-20 06:50:0415657 };
15658 MockRead data_reads[] = {
15659 MockRead(ASYNC, ERR_CONNECTION_RESET),
15660 };
15661
15662 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
15663 data_writes, arraysize(data_writes));
15664 session_deps_.socket_factory->AddSocketDataProvider(&data);
15665
15666 TestCompletionCallback callback;
15667
tfarina42834112016-09-22 13:38:2015668 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0115669 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]79e1fd62013-06-20 06:50:0415670
15671 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0115672 EXPECT_THAT(rv, IsError(ERR_CONNECTION_RESET));
[email protected]79e1fd62013-06-20 06:50:0415673
[email protected]79e1fd62013-06-20 06:50:0415674 HttpRequestHeaders request_headers;
bnc691fda62016-08-12 00:43:1615675 EXPECT_TRUE(trans.GetFullRequestHeaders(&request_headers));
[email protected]79e1fd62013-06-20 06:50:0415676 EXPECT_TRUE(request_headers.HasHeader("Host"));
15677}
15678
bncd16676a2016-07-20 16:23:0115679TEST_F(HttpNetworkTransactionTest, GetFullRequestHeadersIncludesExtraHeader) {
[email protected]79e1fd62013-06-20 06:50:0415680 HttpRequestInfo request;
15681 request.method = "GET";
bncce36dca22015-04-21 22:11:2315682 request.url = GURL("http://www.example.org/");
[email protected]79e1fd62013-06-20 06:50:0415683 request.extra_headers.SetHeader("X-Foo", "bar");
15684
danakj1fd259a02016-04-16 03:17:0915685 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1615686 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]79e1fd62013-06-20 06:50:0415687
15688 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:2315689 MockWrite(
15690 "GET / HTTP/1.1\r\n"
15691 "Host: www.example.org\r\n"
15692 "Connection: keep-alive\r\n"
15693 "X-Foo: bar\r\n\r\n"),
[email protected]79e1fd62013-06-20 06:50:0415694 };
15695 MockRead data_reads[] = {
15696 MockRead("HTTP/1.1 200 OK\r\n"
15697 "Content-Length: 5\r\n\r\n"
15698 "hello"),
15699 MockRead(ASYNC, ERR_UNEXPECTED),
15700 };
15701
15702 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
15703 data_writes, arraysize(data_writes));
15704 session_deps_.socket_factory->AddSocketDataProvider(&data);
15705
15706 TestCompletionCallback callback;
15707
tfarina42834112016-09-22 13:38:2015708 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0115709 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]79e1fd62013-06-20 06:50:0415710
15711 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0115712 EXPECT_THAT(rv, IsOk());
[email protected]79e1fd62013-06-20 06:50:0415713
15714 HttpRequestHeaders request_headers;
bnc691fda62016-08-12 00:43:1615715 EXPECT_TRUE(trans.GetFullRequestHeaders(&request_headers));
[email protected]79e1fd62013-06-20 06:50:0415716 std::string foo;
15717 EXPECT_TRUE(request_headers.GetHeader("X-Foo", &foo));
15718 EXPECT_EQ("bar", foo);
15719}
15720
[email protected]bf828982013-08-14 18:01:4715721namespace {
15722
yhiranoa7e05bb2014-11-06 05:40:3915723// Fake HttpStream that simply records calls to SetPriority().
15724class FakeStream : public HttpStream,
[email protected]e86839fd2013-08-14 18:29:0315725 public base::SupportsWeakPtr<FakeStream> {
15726 public:
15727 explicit FakeStream(RequestPriority priority) : priority_(priority) {}
Chris Watkins7a41d3552017-12-01 02:13:2715728 ~FakeStream() override = default;
[email protected]e86839fd2013-08-14 18:29:0315729
15730 RequestPriority priority() const { return priority_; }
15731
dchengb03027d2014-10-21 12:00:2015732 int InitializeStream(const HttpRequestInfo* request_info,
Steven Valdezb4ff0412018-01-18 22:39:2715733 bool can_send_early,
dchengb03027d2014-10-21 12:00:2015734 RequestPriority priority,
tfarina42834112016-09-22 13:38:2015735 const NetLogWithSource& net_log,
dchengb03027d2014-10-21 12:00:2015736 const CompletionCallback& callback) override {
[email protected]e86839fd2013-08-14 18:29:0315737 return ERR_IO_PENDING;
15738 }
15739
dchengb03027d2014-10-21 12:00:2015740 int SendRequest(const HttpRequestHeaders& request_headers,
15741 HttpResponseInfo* response,
15742 const CompletionCallback& callback) override {
[email protected]e86839fd2013-08-14 18:29:0315743 ADD_FAILURE();
15744 return ERR_UNEXPECTED;
15745 }
15746
dchengb03027d2014-10-21 12:00:2015747 int ReadResponseHeaders(const CompletionCallback& callback) override {
[email protected]e86839fd2013-08-14 18:29:0315748 ADD_FAILURE();
15749 return ERR_UNEXPECTED;
15750 }
15751
dchengb03027d2014-10-21 12:00:2015752 int ReadResponseBody(IOBuffer* buf,
15753 int buf_len,
15754 const CompletionCallback& callback) override {
[email protected]e86839fd2013-08-14 18:29:0315755 ADD_FAILURE();
15756 return ERR_UNEXPECTED;
15757 }
15758
dchengb03027d2014-10-21 12:00:2015759 void Close(bool not_reusable) override {}
[email protected]e86839fd2013-08-14 18:29:0315760
dchengb03027d2014-10-21 12:00:2015761 bool IsResponseBodyComplete() const override {
[email protected]e86839fd2013-08-14 18:29:0315762 ADD_FAILURE();
15763 return false;
15764 }
15765
dchengb03027d2014-10-21 12:00:2015766 bool IsConnectionReused() const override {
[email protected]e86839fd2013-08-14 18:29:0315767 ADD_FAILURE();
15768 return false;
15769 }
15770
dchengb03027d2014-10-21 12:00:2015771 void SetConnectionReused() override { ADD_FAILURE(); }
[email protected]e86839fd2013-08-14 18:29:0315772
mmenkebd84c392015-09-02 14:12:3415773 bool CanReuseConnection() const override { return false; }
[email protected]e86839fd2013-08-14 18:29:0315774
sclittle4de1bab92015-09-22 21:28:2415775 int64_t GetTotalReceivedBytes() const override {
[email protected]bc92bc972013-12-13 08:32:5915776 ADD_FAILURE();
15777 return 0;
15778 }
15779
sclittlebe1ccf62015-09-02 19:40:3615780 int64_t GetTotalSentBytes() const override {
15781 ADD_FAILURE();
15782 return 0;
15783 }
15784
dchengb03027d2014-10-21 12:00:2015785 bool GetLoadTimingInfo(LoadTimingInfo* load_timing_info) const override {
[email protected]e86839fd2013-08-14 18:29:0315786 ADD_FAILURE();
15787 return false;
15788 }
15789
rchcd379012017-04-12 21:53:3215790 bool GetAlternativeService(
15791 AlternativeService* alternative_service) const override {
15792 ADD_FAILURE();
15793 return false;
15794 }
15795
dchengb03027d2014-10-21 12:00:2015796 void GetSSLInfo(SSLInfo* ssl_info) override { ADD_FAILURE(); }
15797
15798 void GetSSLCertRequestInfo(SSLCertRequestInfo* cert_request_info) override {
[email protected]e86839fd2013-08-14 18:29:0315799 ADD_FAILURE();
15800 }
15801
ttuttled9dbc652015-09-29 20:00:5915802 bool GetRemoteEndpoint(IPEndPoint* endpoint) override { return false; }
15803
nharper78e6d2b2016-09-21 05:42:3515804 Error GetTokenBindingSignature(crypto::ECPrivateKey* key,
15805 TokenBindingType tb_type,
15806 std::vector<uint8_t>* out) override {
nharperb7441ef2016-01-25 23:54:1415807 ADD_FAILURE();
15808 return ERR_NOT_IMPLEMENTED;
15809 }
15810
dchengb03027d2014-10-21 12:00:2015811 void Drain(HttpNetworkSession* session) override { ADD_FAILURE(); }
[email protected]e86839fd2013-08-14 18:29:0315812
zhongyica364fbb2015-12-12 03:39:1215813 void PopulateNetErrorDetails(NetErrorDetails* details) override { return; }
15814
dchengb03027d2014-10-21 12:00:2015815 void SetPriority(RequestPriority priority) override { priority_ = priority; }
[email protected]e86839fd2013-08-14 18:29:0315816
yhiranoa7e05bb2014-11-06 05:40:3915817 HttpStream* RenewStreamForAuth() override { return NULL; }
15818
Andrey Kosyakov83a6eee2017-08-14 19:20:0415819 void SetRequestHeadersCallback(RequestHeadersCallback callback) override {}
15820
[email protected]e86839fd2013-08-14 18:29:0315821 private:
15822 RequestPriority priority_;
15823
15824 DISALLOW_COPY_AND_ASSIGN(FakeStream);
15825};
15826
15827// Fake HttpStreamRequest that simply records calls to SetPriority()
15828// and vends FakeStreams with its current priority.
[email protected]bf828982013-08-14 18:01:4715829class FakeStreamRequest : public HttpStreamRequest,
15830 public base::SupportsWeakPtr<FakeStreamRequest> {
15831 public:
[email protected]e86839fd2013-08-14 18:29:0315832 FakeStreamRequest(RequestPriority priority,
15833 HttpStreamRequest::Delegate* delegate)
15834 : priority_(priority),
[email protected]831e4a32013-11-14 02:14:4415835 delegate_(delegate),
15836 websocket_stream_create_helper_(NULL) {}
15837
15838 FakeStreamRequest(RequestPriority priority,
15839 HttpStreamRequest::Delegate* delegate,
15840 WebSocketHandshakeStreamBase::CreateHelper* create_helper)
15841 : priority_(priority),
15842 delegate_(delegate),
15843 websocket_stream_create_helper_(create_helper) {}
[email protected]e86839fd2013-08-14 18:29:0315844
Chris Watkins7a41d3552017-12-01 02:13:2715845 ~FakeStreamRequest() override = default;
[email protected]bf828982013-08-14 18:01:4715846
15847 RequestPriority priority() const { return priority_; }
15848
[email protected]831e4a32013-11-14 02:14:4415849 const WebSocketHandshakeStreamBase::CreateHelper*
15850 websocket_stream_create_helper() const {
15851 return websocket_stream_create_helper_;
15852 }
15853
[email protected]e86839fd2013-08-14 18:29:0315854 // Create a new FakeStream and pass it to the request's
15855 // delegate. Returns a weak pointer to the FakeStream.
15856 base::WeakPtr<FakeStream> FinishStreamRequest() {
Jeremy Roman0579ed62017-08-29 15:56:1915857 auto fake_stream = std::make_unique<FakeStream>(priority_);
[email protected]e86839fd2013-08-14 18:29:0315858 // Do this before calling OnStreamReady() as OnStreamReady() may
15859 // immediately delete |fake_stream|.
15860 base::WeakPtr<FakeStream> weak_stream = fake_stream->AsWeakPtr();
bnc5029f4632017-06-08 16:19:0015861 delegate_->OnStreamReady(SSLConfig(), ProxyInfo(), std::move(fake_stream));
[email protected]e86839fd2013-08-14 18:29:0315862 return weak_stream;
15863 }
15864
asanka681f02d2017-02-22 17:06:3915865 int RestartTunnelWithProxyAuth() override {
[email protected]bf828982013-08-14 18:01:4715866 ADD_FAILURE();
15867 return ERR_UNEXPECTED;
15868 }
15869
dchengb03027d2014-10-21 12:00:2015870 LoadState GetLoadState() const override {
[email protected]bf828982013-08-14 18:01:4715871 ADD_FAILURE();
15872 return LoadState();
15873 }
15874
dchengb03027d2014-10-21 12:00:2015875 void SetPriority(RequestPriority priority) override { priority_ = priority; }
[email protected]bf828982013-08-14 18:01:4715876
bnc94c92842016-09-21 15:22:5215877 bool was_alpn_negotiated() const override { return false; }
[email protected]bf828982013-08-14 18:01:4715878
bnc6227b26e2016-08-12 02:00:4315879 NextProto negotiated_protocol() const override { return kProtoUnknown; }
[email protected]bf828982013-08-14 18:01:4715880
dchengb03027d2014-10-21 12:00:2015881 bool using_spdy() const override { return false; }
[email protected]bf828982013-08-14 18:01:4715882
ttuttle1f2d7e92015-04-28 16:17:4715883 const ConnectionAttempts& connection_attempts() const override {
15884 static ConnectionAttempts no_attempts;
15885 return no_attempts;
15886 }
15887
[email protected]bf828982013-08-14 18:01:4715888 private:
15889 RequestPriority priority_;
[email protected]e86839fd2013-08-14 18:29:0315890 HttpStreamRequest::Delegate* const delegate_;
[email protected]831e4a32013-11-14 02:14:4415891 WebSocketHandshakeStreamBase::CreateHelper* websocket_stream_create_helper_;
[email protected]bf828982013-08-14 18:01:4715892
15893 DISALLOW_COPY_AND_ASSIGN(FakeStreamRequest);
15894};
15895
15896// Fake HttpStreamFactory that vends FakeStreamRequests.
15897class FakeStreamFactory : public HttpStreamFactory {
15898 public:
Chris Watkins7a41d3552017-12-01 02:13:2715899 FakeStreamFactory() = default;
15900 ~FakeStreamFactory() override = default;
[email protected]bf828982013-08-14 18:01:4715901
15902 // Returns a WeakPtr<> to the last HttpStreamRequest returned by
15903 // RequestStream() (which may be NULL if it was destroyed already).
15904 base::WeakPtr<FakeStreamRequest> last_stream_request() {
15905 return last_stream_request_;
15906 }
15907
xunjieli96f2a402017-06-05 17:24:2715908 std::unique_ptr<HttpStreamRequest> RequestStream(
15909 const HttpRequestInfo& info,
15910 RequestPriority priority,
15911 const SSLConfig& server_ssl_config,
15912 const SSLConfig& proxy_ssl_config,
15913 HttpStreamRequest::Delegate* delegate,
15914 bool enable_ip_based_pooling,
15915 bool enable_alternative_services,
15916 const NetLogWithSource& net_log) override {
Jeremy Roman0579ed62017-08-29 15:56:1915917 auto fake_request = std::make_unique<FakeStreamRequest>(priority, delegate);
[email protected]bf828982013-08-14 18:01:4715918 last_stream_request_ = fake_request->AsWeakPtr();
xunjieli96f2a402017-06-05 17:24:2715919 return std::move(fake_request);
[email protected]bf828982013-08-14 18:01:4715920 }
15921
xunjieli96f2a402017-06-05 17:24:2715922 std::unique_ptr<HttpStreamRequest> RequestBidirectionalStreamImpl(
xunjieli11834f02015-12-22 04:27:0815923 const HttpRequestInfo& info,
15924 RequestPriority priority,
15925 const SSLConfig& server_ssl_config,
15926 const SSLConfig& proxy_ssl_config,
15927 HttpStreamRequest::Delegate* delegate,
bnc8016c1f2017-03-31 02:11:2915928 bool enable_ip_based_pooling,
bncaccd4962017-04-06 21:00:2615929 bool enable_alternative_services,
tfarina42834112016-09-22 13:38:2015930 const NetLogWithSource& net_log) override {
xunjieli11834f02015-12-22 04:27:0815931 NOTREACHED();
15932 return nullptr;
15933 }
15934
xunjieli96f2a402017-06-05 17:24:2715935 std::unique_ptr<HttpStreamRequest> RequestWebSocketHandshakeStream(
[email protected]bf828982013-08-14 18:01:4715936 const HttpRequestInfo& info,
15937 RequestPriority priority,
15938 const SSLConfig& server_ssl_config,
15939 const SSLConfig& proxy_ssl_config,
15940 HttpStreamRequest::Delegate* delegate,
[email protected]467086b2013-11-12 08:19:4615941 WebSocketHandshakeStreamBase::CreateHelper* create_helper,
bnc8016c1f2017-03-31 02:11:2915942 bool enable_ip_based_pooling,
bncaccd4962017-04-06 21:00:2615943 bool enable_alternative_services,
tfarina42834112016-09-22 13:38:2015944 const NetLogWithSource& net_log) override {
xunjieli96f2a402017-06-05 17:24:2715945 auto fake_request =
Jeremy Roman0579ed62017-08-29 15:56:1915946 std::make_unique<FakeStreamRequest>(priority, delegate, create_helper);
[email protected]831e4a32013-11-14 02:14:4415947 last_stream_request_ = fake_request->AsWeakPtr();
xunjieli96f2a402017-06-05 17:24:2715948 return std::move(fake_request);
[email protected]bf828982013-08-14 18:01:4715949 }
15950
dchengb03027d2014-10-21 12:00:2015951 void PreconnectStreams(int num_streams,
nharper8cdb0fb2016-04-22 21:34:5915952 const HttpRequestInfo& info) override {
[email protected]bf828982013-08-14 18:01:4715953 ADD_FAILURE();
15954 }
15955
dchengb03027d2014-10-21 12:00:2015956 const HostMappingRules* GetHostMappingRules() const override {
[email protected]bf828982013-08-14 18:01:4715957 ADD_FAILURE();
15958 return NULL;
15959 }
15960
xunjielif5267de2017-01-20 21:18:5715961 void DumpMemoryStats(base::trace_event::ProcessMemoryDump* pmd,
15962 const std::string& parent_absolute_name) const override {
15963 ADD_FAILURE();
15964 }
15965
[email protected]bf828982013-08-14 18:01:4715966 private:
15967 base::WeakPtr<FakeStreamRequest> last_stream_request_;
15968
15969 DISALLOW_COPY_AND_ASSIGN(FakeStreamFactory);
15970};
15971
Adam Rice425cf122015-01-19 06:18:2415972// TODO(ricea): Maybe unify this with the one in
15973// url_request_http_job_unittest.cc ?
15974class FakeWebSocketBasicHandshakeStream : public WebSocketHandshakeStreamBase {
15975 public:
danakj1fd259a02016-04-16 03:17:0915976 FakeWebSocketBasicHandshakeStream(
15977 std::unique_ptr<ClientSocketHandle> connection,
15978 bool using_proxy)
mmenkea7da6da2016-09-01 21:56:5215979 : state_(std::move(connection), using_proxy, false) {}
Adam Rice425cf122015-01-19 06:18:2415980
15981 // Fake implementation of HttpStreamBase methods.
15982 // This ends up being quite "real" because this object has to really send data
15983 // on the mock socket. It might be easier to use the real implementation, but
15984 // the fact that the WebSocket code is not compiled on iOS makes that
15985 // difficult.
15986 int InitializeStream(const HttpRequestInfo* request_info,
Steven Valdezb4ff0412018-01-18 22:39:2715987 bool can_send_early,
Adam Rice425cf122015-01-19 06:18:2415988 RequestPriority priority,
tfarina42834112016-09-22 13:38:2015989 const NetLogWithSource& net_log,
Adam Rice425cf122015-01-19 06:18:2415990 const CompletionCallback& callback) override {
Steven Valdezb4ff0412018-01-18 22:39:2715991 state_.Initialize(request_info, can_send_early, priority, net_log,
15992 callback);
Adam Rice425cf122015-01-19 06:18:2415993 return OK;
15994 }
15995
15996 int SendRequest(const HttpRequestHeaders& request_headers,
15997 HttpResponseInfo* response,
15998 const CompletionCallback& callback) override {
15999 return parser()->SendRequest(state_.GenerateRequestLine(), request_headers,
[email protected]baee31a2018-01-18 06:10:2316000 TRAFFIC_ANNOTATION_FOR_TESTS, response,
16001 callback);
Adam Rice425cf122015-01-19 06:18:2416002 }
16003
16004 int ReadResponseHeaders(const CompletionCallback& callback) override {
16005 return parser()->ReadResponseHeaders(callback);
16006 }
16007
16008 int ReadResponseBody(IOBuffer* buf,
16009 int buf_len,
16010 const CompletionCallback& callback) override {
16011 NOTREACHED();
16012 return ERR_IO_PENDING;
16013 }
16014
16015 void Close(bool not_reusable) override {
16016 if (parser())
16017 parser()->Close(true);
16018 }
16019
16020 bool IsResponseBodyComplete() const override {
16021 NOTREACHED();
16022 return false;
16023 }
16024
Adam Rice425cf122015-01-19 06:18:2416025 bool IsConnectionReused() const override {
16026 NOTREACHED();
16027 return false;
16028 }
16029 void SetConnectionReused() override { NOTREACHED(); }
16030
mmenkebd84c392015-09-02 14:12:3416031 bool CanReuseConnection() const override { return false; }
Adam Rice425cf122015-01-19 06:18:2416032
sclittle4de1bab92015-09-22 21:28:2416033 int64_t GetTotalReceivedBytes() const override {
Adam Rice425cf122015-01-19 06:18:2416034 NOTREACHED();
16035 return 0;
16036 }
16037
sclittlebe1ccf62015-09-02 19:40:3616038 int64_t GetTotalSentBytes() const override {
16039 NOTREACHED();
16040 return 0;
16041 }
16042
Adam Rice425cf122015-01-19 06:18:2416043 bool GetLoadTimingInfo(LoadTimingInfo* load_timing_info) const override {
16044 NOTREACHED();
16045 return false;
16046 }
16047
rchcd379012017-04-12 21:53:3216048 bool GetAlternativeService(
16049 AlternativeService* alternative_service) const override {
16050 ADD_FAILURE();
16051 return false;
16052 }
16053
Adam Ricecb76ac62015-02-20 05:33:2516054 void GetSSLInfo(SSLInfo* ssl_info) override {}
Adam Rice425cf122015-01-19 06:18:2416055
16056 void GetSSLCertRequestInfo(SSLCertRequestInfo* cert_request_info) override {
16057 NOTREACHED();
16058 }
16059
ttuttled9dbc652015-09-29 20:00:5916060 bool GetRemoteEndpoint(IPEndPoint* endpoint) override { return false; }
16061
nharper78e6d2b2016-09-21 05:42:3516062 Error GetTokenBindingSignature(crypto::ECPrivateKey* key,
16063 TokenBindingType tb_type,
16064 std::vector<uint8_t>* out) override {
nharperb7441ef2016-01-25 23:54:1416065 ADD_FAILURE();
16066 return ERR_NOT_IMPLEMENTED;
16067 }
16068
Adam Rice425cf122015-01-19 06:18:2416069 void Drain(HttpNetworkSession* session) override { NOTREACHED(); }
16070
zhongyica364fbb2015-12-12 03:39:1216071 void PopulateNetErrorDetails(NetErrorDetails* details) override { return; }
16072
Adam Rice425cf122015-01-19 06:18:2416073 void SetPriority(RequestPriority priority) override { NOTREACHED(); }
16074
Adam Rice425cf122015-01-19 06:18:2416075 HttpStream* RenewStreamForAuth() override {
16076 NOTREACHED();
16077 return nullptr;
16078 }
16079
16080 // Fake implementation of WebSocketHandshakeStreamBase method(s)
danakj1fd259a02016-04-16 03:17:0916081 std::unique_ptr<WebSocketStream> Upgrade() override {
Adam Rice425cf122015-01-19 06:18:2416082 NOTREACHED();
danakj1fd259a02016-04-16 03:17:0916083 return std::unique_ptr<WebSocketStream>();
Adam Rice425cf122015-01-19 06:18:2416084 }
16085
16086 private:
16087 HttpStreamParser* parser() const { return state_.parser(); }
16088 HttpBasicState state_;
16089
16090 DISALLOW_COPY_AND_ASSIGN(FakeWebSocketBasicHandshakeStream);
16091};
16092
[email protected]831e4a32013-11-14 02:14:4416093// TODO(yhirano): Split this class out into a net/websockets file, if it is
16094// worth doing.
16095class FakeWebSocketStreamCreateHelper :
16096 public WebSocketHandshakeStreamBase::CreateHelper {
16097 public:
bnc615cf2f2017-05-19 18:53:2616098 std::unique_ptr<WebSocketHandshakeStreamBase> CreateBasicStream(
danakj1fd259a02016-04-16 03:17:0916099 std::unique_ptr<ClientSocketHandle> connection,
mostynbba063d6032014-10-09 11:01:1316100 bool using_proxy) override {
Jeremy Roman0579ed62017-08-29 15:56:1916101 return std::make_unique<FakeWebSocketBasicHandshakeStream>(
bnc615cf2f2017-05-19 18:53:2616102 std::move(connection), using_proxy);
[email protected]831e4a32013-11-14 02:14:4416103 }
16104
Chris Watkins7a41d3552017-12-01 02:13:2716105 ~FakeWebSocketStreamCreateHelper() override = default;
[email protected]831e4a32013-11-14 02:14:4416106
danakj1fd259a02016-04-16 03:17:0916107 virtual std::unique_ptr<WebSocketStream> Upgrade() {
[email protected]831e4a32013-11-14 02:14:4416108 NOTREACHED();
danakj1fd259a02016-04-16 03:17:0916109 return std::unique_ptr<WebSocketStream>();
[email protected]831e4a32013-11-14 02:14:4416110 }
16111};
16112
[email protected]bf828982013-08-14 18:01:4716113} // namespace
16114
16115// Make sure that HttpNetworkTransaction passes on its priority to its
16116// stream request on start.
bncd16676a2016-07-20 16:23:0116117TEST_F(HttpNetworkTransactionTest, SetStreamRequestPriorityOnStart) {
danakj1fd259a02016-04-16 03:17:0916118 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
mmenkee65e7af2015-10-13 17:16:4216119 HttpNetworkSessionPeer peer(session.get());
[email protected]bf828982013-08-14 18:01:4716120 FakeStreamFactory* fake_factory = new FakeStreamFactory();
danakj1fd259a02016-04-16 03:17:0916121 peer.SetHttpStreamFactory(std::unique_ptr<HttpStreamFactory>(fake_factory));
[email protected]bf828982013-08-14 18:01:4716122
krasinc06a72a2016-12-21 03:42:4616123 HttpRequestInfo request;
dcheng48459ac22014-08-26 00:46:4116124 HttpNetworkTransaction trans(LOW, session.get());
[email protected]bf828982013-08-14 18:01:4716125
wezca1070932016-05-26 20:30:5216126 ASSERT_FALSE(fake_factory->last_stream_request());
[email protected]bf828982013-08-14 18:01:4716127
[email protected]bf828982013-08-14 18:01:4716128 TestCompletionCallback callback;
16129 EXPECT_EQ(ERR_IO_PENDING,
tfarina42834112016-09-22 13:38:2016130 trans.Start(&request, callback.callback(), NetLogWithSource()));
[email protected]bf828982013-08-14 18:01:4716131
16132 base::WeakPtr<FakeStreamRequest> fake_request =
16133 fake_factory->last_stream_request();
wezca1070932016-05-26 20:30:5216134 ASSERT_TRUE(fake_request);
[email protected]bf828982013-08-14 18:01:4716135 EXPECT_EQ(LOW, fake_request->priority());
16136}
16137
16138// Make sure that HttpNetworkTransaction passes on its priority
16139// updates to its stream request.
bncd16676a2016-07-20 16:23:0116140TEST_F(HttpNetworkTransactionTest, SetStreamRequestPriority) {
danakj1fd259a02016-04-16 03:17:0916141 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
mmenkee65e7af2015-10-13 17:16:4216142 HttpNetworkSessionPeer peer(session.get());
[email protected]bf828982013-08-14 18:01:4716143 FakeStreamFactory* fake_factory = new FakeStreamFactory();
danakj1fd259a02016-04-16 03:17:0916144 peer.SetHttpStreamFactory(std::unique_ptr<HttpStreamFactory>(fake_factory));
[email protected]bf828982013-08-14 18:01:4716145
krasinc06a72a2016-12-21 03:42:4616146 HttpRequestInfo request;
dcheng48459ac22014-08-26 00:46:4116147 HttpNetworkTransaction trans(LOW, session.get());
[email protected]bf828982013-08-14 18:01:4716148
[email protected]bf828982013-08-14 18:01:4716149 TestCompletionCallback callback;
16150 EXPECT_EQ(ERR_IO_PENDING,
tfarina42834112016-09-22 13:38:2016151 trans.Start(&request, callback.callback(), NetLogWithSource()));
[email protected]bf828982013-08-14 18:01:4716152
16153 base::WeakPtr<FakeStreamRequest> fake_request =
16154 fake_factory->last_stream_request();
wezca1070932016-05-26 20:30:5216155 ASSERT_TRUE(fake_request);
[email protected]bf828982013-08-14 18:01:4716156 EXPECT_EQ(LOW, fake_request->priority());
16157
16158 trans.SetPriority(LOWEST);
wezca1070932016-05-26 20:30:5216159 ASSERT_TRUE(fake_request);
[email protected]bf828982013-08-14 18:01:4716160 EXPECT_EQ(LOWEST, fake_request->priority());
16161}
16162
[email protected]e86839fd2013-08-14 18:29:0316163// Make sure that HttpNetworkTransaction passes on its priority
16164// updates to its stream.
bncd16676a2016-07-20 16:23:0116165TEST_F(HttpNetworkTransactionTest, SetStreamPriority) {
danakj1fd259a02016-04-16 03:17:0916166 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
mmenkee65e7af2015-10-13 17:16:4216167 HttpNetworkSessionPeer peer(session.get());
[email protected]e86839fd2013-08-14 18:29:0316168 FakeStreamFactory* fake_factory = new FakeStreamFactory();
danakj1fd259a02016-04-16 03:17:0916169 peer.SetHttpStreamFactory(std::unique_ptr<HttpStreamFactory>(fake_factory));
[email protected]e86839fd2013-08-14 18:29:0316170
krasinc06a72a2016-12-21 03:42:4616171 HttpRequestInfo request;
dcheng48459ac22014-08-26 00:46:4116172 HttpNetworkTransaction trans(LOW, session.get());
[email protected]e86839fd2013-08-14 18:29:0316173
[email protected]e86839fd2013-08-14 18:29:0316174 TestCompletionCallback callback;
16175 EXPECT_EQ(ERR_IO_PENDING,
tfarina42834112016-09-22 13:38:2016176 trans.Start(&request, callback.callback(), NetLogWithSource()));
[email protected]e86839fd2013-08-14 18:29:0316177
16178 base::WeakPtr<FakeStreamRequest> fake_request =
16179 fake_factory->last_stream_request();
wezca1070932016-05-26 20:30:5216180 ASSERT_TRUE(fake_request);
[email protected]e86839fd2013-08-14 18:29:0316181 base::WeakPtr<FakeStream> fake_stream = fake_request->FinishStreamRequest();
wezca1070932016-05-26 20:30:5216182 ASSERT_TRUE(fake_stream);
[email protected]e86839fd2013-08-14 18:29:0316183 EXPECT_EQ(LOW, fake_stream->priority());
16184
16185 trans.SetPriority(LOWEST);
16186 EXPECT_EQ(LOWEST, fake_stream->priority());
16187}
16188
bncd16676a2016-07-20 16:23:0116189TEST_F(HttpNetworkTransactionTest, CreateWebSocketHandshakeStream) {
[email protected]831e4a32013-11-14 02:14:4416190 // The same logic needs to be tested for both ws: and wss: schemes, but this
16191 // test is already parameterised on NextProto, so it uses a loop to verify
16192 // that the different schemes work.
bncce36dca22015-04-21 22:11:2316193 std::string test_cases[] = {"ws://www.example.org/",
16194 "wss://www.example.org/"};
[email protected]831e4a32013-11-14 02:14:4416195 for (size_t i = 0; i < arraysize(test_cases); ++i) {
danakj1fd259a02016-04-16 03:17:0916196 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
mmenkee65e7af2015-10-13 17:16:4216197 HttpNetworkSessionPeer peer(session.get());
[email protected]831e4a32013-11-14 02:14:4416198 FakeStreamFactory* fake_factory = new FakeStreamFactory();
16199 FakeWebSocketStreamCreateHelper websocket_stream_create_helper;
Bence Béky8cae04e2018-01-15 18:37:0616200 peer.SetHttpStreamFactory(std::unique_ptr<HttpStreamFactory>(fake_factory));
[email protected]831e4a32013-11-14 02:14:4416201
krasinc06a72a2016-12-21 03:42:4616202 HttpRequestInfo request;
dcheng48459ac22014-08-26 00:46:4116203 HttpNetworkTransaction trans(LOW, session.get());
[email protected]831e4a32013-11-14 02:14:4416204 trans.SetWebSocketHandshakeStreamCreateHelper(
16205 &websocket_stream_create_helper);
16206
[email protected]831e4a32013-11-14 02:14:4416207 TestCompletionCallback callback;
16208 request.method = "GET";
16209 request.url = GURL(test_cases[i]);
16210
16211 EXPECT_EQ(ERR_IO_PENDING,
tfarina42834112016-09-22 13:38:2016212 trans.Start(&request, callback.callback(), NetLogWithSource()));
[email protected]831e4a32013-11-14 02:14:4416213
16214 base::WeakPtr<FakeStreamRequest> fake_request =
16215 fake_factory->last_stream_request();
wezca1070932016-05-26 20:30:5216216 ASSERT_TRUE(fake_request);
[email protected]831e4a32013-11-14 02:14:4416217 EXPECT_EQ(&websocket_stream_create_helper,
16218 fake_request->websocket_stream_create_helper());
16219 }
16220}
16221
[email protected]043b68c82013-08-22 23:41:5216222// Tests that when a used socket is returned to the SSL socket pool, it's closed
16223// if the transport socket pool is stalled on the global socket limit.
bncd16676a2016-07-20 16:23:0116224TEST_F(HttpNetworkTransactionTest, CloseSSLSocketOnIdleForHttpRequest) {
[email protected]043b68c82013-08-22 23:41:5216225 ClientSocketPoolManager::set_max_sockets_per_group(
16226 HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
16227 ClientSocketPoolManager::set_max_sockets_per_pool(
16228 HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
16229
16230 // Set up SSL request.
16231
16232 HttpRequestInfo ssl_request;
16233 ssl_request.method = "GET";
bncce36dca22015-04-21 22:11:2316234 ssl_request.url = GURL("https://www.example.org/");
[email protected]043b68c82013-08-22 23:41:5216235
16236 MockWrite ssl_writes[] = {
bncce36dca22015-04-21 22:11:2316237 MockWrite(
16238 "GET / HTTP/1.1\r\n"
16239 "Host: www.example.org\r\n"
16240 "Connection: keep-alive\r\n\r\n"),
[email protected]043b68c82013-08-22 23:41:5216241 };
16242 MockRead ssl_reads[] = {
16243 MockRead("HTTP/1.1 200 OK\r\n"),
16244 MockRead("Content-Length: 11\r\n\r\n"),
16245 MockRead("hello world"),
16246 MockRead(SYNCHRONOUS, OK),
16247 };
16248 StaticSocketDataProvider ssl_data(ssl_reads, arraysize(ssl_reads),
16249 ssl_writes, arraysize(ssl_writes));
16250 session_deps_.socket_factory->AddSocketDataProvider(&ssl_data);
16251
16252 SSLSocketDataProvider ssl(ASYNC, OK);
16253 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
16254
16255 // Set up HTTP request.
16256
16257 HttpRequestInfo http_request;
16258 http_request.method = "GET";
bncce36dca22015-04-21 22:11:2316259 http_request.url = GURL("http://www.example.org/");
[email protected]043b68c82013-08-22 23:41:5216260
16261 MockWrite http_writes[] = {
bncce36dca22015-04-21 22:11:2316262 MockWrite(
16263 "GET / HTTP/1.1\r\n"
16264 "Host: www.example.org\r\n"
16265 "Connection: keep-alive\r\n\r\n"),
[email protected]043b68c82013-08-22 23:41:5216266 };
16267 MockRead http_reads[] = {
16268 MockRead("HTTP/1.1 200 OK\r\n"),
16269 MockRead("Content-Length: 7\r\n\r\n"),
16270 MockRead("falafel"),
16271 MockRead(SYNCHRONOUS, OK),
16272 };
16273 StaticSocketDataProvider http_data(http_reads, arraysize(http_reads),
16274 http_writes, arraysize(http_writes));
16275 session_deps_.socket_factory->AddSocketDataProvider(&http_data);
16276
danakj1fd259a02016-04-16 03:17:0916277 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]043b68c82013-08-22 23:41:5216278
16279 // Start the SSL request.
16280 TestCompletionCallback ssl_callback;
bnc691fda62016-08-12 00:43:1616281 HttpNetworkTransaction ssl_trans(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:2016282 ASSERT_EQ(ERR_IO_PENDING,
16283 ssl_trans.Start(&ssl_request, ssl_callback.callback(),
16284 NetLogWithSource()));
[email protected]043b68c82013-08-22 23:41:5216285
16286 // Start the HTTP request. Pool should stall.
16287 TestCompletionCallback http_callback;
bnc691fda62016-08-12 00:43:1616288 HttpNetworkTransaction http_trans(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:2016289 ASSERT_EQ(ERR_IO_PENDING,
16290 http_trans.Start(&http_request, http_callback.callback(),
16291 NetLogWithSource()));
dcheng48459ac22014-08-26 00:46:4116292 EXPECT_TRUE(IsTransportSocketPoolStalled(session.get()));
[email protected]043b68c82013-08-22 23:41:5216293
16294 // Wait for response from SSL request.
robpercival214763f2016-07-01 23:27:0116295 ASSERT_THAT(ssl_callback.WaitForResult(), IsOk());
[email protected]043b68c82013-08-22 23:41:5216296 std::string response_data;
bnc691fda62016-08-12 00:43:1616297 ASSERT_THAT(ReadTransaction(&ssl_trans, &response_data), IsOk());
[email protected]043b68c82013-08-22 23:41:5216298 EXPECT_EQ("hello world", response_data);
16299
16300 // The SSL socket should automatically be closed, so the HTTP request can
16301 // start.
dcheng48459ac22014-08-26 00:46:4116302 EXPECT_EQ(0, GetIdleSocketCountInSSLSocketPool(session.get()));
16303 ASSERT_FALSE(IsTransportSocketPoolStalled(session.get()));
[email protected]043b68c82013-08-22 23:41:5216304
16305 // The HTTP request can now complete.
robpercival214763f2016-07-01 23:27:0116306 ASSERT_THAT(http_callback.WaitForResult(), IsOk());
bnc691fda62016-08-12 00:43:1616307 ASSERT_THAT(ReadTransaction(&http_trans, &response_data), IsOk());
[email protected]043b68c82013-08-22 23:41:5216308 EXPECT_EQ("falafel", response_data);
16309
dcheng48459ac22014-08-26 00:46:4116310 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]043b68c82013-08-22 23:41:5216311}
16312
16313// Tests that when a SSL connection is established but there's no corresponding
16314// request that needs it, the new socket is closed if the transport socket pool
16315// is stalled on the global socket limit.
bncd16676a2016-07-20 16:23:0116316TEST_F(HttpNetworkTransactionTest, CloseSSLSocketOnIdleForHttpRequest2) {
[email protected]043b68c82013-08-22 23:41:5216317 ClientSocketPoolManager::set_max_sockets_per_group(
16318 HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
16319 ClientSocketPoolManager::set_max_sockets_per_pool(
16320 HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
16321
16322 // Set up an ssl request.
16323
16324 HttpRequestInfo ssl_request;
16325 ssl_request.method = "GET";
16326 ssl_request.url = GURL("https://www.foopy.com/");
16327
16328 // No data will be sent on the SSL socket.
16329 StaticSocketDataProvider ssl_data;
16330 session_deps_.socket_factory->AddSocketDataProvider(&ssl_data);
16331
16332 SSLSocketDataProvider ssl(ASYNC, OK);
16333 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
16334
16335 // Set up HTTP request.
16336
16337 HttpRequestInfo http_request;
16338 http_request.method = "GET";
bncce36dca22015-04-21 22:11:2316339 http_request.url = GURL("http://www.example.org/");
[email protected]043b68c82013-08-22 23:41:5216340
16341 MockWrite http_writes[] = {
bncce36dca22015-04-21 22:11:2316342 MockWrite(
16343 "GET / HTTP/1.1\r\n"
16344 "Host: www.example.org\r\n"
16345 "Connection: keep-alive\r\n\r\n"),
[email protected]043b68c82013-08-22 23:41:5216346 };
16347 MockRead http_reads[] = {
16348 MockRead("HTTP/1.1 200 OK\r\n"),
16349 MockRead("Content-Length: 7\r\n\r\n"),
16350 MockRead("falafel"),
16351 MockRead(SYNCHRONOUS, OK),
16352 };
16353 StaticSocketDataProvider http_data(http_reads, arraysize(http_reads),
16354 http_writes, arraysize(http_writes));
16355 session_deps_.socket_factory->AddSocketDataProvider(&http_data);
16356
danakj1fd259a02016-04-16 03:17:0916357 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]043b68c82013-08-22 23:41:5216358
16359 // Preconnect an SSL socket. A preconnect is needed because connect jobs are
16360 // cancelled when a normal transaction is cancelled.
ttuttle859dc7a2015-04-23 19:42:2916361 HttpStreamFactory* http_stream_factory = session->http_stream_factory();
nharper8cdb0fb2016-04-22 21:34:5916362 http_stream_factory->PreconnectStreams(1, ssl_request);
dcheng48459ac22014-08-26 00:46:4116363 EXPECT_EQ(0, GetIdleSocketCountInSSLSocketPool(session.get()));
[email protected]043b68c82013-08-22 23:41:5216364
16365 // Start the HTTP request. Pool should stall.
16366 TestCompletionCallback http_callback;
bnc691fda62016-08-12 00:43:1616367 HttpNetworkTransaction http_trans(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:2016368 ASSERT_EQ(ERR_IO_PENDING,
16369 http_trans.Start(&http_request, http_callback.callback(),
16370 NetLogWithSource()));
dcheng48459ac22014-08-26 00:46:4116371 EXPECT_TRUE(IsTransportSocketPoolStalled(session.get()));
[email protected]043b68c82013-08-22 23:41:5216372
16373 // The SSL connection will automatically be closed once the connection is
16374 // established, to let the HTTP request start.
robpercival214763f2016-07-01 23:27:0116375 ASSERT_THAT(http_callback.WaitForResult(), IsOk());
[email protected]043b68c82013-08-22 23:41:5216376 std::string response_data;
bnc691fda62016-08-12 00:43:1616377 ASSERT_THAT(ReadTransaction(&http_trans, &response_data), IsOk());
[email protected]043b68c82013-08-22 23:41:5216378 EXPECT_EQ("falafel", response_data);
16379
dcheng48459ac22014-08-26 00:46:4116380 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]043b68c82013-08-22 23:41:5216381}
16382
bncd16676a2016-07-20 16:23:0116383TEST_F(HttpNetworkTransactionTest, PostReadsErrorResponseAfterReset) {
danakj1fd259a02016-04-16 03:17:0916384 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:2216385 element_readers.push_back(
Jeremy Roman0579ed62017-08-29 15:56:1916386 std::make_unique<UploadBytesElementReader>("foo", 3));
olli.raula6df48b2a2015-11-26 07:40:2216387 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]02d74a02014-04-23 18:10:5416388
16389 HttpRequestInfo request;
16390 request.method = "POST";
16391 request.url = GURL("http://www.foo.com/");
16392 request.upload_data_stream = &upload_data_stream;
[email protected]02d74a02014-04-23 18:10:5416393
danakj1fd259a02016-04-16 03:17:0916394 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1616395 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]02d74a02014-04-23 18:10:5416396 // Send headers successfully, but get an error while sending the body.
16397 MockWrite data_writes[] = {
16398 MockWrite("POST / HTTP/1.1\r\n"
16399 "Host: www.foo.com\r\n"
16400 "Connection: keep-alive\r\n"
16401 "Content-Length: 3\r\n\r\n"),
16402 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
16403 };
16404
16405 MockRead data_reads[] = {
16406 MockRead("HTTP/1.0 400 Not OK\r\n\r\n"),
16407 MockRead("hello world"),
16408 MockRead(SYNCHRONOUS, OK),
16409 };
16410 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
16411 arraysize(data_writes));
16412 session_deps_.socket_factory->AddSocketDataProvider(&data);
16413
16414 TestCompletionCallback callback;
16415
tfarina42834112016-09-22 13:38:2016416 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0116417 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]02d74a02014-04-23 18:10:5416418
16419 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0116420 EXPECT_THAT(rv, IsOk());
[email protected]02d74a02014-04-23 18:10:5416421
bnc691fda62016-08-12 00:43:1616422 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5216423 ASSERT_TRUE(response);
[email protected]02d74a02014-04-23 18:10:5416424
wezca1070932016-05-26 20:30:5216425 EXPECT_TRUE(response->headers);
[email protected]02d74a02014-04-23 18:10:5416426 EXPECT_EQ("HTTP/1.0 400 Not OK", response->headers->GetStatusLine());
16427
16428 std::string response_data;
bnc691fda62016-08-12 00:43:1616429 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:0116430 EXPECT_THAT(rv, IsOk());
[email protected]02d74a02014-04-23 18:10:5416431 EXPECT_EQ("hello world", response_data);
16432}
16433
16434// This test makes sure the retry logic doesn't trigger when reading an error
16435// response from a server that rejected a POST with a CONNECTION_RESET.
bncd16676a2016-07-20 16:23:0116436TEST_F(HttpNetworkTransactionTest,
[email protected]02d74a02014-04-23 18:10:5416437 PostReadsErrorResponseAfterResetOnReusedSocket) {
danakj1fd259a02016-04-16 03:17:0916438 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]02d74a02014-04-23 18:10:5416439 MockWrite data_writes[] = {
16440 MockWrite("GET / HTTP/1.1\r\n"
16441 "Host: www.foo.com\r\n"
16442 "Connection: keep-alive\r\n\r\n"),
16443 MockWrite("POST / HTTP/1.1\r\n"
16444 "Host: www.foo.com\r\n"
16445 "Connection: keep-alive\r\n"
16446 "Content-Length: 3\r\n\r\n"),
16447 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
16448 };
16449
16450 MockRead data_reads[] = {
16451 MockRead("HTTP/1.1 200 Peachy\r\n"
16452 "Content-Length: 14\r\n\r\n"),
16453 MockRead("first response"),
16454 MockRead("HTTP/1.1 400 Not OK\r\n"
16455 "Content-Length: 15\r\n\r\n"),
16456 MockRead("second response"),
16457 MockRead(SYNCHRONOUS, OK),
16458 };
16459 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
16460 arraysize(data_writes));
16461 session_deps_.socket_factory->AddSocketDataProvider(&data);
16462
16463 TestCompletionCallback callback;
16464 HttpRequestInfo request1;
16465 request1.method = "GET";
16466 request1.url = GURL("http://www.foo.com/");
16467 request1.load_flags = 0;
16468
bnc87dcefc2017-05-25 12:47:5816469 auto trans1 =
Jeremy Roman0579ed62017-08-29 15:56:1916470 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:2016471 int rv = trans1->Start(&request1, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0116472 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]02d74a02014-04-23 18:10:5416473
16474 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0116475 EXPECT_THAT(rv, IsOk());
[email protected]02d74a02014-04-23 18:10:5416476
16477 const HttpResponseInfo* response1 = trans1->GetResponseInfo();
wezca1070932016-05-26 20:30:5216478 ASSERT_TRUE(response1);
[email protected]02d74a02014-04-23 18:10:5416479
wezca1070932016-05-26 20:30:5216480 EXPECT_TRUE(response1->headers);
[email protected]02d74a02014-04-23 18:10:5416481 EXPECT_EQ("HTTP/1.1 200 Peachy", response1->headers->GetStatusLine());
16482
16483 std::string response_data1;
16484 rv = ReadTransaction(trans1.get(), &response_data1);
robpercival214763f2016-07-01 23:27:0116485 EXPECT_THAT(rv, IsOk());
[email protected]02d74a02014-04-23 18:10:5416486 EXPECT_EQ("first response", response_data1);
16487 // Delete the transaction to release the socket back into the socket pool.
16488 trans1.reset();
16489
danakj1fd259a02016-04-16 03:17:0916490 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:2216491 element_readers.push_back(
Jeremy Roman0579ed62017-08-29 15:56:1916492 std::make_unique<UploadBytesElementReader>("foo", 3));
olli.raula6df48b2a2015-11-26 07:40:2216493 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]02d74a02014-04-23 18:10:5416494
16495 HttpRequestInfo request2;
16496 request2.method = "POST";
16497 request2.url = GURL("http://www.foo.com/");
16498 request2.upload_data_stream = &upload_data_stream;
16499 request2.load_flags = 0;
16500
bnc691fda62016-08-12 00:43:1616501 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:2016502 rv = trans2.Start(&request2, 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
bnc691fda62016-08-12 00:43:1616508 const HttpResponseInfo* response2 = trans2.GetResponseInfo();
wezca1070932016-05-26 20:30:5216509 ASSERT_TRUE(response2);
[email protected]02d74a02014-04-23 18:10:5416510
wezca1070932016-05-26 20:30:5216511 EXPECT_TRUE(response2->headers);
[email protected]02d74a02014-04-23 18:10:5416512 EXPECT_EQ("HTTP/1.1 400 Not OK", response2->headers->GetStatusLine());
16513
16514 std::string response_data2;
bnc691fda62016-08-12 00:43:1616515 rv = ReadTransaction(&trans2, &response_data2);
robpercival214763f2016-07-01 23:27:0116516 EXPECT_THAT(rv, IsOk());
[email protected]02d74a02014-04-23 18:10:5416517 EXPECT_EQ("second response", response_data2);
16518}
16519
bncd16676a2016-07-20 16:23:0116520TEST_F(HttpNetworkTransactionTest,
[email protected]02d74a02014-04-23 18:10:5416521 PostReadsErrorResponseAfterResetPartialBodySent) {
danakj1fd259a02016-04-16 03:17:0916522 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:2216523 element_readers.push_back(
Jeremy Roman0579ed62017-08-29 15:56:1916524 std::make_unique<UploadBytesElementReader>("foo", 3));
olli.raula6df48b2a2015-11-26 07:40:2216525 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]02d74a02014-04-23 18:10:5416526
16527 HttpRequestInfo request;
16528 request.method = "POST";
16529 request.url = GURL("http://www.foo.com/");
16530 request.upload_data_stream = &upload_data_stream;
[email protected]02d74a02014-04-23 18:10:5416531
danakj1fd259a02016-04-16 03:17:0916532 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1616533 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]02d74a02014-04-23 18:10:5416534 // Send headers successfully, but get an error while sending the body.
16535 MockWrite data_writes[] = {
16536 MockWrite("POST / HTTP/1.1\r\n"
16537 "Host: www.foo.com\r\n"
16538 "Connection: keep-alive\r\n"
16539 "Content-Length: 3\r\n\r\n"
16540 "fo"),
16541 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
16542 };
16543
16544 MockRead data_reads[] = {
16545 MockRead("HTTP/1.0 400 Not OK\r\n\r\n"),
16546 MockRead("hello world"),
16547 MockRead(SYNCHRONOUS, OK),
16548 };
16549 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
16550 arraysize(data_writes));
16551 session_deps_.socket_factory->AddSocketDataProvider(&data);
16552
16553 TestCompletionCallback callback;
16554
tfarina42834112016-09-22 13:38:2016555 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0116556 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]02d74a02014-04-23 18:10:5416557
16558 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0116559 EXPECT_THAT(rv, IsOk());
[email protected]02d74a02014-04-23 18:10:5416560
bnc691fda62016-08-12 00:43:1616561 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5216562 ASSERT_TRUE(response);
[email protected]02d74a02014-04-23 18:10:5416563
wezca1070932016-05-26 20:30:5216564 EXPECT_TRUE(response->headers);
[email protected]02d74a02014-04-23 18:10:5416565 EXPECT_EQ("HTTP/1.0 400 Not OK", response->headers->GetStatusLine());
16566
16567 std::string response_data;
bnc691fda62016-08-12 00:43:1616568 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:0116569 EXPECT_THAT(rv, IsOk());
[email protected]02d74a02014-04-23 18:10:5416570 EXPECT_EQ("hello world", response_data);
16571}
16572
16573// This tests the more common case than the previous test, where headers and
16574// body are not merged into a single request.
bncd16676a2016-07-20 16:23:0116575TEST_F(HttpNetworkTransactionTest, ChunkedPostReadsErrorResponseAfterReset) {
mmenkecbc2b712014-10-09 20:29:0716576 ChunkedUploadDataStream upload_data_stream(0);
[email protected]02d74a02014-04-23 18:10:5416577
16578 HttpRequestInfo request;
16579 request.method = "POST";
16580 request.url = GURL("http://www.foo.com/");
16581 request.upload_data_stream = &upload_data_stream;
[email protected]02d74a02014-04-23 18:10:5416582
danakj1fd259a02016-04-16 03:17:0916583 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1616584 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]02d74a02014-04-23 18:10:5416585 // Send headers successfully, but get an error while sending the body.
16586 MockWrite data_writes[] = {
16587 MockWrite("POST / HTTP/1.1\r\n"
16588 "Host: www.foo.com\r\n"
16589 "Connection: keep-alive\r\n"
16590 "Transfer-Encoding: chunked\r\n\r\n"),
16591 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
16592 };
16593
16594 MockRead data_reads[] = {
16595 MockRead("HTTP/1.0 400 Not OK\r\n\r\n"),
16596 MockRead("hello world"),
16597 MockRead(SYNCHRONOUS, OK),
16598 };
16599 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
16600 arraysize(data_writes));
16601 session_deps_.socket_factory->AddSocketDataProvider(&data);
16602
16603 TestCompletionCallback callback;
16604
tfarina42834112016-09-22 13:38:2016605 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0116606 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]02d74a02014-04-23 18:10:5416607 // Make sure the headers are sent before adding a chunk. This ensures that
16608 // they can't be merged with the body in a single send. Not currently
16609 // necessary since a chunked body is never merged with headers, but this makes
16610 // the test more future proof.
16611 base::RunLoop().RunUntilIdle();
16612
mmenkecbc2b712014-10-09 20:29:0716613 upload_data_stream.AppendData("last chunk", 10, true);
[email protected]02d74a02014-04-23 18:10:5416614
16615 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0116616 EXPECT_THAT(rv, IsOk());
[email protected]02d74a02014-04-23 18:10:5416617
bnc691fda62016-08-12 00:43:1616618 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5216619 ASSERT_TRUE(response);
[email protected]02d74a02014-04-23 18:10:5416620
wezca1070932016-05-26 20:30:5216621 EXPECT_TRUE(response->headers);
[email protected]02d74a02014-04-23 18:10:5416622 EXPECT_EQ("HTTP/1.0 400 Not OK", response->headers->GetStatusLine());
16623
16624 std::string response_data;
bnc691fda62016-08-12 00:43:1616625 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:0116626 EXPECT_THAT(rv, IsOk());
[email protected]02d74a02014-04-23 18:10:5416627 EXPECT_EQ("hello world", response_data);
16628}
16629
bncd16676a2016-07-20 16:23:0116630TEST_F(HttpNetworkTransactionTest, PostReadsErrorResponseAfterResetAnd100) {
danakj1fd259a02016-04-16 03:17:0916631 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:2216632 element_readers.push_back(
Jeremy Roman0579ed62017-08-29 15:56:1916633 std::make_unique<UploadBytesElementReader>("foo", 3));
olli.raula6df48b2a2015-11-26 07:40:2216634 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]02d74a02014-04-23 18:10:5416635
16636 HttpRequestInfo request;
16637 request.method = "POST";
16638 request.url = GURL("http://www.foo.com/");
16639 request.upload_data_stream = &upload_data_stream;
[email protected]02d74a02014-04-23 18:10:5416640
danakj1fd259a02016-04-16 03:17:0916641 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1616642 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]02d74a02014-04-23 18:10:5416643
16644 MockWrite data_writes[] = {
16645 MockWrite("POST / HTTP/1.1\r\n"
16646 "Host: www.foo.com\r\n"
16647 "Connection: keep-alive\r\n"
16648 "Content-Length: 3\r\n\r\n"),
16649 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
16650 };
16651
16652 MockRead data_reads[] = {
16653 MockRead("HTTP/1.0 100 Continue\r\n\r\n"),
16654 MockRead("HTTP/1.0 400 Not OK\r\n\r\n"),
16655 MockRead("hello world"),
16656 MockRead(SYNCHRONOUS, OK),
16657 };
16658 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
16659 arraysize(data_writes));
16660 session_deps_.socket_factory->AddSocketDataProvider(&data);
16661
16662 TestCompletionCallback callback;
16663
tfarina42834112016-09-22 13:38:2016664 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0116665 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]02d74a02014-04-23 18:10:5416666
16667 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0116668 EXPECT_THAT(rv, IsOk());
[email protected]02d74a02014-04-23 18:10:5416669
bnc691fda62016-08-12 00:43:1616670 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5216671 ASSERT_TRUE(response);
[email protected]02d74a02014-04-23 18:10:5416672
wezca1070932016-05-26 20:30:5216673 EXPECT_TRUE(response->headers);
[email protected]02d74a02014-04-23 18:10:5416674 EXPECT_EQ("HTTP/1.0 400 Not OK", response->headers->GetStatusLine());
16675
16676 std::string response_data;
bnc691fda62016-08-12 00:43:1616677 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:0116678 EXPECT_THAT(rv, IsOk());
[email protected]02d74a02014-04-23 18:10:5416679 EXPECT_EQ("hello world", response_data);
16680}
16681
bncd16676a2016-07-20 16:23:0116682TEST_F(HttpNetworkTransactionTest, PostIgnoresNonErrorResponseAfterReset) {
danakj1fd259a02016-04-16 03:17:0916683 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:2216684 element_readers.push_back(
Jeremy Roman0579ed62017-08-29 15:56:1916685 std::make_unique<UploadBytesElementReader>("foo", 3));
olli.raula6df48b2a2015-11-26 07:40:2216686 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]02d74a02014-04-23 18:10:5416687
16688 HttpRequestInfo request;
16689 request.method = "POST";
16690 request.url = GURL("http://www.foo.com/");
16691 request.upload_data_stream = &upload_data_stream;
[email protected]02d74a02014-04-23 18:10:5416692
danakj1fd259a02016-04-16 03:17:0916693 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1616694 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]02d74a02014-04-23 18:10:5416695 // Send headers successfully, but get an error while sending the body.
16696 MockWrite data_writes[] = {
16697 MockWrite("POST / HTTP/1.1\r\n"
16698 "Host: www.foo.com\r\n"
16699 "Connection: keep-alive\r\n"
16700 "Content-Length: 3\r\n\r\n"),
16701 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
16702 };
16703
16704 MockRead data_reads[] = {
16705 MockRead("HTTP/1.0 200 Just Dandy\r\n\r\n"),
16706 MockRead("hello world"),
16707 MockRead(SYNCHRONOUS, OK),
16708 };
16709 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
16710 arraysize(data_writes));
16711 session_deps_.socket_factory->AddSocketDataProvider(&data);
16712
16713 TestCompletionCallback callback;
16714
tfarina42834112016-09-22 13:38:2016715 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0116716 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]02d74a02014-04-23 18:10:5416717
16718 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0116719 EXPECT_THAT(rv, IsError(ERR_CONNECTION_RESET));
[email protected]02d74a02014-04-23 18:10:5416720}
16721
bncd16676a2016-07-20 16:23:0116722TEST_F(HttpNetworkTransactionTest,
[email protected]02d74a02014-04-23 18:10:5416723 PostIgnoresNonErrorResponseAfterResetAnd100) {
danakj1fd259a02016-04-16 03:17:0916724 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:2216725 element_readers.push_back(
Jeremy Roman0579ed62017-08-29 15:56:1916726 std::make_unique<UploadBytesElementReader>("foo", 3));
olli.raula6df48b2a2015-11-26 07:40:2216727 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]02d74a02014-04-23 18:10:5416728
16729 HttpRequestInfo request;
16730 request.method = "POST";
16731 request.url = GURL("http://www.foo.com/");
16732 request.upload_data_stream = &upload_data_stream;
[email protected]02d74a02014-04-23 18:10:5416733
danakj1fd259a02016-04-16 03:17:0916734 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1616735 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]02d74a02014-04-23 18:10:5416736 // Send headers successfully, but get an error while sending the body.
16737 MockWrite data_writes[] = {
16738 MockWrite("POST / HTTP/1.1\r\n"
16739 "Host: www.foo.com\r\n"
16740 "Connection: keep-alive\r\n"
16741 "Content-Length: 3\r\n\r\n"),
16742 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
16743 };
16744
16745 MockRead data_reads[] = {
16746 MockRead("HTTP/1.0 100 Continue\r\n\r\n"),
16747 MockRead("HTTP/1.0 302 Redirect\r\n"),
16748 MockRead("Location: http://somewhere-else.com/\r\n"),
16749 MockRead("Content-Length: 0\r\n\r\n"),
16750 MockRead(SYNCHRONOUS, OK),
16751 };
16752 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
16753 arraysize(data_writes));
16754 session_deps_.socket_factory->AddSocketDataProvider(&data);
16755
16756 TestCompletionCallback callback;
16757
tfarina42834112016-09-22 13:38:2016758 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0116759 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]02d74a02014-04-23 18:10:5416760
16761 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0116762 EXPECT_THAT(rv, IsError(ERR_CONNECTION_RESET));
[email protected]02d74a02014-04-23 18:10:5416763}
16764
bncd16676a2016-07-20 16:23:0116765TEST_F(HttpNetworkTransactionTest, PostIgnoresHttp09ResponseAfterReset) {
danakj1fd259a02016-04-16 03:17:0916766 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:2216767 element_readers.push_back(
Jeremy Roman0579ed62017-08-29 15:56:1916768 std::make_unique<UploadBytesElementReader>("foo", 3));
olli.raula6df48b2a2015-11-26 07:40:2216769 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]02d74a02014-04-23 18:10:5416770
16771 HttpRequestInfo request;
16772 request.method = "POST";
16773 request.url = GURL("http://www.foo.com/");
16774 request.upload_data_stream = &upload_data_stream;
[email protected]02d74a02014-04-23 18:10:5416775
danakj1fd259a02016-04-16 03:17:0916776 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1616777 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]02d74a02014-04-23 18:10:5416778 // Send headers successfully, but get an error while sending the body.
16779 MockWrite data_writes[] = {
16780 MockWrite("POST / HTTP/1.1\r\n"
16781 "Host: www.foo.com\r\n"
16782 "Connection: keep-alive\r\n"
16783 "Content-Length: 3\r\n\r\n"),
16784 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
16785 };
16786
16787 MockRead data_reads[] = {
16788 MockRead("HTTP 0.9 rocks!"),
16789 MockRead(SYNCHRONOUS, OK),
16790 };
16791 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
16792 arraysize(data_writes));
16793 session_deps_.socket_factory->AddSocketDataProvider(&data);
16794
16795 TestCompletionCallback callback;
16796
tfarina42834112016-09-22 13:38:2016797 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0116798 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]02d74a02014-04-23 18:10:5416799
16800 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0116801 EXPECT_THAT(rv, IsError(ERR_CONNECTION_RESET));
[email protected]02d74a02014-04-23 18:10:5416802}
16803
bncd16676a2016-07-20 16:23:0116804TEST_F(HttpNetworkTransactionTest, PostIgnoresPartial400HeadersAfterReset) {
danakj1fd259a02016-04-16 03:17:0916805 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:2216806 element_readers.push_back(
Jeremy Roman0579ed62017-08-29 15:56:1916807 std::make_unique<UploadBytesElementReader>("foo", 3));
olli.raula6df48b2a2015-11-26 07:40:2216808 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]02d74a02014-04-23 18:10:5416809
16810 HttpRequestInfo request;
16811 request.method = "POST";
16812 request.url = GURL("http://www.foo.com/");
16813 request.upload_data_stream = &upload_data_stream;
[email protected]02d74a02014-04-23 18:10:5416814
danakj1fd259a02016-04-16 03:17:0916815 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1616816 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]02d74a02014-04-23 18:10:5416817 // Send headers successfully, but get an error while sending the body.
16818 MockWrite data_writes[] = {
16819 MockWrite("POST / HTTP/1.1\r\n"
16820 "Host: www.foo.com\r\n"
16821 "Connection: keep-alive\r\n"
16822 "Content-Length: 3\r\n\r\n"),
16823 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
16824 };
16825
16826 MockRead data_reads[] = {
16827 MockRead("HTTP/1.0 400 Not a Full Response\r\n"),
16828 MockRead(SYNCHRONOUS, OK),
16829 };
16830 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
16831 arraysize(data_writes));
16832 session_deps_.socket_factory->AddSocketDataProvider(&data);
16833
16834 TestCompletionCallback callback;
16835
tfarina42834112016-09-22 13:38:2016836 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0116837 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]02d74a02014-04-23 18:10:5416838
16839 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0116840 EXPECT_THAT(rv, IsError(ERR_CONNECTION_RESET));
[email protected]02d74a02014-04-23 18:10:5416841}
16842
Adam Rice425cf122015-01-19 06:18:2416843// Verify that proxy headers are not sent to the destination server when
16844// establishing a tunnel for a secure WebSocket connection.
bncd16676a2016-07-20 16:23:0116845TEST_F(HttpNetworkTransactionTest, ProxyHeadersNotSentOverWssTunnel) {
Adam Rice425cf122015-01-19 06:18:2416846 HttpRequestInfo request;
16847 request.method = "GET";
bncce36dca22015-04-21 22:11:2316848 request.url = GURL("wss://www.example.org/");
Adam Rice425cf122015-01-19 06:18:2416849 AddWebSocketHeaders(&request.extra_headers);
16850
16851 // Configure against proxy server "myproxy:70".
rdsmith82957ad2015-09-16 19:42:0316852 session_deps_.proxy_service =
16853 ProxyService::CreateFixedFromPacResult("PROXY myproxy:70");
Adam Rice425cf122015-01-19 06:18:2416854
danakj1fd259a02016-04-16 03:17:0916855 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
Adam Rice425cf122015-01-19 06:18:2416856
16857 // Since a proxy is configured, try to establish a tunnel.
16858 MockWrite data_writes[] = {
rsleevidb16bb02015-11-12 23:47:1716859 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
16860 "Host: www.example.org:443\r\n"
16861 "Proxy-Connection: keep-alive\r\n\r\n"),
Adam Rice425cf122015-01-19 06:18:2416862
16863 // After calling trans->RestartWithAuth(), this is the request we should
16864 // be issuing -- the final header line contains the credentials.
rsleevidb16bb02015-11-12 23:47:1716865 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
16866 "Host: www.example.org:443\r\n"
16867 "Proxy-Connection: keep-alive\r\n"
16868 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
Adam Rice425cf122015-01-19 06:18:2416869
rsleevidb16bb02015-11-12 23:47:1716870 MockWrite("GET / HTTP/1.1\r\n"
16871 "Host: www.example.org\r\n"
16872 "Connection: Upgrade\r\n"
16873 "Upgrade: websocket\r\n"
16874 "Origin: http://www.example.org\r\n"
16875 "Sec-WebSocket-Version: 13\r\n"
16876 "Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==\r\n\r\n"),
Adam Rice425cf122015-01-19 06:18:2416877 };
16878
16879 // The proxy responds to the connect with a 407, using a persistent
16880 // connection.
16881 MockRead data_reads[] = {
16882 // No credentials.
16883 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
16884 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
mmenkee71e15332015-10-07 16:39:5416885 MockRead("Content-Length: 0\r\n"),
16886 MockRead("Proxy-Connection: keep-alive\r\n\r\n"),
Adam Rice425cf122015-01-19 06:18:2416887
16888 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
16889
16890 MockRead("HTTP/1.1 101 Switching Protocols\r\n"),
16891 MockRead("Upgrade: websocket\r\n"),
16892 MockRead("Connection: Upgrade\r\n"),
16893 MockRead("Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=\r\n\r\n"),
16894 };
16895
16896 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
16897 arraysize(data_writes));
16898 session_deps_.socket_factory->AddSocketDataProvider(&data);
16899 SSLSocketDataProvider ssl(ASYNC, OK);
16900 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
16901
bnc87dcefc2017-05-25 12:47:5816902 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:1916903 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
Adam Rice425cf122015-01-19 06:18:2416904 FakeWebSocketStreamCreateHelper websocket_stream_create_helper;
16905 trans->SetWebSocketHandshakeStreamCreateHelper(
16906 &websocket_stream_create_helper);
16907
16908 {
16909 TestCompletionCallback callback;
16910
tfarina42834112016-09-22 13:38:2016911 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0116912 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
Adam Rice425cf122015-01-19 06:18:2416913
16914 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0116915 EXPECT_THAT(rv, IsOk());
Adam Rice425cf122015-01-19 06:18:2416916 }
16917
16918 const HttpResponseInfo* response = trans->GetResponseInfo();
16919 ASSERT_TRUE(response);
wezca1070932016-05-26 20:30:5216920 ASSERT_TRUE(response->headers);
Adam Rice425cf122015-01-19 06:18:2416921 EXPECT_EQ(407, response->headers->response_code());
16922
16923 {
16924 TestCompletionCallback callback;
16925
16926 int rv = trans->RestartWithAuth(AuthCredentials(kFoo, kBar),
16927 callback.callback());
robpercival214763f2016-07-01 23:27:0116928 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
Adam Rice425cf122015-01-19 06:18:2416929
16930 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0116931 EXPECT_THAT(rv, IsOk());
Adam Rice425cf122015-01-19 06:18:2416932 }
16933
16934 response = trans->GetResponseInfo();
16935 ASSERT_TRUE(response);
wezca1070932016-05-26 20:30:5216936 ASSERT_TRUE(response->headers);
Adam Rice425cf122015-01-19 06:18:2416937
16938 EXPECT_EQ(101, response->headers->response_code());
16939
16940 trans.reset();
16941 session->CloseAllConnections();
16942}
16943
16944// Verify that proxy headers are not sent to the destination server when
16945// establishing a tunnel for an insecure WebSocket connection.
16946// This requires the authentication info to be injected into the auth cache
16947// due to crbug.com/395064
16948// TODO(ricea): Change to use a 407 response once issue 395064 is fixed.
bncd16676a2016-07-20 16:23:0116949TEST_F(HttpNetworkTransactionTest, ProxyHeadersNotSentOverWsTunnel) {
Adam Rice425cf122015-01-19 06:18:2416950 HttpRequestInfo request;
16951 request.method = "GET";
bncce36dca22015-04-21 22:11:2316952 request.url = GURL("ws://www.example.org/");
Adam Rice425cf122015-01-19 06:18:2416953 AddWebSocketHeaders(&request.extra_headers);
16954
16955 // Configure against proxy server "myproxy:70".
rdsmith82957ad2015-09-16 19:42:0316956 session_deps_.proxy_service =
16957 ProxyService::CreateFixedFromPacResult("PROXY myproxy:70");
Adam Rice425cf122015-01-19 06:18:2416958
danakj1fd259a02016-04-16 03:17:0916959 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
Adam Rice425cf122015-01-19 06:18:2416960
16961 MockWrite data_writes[] = {
16962 // Try to establish a tunnel for the WebSocket connection, with
16963 // credentials. Because WebSockets have a separate set of socket pools,
16964 // they cannot and will not use the same TCP/IP connection as the
16965 // preflight HTTP request.
16966 MockWrite(
bncce36dca22015-04-21 22:11:2316967 "CONNECT www.example.org:80 HTTP/1.1\r\n"
16968 "Host: www.example.org:80\r\n"
Adam Rice425cf122015-01-19 06:18:2416969 "Proxy-Connection: keep-alive\r\n"
16970 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
16971
16972 MockWrite(
16973 "GET / HTTP/1.1\r\n"
bncce36dca22015-04-21 22:11:2316974 "Host: www.example.org\r\n"
Adam Rice425cf122015-01-19 06:18:2416975 "Connection: Upgrade\r\n"
16976 "Upgrade: websocket\r\n"
bncce36dca22015-04-21 22:11:2316977 "Origin: http://www.example.org\r\n"
Adam Rice425cf122015-01-19 06:18:2416978 "Sec-WebSocket-Version: 13\r\n"
16979 "Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==\r\n\r\n"),
16980 };
16981
16982 MockRead data_reads[] = {
16983 // HTTP CONNECT with credentials.
16984 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
16985
16986 // WebSocket connection established inside tunnel.
16987 MockRead("HTTP/1.1 101 Switching Protocols\r\n"),
16988 MockRead("Upgrade: websocket\r\n"),
16989 MockRead("Connection: Upgrade\r\n"),
16990 MockRead("Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=\r\n\r\n"),
16991 };
16992
16993 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
16994 arraysize(data_writes));
16995 session_deps_.socket_factory->AddSocketDataProvider(&data);
16996
16997 session->http_auth_cache()->Add(
16998 GURL("http://myproxy:70/"), "MyRealm1", HttpAuth::AUTH_SCHEME_BASIC,
16999 "Basic realm=MyRealm1", AuthCredentials(kFoo, kBar), "/");
17000
bnc87dcefc2017-05-25 12:47:5817001 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:1917002 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
Adam Rice425cf122015-01-19 06:18:2417003 FakeWebSocketStreamCreateHelper websocket_stream_create_helper;
17004 trans->SetWebSocketHandshakeStreamCreateHelper(
17005 &websocket_stream_create_helper);
17006
17007 TestCompletionCallback callback;
17008
tfarina42834112016-09-22 13:38:2017009 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0117010 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
Adam Rice425cf122015-01-19 06:18:2417011
17012 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0117013 EXPECT_THAT(rv, IsOk());
Adam Rice425cf122015-01-19 06:18:2417014
17015 const HttpResponseInfo* response = trans->GetResponseInfo();
17016 ASSERT_TRUE(response);
wezca1070932016-05-26 20:30:5217017 ASSERT_TRUE(response->headers);
Adam Rice425cf122015-01-19 06:18:2417018
17019 EXPECT_EQ(101, response->headers->response_code());
17020
17021 trans.reset();
17022 session->CloseAllConnections();
17023}
17024
bncd16676a2016-07-20 16:23:0117025TEST_F(HttpNetworkTransactionTest, TotalNetworkBytesPost) {
danakj1fd259a02016-04-16 03:17:0917026 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:2217027 element_readers.push_back(
Jeremy Roman0579ed62017-08-29 15:56:1917028 std::make_unique<UploadBytesElementReader>("foo", 3));
olli.raula6df48b2a2015-11-26 07:40:2217029 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
sclittlefb249892015-09-10 21:33:2217030
17031 HttpRequestInfo request;
17032 request.method = "POST";
17033 request.url = GURL("http://www.foo.com/");
17034 request.upload_data_stream = &upload_data_stream;
17035
danakj1fd259a02016-04-16 03:17:0917036 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1617037 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
sclittlefb249892015-09-10 21:33:2217038 MockWrite data_writes[] = {
17039 MockWrite("POST / HTTP/1.1\r\n"
17040 "Host: www.foo.com\r\n"
17041 "Connection: keep-alive\r\n"
17042 "Content-Length: 3\r\n\r\n"),
17043 MockWrite("foo"),
17044 };
17045
17046 MockRead data_reads[] = {
17047 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello world"),
17048 MockRead(SYNCHRONOUS, OK),
17049 };
17050 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
17051 arraysize(data_writes));
17052 session_deps_.socket_factory->AddSocketDataProvider(&data);
17053
17054 TestCompletionCallback callback;
17055
17056 EXPECT_EQ(ERR_IO_PENDING,
tfarina42834112016-09-22 13:38:2017057 trans.Start(&request, callback.callback(), NetLogWithSource()));
robpercival214763f2016-07-01 23:27:0117058 EXPECT_THAT(callback.WaitForResult(), IsOk());
sclittlefb249892015-09-10 21:33:2217059
17060 std::string response_data;
bnc691fda62016-08-12 00:43:1617061 EXPECT_THAT(ReadTransaction(&trans, &response_data), IsOk());
sclittlefb249892015-09-10 21:33:2217062
17063 EXPECT_EQ(CountWriteBytes(data_writes, arraysize(data_writes)),
bnc691fda62016-08-12 00:43:1617064 trans.GetTotalSentBytes());
sclittlefb249892015-09-10 21:33:2217065 EXPECT_EQ(CountReadBytes(data_reads, arraysize(data_reads)),
bnc691fda62016-08-12 00:43:1617066 trans.GetTotalReceivedBytes());
sclittlefb249892015-09-10 21:33:2217067}
17068
bncd16676a2016-07-20 16:23:0117069TEST_F(HttpNetworkTransactionTest, TotalNetworkBytesPost100Continue) {
danakj1fd259a02016-04-16 03:17:0917070 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:2217071 element_readers.push_back(
Jeremy Roman0579ed62017-08-29 15:56:1917072 std::make_unique<UploadBytesElementReader>("foo", 3));
olli.raula6df48b2a2015-11-26 07:40:2217073 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
sclittlefb249892015-09-10 21:33:2217074
17075 HttpRequestInfo request;
17076 request.method = "POST";
17077 request.url = GURL("http://www.foo.com/");
17078 request.upload_data_stream = &upload_data_stream;
17079
danakj1fd259a02016-04-16 03:17:0917080 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1617081 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
sclittlefb249892015-09-10 21:33:2217082 MockWrite data_writes[] = {
17083 MockWrite("POST / HTTP/1.1\r\n"
17084 "Host: www.foo.com\r\n"
17085 "Connection: keep-alive\r\n"
17086 "Content-Length: 3\r\n\r\n"),
17087 MockWrite("foo"),
17088 };
17089
17090 MockRead data_reads[] = {
17091 MockRead("HTTP/1.1 100 Continue\r\n\r\n"),
17092 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello world"),
17093 MockRead(SYNCHRONOUS, OK),
17094 };
17095 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
17096 arraysize(data_writes));
17097 session_deps_.socket_factory->AddSocketDataProvider(&data);
17098
17099 TestCompletionCallback callback;
17100
17101 EXPECT_EQ(ERR_IO_PENDING,
tfarina42834112016-09-22 13:38:2017102 trans.Start(&request, callback.callback(), NetLogWithSource()));
robpercival214763f2016-07-01 23:27:0117103 EXPECT_THAT(callback.WaitForResult(), IsOk());
sclittlefb249892015-09-10 21:33:2217104
17105 std::string response_data;
bnc691fda62016-08-12 00:43:1617106 EXPECT_THAT(ReadTransaction(&trans, &response_data), IsOk());
sclittlefb249892015-09-10 21:33:2217107
17108 EXPECT_EQ(CountWriteBytes(data_writes, arraysize(data_writes)),
bnc691fda62016-08-12 00:43:1617109 trans.GetTotalSentBytes());
sclittlefb249892015-09-10 21:33:2217110 EXPECT_EQ(CountReadBytes(data_reads, arraysize(data_reads)),
bnc691fda62016-08-12 00:43:1617111 trans.GetTotalReceivedBytes());
sclittlefb249892015-09-10 21:33:2217112}
17113
bncd16676a2016-07-20 16:23:0117114TEST_F(HttpNetworkTransactionTest, TotalNetworkBytesChunkedPost) {
sclittlefb249892015-09-10 21:33:2217115 ChunkedUploadDataStream upload_data_stream(0);
17116
17117 HttpRequestInfo request;
17118 request.method = "POST";
17119 request.url = GURL("http://www.foo.com/");
17120 request.upload_data_stream = &upload_data_stream;
17121
danakj1fd259a02016-04-16 03:17:0917122 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1617123 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
sclittlefb249892015-09-10 21:33:2217124 // Send headers successfully, but get an error while sending the body.
17125 MockWrite data_writes[] = {
17126 MockWrite("POST / HTTP/1.1\r\n"
17127 "Host: www.foo.com\r\n"
17128 "Connection: keep-alive\r\n"
17129 "Transfer-Encoding: chunked\r\n\r\n"),
17130 MockWrite("1\r\nf\r\n"), MockWrite("2\r\noo\r\n"), MockWrite("0\r\n\r\n"),
17131 };
17132
17133 MockRead data_reads[] = {
17134 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello world"),
17135 MockRead(SYNCHRONOUS, OK),
17136 };
17137 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
17138 arraysize(data_writes));
17139 session_deps_.socket_factory->AddSocketDataProvider(&data);
17140
17141 TestCompletionCallback callback;
17142
17143 EXPECT_EQ(ERR_IO_PENDING,
tfarina42834112016-09-22 13:38:2017144 trans.Start(&request, callback.callback(), NetLogWithSource()));
sclittlefb249892015-09-10 21:33:2217145
17146 base::RunLoop().RunUntilIdle();
17147 upload_data_stream.AppendData("f", 1, false);
17148
17149 base::RunLoop().RunUntilIdle();
17150 upload_data_stream.AppendData("oo", 2, true);
17151
robpercival214763f2016-07-01 23:27:0117152 EXPECT_THAT(callback.WaitForResult(), IsOk());
sclittlefb249892015-09-10 21:33:2217153
17154 std::string response_data;
bnc691fda62016-08-12 00:43:1617155 EXPECT_THAT(ReadTransaction(&trans, &response_data), IsOk());
sclittlefb249892015-09-10 21:33:2217156
17157 EXPECT_EQ(CountWriteBytes(data_writes, arraysize(data_writes)),
bnc691fda62016-08-12 00:43:1617158 trans.GetTotalSentBytes());
sclittlefb249892015-09-10 21:33:2217159 EXPECT_EQ(CountReadBytes(data_reads, arraysize(data_reads)),
bnc691fda62016-08-12 00:43:1617160 trans.GetTotalReceivedBytes());
sclittlefb249892015-09-10 21:33:2217161}
17162
rdsmith1d343be52016-10-21 20:37:5017163// Confirm that transactions whose throttle is created in (and stays in)
17164// the unthrottled state are not blocked.
17165TEST_F(HttpNetworkTransactionTest, ThrottlingUnthrottled) {
17166 TestNetworkStreamThrottler* throttler(nullptr);
17167 std::unique_ptr<HttpNetworkSession> session(
17168 CreateSessionWithThrottler(&session_deps_, &throttler));
17169
17170 // Send a simple request and make sure it goes through.
17171 HttpRequestInfo request;
17172 request.method = "GET";
17173 request.url = GURL("http://www.example.org/");
17174
bnc87dcefc2017-05-25 12:47:5817175 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:1917176 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
rdsmith1d343be52016-10-21 20:37:5017177
17178 MockWrite data_writes[] = {
17179 MockWrite("GET / HTTP/1.1\r\n"
17180 "Host: www.example.org\r\n"
17181 "Connection: keep-alive\r\n\r\n"),
17182 };
17183 MockRead data_reads[] = {
17184 MockRead("HTTP/1.0 200 OK\r\n\r\n"), MockRead("hello world"),
17185 MockRead(SYNCHRONOUS, OK),
17186 };
17187 StaticSocketDataProvider reads(data_reads, arraysize(data_reads), data_writes,
17188 arraysize(data_writes));
17189 session_deps_.socket_factory->AddSocketDataProvider(&reads);
17190
17191 TestCompletionCallback callback;
17192 trans->Start(&request, callback.callback(), NetLogWithSource());
17193 EXPECT_EQ(OK, callback.WaitForResult());
17194}
17195
17196// Confirm requests can be blocked by a throttler, and are resumed
17197// when the throttle is unblocked.
17198TEST_F(HttpNetworkTransactionTest, ThrottlingBasic) {
17199 TestNetworkStreamThrottler* throttler(nullptr);
17200 std::unique_ptr<HttpNetworkSession> session(
17201 CreateSessionWithThrottler(&session_deps_, &throttler));
17202
17203 // Send a simple request and make sure it goes through.
17204 HttpRequestInfo request;
17205 request.method = "GET";
17206 request.url = GURL("http://www.example.org/");
17207
17208 MockWrite data_writes[] = {
17209 MockWrite("GET / HTTP/1.1\r\n"
17210 "Host: www.example.org\r\n"
17211 "Connection: keep-alive\r\n\r\n"),
17212 };
17213 MockRead data_reads[] = {
17214 MockRead("HTTP/1.0 200 OK\r\n\r\n"), MockRead("hello world"),
17215 MockRead(SYNCHRONOUS, OK),
17216 };
17217 StaticSocketDataProvider reads(data_reads, arraysize(data_reads), data_writes,
17218 arraysize(data_writes));
17219 session_deps_.socket_factory->AddSocketDataProvider(&reads);
17220
17221 // Start a request that will be throttled at start; confirm it
17222 // doesn't complete.
17223 throttler->set_throttle_new_requests(true);
bnc87dcefc2017-05-25 12:47:5817224 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:1917225 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
rdsmith1d343be52016-10-21 20:37:5017226
17227 TestCompletionCallback callback;
17228 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
17229 EXPECT_EQ(ERR_IO_PENDING, rv);
17230
17231 base::RunLoop().RunUntilIdle();
17232 EXPECT_EQ(LOAD_STATE_THROTTLED, trans->GetLoadState());
17233 EXPECT_FALSE(callback.have_result());
17234
17235 // Confirm the request goes on to complete when unthrottled.
17236 throttler->UnthrottleAllRequests();
17237 base::RunLoop().RunUntilIdle();
17238 ASSERT_TRUE(callback.have_result());
17239 EXPECT_EQ(OK, callback.WaitForResult());
17240}
17241
17242// Destroy a request while it's throttled.
17243TEST_F(HttpNetworkTransactionTest, ThrottlingDestruction) {
17244 TestNetworkStreamThrottler* throttler(nullptr);
17245 std::unique_ptr<HttpNetworkSession> session(
17246 CreateSessionWithThrottler(&session_deps_, &throttler));
17247
17248 // Send a simple request and make sure it goes through.
17249 HttpRequestInfo request;
17250 request.method = "GET";
17251 request.url = GURL("http://www.example.org/");
17252
17253 MockWrite data_writes[] = {
17254 MockWrite("GET / HTTP/1.1\r\n"
17255 "Host: www.example.org\r\n"
17256 "Connection: keep-alive\r\n\r\n"),
17257 };
17258 MockRead data_reads[] = {
17259 MockRead("HTTP/1.0 200 OK\r\n\r\n"), MockRead("hello world"),
17260 MockRead(SYNCHRONOUS, OK),
17261 };
17262 StaticSocketDataProvider reads(data_reads, arraysize(data_reads), data_writes,
17263 arraysize(data_writes));
17264 session_deps_.socket_factory->AddSocketDataProvider(&reads);
17265
17266 // Start a request that will be throttled at start; confirm it
17267 // doesn't complete.
17268 throttler->set_throttle_new_requests(true);
bnc87dcefc2017-05-25 12:47:5817269 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:1917270 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
rdsmith1d343be52016-10-21 20:37:5017271
17272 TestCompletionCallback callback;
17273 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
17274 EXPECT_EQ(ERR_IO_PENDING, rv);
17275
17276 base::RunLoop().RunUntilIdle();
17277 EXPECT_EQ(LOAD_STATE_THROTTLED, trans->GetLoadState());
17278 EXPECT_FALSE(callback.have_result());
17279
17280 EXPECT_EQ(1u, throttler->num_outstanding_requests());
17281 trans.reset();
17282 EXPECT_EQ(0u, throttler->num_outstanding_requests());
17283}
17284
17285// Confirm the throttler receives SetPriority calls.
17286TEST_F(HttpNetworkTransactionTest, ThrottlingPrioritySet) {
17287 TestNetworkStreamThrottler* throttler(nullptr);
17288 std::unique_ptr<HttpNetworkSession> session(
17289 CreateSessionWithThrottler(&session_deps_, &throttler));
17290
17291 // Send a simple request and make sure it goes through.
17292 HttpRequestInfo request;
17293 request.method = "GET";
17294 request.url = GURL("http://www.example.org/");
17295
17296 MockWrite data_writes[] = {
17297 MockWrite("GET / HTTP/1.1\r\n"
17298 "Host: www.example.org\r\n"
17299 "Connection: keep-alive\r\n\r\n"),
17300 };
17301 MockRead data_reads[] = {
17302 MockRead("HTTP/1.0 200 OK\r\n\r\n"), MockRead("hello world"),
17303 MockRead(SYNCHRONOUS, OK),
17304 };
17305 StaticSocketDataProvider reads(data_reads, arraysize(data_reads), data_writes,
17306 arraysize(data_writes));
17307 session_deps_.socket_factory->AddSocketDataProvider(&reads);
17308
17309 throttler->set_throttle_new_requests(true);
Jeremy Roman0579ed62017-08-29 15:56:1917310 auto trans = std::make_unique<HttpNetworkTransaction>(IDLE, session.get());
rdsmith1d343be52016-10-21 20:37:5017311 // Start the transaction to associate a throttle with it.
17312 TestCompletionCallback callback;
17313 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
17314 EXPECT_EQ(ERR_IO_PENDING, rv);
17315
17316 EXPECT_EQ(0, throttler->num_set_priority_calls());
17317 trans->SetPriority(LOW);
17318 EXPECT_EQ(1, throttler->num_set_priority_calls());
17319 EXPECT_EQ(LOW, throttler->last_priority_set());
17320
17321 throttler->UnthrottleAllRequests();
17322 base::RunLoop().RunUntilIdle();
17323 ASSERT_TRUE(callback.have_result());
17324 EXPECT_EQ(OK, callback.WaitForResult());
17325}
17326
17327// Confirm that unthrottling from a SetPriority call by the
17328// throttler works properly.
17329TEST_F(HttpNetworkTransactionTest, ThrottlingPrioritySetUnthrottle) {
17330 TestNetworkStreamThrottler* throttler(nullptr);
17331 std::unique_ptr<HttpNetworkSession> session(
17332 CreateSessionWithThrottler(&session_deps_, &throttler));
17333
17334 // Send a simple request and make sure it goes through.
17335 HttpRequestInfo request;
17336 request.method = "GET";
17337 request.url = GURL("http://www.example.org/");
17338
17339 MockWrite data_writes[] = {
17340 MockWrite("GET / HTTP/1.1\r\n"
17341 "Host: www.example.org\r\n"
17342 "Connection: keep-alive\r\n\r\n"),
17343 };
17344 MockRead data_reads[] = {
17345 MockRead("HTTP/1.0 200 OK\r\n\r\n"), MockRead("hello world"),
17346 MockRead(SYNCHRONOUS, OK),
17347 };
17348 StaticSocketDataProvider reads(data_reads, arraysize(data_reads), data_writes,
17349 arraysize(data_writes));
17350 session_deps_.socket_factory->AddSocketDataProvider(&reads);
17351
17352 StaticSocketDataProvider reads1(data_reads, arraysize(data_reads),
17353 data_writes, arraysize(data_writes));
17354 session_deps_.socket_factory->AddSocketDataProvider(&reads1);
17355
17356 // Start a request that will be throttled at start; confirm it
17357 // doesn't complete.
17358 throttler->set_throttle_new_requests(true);
bnc87dcefc2017-05-25 12:47:5817359 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:1917360 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
rdsmith1d343be52016-10-21 20:37:5017361
17362 TestCompletionCallback callback;
17363 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
17364 EXPECT_EQ(ERR_IO_PENDING, rv);
17365
17366 base::RunLoop().RunUntilIdle();
17367 EXPECT_EQ(LOAD_STATE_THROTTLED, trans->GetLoadState());
17368 EXPECT_FALSE(callback.have_result());
17369
17370 // Create a new request, call SetPriority on it to unthrottle,
17371 // and make sure that allows the original request to complete.
Jeremy Roman0579ed62017-08-29 15:56:1917372 auto trans1 = std::make_unique<HttpNetworkTransaction>(LOW, session.get());
rdsmith1d343be52016-10-21 20:37:5017373 throttler->set_priority_change_closure(
17374 base::Bind(&TestNetworkStreamThrottler::UnthrottleAllRequests,
17375 base::Unretained(throttler)));
17376
17377 // Start the transaction to associate a throttle with it.
17378 TestCompletionCallback callback1;
17379 rv = trans1->Start(&request, callback1.callback(), NetLogWithSource());
17380 EXPECT_EQ(ERR_IO_PENDING, rv);
17381
17382 trans1->SetPriority(IDLE);
17383
17384 base::RunLoop().RunUntilIdle();
17385 ASSERT_TRUE(callback.have_result());
17386 EXPECT_EQ(OK, callback.WaitForResult());
17387 ASSERT_TRUE(callback1.have_result());
17388 EXPECT_EQ(OK, callback1.WaitForResult());
17389}
17390
17391// Transaction will be destroyed when the unique_ptr goes out of scope.
bnc87dcefc2017-05-25 12:47:5817392void DestroyTransaction(std::unique_ptr<HttpNetworkTransaction> transaction) {}
rdsmith1d343be52016-10-21 20:37:5017393
17394// Confirm that destroying a transaction from a SetPriority call by the
17395// throttler works properly.
17396TEST_F(HttpNetworkTransactionTest, ThrottlingPrioritySetDestroy) {
17397 TestNetworkStreamThrottler* throttler(nullptr);
17398 std::unique_ptr<HttpNetworkSession> session(
17399 CreateSessionWithThrottler(&session_deps_, &throttler));
17400
17401 // Send a simple request and make sure it goes through.
17402 HttpRequestInfo request;
17403 request.method = "GET";
17404 request.url = GURL("http://www.example.org/");
17405
17406 MockWrite data_writes[] = {
17407 MockWrite("GET / HTTP/1.1\r\n"
17408 "Host: www.example.org\r\n"
17409 "Connection: keep-alive\r\n\r\n"),
17410 };
17411 MockRead data_reads[] = {
17412 MockRead("HTTP/1.0 200 OK\r\n\r\n"), MockRead("hello world"),
17413 MockRead(SYNCHRONOUS, OK),
17414 };
17415 StaticSocketDataProvider reads(data_reads, arraysize(data_reads), data_writes,
17416 arraysize(data_writes));
17417 session_deps_.socket_factory->AddSocketDataProvider(&reads);
17418
17419 StaticSocketDataProvider reads1(data_reads, arraysize(data_reads),
17420 data_writes, arraysize(data_writes));
17421 session_deps_.socket_factory->AddSocketDataProvider(&reads1);
17422
17423 // Start a request that will be throttled at start; confirm it
17424 // doesn't complete.
17425 throttler->set_throttle_new_requests(true);
bnc87dcefc2017-05-25 12:47:5817426 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:1917427 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
rdsmith1d343be52016-10-21 20:37:5017428
17429 TestCompletionCallback callback;
17430 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
17431 EXPECT_EQ(ERR_IO_PENDING, rv);
17432
17433 base::RunLoop().RunUntilIdle();
17434 EXPECT_EQ(LOAD_STATE_THROTTLED, trans->GetLoadState());
17435 EXPECT_FALSE(callback.have_result());
17436
17437 // Arrange for the set priority call on the above transaction to delete
17438 // the transaction.
bnc87dcefc2017-05-25 12:47:5817439 HttpNetworkTransaction* trans_ptr(trans.get());
rdsmith1d343be52016-10-21 20:37:5017440 throttler->set_priority_change_closure(
17441 base::Bind(&DestroyTransaction, base::Passed(&trans)));
17442
17443 // Call it and check results (partially a "doesn't crash" test).
17444 trans_ptr->SetPriority(IDLE);
17445 trans_ptr = nullptr; // No longer a valid pointer.
17446
17447 base::RunLoop().RunUntilIdle();
17448 ASSERT_FALSE(callback.have_result());
17449}
17450
nharperb7441ef2016-01-25 23:54:1417451#if !defined(OS_IOS)
bncd16676a2016-07-20 16:23:0117452TEST_F(HttpNetworkTransactionTest, TokenBindingSpdy) {
nharperb7441ef2016-01-25 23:54:1417453 const std::string https_url = "https://www.example.com";
17454 HttpRequestInfo request;
17455 request.url = GURL(https_url);
17456 request.method = "GET";
17457
17458 SSLSocketDataProvider ssl(ASYNC, OK);
Ryan Sleevi4f832092017-11-21 23:25:4917459 ssl.ssl_info.token_binding_negotiated = true;
17460 ssl.ssl_info.token_binding_key_param = TB_PARAM_ECDSAP256;
bnc3cf2a592016-08-11 14:48:3617461 ssl.next_proto = kProtoHTTP2;
nharperb7441ef2016-01-25 23:54:1417462 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
17463
bnc42331402016-07-25 13:36:1517464 SpdySerializedFrame resp(spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
bncdf80d44fd2016-07-15 20:27:4117465 SpdySerializedFrame body(spdy_util_.ConstructSpdyDataFrame(1, true));
17466 MockRead reads[] = {CreateMockRead(resp), CreateMockRead(body),
nharperb7441ef2016-01-25 23:54:1417467 MockRead(ASYNC, ERR_IO_PENDING)};
17468 StaticSocketDataProvider data(reads, arraysize(reads), nullptr, 0);
17469 session_deps_.socket_factory->AddSocketDataProvider(&data);
bnc87dcefc2017-05-25 12:47:5817470 session_deps_.channel_id_service =
Jeremy Roman0579ed62017-08-29 15:56:1917471 std::make_unique<ChannelIDService>(new DefaultChannelIDStore(nullptr));
danakj1fd259a02016-04-16 03:17:0917472 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
nharperb7441ef2016-01-25 23:54:1417473
17474 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
17475 TestCompletionCallback callback;
17476 EXPECT_EQ(ERR_IO_PENDING,
tfarina42834112016-09-22 13:38:2017477 trans.Start(&request, callback.callback(), NetLogWithSource()));
fdorayf33fede2017-05-11 21:18:1017478
17479 NetTestSuite::GetScopedTaskEnvironment()->RunUntilIdle();
nharperb7441ef2016-01-25 23:54:1417480
17481 EXPECT_TRUE(trans.GetResponseInfo()->was_fetched_via_spdy);
17482 HttpRequestHeaders headers;
17483 ASSERT_TRUE(trans.GetFullRequestHeaders(&headers));
17484 EXPECT_TRUE(headers.HasHeader(HttpRequestHeaders::kTokenBinding));
17485}
17486#endif // !defined(OS_IOS)
17487
eustasc7d27da2017-04-06 10:33:2017488void CheckContentEncodingMatching(SpdySessionDependencies* session_deps,
17489 const std::string& accept_encoding,
17490 const std::string& content_encoding,
sky50576f32017-05-01 19:28:0317491 const std::string& location,
eustasc7d27da2017-04-06 10:33:2017492 bool should_match) {
17493 HttpRequestInfo request;
17494 request.method = "GET";
17495 request.url = GURL("http://www.foo.com/");
17496 request.extra_headers.SetHeader(HttpRequestHeaders::kAcceptEncoding,
17497 accept_encoding);
17498
17499 std::unique_ptr<HttpNetworkSession> session(CreateSession(session_deps));
17500 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
17501 // Send headers successfully, but get an error while sending the body.
17502 MockWrite data_writes[] = {
17503 MockWrite("GET / HTTP/1.1\r\n"
17504 "Host: www.foo.com\r\n"
17505 "Connection: keep-alive\r\n"
17506 "Accept-Encoding: "),
17507 MockWrite(accept_encoding.data()), MockWrite("\r\n\r\n"),
17508 };
17509
sky50576f32017-05-01 19:28:0317510 std::string response_code = "200 OK";
17511 std::string extra;
17512 if (!location.empty()) {
17513 response_code = "301 Redirect\r\nLocation: ";
17514 response_code.append(location);
17515 }
17516
eustasc7d27da2017-04-06 10:33:2017517 MockRead data_reads[] = {
sky50576f32017-05-01 19:28:0317518 MockRead("HTTP/1.0 "),
17519 MockRead(response_code.data()),
17520 MockRead("\r\nContent-Encoding: "),
17521 MockRead(content_encoding.data()),
17522 MockRead("\r\n\r\n"),
eustasc7d27da2017-04-06 10:33:2017523 MockRead(SYNCHRONOUS, OK),
17524 };
17525 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
17526 arraysize(data_writes));
17527 session_deps->socket_factory->AddSocketDataProvider(&data);
17528
17529 TestCompletionCallback callback;
17530
17531 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
17532 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
17533
17534 rv = callback.WaitForResult();
17535 if (should_match) {
17536 EXPECT_THAT(rv, IsOk());
17537 } else {
17538 EXPECT_THAT(rv, IsError(ERR_CONTENT_DECODING_FAILED));
17539 }
17540}
17541
17542TEST_F(HttpNetworkTransactionTest, MatchContentEncoding1) {
sky50576f32017-05-01 19:28:0317543 CheckContentEncodingMatching(&session_deps_, "gzip,sdch", "br", "", false);
eustasc7d27da2017-04-06 10:33:2017544}
17545
17546TEST_F(HttpNetworkTransactionTest, MatchContentEncoding2) {
sky50576f32017-05-01 19:28:0317547 CheckContentEncodingMatching(&session_deps_, "identity;q=1, *;q=0", "", "",
17548 true);
eustasc7d27da2017-04-06 10:33:2017549}
17550
17551TEST_F(HttpNetworkTransactionTest, MatchContentEncoding3) {
17552 CheckContentEncodingMatching(&session_deps_, "identity;q=1, *;q=0", "gzip",
sky50576f32017-05-01 19:28:0317553 "", false);
17554}
17555
17556TEST_F(HttpNetworkTransactionTest, MatchContentEncoding4) {
17557 CheckContentEncodingMatching(&session_deps_, "identity;q=1, *;q=0", "gzip",
17558 "www.foo.com/other", true);
eustasc7d27da2017-04-06 10:33:2017559}
17560
xunjieli96f2a402017-06-05 17:24:2717561TEST_F(HttpNetworkTransactionTest, ProxyResolutionFailsSync) {
17562 ProxyConfig proxy_config;
17563 proxy_config.set_pac_url(GURL("http://fooproxyurl"));
17564 proxy_config.set_pac_mandatory(true);
17565 MockAsyncProxyResolver resolver;
17566 session_deps_.proxy_service.reset(new ProxyService(
Jeremy Roman0579ed62017-08-29 15:56:1917567 std::make_unique<ProxyConfigServiceFixed>(proxy_config),
Bence Béky8f9d7d3952017-10-09 19:58:0417568 std::make_unique<FailingProxyResolverFactory>(), nullptr));
xunjieli96f2a402017-06-05 17:24:2717569
17570 HttpRequestInfo request;
17571 request.method = "GET";
17572 request.url = GURL("http://www.example.org/");
17573
17574 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
17575 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
17576
17577 TestCompletionCallback callback;
17578
17579 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
17580 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
17581 EXPECT_THAT(callback.WaitForResult(),
17582 IsError(ERR_MANDATORY_PROXY_CONFIGURATION_FAILED));
17583}
17584
17585TEST_F(HttpNetworkTransactionTest, ProxyResolutionFailsAsync) {
17586 ProxyConfig proxy_config;
17587 proxy_config.set_pac_url(GURL("http://fooproxyurl"));
17588 proxy_config.set_pac_mandatory(true);
17589 MockAsyncProxyResolverFactory* proxy_resolver_factory =
17590 new MockAsyncProxyResolverFactory(false);
17591 MockAsyncProxyResolver resolver;
17592 session_deps_.proxy_service.reset(
Jeremy Roman0579ed62017-08-29 15:56:1917593 new ProxyService(std::make_unique<ProxyConfigServiceFixed>(proxy_config),
xunjieli96f2a402017-06-05 17:24:2717594 base::WrapUnique(proxy_resolver_factory), nullptr));
17595 HttpRequestInfo request;
17596 request.method = "GET";
17597 request.url = GURL("http://www.example.org/");
17598
17599 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
17600 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
17601
17602 TestCompletionCallback callback;
17603 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
17604 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
17605
17606 proxy_resolver_factory->pending_requests()[0]->CompleteNowWithForwarder(
17607 ERR_FAILED, &resolver);
17608 EXPECT_THAT(callback.WaitForResult(),
17609 IsError(ERR_MANDATORY_PROXY_CONFIGURATION_FAILED));
17610}
17611
17612TEST_F(HttpNetworkTransactionTest, NoSupportedProxies) {
17613 session_deps_.proxy_service =
17614 ProxyService::CreateFixedFromPacResult("QUIC myproxy.org:443");
17615 session_deps_.enable_quic = false;
17616 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
17617
17618 HttpRequestInfo request;
17619 request.method = "GET";
17620 request.url = GURL("http://www.example.org/");
17621
17622 TestCompletionCallback callback;
17623 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
17624 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
17625 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
17626
17627 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_NO_SUPPORTED_PROXIES));
17628}
17629
[email protected]89ceba9a2009-03-21 03:46:0617630} // namespace net