blob: 839ff76f657703a44844019845cd4f940f090e9a [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"
[email protected]f7984fc62009-06-22 23:26:4484#include "net/socket/socket_test_util.h"
85#include "net/socket/ssl_client_socket.h"
bnc8f8f7d302017-04-24 18:08:0686#include "net/spdy/chromium/spdy_session.h"
87#include "net/spdy/chromium/spdy_session_pool.h"
88#include "net/spdy/chromium/spdy_test_util_common.h"
89#include "net/spdy/core/spdy_framer.h"
nharperb7441ef2016-01-25 23:54:1490#include "net/ssl/default_channel_id_store.h"
[email protected]536fd0b2013-03-14 17:41:5791#include "net/ssl/ssl_cert_request_info.h"
[email protected]e86839fd2013-08-14 18:29:0392#include "net/ssl/ssl_config_service.h"
[email protected]536fd0b2013-03-14 17:41:5793#include "net/ssl/ssl_config_service_defaults.h"
94#include "net/ssl/ssl_info.h"
svaldez7872fd02015-11-19 21:10:5495#include "net/ssl/ssl_private_key.h"
[email protected]6e7845ae2013-03-29 21:48:1196#include "net/test/cert_test_util.h"
robpercival214763f2016-07-01 23:27:0197#include "net/test/gtest_util.h"
fdorayf33fede2017-05-11 21:18:1098#include "net/test/net_test_suite.h"
rsleevia69c79a2016-06-22 03:28:4399#include "net/test/test_data_directory.h"
[email protected]831e4a32013-11-14 02:14:44100#include "net/websockets/websocket_handshake_stream_base.h"
bncf4588402015-11-24 13:33:18101#include "testing/gmock/include/gmock/gmock.h"
initial.commit586acc5fe2008-07-26 22:42:52102#include "testing/gtest/include/gtest/gtest.h"
[email protected]23887f04f2008-12-02 19:20:15103#include "testing/platform_test.h"
[email protected]795cbf82013-07-22 09:37:27104#include "url/gurl.h"
initial.commit586acc5fe2008-07-26 22:42:52105
Zentaro Kavanagh5b27a6e22017-09-25 23:00:37106#if defined(NTLM_PORTABLE)
107#include "base/base64.h"
108#include "net/ntlm/ntlm_test_data.h"
109#endif
110
robpercival214763f2016-07-01 23:27:01111using net::test::IsError;
112using net::test::IsOk;
113
[email protected]ad65a3e2013-12-25 18:18:01114using base::ASCIIToUTF16;
115
initial.commit586acc5fe2008-07-26 22:42:52116//-----------------------------------------------------------------------------
117
ttuttle859dc7a2015-04-23 19:42:29118namespace net {
119
[email protected]13c8a092010-07-29 06:15:44120namespace {
121
rdsmith1d343be52016-10-21 20:37:50122class TestNetworkStreamThrottler : public NetworkThrottleManager {
123 public:
124 TestNetworkStreamThrottler()
125 : throttle_new_requests_(false),
126 num_set_priority_calls_(0),
127 last_priority_set_(IDLE) {}
128
129 ~TestNetworkStreamThrottler() override {
130 EXPECT_TRUE(outstanding_throttles_.empty());
131 }
132
133 // NetworkThrottleManager
134 std::unique_ptr<Throttle> CreateThrottle(ThrottleDelegate* delegate,
135 RequestPriority priority,
136 bool ignore_limits) override {
bnc87dcefc2017-05-25 12:47:58137 auto test_throttle =
Jeremy Roman0579ed62017-08-29 15:56:19138 std::make_unique<TestThrottle>(throttle_new_requests_, delegate, this);
rdsmith1d343be52016-10-21 20:37:50139 outstanding_throttles_.insert(test_throttle.get());
140 return std::move(test_throttle);
141 }
142
143 void UnthrottleAllRequests() {
144 std::set<TestThrottle*> outstanding_throttles_copy(outstanding_throttles_);
vmpstr6d9996c82017-02-23 00:43:25145 for (auto* throttle : outstanding_throttles_copy) {
rdsmithbf8c3c12016-11-18 18:16:24146 if (throttle->IsBlocked())
rdsmith1d343be52016-10-21 20:37:50147 throttle->Unthrottle();
148 }
149 }
150
151 void set_throttle_new_requests(bool throttle_new_requests) {
152 throttle_new_requests_ = throttle_new_requests;
153 }
154
155 // Includes both throttled and unthrottled throttles.
156 size_t num_outstanding_requests() const {
157 return outstanding_throttles_.size();
158 }
159
160 int num_set_priority_calls() const { return num_set_priority_calls_; }
161 RequestPriority last_priority_set() const { return last_priority_set_; }
162 void set_priority_change_closure(
163 const base::Closure& priority_change_closure) {
164 priority_change_closure_ = priority_change_closure;
165 }
166
167 private:
168 class TestThrottle : public NetworkThrottleManager::Throttle {
169 public:
170 ~TestThrottle() override { throttler_->OnThrottleDestroyed(this); }
171
172 // Throttle
rdsmithbf8c3c12016-11-18 18:16:24173 bool IsBlocked() const override { return throttled_; }
174 RequestPriority Priority() const override {
175 NOTREACHED();
176 return IDLE;
177 }
rdsmith1d343be52016-10-21 20:37:50178 void SetPriority(RequestPriority priority) override {
179 throttler_->SetPriorityCalled(priority);
180 }
181
182 TestThrottle(bool throttled,
183 ThrottleDelegate* delegate,
184 TestNetworkStreamThrottler* throttler)
185 : throttled_(throttled), delegate_(delegate), throttler_(throttler) {}
186
187 void Unthrottle() {
188 EXPECT_TRUE(throttled_);
189
190 throttled_ = false;
rdsmithbf8c3c12016-11-18 18:16:24191 delegate_->OnThrottleUnblocked(this);
rdsmith1d343be52016-10-21 20:37:50192 }
193
194 bool throttled_;
195 ThrottleDelegate* delegate_;
196 TestNetworkStreamThrottler* throttler_;
197 };
198
199 void OnThrottleDestroyed(TestThrottle* throttle) {
200 EXPECT_NE(0u, outstanding_throttles_.count(throttle));
201 outstanding_throttles_.erase(throttle);
202 }
203
204 void SetPriorityCalled(RequestPriority priority) {
205 ++num_set_priority_calls_;
206 last_priority_set_ = priority;
207 if (!priority_change_closure_.is_null())
208 priority_change_closure_.Run();
209 }
210
211 // Includes both throttled and unthrottled throttles.
212 std::set<TestThrottle*> outstanding_throttles_;
213 bool throttle_new_requests_;
214 int num_set_priority_calls_;
215 RequestPriority last_priority_set_;
216 base::Closure priority_change_closure_;
217
218 DISALLOW_COPY_AND_ASSIGN(TestNetworkStreamThrottler);
219};
220
[email protected]42cba2fb2013-03-29 19:58:57221const base::string16 kBar(ASCIIToUTF16("bar"));
222const base::string16 kBar2(ASCIIToUTF16("bar2"));
223const base::string16 kBar3(ASCIIToUTF16("bar3"));
224const base::string16 kBaz(ASCIIToUTF16("baz"));
225const base::string16 kFirst(ASCIIToUTF16("first"));
226const base::string16 kFoo(ASCIIToUTF16("foo"));
227const base::string16 kFoo2(ASCIIToUTF16("foo2"));
228const base::string16 kFoo3(ASCIIToUTF16("foo3"));
229const base::string16 kFou(ASCIIToUTF16("fou"));
230const base::string16 kSecond(ASCIIToUTF16("second"));
[email protected]42cba2fb2013-03-29 19:58:57231const base::string16 kWrongPassword(ASCIIToUTF16("wrongpassword"));
[email protected]13c8a092010-07-29 06:15:44232
bnc2df4b522016-07-08 18:17:43233const char kAlternativeServiceHttpHeader[] =
234 "Alt-Svc: h2=\"mail.example.org:443\"\r\n";
235
ttuttle859dc7a2015-04-23 19:42:29236int GetIdleSocketCountInTransportSocketPool(HttpNetworkSession* session) {
237 return session->GetTransportSocketPool(HttpNetworkSession::NORMAL_SOCKET_POOL)
238 ->IdleSocketCount();
[email protected]e5c026642012-03-17 00:14:02239}
240
ttuttle859dc7a2015-04-23 19:42:29241int GetIdleSocketCountInSSLSocketPool(HttpNetworkSession* session) {
242 return session->GetSSLSocketPool(HttpNetworkSession::NORMAL_SOCKET_POOL)
243 ->IdleSocketCount();
[email protected]e5c026642012-03-17 00:14:02244}
245
ttuttle859dc7a2015-04-23 19:42:29246bool IsTransportSocketPoolStalled(HttpNetworkSession* session) {
247 return session->GetTransportSocketPool(HttpNetworkSession::NORMAL_SOCKET_POOL)
248 ->IsStalled();
[email protected]043b68c82013-08-22 23:41:52249}
250
[email protected]f3da152d2012-06-02 01:00:57251// Takes in a Value created from a NetLogHttpResponseParameter, and returns
252// a JSONified list of headers as a single string. Uses single quotes instead
253// of double quotes for easier comparison. Returns false on failure.
[email protected]ea5ef4c2013-06-13 22:50:27254bool GetHeaders(base::DictionaryValue* params, std::string* headers) {
[email protected]f3da152d2012-06-02 01:00:57255 if (!params)
256 return false;
[email protected]ea5ef4c2013-06-13 22:50:27257 base::ListValue* header_list;
[email protected]f3da152d2012-06-02 01:00:57258 if (!params->GetList("headers", &header_list))
259 return false;
260 std::string double_quote_headers;
estade8d046462015-05-16 01:02:34261 base::JSONWriter::Write(*header_list, &double_quote_headers);
[email protected]466c9862013-12-03 22:05:28262 base::ReplaceChars(double_quote_headers, "\"", "'", headers);
[email protected]f3da152d2012-06-02 01:00:57263 return true;
264}
265
[email protected]029c83b62013-01-24 05:28:20266// Tests LoadTimingInfo in the case a socket is reused and no PAC script is
267// used.
ttuttle859dc7a2015-04-23 19:42:29268void TestLoadTimingReused(const LoadTimingInfo& load_timing_info) {
[email protected]029c83b62013-01-24 05:28:20269 EXPECT_TRUE(load_timing_info.socket_reused);
mikecironef22f9812016-10-04 03:40:19270 EXPECT_NE(NetLogSource::kInvalidId, load_timing_info.socket_log_id);
[email protected]58e32bb2013-01-21 18:23:25271
[email protected]029c83b62013-01-24 05:28:20272 EXPECT_TRUE(load_timing_info.proxy_resolve_start.is_null());
273 EXPECT_TRUE(load_timing_info.proxy_resolve_end.is_null());
274
ttuttle859dc7a2015-04-23 19:42:29275 ExpectConnectTimingHasNoTimes(load_timing_info.connect_timing);
[email protected]029c83b62013-01-24 05:28:20276 EXPECT_FALSE(load_timing_info.send_start.is_null());
[email protected]58e32bb2013-01-21 18:23:25277
278 EXPECT_LE(load_timing_info.send_start, load_timing_info.send_end);
[email protected]58e32bb2013-01-21 18:23:25279
[email protected]3b23a222013-05-15 21:33:25280 // Set at a higher level.
[email protected]58e32bb2013-01-21 18:23:25281 EXPECT_TRUE(load_timing_info.request_start_time.is_null());
282 EXPECT_TRUE(load_timing_info.request_start.is_null());
[email protected]3b23a222013-05-15 21:33:25283 EXPECT_TRUE(load_timing_info.receive_headers_end.is_null());
[email protected]58e32bb2013-01-21 18:23:25284}
285
[email protected]029c83b62013-01-24 05:28:20286// Tests LoadTimingInfo in the case a new socket is used and no PAC script is
287// used.
ttuttle859dc7a2015-04-23 19:42:29288void TestLoadTimingNotReused(const LoadTimingInfo& load_timing_info,
[email protected]58e32bb2013-01-21 18:23:25289 int connect_timing_flags) {
[email protected]029c83b62013-01-24 05:28:20290 EXPECT_FALSE(load_timing_info.socket_reused);
mikecironef22f9812016-10-04 03:40:19291 EXPECT_NE(NetLogSource::kInvalidId, load_timing_info.socket_log_id);
[email protected]029c83b62013-01-24 05:28:20292
293 EXPECT_TRUE(load_timing_info.proxy_resolve_start.is_null());
294 EXPECT_TRUE(load_timing_info.proxy_resolve_end.is_null());
295
ttuttle859dc7a2015-04-23 19:42:29296 ExpectConnectTimingHasTimes(load_timing_info.connect_timing,
297 connect_timing_flags);
[email protected]029c83b62013-01-24 05:28:20298 EXPECT_LE(load_timing_info.connect_timing.connect_end,
299 load_timing_info.send_start);
300
301 EXPECT_LE(load_timing_info.send_start, load_timing_info.send_end);
[email protected]029c83b62013-01-24 05:28:20302
[email protected]3b23a222013-05-15 21:33:25303 // Set at a higher level.
[email protected]029c83b62013-01-24 05:28:20304 EXPECT_TRUE(load_timing_info.request_start_time.is_null());
305 EXPECT_TRUE(load_timing_info.request_start.is_null());
[email protected]3b23a222013-05-15 21:33:25306 EXPECT_TRUE(load_timing_info.receive_headers_end.is_null());
[email protected]029c83b62013-01-24 05:28:20307}
308
309// Tests LoadTimingInfo in the case a socket is reused and a PAC script is
310// used.
ttuttle859dc7a2015-04-23 19:42:29311void TestLoadTimingReusedWithPac(const LoadTimingInfo& load_timing_info) {
[email protected]029c83b62013-01-24 05:28:20312 EXPECT_TRUE(load_timing_info.socket_reused);
mikecironef22f9812016-10-04 03:40:19313 EXPECT_NE(NetLogSource::kInvalidId, load_timing_info.socket_log_id);
[email protected]029c83b62013-01-24 05:28:20314
ttuttle859dc7a2015-04-23 19:42:29315 ExpectConnectTimingHasNoTimes(load_timing_info.connect_timing);
[email protected]029c83b62013-01-24 05:28:20316
317 EXPECT_FALSE(load_timing_info.proxy_resolve_start.is_null());
318 EXPECT_LE(load_timing_info.proxy_resolve_start,
319 load_timing_info.proxy_resolve_end);
320 EXPECT_LE(load_timing_info.proxy_resolve_end,
321 load_timing_info.send_start);
322 EXPECT_LE(load_timing_info.send_start, load_timing_info.send_end);
[email protected]029c83b62013-01-24 05:28:20323
[email protected]3b23a222013-05-15 21:33:25324 // Set at a higher level.
[email protected]029c83b62013-01-24 05:28:20325 EXPECT_TRUE(load_timing_info.request_start_time.is_null());
326 EXPECT_TRUE(load_timing_info.request_start.is_null());
[email protected]3b23a222013-05-15 21:33:25327 EXPECT_TRUE(load_timing_info.receive_headers_end.is_null());
[email protected]029c83b62013-01-24 05:28:20328}
329
330// Tests LoadTimingInfo in the case a new socket is used and a PAC script is
331// used.
ttuttle859dc7a2015-04-23 19:42:29332void TestLoadTimingNotReusedWithPac(const LoadTimingInfo& load_timing_info,
[email protected]029c83b62013-01-24 05:28:20333 int connect_timing_flags) {
334 EXPECT_FALSE(load_timing_info.socket_reused);
mikecironef22f9812016-10-04 03:40:19335 EXPECT_NE(NetLogSource::kInvalidId, load_timing_info.socket_log_id);
[email protected]029c83b62013-01-24 05:28:20336
337 EXPECT_FALSE(load_timing_info.proxy_resolve_start.is_null());
338 EXPECT_LE(load_timing_info.proxy_resolve_start,
339 load_timing_info.proxy_resolve_end);
340 EXPECT_LE(load_timing_info.proxy_resolve_end,
341 load_timing_info.connect_timing.connect_start);
ttuttle859dc7a2015-04-23 19:42:29342 ExpectConnectTimingHasTimes(load_timing_info.connect_timing,
343 connect_timing_flags);
[email protected]029c83b62013-01-24 05:28:20344 EXPECT_LE(load_timing_info.connect_timing.connect_end,
345 load_timing_info.send_start);
346
347 EXPECT_LE(load_timing_info.send_start, load_timing_info.send_end);
[email protected]029c83b62013-01-24 05:28:20348
[email protected]3b23a222013-05-15 21:33:25349 // Set at a higher level.
[email protected]029c83b62013-01-24 05:28:20350 EXPECT_TRUE(load_timing_info.request_start_time.is_null());
351 EXPECT_TRUE(load_timing_info.request_start.is_null());
[email protected]3b23a222013-05-15 21:33:25352 EXPECT_TRUE(load_timing_info.receive_headers_end.is_null());
[email protected]58e32bb2013-01-21 18:23:25353}
354
ttuttle859dc7a2015-04-23 19:42:29355void AddWebSocketHeaders(HttpRequestHeaders* headers) {
Adam Rice425cf122015-01-19 06:18:24356 headers->SetHeader("Connection", "Upgrade");
357 headers->SetHeader("Upgrade", "websocket");
bncce36dca22015-04-21 22:11:23358 headers->SetHeader("Origin", "http://www.example.org");
Adam Rice425cf122015-01-19 06:18:24359 headers->SetHeader("Sec-WebSocket-Version", "13");
360 headers->SetHeader("Sec-WebSocket-Key", "dGhlIHNhbXBsZSBub25jZQ==");
361}
362
danakj1fd259a02016-04-16 03:17:09363std::unique_ptr<HttpNetworkSession> CreateSession(
mmenkee65e7af2015-10-13 17:16:42364 SpdySessionDependencies* session_deps) {
[email protected]c6bf8152012-12-02 07:43:34365 return SpdySessionDependencies::SpdyCreateSession(session_deps);
[email protected]e8d536192008-10-17 22:21:14366}
367
rdsmith1d343be52016-10-21 20:37:50368// Note that the pointer written into |*throttler| will only be valid
369// for the lifetime of the returned HttpNetworkSession.
370std::unique_ptr<HttpNetworkSession> CreateSessionWithThrottler(
371 SpdySessionDependencies* session_deps,
372 TestNetworkStreamThrottler** throttler) {
373 std::unique_ptr<HttpNetworkSession> session(
374 SpdySessionDependencies::SpdyCreateSession(session_deps));
375
Jeremy Roman0579ed62017-08-29 15:56:19376 auto owned_throttler = std::make_unique<TestNetworkStreamThrottler>();
rdsmith1d343be52016-10-21 20:37:50377 *throttler = owned_throttler.get();
378
379 HttpNetworkSessionPeer peer(session.get());
380 peer.SetNetworkStreamThrottler(std::move(owned_throttler));
381
382 return session;
383}
384
xunjieli96f2a402017-06-05 17:24:27385class FailingProxyResolverFactory : public ProxyResolverFactory {
386 public:
387 FailingProxyResolverFactory() : ProxyResolverFactory(false) {}
388
389 // ProxyResolverFactory override.
390 int CreateProxyResolver(
391 const scoped_refptr<ProxyResolverScriptData>& script_data,
392 std::unique_ptr<ProxyResolver>* result,
393 const CompletionCallback& callback,
394 std::unique_ptr<Request>* request) override {
395 return ERR_PAC_SCRIPT_FAILED;
396 }
397};
398
[email protected]448d4ca52012-03-04 04:12:23399} // namespace
400
bncd16676a2016-07-20 16:23:01401class HttpNetworkTransactionTest : public PlatformTest {
[email protected]483fa202013-05-14 01:07:03402 public:
bncd16676a2016-07-20 16:23:01403 ~HttpNetworkTransactionTest() override {
[email protected]483fa202013-05-14 01:07:03404 // Important to restore the per-pool limit first, since the pool limit must
405 // always be greater than group limit, and the tests reduce both limits.
406 ClientSocketPoolManager::set_max_sockets_per_pool(
407 HttpNetworkSession::NORMAL_SOCKET_POOL, old_max_pool_sockets_);
408 ClientSocketPoolManager::set_max_sockets_per_group(
409 HttpNetworkSession::NORMAL_SOCKET_POOL, old_max_group_sockets_);
410 }
411
[email protected]e3ceb682011-06-28 23:55:46412 protected:
[email protected]23e482282013-06-14 16:08:02413 HttpNetworkTransactionTest()
bnc032658ba2016-09-26 18:17:15414 : ssl_(ASYNC, OK),
415 old_max_group_sockets_(ClientSocketPoolManager::max_sockets_per_group(
[email protected]483fa202013-05-14 01:07:03416 HttpNetworkSession::NORMAL_SOCKET_POOL)),
417 old_max_pool_sockets_(ClientSocketPoolManager::max_sockets_per_pool(
418 HttpNetworkSession::NORMAL_SOCKET_POOL)) {
bnca86731e2017-04-17 12:31:28419 session_deps_.enable_http2_alternative_service = true;
[email protected]483fa202013-05-14 01:07:03420 }
[email protected]bb88e1d32013-05-03 23:11:07421
[email protected]e3ceb682011-06-28 23:55:46422 struct SimpleGetHelperResult {
423 int rv;
424 std::string status_line;
425 std::string response_data;
sclittlefb249892015-09-10 21:33:22426 int64_t total_received_bytes;
427 int64_t total_sent_bytes;
[email protected]58e32bb2013-01-21 18:23:25428 LoadTimingInfo load_timing_info;
ttuttle1f2d7e92015-04-28 16:17:47429 ConnectionAttempts connection_attempts;
ttuttled9dbc652015-09-29 20:00:59430 IPEndPoint remote_endpoint_after_start;
[email protected]e3ceb682011-06-28 23:55:46431 };
432
dcheng67be2b1f2014-10-27 21:47:29433 void SetUp() override {
[email protected]0b0bf032010-09-21 18:08:50434 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
fdoray92e35a72016-06-10 15:54:55435 base::RunLoop().RunUntilIdle();
[email protected]2ff8b312010-04-26 22:20:54436 }
437
dcheng67be2b1f2014-10-27 21:47:29438 void TearDown() override {
[email protected]0b0bf032010-09-21 18:08:50439 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
fdoray92e35a72016-06-10 15:54:55440 base::RunLoop().RunUntilIdle();
[email protected]0e75a732008-10-16 20:36:09441 // Empty the current queue.
fdoray92e35a72016-06-10 15:54:55442 base::RunLoop().RunUntilIdle();
[email protected]0e75a732008-10-16 20:36:09443 PlatformTest::TearDown();
[email protected]0b0bf032010-09-21 18:08:50444 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
fdoray92e35a72016-06-10 15:54:55445 base::RunLoop().RunUntilIdle();
[email protected]0e75a732008-10-16 20:36:09446 }
447
[email protected]202965992011-12-07 23:04:51448 // Either |write_failure| specifies a write failure or |read_failure|
449 // specifies a read failure when using a reused socket. In either case, the
450 // failure should cause the network transaction to resend the request, and the
451 // other argument should be NULL.
452 void KeepAliveConnectionResendRequestTest(const MockWrite* write_failure,
453 const MockRead* read_failure);
initial.commit586acc5fe2008-07-26 22:42:52454
[email protected]a34f61ee2014-03-18 20:59:49455 // Either |write_failure| specifies a write failure or |read_failure|
456 // specifies a read failure when using a reused socket. In either case, the
457 // failure should cause the network transaction to resend the request, and the
458 // other argument should be NULL.
459 void PreconnectErrorResendRequestTest(const MockWrite* write_failure,
[email protected]09356c652014-03-25 15:36:10460 const MockRead* read_failure,
461 bool use_spdy);
[email protected]a34f61ee2014-03-18 20:59:49462
[email protected]5a60c8b2011-10-19 20:14:29463 SimpleGetHelperResult SimpleGetHelperForData(StaticSocketDataProvider* data[],
464 size_t data_count) {
[email protected]ff007e162009-05-23 09:13:15465 SimpleGetHelperResult out;
initial.commit586acc5fe2008-07-26 22:42:52466
[email protected]ff007e162009-05-23 09:13:15467 HttpRequestInfo request;
468 request.method = "GET";
bncce36dca22015-04-21 22:11:23469 request.url = GURL("http://www.example.org/");
initial.commit586acc5fe2008-07-26 22:42:52470
vishal.b62985ca92015-04-17 08:45:51471 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:07472 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:09473 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:16474 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:27475
[email protected]5a60c8b2011-10-19 20:14:29476 for (size_t i = 0; i < data_count; ++i) {
[email protected]bb88e1d32013-05-03 23:11:07477 session_deps_.socket_factory->AddSocketDataProvider(data[i]);
[email protected]5a60c8b2011-10-19 20:14:29478 }
initial.commit586acc5fe2008-07-26 22:42:52479
[email protected]49639fa2011-12-20 23:22:41480 TestCompletionCallback callback;
initial.commit586acc5fe2008-07-26 22:42:52481
eroman24bc6a12015-05-06 19:55:48482 EXPECT_TRUE(log.bound().IsCapturing());
bnc691fda62016-08-12 00:43:16483 int rv = trans.Start(&request, callback.callback(), log.bound());
robpercival214763f2016-07-01 23:27:01484 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
initial.commit586acc5fe2008-07-26 22:42:52485
[email protected]ff007e162009-05-23 09:13:15486 out.rv = callback.WaitForResult();
bnc691fda62016-08-12 00:43:16487 out.total_received_bytes = trans.GetTotalReceivedBytes();
488 out.total_sent_bytes = trans.GetTotalSentBytes();
[email protected]58e32bb2013-01-21 18:23:25489
490 // Even in the failure cases that use this function, connections are always
491 // successfully established before the error.
bnc691fda62016-08-12 00:43:16492 EXPECT_TRUE(trans.GetLoadTimingInfo(&out.load_timing_info));
[email protected]58e32bb2013-01-21 18:23:25493 TestLoadTimingNotReused(out.load_timing_info, CONNECT_TIMING_HAS_DNS_TIMES);
494
[email protected]ff007e162009-05-23 09:13:15495 if (out.rv != OK)
496 return out;
497
bnc691fda62016-08-12 00:43:16498 const HttpResponseInfo* response = trans.GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:50499 // Can't use ASSERT_* inside helper functions like this, so
500 // return an error.
wezca1070932016-05-26 20:30:52501 if (!response || !response->headers) {
[email protected]fe2255a2011-09-20 19:37:50502 out.rv = ERR_UNEXPECTED;
503 return out;
504 }
[email protected]ff007e162009-05-23 09:13:15505 out.status_line = response->headers->GetStatusLine();
506
[email protected]80a09a82012-11-16 17:40:06507 EXPECT_EQ("127.0.0.1", response->socket_address.host());
508 EXPECT_EQ(80, response->socket_address.port());
[email protected]6d81b482011-02-22 19:47:19509
ttuttled9dbc652015-09-29 20:00:59510 bool got_endpoint =
bnc691fda62016-08-12 00:43:16511 trans.GetRemoteEndpoint(&out.remote_endpoint_after_start);
ttuttled9dbc652015-09-29 20:00:59512 EXPECT_EQ(got_endpoint,
513 out.remote_endpoint_after_start.address().size() > 0);
514
bnc691fda62016-08-12 00:43:16515 rv = ReadTransaction(&trans, &out.response_data);
robpercival214763f2016-07-01 23:27:01516 EXPECT_THAT(rv, IsOk());
[email protected]b2fcd0e2010-12-01 15:19:40517
mmenke43758e62015-05-04 21:09:46518 TestNetLogEntry::List entries;
[email protected]b2fcd0e2010-12-01 15:19:40519 log.GetEntries(&entries);
[email protected]dbb83db2010-05-11 18:13:39520 size_t pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:00521 entries, 0, NetLogEventType::HTTP_TRANSACTION_SEND_REQUEST_HEADERS,
522 NetLogEventPhase::NONE);
[email protected]dbb83db2010-05-11 18:13:39523 ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:00524 entries, pos, NetLogEventType::HTTP_TRANSACTION_READ_RESPONSE_HEADERS,
525 NetLogEventPhase::NONE);
[email protected]ff007e162009-05-23 09:13:15526
[email protected]f3da152d2012-06-02 01:00:57527 std::string line;
528 EXPECT_TRUE(entries[pos].GetStringValue("line", &line));
529 EXPECT_EQ("GET / HTTP/1.1\r\n", line);
530
[email protected]79e1fd62013-06-20 06:50:04531 HttpRequestHeaders request_headers;
bnc691fda62016-08-12 00:43:16532 EXPECT_TRUE(trans.GetFullRequestHeaders(&request_headers));
[email protected]79e1fd62013-06-20 06:50:04533 std::string value;
534 EXPECT_TRUE(request_headers.GetHeader("Host", &value));
bncce36dca22015-04-21 22:11:23535 EXPECT_EQ("www.example.org", value);
[email protected]79e1fd62013-06-20 06:50:04536 EXPECT_TRUE(request_headers.GetHeader("Connection", &value));
537 EXPECT_EQ("keep-alive", value);
538
539 std::string response_headers;
540 EXPECT_TRUE(GetHeaders(entries[pos].params.get(), &response_headers));
bncce36dca22015-04-21 22:11:23541 EXPECT_EQ("['Host: www.example.org','Connection: keep-alive']",
[email protected]79e1fd62013-06-20 06:50:04542 response_headers);
[email protected]3deb9a52010-11-11 00:24:40543
bnc691fda62016-08-12 00:43:16544 out.total_received_bytes = trans.GetTotalReceivedBytes();
sclittlefb249892015-09-10 21:33:22545 // The total number of sent bytes should not have changed.
bnc691fda62016-08-12 00:43:16546 EXPECT_EQ(out.total_sent_bytes, trans.GetTotalSentBytes());
sclittlefb249892015-09-10 21:33:22547
bnc691fda62016-08-12 00:43:16548 trans.GetConnectionAttempts(&out.connection_attempts);
[email protected]aecfbf22008-10-16 02:02:47549 return out;
[email protected]ff007e162009-05-23 09:13:15550 }
initial.commit586acc5fe2008-07-26 22:42:52551
[email protected]5a60c8b2011-10-19 20:14:29552 SimpleGetHelperResult SimpleGetHelper(MockRead data_reads[],
553 size_t reads_count) {
sclittlefb249892015-09-10 21:33:22554 MockWrite data_writes[] = {
555 MockWrite("GET / HTTP/1.1\r\n"
556 "Host: www.example.org\r\n"
557 "Connection: keep-alive\r\n\r\n"),
558 };
[email protected]5a60c8b2011-10-19 20:14:29559
sclittlefb249892015-09-10 21:33:22560 StaticSocketDataProvider reads(data_reads, reads_count, data_writes,
561 arraysize(data_writes));
562 StaticSocketDataProvider* data[] = {&reads};
563 SimpleGetHelperResult out = SimpleGetHelperForData(data, 1);
564
565 EXPECT_EQ(CountWriteBytes(data_writes, arraysize(data_writes)),
566 out.total_sent_bytes);
567 return out;
[email protected]b8015c42013-12-24 15:18:19568 }
569
bnc032658ba2016-09-26 18:17:15570 void AddSSLSocketData() {
571 ssl_.next_proto = kProtoHTTP2;
Ryan Sleevi4f832092017-11-21 23:25:49572 ssl_.ssl_info.cert =
573 ImportCertFromFile(GetTestCertsDirectory(), "spdy_pooling.pem");
574 ASSERT_TRUE(ssl_.ssl_info.cert);
bnc032658ba2016-09-26 18:17:15575 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_);
576 }
577
[email protected]ff007e162009-05-23 09:13:15578 void ConnectStatusHelperWithExpectedStatus(const MockRead& status,
579 int expected_status);
initial.commit586acc5fe2008-07-26 22:42:52580
[email protected]ff007e162009-05-23 09:13:15581 void ConnectStatusHelper(const MockRead& status);
[email protected]bb88e1d32013-05-03 23:11:07582
583 void BypassHostCacheOnRefreshHelper(int load_flags);
584
585 void CheckErrorIsPassedBack(int error, IoMode mode);
586
[email protected]4bd46222013-05-14 19:32:23587 SpdyTestUtil spdy_util_;
[email protected]bb88e1d32013-05-03 23:11:07588 SpdySessionDependencies session_deps_;
bnc032658ba2016-09-26 18:17:15589 SSLSocketDataProvider ssl_;
[email protected]483fa202013-05-14 01:07:03590
591 // Original socket limits. Some tests set these. Safest to always restore
592 // them once each test has been run.
593 int old_max_group_sockets_;
594 int old_max_pool_sockets_;
[email protected]ff007e162009-05-23 09:13:15595};
[email protected]231d5a32008-09-13 00:45:27596
[email protected]448d4ca52012-03-04 04:12:23597namespace {
598
ryansturm49a8cb12016-06-15 16:51:09599class BeforeHeadersSentHandler {
[email protected]597a1ab2014-06-26 08:12:27600 public:
ryansturm49a8cb12016-06-15 16:51:09601 BeforeHeadersSentHandler()
602 : observed_before_headers_sent_with_proxy_(false),
603 observed_before_headers_sent_(false) {}
[email protected]597a1ab2014-06-26 08:12:27604
ryansturm49a8cb12016-06-15 16:51:09605 void OnBeforeHeadersSent(const ProxyInfo& proxy_info,
606 HttpRequestHeaders* request_headers) {
607 observed_before_headers_sent_ = true;
608 if (!proxy_info.is_http() && !proxy_info.is_https() &&
609 !proxy_info.is_quic()) {
610 return;
611 }
612 observed_before_headers_sent_with_proxy_ = true;
[email protected]597a1ab2014-06-26 08:12:27613 observed_proxy_server_uri_ = proxy_info.proxy_server().ToURI();
614 }
615
ryansturm49a8cb12016-06-15 16:51:09616 bool observed_before_headers_sent_with_proxy() const {
617 return observed_before_headers_sent_with_proxy_;
618 }
619
620 bool observed_before_headers_sent() const {
621 return observed_before_headers_sent_;
[email protected]597a1ab2014-06-26 08:12:27622 }
623
624 std::string observed_proxy_server_uri() const {
625 return observed_proxy_server_uri_;
626 }
627
628 private:
ryansturm49a8cb12016-06-15 16:51:09629 bool observed_before_headers_sent_with_proxy_;
630 bool observed_before_headers_sent_;
[email protected]597a1ab2014-06-26 08:12:27631 std::string observed_proxy_server_uri_;
632
ryansturm49a8cb12016-06-15 16:51:09633 DISALLOW_COPY_AND_ASSIGN(BeforeHeadersSentHandler);
[email protected]597a1ab2014-06-26 08:12:27634};
635
[email protected]15a5ccf82008-10-23 19:57:43636// Fill |str| with a long header list that consumes >= |size| bytes.
637void FillLargeHeadersString(std::string* str, int size) {
thestig9d3bb0c2015-01-24 00:49:51638 const char row[] =
[email protected]4ddaf2502008-10-23 18:26:19639 "SomeHeaderName: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx\r\n";
640 const int sizeof_row = strlen(row);
641 const int num_rows = static_cast<int>(
642 ceil(static_cast<float>(size) / sizeof_row));
643 const int sizeof_data = num_rows * sizeof_row;
644 DCHECK(sizeof_data >= size);
[email protected]15a5ccf82008-10-23 19:57:43645 str->reserve(sizeof_data);
[email protected]372d34a2008-11-05 21:30:51646
[email protected]4ddaf2502008-10-23 18:26:19647 for (int i = 0; i < num_rows; ++i)
[email protected]15a5ccf82008-10-23 19:57:43648 str->append(row, sizeof_row);
[email protected]4ddaf2502008-10-23 18:26:19649}
650
thakis84dff942015-07-28 20:47:38651#if defined(NTLM_PORTABLE)
Zentaro Kavanagh6ccee512017-09-28 18:34:09652uint64_t MockGetMSTime() {
653 // Tue, 23 May 2017 20:13:07 +0000
654 return 131400439870000000;
655}
656
[email protected]385a4672009-03-11 22:21:29657// Alternative functions that eliminate randomness and dependency on the local
658// host name so that the generated NTLM messages are reproducible.
Zentaro Kavanagh5b27a6e22017-09-25 23:00:37659void MockGenerateRandom(uint8_t* output, size_t n) {
660 // This is set to 0xaa because the client challenge for testing in
661 // [MS-NLMP] Section 4.2.1 is 8 bytes of 0xaa.
662 memset(output, 0xaa, n);
[email protected]385a4672009-03-11 22:21:29663}
664
[email protected]fe2bc6a2009-03-23 16:52:20665std::string MockGetHostName() {
Zentaro Kavanagh5b27a6e22017-09-25 23:00:37666 return ntlm::test::kHostnameAscii;
[email protected]385a4672009-03-11 22:21:29667}
thakis84dff942015-07-28 20:47:38668#endif // defined(NTLM_PORTABLE)
[email protected]385a4672009-03-11 22:21:29669
[email protected]e60e47a2010-07-14 03:37:18670template<typename ParentPool>
671class CaptureGroupNameSocketPool : public ParentPool {
[email protected]04e5be32009-06-26 20:00:31672 public:
[email protected]9e1bdd32011-02-03 21:48:34673 CaptureGroupNameSocketPool(HostResolver* host_resolver,
674 CertVerifier* cert_verifier);
[email protected]e60e47a2010-07-14 03:37:18675
[email protected]d80a4322009-08-14 07:07:49676 const std::string last_group_name_received() const {
677 return last_group_name_;
678 }
679
dmichaeld6e570d2014-12-18 22:30:57680 int RequestSocket(const std::string& group_name,
681 const void* socket_params,
682 RequestPriority priority,
Paul Jensen8d6f87ec2018-01-13 00:46:54683 const SocketTag& socket_tag,
mmenked3641e12016-01-28 16:06:15684 ClientSocketPool::RespectLimits respect_limits,
dmichaeld6e570d2014-12-18 22:30:57685 ClientSocketHandle* handle,
686 const CompletionCallback& callback,
tfarina42834112016-09-22 13:38:20687 const NetLogWithSource& net_log) override {
[email protected]04e5be32009-06-26 20:00:31688 last_group_name_ = group_name;
689 return ERR_IO_PENDING;
690 }
dmichaeld6e570d2014-12-18 22:30:57691 void CancelRequest(const std::string& group_name,
692 ClientSocketHandle* handle) override {}
693 void ReleaseSocket(const std::string& group_name,
danakj1fd259a02016-04-16 03:17:09694 std::unique_ptr<StreamSocket> socket,
dmichaeld6e570d2014-12-18 22:30:57695 int id) override {}
696 void CloseIdleSockets() override {}
xunjieli92feb332017-03-03 17:19:23697 void CloseIdleSocketsInGroup(const std::string& group_name) override {}
dmichaeld6e570d2014-12-18 22:30:57698 int IdleSocketCount() const override { return 0; }
699 int IdleSocketCountInGroup(const std::string& group_name) const override {
[email protected]04e5be32009-06-26 20:00:31700 return 0;
701 }
dmichaeld6e570d2014-12-18 22:30:57702 LoadState GetLoadState(const std::string& group_name,
703 const ClientSocketHandle* handle) const override {
[email protected]04e5be32009-06-26 20:00:31704 return LOAD_STATE_IDLE;
705 }
dmichaeld6e570d2014-12-18 22:30:57706 base::TimeDelta ConnectionTimeout() const override {
[email protected]a796bcec2010-03-22 17:17:26707 return base::TimeDelta();
708 }
[email protected]d80a4322009-08-14 07:07:49709
710 private:
[email protected]04e5be32009-06-26 20:00:31711 std::string last_group_name_;
712};
713
[email protected]ab739042011-04-07 15:22:28714typedef CaptureGroupNameSocketPool<TransportClientSocketPool>
715CaptureGroupNameTransportSocketPool;
[email protected]e772db3f2010-07-12 18:11:13716typedef CaptureGroupNameSocketPool<HttpProxyClientSocketPool>
717CaptureGroupNameHttpProxySocketPool;
[email protected]2d731a32010-04-29 01:04:06718typedef CaptureGroupNameSocketPool<SOCKSClientSocketPool>
[email protected]2227c692010-05-04 15:36:11719CaptureGroupNameSOCKSSocketPool;
[email protected]e60e47a2010-07-14 03:37:18720typedef CaptureGroupNameSocketPool<SSLClientSocketPool>
721CaptureGroupNameSSLSocketPool;
722
rkaplowd90695c2015-03-25 22:12:41723template <typename ParentPool>
[email protected]e60e47a2010-07-14 03:37:18724CaptureGroupNameSocketPool<ParentPool>::CaptureGroupNameSocketPool(
[email protected]9e1bdd32011-02-03 21:48:34725 HostResolver* host_resolver,
726 CertVerifier* /* cert_verifier */)
tbansal7b403bcc2016-04-13 22:33:21727 : ParentPool(0, 0, host_resolver, NULL, NULL, NULL) {}
[email protected]e60e47a2010-07-14 03:37:18728
hashimoto0d3e4fb2015-01-09 05:02:50729template <>
[email protected]2df19bb2010-08-25 20:13:46730CaptureGroupNameHttpProxySocketPool::CaptureGroupNameSocketPool(
hashimotodae13b02015-01-15 04:28:21731 HostResolver* /* host_resolver */,
[email protected]9e1bdd32011-02-03 21:48:34732 CertVerifier* /* cert_verifier */)
tbansal16196a1e2017-06-09 01:50:09733 : HttpProxyClientSocketPool(0, 0, NULL, NULL, NULL, NULL) {}
[email protected]2df19bb2010-08-25 20:13:46734
[email protected]007b3f82013-04-09 08:46:45735template <>
[email protected]e60e47a2010-07-14 03:37:18736CaptureGroupNameSSLSocketPool::CaptureGroupNameSocketPool(
hashimotodae13b02015-01-15 04:28:21737 HostResolver* /* host_resolver */,
[email protected]9e1bdd32011-02-03 21:48:34738 CertVerifier* cert_verifier)
[email protected]007b3f82013-04-09 08:46:45739 : SSLClientSocketPool(0,
740 0,
[email protected]007b3f82013-04-09 08:46:45741 cert_verifier,
742 NULL,
743 NULL,
[email protected]284303b62013-11-28 15:11:54744 NULL,
eranm6571b2b2014-12-03 15:53:23745 NULL,
[email protected]007b3f82013-04-09 08:46:45746 std::string(),
747 NULL,
748 NULL,
749 NULL,
750 NULL,
751 NULL,
[email protected]8e458552014-08-05 00:02:15752 NULL) {
753}
[email protected]2227c692010-05-04 15:36:11754
[email protected]231d5a32008-09-13 00:45:27755//-----------------------------------------------------------------------------
756
[email protected]79cb5c12011-09-12 13:12:04757// Helper functions for validating that AuthChallengeInfo's are correctly
758// configured for common cases.
759bool CheckBasicServerAuth(const AuthChallengeInfo* auth_challenge) {
760 if (!auth_challenge)
761 return false;
762 EXPECT_FALSE(auth_challenge->is_proxy);
asanka098c0092016-06-16 20:18:43763 EXPECT_EQ("http://www.example.org", auth_challenge->challenger.Serialize());
[email protected]79cb5c12011-09-12 13:12:04764 EXPECT_EQ("MyRealm1", auth_challenge->realm);
aberentbba302d2015-12-03 10:20:19765 EXPECT_EQ(kBasicAuthScheme, auth_challenge->scheme);
[email protected]79cb5c12011-09-12 13:12:04766 return true;
767}
768
769bool CheckBasicProxyAuth(const AuthChallengeInfo* auth_challenge) {
770 if (!auth_challenge)
771 return false;
772 EXPECT_TRUE(auth_challenge->is_proxy);
asanka098c0092016-06-16 20:18:43773 EXPECT_EQ("http://myproxy:70", auth_challenge->challenger.Serialize());
774 EXPECT_EQ("MyRealm1", auth_challenge->realm);
775 EXPECT_EQ(kBasicAuthScheme, auth_challenge->scheme);
776 return true;
777}
778
779bool CheckBasicSecureProxyAuth(const AuthChallengeInfo* auth_challenge) {
780 if (!auth_challenge)
781 return false;
782 EXPECT_TRUE(auth_challenge->is_proxy);
783 EXPECT_EQ("https://myproxy:70", auth_challenge->challenger.Serialize());
[email protected]79cb5c12011-09-12 13:12:04784 EXPECT_EQ("MyRealm1", auth_challenge->realm);
aberentbba302d2015-12-03 10:20:19785 EXPECT_EQ(kBasicAuthScheme, auth_challenge->scheme);
[email protected]79cb5c12011-09-12 13:12:04786 return true;
787}
788
789bool CheckDigestServerAuth(const AuthChallengeInfo* auth_challenge) {
790 if (!auth_challenge)
791 return false;
792 EXPECT_FALSE(auth_challenge->is_proxy);
asanka098c0092016-06-16 20:18:43793 EXPECT_EQ("http://www.example.org", auth_challenge->challenger.Serialize());
[email protected]79cb5c12011-09-12 13:12:04794 EXPECT_EQ("digestive", auth_challenge->realm);
aberentbba302d2015-12-03 10:20:19795 EXPECT_EQ(kDigestAuthScheme, auth_challenge->scheme);
[email protected]79cb5c12011-09-12 13:12:04796 return true;
797}
798
thakis84dff942015-07-28 20:47:38799#if defined(NTLM_PORTABLE)
[email protected]79cb5c12011-09-12 13:12:04800bool CheckNTLMServerAuth(const AuthChallengeInfo* auth_challenge) {
801 if (!auth_challenge)
802 return false;
803 EXPECT_FALSE(auth_challenge->is_proxy);
Bence Béky83eb3512017-09-05 12:56:09804 EXPECT_EQ("https://172.22.68.17", auth_challenge->challenger.Serialize());
[email protected]79cb5c12011-09-12 13:12:04805 EXPECT_EQ(std::string(), auth_challenge->realm);
aberentbba302d2015-12-03 10:20:19806 EXPECT_EQ(kNtlmAuthScheme, auth_challenge->scheme);
[email protected]79cb5c12011-09-12 13:12:04807 return true;
808}
thakis84dff942015-07-28 20:47:38809#endif // defined(NTLM_PORTABLE)
[email protected]79cb5c12011-09-12 13:12:04810
[email protected]448d4ca52012-03-04 04:12:23811} // namespace
812
bncd16676a2016-07-20 16:23:01813TEST_F(HttpNetworkTransactionTest, Basic) {
danakj1fd259a02016-04-16 03:17:09814 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:16815 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]231d5a32008-09-13 00:45:27816}
817
bncd16676a2016-07-20 16:23:01818TEST_F(HttpNetworkTransactionTest, SimpleGET) {
[email protected]231d5a32008-09-13 00:45:27819 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:35820 MockRead("HTTP/1.0 200 OK\r\n\r\n"),
821 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:06822 MockRead(SYNCHRONOUS, OK),
[email protected]231d5a32008-09-13 00:45:27823 };
[email protected]31a2bfe2010-02-09 08:03:39824 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
825 arraysize(data_reads));
robpercival214763f2016-07-01 23:27:01826 EXPECT_THAT(out.rv, IsOk());
[email protected]231d5a32008-09-13 00:45:27827 EXPECT_EQ("HTTP/1.0 200 OK", out.status_line);
828 EXPECT_EQ("hello world", out.response_data);
sclittlefb249892015-09-10 21:33:22829 int64_t reads_size = CountReadBytes(data_reads, arraysize(data_reads));
830 EXPECT_EQ(reads_size, out.total_received_bytes);
ttuttle1f2d7e92015-04-28 16:17:47831 EXPECT_EQ(0u, out.connection_attempts.size());
ttuttled9dbc652015-09-29 20:00:59832
833 EXPECT_FALSE(out.remote_endpoint_after_start.address().empty());
[email protected]231d5a32008-09-13 00:45:27834}
835
836// Response with no status line.
bncd16676a2016-07-20 16:23:01837TEST_F(HttpNetworkTransactionTest, SimpleGETNoHeaders) {
[email protected]231d5a32008-09-13 00:45:27838 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:35839 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:06840 MockRead(SYNCHRONOUS, OK),
[email protected]231d5a32008-09-13 00:45:27841 };
[email protected]31a2bfe2010-02-09 08:03:39842 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
843 arraysize(data_reads));
mmenkea2dcd3bf2016-08-16 21:49:41844 EXPECT_THAT(out.rv, IsOk());
845 EXPECT_EQ("HTTP/0.9 200 OK", out.status_line);
846 EXPECT_EQ("hello world", out.response_data);
847 int64_t reads_size = CountReadBytes(data_reads, arraysize(data_reads));
848 EXPECT_EQ(reads_size, out.total_received_bytes);
[email protected]231d5a32008-09-13 00:45:27849}
850
mmenkea7da6da2016-09-01 21:56:52851// Response with no status line, and a weird port. Should fail by default.
852TEST_F(HttpNetworkTransactionTest, SimpleGETNoHeadersWeirdPort) {
853 MockRead data_reads[] = {
854 MockRead("hello world"), MockRead(SYNCHRONOUS, OK),
855 };
856
857 StaticSocketDataProvider data(data_reads, arraysize(data_reads), nullptr, 0);
858 session_deps_.socket_factory->AddSocketDataProvider(&data);
859
860 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
861
krasinc06a72a2016-12-21 03:42:46862 HttpRequestInfo request;
bnc87dcefc2017-05-25 12:47:58863 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:19864 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
mmenkea7da6da2016-09-01 21:56:52865
mmenkea7da6da2016-09-01 21:56:52866 request.method = "GET";
867 request.url = GURL("http://www.example.com:2000/");
868 TestCompletionCallback callback;
tfarina42834112016-09-22 13:38:20869 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
mmenkea7da6da2016-09-01 21:56:52870 EXPECT_THAT(callback.GetResult(rv), IsError(ERR_INVALID_HTTP_RESPONSE));
871}
872
Shivani Sharmafdcaefd2017-11-02 00:12:26873// Tests that request info can be destroyed after the headers phase is complete.
874TEST_F(HttpNetworkTransactionTest, SimpleGETNoReadDestroyRequestInfo) {
875 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
876 auto trans =
877 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
878
879 MockRead data_reads[] = {
880 MockRead("HTTP/1.0 200 OK\r\n"), MockRead("Connection: keep-alive\r\n"),
881 MockRead("Content-Length: 100\r\n\r\n"), MockRead(SYNCHRONOUS, 0),
882 };
883 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
884 session_deps_.socket_factory->AddSocketDataProvider(&data);
885
886 TestCompletionCallback callback;
887
888 {
889 auto request = std::make_unique<HttpRequestInfo>();
890 request->method = "GET";
891 request->url = GURL("http://www.example.org/");
892
893 int rv =
894 trans->Start(request.get(), callback.callback(), NetLogWithSource());
895
896 EXPECT_THAT(callback.GetResult(rv), IsOk());
897 } // Let request info be destroyed.
898
899 trans.reset();
900}
901
mmenkea7da6da2016-09-01 21:56:52902// Response with no status line, and a weird port. Option to allow weird ports
903// enabled.
904TEST_F(HttpNetworkTransactionTest, SimpleGETNoHeadersWeirdPortAllowed) {
905 MockRead data_reads[] = {
906 MockRead("hello world"), MockRead(SYNCHRONOUS, OK),
907 };
908
909 StaticSocketDataProvider data(data_reads, arraysize(data_reads), nullptr, 0);
910 session_deps_.socket_factory->AddSocketDataProvider(&data);
911 session_deps_.http_09_on_non_default_ports_enabled = true;
912 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
913
krasinc06a72a2016-12-21 03:42:46914 HttpRequestInfo request;
bnc87dcefc2017-05-25 12:47:58915 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:19916 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
mmenkea7da6da2016-09-01 21:56:52917
mmenkea7da6da2016-09-01 21:56:52918 request.method = "GET";
919 request.url = GURL("http://www.example.com:2000/");
920 TestCompletionCallback callback;
tfarina42834112016-09-22 13:38:20921 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
mmenkea7da6da2016-09-01 21:56:52922 EXPECT_THAT(callback.GetResult(rv), IsOk());
923
924 const HttpResponseInfo* info = trans->GetResponseInfo();
925 ASSERT_TRUE(info->headers);
926 EXPECT_EQ("HTTP/0.9 200 OK", info->headers->GetStatusLine());
927
928 // Don't bother to read the body - that's verified elsewhere, important thing
929 // is that the option to allow HTTP/0.9 on non-default ports is respected.
930}
931
[email protected]231d5a32008-09-13 00:45:27932// Allow up to 4 bytes of junk to precede status line.
bncd16676a2016-07-20 16:23:01933TEST_F(HttpNetworkTransactionTest, StatusLineJunk3Bytes) {
[email protected]231d5a32008-09-13 00:45:27934 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:35935 MockRead("xxxHTTP/1.0 404 Not Found\nServer: blah\n\nDATA"),
[email protected]8ddf8322012-02-23 18:08:06936 MockRead(SYNCHRONOUS, OK),
[email protected]231d5a32008-09-13 00:45:27937 };
[email protected]31a2bfe2010-02-09 08:03:39938 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
939 arraysize(data_reads));
robpercival214763f2016-07-01 23:27:01940 EXPECT_THAT(out.rv, IsOk());
[email protected]231d5a32008-09-13 00:45:27941 EXPECT_EQ("HTTP/1.0 404 Not Found", out.status_line);
942 EXPECT_EQ("DATA", out.response_data);
sclittlefb249892015-09-10 21:33:22943 int64_t reads_size = CountReadBytes(data_reads, arraysize(data_reads));
944 EXPECT_EQ(reads_size, out.total_received_bytes);
[email protected]231d5a32008-09-13 00:45:27945}
946
947// Allow up to 4 bytes of junk to precede status line.
bncd16676a2016-07-20 16:23:01948TEST_F(HttpNetworkTransactionTest, StatusLineJunk4Bytes) {
[email protected]231d5a32008-09-13 00:45:27949 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:35950 MockRead("\n\nQJHTTP/1.0 404 Not Found\nServer: blah\n\nDATA"),
[email protected]8ddf8322012-02-23 18:08:06951 MockRead(SYNCHRONOUS, OK),
[email protected]231d5a32008-09-13 00:45:27952 };
[email protected]31a2bfe2010-02-09 08:03:39953 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
954 arraysize(data_reads));
robpercival214763f2016-07-01 23:27:01955 EXPECT_THAT(out.rv, IsOk());
[email protected]231d5a32008-09-13 00:45:27956 EXPECT_EQ("HTTP/1.0 404 Not Found", out.status_line);
957 EXPECT_EQ("DATA", out.response_data);
sclittlefb249892015-09-10 21:33:22958 int64_t reads_size = CountReadBytes(data_reads, arraysize(data_reads));
959 EXPECT_EQ(reads_size, out.total_received_bytes);
[email protected]231d5a32008-09-13 00:45:27960}
961
962// Beyond 4 bytes of slop and it should fail to find a status line.
bncd16676a2016-07-20 16:23:01963TEST_F(HttpNetworkTransactionTest, StatusLineJunk5Bytes) {
[email protected]231d5a32008-09-13 00:45:27964 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:35965 MockRead("xxxxxHTTP/1.1 404 Not Found\nServer: blah"),
[email protected]8ddf8322012-02-23 18:08:06966 MockRead(SYNCHRONOUS, OK),
[email protected]231d5a32008-09-13 00:45:27967 };
[email protected]31a2bfe2010-02-09 08:03:39968 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
969 arraysize(data_reads));
mmenkea2dcd3bf2016-08-16 21:49:41970 EXPECT_THAT(out.rv, IsOk());
971 EXPECT_EQ("HTTP/0.9 200 OK", out.status_line);
972 EXPECT_EQ("xxxxxHTTP/1.1 404 Not Found\nServer: blah", out.response_data);
973 int64_t reads_size = CountReadBytes(data_reads, arraysize(data_reads));
974 EXPECT_EQ(reads_size, out.total_received_bytes);
[email protected]231d5a32008-09-13 00:45:27975}
976
977// Same as StatusLineJunk4Bytes, except the read chunks are smaller.
bncd16676a2016-07-20 16:23:01978TEST_F(HttpNetworkTransactionTest, StatusLineJunk4Bytes_Slow) {
[email protected]231d5a32008-09-13 00:45:27979 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:35980 MockRead("\n"),
981 MockRead("\n"),
982 MockRead("Q"),
983 MockRead("J"),
984 MockRead("HTTP/1.0 404 Not Found\nServer: blah\n\nDATA"),
[email protected]8ddf8322012-02-23 18:08:06985 MockRead(SYNCHRONOUS, OK),
[email protected]231d5a32008-09-13 00:45:27986 };
[email protected]31a2bfe2010-02-09 08:03:39987 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
988 arraysize(data_reads));
robpercival214763f2016-07-01 23:27:01989 EXPECT_THAT(out.rv, IsOk());
[email protected]231d5a32008-09-13 00:45:27990 EXPECT_EQ("HTTP/1.0 404 Not Found", out.status_line);
991 EXPECT_EQ("DATA", out.response_data);
sclittlefb249892015-09-10 21:33:22992 int64_t reads_size = CountReadBytes(data_reads, arraysize(data_reads));
993 EXPECT_EQ(reads_size, out.total_received_bytes);
[email protected]231d5a32008-09-13 00:45:27994}
995
996// Close the connection before enough bytes to have a status line.
bncd16676a2016-07-20 16:23:01997TEST_F(HttpNetworkTransactionTest, StatusLinePartial) {
[email protected]231d5a32008-09-13 00:45:27998 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:35999 MockRead("HTT"),
[email protected]8ddf8322012-02-23 18:08:061000 MockRead(SYNCHRONOUS, OK),
[email protected]231d5a32008-09-13 00:45:271001 };
[email protected]31a2bfe2010-02-09 08:03:391002 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
1003 arraysize(data_reads));
mmenkea2dcd3bf2016-08-16 21:49:411004 EXPECT_THAT(out.rv, IsOk());
1005 EXPECT_EQ("HTTP/0.9 200 OK", out.status_line);
1006 EXPECT_EQ("HTT", out.response_data);
1007 int64_t reads_size = CountReadBytes(data_reads, arraysize(data_reads));
1008 EXPECT_EQ(reads_size, out.total_received_bytes);
initial.commit586acc5fe2008-07-26 22:42:521009}
1010
[email protected]f9d44aa2008-09-23 23:57:171011// Simulate a 204 response, lacking a Content-Length header, sent over a
1012// persistent connection. The response should still terminate since a 204
1013// cannot have a response body.
bncd16676a2016-07-20 16:23:011014TEST_F(HttpNetworkTransactionTest, StopsReading204) {
[email protected]b8015c42013-12-24 15:18:191015 char junk[] = "junk";
[email protected]f9d44aa2008-09-23 23:57:171016 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:351017 MockRead("HTTP/1.1 204 No Content\r\n\r\n"),
[email protected]b8015c42013-12-24 15:18:191018 MockRead(junk), // Should not be read!!
[email protected]8ddf8322012-02-23 18:08:061019 MockRead(SYNCHRONOUS, OK),
[email protected]f9d44aa2008-09-23 23:57:171020 };
[email protected]31a2bfe2010-02-09 08:03:391021 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
1022 arraysize(data_reads));
robpercival214763f2016-07-01 23:27:011023 EXPECT_THAT(out.rv, IsOk());
[email protected]f9d44aa2008-09-23 23:57:171024 EXPECT_EQ("HTTP/1.1 204 No Content", out.status_line);
1025 EXPECT_EQ("", out.response_data);
sclittlefb249892015-09-10 21:33:221026 int64_t reads_size = CountReadBytes(data_reads, arraysize(data_reads));
1027 int64_t response_size = reads_size - strlen(junk);
1028 EXPECT_EQ(response_size, out.total_received_bytes);
[email protected]f9d44aa2008-09-23 23:57:171029}
1030
[email protected]0877e3d2009-10-17 22:29:571031// A simple request using chunked encoding with some extra data after.
bncd16676a2016-07-20 16:23:011032TEST_F(HttpNetworkTransactionTest, ChunkedEncoding) {
[email protected]b8015c42013-12-24 15:18:191033 std::string final_chunk = "0\r\n\r\n";
1034 std::string extra_data = "HTTP/1.1 200 OK\r\n";
1035 std::string last_read = final_chunk + extra_data;
[email protected]0877e3d2009-10-17 22:29:571036 MockRead data_reads[] = {
1037 MockRead("HTTP/1.1 200 OK\r\nTransfer-Encoding: chunked\r\n\r\n"),
1038 MockRead("5\r\nHello\r\n"),
1039 MockRead("1\r\n"),
1040 MockRead(" \r\n"),
1041 MockRead("5\r\nworld\r\n"),
[email protected]b8015c42013-12-24 15:18:191042 MockRead(last_read.data()),
[email protected]8ddf8322012-02-23 18:08:061043 MockRead(SYNCHRONOUS, OK),
[email protected]0877e3d2009-10-17 22:29:571044 };
[email protected]31a2bfe2010-02-09 08:03:391045 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
1046 arraysize(data_reads));
robpercival214763f2016-07-01 23:27:011047 EXPECT_THAT(out.rv, IsOk());
[email protected]0877e3d2009-10-17 22:29:571048 EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
1049 EXPECT_EQ("Hello world", out.response_data);
sclittlefb249892015-09-10 21:33:221050 int64_t reads_size = CountReadBytes(data_reads, arraysize(data_reads));
1051 int64_t response_size = reads_size - extra_data.size();
1052 EXPECT_EQ(response_size, out.total_received_bytes);
[email protected]0877e3d2009-10-17 22:29:571053}
1054
[email protected]9fe44f52010-09-23 18:36:001055// Next tests deal with http://crbug.com/56344.
1056
bncd16676a2016-07-20 16:23:011057TEST_F(HttpNetworkTransactionTest,
[email protected]9fe44f52010-09-23 18:36:001058 MultipleContentLengthHeadersNoTransferEncoding) {
1059 MockRead data_reads[] = {
1060 MockRead("HTTP/1.1 200 OK\r\n"),
1061 MockRead("Content-Length: 10\r\n"),
1062 MockRead("Content-Length: 5\r\n\r\n"),
1063 };
1064 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
1065 arraysize(data_reads));
robpercival214763f2016-07-01 23:27:011066 EXPECT_THAT(out.rv, IsError(ERR_RESPONSE_HEADERS_MULTIPLE_CONTENT_LENGTH));
[email protected]9fe44f52010-09-23 18:36:001067}
1068
bncd16676a2016-07-20 16:23:011069TEST_F(HttpNetworkTransactionTest,
[email protected]44b52042010-10-29 22:48:041070 DuplicateContentLengthHeadersNoTransferEncoding) {
1071 MockRead data_reads[] = {
1072 MockRead("HTTP/1.1 200 OK\r\n"),
1073 MockRead("Content-Length: 5\r\n"),
1074 MockRead("Content-Length: 5\r\n\r\n"),
1075 MockRead("Hello"),
1076 };
1077 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
1078 arraysize(data_reads));
robpercival214763f2016-07-01 23:27:011079 EXPECT_THAT(out.rv, IsOk());
[email protected]44b52042010-10-29 22:48:041080 EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
1081 EXPECT_EQ("Hello", out.response_data);
1082}
1083
bncd16676a2016-07-20 16:23:011084TEST_F(HttpNetworkTransactionTest,
[email protected]44b52042010-10-29 22:48:041085 ComplexContentLengthHeadersNoTransferEncoding) {
1086 // More than 2 dupes.
1087 {
1088 MockRead data_reads[] = {
1089 MockRead("HTTP/1.1 200 OK\r\n"),
1090 MockRead("Content-Length: 5\r\n"),
1091 MockRead("Content-Length: 5\r\n"),
1092 MockRead("Content-Length: 5\r\n\r\n"),
1093 MockRead("Hello"),
1094 };
1095 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
1096 arraysize(data_reads));
robpercival214763f2016-07-01 23:27:011097 EXPECT_THAT(out.rv, IsOk());
[email protected]44b52042010-10-29 22:48:041098 EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
1099 EXPECT_EQ("Hello", out.response_data);
1100 }
1101 // HTTP/1.0
1102 {
1103 MockRead data_reads[] = {
1104 MockRead("HTTP/1.0 200 OK\r\n"),
1105 MockRead("Content-Length: 5\r\n"),
1106 MockRead("Content-Length: 5\r\n"),
1107 MockRead("Content-Length: 5\r\n\r\n"),
1108 MockRead("Hello"),
1109 };
1110 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
1111 arraysize(data_reads));
robpercival214763f2016-07-01 23:27:011112 EXPECT_THAT(out.rv, IsOk());
[email protected]44b52042010-10-29 22:48:041113 EXPECT_EQ("HTTP/1.0 200 OK", out.status_line);
1114 EXPECT_EQ("Hello", out.response_data);
1115 }
1116 // 2 dupes and one mismatched.
1117 {
1118 MockRead data_reads[] = {
1119 MockRead("HTTP/1.1 200 OK\r\n"),
1120 MockRead("Content-Length: 10\r\n"),
1121 MockRead("Content-Length: 10\r\n"),
1122 MockRead("Content-Length: 5\r\n\r\n"),
1123 };
1124 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
1125 arraysize(data_reads));
robpercival214763f2016-07-01 23:27:011126 EXPECT_THAT(out.rv, IsError(ERR_RESPONSE_HEADERS_MULTIPLE_CONTENT_LENGTH));
[email protected]44b52042010-10-29 22:48:041127 }
1128}
1129
bncd16676a2016-07-20 16:23:011130TEST_F(HttpNetworkTransactionTest,
[email protected]9fe44f52010-09-23 18:36:001131 MultipleContentLengthHeadersTransferEncoding) {
1132 MockRead data_reads[] = {
1133 MockRead("HTTP/1.1 200 OK\r\n"),
1134 MockRead("Content-Length: 666\r\n"),
1135 MockRead("Content-Length: 1337\r\n"),
1136 MockRead("Transfer-Encoding: chunked\r\n\r\n"),
1137 MockRead("5\r\nHello\r\n"),
1138 MockRead("1\r\n"),
1139 MockRead(" \r\n"),
1140 MockRead("5\r\nworld\r\n"),
1141 MockRead("0\r\n\r\nHTTP/1.1 200 OK\r\n"),
[email protected]8ddf8322012-02-23 18:08:061142 MockRead(SYNCHRONOUS, OK),
[email protected]9fe44f52010-09-23 18:36:001143 };
1144 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
1145 arraysize(data_reads));
robpercival214763f2016-07-01 23:27:011146 EXPECT_THAT(out.rv, IsOk());
[email protected]9fe44f52010-09-23 18:36:001147 EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
1148 EXPECT_EQ("Hello world", out.response_data);
1149}
1150
[email protected]1628fe92011-10-04 23:04:551151// Next tests deal with http://crbug.com/98895.
1152
1153// Checks that a single Content-Disposition header results in no error.
bncd16676a2016-07-20 16:23:011154TEST_F(HttpNetworkTransactionTest, SingleContentDispositionHeader) {
[email protected]1628fe92011-10-04 23:04:551155 MockRead data_reads[] = {
1156 MockRead("HTTP/1.1 200 OK\r\n"),
1157 MockRead("Content-Disposition: attachment;filename=\"salutations.txt\"r\n"),
1158 MockRead("Content-Length: 5\r\n\r\n"),
1159 MockRead("Hello"),
1160 };
1161 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
1162 arraysize(data_reads));
robpercival214763f2016-07-01 23:27:011163 EXPECT_THAT(out.rv, IsOk());
[email protected]1628fe92011-10-04 23:04:551164 EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
1165 EXPECT_EQ("Hello", out.response_data);
1166}
1167
[email protected]54a9c6e52012-03-21 20:10:591168// Checks that two identical Content-Disposition headers result in no error.
bncd16676a2016-07-20 16:23:011169TEST_F(HttpNetworkTransactionTest, TwoIdenticalContentDispositionHeaders) {
[email protected]1628fe92011-10-04 23:04:551170 MockRead data_reads[] = {
1171 MockRead("HTTP/1.1 200 OK\r\n"),
1172 MockRead("Content-Disposition: attachment;filename=\"greetings.txt\"r\n"),
1173 MockRead("Content-Disposition: attachment;filename=\"greetings.txt\"r\n"),
1174 MockRead("Content-Length: 5\r\n\r\n"),
1175 MockRead("Hello"),
1176 };
1177 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
1178 arraysize(data_reads));
robpercival214763f2016-07-01 23:27:011179 EXPECT_THAT(out.rv, IsOk());
[email protected]54a9c6e52012-03-21 20:10:591180 EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
1181 EXPECT_EQ("Hello", out.response_data);
[email protected]1628fe92011-10-04 23:04:551182}
1183
1184// Checks that two distinct Content-Disposition headers result in an error.
bncd16676a2016-07-20 16:23:011185TEST_F(HttpNetworkTransactionTest, TwoDistinctContentDispositionHeaders) {
[email protected]1628fe92011-10-04 23:04:551186 MockRead data_reads[] = {
1187 MockRead("HTTP/1.1 200 OK\r\n"),
1188 MockRead("Content-Disposition: attachment;filename=\"greetings.txt\"r\n"),
1189 MockRead("Content-Disposition: attachment;filename=\"hi.txt\"r\n"),
1190 MockRead("Content-Length: 5\r\n\r\n"),
1191 MockRead("Hello"),
1192 };
1193 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
1194 arraysize(data_reads));
robpercival214763f2016-07-01 23:27:011195 EXPECT_THAT(out.rv,
1196 IsError(ERR_RESPONSE_HEADERS_MULTIPLE_CONTENT_DISPOSITION));
[email protected]1628fe92011-10-04 23:04:551197}
1198
[email protected]54a9c6e52012-03-21 20:10:591199// Checks that two identical Location headers result in no error.
1200// Also tests Location header behavior.
bncd16676a2016-07-20 16:23:011201TEST_F(HttpNetworkTransactionTest, TwoIdenticalLocationHeaders) {
[email protected]1628fe92011-10-04 23:04:551202 MockRead data_reads[] = {
1203 MockRead("HTTP/1.1 302 Redirect\r\n"),
1204 MockRead("Location: http://good.com/\r\n"),
[email protected]54a9c6e52012-03-21 20:10:591205 MockRead("Location: http://good.com/\r\n"),
[email protected]1628fe92011-10-04 23:04:551206 MockRead("Content-Length: 0\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:061207 MockRead(SYNCHRONOUS, OK),
[email protected]1628fe92011-10-04 23:04:551208 };
1209
1210 HttpRequestInfo request;
1211 request.method = "GET";
1212 request.url = GURL("http://redirect.com/");
[email protected]1628fe92011-10-04 23:04:551213
danakj1fd259a02016-04-16 03:17:091214 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:161215 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]1628fe92011-10-04 23:04:551216
1217 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:071218 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1628fe92011-10-04 23:04:551219
[email protected]49639fa2011-12-20 23:22:411220 TestCompletionCallback callback;
[email protected]1628fe92011-10-04 23:04:551221
tfarina42834112016-09-22 13:38:201222 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:011223 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]1628fe92011-10-04 23:04:551224
robpercival214763f2016-07-01 23:27:011225 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]1628fe92011-10-04 23:04:551226
bnc691fda62016-08-12 00:43:161227 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:521228 ASSERT_TRUE(response);
1229 ASSERT_TRUE(response->headers);
[email protected]1628fe92011-10-04 23:04:551230 EXPECT_EQ("HTTP/1.1 302 Redirect", response->headers->GetStatusLine());
1231 std::string url;
1232 EXPECT_TRUE(response->headers->IsRedirect(&url));
1233 EXPECT_EQ("http://good.com/", url);
tbansal2ecbbc72016-10-06 17:15:471234 EXPECT_TRUE(response->proxy_server.is_direct());
[email protected]1628fe92011-10-04 23:04:551235}
1236
[email protected]1628fe92011-10-04 23:04:551237// Checks that two distinct Location headers result in an error.
bncd16676a2016-07-20 16:23:011238TEST_F(HttpNetworkTransactionTest, TwoDistinctLocationHeaders) {
[email protected]1628fe92011-10-04 23:04:551239 MockRead data_reads[] = {
1240 MockRead("HTTP/1.1 302 Redirect\r\n"),
1241 MockRead("Location: http://good.com/\r\n"),
1242 MockRead("Location: http://evil.com/\r\n"),
1243 MockRead("Content-Length: 0\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:061244 MockRead(SYNCHRONOUS, OK),
[email protected]1628fe92011-10-04 23:04:551245 };
1246 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
1247 arraysize(data_reads));
robpercival214763f2016-07-01 23:27:011248 EXPECT_THAT(out.rv, IsError(ERR_RESPONSE_HEADERS_MULTIPLE_LOCATION));
[email protected]1628fe92011-10-04 23:04:551249}
1250
[email protected]ef0faf2e72009-03-05 23:27:231251// Do a request using the HEAD method. Verify that we don't try to read the
1252// message body (since HEAD has none).
bncd16676a2016-07-20 16:23:011253TEST_F(HttpNetworkTransactionTest, Head) {
[email protected]1c773ea12009-04-28 19:58:421254 HttpRequestInfo request;
[email protected]ef0faf2e72009-03-05 23:27:231255 request.method = "HEAD";
bncce36dca22015-04-21 22:11:231256 request.url = GURL("http://www.example.org/");
[email protected]ef0faf2e72009-03-05 23:27:231257
danakj1fd259a02016-04-16 03:17:091258 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:161259 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
ryansturm49a8cb12016-06-15 16:51:091260 BeforeHeadersSentHandler headers_handler;
bnc691fda62016-08-12 00:43:161261 trans.SetBeforeHeadersSentCallback(
ryansturm49a8cb12016-06-15 16:51:091262 base::Bind(&BeforeHeadersSentHandler::OnBeforeHeadersSent,
1263 base::Unretained(&headers_handler)));
[email protected]cb9bf6ca2011-01-28 13:15:271264
[email protected]ef0faf2e72009-03-05 23:27:231265 MockWrite data_writes1[] = {
csharrisonf473dd192015-08-18 13:54:131266 MockWrite("HEAD / HTTP/1.1\r\n"
1267 "Host: www.example.org\r\n"
1268 "Connection: keep-alive\r\n\r\n"),
[email protected]ef0faf2e72009-03-05 23:27:231269 };
1270 MockRead data_reads1[] = {
mmenked39192ee2015-12-09 00:57:231271 MockRead("HTTP/1.1 404 Not Found\r\n"), MockRead("Server: Blah\r\n"),
1272 MockRead("Content-Length: 1234\r\n\r\n"),
[email protected]ef0faf2e72009-03-05 23:27:231273
mmenked39192ee2015-12-09 00:57:231274 // No response body because the test stops reading here.
1275 MockRead(SYNCHRONOUS, ERR_UNEXPECTED),
[email protected]ef0faf2e72009-03-05 23:27:231276 };
1277
[email protected]31a2bfe2010-02-09 08:03:391278 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
1279 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:071280 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]ef0faf2e72009-03-05 23:27:231281
[email protected]49639fa2011-12-20 23:22:411282 TestCompletionCallback callback1;
[email protected]ef0faf2e72009-03-05 23:27:231283
tfarina42834112016-09-22 13:38:201284 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:011285 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]ef0faf2e72009-03-05 23:27:231286
1287 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:011288 EXPECT_THAT(rv, IsOk());
[email protected]ef0faf2e72009-03-05 23:27:231289
bnc691fda62016-08-12 00:43:161290 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:521291 ASSERT_TRUE(response);
[email protected]ef0faf2e72009-03-05 23:27:231292
1293 // Check that the headers got parsed.
wezca1070932016-05-26 20:30:521294 EXPECT_TRUE(response->headers);
[email protected]ef0faf2e72009-03-05 23:27:231295 EXPECT_EQ(1234, response->headers->GetContentLength());
1296 EXPECT_EQ("HTTP/1.1 404 Not Found", response->headers->GetStatusLine());
tbansal2ecbbc72016-10-06 17:15:471297 EXPECT_TRUE(response->proxy_server.is_direct());
ryansturm49a8cb12016-06-15 16:51:091298 EXPECT_TRUE(headers_handler.observed_before_headers_sent());
1299 EXPECT_FALSE(headers_handler.observed_before_headers_sent_with_proxy());
[email protected]ef0faf2e72009-03-05 23:27:231300
1301 std::string server_header;
olli.raulaee489a52016-01-25 08:37:101302 size_t iter = 0;
[email protected]ef0faf2e72009-03-05 23:27:231303 bool has_server_header = response->headers->EnumerateHeader(
1304 &iter, "Server", &server_header);
1305 EXPECT_TRUE(has_server_header);
1306 EXPECT_EQ("Blah", server_header);
1307
1308 // Reading should give EOF right away, since there is no message body
1309 // (despite non-zero content-length).
1310 std::string response_data;
bnc691fda62016-08-12 00:43:161311 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:011312 EXPECT_THAT(rv, IsOk());
[email protected]ef0faf2e72009-03-05 23:27:231313 EXPECT_EQ("", response_data);
1314}
1315
bncd16676a2016-07-20 16:23:011316TEST_F(HttpNetworkTransactionTest, ReuseConnection) {
danakj1fd259a02016-04-16 03:17:091317 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
initial.commit586acc5fe2008-07-26 22:42:521318
1319 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:351320 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
1321 MockRead("hello"),
1322 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
1323 MockRead("world"),
[email protected]8ddf8322012-02-23 18:08:061324 MockRead(SYNCHRONOUS, OK),
initial.commit586acc5fe2008-07-26 22:42:521325 };
[email protected]31a2bfe2010-02-09 08:03:391326 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:071327 session_deps_.socket_factory->AddSocketDataProvider(&data);
initial.commit586acc5fe2008-07-26 22:42:521328
[email protected]0b0bf032010-09-21 18:08:501329 const char* const kExpectedResponseData[] = {
initial.commit586acc5fe2008-07-26 22:42:521330 "hello", "world"
1331 };
1332
1333 for (int i = 0; i < 2; ++i) {
[email protected]1c773ea12009-04-28 19:58:421334 HttpRequestInfo request;
initial.commit586acc5fe2008-07-26 22:42:521335 request.method = "GET";
bncce36dca22015-04-21 22:11:231336 request.url = GURL("http://www.example.org/");
initial.commit586acc5fe2008-07-26 22:42:521337
bnc691fda62016-08-12 00:43:161338 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:271339
[email protected]49639fa2011-12-20 23:22:411340 TestCompletionCallback callback;
initial.commit586acc5fe2008-07-26 22:42:521341
tfarina42834112016-09-22 13:38:201342 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:011343 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
initial.commit586acc5fe2008-07-26 22:42:521344
1345 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:011346 EXPECT_THAT(rv, IsOk());
initial.commit586acc5fe2008-07-26 22:42:521347
bnc691fda62016-08-12 00:43:161348 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:521349 ASSERT_TRUE(response);
initial.commit586acc5fe2008-07-26 22:42:521350
wezca1070932016-05-26 20:30:521351 EXPECT_TRUE(response->headers);
[email protected]3d2a59b2008-09-26 19:44:251352 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
tbansal2ecbbc72016-10-06 17:15:471353 EXPECT_TRUE(response->proxy_server.is_direct());
initial.commit586acc5fe2008-07-26 22:42:521354
1355 std::string response_data;
bnc691fda62016-08-12 00:43:161356 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:011357 EXPECT_THAT(rv, IsOk());
[email protected]3d2a59b2008-09-26 19:44:251358 EXPECT_EQ(kExpectedResponseData[i], response_data);
initial.commit586acc5fe2008-07-26 22:42:521359 }
1360}
1361
bncd16676a2016-07-20 16:23:011362TEST_F(HttpNetworkTransactionTest, Ignores100) {
danakj1fd259a02016-04-16 03:17:091363 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:221364 element_readers.push_back(
Jeremy Roman0579ed62017-08-29 15:56:191365 std::make_unique<UploadBytesElementReader>("foo", 3));
olli.raula6df48b2a2015-11-26 07:40:221366 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]329b68b2012-11-14 17:54:271367
[email protected]1c773ea12009-04-28 19:58:421368 HttpRequestInfo request;
initial.commit586acc5fe2008-07-26 22:42:521369 request.method = "POST";
1370 request.url = GURL("http://www.foo.com/");
[email protected]329b68b2012-11-14 17:54:271371 request.upload_data_stream = &upload_data_stream;
initial.commit586acc5fe2008-07-26 22:42:521372
shivanishab9a143952016-09-19 17:23:411373 // Check the upload progress returned before initialization is correct.
1374 UploadProgress progress = request.upload_data_stream->GetUploadProgress();
1375 EXPECT_EQ(0u, progress.size());
1376 EXPECT_EQ(0u, progress.position());
1377
danakj1fd259a02016-04-16 03:17:091378 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:161379 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:271380
initial.commit586acc5fe2008-07-26 22:42:521381 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:351382 MockRead("HTTP/1.0 100 Continue\r\n\r\n"),
1383 MockRead("HTTP/1.0 200 OK\r\n\r\n"),
1384 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:061385 MockRead(SYNCHRONOUS, OK),
initial.commit586acc5fe2008-07-26 22:42:521386 };
[email protected]31a2bfe2010-02-09 08:03:391387 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:071388 session_deps_.socket_factory->AddSocketDataProvider(&data);
initial.commit586acc5fe2008-07-26 22:42:521389
[email protected]49639fa2011-12-20 23:22:411390 TestCompletionCallback callback;
initial.commit586acc5fe2008-07-26 22:42:521391
tfarina42834112016-09-22 13:38:201392 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:011393 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
initial.commit586acc5fe2008-07-26 22:42:521394
1395 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:011396 EXPECT_THAT(rv, IsOk());
initial.commit586acc5fe2008-07-26 22:42:521397
bnc691fda62016-08-12 00:43:161398 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:521399 ASSERT_TRUE(response);
initial.commit586acc5fe2008-07-26 22:42:521400
wezca1070932016-05-26 20:30:521401 EXPECT_TRUE(response->headers);
[email protected]3d2a59b2008-09-26 19:44:251402 EXPECT_EQ("HTTP/1.0 200 OK", response->headers->GetStatusLine());
initial.commit586acc5fe2008-07-26 22:42:521403
1404 std::string response_data;
bnc691fda62016-08-12 00:43:161405 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:011406 EXPECT_THAT(rv, IsOk());
[email protected]3d2a59b2008-09-26 19:44:251407 EXPECT_EQ("hello world", response_data);
initial.commit586acc5fe2008-07-26 22:42:521408}
1409
[email protected]3a2d3662009-03-27 03:49:141410// This test is almost the same as Ignores100 above, but the response contains
1411// a 102 instead of a 100. Also, instead of HTTP/1.0 the response is
[email protected]0877e3d2009-10-17 22:29:571412// HTTP/1.1 and the two status headers are read in one read.
bncd16676a2016-07-20 16:23:011413TEST_F(HttpNetworkTransactionTest, Ignores1xx) {
[email protected]1c773ea12009-04-28 19:58:421414 HttpRequestInfo request;
[email protected]3a2d3662009-03-27 03:49:141415 request.method = "GET";
1416 request.url = GURL("http://www.foo.com/");
[email protected]3a2d3662009-03-27 03:49:141417
danakj1fd259a02016-04-16 03:17:091418 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:161419 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:271420
[email protected]3a2d3662009-03-27 03:49:141421 MockRead data_reads[] = {
[email protected]0877e3d2009-10-17 22:29:571422 MockRead("HTTP/1.1 102 Unspecified status code\r\n\r\n"
1423 "HTTP/1.1 200 OK\r\n\r\n"),
[email protected]3a2d3662009-03-27 03:49:141424 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:061425 MockRead(SYNCHRONOUS, OK),
[email protected]3a2d3662009-03-27 03:49:141426 };
[email protected]31a2bfe2010-02-09 08:03:391427 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:071428 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]3a2d3662009-03-27 03:49:141429
[email protected]49639fa2011-12-20 23:22:411430 TestCompletionCallback callback;
[email protected]3a2d3662009-03-27 03:49:141431
tfarina42834112016-09-22 13:38:201432 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:011433 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]3a2d3662009-03-27 03:49:141434
1435 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:011436 EXPECT_THAT(rv, IsOk());
[email protected]3a2d3662009-03-27 03:49:141437
bnc691fda62016-08-12 00:43:161438 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:521439 ASSERT_TRUE(response);
[email protected]3a2d3662009-03-27 03:49:141440
wezca1070932016-05-26 20:30:521441 EXPECT_TRUE(response->headers);
[email protected]3a2d3662009-03-27 03:49:141442 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
1443
1444 std::string response_data;
bnc691fda62016-08-12 00:43:161445 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:011446 EXPECT_THAT(rv, IsOk());
[email protected]3a2d3662009-03-27 03:49:141447 EXPECT_EQ("hello world", response_data);
1448}
1449
bncd16676a2016-07-20 16:23:011450TEST_F(HttpNetworkTransactionTest, Incomplete100ThenEOF) {
zmo9528c9f42015-08-04 22:12:081451 HttpRequestInfo request;
1452 request.method = "POST";
1453 request.url = GURL("http://www.foo.com/");
zmo9528c9f42015-08-04 22:12:081454
danakj1fd259a02016-04-16 03:17:091455 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:161456 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
zmo9528c9f42015-08-04 22:12:081457
1458 MockRead data_reads[] = {
1459 MockRead(SYNCHRONOUS, "HTTP/1.0 100 Continue\r\n"),
1460 MockRead(ASYNC, 0),
[email protected]ee9410e72010-01-07 01:42:381461 };
zmo9528c9f42015-08-04 22:12:081462 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
1463 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]ee9410e72010-01-07 01:42:381464
zmo9528c9f42015-08-04 22:12:081465 TestCompletionCallback callback;
[email protected]ee9410e72010-01-07 01:42:381466
tfarina42834112016-09-22 13:38:201467 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:011468 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]ee9410e72010-01-07 01:42:381469
zmo9528c9f42015-08-04 22:12:081470 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:011471 EXPECT_THAT(rv, IsOk());
[email protected]ee9410e72010-01-07 01:42:381472
zmo9528c9f42015-08-04 22:12:081473 std::string response_data;
bnc691fda62016-08-12 00:43:161474 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:011475 EXPECT_THAT(rv, IsOk());
zmo9528c9f42015-08-04 22:12:081476 EXPECT_EQ("", response_data);
[email protected]ee9410e72010-01-07 01:42:381477}
1478
bncd16676a2016-07-20 16:23:011479TEST_F(HttpNetworkTransactionTest, EmptyResponse) {
[email protected]ee9410e72010-01-07 01:42:381480 HttpRequestInfo request;
1481 request.method = "POST";
1482 request.url = GURL("http://www.foo.com/");
[email protected]ee9410e72010-01-07 01:42:381483
danakj1fd259a02016-04-16 03:17:091484 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:161485 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:271486
[email protected]ee9410e72010-01-07 01:42:381487 MockRead data_reads[] = {
[email protected]8ddf8322012-02-23 18:08:061488 MockRead(ASYNC, 0),
[email protected]ee9410e72010-01-07 01:42:381489 };
[email protected]31a2bfe2010-02-09 08:03:391490 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:071491 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]ee9410e72010-01-07 01:42:381492
[email protected]49639fa2011-12-20 23:22:411493 TestCompletionCallback callback;
[email protected]ee9410e72010-01-07 01:42:381494
tfarina42834112016-09-22 13:38:201495 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:011496 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]ee9410e72010-01-07 01:42:381497
1498 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:011499 EXPECT_THAT(rv, IsError(ERR_EMPTY_RESPONSE));
[email protected]ee9410e72010-01-07 01:42:381500}
1501
[email protected]23e482282013-06-14 16:08:021502void HttpNetworkTransactionTest::KeepAliveConnectionResendRequestTest(
[email protected]202965992011-12-07 23:04:511503 const MockWrite* write_failure,
1504 const MockRead* read_failure) {
[email protected]1c773ea12009-04-28 19:58:421505 HttpRequestInfo request;
initial.commit586acc5fe2008-07-26 22:42:521506 request.method = "GET";
1507 request.url = GURL("http://www.foo.com/");
initial.commit586acc5fe2008-07-26 22:42:521508
vishal.b62985ca92015-04-17 08:45:511509 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:071510 session_deps_.net_log = &net_log;
danakj1fd259a02016-04-16 03:17:091511 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:271512
[email protected]202965992011-12-07 23:04:511513 // Written data for successfully sending both requests.
1514 MockWrite data1_writes[] = {
1515 MockWrite("GET / HTTP/1.1\r\n"
1516 "Host: www.foo.com\r\n"
1517 "Connection: keep-alive\r\n\r\n"),
1518 MockWrite("GET / HTTP/1.1\r\n"
1519 "Host: www.foo.com\r\n"
1520 "Connection: keep-alive\r\n\r\n")
1521 };
1522
1523 // Read results for the first request.
initial.commit586acc5fe2008-07-26 22:42:521524 MockRead data1_reads[] = {
[email protected]217e6022008-09-29 18:18:351525 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
1526 MockRead("hello"),
[email protected]8ddf8322012-02-23 18:08:061527 MockRead(ASYNC, OK),
initial.commit586acc5fe2008-07-26 22:42:521528 };
[email protected]202965992011-12-07 23:04:511529
1530 if (write_failure) {
[email protected]a34f61ee2014-03-18 20:59:491531 ASSERT_FALSE(read_failure);
[email protected]202965992011-12-07 23:04:511532 data1_writes[1] = *write_failure;
1533 } else {
1534 ASSERT_TRUE(read_failure);
1535 data1_reads[2] = *read_failure;
1536 }
1537
1538 StaticSocketDataProvider data1(data1_reads, arraysize(data1_reads),
1539 data1_writes, arraysize(data1_writes));
[email protected]bb88e1d32013-05-03 23:11:071540 session_deps_.socket_factory->AddSocketDataProvider(&data1);
initial.commit586acc5fe2008-07-26 22:42:521541
1542 MockRead data2_reads[] = {
[email protected]217e6022008-09-29 18:18:351543 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
1544 MockRead("world"),
[email protected]8ddf8322012-02-23 18:08:061545 MockRead(ASYNC, OK),
initial.commit586acc5fe2008-07-26 22:42:521546 };
[email protected]31a2bfe2010-02-09 08:03:391547 StaticSocketDataProvider data2(data2_reads, arraysize(data2_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:071548 session_deps_.socket_factory->AddSocketDataProvider(&data2);
initial.commit586acc5fe2008-07-26 22:42:521549
thestig9d3bb0c2015-01-24 00:49:511550 const char* const kExpectedResponseData[] = {
initial.commit586acc5fe2008-07-26 22:42:521551 "hello", "world"
1552 };
1553
mikecironef22f9812016-10-04 03:40:191554 uint32_t first_socket_log_id = NetLogSource::kInvalidId;
initial.commit586acc5fe2008-07-26 22:42:521555 for (int i = 0; i < 2; ++i) {
[email protected]49639fa2011-12-20 23:22:411556 TestCompletionCallback callback;
initial.commit586acc5fe2008-07-26 22:42:521557
bnc691fda62016-08-12 00:43:161558 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
initial.commit586acc5fe2008-07-26 22:42:521559
tfarina42834112016-09-22 13:38:201560 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:011561 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
initial.commit586acc5fe2008-07-26 22:42:521562
1563 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:011564 EXPECT_THAT(rv, IsOk());
initial.commit586acc5fe2008-07-26 22:42:521565
[email protected]58e32bb2013-01-21 18:23:251566 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:161567 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]58e32bb2013-01-21 18:23:251568 TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_DNS_TIMES);
1569 if (i == 0) {
1570 first_socket_log_id = load_timing_info.socket_log_id;
1571 } else {
1572 // The second request should be using a new socket.
1573 EXPECT_NE(first_socket_log_id, load_timing_info.socket_log_id);
1574 }
1575
bnc691fda62016-08-12 00:43:161576 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:521577 ASSERT_TRUE(response);
initial.commit586acc5fe2008-07-26 22:42:521578
wezca1070932016-05-26 20:30:521579 EXPECT_TRUE(response->headers);
tbansal2ecbbc72016-10-06 17:15:471580 EXPECT_TRUE(response->proxy_server.is_direct());
[email protected]3d2a59b2008-09-26 19:44:251581 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
initial.commit586acc5fe2008-07-26 22:42:521582
1583 std::string response_data;
bnc691fda62016-08-12 00:43:161584 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:011585 EXPECT_THAT(rv, IsOk());
[email protected]3d2a59b2008-09-26 19:44:251586 EXPECT_EQ(kExpectedResponseData[i], response_data);
initial.commit586acc5fe2008-07-26 22:42:521587 }
1588}
[email protected]3d2a59b2008-09-26 19:44:251589
[email protected]a34f61ee2014-03-18 20:59:491590void HttpNetworkTransactionTest::PreconnectErrorResendRequestTest(
1591 const MockWrite* write_failure,
[email protected]09356c652014-03-25 15:36:101592 const MockRead* read_failure,
1593 bool use_spdy) {
[email protected]a34f61ee2014-03-18 20:59:491594 HttpRequestInfo request;
1595 request.method = "GET";
[email protected]09356c652014-03-25 15:36:101596 request.url = GURL("https://www.foo.com/");
[email protected]a34f61ee2014-03-18 20:59:491597
vishal.b62985ca92015-04-17 08:45:511598 TestNetLog net_log;
[email protected]a34f61ee2014-03-18 20:59:491599 session_deps_.net_log = &net_log;
danakj1fd259a02016-04-16 03:17:091600 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]a34f61ee2014-03-18 20:59:491601
[email protected]09356c652014-03-25 15:36:101602 SSLSocketDataProvider ssl1(ASYNC, OK);
1603 SSLSocketDataProvider ssl2(ASYNC, OK);
1604 if (use_spdy) {
bnc3cf2a592016-08-11 14:48:361605 ssl1.next_proto = kProtoHTTP2;
1606 ssl2.next_proto = kProtoHTTP2;
[email protected]09356c652014-03-25 15:36:101607 }
1608 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl1);
1609 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
[email protected]a34f61ee2014-03-18 20:59:491610
[email protected]09356c652014-03-25 15:36:101611 // SPDY versions of the request and response.
bncdf80d44fd2016-07-15 20:27:411612 SpdySerializedFrame spdy_request(spdy_util_.ConstructSpdyGet(
bnc38dcd392016-02-09 23:19:491613 request.url.spec().c_str(), 1, DEFAULT_PRIORITY));
bncdf80d44fd2016-07-15 20:27:411614 SpdySerializedFrame spdy_response(
bnc42331402016-07-25 13:36:151615 spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
bncdf80d44fd2016-07-15 20:27:411616 SpdySerializedFrame spdy_data(
1617 spdy_util_.ConstructSpdyDataFrame(1, "hello", 5, true));
[email protected]a34f61ee2014-03-18 20:59:491618
[email protected]09356c652014-03-25 15:36:101619 // HTTP/1.1 versions of the request and response.
1620 const char kHttpRequest[] = "GET / HTTP/1.1\r\n"
1621 "Host: www.foo.com\r\n"
1622 "Connection: keep-alive\r\n\r\n";
1623 const char kHttpResponse[] = "HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n";
1624 const char kHttpData[] = "hello";
1625
1626 std::vector<MockRead> data1_reads;
1627 std::vector<MockWrite> data1_writes;
[email protected]a34f61ee2014-03-18 20:59:491628 if (write_failure) {
1629 ASSERT_FALSE(read_failure);
[email protected]09356c652014-03-25 15:36:101630 data1_writes.push_back(*write_failure);
1631 data1_reads.push_back(MockRead(ASYNC, OK));
[email protected]a34f61ee2014-03-18 20:59:491632 } else {
1633 ASSERT_TRUE(read_failure);
[email protected]09356c652014-03-25 15:36:101634 if (use_spdy) {
bncdf80d44fd2016-07-15 20:27:411635 data1_writes.push_back(CreateMockWrite(spdy_request));
[email protected]09356c652014-03-25 15:36:101636 } else {
1637 data1_writes.push_back(MockWrite(kHttpRequest));
1638 }
1639 data1_reads.push_back(*read_failure);
[email protected]a34f61ee2014-03-18 20:59:491640 }
1641
[email protected]09356c652014-03-25 15:36:101642 StaticSocketDataProvider data1(&data1_reads[0], data1_reads.size(),
1643 &data1_writes[0], data1_writes.size());
[email protected]a34f61ee2014-03-18 20:59:491644 session_deps_.socket_factory->AddSocketDataProvider(&data1);
1645
[email protected]09356c652014-03-25 15:36:101646 std::vector<MockRead> data2_reads;
1647 std::vector<MockWrite> data2_writes;
1648
1649 if (use_spdy) {
bncdf80d44fd2016-07-15 20:27:411650 data2_writes.push_back(CreateMockWrite(spdy_request, 0, ASYNC));
[email protected]09356c652014-03-25 15:36:101651
bncdf80d44fd2016-07-15 20:27:411652 data2_reads.push_back(CreateMockRead(spdy_response, 1, ASYNC));
1653 data2_reads.push_back(CreateMockRead(spdy_data, 2, ASYNC));
[email protected]09356c652014-03-25 15:36:101654 data2_reads.push_back(MockRead(ASYNC, OK, 3));
1655 } else {
1656 data2_writes.push_back(
1657 MockWrite(ASYNC, kHttpRequest, strlen(kHttpRequest), 0));
1658
1659 data2_reads.push_back(
1660 MockRead(ASYNC, kHttpResponse, strlen(kHttpResponse), 1));
1661 data2_reads.push_back(MockRead(ASYNC, kHttpData, strlen(kHttpData), 2));
1662 data2_reads.push_back(MockRead(ASYNC, OK, 3));
1663 }
rch8e6c6c42015-05-01 14:05:131664 SequencedSocketData data2(&data2_reads[0], data2_reads.size(),
1665 &data2_writes[0], data2_writes.size());
[email protected]a34f61ee2014-03-18 20:59:491666 session_deps_.socket_factory->AddSocketDataProvider(&data2);
1667
1668 // Preconnect a socket.
nharper8cdb0fb2016-04-22 21:34:591669 session->http_stream_factory()->PreconnectStreams(1, request);
[email protected]a34f61ee2014-03-18 20:59:491670 // Wait for the preconnect to complete.
1671 // TODO(davidben): Some way to wait for an idle socket count might be handy.
1672 base::RunLoop().RunUntilIdle();
[email protected]09356c652014-03-25 15:36:101673 EXPECT_EQ(1, GetIdleSocketCountInSSLSocketPool(session.get()));
[email protected]a34f61ee2014-03-18 20:59:491674
1675 // Make the request.
1676 TestCompletionCallback callback;
1677
bnc691fda62016-08-12 00:43:161678 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]a34f61ee2014-03-18 20:59:491679
tfarina42834112016-09-22 13:38:201680 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:011681 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]a34f61ee2014-03-18 20:59:491682
1683 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:011684 EXPECT_THAT(rv, IsOk());
[email protected]a34f61ee2014-03-18 20:59:491685
1686 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:161687 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]09356c652014-03-25 15:36:101688 TestLoadTimingNotReused(
1689 load_timing_info,
1690 CONNECT_TIMING_HAS_DNS_TIMES|CONNECT_TIMING_HAS_SSL_TIMES);
[email protected]a34f61ee2014-03-18 20:59:491691
bnc691fda62016-08-12 00:43:161692 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:521693 ASSERT_TRUE(response);
[email protected]a34f61ee2014-03-18 20:59:491694
wezca1070932016-05-26 20:30:521695 EXPECT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:021696 if (response->was_fetched_via_spdy) {
1697 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
1698 } else {
1699 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
1700 }
[email protected]a34f61ee2014-03-18 20:59:491701
1702 std::string response_data;
bnc691fda62016-08-12 00:43:161703 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:011704 EXPECT_THAT(rv, IsOk());
[email protected]09356c652014-03-25 15:36:101705 EXPECT_EQ(kHttpData, response_data);
[email protected]a34f61ee2014-03-18 20:59:491706}
1707
Biljith Jayan45a41722017-08-16 18:43:141708// Test that we do not retry indefinitely when a server sends an error like
1709// ERR_SPDY_PING_FAILED, ERR_SPDY_SERVER_REFUSED_STREAM,
1710// ERR_QUIC_HANDSHAKE_FAILED or ERR_QUIC_PROTOCOL_ERROR.
1711TEST_F(HttpNetworkTransactionTest, FiniteRetriesOnIOError) {
1712 HttpRequestInfo request;
1713 request.method = "GET";
1714 request.url = GURL("https://www.foo.com/");
1715
1716 // Check whether we give up after the third try.
1717
1718 // Construct an HTTP2 request and a "Go away" response.
1719 SpdySerializedFrame spdy_request(spdy_util_.ConstructSpdyGet(
1720 request.url.spec().c_str(), 1, DEFAULT_PRIORITY));
1721 SpdySerializedFrame spdy_response_go_away(spdy_util_.ConstructSpdyGoAway());
1722 MockRead data_read1 = CreateMockRead(spdy_response_go_away);
1723 MockWrite data_write = CreateMockWrite(spdy_request, 0);
1724
1725 // Three go away responses.
1726 StaticSocketDataProvider data1(&data_read1, 1, &data_write, 1);
1727 StaticSocketDataProvider data2(&data_read1, 1, &data_write, 1);
1728 StaticSocketDataProvider data3(&data_read1, 1, &data_write, 1);
1729
1730 session_deps_.socket_factory->AddSocketDataProvider(&data1);
1731 AddSSLSocketData();
1732 session_deps_.socket_factory->AddSocketDataProvider(&data2);
1733 AddSSLSocketData();
1734 session_deps_.socket_factory->AddSocketDataProvider(&data3);
1735 AddSSLSocketData();
1736
1737 TestCompletionCallback callback;
1738 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
1739 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
1740
1741 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
1742 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
1743
1744 rv = callback.WaitForResult();
1745 EXPECT_THAT(rv, IsError(ERR_SPDY_SERVER_REFUSED_STREAM));
1746}
1747
1748TEST_F(HttpNetworkTransactionTest, RetryTwiceOnIOError) {
1749 HttpRequestInfo request;
1750 request.method = "GET";
1751 request.url = GURL("https://www.foo.com/");
1752
1753 // Check whether we try atleast thrice before giving up.
1754
1755 // Construct an HTTP2 request and a "Go away" response.
1756 SpdySerializedFrame spdy_request(spdy_util_.ConstructSpdyGet(
1757 request.url.spec().c_str(), 1, DEFAULT_PRIORITY));
1758 SpdySerializedFrame spdy_response_go_away(spdy_util_.ConstructSpdyGoAway());
1759 MockRead data_read1 = CreateMockRead(spdy_response_go_away);
1760 MockWrite data_write = CreateMockWrite(spdy_request, 0);
1761
1762 // Construct a non error HTTP2 response.
1763 SpdySerializedFrame spdy_response_no_error(
1764 spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
1765 SpdySerializedFrame spdy_data(spdy_util_.ConstructSpdyDataFrame(1, true));
1766 MockRead data_read2[] = {CreateMockRead(spdy_response_no_error, 1),
1767 CreateMockRead(spdy_data, 2)};
1768
1769 // Two error responses.
1770 StaticSocketDataProvider data1(&data_read1, 1, &data_write, 1);
1771 StaticSocketDataProvider data2(&data_read1, 1, &data_write, 1);
1772 // Followed by a success response.
1773 SequencedSocketData data3(data_read2, 2, &data_write, 1);
1774
1775 session_deps_.socket_factory->AddSocketDataProvider(&data1);
1776 AddSSLSocketData();
1777 session_deps_.socket_factory->AddSocketDataProvider(&data2);
1778 AddSSLSocketData();
1779 session_deps_.socket_factory->AddSocketDataProvider(&data3);
1780 AddSSLSocketData();
1781
1782 TestCompletionCallback callback;
1783 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
1784 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
1785
1786 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
1787 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
1788
1789 rv = callback.WaitForResult();
1790 EXPECT_THAT(rv, IsOk());
1791}
1792
bncd16676a2016-07-20 16:23:011793TEST_F(HttpNetworkTransactionTest, KeepAliveConnectionNotConnectedOnWrite) {
[email protected]8ddf8322012-02-23 18:08:061794 MockWrite write_failure(ASYNC, ERR_SOCKET_NOT_CONNECTED);
[email protected]202965992011-12-07 23:04:511795 KeepAliveConnectionResendRequestTest(&write_failure, NULL);
1796}
1797
bncd16676a2016-07-20 16:23:011798TEST_F(HttpNetworkTransactionTest, KeepAliveConnectionReset) {
[email protected]8ddf8322012-02-23 18:08:061799 MockRead read_failure(ASYNC, ERR_CONNECTION_RESET);
[email protected]202965992011-12-07 23:04:511800 KeepAliveConnectionResendRequestTest(NULL, &read_failure);
[email protected]3d2a59b2008-09-26 19:44:251801}
1802
bncd16676a2016-07-20 16:23:011803TEST_F(HttpNetworkTransactionTest, KeepAliveConnectionEOF) {
[email protected]8ddf8322012-02-23 18:08:061804 MockRead read_failure(SYNCHRONOUS, OK); // EOF
[email protected]202965992011-12-07 23:04:511805 KeepAliveConnectionResendRequestTest(NULL, &read_failure);
[email protected]3d2a59b2008-09-26 19:44:251806}
1807
[email protected]d58ceea82014-06-04 10:55:541808// Make sure that on a 408 response (Request Timeout), the request is retried,
1809// if the socket was a reused keep alive socket.
bncd16676a2016-07-20 16:23:011810TEST_F(HttpNetworkTransactionTest, KeepAlive408) {
[email protected]d58ceea82014-06-04 10:55:541811 MockRead read_failure(SYNCHRONOUS,
1812 "HTTP/1.1 408 Request Timeout\r\n"
1813 "Connection: Keep-Alive\r\n"
1814 "Content-Length: 6\r\n\r\n"
1815 "Pickle");
1816 KeepAliveConnectionResendRequestTest(NULL, &read_failure);
1817}
1818
bncd16676a2016-07-20 16:23:011819TEST_F(HttpNetworkTransactionTest, PreconnectErrorNotConnectedOnWrite) {
[email protected]a34f61ee2014-03-18 20:59:491820 MockWrite write_failure(ASYNC, ERR_SOCKET_NOT_CONNECTED);
[email protected]09356c652014-03-25 15:36:101821 PreconnectErrorResendRequestTest(&write_failure, NULL, false);
[email protected]a34f61ee2014-03-18 20:59:491822}
1823
bncd16676a2016-07-20 16:23:011824TEST_F(HttpNetworkTransactionTest, PreconnectErrorReset) {
[email protected]a34f61ee2014-03-18 20:59:491825 MockRead read_failure(ASYNC, ERR_CONNECTION_RESET);
[email protected]09356c652014-03-25 15:36:101826 PreconnectErrorResendRequestTest(NULL, &read_failure, false);
[email protected]a34f61ee2014-03-18 20:59:491827}
1828
bncd16676a2016-07-20 16:23:011829TEST_F(HttpNetworkTransactionTest, PreconnectErrorEOF) {
[email protected]a34f61ee2014-03-18 20:59:491830 MockRead read_failure(SYNCHRONOUS, OK); // EOF
[email protected]09356c652014-03-25 15:36:101831 PreconnectErrorResendRequestTest(NULL, &read_failure, false);
1832}
1833
bncd16676a2016-07-20 16:23:011834TEST_F(HttpNetworkTransactionTest, PreconnectErrorAsyncEOF) {
[email protected]09356c652014-03-25 15:36:101835 MockRead read_failure(ASYNC, OK); // EOF
1836 PreconnectErrorResendRequestTest(NULL, &read_failure, false);
1837}
1838
[email protected]d58ceea82014-06-04 10:55:541839// Make sure that on a 408 response (Request Timeout), the request is retried,
1840// if the socket was a preconnected (UNUSED_IDLE) socket.
bncd16676a2016-07-20 16:23:011841TEST_F(HttpNetworkTransactionTest, RetryOnIdle408) {
[email protected]d58ceea82014-06-04 10:55:541842 MockRead read_failure(SYNCHRONOUS,
1843 "HTTP/1.1 408 Request Timeout\r\n"
1844 "Connection: Keep-Alive\r\n"
1845 "Content-Length: 6\r\n\r\n"
1846 "Pickle");
1847 KeepAliveConnectionResendRequestTest(NULL, &read_failure);
1848 PreconnectErrorResendRequestTest(NULL, &read_failure, false);
1849}
1850
bncd16676a2016-07-20 16:23:011851TEST_F(HttpNetworkTransactionTest, SpdyPreconnectErrorNotConnectedOnWrite) {
[email protected]09356c652014-03-25 15:36:101852 MockWrite write_failure(ASYNC, ERR_SOCKET_NOT_CONNECTED);
1853 PreconnectErrorResendRequestTest(&write_failure, NULL, true);
1854}
1855
bncd16676a2016-07-20 16:23:011856TEST_F(HttpNetworkTransactionTest, SpdyPreconnectErrorReset) {
[email protected]09356c652014-03-25 15:36:101857 MockRead read_failure(ASYNC, ERR_CONNECTION_RESET);
1858 PreconnectErrorResendRequestTest(NULL, &read_failure, true);
1859}
1860
bncd16676a2016-07-20 16:23:011861TEST_F(HttpNetworkTransactionTest, SpdyPreconnectErrorEOF) {
[email protected]09356c652014-03-25 15:36:101862 MockRead read_failure(SYNCHRONOUS, OK); // EOF
1863 PreconnectErrorResendRequestTest(NULL, &read_failure, true);
1864}
1865
bncd16676a2016-07-20 16:23:011866TEST_F(HttpNetworkTransactionTest, SpdyPreconnectErrorAsyncEOF) {
[email protected]09356c652014-03-25 15:36:101867 MockRead read_failure(ASYNC, OK); // EOF
1868 PreconnectErrorResendRequestTest(NULL, &read_failure, true);
[email protected]a34f61ee2014-03-18 20:59:491869}
1870
bncd16676a2016-07-20 16:23:011871TEST_F(HttpNetworkTransactionTest, NonKeepAliveConnectionReset) {
[email protected]1c773ea12009-04-28 19:58:421872 HttpRequestInfo request;
[email protected]3d2a59b2008-09-26 19:44:251873 request.method = "GET";
bncce36dca22015-04-21 22:11:231874 request.url = GURL("http://www.example.org/");
[email protected]3d2a59b2008-09-26 19:44:251875
danakj1fd259a02016-04-16 03:17:091876 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:161877 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:271878
[email protected]3d2a59b2008-09-26 19:44:251879 MockRead data_reads[] = {
[email protected]8ddf8322012-02-23 18:08:061880 MockRead(ASYNC, ERR_CONNECTION_RESET),
[email protected]217e6022008-09-29 18:18:351881 MockRead("HTTP/1.0 200 OK\r\n\r\n"), // Should not be used
1882 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:061883 MockRead(SYNCHRONOUS, OK),
[email protected]3d2a59b2008-09-26 19:44:251884 };
[email protected]31a2bfe2010-02-09 08:03:391885 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:071886 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]3d2a59b2008-09-26 19:44:251887
[email protected]49639fa2011-12-20 23:22:411888 TestCompletionCallback callback;
[email protected]3d2a59b2008-09-26 19:44:251889
tfarina42834112016-09-22 13:38:201890 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:011891 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]3d2a59b2008-09-26 19:44:251892
1893 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:011894 EXPECT_THAT(rv, IsError(ERR_CONNECTION_RESET));
ttuttled9dbc652015-09-29 20:00:591895
1896 IPEndPoint endpoint;
bnc691fda62016-08-12 00:43:161897 EXPECT_TRUE(trans.GetRemoteEndpoint(&endpoint));
ttuttled9dbc652015-09-29 20:00:591898 EXPECT_LT(0u, endpoint.address().size());
[email protected]3d2a59b2008-09-26 19:44:251899}
1900
1901// What do various browsers do when the server closes a non-keepalive
1902// connection without sending any response header or body?
1903//
1904// IE7: error page
1905// Safari 3.1.2 (Windows): error page
1906// Firefox 3.0.1: blank page
1907// Opera 9.52: after five attempts, blank page
[email protected]1c773ea12009-04-28 19:58:421908// Us with WinHTTP: error page (ERR_INVALID_RESPONSE)
1909// Us: error page (EMPTY_RESPONSE)
bncd16676a2016-07-20 16:23:011910TEST_F(HttpNetworkTransactionTest, NonKeepAliveConnectionEOF) {
[email protected]3d2a59b2008-09-26 19:44:251911 MockRead data_reads[] = {
[email protected]8ddf8322012-02-23 18:08:061912 MockRead(SYNCHRONOUS, OK), // EOF
[email protected]217e6022008-09-29 18:18:351913 MockRead("HTTP/1.0 200 OK\r\n\r\n"), // Should not be used
1914 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:061915 MockRead(SYNCHRONOUS, OK),
[email protected]3d2a59b2008-09-26 19:44:251916 };
[email protected]31a2bfe2010-02-09 08:03:391917 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
1918 arraysize(data_reads));
robpercival214763f2016-07-01 23:27:011919 EXPECT_THAT(out.rv, IsError(ERR_EMPTY_RESPONSE));
[email protected]3d2a59b2008-09-26 19:44:251920}
[email protected]1826a402014-01-08 15:40:481921
[email protected]7a5378b2012-11-04 03:25:171922// Next 2 cases (KeepAliveEarlyClose and KeepAliveEarlyClose2) are regression
1923// tests. There was a bug causing HttpNetworkTransaction to hang in the
1924// destructor in such situations.
1925// See http://crbug.com/154712 and http://crbug.com/156609.
bncd16676a2016-07-20 16:23:011926TEST_F(HttpNetworkTransactionTest, KeepAliveEarlyClose) {
[email protected]7a5378b2012-11-04 03:25:171927 HttpRequestInfo request;
1928 request.method = "GET";
bncce36dca22015-04-21 22:11:231929 request.url = GURL("http://www.example.org/");
[email protected]7a5378b2012-11-04 03:25:171930
danakj1fd259a02016-04-16 03:17:091931 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc87dcefc2017-05-25 12:47:581932 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:191933 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]7a5378b2012-11-04 03:25:171934
1935 MockRead data_reads[] = {
1936 MockRead("HTTP/1.0 200 OK\r\n"),
1937 MockRead("Connection: keep-alive\r\n"),
1938 MockRead("Content-Length: 100\r\n\r\n"),
1939 MockRead("hello"),
1940 MockRead(SYNCHRONOUS, 0),
1941 };
1942 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:071943 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]7a5378b2012-11-04 03:25:171944
1945 TestCompletionCallback callback;
1946
tfarina42834112016-09-22 13:38:201947 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:011948 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]7a5378b2012-11-04 03:25:171949
1950 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:011951 EXPECT_THAT(rv, IsOk());
[email protected]7a5378b2012-11-04 03:25:171952
1953 scoped_refptr<IOBufferWithSize> io_buf(new IOBufferWithSize(100));
[email protected]90499482013-06-01 00:39:501954 rv = trans->Read(io_buf.get(), io_buf->size(), callback.callback());
[email protected]7a5378b2012-11-04 03:25:171955 if (rv == ERR_IO_PENDING)
1956 rv = callback.WaitForResult();
1957 EXPECT_EQ(5, rv);
[email protected]90499482013-06-01 00:39:501958 rv = trans->Read(io_buf.get(), io_buf->size(), callback.callback());
robpercival214763f2016-07-01 23:27:011959 EXPECT_THAT(rv, IsError(ERR_CONTENT_LENGTH_MISMATCH));
[email protected]7a5378b2012-11-04 03:25:171960
1961 trans.reset();
fdoray92e35a72016-06-10 15:54:551962 base::RunLoop().RunUntilIdle();
[email protected]7a5378b2012-11-04 03:25:171963 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
1964}
1965
bncd16676a2016-07-20 16:23:011966TEST_F(HttpNetworkTransactionTest, KeepAliveEarlyClose2) {
[email protected]7a5378b2012-11-04 03:25:171967 HttpRequestInfo request;
1968 request.method = "GET";
bncce36dca22015-04-21 22:11:231969 request.url = GURL("http://www.example.org/");
[email protected]7a5378b2012-11-04 03:25:171970
danakj1fd259a02016-04-16 03:17:091971 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc87dcefc2017-05-25 12:47:581972 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:191973 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]7a5378b2012-11-04 03:25:171974
1975 MockRead data_reads[] = {
1976 MockRead("HTTP/1.0 200 OK\r\n"),
1977 MockRead("Connection: keep-alive\r\n"),
1978 MockRead("Content-Length: 100\r\n\r\n"),
1979 MockRead(SYNCHRONOUS, 0),
1980 };
1981 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:071982 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]7a5378b2012-11-04 03:25:171983
1984 TestCompletionCallback callback;
1985
tfarina42834112016-09-22 13:38:201986 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:011987 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]7a5378b2012-11-04 03:25:171988
1989 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:011990 EXPECT_THAT(rv, IsOk());
[email protected]7a5378b2012-11-04 03:25:171991
1992 scoped_refptr<IOBufferWithSize> io_buf(new IOBufferWithSize(100));
[email protected]90499482013-06-01 00:39:501993 rv = trans->Read(io_buf.get(), io_buf->size(), callback.callback());
[email protected]7a5378b2012-11-04 03:25:171994 if (rv == ERR_IO_PENDING)
1995 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:011996 EXPECT_THAT(rv, IsError(ERR_CONTENT_LENGTH_MISMATCH));
[email protected]7a5378b2012-11-04 03:25:171997
1998 trans.reset();
fdoray92e35a72016-06-10 15:54:551999 base::RunLoop().RunUntilIdle();
[email protected]7a5378b2012-11-04 03:25:172000 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
2001}
2002
[email protected]0b0bf032010-09-21 18:08:502003// Test that we correctly reuse a keep-alive connection after not explicitly
2004// reading the body.
bncd16676a2016-07-20 16:23:012005TEST_F(HttpNetworkTransactionTest, KeepAliveAfterUnreadBody) {
[email protected]fc31d6a42010-06-24 18:05:132006 HttpRequestInfo request;
2007 request.method = "GET";
2008 request.url = GURL("http://www.foo.com/");
[email protected]fc31d6a42010-06-24 18:05:132009
vishal.b62985ca92015-04-17 08:45:512010 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:072011 session_deps_.net_log = &net_log;
danakj1fd259a02016-04-16 03:17:092012 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:272013
mmenkecc2298e2015-12-07 18:20:182014 const char* request_data =
2015 "GET / HTTP/1.1\r\n"
2016 "Host: www.foo.com\r\n"
2017 "Connection: keep-alive\r\n\r\n";
2018 MockWrite data_writes[] = {
2019 MockWrite(ASYNC, 0, request_data), MockWrite(ASYNC, 2, request_data),
2020 MockWrite(ASYNC, 4, request_data), MockWrite(ASYNC, 6, request_data),
2021 MockWrite(ASYNC, 8, request_data), MockWrite(ASYNC, 10, request_data),
2022 MockWrite(ASYNC, 12, request_data), MockWrite(ASYNC, 14, request_data),
2023 MockWrite(ASYNC, 17, request_data), MockWrite(ASYNC, 20, request_data),
2024 };
2025
[email protected]0b0bf032010-09-21 18:08:502026 // Note that because all these reads happen in the same
2027 // StaticSocketDataProvider, it shows that the same socket is being reused for
2028 // all transactions.
mmenkecc2298e2015-12-07 18:20:182029 MockRead data_reads[] = {
2030 MockRead(ASYNC, 1, "HTTP/1.1 204 No Content\r\n\r\n"),
2031 MockRead(ASYNC, 3, "HTTP/1.1 205 Reset Content\r\n\r\n"),
2032 MockRead(ASYNC, 5, "HTTP/1.1 304 Not Modified\r\n\r\n"),
2033 MockRead(ASYNC, 7,
2034 "HTTP/1.1 302 Found\r\n"
2035 "Content-Length: 0\r\n\r\n"),
2036 MockRead(ASYNC, 9,
2037 "HTTP/1.1 302 Found\r\n"
2038 "Content-Length: 5\r\n\r\n"
2039 "hello"),
2040 MockRead(ASYNC, 11,
2041 "HTTP/1.1 301 Moved Permanently\r\n"
2042 "Content-Length: 0\r\n\r\n"),
2043 MockRead(ASYNC, 13,
2044 "HTTP/1.1 301 Moved Permanently\r\n"
2045 "Content-Length: 5\r\n\r\n"
2046 "hello"),
[email protected]fc31d6a42010-06-24 18:05:132047
mmenkecc2298e2015-12-07 18:20:182048 // In the next two rounds, IsConnectedAndIdle returns false, due to
2049 // the set_busy_before_sync_reads(true) call, while the
2050 // HttpNetworkTransaction is being shut down, but the socket is still
2051 // reuseable. See http://crbug.com/544255.
2052 MockRead(ASYNC, 15,
2053 "HTTP/1.1 200 Hunky-Dory\r\n"
2054 "Content-Length: 5\r\n\r\n"),
2055 MockRead(SYNCHRONOUS, 16, "hello"),
[email protected]fc31d6a42010-06-24 18:05:132056
mmenkecc2298e2015-12-07 18:20:182057 MockRead(ASYNC, 18,
2058 "HTTP/1.1 200 Hunky-Dory\r\n"
2059 "Content-Length: 5\r\n\r\n"
2060 "he"),
2061 MockRead(SYNCHRONOUS, 19, "llo"),
2062
2063 // The body of the final request is actually read.
2064 MockRead(ASYNC, 21, "HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
2065 MockRead(ASYNC, 22, "hello"),
2066 };
2067 SequencedSocketData data(data_reads, arraysize(data_reads), data_writes,
2068 arraysize(data_writes));
2069 data.set_busy_before_sync_reads(true);
2070 session_deps_.socket_factory->AddSocketDataProvider(&data);
2071
2072 const int kNumUnreadBodies = arraysize(data_writes) - 1;
[email protected]0b0bf032010-09-21 18:08:502073 std::string response_lines[kNumUnreadBodies];
2074
mikecironef22f9812016-10-04 03:40:192075 uint32_t first_socket_log_id = NetLogSource::kInvalidId;
mmenkecc2298e2015-12-07 18:20:182076 for (size_t i = 0; i < kNumUnreadBodies; ++i) {
[email protected]49639fa2011-12-20 23:22:412077 TestCompletionCallback callback;
[email protected]fc31d6a42010-06-24 18:05:132078
Jeremy Roman0579ed62017-08-29 15:56:192079 auto trans = std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY,
bnc87dcefc2017-05-25 12:47:582080 session.get());
[email protected]fc31d6a42010-06-24 18:05:132081
tfarina42834112016-09-22 13:38:202082 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012083 EXPECT_THAT(callback.GetResult(rv), IsOk());
[email protected]fc31d6a42010-06-24 18:05:132084
[email protected]58e32bb2013-01-21 18:23:252085 LoadTimingInfo load_timing_info;
2086 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
2087 if (i == 0) {
2088 TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_DNS_TIMES);
2089 first_socket_log_id = load_timing_info.socket_log_id;
2090 } else {
2091 TestLoadTimingReused(load_timing_info);
2092 EXPECT_EQ(first_socket_log_id, load_timing_info.socket_log_id);
2093 }
2094
[email protected]fc31d6a42010-06-24 18:05:132095 const HttpResponseInfo* response = trans->GetResponseInfo();
mmenkecc2298e2015-12-07 18:20:182096 ASSERT_TRUE(response);
[email protected]fc31d6a42010-06-24 18:05:132097
mmenkecc2298e2015-12-07 18:20:182098 ASSERT_TRUE(response->headers);
[email protected]0b0bf032010-09-21 18:08:502099 response_lines[i] = response->headers->GetStatusLine();
2100
mmenkecc2298e2015-12-07 18:20:182101 // Delete the transaction without reading the response bodies. Then spin
2102 // the message loop, so the response bodies are drained.
2103 trans.reset();
2104 base::RunLoop().RunUntilIdle();
[email protected]fc31d6a42010-06-24 18:05:132105 }
[email protected]0b0bf032010-09-21 18:08:502106
2107 const char* const kStatusLines[] = {
mmenkecc2298e2015-12-07 18:20:182108 "HTTP/1.1 204 No Content",
2109 "HTTP/1.1 205 Reset Content",
2110 "HTTP/1.1 304 Not Modified",
2111 "HTTP/1.1 302 Found",
2112 "HTTP/1.1 302 Found",
2113 "HTTP/1.1 301 Moved Permanently",
2114 "HTTP/1.1 301 Moved Permanently",
2115 "HTTP/1.1 200 Hunky-Dory",
2116 "HTTP/1.1 200 Hunky-Dory",
[email protected]0b0bf032010-09-21 18:08:502117 };
2118
mostynb91e0da982015-01-20 19:17:272119 static_assert(kNumUnreadBodies == arraysize(kStatusLines),
2120 "forgot to update kStatusLines");
[email protected]0b0bf032010-09-21 18:08:502121
2122 for (int i = 0; i < kNumUnreadBodies; ++i)
2123 EXPECT_EQ(kStatusLines[i], response_lines[i]);
2124
[email protected]49639fa2011-12-20 23:22:412125 TestCompletionCallback callback;
bnc691fda62016-08-12 00:43:162126 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:202127 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012128 EXPECT_THAT(callback.GetResult(rv), IsOk());
bnc691fda62016-08-12 00:43:162129 const HttpResponseInfo* response = trans.GetResponseInfo();
mmenkecc2298e2015-12-07 18:20:182130 ASSERT_TRUE(response);
2131 ASSERT_TRUE(response->headers);
[email protected]0b0bf032010-09-21 18:08:502132 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
2133 std::string response_data;
bnc691fda62016-08-12 00:43:162134 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:012135 EXPECT_THAT(rv, IsOk());
[email protected]0b0bf032010-09-21 18:08:502136 EXPECT_EQ("hello", response_data);
[email protected]fc31d6a42010-06-24 18:05:132137}
2138
mmenke5f94fda2016-06-02 20:54:132139// Sockets that receive extra data after a response is complete should not be
2140// reused.
bncd16676a2016-07-20 16:23:012141TEST_F(HttpNetworkTransactionTest, KeepAliveWithUnusedData1) {
mmenke5f94fda2016-06-02 20:54:132142 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
2143 MockWrite data_writes1[] = {
2144 MockWrite("HEAD / HTTP/1.1\r\n"
2145 "Host: www.borked.com\r\n"
2146 "Connection: keep-alive\r\n\r\n"),
2147 };
2148
2149 MockRead data_reads1[] = {
2150 MockRead("HTTP/1.1 200 OK\r\n"
2151 "Connection: keep-alive\r\n"
2152 "Content-Length: 22\r\n\r\n"
2153 "This server is borked."),
2154 };
2155
2156 MockWrite data_writes2[] = {
2157 MockWrite("GET /foo HTTP/1.1\r\n"
2158 "Host: www.borked.com\r\n"
2159 "Connection: keep-alive\r\n\r\n"),
2160 };
2161
2162 MockRead data_reads2[] = {
2163 MockRead("HTTP/1.1 200 OK\r\n"
2164 "Content-Length: 3\r\n\r\n"
2165 "foo"),
2166 };
2167 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
2168 data_writes1, arraysize(data_writes1));
2169 session_deps_.socket_factory->AddSocketDataProvider(&data1);
2170 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
2171 data_writes2, arraysize(data_writes2));
2172 session_deps_.socket_factory->AddSocketDataProvider(&data2);
2173
2174 TestCompletionCallback callback;
2175 HttpRequestInfo request1;
2176 request1.method = "HEAD";
2177 request1.url = GURL("http://www.borked.com/");
2178
bnc87dcefc2017-05-25 12:47:582179 auto trans1 =
Jeremy Roman0579ed62017-08-29 15:56:192180 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:202181 int rv = trans1->Start(&request1, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012182 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenke5f94fda2016-06-02 20:54:132183
2184 const HttpResponseInfo* response1 = trans1->GetResponseInfo();
2185 ASSERT_TRUE(response1);
2186 ASSERT_TRUE(response1->headers);
2187 EXPECT_EQ(200, response1->headers->response_code());
2188 EXPECT_TRUE(response1->headers->IsKeepAlive());
2189
2190 std::string response_data1;
robpercival214763f2016-07-01 23:27:012191 EXPECT_THAT(ReadTransaction(trans1.get(), &response_data1), IsOk());
mmenke5f94fda2016-06-02 20:54:132192 EXPECT_EQ("", response_data1);
2193 // Deleting the transaction attempts to release the socket back into the
2194 // socket pool.
2195 trans1.reset();
2196
2197 HttpRequestInfo request2;
2198 request2.method = "GET";
2199 request2.url = GURL("http://www.borked.com/foo");
2200
bnc87dcefc2017-05-25 12:47:582201 auto trans2 =
Jeremy Roman0579ed62017-08-29 15:56:192202 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:202203 rv = trans2->Start(&request2, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012204 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenke5f94fda2016-06-02 20:54:132205
2206 const HttpResponseInfo* response2 = trans2->GetResponseInfo();
2207 ASSERT_TRUE(response2);
2208 ASSERT_TRUE(response2->headers);
2209 EXPECT_EQ(200, response2->headers->response_code());
2210
2211 std::string response_data2;
robpercival214763f2016-07-01 23:27:012212 EXPECT_THAT(ReadTransaction(trans2.get(), &response_data2), IsOk());
mmenke5f94fda2016-06-02 20:54:132213 EXPECT_EQ("foo", response_data2);
2214}
2215
bncd16676a2016-07-20 16:23:012216TEST_F(HttpNetworkTransactionTest, KeepAliveWithUnusedData2) {
mmenke5f94fda2016-06-02 20:54:132217 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
2218 MockWrite data_writes1[] = {
2219 MockWrite("GET / HTTP/1.1\r\n"
2220 "Host: www.borked.com\r\n"
2221 "Connection: keep-alive\r\n\r\n"),
2222 };
2223
2224 MockRead data_reads1[] = {
2225 MockRead("HTTP/1.1 200 OK\r\n"
2226 "Connection: keep-alive\r\n"
2227 "Content-Length: 22\r\n\r\n"
2228 "This server is borked."
2229 "Bonus data!"),
2230 };
2231
2232 MockWrite data_writes2[] = {
2233 MockWrite("GET /foo HTTP/1.1\r\n"
2234 "Host: www.borked.com\r\n"
2235 "Connection: keep-alive\r\n\r\n"),
2236 };
2237
2238 MockRead data_reads2[] = {
2239 MockRead("HTTP/1.1 200 OK\r\n"
2240 "Content-Length: 3\r\n\r\n"
2241 "foo"),
2242 };
2243 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
2244 data_writes1, arraysize(data_writes1));
2245 session_deps_.socket_factory->AddSocketDataProvider(&data1);
2246 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
2247 data_writes2, arraysize(data_writes2));
2248 session_deps_.socket_factory->AddSocketDataProvider(&data2);
2249
2250 TestCompletionCallback callback;
2251 HttpRequestInfo request1;
2252 request1.method = "GET";
2253 request1.url = GURL("http://www.borked.com/");
2254
bnc87dcefc2017-05-25 12:47:582255 auto trans1 =
Jeremy Roman0579ed62017-08-29 15:56:192256 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:202257 int rv = trans1->Start(&request1, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012258 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenke5f94fda2016-06-02 20:54:132259
2260 const HttpResponseInfo* response1 = trans1->GetResponseInfo();
2261 ASSERT_TRUE(response1);
2262 ASSERT_TRUE(response1->headers);
2263 EXPECT_EQ(200, response1->headers->response_code());
2264 EXPECT_TRUE(response1->headers->IsKeepAlive());
2265
2266 std::string response_data1;
robpercival214763f2016-07-01 23:27:012267 EXPECT_THAT(ReadTransaction(trans1.get(), &response_data1), IsOk());
mmenke5f94fda2016-06-02 20:54:132268 EXPECT_EQ("This server is borked.", response_data1);
2269 // Deleting the transaction attempts to release the socket back into the
2270 // socket pool.
2271 trans1.reset();
2272
2273 HttpRequestInfo request2;
2274 request2.method = "GET";
2275 request2.url = GURL("http://www.borked.com/foo");
2276
bnc87dcefc2017-05-25 12:47:582277 auto trans2 =
Jeremy Roman0579ed62017-08-29 15:56:192278 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:202279 rv = trans2->Start(&request2, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012280 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenke5f94fda2016-06-02 20:54:132281
2282 const HttpResponseInfo* response2 = trans2->GetResponseInfo();
2283 ASSERT_TRUE(response2);
2284 ASSERT_TRUE(response2->headers);
2285 EXPECT_EQ(200, response2->headers->response_code());
2286
2287 std::string response_data2;
robpercival214763f2016-07-01 23:27:012288 EXPECT_THAT(ReadTransaction(trans2.get(), &response_data2), IsOk());
mmenke5f94fda2016-06-02 20:54:132289 EXPECT_EQ("foo", response_data2);
2290}
2291
bncd16676a2016-07-20 16:23:012292TEST_F(HttpNetworkTransactionTest, KeepAliveWithUnusedData3) {
mmenke5f94fda2016-06-02 20:54:132293 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
2294 MockWrite data_writes1[] = {
2295 MockWrite("GET / HTTP/1.1\r\n"
2296 "Host: www.borked.com\r\n"
2297 "Connection: keep-alive\r\n\r\n"),
2298 };
2299
2300 MockRead data_reads1[] = {
2301 MockRead("HTTP/1.1 200 OK\r\n"
2302 "Connection: keep-alive\r\n"
2303 "Transfer-Encoding: chunked\r\n\r\n"),
2304 MockRead("16\r\nThis server is borked.\r\n"),
2305 MockRead("0\r\n\r\nBonus data!"),
2306 };
2307
2308 MockWrite data_writes2[] = {
2309 MockWrite("GET /foo HTTP/1.1\r\n"
2310 "Host: www.borked.com\r\n"
2311 "Connection: keep-alive\r\n\r\n"),
2312 };
2313
2314 MockRead data_reads2[] = {
2315 MockRead("HTTP/1.1 200 OK\r\n"
2316 "Content-Length: 3\r\n\r\n"
2317 "foo"),
2318 };
2319 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
2320 data_writes1, arraysize(data_writes1));
2321 session_deps_.socket_factory->AddSocketDataProvider(&data1);
2322 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
2323 data_writes2, arraysize(data_writes2));
2324 session_deps_.socket_factory->AddSocketDataProvider(&data2);
2325
2326 TestCompletionCallback callback;
2327 HttpRequestInfo request1;
2328 request1.method = "GET";
2329 request1.url = GURL("http://www.borked.com/");
2330
bnc87dcefc2017-05-25 12:47:582331 auto trans1 =
Jeremy Roman0579ed62017-08-29 15:56:192332 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:202333 int rv = trans1->Start(&request1, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012334 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenke5f94fda2016-06-02 20:54:132335
2336 const HttpResponseInfo* response1 = trans1->GetResponseInfo();
2337 ASSERT_TRUE(response1);
2338 ASSERT_TRUE(response1->headers);
2339 EXPECT_EQ(200, response1->headers->response_code());
2340 EXPECT_TRUE(response1->headers->IsKeepAlive());
2341
2342 std::string response_data1;
robpercival214763f2016-07-01 23:27:012343 EXPECT_THAT(ReadTransaction(trans1.get(), &response_data1), IsOk());
mmenke5f94fda2016-06-02 20:54:132344 EXPECT_EQ("This server is borked.", response_data1);
2345 // Deleting the transaction attempts to release the socket back into the
2346 // socket pool.
2347 trans1.reset();
2348
2349 HttpRequestInfo request2;
2350 request2.method = "GET";
2351 request2.url = GURL("http://www.borked.com/foo");
2352
bnc87dcefc2017-05-25 12:47:582353 auto trans2 =
Jeremy Roman0579ed62017-08-29 15:56:192354 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:202355 rv = trans2->Start(&request2, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012356 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenke5f94fda2016-06-02 20:54:132357
2358 const HttpResponseInfo* response2 = trans2->GetResponseInfo();
2359 ASSERT_TRUE(response2);
2360 ASSERT_TRUE(response2->headers);
2361 EXPECT_EQ(200, response2->headers->response_code());
2362
2363 std::string response_data2;
robpercival214763f2016-07-01 23:27:012364 EXPECT_THAT(ReadTransaction(trans2.get(), &response_data2), IsOk());
mmenke5f94fda2016-06-02 20:54:132365 EXPECT_EQ("foo", response_data2);
2366}
2367
2368// This is a little different from the others - it tests the case that the
2369// HttpStreamParser doesn't know if there's extra data on a socket or not when
2370// the HttpNetworkTransaction is torn down, because the response body hasn't
2371// been read from yet, but the request goes through the HttpResponseBodyDrainer.
bncd16676a2016-07-20 16:23:012372TEST_F(HttpNetworkTransactionTest, KeepAliveWithUnusedData4) {
mmenke5f94fda2016-06-02 20:54:132373 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
2374 MockWrite data_writes1[] = {
2375 MockWrite("GET / HTTP/1.1\r\n"
2376 "Host: www.borked.com\r\n"
2377 "Connection: keep-alive\r\n\r\n"),
2378 };
2379
2380 MockRead data_reads1[] = {
2381 MockRead("HTTP/1.1 200 OK\r\n"
2382 "Connection: keep-alive\r\n"
2383 "Transfer-Encoding: chunked\r\n\r\n"),
2384 MockRead("16\r\nThis server is borked.\r\n"),
2385 MockRead("0\r\n\r\nBonus data!"),
2386 };
2387 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
2388 data_writes1, arraysize(data_writes1));
2389 session_deps_.socket_factory->AddSocketDataProvider(&data1);
2390
2391 TestCompletionCallback callback;
2392 HttpRequestInfo request1;
2393 request1.method = "GET";
2394 request1.url = GURL("http://www.borked.com/");
2395
bnc87dcefc2017-05-25 12:47:582396 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:192397 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
bnc87dcefc2017-05-25 12:47:582398 int rv = trans->Start(&request1, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012399 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenke5f94fda2016-06-02 20:54:132400
bnc87dcefc2017-05-25 12:47:582401 const HttpResponseInfo* response1 = trans->GetResponseInfo();
mmenke5f94fda2016-06-02 20:54:132402 ASSERT_TRUE(response1);
2403 ASSERT_TRUE(response1->headers);
2404 EXPECT_EQ(200, response1->headers->response_code());
2405 EXPECT_TRUE(response1->headers->IsKeepAlive());
2406
2407 // Deleting the transaction creates an HttpResponseBodyDrainer to read the
2408 // response body.
bnc87dcefc2017-05-25 12:47:582409 trans.reset();
mmenke5f94fda2016-06-02 20:54:132410
2411 // Let the HttpResponseBodyDrainer drain the socket. It should determine the
2412 // socket can't be reused, rather than returning it to the socket pool.
2413 base::RunLoop().RunUntilIdle();
2414
2415 // There should be no idle sockets in the pool.
2416 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
2417}
2418
[email protected]038e9a32008-10-08 22:40:162419// Test the request-challenge-retry sequence for basic auth.
2420// (basic auth is the easiest to mock, because it has no randomness).
bncd16676a2016-07-20 16:23:012421TEST_F(HttpNetworkTransactionTest, BasicAuth) {
[email protected]1c773ea12009-04-28 19:58:422422 HttpRequestInfo request;
[email protected]038e9a32008-10-08 22:40:162423 request.method = "GET";
bncce36dca22015-04-21 22:11:232424 request.url = GURL("http://www.example.org/");
[email protected]038e9a32008-10-08 22:40:162425
vishal.b62985ca92015-04-17 08:45:512426 TestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:072427 session_deps_.net_log = &log;
danakj1fd259a02016-04-16 03:17:092428 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:162429 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:272430
[email protected]f9ee6b52008-11-08 06:46:232431 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:232432 MockWrite(
2433 "GET / HTTP/1.1\r\n"
2434 "Host: www.example.org\r\n"
2435 "Connection: keep-alive\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:232436 };
2437
[email protected]038e9a32008-10-08 22:40:162438 MockRead data_reads1[] = {
2439 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
2440 // Give a couple authenticate options (only the middle one is actually
2441 // supported).
[email protected]22927ad2009-09-21 19:56:192442 MockRead("WWW-Authenticate: Basic invalid\r\n"), // Malformed.
[email protected]038e9a32008-10-08 22:40:162443 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2444 MockRead("WWW-Authenticate: UNSUPPORTED realm=\"FOO\"\r\n"),
2445 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
2446 // Large content-length -- won't matter, as connection will be reset.
2447 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:062448 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]038e9a32008-10-08 22:40:162449 };
2450
2451 // After calling trans->RestartWithAuth(), this is the request we should
2452 // be issuing -- the final header line contains the credentials.
2453 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:232454 MockWrite(
2455 "GET / HTTP/1.1\r\n"
2456 "Host: www.example.org\r\n"
2457 "Connection: keep-alive\r\n"
2458 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]038e9a32008-10-08 22:40:162459 };
2460
2461 // Lastly, the server responds with the actual content.
2462 MockRead data_reads2[] = {
2463 MockRead("HTTP/1.0 200 OK\r\n"),
2464 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
2465 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:062466 MockRead(SYNCHRONOUS, OK),
[email protected]038e9a32008-10-08 22:40:162467 };
2468
[email protected]31a2bfe2010-02-09 08:03:392469 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
2470 data_writes1, arraysize(data_writes1));
2471 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
2472 data_writes2, arraysize(data_writes2));
[email protected]bb88e1d32013-05-03 23:11:072473 session_deps_.socket_factory->AddSocketDataProvider(&data1);
2474 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]038e9a32008-10-08 22:40:162475
[email protected]49639fa2011-12-20 23:22:412476 TestCompletionCallback callback1;
[email protected]038e9a32008-10-08 22:40:162477
tfarina42834112016-09-22 13:38:202478 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012479 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]038e9a32008-10-08 22:40:162480
2481 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:012482 EXPECT_THAT(rv, IsOk());
[email protected]038e9a32008-10-08 22:40:162483
[email protected]58e32bb2013-01-21 18:23:252484 LoadTimingInfo load_timing_info1;
bnc691fda62016-08-12 00:43:162485 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info1));
[email protected]58e32bb2013-01-21 18:23:252486 TestLoadTimingNotReused(load_timing_info1, CONNECT_TIMING_HAS_DNS_TIMES);
2487
sclittlefb249892015-09-10 21:33:222488 int64_t writes_size1 = CountWriteBytes(data_writes1, arraysize(data_writes1));
bnc691fda62016-08-12 00:43:162489 EXPECT_EQ(writes_size1, trans.GetTotalSentBytes());
sclittlefb249892015-09-10 21:33:222490 int64_t reads_size1 = CountReadBytes(data_reads1, arraysize(data_reads1));
bnc691fda62016-08-12 00:43:162491 EXPECT_EQ(reads_size1, trans.GetTotalReceivedBytes());
[email protected]b8015c42013-12-24 15:18:192492
bnc691fda62016-08-12 00:43:162493 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:522494 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:042495 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]038e9a32008-10-08 22:40:162496
[email protected]49639fa2011-12-20 23:22:412497 TestCompletionCallback callback2;
[email protected]038e9a32008-10-08 22:40:162498
bnc691fda62016-08-12 00:43:162499 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar), callback2.callback());
robpercival214763f2016-07-01 23:27:012500 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]038e9a32008-10-08 22:40:162501
2502 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:012503 EXPECT_THAT(rv, IsOk());
[email protected]038e9a32008-10-08 22:40:162504
[email protected]58e32bb2013-01-21 18:23:252505 LoadTimingInfo load_timing_info2;
bnc691fda62016-08-12 00:43:162506 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info2));
[email protected]58e32bb2013-01-21 18:23:252507 TestLoadTimingNotReused(load_timing_info2, CONNECT_TIMING_HAS_DNS_TIMES);
2508 // The load timing after restart should have a new socket ID, and times after
2509 // those of the first load timing.
2510 EXPECT_LE(load_timing_info1.receive_headers_end,
2511 load_timing_info2.connect_timing.connect_start);
2512 EXPECT_NE(load_timing_info1.socket_log_id, load_timing_info2.socket_log_id);
2513
sclittlefb249892015-09-10 21:33:222514 int64_t writes_size2 = CountWriteBytes(data_writes2, arraysize(data_writes2));
bnc691fda62016-08-12 00:43:162515 EXPECT_EQ(writes_size1 + writes_size2, trans.GetTotalSentBytes());
sclittlefb249892015-09-10 21:33:222516 int64_t reads_size2 = CountReadBytes(data_reads2, arraysize(data_reads2));
bnc691fda62016-08-12 00:43:162517 EXPECT_EQ(reads_size1 + reads_size2, trans.GetTotalReceivedBytes());
[email protected]b8015c42013-12-24 15:18:192518
bnc691fda62016-08-12 00:43:162519 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:522520 ASSERT_TRUE(response);
2521 EXPECT_FALSE(response->auth_challenge);
[email protected]038e9a32008-10-08 22:40:162522 EXPECT_EQ(100, response->headers->GetContentLength());
[email protected]038e9a32008-10-08 22:40:162523}
2524
ttuttled9dbc652015-09-29 20:00:592525// Test the request-challenge-retry sequence for basic auth.
2526// (basic auth is the easiest to mock, because it has no randomness).
bncd16676a2016-07-20 16:23:012527TEST_F(HttpNetworkTransactionTest, BasicAuthWithAddressChange) {
ttuttled9dbc652015-09-29 20:00:592528 HttpRequestInfo request;
2529 request.method = "GET";
2530 request.url = GURL("http://www.example.org/");
ttuttled9dbc652015-09-29 20:00:592531
2532 TestNetLog log;
2533 MockHostResolver* resolver = new MockHostResolver();
2534 session_deps_.net_log = &log;
2535 session_deps_.host_resolver.reset(resolver);
danakj1fd259a02016-04-16 03:17:092536 std::unique_ptr<HttpNetworkSession> session = CreateSession(&session_deps_);
bnc691fda62016-08-12 00:43:162537 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
ttuttled9dbc652015-09-29 20:00:592538
2539 resolver->rules()->ClearRules();
2540 resolver->rules()->AddRule("www.example.org", "127.0.0.1");
2541
2542 MockWrite data_writes1[] = {
2543 MockWrite("GET / HTTP/1.1\r\n"
2544 "Host: www.example.org\r\n"
2545 "Connection: keep-alive\r\n\r\n"),
2546 };
2547
2548 MockRead data_reads1[] = {
2549 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
2550 // Give a couple authenticate options (only the middle one is actually
2551 // supported).
2552 MockRead("WWW-Authenticate: Basic invalid\r\n"), // Malformed.
2553 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2554 MockRead("WWW-Authenticate: UNSUPPORTED realm=\"FOO\"\r\n"),
2555 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
2556 // Large content-length -- won't matter, as connection will be reset.
2557 MockRead("Content-Length: 10000\r\n\r\n"),
2558 MockRead(SYNCHRONOUS, ERR_FAILED),
2559 };
2560
2561 // After calling trans->RestartWithAuth(), this is the request we should
2562 // be issuing -- the final header line contains the credentials.
2563 MockWrite data_writes2[] = {
2564 MockWrite("GET / HTTP/1.1\r\n"
2565 "Host: www.example.org\r\n"
2566 "Connection: keep-alive\r\n"
2567 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
2568 };
2569
2570 // Lastly, the server responds with the actual content.
2571 MockRead data_reads2[] = {
2572 MockRead("HTTP/1.0 200 OK\r\n"),
2573 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
2574 MockRead("Content-Length: 100\r\n\r\n"), MockRead(SYNCHRONOUS, OK),
2575 };
2576
2577 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
2578 data_writes1, arraysize(data_writes1));
2579 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
2580 data_writes2, arraysize(data_writes2));
2581 session_deps_.socket_factory->AddSocketDataProvider(&data1);
2582 session_deps_.socket_factory->AddSocketDataProvider(&data2);
2583
2584 TestCompletionCallback callback1;
2585
bnc691fda62016-08-12 00:43:162586 EXPECT_EQ(OK, callback1.GetResult(trans.Start(&request, callback1.callback(),
tfarina42834112016-09-22 13:38:202587 NetLogWithSource())));
ttuttled9dbc652015-09-29 20:00:592588
2589 LoadTimingInfo load_timing_info1;
bnc691fda62016-08-12 00:43:162590 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info1));
ttuttled9dbc652015-09-29 20:00:592591 TestLoadTimingNotReused(load_timing_info1, CONNECT_TIMING_HAS_DNS_TIMES);
2592
2593 int64_t writes_size1 = CountWriteBytes(data_writes1, arraysize(data_writes1));
bnc691fda62016-08-12 00:43:162594 EXPECT_EQ(writes_size1, trans.GetTotalSentBytes());
ttuttled9dbc652015-09-29 20:00:592595 int64_t reads_size1 = CountReadBytes(data_reads1, arraysize(data_reads1));
bnc691fda62016-08-12 00:43:162596 EXPECT_EQ(reads_size1, trans.GetTotalReceivedBytes());
ttuttled9dbc652015-09-29 20:00:592597
bnc691fda62016-08-12 00:43:162598 const HttpResponseInfo* response = trans.GetResponseInfo();
ttuttled9dbc652015-09-29 20:00:592599 ASSERT_TRUE(response);
2600 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
2601
2602 IPEndPoint endpoint;
bnc691fda62016-08-12 00:43:162603 EXPECT_TRUE(trans.GetRemoteEndpoint(&endpoint));
ttuttled9dbc652015-09-29 20:00:592604 ASSERT_FALSE(endpoint.address().empty());
2605 EXPECT_EQ("127.0.0.1:80", endpoint.ToString());
2606
2607 resolver->rules()->ClearRules();
2608 resolver->rules()->AddRule("www.example.org", "127.0.0.2");
2609
2610 TestCompletionCallback callback2;
2611
bnc691fda62016-08-12 00:43:162612 EXPECT_EQ(OK, callback2.GetResult(trans.RestartWithAuth(
ttuttled9dbc652015-09-29 20:00:592613 AuthCredentials(kFoo, kBar), callback2.callback())));
2614
2615 LoadTimingInfo load_timing_info2;
bnc691fda62016-08-12 00:43:162616 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info2));
ttuttled9dbc652015-09-29 20:00:592617 TestLoadTimingNotReused(load_timing_info2, CONNECT_TIMING_HAS_DNS_TIMES);
2618 // The load timing after restart should have a new socket ID, and times after
2619 // those of the first load timing.
2620 EXPECT_LE(load_timing_info1.receive_headers_end,
2621 load_timing_info2.connect_timing.connect_start);
2622 EXPECT_NE(load_timing_info1.socket_log_id, load_timing_info2.socket_log_id);
2623
2624 int64_t writes_size2 = CountWriteBytes(data_writes2, arraysize(data_writes2));
bnc691fda62016-08-12 00:43:162625 EXPECT_EQ(writes_size1 + writes_size2, trans.GetTotalSentBytes());
ttuttled9dbc652015-09-29 20:00:592626 int64_t reads_size2 = CountReadBytes(data_reads2, arraysize(data_reads2));
bnc691fda62016-08-12 00:43:162627 EXPECT_EQ(reads_size1 + reads_size2, trans.GetTotalReceivedBytes());
ttuttled9dbc652015-09-29 20:00:592628
bnc691fda62016-08-12 00:43:162629 response = trans.GetResponseInfo();
ttuttled9dbc652015-09-29 20:00:592630 ASSERT_TRUE(response);
wezca1070932016-05-26 20:30:522631 EXPECT_FALSE(response->auth_challenge);
ttuttled9dbc652015-09-29 20:00:592632 EXPECT_EQ(100, response->headers->GetContentLength());
2633
bnc691fda62016-08-12 00:43:162634 EXPECT_TRUE(trans.GetRemoteEndpoint(&endpoint));
ttuttled9dbc652015-09-29 20:00:592635 ASSERT_FALSE(endpoint.address().empty());
2636 EXPECT_EQ("127.0.0.2:80", endpoint.ToString());
2637}
2638
bncd16676a2016-07-20 16:23:012639TEST_F(HttpNetworkTransactionTest, DoNotSendAuth) {
[email protected]861fcd52009-08-26 02:33:462640 HttpRequestInfo request;
2641 request.method = "GET";
bncce36dca22015-04-21 22:11:232642 request.url = GURL("http://www.example.org/");
ttuttle859dc7a2015-04-23 19:42:292643 request.load_flags = LOAD_DO_NOT_SEND_AUTH_DATA;
[email protected]861fcd52009-08-26 02:33:462644
danakj1fd259a02016-04-16 03:17:092645 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:162646 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:272647
[email protected]861fcd52009-08-26 02:33:462648 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:232649 MockWrite(
2650 "GET / HTTP/1.1\r\n"
2651 "Host: www.example.org\r\n"
2652 "Connection: keep-alive\r\n\r\n"),
[email protected]861fcd52009-08-26 02:33:462653 };
2654
2655 MockRead data_reads[] = {
2656 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
2657 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2658 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
2659 // Large content-length -- won't matter, as connection will be reset.
2660 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:062661 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]861fcd52009-08-26 02:33:462662 };
2663
[email protected]31a2bfe2010-02-09 08:03:392664 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
2665 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:072666 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]49639fa2011-12-20 23:22:412667 TestCompletionCallback callback;
[email protected]861fcd52009-08-26 02:33:462668
tfarina42834112016-09-22 13:38:202669 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012670 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]861fcd52009-08-26 02:33:462671
2672 rv = callback.WaitForResult();
2673 EXPECT_EQ(0, rv);
2674
sclittlefb249892015-09-10 21:33:222675 int64_t writes_size = CountWriteBytes(data_writes, arraysize(data_writes));
bnc691fda62016-08-12 00:43:162676 EXPECT_EQ(writes_size, trans.GetTotalSentBytes());
sclittlefb249892015-09-10 21:33:222677 int64_t reads_size = CountReadBytes(data_reads, arraysize(data_reads));
bnc691fda62016-08-12 00:43:162678 EXPECT_EQ(reads_size, trans.GetTotalReceivedBytes());
[email protected]b8015c42013-12-24 15:18:192679
bnc691fda62016-08-12 00:43:162680 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:522681 ASSERT_TRUE(response);
2682 EXPECT_FALSE(response->auth_challenge);
[email protected]861fcd52009-08-26 02:33:462683}
2684
[email protected]2d2697f92009-02-18 21:00:322685// Test the request-challenge-retry sequence for basic auth, over a keep-alive
2686// connection.
bncd16676a2016-07-20 16:23:012687TEST_F(HttpNetworkTransactionTest, BasicAuthKeepAlive) {
mmenkecc2298e2015-12-07 18:20:182688 // On the second pass, the body read of the auth challenge is synchronous, so
2689 // IsConnectedAndIdle returns false. The socket should still be drained and
2690 // reused. See http://crbug.com/544255.
2691 for (int i = 0; i < 2; ++i) {
2692 HttpRequestInfo request;
2693 request.method = "GET";
2694 request.url = GURL("http://www.example.org/");
[email protected]2d2697f92009-02-18 21:00:322695
mmenkecc2298e2015-12-07 18:20:182696 TestNetLog log;
2697 session_deps_.net_log = &log;
danakj1fd259a02016-04-16 03:17:092698 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:272699
mmenkecc2298e2015-12-07 18:20:182700 MockWrite data_writes[] = {
2701 MockWrite(ASYNC, 0,
2702 "GET / HTTP/1.1\r\n"
2703 "Host: www.example.org\r\n"
2704 "Connection: keep-alive\r\n\r\n"),
[email protected]2d2697f92009-02-18 21:00:322705
bnc691fda62016-08-12 00:43:162706 // After calling trans.RestartWithAuth(), this is the request we should
mmenkecc2298e2015-12-07 18:20:182707 // be issuing -- the final header line contains the credentials.
2708 MockWrite(ASYNC, 6,
2709 "GET / HTTP/1.1\r\n"
2710 "Host: www.example.org\r\n"
2711 "Connection: keep-alive\r\n"
2712 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
2713 };
[email protected]2d2697f92009-02-18 21:00:322714
mmenkecc2298e2015-12-07 18:20:182715 MockRead data_reads[] = {
2716 MockRead(ASYNC, 1, "HTTP/1.1 401 Unauthorized\r\n"),
2717 MockRead(ASYNC, 2, "WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2718 MockRead(ASYNC, 3, "Content-Type: text/html; charset=iso-8859-1\r\n"),
2719 MockRead(ASYNC, 4, "Content-Length: 14\r\n\r\n"),
2720 MockRead(i == 0 ? ASYNC : SYNCHRONOUS, 5, "Unauthorized\r\n"),
[email protected]2d2697f92009-02-18 21:00:322721
mmenkecc2298e2015-12-07 18:20:182722 // Lastly, the server responds with the actual content.
2723 MockRead(ASYNC, 7, "HTTP/1.1 200 OK\r\n"),
2724 MockRead(ASYNC, 8, "Content-Type: text/html; charset=iso-8859-1\r\n"),
2725 MockRead(ASYNC, 9, "Content-Length: 5\r\n\r\n"),
2726 MockRead(ASYNC, 10, "Hello"),
2727 };
[email protected]2d2697f92009-02-18 21:00:322728
mmenkecc2298e2015-12-07 18:20:182729 SequencedSocketData data(data_reads, arraysize(data_reads), data_writes,
2730 arraysize(data_writes));
2731 data.set_busy_before_sync_reads(true);
2732 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]2d0a4f92011-05-05 16:38:462733
mmenkecc2298e2015-12-07 18:20:182734 TestCompletionCallback callback1;
[email protected]2d2697f92009-02-18 21:00:322735
bnc691fda62016-08-12 00:43:162736 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:202737 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012738 ASSERT_THAT(callback1.GetResult(rv), IsOk());
[email protected]2d2697f92009-02-18 21:00:322739
mmenkecc2298e2015-12-07 18:20:182740 LoadTimingInfo load_timing_info1;
bnc691fda62016-08-12 00:43:162741 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info1));
mmenkecc2298e2015-12-07 18:20:182742 TestLoadTimingNotReused(load_timing_info1, CONNECT_TIMING_HAS_DNS_TIMES);
[email protected]2d2697f92009-02-18 21:00:322743
bnc691fda62016-08-12 00:43:162744 const HttpResponseInfo* response = trans.GetResponseInfo();
mmenkecc2298e2015-12-07 18:20:182745 ASSERT_TRUE(response);
2746 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]2d2697f92009-02-18 21:00:322747
mmenkecc2298e2015-12-07 18:20:182748 TestCompletionCallback callback2;
[email protected]58e32bb2013-01-21 18:23:252749
bnc691fda62016-08-12 00:43:162750 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar),
2751 callback2.callback());
robpercival214763f2016-07-01 23:27:012752 ASSERT_THAT(callback2.GetResult(rv), IsOk());
[email protected]2d2697f92009-02-18 21:00:322753
mmenkecc2298e2015-12-07 18:20:182754 LoadTimingInfo load_timing_info2;
bnc691fda62016-08-12 00:43:162755 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info2));
mmenkecc2298e2015-12-07 18:20:182756 TestLoadTimingReused(load_timing_info2);
2757 // The load timing after restart should have the same socket ID, and times
2758 // those of the first load timing.
2759 EXPECT_LE(load_timing_info1.receive_headers_end,
2760 load_timing_info2.send_start);
2761 EXPECT_EQ(load_timing_info1.socket_log_id, load_timing_info2.socket_log_id);
[email protected]2d2697f92009-02-18 21:00:322762
bnc691fda62016-08-12 00:43:162763 response = trans.GetResponseInfo();
mmenkecc2298e2015-12-07 18:20:182764 ASSERT_TRUE(response);
2765 EXPECT_FALSE(response->auth_challenge);
2766 EXPECT_EQ(5, response->headers->GetContentLength());
[email protected]2d2697f92009-02-18 21:00:322767
mmenkecc2298e2015-12-07 18:20:182768 std::string response_data;
bnc691fda62016-08-12 00:43:162769 EXPECT_THAT(ReadTransaction(&trans, &response_data), IsOk());
[email protected]2d2697f92009-02-18 21:00:322770
mmenkecc2298e2015-12-07 18:20:182771 int64_t writes_size = CountWriteBytes(data_writes, arraysize(data_writes));
bnc691fda62016-08-12 00:43:162772 EXPECT_EQ(writes_size, trans.GetTotalSentBytes());
mmenkecc2298e2015-12-07 18:20:182773 int64_t reads_size = CountReadBytes(data_reads, arraysize(data_reads));
bnc691fda62016-08-12 00:43:162774 EXPECT_EQ(reads_size, trans.GetTotalReceivedBytes());
mmenkecc2298e2015-12-07 18:20:182775 }
[email protected]2d2697f92009-02-18 21:00:322776}
2777
2778// Test the request-challenge-retry sequence for basic auth, over a keep-alive
2779// connection and with no response body to drain.
bncd16676a2016-07-20 16:23:012780TEST_F(HttpNetworkTransactionTest, BasicAuthKeepAliveNoBody) {
[email protected]1c773ea12009-04-28 19:58:422781 HttpRequestInfo request;
[email protected]2d2697f92009-02-18 21:00:322782 request.method = "GET";
bncce36dca22015-04-21 22:11:232783 request.url = GURL("http://www.example.org/");
[email protected]2d2697f92009-02-18 21:00:322784
danakj1fd259a02016-04-16 03:17:092785 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:272786
[email protected]2d2697f92009-02-18 21:00:322787 MockWrite data_writes1[] = {
bnc691fda62016-08-12 00:43:162788 MockWrite("GET / HTTP/1.1\r\n"
2789 "Host: www.example.org\r\n"
2790 "Connection: keep-alive\r\n\r\n"),
[email protected]2d2697f92009-02-18 21:00:322791
bnc691fda62016-08-12 00:43:162792 // After calling trans.RestartWithAuth(), this is the request we should
bncce36dca22015-04-21 22:11:232793 // be issuing -- the final header line contains the credentials.
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"
2797 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]2d2697f92009-02-18 21:00:322798 };
2799
[email protected]2d2697f92009-02-18 21:00:322800 MockRead data_reads1[] = {
2801 MockRead("HTTP/1.1 401 Unauthorized\r\n"),
2802 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
[email protected]11203f012009-11-12 23:02:312803 MockRead("Content-Length: 0\r\n\r\n"), // No response body.
[email protected]2d2697f92009-02-18 21:00:322804
2805 // Lastly, the server responds with the actual content.
2806 MockRead("HTTP/1.1 200 OK\r\n"),
2807 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
[email protected]0b0bf032010-09-21 18:08:502808 MockRead("Content-Length: 5\r\n\r\n"),
2809 MockRead("hello"),
[email protected]2d2697f92009-02-18 21:00:322810 };
2811
[email protected]2d0a4f92011-05-05 16:38:462812 // An incorrect reconnect would cause this to be read.
2813 MockRead data_reads2[] = {
[email protected]8ddf8322012-02-23 18:08:062814 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]2d0a4f92011-05-05 16:38:462815 };
2816
[email protected]31a2bfe2010-02-09 08:03:392817 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
2818 data_writes1, arraysize(data_writes1));
[email protected]2d0a4f92011-05-05 16:38:462819 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
2820 NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:072821 session_deps_.socket_factory->AddSocketDataProvider(&data1);
2822 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]2d2697f92009-02-18 21:00:322823
[email protected]49639fa2011-12-20 23:22:412824 TestCompletionCallback callback1;
[email protected]2d2697f92009-02-18 21:00:322825
bnc691fda62016-08-12 00:43:162826 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:202827 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012828 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2d2697f92009-02-18 21:00:322829
2830 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:012831 EXPECT_THAT(rv, IsOk());
[email protected]2d2697f92009-02-18 21:00:322832
bnc691fda62016-08-12 00:43:162833 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:522834 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:042835 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]2d2697f92009-02-18 21:00:322836
[email protected]49639fa2011-12-20 23:22:412837 TestCompletionCallback callback2;
[email protected]2d2697f92009-02-18 21:00:322838
bnc691fda62016-08-12 00:43:162839 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar), callback2.callback());
robpercival214763f2016-07-01 23:27:012840 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2d2697f92009-02-18 21:00:322841
2842 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:012843 EXPECT_THAT(rv, IsOk());
[email protected]2d2697f92009-02-18 21:00:322844
bnc691fda62016-08-12 00:43:162845 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:522846 ASSERT_TRUE(response);
2847 EXPECT_FALSE(response->auth_challenge);
[email protected]0b0bf032010-09-21 18:08:502848 EXPECT_EQ(5, response->headers->GetContentLength());
[email protected]2d2697f92009-02-18 21:00:322849}
2850
2851// Test the request-challenge-retry sequence for basic auth, over a keep-alive
2852// connection and with a large response body to drain.
bncd16676a2016-07-20 16:23:012853TEST_F(HttpNetworkTransactionTest, BasicAuthKeepAliveLargeBody) {
[email protected]1c773ea12009-04-28 19:58:422854 HttpRequestInfo request;
[email protected]2d2697f92009-02-18 21:00:322855 request.method = "GET";
bncce36dca22015-04-21 22:11:232856 request.url = GURL("http://www.example.org/");
[email protected]2d2697f92009-02-18 21:00:322857
danakj1fd259a02016-04-16 03:17:092858 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:272859
[email protected]2d2697f92009-02-18 21:00:322860 MockWrite data_writes1[] = {
bnc691fda62016-08-12 00:43:162861 MockWrite("GET / HTTP/1.1\r\n"
2862 "Host: www.example.org\r\n"
2863 "Connection: keep-alive\r\n\r\n"),
[email protected]2d2697f92009-02-18 21:00:322864
bnc691fda62016-08-12 00:43:162865 // After calling trans.RestartWithAuth(), this is the request we should
bncce36dca22015-04-21 22:11:232866 // be issuing -- the final header line contains the credentials.
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"
2870 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]2d2697f92009-02-18 21:00:322871 };
2872
2873 // Respond with 5 kb of response body.
2874 std::string large_body_string("Unauthorized");
2875 large_body_string.append(5 * 1024, ' ');
2876 large_body_string.append("\r\n");
2877
2878 MockRead data_reads1[] = {
2879 MockRead("HTTP/1.1 401 Unauthorized\r\n"),
2880 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2881 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
2882 // 5134 = 12 + 5 * 1024 + 2
2883 MockRead("Content-Length: 5134\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:062884 MockRead(ASYNC, large_body_string.data(), large_body_string.size()),
[email protected]2d2697f92009-02-18 21:00:322885
2886 // Lastly, the server responds with the actual content.
2887 MockRead("HTTP/1.1 200 OK\r\n"),
2888 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
[email protected]0b0bf032010-09-21 18:08:502889 MockRead("Content-Length: 5\r\n\r\n"),
2890 MockRead("hello"),
[email protected]2d2697f92009-02-18 21:00:322891 };
2892
[email protected]2d0a4f92011-05-05 16:38:462893 // An incorrect reconnect would cause this to be read.
2894 MockRead data_reads2[] = {
[email protected]8ddf8322012-02-23 18:08:062895 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]2d0a4f92011-05-05 16:38:462896 };
2897
[email protected]31a2bfe2010-02-09 08:03:392898 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
2899 data_writes1, arraysize(data_writes1));
[email protected]2d0a4f92011-05-05 16:38:462900 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
2901 NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:072902 session_deps_.socket_factory->AddSocketDataProvider(&data1);
2903 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]2d2697f92009-02-18 21:00:322904
[email protected]49639fa2011-12-20 23:22:412905 TestCompletionCallback callback1;
[email protected]2d2697f92009-02-18 21:00:322906
bnc691fda62016-08-12 00:43:162907 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:202908 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012909 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2d2697f92009-02-18 21:00:322910
2911 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:012912 EXPECT_THAT(rv, IsOk());
[email protected]2d2697f92009-02-18 21:00:322913
bnc691fda62016-08-12 00:43:162914 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:522915 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:042916 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]2d2697f92009-02-18 21:00:322917
[email protected]49639fa2011-12-20 23:22:412918 TestCompletionCallback callback2;
[email protected]2d2697f92009-02-18 21:00:322919
bnc691fda62016-08-12 00:43:162920 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar), callback2.callback());
robpercival214763f2016-07-01 23:27:012921 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2d2697f92009-02-18 21:00:322922
2923 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:012924 EXPECT_THAT(rv, IsOk());
[email protected]2d2697f92009-02-18 21:00:322925
bnc691fda62016-08-12 00:43:162926 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:522927 ASSERT_TRUE(response);
2928 EXPECT_FALSE(response->auth_challenge);
[email protected]0b0bf032010-09-21 18:08:502929 EXPECT_EQ(5, response->headers->GetContentLength());
[email protected]2d2697f92009-02-18 21:00:322930}
2931
2932// Test the request-challenge-retry sequence for basic auth, over a keep-alive
[email protected]11203f012009-11-12 23:02:312933// connection, but the server gets impatient and closes the connection.
bncd16676a2016-07-20 16:23:012934TEST_F(HttpNetworkTransactionTest, BasicAuthKeepAliveImpatientServer) {
[email protected]11203f012009-11-12 23:02:312935 HttpRequestInfo request;
2936 request.method = "GET";
bncce36dca22015-04-21 22:11:232937 request.url = GURL("http://www.example.org/");
[email protected]11203f012009-11-12 23:02:312938
danakj1fd259a02016-04-16 03:17:092939 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:272940
[email protected]11203f012009-11-12 23:02:312941 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:232942 MockWrite(
2943 "GET / HTTP/1.1\r\n"
2944 "Host: www.example.org\r\n"
2945 "Connection: keep-alive\r\n\r\n"),
2946 // This simulates the seemingly successful write to a closed connection
2947 // if the bug is not fixed.
2948 MockWrite(
2949 "GET / HTTP/1.1\r\n"
2950 "Host: www.example.org\r\n"
2951 "Connection: keep-alive\r\n"
2952 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]11203f012009-11-12 23:02:312953 };
2954
2955 MockRead data_reads1[] = {
2956 MockRead("HTTP/1.1 401 Unauthorized\r\n"),
2957 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2958 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
2959 MockRead("Content-Length: 14\r\n\r\n"),
2960 // Tell MockTCPClientSocket to simulate the server closing the connection.
[email protected]8ddf8322012-02-23 18:08:062961 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
[email protected]11203f012009-11-12 23:02:312962 MockRead("Unauthorized\r\n"),
[email protected]8ddf8322012-02-23 18:08:062963 MockRead(SYNCHRONOUS, OK), // The server closes the connection.
[email protected]11203f012009-11-12 23:02:312964 };
2965
bnc691fda62016-08-12 00:43:162966 // After calling trans.RestartWithAuth(), this is the request we should
[email protected]11203f012009-11-12 23:02:312967 // be issuing -- the final header line contains the credentials.
2968 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:232969 MockWrite(
2970 "GET / HTTP/1.1\r\n"
2971 "Host: www.example.org\r\n"
2972 "Connection: keep-alive\r\n"
2973 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]11203f012009-11-12 23:02:312974 };
2975
2976 // Lastly, the server responds with the actual content.
2977 MockRead data_reads2[] = {
2978 MockRead("HTTP/1.1 200 OK\r\n"),
2979 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
[email protected]0b0bf032010-09-21 18:08:502980 MockRead("Content-Length: 5\r\n\r\n"),
2981 MockRead("hello"),
[email protected]11203f012009-11-12 23:02:312982 };
2983
[email protected]31a2bfe2010-02-09 08:03:392984 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
2985 data_writes1, arraysize(data_writes1));
2986 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
2987 data_writes2, arraysize(data_writes2));
[email protected]bb88e1d32013-05-03 23:11:072988 session_deps_.socket_factory->AddSocketDataProvider(&data1);
2989 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]11203f012009-11-12 23:02:312990
[email protected]49639fa2011-12-20 23:22:412991 TestCompletionCallback callback1;
[email protected]11203f012009-11-12 23:02:312992
bnc691fda62016-08-12 00:43:162993 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:202994 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012995 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]11203f012009-11-12 23:02:312996
2997 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:012998 EXPECT_THAT(rv, IsOk());
[email protected]11203f012009-11-12 23:02:312999
bnc691fda62016-08-12 00:43:163000 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:523001 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:043002 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]11203f012009-11-12 23:02:313003
[email protected]49639fa2011-12-20 23:22:413004 TestCompletionCallback callback2;
[email protected]11203f012009-11-12 23:02:313005
bnc691fda62016-08-12 00:43:163006 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar), callback2.callback());
robpercival214763f2016-07-01 23:27:013007 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]11203f012009-11-12 23:02:313008
3009 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:013010 EXPECT_THAT(rv, IsOk());
[email protected]11203f012009-11-12 23:02:313011
bnc691fda62016-08-12 00:43:163012 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:523013 ASSERT_TRUE(response);
3014 EXPECT_FALSE(response->auth_challenge);
[email protected]0b0bf032010-09-21 18:08:503015 EXPECT_EQ(5, response->headers->GetContentLength());
[email protected]11203f012009-11-12 23:02:313016}
3017
[email protected]394816e92010-08-03 07:38:593018// Test the request-challenge-retry sequence for basic auth, over a connection
3019// that requires a restart when setting up an SSL tunnel.
bncd16676a2016-07-20 16:23:013020TEST_F(HttpNetworkTransactionTest, BasicAuthProxyNoKeepAliveHttp10) {
ttuttle34f63b52015-03-05 04:33:013021 HttpRequestInfo request;
3022 request.method = "GET";
bncce36dca22015-04-21 22:11:233023 request.url = GURL("https://www.example.org/");
ttuttle34f63b52015-03-05 04:33:013024 // when the no authentication data flag is set.
ttuttle859dc7a2015-04-23 19:42:293025 request.load_flags = LOAD_DO_NOT_SEND_AUTH_DATA;
ttuttle34f63b52015-03-05 04:33:013026
3027 // Configure against proxy server "myproxy:70".
rdsmith82957ad2015-09-16 19:42:033028 session_deps_.proxy_service =
3029 ProxyService::CreateFixedFromPacResult("PROXY myproxy:70");
vishal.b62985ca92015-04-17 08:45:513030 BoundTestNetLog log;
ttuttle34f63b52015-03-05 04:33:013031 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:093032 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
ttuttle34f63b52015-03-05 04:33:013033
3034 // Since we have proxy, should try to establish tunnel.
3035 MockWrite data_writes1[] = {
mmenkee71e15332015-10-07 16:39:543036 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:173037 "Host: www.example.org:443\r\n"
mmenkee71e15332015-10-07 16:39:543038 "Proxy-Connection: keep-alive\r\n\r\n"),
ttuttle34f63b52015-03-05 04:33:013039 };
3040
mmenkee71e15332015-10-07 16:39:543041 // The proxy responds to the connect with a 407, using a non-persistent
ttuttle34f63b52015-03-05 04:33:013042 // connection.
3043 MockRead data_reads1[] = {
3044 // No credentials.
3045 MockRead("HTTP/1.0 407 Proxy Authentication Required\r\n"),
3046 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n\r\n"),
mmenkee71e15332015-10-07 16:39:543047 };
ttuttle34f63b52015-03-05 04:33:013048
mmenkee71e15332015-10-07 16:39:543049 // Since the first connection couldn't be reused, need to establish another
3050 // once given credentials.
3051 MockWrite data_writes2[] = {
3052 // After calling trans->RestartWithAuth(), this is the request we should
3053 // be issuing -- the final header line contains the credentials.
3054 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:173055 "Host: www.example.org:443\r\n"
mmenkee71e15332015-10-07 16:39:543056 "Proxy-Connection: keep-alive\r\n"
3057 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
3058
3059 MockWrite("GET / HTTP/1.1\r\n"
3060 "Host: www.example.org\r\n"
3061 "Connection: keep-alive\r\n\r\n"),
3062 };
3063
3064 MockRead data_reads2[] = {
ttuttle34f63b52015-03-05 04:33:013065 MockRead("HTTP/1.0 200 Connection Established\r\n\r\n"),
3066
3067 MockRead("HTTP/1.1 200 OK\r\n"),
3068 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
3069 MockRead("Content-Length: 5\r\n\r\n"),
3070 MockRead(SYNCHRONOUS, "hello"),
3071 };
3072
3073 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
3074 data_writes1, arraysize(data_writes1));
3075 session_deps_.socket_factory->AddSocketDataProvider(&data1);
mmenkee71e15332015-10-07 16:39:543076 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
3077 data_writes2, arraysize(data_writes2));
3078 session_deps_.socket_factory->AddSocketDataProvider(&data2);
ttuttle34f63b52015-03-05 04:33:013079 SSLSocketDataProvider ssl(ASYNC, OK);
3080 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
3081
3082 TestCompletionCallback callback1;
3083
bnc87dcefc2017-05-25 12:47:583084 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:193085 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
ttuttle34f63b52015-03-05 04:33:013086
3087 int rv = trans->Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:013088 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
ttuttle34f63b52015-03-05 04:33:013089
3090 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:013091 EXPECT_THAT(rv, IsOk());
mmenke43758e62015-05-04 21:09:463092 TestNetLogEntry::List entries;
ttuttle34f63b52015-03-05 04:33:013093 log.GetEntries(&entries);
3094 size_t pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:003095 entries, 0, NetLogEventType::HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
3096 NetLogEventPhase::NONE);
ttuttle34f63b52015-03-05 04:33:013097 ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:003098 entries, pos,
3099 NetLogEventType::HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
3100 NetLogEventPhase::NONE);
ttuttle34f63b52015-03-05 04:33:013101
3102 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:523103 ASSERT_TRUE(response);
ttuttle34f63b52015-03-05 04:33:013104 EXPECT_FALSE(response->headers->IsKeepAlive());
wezca1070932016-05-26 20:30:523105 ASSERT_TRUE(response->headers);
ttuttle34f63b52015-03-05 04:33:013106 EXPECT_EQ(407, response->headers->response_code());
3107 EXPECT_TRUE(HttpVersion(1, 0) == response->headers->GetHttpVersion());
3108 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
3109
3110 LoadTimingInfo load_timing_info;
3111 // CONNECT requests and responses are handled at the connect job level, so
3112 // the transaction does not yet have a connection.
3113 EXPECT_FALSE(trans->GetLoadTimingInfo(&load_timing_info));
3114
3115 TestCompletionCallback callback2;
3116
3117 rv =
3118 trans->RestartWithAuth(AuthCredentials(kFoo, kBar), callback2.callback());
robpercival214763f2016-07-01 23:27:013119 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
ttuttle34f63b52015-03-05 04:33:013120
3121 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:013122 EXPECT_THAT(rv, IsOk());
ttuttle34f63b52015-03-05 04:33:013123
3124 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:523125 ASSERT_TRUE(response);
ttuttle34f63b52015-03-05 04:33:013126
3127 EXPECT_TRUE(response->headers->IsKeepAlive());
3128 EXPECT_EQ(200, response->headers->response_code());
3129 EXPECT_EQ(5, response->headers->GetContentLength());
3130 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
3131
3132 // The password prompt info should not be set.
wezca1070932016-05-26 20:30:523133 EXPECT_FALSE(response->auth_challenge);
ttuttle34f63b52015-03-05 04:33:013134
3135 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
3136 TestLoadTimingNotReusedWithPac(load_timing_info,
3137 CONNECT_TIMING_HAS_SSL_TIMES);
3138
3139 trans.reset();
3140 session->CloseAllConnections();
3141}
3142
3143// Test the request-challenge-retry sequence for basic auth, over a connection
3144// that requires a restart when setting up an SSL tunnel.
bncd16676a2016-07-20 16:23:013145TEST_F(HttpNetworkTransactionTest, BasicAuthProxyNoKeepAliveHttp11) {
[email protected]394816e92010-08-03 07:38:593146 HttpRequestInfo request;
3147 request.method = "GET";
bncce36dca22015-04-21 22:11:233148 request.url = GURL("https://www.example.org/");
[email protected]394816e92010-08-03 07:38:593149 // when the no authentication data flag is set.
ttuttle859dc7a2015-04-23 19:42:293150 request.load_flags = LOAD_DO_NOT_SEND_AUTH_DATA;
[email protected]394816e92010-08-03 07:38:593151
[email protected]cb9bf6ca2011-01-28 13:15:273152 // Configure against proxy server "myproxy:70".
rdsmith82957ad2015-09-16 19:42:033153 session_deps_.proxy_service =
3154 ProxyService::CreateFixedFromPacResult("PROXY myproxy:70");
vishal.b62985ca92015-04-17 08:45:513155 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:073156 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:093157 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:273158
[email protected]394816e92010-08-03 07:38:593159 // Since we have proxy, should try to establish tunnel.
3160 MockWrite data_writes1[] = {
mmenkee71e15332015-10-07 16:39:543161 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:173162 "Host: www.example.org:443\r\n"
mmenkee71e15332015-10-07 16:39:543163 "Proxy-Connection: keep-alive\r\n\r\n"),
mmenkee0b5c882015-08-26 20:29:113164 };
3165
mmenkee71e15332015-10-07 16:39:543166 // The proxy responds to the connect with a 407, using a non-persistent
mmenke0fd148d2015-09-30 23:00:083167 // connection.
3168 MockRead data_reads1[] = {
mmenkee71e15332015-10-07 16:39:543169 // No credentials.
3170 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
3171 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
3172 MockRead("Proxy-Connection: close\r\n\r\n"),
3173 };
mmenkee0b5c882015-08-26 20:29:113174
mmenkee71e15332015-10-07 16:39:543175 MockWrite data_writes2[] = {
3176 // After calling trans->RestartWithAuth(), this is the request we should
3177 // be issuing -- the final header line contains the credentials.
3178 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:173179 "Host: www.example.org:443\r\n"
mmenkee71e15332015-10-07 16:39:543180 "Proxy-Connection: keep-alive\r\n"
3181 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
mmenke0fd148d2015-09-30 23:00:083182
mmenkee71e15332015-10-07 16:39:543183 MockWrite("GET / HTTP/1.1\r\n"
3184 "Host: www.example.org\r\n"
3185 "Connection: keep-alive\r\n\r\n"),
3186 };
3187
3188 MockRead data_reads2[] = {
3189 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
3190
3191 MockRead("HTTP/1.1 200 OK\r\n"),
3192 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
3193 MockRead("Content-Length: 5\r\n\r\n"),
3194 MockRead(SYNCHRONOUS, "hello"),
[email protected]394816e92010-08-03 07:38:593195 };
3196
3197 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
3198 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:073199 session_deps_.socket_factory->AddSocketDataProvider(&data1);
mmenkee71e15332015-10-07 16:39:543200 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
3201 data_writes2, arraysize(data_writes2));
3202 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]8ddf8322012-02-23 18:08:063203 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:073204 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]394816e92010-08-03 07:38:593205
[email protected]49639fa2011-12-20 23:22:413206 TestCompletionCallback callback1;
[email protected]394816e92010-08-03 07:38:593207
bnc87dcefc2017-05-25 12:47:583208 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:193209 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]0b0bf032010-09-21 18:08:503210
[email protected]49639fa2011-12-20 23:22:413211 int rv = trans->Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:013212 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]394816e92010-08-03 07:38:593213
3214 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:013215 EXPECT_THAT(rv, IsOk());
mmenke43758e62015-05-04 21:09:463216 TestNetLogEntry::List entries;
[email protected]b2fcd0e2010-12-01 15:19:403217 log.GetEntries(&entries);
[email protected]394816e92010-08-03 07:38:593218 size_t pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:003219 entries, 0, NetLogEventType::HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
3220 NetLogEventPhase::NONE);
[email protected]394816e92010-08-03 07:38:593221 ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:403222 entries, pos,
mikecirone8b85c432016-09-08 19:11:003223 NetLogEventType::HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
3224 NetLogEventPhase::NONE);
[email protected]394816e92010-08-03 07:38:593225
3226 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:523227 ASSERT_TRUE(response);
ttuttle34f63b52015-03-05 04:33:013228 EXPECT_FALSE(response->headers->IsKeepAlive());
wezca1070932016-05-26 20:30:523229 ASSERT_TRUE(response->headers);
[email protected]394816e92010-08-03 07:38:593230 EXPECT_EQ(407, response->headers->response_code());
3231 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
[email protected]79cb5c12011-09-12 13:12:043232 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
[email protected]394816e92010-08-03 07:38:593233
[email protected]029c83b62013-01-24 05:28:203234 LoadTimingInfo load_timing_info;
3235 // CONNECT requests and responses are handled at the connect job level, so
3236 // the transaction does not yet have a connection.
3237 EXPECT_FALSE(trans->GetLoadTimingInfo(&load_timing_info));
3238
[email protected]49639fa2011-12-20 23:22:413239 TestCompletionCallback callback2;
[email protected]394816e92010-08-03 07:38:593240
[email protected]49639fa2011-12-20 23:22:413241 rv = trans->RestartWithAuth(
3242 AuthCredentials(kFoo, kBar), callback2.callback());
robpercival214763f2016-07-01 23:27:013243 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]394816e92010-08-03 07:38:593244
3245 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:013246 EXPECT_THAT(rv, IsOk());
[email protected]394816e92010-08-03 07:38:593247
3248 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:523249 ASSERT_TRUE(response);
[email protected]394816e92010-08-03 07:38:593250
3251 EXPECT_TRUE(response->headers->IsKeepAlive());
3252 EXPECT_EQ(200, response->headers->response_code());
[email protected]0b0bf032010-09-21 18:08:503253 EXPECT_EQ(5, response->headers->GetContentLength());
[email protected]394816e92010-08-03 07:38:593254 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
3255
3256 // The password prompt info should not be set.
wezca1070932016-05-26 20:30:523257 EXPECT_FALSE(response->auth_challenge);
[email protected]0b0bf032010-09-21 18:08:503258
[email protected]029c83b62013-01-24 05:28:203259 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
3260 TestLoadTimingNotReusedWithPac(load_timing_info,
3261 CONNECT_TIMING_HAS_SSL_TIMES);
3262
[email protected]0b0bf032010-09-21 18:08:503263 trans.reset();
[email protected]102e27c2011-02-23 01:01:313264 session->CloseAllConnections();
[email protected]394816e92010-08-03 07:38:593265}
3266
[email protected]11203f012009-11-12 23:02:313267// Test the request-challenge-retry sequence for basic auth, over a keep-alive
ttuttle34f63b52015-03-05 04:33:013268// proxy connection with HTTP/1.0 responses, when setting up an SSL tunnel.
bncd16676a2016-07-20 16:23:013269TEST_F(HttpNetworkTransactionTest, BasicAuthProxyKeepAliveHttp10) {
mmenked39192ee2015-12-09 00:57:233270 // On the second pass, the body read of the auth challenge is synchronous, so
3271 // IsConnectedAndIdle returns false. The socket should still be drained and
3272 // reused. See http://crbug.com/544255.
3273 for (int i = 0; i < 2; ++i) {
3274 HttpRequestInfo request;
3275 request.method = "GET";
3276 request.url = GURL("https://www.example.org/");
3277 // Ensure that proxy authentication is attempted even
3278 // when the no authentication data flag is set.
3279 request.load_flags = LOAD_DO_NOT_SEND_AUTH_DATA;
ttuttle34f63b52015-03-05 04:33:013280
mmenked39192ee2015-12-09 00:57:233281 // Configure against proxy server "myproxy:70".
3282 session_deps_.proxy_service = ProxyService::CreateFixed("myproxy:70");
3283 BoundTestNetLog log;
3284 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:093285 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
ttuttle34f63b52015-03-05 04:33:013286
bnc691fda62016-08-12 00:43:163287 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
ttuttle34f63b52015-03-05 04:33:013288
mmenked39192ee2015-12-09 00:57:233289 // Since we have proxy, should try to establish tunnel.
3290 MockWrite data_writes1[] = {
3291 MockWrite(ASYNC, 0,
3292 "CONNECT www.example.org:443 HTTP/1.1\r\n"
3293 "Host: www.example.org:443\r\n"
3294 "Proxy-Connection: keep-alive\r\n\r\n"),
ttuttle34f63b52015-03-05 04:33:013295
bnc691fda62016-08-12 00:43:163296 // After calling trans.RestartWithAuth(), this is the request we should
mmenked39192ee2015-12-09 00:57:233297 // be issuing -- the final header line contains the credentials.
3298 MockWrite(ASYNC, 3,
3299 "CONNECT www.example.org:443 HTTP/1.1\r\n"
3300 "Host: www.example.org:443\r\n"
3301 "Proxy-Connection: keep-alive\r\n"
3302 "Proxy-Authorization: Basic Zm9vOmJheg==\r\n\r\n"),
3303 };
ttuttle34f63b52015-03-05 04:33:013304
mmenked39192ee2015-12-09 00:57:233305 // The proxy responds to the connect with a 407, using a persistent
3306 // connection. (Since it's HTTP/1.0, keep-alive has to be explicit.)
3307 MockRead data_reads1[] = {
3308 // No credentials.
3309 MockRead(ASYNC, 1,
3310 "HTTP/1.0 407 Proxy Authentication Required\r\n"
3311 "Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"
3312 "Proxy-Connection: keep-alive\r\n"
3313 "Content-Length: 10\r\n\r\n"),
3314 MockRead(i == 0 ? ASYNC : SYNCHRONOUS, 2, "0123456789"),
ttuttle34f63b52015-03-05 04:33:013315
mmenked39192ee2015-12-09 00:57:233316 // Wrong credentials (wrong password).
3317 MockRead(ASYNC, 4,
3318 "HTTP/1.0 407 Proxy Authentication Required\r\n"
3319 "Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"
3320 "Proxy-Connection: keep-alive\r\n"
3321 "Content-Length: 10\r\n\r\n"),
3322 // No response body because the test stops reading here.
3323 MockRead(SYNCHRONOUS, ERR_UNEXPECTED, 5),
3324 };
ttuttle34f63b52015-03-05 04:33:013325
mmenked39192ee2015-12-09 00:57:233326 SequencedSocketData data1(data_reads1, arraysize(data_reads1), data_writes1,
3327 arraysize(data_writes1));
3328 data1.set_busy_before_sync_reads(true);
3329 session_deps_.socket_factory->AddSocketDataProvider(&data1);
ttuttle34f63b52015-03-05 04:33:013330
mmenked39192ee2015-12-09 00:57:233331 TestCompletionCallback callback1;
ttuttle34f63b52015-03-05 04:33:013332
bnc691fda62016-08-12 00:43:163333 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:013334 EXPECT_THAT(callback1.GetResult(rv), IsOk());
ttuttle34f63b52015-03-05 04:33:013335
mmenked39192ee2015-12-09 00:57:233336 TestNetLogEntry::List entries;
3337 log.GetEntries(&entries);
3338 size_t pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:003339 entries, 0, NetLogEventType::HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
3340 NetLogEventPhase::NONE);
mmenked39192ee2015-12-09 00:57:233341 ExpectLogContainsSomewhere(
3342 entries, pos,
mikecirone8b85c432016-09-08 19:11:003343 NetLogEventType::HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
3344 NetLogEventPhase::NONE);
ttuttle34f63b52015-03-05 04:33:013345
bnc691fda62016-08-12 00:43:163346 const HttpResponseInfo* response = trans.GetResponseInfo();
mmenked39192ee2015-12-09 00:57:233347 ASSERT_TRUE(response);
3348 ASSERT_TRUE(response->headers);
3349 EXPECT_TRUE(response->headers->IsKeepAlive());
3350 EXPECT_EQ(407, response->headers->response_code());
3351 EXPECT_EQ(10, response->headers->GetContentLength());
3352 EXPECT_TRUE(HttpVersion(1, 0) == response->headers->GetHttpVersion());
3353 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
ttuttle34f63b52015-03-05 04:33:013354
mmenked39192ee2015-12-09 00:57:233355 TestCompletionCallback callback2;
ttuttle34f63b52015-03-05 04:33:013356
mmenked39192ee2015-12-09 00:57:233357 // Wrong password (should be "bar").
bnc691fda62016-08-12 00:43:163358 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBaz),
3359 callback2.callback());
robpercival214763f2016-07-01 23:27:013360 EXPECT_THAT(callback2.GetResult(rv), IsOk());
ttuttle34f63b52015-03-05 04:33:013361
bnc691fda62016-08-12 00:43:163362 response = trans.GetResponseInfo();
mmenked39192ee2015-12-09 00:57:233363 ASSERT_TRUE(response);
3364 ASSERT_TRUE(response->headers);
3365 EXPECT_TRUE(response->headers->IsKeepAlive());
3366 EXPECT_EQ(407, response->headers->response_code());
3367 EXPECT_EQ(10, response->headers->GetContentLength());
3368 EXPECT_TRUE(HttpVersion(1, 0) == response->headers->GetHttpVersion());
3369 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
ttuttle34f63b52015-03-05 04:33:013370
mmenked39192ee2015-12-09 00:57:233371 // Flush the idle socket before the NetLog and HttpNetworkTransaction go
3372 // out of scope.
3373 session->CloseAllConnections();
3374 }
ttuttle34f63b52015-03-05 04:33:013375}
3376
3377// Test the request-challenge-retry sequence for basic auth, over a keep-alive
3378// proxy connection with HTTP/1.1 responses, when setting up an SSL tunnel.
bncd16676a2016-07-20 16:23:013379TEST_F(HttpNetworkTransactionTest, BasicAuthProxyKeepAliveHttp11) {
mmenked39192ee2015-12-09 00:57:233380 // On the second pass, the body read of the auth challenge is synchronous, so
3381 // IsConnectedAndIdle returns false. The socket should still be drained and
3382 // reused. See http://crbug.com/544255.
3383 for (int i = 0; i < 2; ++i) {
3384 HttpRequestInfo request;
3385 request.method = "GET";
3386 request.url = GURL("https://www.example.org/");
3387 // Ensure that proxy authentication is attempted even
3388 // when the no authentication data flag is set.
3389 request.load_flags = LOAD_DO_NOT_SEND_AUTH_DATA;
3390
3391 // Configure against proxy server "myproxy:70".
3392 session_deps_.proxy_service = ProxyService::CreateFixed("myproxy:70");
3393 BoundTestNetLog log;
3394 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:093395 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
mmenked39192ee2015-12-09 00:57:233396
bnc691fda62016-08-12 00:43:163397 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
mmenked39192ee2015-12-09 00:57:233398
3399 // Since we have proxy, should try to establish tunnel.
3400 MockWrite data_writes1[] = {
3401 MockWrite(ASYNC, 0,
3402 "CONNECT www.example.org:443 HTTP/1.1\r\n"
3403 "Host: www.example.org:443\r\n"
3404 "Proxy-Connection: keep-alive\r\n\r\n"),
3405
bnc691fda62016-08-12 00:43:163406 // After calling trans.RestartWithAuth(), this is the request we should
mmenked39192ee2015-12-09 00:57:233407 // be issuing -- the final header line contains the credentials.
3408 MockWrite(ASYNC, 3,
3409 "CONNECT www.example.org:443 HTTP/1.1\r\n"
3410 "Host: www.example.org:443\r\n"
3411 "Proxy-Connection: keep-alive\r\n"
3412 "Proxy-Authorization: Basic Zm9vOmJheg==\r\n\r\n"),
3413 };
3414
3415 // The proxy responds to the connect with a 407, using a persistent
3416 // connection. (Since it's HTTP/1.0, keep-alive has to be explicit.)
3417 MockRead data_reads1[] = {
3418 // No credentials.
3419 MockRead(ASYNC, 1,
3420 "HTTP/1.1 407 Proxy Authentication Required\r\n"
3421 "Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"
3422 "Content-Length: 10\r\n\r\n"),
3423 MockRead(i == 0 ? ASYNC : SYNCHRONOUS, 2, "0123456789"),
3424
3425 // Wrong credentials (wrong password).
3426 MockRead(ASYNC, 4,
3427 "HTTP/1.1 407 Proxy Authentication Required\r\n"
3428 "Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"
3429 "Content-Length: 10\r\n\r\n"),
3430 // No response body because the test stops reading here.
3431 MockRead(SYNCHRONOUS, ERR_UNEXPECTED, 5),
3432 };
3433
3434 SequencedSocketData data1(data_reads1, arraysize(data_reads1), data_writes1,
3435 arraysize(data_writes1));
3436 data1.set_busy_before_sync_reads(true);
3437 session_deps_.socket_factory->AddSocketDataProvider(&data1);
3438
3439 TestCompletionCallback callback1;
3440
bnc691fda62016-08-12 00:43:163441 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:013442 EXPECT_THAT(callback1.GetResult(rv), IsOk());
mmenked39192ee2015-12-09 00:57:233443
3444 TestNetLogEntry::List entries;
3445 log.GetEntries(&entries);
3446 size_t pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:003447 entries, 0, NetLogEventType::HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
3448 NetLogEventPhase::NONE);
mmenked39192ee2015-12-09 00:57:233449 ExpectLogContainsSomewhere(
3450 entries, pos,
mikecirone8b85c432016-09-08 19:11:003451 NetLogEventType::HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
3452 NetLogEventPhase::NONE);
mmenked39192ee2015-12-09 00:57:233453
bnc691fda62016-08-12 00:43:163454 const HttpResponseInfo* response = trans.GetResponseInfo();
mmenked39192ee2015-12-09 00:57:233455 ASSERT_TRUE(response);
3456 ASSERT_TRUE(response->headers);
3457 EXPECT_TRUE(response->headers->IsKeepAlive());
3458 EXPECT_EQ(407, response->headers->response_code());
3459 EXPECT_EQ(10, response->headers->GetContentLength());
3460 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
3461 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
3462
3463 TestCompletionCallback callback2;
3464
3465 // Wrong password (should be "bar").
bnc691fda62016-08-12 00:43:163466 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBaz),
3467 callback2.callback());
robpercival214763f2016-07-01 23:27:013468 EXPECT_THAT(callback2.GetResult(rv), IsOk());
mmenked39192ee2015-12-09 00:57:233469
bnc691fda62016-08-12 00:43:163470 response = trans.GetResponseInfo();
mmenked39192ee2015-12-09 00:57:233471 ASSERT_TRUE(response);
3472 ASSERT_TRUE(response->headers);
3473 EXPECT_TRUE(response->headers->IsKeepAlive());
3474 EXPECT_EQ(407, response->headers->response_code());
3475 EXPECT_EQ(10, response->headers->GetContentLength());
3476 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
3477 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
3478
3479 // Flush the idle socket before the NetLog and HttpNetworkTransaction go
3480 // out of scope.
3481 session->CloseAllConnections();
3482 }
3483}
3484
3485// Test the request-challenge-retry sequence for basic auth, over a keep-alive
3486// proxy connection with HTTP/1.1 responses, when setting up an SSL tunnel, in
3487// the case the server sends extra data on the original socket, so it can't be
3488// reused.
bncd16676a2016-07-20 16:23:013489TEST_F(HttpNetworkTransactionTest, BasicAuthProxyKeepAliveExtraData) {
[email protected]cb9bf6ca2011-01-28 13:15:273490 HttpRequestInfo request;
3491 request.method = "GET";
bncce36dca22015-04-21 22:11:233492 request.url = GURL("https://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:273493 // when the no authentication data flag is set.
ttuttle859dc7a2015-04-23 19:42:293494 request.load_flags = LOAD_DO_NOT_SEND_AUTH_DATA;
[email protected]cb9bf6ca2011-01-28 13:15:273495
[email protected]2d2697f92009-02-18 21:00:323496 // Configure against proxy server "myproxy:70".
mmenked39192ee2015-12-09 00:57:233497 session_deps_.proxy_service =
3498 ProxyService::CreateFixedFromPacResult("PROXY myproxy:70");
vishal.b62985ca92015-04-17 08:45:513499 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:073500 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:093501 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]2d2697f92009-02-18 21:00:323502
[email protected]2d2697f92009-02-18 21:00:323503 // Since we have proxy, should try to establish tunnel.
3504 MockWrite data_writes1[] = {
mmenked39192ee2015-12-09 00:57:233505 MockWrite(ASYNC, 0,
3506 "CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:173507 "Host: www.example.org:443\r\n"
3508 "Proxy-Connection: keep-alive\r\n\r\n"),
mmenked39192ee2015-12-09 00:57:233509 };
[email protected]2d2697f92009-02-18 21:00:323510
mmenked39192ee2015-12-09 00:57:233511 // The proxy responds to the connect with a 407, using a persistent, but sends
3512 // extra data, so the socket cannot be reused.
3513 MockRead data_reads1[] = {
3514 // No credentials.
3515 MockRead(ASYNC, 1,
3516 "HTTP/1.1 407 Proxy Authentication Required\r\n"
3517 "Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"
3518 "Content-Length: 10\r\n\r\n"),
3519 MockRead(SYNCHRONOUS, 2, "0123456789"),
3520 MockRead(SYNCHRONOUS, 3, "I'm broken!"),
3521 };
3522
3523 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:233524 // After calling trans->RestartWithAuth(), this is the request we should
3525 // be issuing -- the final header line contains the credentials.
mmenked39192ee2015-12-09 00:57:233526 MockWrite(ASYNC, 0,
3527 "CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:173528 "Host: www.example.org:443\r\n"
3529 "Proxy-Connection: keep-alive\r\n"
mmenked39192ee2015-12-09 00:57:233530 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
3531
3532 MockWrite(ASYNC, 2,
3533 "GET / HTTP/1.1\r\n"
3534 "Host: www.example.org\r\n"
3535 "Connection: keep-alive\r\n\r\n"),
[email protected]2d2697f92009-02-18 21:00:323536 };
3537
mmenked39192ee2015-12-09 00:57:233538 MockRead data_reads2[] = {
3539 MockRead(ASYNC, 1, "HTTP/1.1 200 Connection Established\r\n\r\n"),
[email protected]2d2697f92009-02-18 21:00:323540
mmenked39192ee2015-12-09 00:57:233541 MockRead(ASYNC, 3,
3542 "HTTP/1.1 200 OK\r\n"
3543 "Content-Type: text/html; charset=iso-8859-1\r\n"
3544 "Content-Length: 5\r\n\r\n"),
3545 // No response body because the test stops reading here.
3546 MockRead(SYNCHRONOUS, ERR_UNEXPECTED, 4),
[email protected]2d2697f92009-02-18 21:00:323547 };
3548
mmenked39192ee2015-12-09 00:57:233549 SequencedSocketData data1(data_reads1, arraysize(data_reads1), data_writes1,
3550 arraysize(data_writes1));
3551 data1.set_busy_before_sync_reads(true);
[email protected]bb88e1d32013-05-03 23:11:073552 session_deps_.socket_factory->AddSocketDataProvider(&data1);
mmenked39192ee2015-12-09 00:57:233553 SequencedSocketData data2(data_reads2, arraysize(data_reads2), data_writes2,
3554 arraysize(data_writes2));
3555 session_deps_.socket_factory->AddSocketDataProvider(&data2);
3556 SSLSocketDataProvider ssl(ASYNC, OK);
3557 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]2d2697f92009-02-18 21:00:323558
[email protected]49639fa2011-12-20 23:22:413559 TestCompletionCallback callback1;
[email protected]2d2697f92009-02-18 21:00:323560
bnc87dcefc2017-05-25 12:47:583561 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:193562 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]2d2697f92009-02-18 21:00:323563
mmenked39192ee2015-12-09 00:57:233564 int rv = trans->Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:013565 EXPECT_THAT(callback1.GetResult(rv), IsOk());
mmenked39192ee2015-12-09 00:57:233566
mmenke43758e62015-05-04 21:09:463567 TestNetLogEntry::List entries;
[email protected]b2fcd0e2010-12-01 15:19:403568 log.GetEntries(&entries);
[email protected]dbb83db2010-05-11 18:13:393569 size_t pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:003570 entries, 0, NetLogEventType::HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
3571 NetLogEventPhase::NONE);
[email protected]dbb83db2010-05-11 18:13:393572 ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:403573 entries, pos,
mikecirone8b85c432016-09-08 19:11:003574 NetLogEventType::HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
3575 NetLogEventPhase::NONE);
[email protected]2d2697f92009-02-18 21:00:323576
[email protected]1c773ea12009-04-28 19:58:423577 const HttpResponseInfo* response = trans->GetResponseInfo();
ttuttle7933c112015-01-06 00:55:243578 ASSERT_TRUE(response);
3579 ASSERT_TRUE(response->headers);
[email protected]2d2697f92009-02-18 21:00:323580 EXPECT_TRUE(response->headers->IsKeepAlive());
3581 EXPECT_EQ(407, response->headers->response_code());
[email protected]1c773ea12009-04-28 19:58:423582 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
[email protected]79cb5c12011-09-12 13:12:043583 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
[email protected]2d2697f92009-02-18 21:00:323584
mmenked39192ee2015-12-09 00:57:233585 LoadTimingInfo load_timing_info;
3586 // CONNECT requests and responses are handled at the connect job level, so
3587 // the transaction does not yet have a connection.
3588 EXPECT_FALSE(trans->GetLoadTimingInfo(&load_timing_info));
3589
[email protected]49639fa2011-12-20 23:22:413590 TestCompletionCallback callback2;
[email protected]2d2697f92009-02-18 21:00:323591
mmenked39192ee2015-12-09 00:57:233592 rv =
3593 trans->RestartWithAuth(AuthCredentials(kFoo, kBar), callback2.callback());
robpercival214763f2016-07-01 23:27:013594 EXPECT_THAT(callback2.GetResult(rv), IsOk());
[email protected]2d2697f92009-02-18 21:00:323595
[email protected]2d2697f92009-02-18 21:00:323596 EXPECT_TRUE(response->headers->IsKeepAlive());
mmenked39192ee2015-12-09 00:57:233597 EXPECT_EQ(200, response->headers->response_code());
3598 EXPECT_EQ(5, response->headers->GetContentLength());
[email protected]1c773ea12009-04-28 19:58:423599 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
[email protected]e772db3f2010-07-12 18:11:133600
mmenked39192ee2015-12-09 00:57:233601 // The password prompt info should not be set.
3602 EXPECT_FALSE(response->auth_challenge);
3603
3604 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
3605 TestLoadTimingNotReusedWithPac(load_timing_info,
3606 CONNECT_TIMING_HAS_SSL_TIMES);
3607
3608 trans.reset();
[email protected]102e27c2011-02-23 01:01:313609 session->CloseAllConnections();
[email protected]2d2697f92009-02-18 21:00:323610}
3611
mmenkee71e15332015-10-07 16:39:543612// Test the case a proxy closes a socket while the challenge body is being
3613// drained.
bncd16676a2016-07-20 16:23:013614TEST_F(HttpNetworkTransactionTest, BasicAuthProxyKeepAliveHangupDuringBody) {
mmenkee71e15332015-10-07 16:39:543615 HttpRequestInfo request;
3616 request.method = "GET";
3617 request.url = GURL("https://www.example.org/");
3618 // Ensure that proxy authentication is attempted even
3619 // when the no authentication data flag is set.
3620 request.load_flags = LOAD_DO_NOT_SEND_AUTH_DATA;
3621
3622 // Configure against proxy server "myproxy:70".
3623 session_deps_.proxy_service = ProxyService::CreateFixed("myproxy:70");
danakj1fd259a02016-04-16 03:17:093624 std::unique_ptr<HttpNetworkSession> session = CreateSession(&session_deps_);
mmenkee71e15332015-10-07 16:39:543625
bnc691fda62016-08-12 00:43:163626 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
mmenkee71e15332015-10-07 16:39:543627
3628 // Since we have proxy, should try to establish tunnel.
3629 MockWrite data_writes1[] = {
3630 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:173631 "Host: www.example.org:443\r\n"
mmenkee71e15332015-10-07 16:39:543632 "Proxy-Connection: keep-alive\r\n\r\n"),
3633 };
3634
3635 // The proxy responds to the connect with a 407, using a persistent
3636 // connection.
3637 MockRead data_reads1[] = {
3638 // No credentials.
3639 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
3640 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
3641 MockRead("Content-Length: 10\r\n\r\n"), MockRead("spam!"),
3642 // Server hands up in the middle of the body.
3643 MockRead(ASYNC, ERR_CONNECTION_CLOSED),
3644 };
3645
3646 MockWrite data_writes2[] = {
bnc691fda62016-08-12 00:43:163647 // After calling trans.RestartWithAuth(), this is the request we should
mmenkee71e15332015-10-07 16:39:543648 // be issuing -- the final header line contains the credentials.
3649 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:173650 "Host: www.example.org:443\r\n"
mmenkee71e15332015-10-07 16:39:543651 "Proxy-Connection: keep-alive\r\n"
3652 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
3653
3654 MockWrite("GET / HTTP/1.1\r\n"
3655 "Host: www.example.org\r\n"
3656 "Connection: keep-alive\r\n\r\n"),
3657 };
3658
3659 MockRead data_reads2[] = {
3660 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
3661
3662 MockRead("HTTP/1.1 200 OK\r\n"),
3663 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
3664 MockRead("Content-Length: 5\r\n\r\n"),
3665 MockRead(SYNCHRONOUS, "hello"),
3666 };
3667
3668 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
3669 data_writes1, arraysize(data_writes1));
3670 session_deps_.socket_factory->AddSocketDataProvider(&data1);
3671 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
3672 data_writes2, arraysize(data_writes2));
3673 session_deps_.socket_factory->AddSocketDataProvider(&data2);
3674 SSLSocketDataProvider ssl(ASYNC, OK);
3675 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
3676
3677 TestCompletionCallback callback;
3678
tfarina42834112016-09-22 13:38:203679 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:013680 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenkee71e15332015-10-07 16:39:543681
bnc691fda62016-08-12 00:43:163682 const HttpResponseInfo* response = trans.GetResponseInfo();
mmenkee71e15332015-10-07 16:39:543683 ASSERT_TRUE(response);
3684 ASSERT_TRUE(response->headers);
3685 EXPECT_TRUE(response->headers->IsKeepAlive());
3686 EXPECT_EQ(407, response->headers->response_code());
3687 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
3688
bnc691fda62016-08-12 00:43:163689 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar), callback.callback());
robpercival214763f2016-07-01 23:27:013690 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenkee71e15332015-10-07 16:39:543691
bnc691fda62016-08-12 00:43:163692 response = trans.GetResponseInfo();
mmenkee71e15332015-10-07 16:39:543693 ASSERT_TRUE(response);
3694 ASSERT_TRUE(response->headers);
3695 EXPECT_TRUE(response->headers->IsKeepAlive());
3696 EXPECT_EQ(200, response->headers->response_code());
3697 std::string body;
bnc691fda62016-08-12 00:43:163698 EXPECT_THAT(ReadTransaction(&trans, &body), IsOk());
mmenkee71e15332015-10-07 16:39:543699 EXPECT_EQ("hello", body);
3700}
3701
[email protected]a8e9b162009-03-12 00:06:443702// Test that we don't read the response body when we fail to establish a tunnel,
3703// even if the user cancels the proxy's auth attempt.
bncd16676a2016-07-20 16:23:013704TEST_F(HttpNetworkTransactionTest, BasicAuthProxyCancelTunnel) {
[email protected]cb9bf6ca2011-01-28 13:15:273705 HttpRequestInfo request;
3706 request.method = "GET";
bncce36dca22015-04-21 22:11:233707 request.url = GURL("https://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:273708
[email protected]a8e9b162009-03-12 00:06:443709 // Configure against proxy server "myproxy:70".
rdsmith82957ad2015-09-16 19:42:033710 session_deps_.proxy_service = ProxyService::CreateFixed("myproxy:70");
[email protected]a8e9b162009-03-12 00:06:443711
danakj1fd259a02016-04-16 03:17:093712 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]a8e9b162009-03-12 00:06:443713
bnc691fda62016-08-12 00:43:163714 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]a8e9b162009-03-12 00:06:443715
[email protected]a8e9b162009-03-12 00:06:443716 // Since we have proxy, should try to establish tunnel.
3717 MockWrite data_writes[] = {
rsleevidb16bb02015-11-12 23:47:173718 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
3719 "Host: www.example.org:443\r\n"
3720 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]a8e9b162009-03-12 00:06:443721 };
3722
3723 // The proxy responds to the connect with a 407.
3724 MockRead data_reads[] = {
ttuttle7933c112015-01-06 00:55:243725 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
3726 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
3727 MockRead("Content-Length: 10\r\n\r\n"),
mmenked39192ee2015-12-09 00:57:233728 MockRead("0123456789"),
ttuttle7933c112015-01-06 00:55:243729 MockRead(SYNCHRONOUS, ERR_UNEXPECTED),
[email protected]a8e9b162009-03-12 00:06:443730 };
3731
[email protected]31a2bfe2010-02-09 08:03:393732 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
3733 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:073734 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]a8e9b162009-03-12 00:06:443735
[email protected]49639fa2011-12-20 23:22:413736 TestCompletionCallback callback;
[email protected]a8e9b162009-03-12 00:06:443737
tfarina42834112016-09-22 13:38:203738 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:013739 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]a8e9b162009-03-12 00:06:443740
3741 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:013742 EXPECT_THAT(rv, IsOk());
[email protected]a8e9b162009-03-12 00:06:443743
bnc691fda62016-08-12 00:43:163744 const HttpResponseInfo* response = trans.GetResponseInfo();
ttuttle7933c112015-01-06 00:55:243745 ASSERT_TRUE(response);
3746 ASSERT_TRUE(response->headers);
[email protected]a8e9b162009-03-12 00:06:443747 EXPECT_TRUE(response->headers->IsKeepAlive());
3748 EXPECT_EQ(407, response->headers->response_code());
[email protected]1c773ea12009-04-28 19:58:423749 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
[email protected]a8e9b162009-03-12 00:06:443750
3751 std::string response_data;
bnc691fda62016-08-12 00:43:163752 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:013753 EXPECT_THAT(rv, IsError(ERR_TUNNEL_CONNECTION_FAILED));
[email protected]e60e47a2010-07-14 03:37:183754
3755 // Flush the idle socket before the HttpNetworkTransaction goes out of scope.
[email protected]102e27c2011-02-23 01:01:313756 session->CloseAllConnections();
[email protected]a8e9b162009-03-12 00:06:443757}
3758
ttuttle7933c112015-01-06 00:55:243759// Test that we don't pass extraneous headers from the proxy's response to the
3760// caller when the proxy responds to CONNECT with 407.
bncd16676a2016-07-20 16:23:013761TEST_F(HttpNetworkTransactionTest, SanitizeProxyAuthHeaders) {
ttuttle7933c112015-01-06 00:55:243762 HttpRequestInfo request;
3763 request.method = "GET";
bncce36dca22015-04-21 22:11:233764 request.url = GURL("https://www.example.org/");
ttuttle7933c112015-01-06 00:55:243765
3766 // Configure against proxy server "myproxy:70".
rdsmith82957ad2015-09-16 19:42:033767 session_deps_.proxy_service = ProxyService::CreateFixed("myproxy:70");
ttuttle7933c112015-01-06 00:55:243768
danakj1fd259a02016-04-16 03:17:093769 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
ttuttle7933c112015-01-06 00:55:243770
bnc691fda62016-08-12 00:43:163771 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
ttuttle7933c112015-01-06 00:55:243772
3773 // Since we have proxy, should try to establish tunnel.
3774 MockWrite data_writes[] = {
rsleevidb16bb02015-11-12 23:47:173775 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
3776 "Host: www.example.org:443\r\n"
3777 "Proxy-Connection: keep-alive\r\n\r\n"),
ttuttle7933c112015-01-06 00:55:243778 };
3779
3780 // The proxy responds to the connect with a 407.
3781 MockRead data_reads[] = {
3782 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
3783 MockRead("X-Foo: bar\r\n"),
3784 MockRead("Set-Cookie: foo=bar\r\n"),
3785 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
3786 MockRead("Content-Length: 10\r\n\r\n"),
mmenked39192ee2015-12-09 00:57:233787 MockRead(SYNCHRONOUS, ERR_UNEXPECTED),
ttuttle7933c112015-01-06 00:55:243788 };
3789
3790 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
3791 arraysize(data_writes));
3792 session_deps_.socket_factory->AddSocketDataProvider(&data);
3793
3794 TestCompletionCallback callback;
3795
tfarina42834112016-09-22 13:38:203796 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:013797 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
ttuttle7933c112015-01-06 00:55:243798
3799 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:013800 EXPECT_THAT(rv, IsOk());
ttuttle7933c112015-01-06 00:55:243801
bnc691fda62016-08-12 00:43:163802 const HttpResponseInfo* response = trans.GetResponseInfo();
ttuttle7933c112015-01-06 00:55:243803 ASSERT_TRUE(response);
3804 ASSERT_TRUE(response->headers);
3805 EXPECT_TRUE(response->headers->IsKeepAlive());
3806 EXPECT_EQ(407, response->headers->response_code());
3807 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
3808 EXPECT_FALSE(response->headers->HasHeader("X-Foo"));
3809 EXPECT_FALSE(response->headers->HasHeader("Set-Cookie"));
3810
3811 std::string response_data;
bnc691fda62016-08-12 00:43:163812 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:013813 EXPECT_THAT(rv, IsError(ERR_TUNNEL_CONNECTION_FAILED));
ttuttle7933c112015-01-06 00:55:243814
3815 // Flush the idle socket before the HttpNetworkTransaction goes out of scope.
3816 session->CloseAllConnections();
3817}
3818
[email protected]8fdbcd22010-05-05 02:54:523819// Test when a server (non-proxy) returns a 407 (proxy-authenticate).
3820// The request should fail with ERR_UNEXPECTED_PROXY_AUTH.
bncd16676a2016-07-20 16:23:013821TEST_F(HttpNetworkTransactionTest, UnexpectedProxyAuth) {
[email protected]8fdbcd22010-05-05 02:54:523822 HttpRequestInfo request;
3823 request.method = "GET";
bncce36dca22015-04-21 22:11:233824 request.url = GURL("http://www.example.org/");
[email protected]8fdbcd22010-05-05 02:54:523825
[email protected]cb9bf6ca2011-01-28 13:15:273826 // We are using a DIRECT connection (i.e. no proxy) for this session.
danakj1fd259a02016-04-16 03:17:093827 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:163828 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:273829
[email protected]8fdbcd22010-05-05 02:54:523830 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:233831 MockWrite(
3832 "GET / HTTP/1.1\r\n"
3833 "Host: www.example.org\r\n"
3834 "Connection: keep-alive\r\n\r\n"),
[email protected]8fdbcd22010-05-05 02:54:523835 };
3836
3837 MockRead data_reads1[] = {
3838 MockRead("HTTP/1.0 407 Proxy Auth required\r\n"),
3839 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
3840 // Large content-length -- won't matter, as connection will be reset.
3841 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:063842 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]8fdbcd22010-05-05 02:54:523843 };
3844
3845 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
3846 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:073847 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8fdbcd22010-05-05 02:54:523848
[email protected]49639fa2011-12-20 23:22:413849 TestCompletionCallback callback;
[email protected]8fdbcd22010-05-05 02:54:523850
tfarina42834112016-09-22 13:38:203851 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:013852 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]8fdbcd22010-05-05 02:54:523853
3854 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:013855 EXPECT_THAT(rv, IsError(ERR_UNEXPECTED_PROXY_AUTH));
[email protected]8fdbcd22010-05-05 02:54:523856}
3857
[email protected]7a67a8152010-11-05 18:31:103858// Tests when an HTTPS server (non-proxy) returns a 407 (proxy-authentication)
3859// through a non-authenticating proxy. The request should fail with
3860// ERR_UNEXPECTED_PROXY_AUTH.
3861// Note that it is impossible to detect if an HTTP server returns a 407 through
3862// a non-authenticating proxy - there is nothing to indicate whether the
3863// response came from the proxy or the server, so it is treated as if the proxy
3864// issued the challenge.
bncd16676a2016-07-20 16:23:013865TEST_F(HttpNetworkTransactionTest, HttpsServerRequestsProxyAuthThroughProxy) {
[email protected]cb9bf6ca2011-01-28 13:15:273866 HttpRequestInfo request;
3867 request.method = "GET";
bncce36dca22015-04-21 22:11:233868 request.url = GURL("https://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:273869
rdsmith82957ad2015-09-16 19:42:033870 session_deps_.proxy_service = ProxyService::CreateFixed("myproxy:70");
vishal.b62985ca92015-04-17 08:45:513871 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:073872 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:093873 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]7a67a8152010-11-05 18:31:103874
[email protected]7a67a8152010-11-05 18:31:103875 // Since we have proxy, should try to establish tunnel.
3876 MockWrite data_writes1[] = {
rsleevidb16bb02015-11-12 23:47:173877 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
3878 "Host: www.example.org:443\r\n"
3879 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]7a67a8152010-11-05 18:31:103880
rsleevidb16bb02015-11-12 23:47:173881 MockWrite("GET / HTTP/1.1\r\n"
3882 "Host: www.example.org\r\n"
3883 "Connection: keep-alive\r\n\r\n"),
[email protected]7a67a8152010-11-05 18:31:103884 };
3885
3886 MockRead data_reads1[] = {
3887 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
3888
3889 MockRead("HTTP/1.1 407 Unauthorized\r\n"),
3890 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
3891 MockRead("\r\n"),
[email protected]8ddf8322012-02-23 18:08:063892 MockRead(SYNCHRONOUS, OK),
[email protected]7a67a8152010-11-05 18:31:103893 };
3894
3895 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
3896 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:073897 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8ddf8322012-02-23 18:08:063898 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:073899 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]7a67a8152010-11-05 18:31:103900
[email protected]49639fa2011-12-20 23:22:413901 TestCompletionCallback callback1;
[email protected]7a67a8152010-11-05 18:31:103902
bnc691fda62016-08-12 00:43:163903 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]7a67a8152010-11-05 18:31:103904
bnc691fda62016-08-12 00:43:163905 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:013906 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]7a67a8152010-11-05 18:31:103907
3908 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:013909 EXPECT_THAT(rv, IsError(ERR_UNEXPECTED_PROXY_AUTH));
mmenke43758e62015-05-04 21:09:463910 TestNetLogEntry::List entries;
[email protected]b2fcd0e2010-12-01 15:19:403911 log.GetEntries(&entries);
[email protected]7a67a8152010-11-05 18:31:103912 size_t pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:003913 entries, 0, NetLogEventType::HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
3914 NetLogEventPhase::NONE);
[email protected]7a67a8152010-11-05 18:31:103915 ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:403916 entries, pos,
mikecirone8b85c432016-09-08 19:11:003917 NetLogEventType::HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
3918 NetLogEventPhase::NONE);
[email protected]7a67a8152010-11-05 18:31:103919}
[email protected]2df19bb2010-08-25 20:13:463920
mmenke2a1781d2015-10-07 19:25:333921// Test a proxy auth scheme that allows default credentials and a proxy server
3922// that uses non-persistent connections.
bncd16676a2016-07-20 16:23:013923TEST_F(HttpNetworkTransactionTest,
mmenke2a1781d2015-10-07 19:25:333924 AuthAllowsDefaultCredentialsTunnelConnectionClose) {
3925 HttpRequestInfo request;
3926 request.method = "GET";
3927 request.url = GURL("https://www.example.org/");
3928
3929 // Configure against proxy server "myproxy:70".
3930 session_deps_.proxy_service =
3931 ProxyService::CreateFixedFromPacResult("PROXY myproxy:70");
3932
Jeremy Roman0579ed62017-08-29 15:56:193933 auto auth_handler_factory = std::make_unique<HttpAuthHandlerMock::Factory>();
mmenke2a1781d2015-10-07 19:25:333934 auth_handler_factory->set_do_init_from_challenge(true);
Jeremy Roman0579ed62017-08-29 15:56:193935 auto mock_handler = std::make_unique<HttpAuthHandlerMock>();
mmenke2a1781d2015-10-07 19:25:333936 mock_handler->set_allows_default_credentials(true);
3937 auth_handler_factory->AddMockHandler(mock_handler.release(),
3938 HttpAuth::AUTH_PROXY);
dchengc7eeda422015-12-26 03:56:483939 session_deps_.http_auth_handler_factory = std::move(auth_handler_factory);
mmenke2a1781d2015-10-07 19:25:333940
3941 // Add NetLog just so can verify load timing information gets a NetLog ID.
3942 NetLog net_log;
3943 session_deps_.net_log = &net_log;
danakj1fd259a02016-04-16 03:17:093944 std::unique_ptr<HttpNetworkSession> session = CreateSession(&session_deps_);
mmenke2a1781d2015-10-07 19:25:333945
3946 // Since we have proxy, should try to establish tunnel.
3947 MockWrite data_writes1[] = {
3948 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:173949 "Host: www.example.org:443\r\n"
mmenke2a1781d2015-10-07 19:25:333950 "Proxy-Connection: keep-alive\r\n\r\n"),
3951 };
3952
3953 // The proxy responds to the connect with a 407, using a non-persistent
3954 // connection.
3955 MockRead data_reads1[] = {
3956 // No credentials.
3957 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
3958 MockRead("Proxy-Authenticate: Mock\r\n"),
3959 MockRead("Proxy-Connection: close\r\n\r\n"),
3960 };
3961
3962 // Since the first connection couldn't be reused, need to establish another
3963 // once given credentials.
3964 MockWrite data_writes2[] = {
3965 // After calling trans->RestartWithAuth(), this is the request we should
3966 // be issuing -- the final header line contains the credentials.
3967 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:173968 "Host: www.example.org:443\r\n"
mmenke2a1781d2015-10-07 19:25:333969 "Proxy-Connection: keep-alive\r\n"
3970 "Proxy-Authorization: auth_token\r\n\r\n"),
3971
3972 MockWrite("GET / HTTP/1.1\r\n"
3973 "Host: www.example.org\r\n"
3974 "Connection: keep-alive\r\n\r\n"),
3975 };
3976
3977 MockRead data_reads2[] = {
3978 MockRead("HTTP/1.0 200 Connection Established\r\n\r\n"),
3979
3980 MockRead("HTTP/1.1 200 OK\r\n"),
3981 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
3982 MockRead("Content-Length: 5\r\n\r\n"),
3983 MockRead(SYNCHRONOUS, "hello"),
3984 };
3985
3986 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
3987 data_writes1, arraysize(data_writes1));
3988 session_deps_.socket_factory->AddSocketDataProvider(&data1);
3989 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
3990 data_writes2, arraysize(data_writes2));
3991 session_deps_.socket_factory->AddSocketDataProvider(&data2);
3992 SSLSocketDataProvider ssl(ASYNC, OK);
3993 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
3994
bnc87dcefc2017-05-25 12:47:583995 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:193996 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
mmenke2a1781d2015-10-07 19:25:333997
3998 TestCompletionCallback callback;
tfarina42834112016-09-22 13:38:203999 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:014000 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenke2a1781d2015-10-07 19:25:334001
4002 const HttpResponseInfo* response = trans->GetResponseInfo();
4003 ASSERT_TRUE(response);
4004 ASSERT_TRUE(response->headers);
4005 EXPECT_FALSE(response->headers->IsKeepAlive());
4006 EXPECT_EQ(407, response->headers->response_code());
4007 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
4008 EXPECT_TRUE(trans->IsReadyToRestartForAuth());
wezca1070932016-05-26 20:30:524009 EXPECT_FALSE(response->auth_challenge);
mmenke2a1781d2015-10-07 19:25:334010
4011 LoadTimingInfo load_timing_info;
4012 // CONNECT requests and responses are handled at the connect job level, so
4013 // the transaction does not yet have a connection.
4014 EXPECT_FALSE(trans->GetLoadTimingInfo(&load_timing_info));
4015
4016 rv = trans->RestartWithAuth(AuthCredentials(), callback.callback());
robpercival214763f2016-07-01 23:27:014017 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenke2a1781d2015-10-07 19:25:334018 response = trans->GetResponseInfo();
4019 ASSERT_TRUE(response);
4020 ASSERT_TRUE(response->headers);
4021 EXPECT_TRUE(response->headers->IsKeepAlive());
4022 EXPECT_EQ(200, response->headers->response_code());
4023 EXPECT_EQ(5, response->headers->GetContentLength());
4024 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
4025
4026 // The password prompt info should not be set.
4027 EXPECT_FALSE(response->auth_challenge);
4028
4029 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
4030 TestLoadTimingNotReusedWithPac(load_timing_info,
4031 CONNECT_TIMING_HAS_SSL_TIMES);
4032
4033 trans.reset();
4034 session->CloseAllConnections();
4035}
4036
4037// Test a proxy auth scheme that allows default credentials and a proxy server
4038// that hangs up when credentials are initially sent.
bncd16676a2016-07-20 16:23:014039TEST_F(HttpNetworkTransactionTest,
mmenke2a1781d2015-10-07 19:25:334040 AuthAllowsDefaultCredentialsTunnelServerClosesConnection) {
4041 HttpRequestInfo request;
4042 request.method = "GET";
4043 request.url = GURL("https://www.example.org/");
4044
4045 // Configure against proxy server "myproxy:70".
4046 session_deps_.proxy_service =
4047 ProxyService::CreateFixedFromPacResult("PROXY myproxy:70");
4048
Jeremy Roman0579ed62017-08-29 15:56:194049 auto auth_handler_factory = std::make_unique<HttpAuthHandlerMock::Factory>();
mmenke2a1781d2015-10-07 19:25:334050 auth_handler_factory->set_do_init_from_challenge(true);
Jeremy Roman0579ed62017-08-29 15:56:194051 auto mock_handler = std::make_unique<HttpAuthHandlerMock>();
mmenke2a1781d2015-10-07 19:25:334052 mock_handler->set_allows_default_credentials(true);
4053 auth_handler_factory->AddMockHandler(mock_handler.release(),
4054 HttpAuth::AUTH_PROXY);
dchengc7eeda422015-12-26 03:56:484055 session_deps_.http_auth_handler_factory = std::move(auth_handler_factory);
mmenke2a1781d2015-10-07 19:25:334056
4057 // Add NetLog just so can verify load timing information gets a NetLog ID.
4058 NetLog net_log;
4059 session_deps_.net_log = &net_log;
danakj1fd259a02016-04-16 03:17:094060 std::unique_ptr<HttpNetworkSession> session = CreateSession(&session_deps_);
mmenke2a1781d2015-10-07 19:25:334061
4062 // Should try to establish tunnel.
4063 MockWrite data_writes1[] = {
4064 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:174065 "Host: www.example.org:443\r\n"
mmenke2a1781d2015-10-07 19:25:334066 "Proxy-Connection: keep-alive\r\n\r\n"),
4067
4068 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:174069 "Host: www.example.org:443\r\n"
mmenke2a1781d2015-10-07 19:25:334070 "Proxy-Connection: keep-alive\r\n"
4071 "Proxy-Authorization: auth_token\r\n\r\n"),
4072 };
4073
4074 // The proxy responds to the connect with a 407, using a non-persistent
4075 // connection.
4076 MockRead data_reads1[] = {
4077 // No credentials.
4078 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
4079 MockRead("Proxy-Authenticate: Mock\r\n\r\n"),
4080 MockRead(SYNCHRONOUS, ERR_CONNECTION_CLOSED),
4081 };
4082
4083 // Since the first connection was closed, need to establish another once given
4084 // credentials.
4085 MockWrite data_writes2[] = {
4086 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:174087 "Host: www.example.org:443\r\n"
mmenke2a1781d2015-10-07 19:25:334088 "Proxy-Connection: keep-alive\r\n"
4089 "Proxy-Authorization: auth_token\r\n\r\n"),
4090
4091 MockWrite("GET / HTTP/1.1\r\n"
4092 "Host: www.example.org\r\n"
4093 "Connection: keep-alive\r\n\r\n"),
4094 };
4095
4096 MockRead data_reads2[] = {
4097 MockRead("HTTP/1.0 200 Connection Established\r\n\r\n"),
4098
4099 MockRead("HTTP/1.1 200 OK\r\n"),
4100 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
4101 MockRead("Content-Length: 5\r\n\r\n"),
4102 MockRead(SYNCHRONOUS, "hello"),
4103 };
4104
4105 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
4106 data_writes1, arraysize(data_writes1));
4107 session_deps_.socket_factory->AddSocketDataProvider(&data1);
4108 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
4109 data_writes2, arraysize(data_writes2));
4110 session_deps_.socket_factory->AddSocketDataProvider(&data2);
4111 SSLSocketDataProvider ssl(ASYNC, OK);
4112 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
4113
bnc87dcefc2017-05-25 12:47:584114 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:194115 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
mmenke2a1781d2015-10-07 19:25:334116
4117 TestCompletionCallback callback;
tfarina42834112016-09-22 13:38:204118 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:014119 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenke2a1781d2015-10-07 19:25:334120
4121 const HttpResponseInfo* response = trans->GetResponseInfo();
4122 ASSERT_TRUE(response);
4123 ASSERT_TRUE(response->headers);
4124 EXPECT_TRUE(response->headers->IsKeepAlive());
4125 EXPECT_EQ(407, response->headers->response_code());
4126 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
4127 EXPECT_TRUE(trans->IsReadyToRestartForAuth());
4128 EXPECT_FALSE(response->auth_challenge);
4129
4130 LoadTimingInfo load_timing_info;
4131 // CONNECT requests and responses are handled at the connect job level, so
4132 // the transaction does not yet have a connection.
4133 EXPECT_FALSE(trans->GetLoadTimingInfo(&load_timing_info));
4134
4135 rv = trans->RestartWithAuth(AuthCredentials(), callback.callback());
robpercival214763f2016-07-01 23:27:014136 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenke2a1781d2015-10-07 19:25:334137
4138 response = trans->GetResponseInfo();
4139 ASSERT_TRUE(response);
4140 ASSERT_TRUE(response->headers);
4141 EXPECT_TRUE(response->headers->IsKeepAlive());
4142 EXPECT_EQ(200, response->headers->response_code());
4143 EXPECT_EQ(5, response->headers->GetContentLength());
4144 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
4145
4146 // The password prompt info should not be set.
wezca1070932016-05-26 20:30:524147 EXPECT_FALSE(response->auth_challenge);
mmenke2a1781d2015-10-07 19:25:334148
4149 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
4150 TestLoadTimingNotReusedWithPac(load_timing_info,
4151 CONNECT_TIMING_HAS_SSL_TIMES);
4152
4153 trans.reset();
4154 session->CloseAllConnections();
4155}
4156
4157// Test a proxy auth scheme that allows default credentials and a proxy server
4158// that hangs up when credentials are initially sent, and hangs up again when
4159// they are retried.
bncd16676a2016-07-20 16:23:014160TEST_F(HttpNetworkTransactionTest,
mmenke2a1781d2015-10-07 19:25:334161 AuthAllowsDefaultCredentialsTunnelServerClosesConnectionTwice) {
4162 HttpRequestInfo request;
4163 request.method = "GET";
4164 request.url = GURL("https://www.example.org/");
4165
4166 // Configure against proxy server "myproxy:70".
4167 session_deps_.proxy_service =
4168 ProxyService::CreateFixedFromPacResult("PROXY myproxy:70");
4169
Jeremy Roman0579ed62017-08-29 15:56:194170 auto auth_handler_factory = std::make_unique<HttpAuthHandlerMock::Factory>();
mmenke2a1781d2015-10-07 19:25:334171 auth_handler_factory->set_do_init_from_challenge(true);
Jeremy Roman0579ed62017-08-29 15:56:194172 auto mock_handler = std::make_unique<HttpAuthHandlerMock>();
mmenke2a1781d2015-10-07 19:25:334173 mock_handler->set_allows_default_credentials(true);
4174 auth_handler_factory->AddMockHandler(mock_handler.release(),
4175 HttpAuth::AUTH_PROXY);
dchengc7eeda422015-12-26 03:56:484176 session_deps_.http_auth_handler_factory = std::move(auth_handler_factory);
mmenke2a1781d2015-10-07 19:25:334177
4178 // Add NetLog just so can verify load timing information gets a NetLog ID.
4179 NetLog net_log;
4180 session_deps_.net_log = &net_log;
danakj1fd259a02016-04-16 03:17:094181 std::unique_ptr<HttpNetworkSession> session = CreateSession(&session_deps_);
mmenke2a1781d2015-10-07 19:25:334182
4183 // Should try to establish tunnel.
4184 MockWrite data_writes1[] = {
4185 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:174186 "Host: www.example.org:443\r\n"
mmenke2a1781d2015-10-07 19:25:334187 "Proxy-Connection: keep-alive\r\n\r\n"),
4188
4189 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:174190 "Host: www.example.org:443\r\n"
mmenke2a1781d2015-10-07 19:25:334191 "Proxy-Connection: keep-alive\r\n"
4192 "Proxy-Authorization: auth_token\r\n\r\n"),
4193 };
4194
4195 // The proxy responds to the connect with a 407, and then hangs up after the
4196 // second request is sent.
4197 MockRead data_reads1[] = {
4198 // No credentials.
4199 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
4200 MockRead("Content-Length: 0\r\n"),
4201 MockRead("Proxy-Connection: keep-alive\r\n"),
4202 MockRead("Proxy-Authenticate: Mock\r\n\r\n"),
4203 MockRead(SYNCHRONOUS, ERR_CONNECTION_CLOSED),
4204 };
4205
4206 // HttpNetworkTransaction sees a reused connection that was closed with
4207 // ERR_CONNECTION_CLOSED, realized it might have been a race, so retries the
4208 // request.
4209 MockWrite data_writes2[] = {
4210 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:174211 "Host: www.example.org:443\r\n"
mmenke2a1781d2015-10-07 19:25:334212 "Proxy-Connection: keep-alive\r\n\r\n"),
4213 };
4214
4215 // The proxy, having had more than enough of us, just hangs up.
4216 MockRead data_reads2[] = {
4217 // No credentials.
4218 MockRead(SYNCHRONOUS, ERR_CONNECTION_CLOSED),
4219 };
4220
4221 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
4222 data_writes1, arraysize(data_writes1));
4223 session_deps_.socket_factory->AddSocketDataProvider(&data1);
4224 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
4225 data_writes2, arraysize(data_writes2));
4226 session_deps_.socket_factory->AddSocketDataProvider(&data2);
4227
bnc87dcefc2017-05-25 12:47:584228 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:194229 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
mmenke2a1781d2015-10-07 19:25:334230
4231 TestCompletionCallback callback;
tfarina42834112016-09-22 13:38:204232 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:014233 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenke2a1781d2015-10-07 19:25:334234
4235 const HttpResponseInfo* response = trans->GetResponseInfo();
4236 ASSERT_TRUE(response);
4237 ASSERT_TRUE(response->headers);
4238 EXPECT_TRUE(response->headers->IsKeepAlive());
4239 EXPECT_EQ(407, response->headers->response_code());
4240 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
4241 EXPECT_TRUE(trans->IsReadyToRestartForAuth());
4242 EXPECT_FALSE(response->auth_challenge);
4243
4244 LoadTimingInfo load_timing_info;
4245 EXPECT_FALSE(trans->GetLoadTimingInfo(&load_timing_info));
4246
4247 rv = trans->RestartWithAuth(AuthCredentials(), callback.callback());
robpercival214763f2016-07-01 23:27:014248 EXPECT_THAT(callback.GetResult(rv), IsError(ERR_EMPTY_RESPONSE));
mmenke2a1781d2015-10-07 19:25:334249
4250 trans.reset();
4251 session->CloseAllConnections();
4252}
4253
4254// Test a proxy auth scheme that allows default credentials and a proxy server
4255// that hangs up when credentials are initially sent, and sends a challenge
4256// again they are retried.
bncd16676a2016-07-20 16:23:014257TEST_F(HttpNetworkTransactionTest,
mmenke2a1781d2015-10-07 19:25:334258 AuthAllowsDefaultCredentialsTunnelServerChallengesTwice) {
4259 HttpRequestInfo request;
4260 request.method = "GET";
4261 request.url = GURL("https://www.example.org/");
4262
4263 // Configure against proxy server "myproxy:70".
4264 session_deps_.proxy_service =
4265 ProxyService::CreateFixedFromPacResult("PROXY myproxy:70");
4266
Jeremy Roman0579ed62017-08-29 15:56:194267 auto auth_handler_factory = std::make_unique<HttpAuthHandlerMock::Factory>();
mmenke2a1781d2015-10-07 19:25:334268 auth_handler_factory->set_do_init_from_challenge(true);
Jeremy Roman0579ed62017-08-29 15:56:194269 auto mock_handler = std::make_unique<HttpAuthHandlerMock>();
mmenke2a1781d2015-10-07 19:25:334270 mock_handler->set_allows_default_credentials(true);
4271 auth_handler_factory->AddMockHandler(mock_handler.release(),
4272 HttpAuth::AUTH_PROXY);
4273 // Add another handler for the second challenge. It supports default
4274 // credentials, but they shouldn't be used, since they were already tried.
Jeremy Roman0579ed62017-08-29 15:56:194275 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);
dchengc7eeda422015-12-26 03:56:484279 session_deps_.http_auth_handler_factory = std::move(auth_handler_factory);
mmenke2a1781d2015-10-07 19:25:334280
4281 // Add NetLog just so can verify load timing information gets a NetLog ID.
4282 NetLog net_log;
4283 session_deps_.net_log = &net_log;
danakj1fd259a02016-04-16 03:17:094284 std::unique_ptr<HttpNetworkSession> session = CreateSession(&session_deps_);
mmenke2a1781d2015-10-07 19:25:334285
4286 // Should try to establish tunnel.
4287 MockWrite data_writes1[] = {
4288 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:174289 "Host: www.example.org:443\r\n"
mmenke2a1781d2015-10-07 19:25:334290 "Proxy-Connection: keep-alive\r\n\r\n"),
4291 };
4292
4293 // The proxy responds to the connect with a 407, using a non-persistent
4294 // connection.
4295 MockRead data_reads1[] = {
4296 // No credentials.
4297 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
4298 MockRead("Proxy-Authenticate: Mock\r\n"),
4299 MockRead("Proxy-Connection: close\r\n\r\n"),
4300 };
4301
4302 // Since the first connection was closed, need to establish another once given
4303 // credentials.
4304 MockWrite data_writes2[] = {
4305 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:174306 "Host: www.example.org:443\r\n"
mmenke2a1781d2015-10-07 19:25:334307 "Proxy-Connection: keep-alive\r\n"
4308 "Proxy-Authorization: auth_token\r\n\r\n"),
4309 };
4310
4311 MockRead data_reads2[] = {
4312 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
4313 MockRead("Proxy-Authenticate: Mock\r\n"),
4314 MockRead("Proxy-Connection: close\r\n\r\n"),
4315 };
4316
4317 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
4318 data_writes1, arraysize(data_writes1));
4319 session_deps_.socket_factory->AddSocketDataProvider(&data1);
4320 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
4321 data_writes2, arraysize(data_writes2));
4322 session_deps_.socket_factory->AddSocketDataProvider(&data2);
4323 SSLSocketDataProvider ssl(ASYNC, OK);
4324 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
4325
bnc87dcefc2017-05-25 12:47:584326 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:194327 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
mmenke2a1781d2015-10-07 19:25:334328
4329 TestCompletionCallback callback;
tfarina42834112016-09-22 13:38:204330 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:014331 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenke2a1781d2015-10-07 19:25:334332
4333 const HttpResponseInfo* response = trans->GetResponseInfo();
4334 ASSERT_TRUE(response);
4335 ASSERT_TRUE(response->headers);
4336 EXPECT_EQ(407, response->headers->response_code());
4337 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
4338 EXPECT_TRUE(trans->IsReadyToRestartForAuth());
4339 EXPECT_FALSE(response->auth_challenge);
4340
4341 LoadTimingInfo load_timing_info;
4342 EXPECT_FALSE(trans->GetLoadTimingInfo(&load_timing_info));
4343
4344 rv = trans->RestartWithAuth(AuthCredentials(), callback.callback());
robpercival214763f2016-07-01 23:27:014345 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenke2a1781d2015-10-07 19:25:334346 response = trans->GetResponseInfo();
4347 ASSERT_TRUE(response);
4348 ASSERT_TRUE(response->headers);
4349 EXPECT_EQ(407, response->headers->response_code());
4350 EXPECT_FALSE(trans->IsReadyToRestartForAuth());
4351 EXPECT_TRUE(response->auth_challenge);
4352
4353 trans.reset();
4354 session->CloseAllConnections();
4355}
4356
asankae2257db2016-10-11 22:03:164357// A more nuanced test than GenerateAuthToken test which asserts that
4358// ERR_INVALID_AUTH_CREDENTIALS does not cause the auth scheme to be
4359// unnecessarily invalidated, and that if the server co-operates, the
4360// authentication handshake can continue with the same scheme but with a
4361// different identity.
4362TEST_F(HttpNetworkTransactionTest, NonPermanentGenerateAuthTokenError) {
4363 HttpRequestInfo request;
4364 request.method = "GET";
4365 request.url = GURL("http://www.example.org/");
4366
Jeremy Roman0579ed62017-08-29 15:56:194367 auto auth_handler_factory = std::make_unique<HttpAuthHandlerMock::Factory>();
asankae2257db2016-10-11 22:03:164368 auth_handler_factory->set_do_init_from_challenge(true);
4369
4370 // First handler. Uses default credentials, but barfs at generate auth token.
Jeremy Roman0579ed62017-08-29 15:56:194371 auto mock_handler = std::make_unique<HttpAuthHandlerMock>();
asankae2257db2016-10-11 22:03:164372 mock_handler->set_allows_default_credentials(true);
4373 mock_handler->set_allows_explicit_credentials(true);
4374 mock_handler->set_connection_based(true);
4375 mock_handler->SetGenerateExpectation(true, ERR_INVALID_AUTH_CREDENTIALS);
4376 auth_handler_factory->AddMockHandler(mock_handler.release(),
4377 HttpAuth::AUTH_SERVER);
4378
4379 // Add another handler for the second challenge. It supports default
4380 // credentials, but they shouldn't be used, since they were already tried.
Jeremy Roman0579ed62017-08-29 15:56:194381 mock_handler = std::make_unique<HttpAuthHandlerMock>();
asankae2257db2016-10-11 22:03:164382 mock_handler->set_allows_default_credentials(true);
4383 mock_handler->set_allows_explicit_credentials(true);
4384 mock_handler->set_connection_based(true);
4385 auth_handler_factory->AddMockHandler(mock_handler.release(),
4386 HttpAuth::AUTH_SERVER);
4387 session_deps_.http_auth_handler_factory = std::move(auth_handler_factory);
4388
4389 std::unique_ptr<HttpNetworkSession> session = CreateSession(&session_deps_);
4390
4391 MockWrite data_writes1[] = {
4392 MockWrite("GET / HTTP/1.1\r\n"
4393 "Host: www.example.org\r\n"
4394 "Connection: keep-alive\r\n\r\n"),
4395 };
4396
4397 MockRead data_reads1[] = {
4398 MockRead("HTTP/1.1 401 Authentication Required\r\n"
4399 "WWW-Authenticate: Mock\r\n"
4400 "Connection: keep-alive\r\n\r\n"),
4401 };
4402
4403 // Identical to data_writes1[]. The AuthHandler encounters a
4404 // ERR_INVALID_AUTH_CREDENTIALS during the GenerateAuthToken stage, so the
4405 // transaction procceds without an authorization header.
4406 MockWrite data_writes2[] = {
4407 MockWrite("GET / HTTP/1.1\r\n"
4408 "Host: www.example.org\r\n"
4409 "Connection: keep-alive\r\n\r\n"),
4410 };
4411
4412 MockRead data_reads2[] = {
4413 MockRead("HTTP/1.1 401 Authentication Required\r\n"
4414 "WWW-Authenticate: Mock\r\n"
4415 "Connection: keep-alive\r\n\r\n"),
4416 };
4417
4418 MockWrite data_writes3[] = {
4419 MockWrite("GET / HTTP/1.1\r\n"
4420 "Host: www.example.org\r\n"
4421 "Connection: keep-alive\r\n"
4422 "Authorization: auth_token\r\n\r\n"),
4423 };
4424
4425 MockRead data_reads3[] = {
4426 MockRead("HTTP/1.1 200 OK\r\n"
4427 "Content-Length: 5\r\n"
4428 "Content-Type: text/plain\r\n"
4429 "Connection: keep-alive\r\n\r\n"
4430 "Hello"),
4431 };
4432
4433 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
4434 data_writes1, arraysize(data_writes1));
4435 session_deps_.socket_factory->AddSocketDataProvider(&data1);
4436
4437 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
4438 data_writes2, arraysize(data_writes2));
4439 session_deps_.socket_factory->AddSocketDataProvider(&data2);
4440
4441 StaticSocketDataProvider data3(data_reads3, arraysize(data_reads3),
4442 data_writes3, arraysize(data_writes3));
4443 session_deps_.socket_factory->AddSocketDataProvider(&data3);
4444
bnc87dcefc2017-05-25 12:47:584445 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:194446 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
asankae2257db2016-10-11 22:03:164447
4448 TestCompletionCallback callback;
4449 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
4450 EXPECT_THAT(callback.GetResult(rv), IsOk());
4451
4452 const HttpResponseInfo* response = trans->GetResponseInfo();
4453 ASSERT_TRUE(response);
4454 ASSERT_TRUE(response->headers);
4455 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
4456
4457 // The following three tests assert that an authentication challenge was
4458 // received and that the stack is ready to respond to the challenge using
4459 // ambient credentials.
4460 EXPECT_EQ(401, response->headers->response_code());
4461 EXPECT_TRUE(trans->IsReadyToRestartForAuth());
4462 EXPECT_FALSE(response->auth_challenge);
4463
4464 rv = trans->RestartWithAuth(AuthCredentials(), callback.callback());
4465 EXPECT_THAT(callback.GetResult(rv), IsOk());
4466 response = trans->GetResponseInfo();
4467 ASSERT_TRUE(response);
4468 ASSERT_TRUE(response->headers);
4469
4470 // The following three tests assert that an authentication challenge was
4471 // received and that the stack needs explicit credentials before it is ready
4472 // to respond to the challenge.
4473 EXPECT_EQ(401, response->headers->response_code());
4474 EXPECT_FALSE(trans->IsReadyToRestartForAuth());
4475 EXPECT_TRUE(response->auth_challenge);
4476
4477 rv = trans->RestartWithAuth(AuthCredentials(), callback.callback());
4478 EXPECT_THAT(callback.GetResult(rv), IsOk());
4479 response = trans->GetResponseInfo();
4480 ASSERT_TRUE(response);
4481 ASSERT_TRUE(response->headers);
4482 EXPECT_EQ(200, response->headers->response_code());
4483
4484 trans.reset();
4485 session->CloseAllConnections();
4486}
4487
Matt Menked1eb6d42018-01-17 04:54:064488// Proxy resolver that returns a proxy with the same host and port for different
4489// schemes, based on the path of the URL being requests.
4490class SameProxyWithDifferentSchemesProxyResolver : public ProxyResolver {
4491 public:
4492 SameProxyWithDifferentSchemesProxyResolver() {}
4493 ~SameProxyWithDifferentSchemesProxyResolver() override {}
4494
4495 static std::string ProxyHostPortPairAsString() { return "proxy.test:10000"; }
4496
4497 static HostPortPair ProxyHostPortPair() {
4498 return HostPortPair::FromString(ProxyHostPortPairAsString());
4499 }
4500
4501 // ProxyResolver implementation.
4502 int GetProxyForURL(const GURL& url,
4503 ProxyInfo* results,
4504 const CompletionCallback& callback,
4505 std::unique_ptr<Request>* request,
4506 const NetLogWithSource& /*net_log*/) override {
4507 *results = ProxyInfo();
4508 if (url.path() == "/socks4") {
4509 results->UsePacString("SOCKS " + ProxyHostPortPairAsString());
4510 return OK;
4511 }
4512 if (url.path() == "/socks5") {
4513 results->UsePacString("SOCKS5 " + ProxyHostPortPairAsString());
4514 return OK;
4515 }
4516 if (url.path() == "/http") {
4517 results->UsePacString("PROXY " + ProxyHostPortPairAsString());
4518 return OK;
4519 }
4520 if (url.path() == "/https") {
4521 results->UsePacString("HTTPS " + ProxyHostPortPairAsString());
4522 return OK;
4523 }
4524 NOTREACHED();
4525 return ERR_NOT_IMPLEMENTED;
4526 }
4527
4528 private:
4529 DISALLOW_COPY_AND_ASSIGN(SameProxyWithDifferentSchemesProxyResolver);
4530};
4531
4532class SameProxyWithDifferentSchemesProxyResolverFactory
4533 : public ProxyResolverFactory {
4534 public:
4535 SameProxyWithDifferentSchemesProxyResolverFactory()
4536 : ProxyResolverFactory(false) {}
4537
4538 int CreateProxyResolver(
4539 const scoped_refptr<ProxyResolverScriptData>& pac_script,
4540 std::unique_ptr<ProxyResolver>* resolver,
4541 const CompletionCallback& callback,
4542 std::unique_ptr<Request>* request) override {
4543 *resolver = std::make_unique<SameProxyWithDifferentSchemesProxyResolver>();
4544 return OK;
4545 }
4546
4547 private:
4548 DISALLOW_COPY_AND_ASSIGN(SameProxyWithDifferentSchemesProxyResolverFactory);
4549};
4550
4551// Check that when different proxy schemes are all applied to a proxy at the
4552// same address, the sonnections are not grouped together. i.e., a request to
4553// foo.com using proxy.com as an HTTPS proxy won't use the same socket as a
4554// request to foo.com using proxy.com as an HTTP proxy.
4555TEST_F(HttpNetworkTransactionTest, SameDestinationForDifferentProxyTypes) {
4556 session_deps_.proxy_service = std::make_unique<ProxyService>(
4557 std::make_unique<ProxyConfigServiceFixed>(
4558 ProxyConfig::CreateAutoDetect()),
4559 std::make_unique<SameProxyWithDifferentSchemesProxyResolverFactory>(),
4560 nullptr);
4561
4562 std::unique_ptr<HttpNetworkSession> session = CreateSession(&session_deps_);
4563
4564 MockWrite socks_writes[] = {
4565 MockWrite(SYNCHRONOUS, kSOCKS4OkRequestLocalHostPort80,
4566 kSOCKS4OkRequestLocalHostPort80Length),
4567 MockWrite(SYNCHRONOUS,
4568 "GET /socks4 HTTP/1.1\r\n"
4569 "Host: test\r\n"
4570 "Connection: keep-alive\r\n\r\n"),
4571 };
4572 MockRead socks_reads[] = {
4573 MockRead(SYNCHRONOUS, kSOCKS4OkReply, kSOCKS4OkReplyLength),
4574 MockRead("HTTP/1.0 200 OK\r\n"
4575 "Connection: keep-alive\r\n"
4576 "Content-Length: 15\r\n\r\n"
4577 "SOCKS4 Response"),
4578 };
4579 StaticSocketDataProvider socks_data(socks_reads, arraysize(socks_reads),
4580 socks_writes, arraysize(socks_writes));
4581 session_deps_.socket_factory->AddSocketDataProvider(&socks_data);
4582
4583 const char kSOCKS5Request[] = {
4584 0x05, // Version
4585 0x01, // Command (CONNECT)
4586 0x00, // Reserved
4587 0x03, // Address type (DOMAINNAME)
4588 0x04, // Length of domain (4)
4589 't', 'e', 's', 't', // Domain string
4590 0x00, 0x50, // 16-bit port (80)
4591 };
4592 MockWrite socks5_writes[] = {
4593 MockWrite(ASYNC, kSOCKS5GreetRequest, kSOCKS5GreetRequestLength),
4594 MockWrite(ASYNC, kSOCKS5Request, arraysize(kSOCKS5Request)),
4595 MockWrite(SYNCHRONOUS,
4596 "GET /socks5 HTTP/1.1\r\n"
4597 "Host: test\r\n"
4598 "Connection: keep-alive\r\n\r\n"),
4599 };
4600 MockRead socks5_reads[] = {
4601 MockRead(ASYNC, kSOCKS5GreetResponse, kSOCKS5GreetResponseLength),
4602 MockRead(ASYNC, kSOCKS5OkResponse, kSOCKS5OkResponseLength),
4603 MockRead("HTTP/1.0 200 OK\r\n"
4604 "Connection: keep-alive\r\n"
4605 "Content-Length: 15\r\n\r\n"
4606 "SOCKS5 Response"),
4607 };
4608 StaticSocketDataProvider socks5_data(socks5_reads, arraysize(socks5_reads),
4609 socks5_writes, arraysize(socks5_writes));
4610 session_deps_.socket_factory->AddSocketDataProvider(&socks5_data);
4611
4612 MockWrite http_writes[] = {
4613 MockWrite(SYNCHRONOUS,
4614 "GET http://test/http HTTP/1.1\r\n"
4615 "Host: test\r\n"
4616 "Proxy-Connection: keep-alive\r\n\r\n"),
4617 };
4618 MockRead http_reads[] = {
4619 MockRead("HTTP/1.1 200 OK\r\n"
4620 "Proxy-Connection: keep-alive\r\n"
4621 "Content-Length: 13\r\n\r\n"
4622 "HTTP Response"),
4623 };
4624 StaticSocketDataProvider http_data(http_reads, arraysize(http_reads),
4625 http_writes, arraysize(http_writes));
4626 session_deps_.socket_factory->AddSocketDataProvider(&http_data);
4627
4628 MockWrite https_writes[] = {
4629 MockWrite(SYNCHRONOUS,
4630 "GET http://test/https HTTP/1.1\r\n"
4631 "Host: test\r\n"
4632 "Proxy-Connection: keep-alive\r\n\r\n"),
4633 };
4634 MockRead https_reads[] = {
4635 MockRead("HTTP/1.1 200 OK\r\n"
4636 "Proxy-Connection: keep-alive\r\n"
4637 "Content-Length: 14\r\n\r\n"
4638 "HTTPS Response"),
4639 };
4640 StaticSocketDataProvider https_data(https_reads, arraysize(https_reads),
4641 https_writes, arraysize(https_writes));
4642 session_deps_.socket_factory->AddSocketDataProvider(&https_data);
4643 SSLSocketDataProvider ssl(SYNCHRONOUS, OK);
4644 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
4645
4646 struct TestCase {
4647 GURL url;
4648 std::string expected_response;
4649 // How many idle sockets there should be in the SOCKS proxy socket pool
4650 // after the test.
4651 int expected_idle_socks_sockets;
4652 // How many idle sockets there should be in the HTTP proxy socket pool after
4653 // the test.
4654 int expected_idle_http_sockets;
4655 } const kTestCases[] = {
4656 {GURL("http://test/socks4"), "SOCKS4 Response", 1, 0},
4657 {GURL("http://test/socks5"), "SOCKS5 Response", 2, 0},
4658 {GURL("http://test/http"), "HTTP Response", 2, 1},
4659 {GURL("http://test/https"), "HTTPS Response", 2, 2},
4660 };
4661
4662 for (const auto& test_case : kTestCases) {
4663 HttpRequestInfo request;
4664 request.method = "GET";
4665 request.url = test_case.url;
4666 std::unique_ptr<HttpNetworkTransaction> trans =
4667 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY,
4668 session.get());
4669 TestCompletionCallback callback;
4670 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
4671 EXPECT_THAT(callback.GetResult(rv), IsOk());
4672
4673 const HttpResponseInfo* response = trans->GetResponseInfo();
4674 ASSERT_TRUE(response);
4675 ASSERT_TRUE(response->headers);
4676 EXPECT_EQ(200, response->headers->response_code());
4677 std::string response_data;
4678 EXPECT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
4679 EXPECT_EQ(test_case.expected_response, response_data);
4680
4681 // Return the socket to the socket pool, so can make sure it's not used for
4682 // the next requests.
4683 trans.reset();
4684 base::RunLoop().RunUntilIdle();
4685
4686 // Check the number of idle sockets in the pool, to make sure that used
4687 // sockets are indeed being returned to the socket pool. If each request
4688 // doesn't return an idle socket to the pool, the test would incorrectly
4689 // pass.
4690 EXPECT_EQ(
4691 test_case.expected_idle_socks_sockets,
4692 session
4693 ->GetSocketPoolForSOCKSProxy(
4694 HttpNetworkSession::NORMAL_SOCKET_POOL,
4695 SameProxyWithDifferentSchemesProxyResolver::ProxyHostPortPair())
4696 ->IdleSocketCount());
4697 EXPECT_EQ(
4698 test_case.expected_idle_http_sockets,
4699 session
4700 ->GetSocketPoolForHTTPProxy(
4701 HttpNetworkSession::NORMAL_SOCKET_POOL,
4702 SameProxyWithDifferentSchemesProxyResolver::ProxyHostPortPair())
4703 ->IdleSocketCount());
4704 }
4705}
4706
[email protected]029c83b62013-01-24 05:28:204707// Test the load timing for HTTPS requests with an HTTP proxy.
bncd16676a2016-07-20 16:23:014708TEST_F(HttpNetworkTransactionTest, HttpProxyLoadTimingNoPacTwoRequests) {
[email protected]029c83b62013-01-24 05:28:204709 HttpRequestInfo request1;
4710 request1.method = "GET";
bncce36dca22015-04-21 22:11:234711 request1.url = GURL("https://www.example.org/1");
[email protected]029c83b62013-01-24 05:28:204712
4713 HttpRequestInfo request2;
4714 request2.method = "GET";
bncce36dca22015-04-21 22:11:234715 request2.url = GURL("https://www.example.org/2");
[email protected]029c83b62013-01-24 05:28:204716
4717 // Configure against proxy server "myproxy:70".
brettwc1213d92016-11-12 03:41:134718 session_deps_.proxy_service = ProxyService::CreateFixed("myproxy:70");
vishal.b62985ca92015-04-17 08:45:514719 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:074720 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:094721 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]029c83b62013-01-24 05:28:204722
4723 // Since we have proxy, should try to establish tunnel.
4724 MockWrite data_writes1[] = {
rsleevidb16bb02015-11-12 23:47:174725 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
4726 "Host: www.example.org:443\r\n"
4727 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]029c83b62013-01-24 05:28:204728
rsleevidb16bb02015-11-12 23:47:174729 MockWrite("GET /1 HTTP/1.1\r\n"
4730 "Host: www.example.org\r\n"
4731 "Connection: keep-alive\r\n\r\n"),
[email protected]029c83b62013-01-24 05:28:204732
rsleevidb16bb02015-11-12 23:47:174733 MockWrite("GET /2 HTTP/1.1\r\n"
4734 "Host: www.example.org\r\n"
4735 "Connection: keep-alive\r\n\r\n"),
[email protected]029c83b62013-01-24 05:28:204736 };
4737
4738 // The proxy responds to the connect with a 407, using a persistent
4739 // connection.
4740 MockRead data_reads1[] = {
4741 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
4742
4743 MockRead("HTTP/1.1 200 OK\r\n"),
4744 MockRead("Content-Length: 1\r\n\r\n"),
4745 MockRead(SYNCHRONOUS, "1"),
4746
4747 MockRead("HTTP/1.1 200 OK\r\n"),
4748 MockRead("Content-Length: 2\r\n\r\n"),
4749 MockRead(SYNCHRONOUS, "22"),
4750 };
4751
4752 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
4753 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:074754 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]029c83b62013-01-24 05:28:204755 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:074756 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]029c83b62013-01-24 05:28:204757
4758 TestCompletionCallback callback1;
bnc87dcefc2017-05-25 12:47:584759 auto trans1 =
Jeremy Roman0579ed62017-08-29 15:56:194760 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]029c83b62013-01-24 05:28:204761
4762 int rv = trans1->Start(&request1, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:014763 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]029c83b62013-01-24 05:28:204764
4765 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:014766 EXPECT_THAT(rv, IsOk());
[email protected]029c83b62013-01-24 05:28:204767
4768 const HttpResponseInfo* response1 = trans1->GetResponseInfo();
wezca1070932016-05-26 20:30:524769 ASSERT_TRUE(response1);
tbansal2ecbbc72016-10-06 17:15:474770 EXPECT_TRUE(response1->proxy_server.is_http());
wezca1070932016-05-26 20:30:524771 ASSERT_TRUE(response1->headers);
[email protected]029c83b62013-01-24 05:28:204772 EXPECT_EQ(1, response1->headers->GetContentLength());
4773
4774 LoadTimingInfo load_timing_info1;
4775 EXPECT_TRUE(trans1->GetLoadTimingInfo(&load_timing_info1));
4776 TestLoadTimingNotReused(load_timing_info1, CONNECT_TIMING_HAS_SSL_TIMES);
4777
4778 trans1.reset();
4779
4780 TestCompletionCallback callback2;
bnc87dcefc2017-05-25 12:47:584781 auto trans2 =
Jeremy Roman0579ed62017-08-29 15:56:194782 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]029c83b62013-01-24 05:28:204783
4784 rv = trans2->Start(&request2, callback2.callback(), log.bound());
robpercival214763f2016-07-01 23:27:014785 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]029c83b62013-01-24 05:28:204786
4787 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:014788 EXPECT_THAT(rv, IsOk());
[email protected]029c83b62013-01-24 05:28:204789
4790 const HttpResponseInfo* response2 = trans2->GetResponseInfo();
wezca1070932016-05-26 20:30:524791 ASSERT_TRUE(response2);
tbansal2ecbbc72016-10-06 17:15:474792 EXPECT_TRUE(response2->proxy_server.is_http());
wezca1070932016-05-26 20:30:524793 ASSERT_TRUE(response2->headers);
[email protected]029c83b62013-01-24 05:28:204794 EXPECT_EQ(2, response2->headers->GetContentLength());
4795
4796 LoadTimingInfo load_timing_info2;
4797 EXPECT_TRUE(trans2->GetLoadTimingInfo(&load_timing_info2));
4798 TestLoadTimingReused(load_timing_info2);
4799
4800 EXPECT_EQ(load_timing_info1.socket_log_id, load_timing_info2.socket_log_id);
4801
4802 trans2.reset();
4803 session->CloseAllConnections();
4804}
4805
4806// Test the load timing for HTTPS requests with an HTTP proxy and a PAC script.
bncd16676a2016-07-20 16:23:014807TEST_F(HttpNetworkTransactionTest, HttpProxyLoadTimingWithPacTwoRequests) {
[email protected]029c83b62013-01-24 05:28:204808 HttpRequestInfo request1;
4809 request1.method = "GET";
bncce36dca22015-04-21 22:11:234810 request1.url = GURL("https://www.example.org/1");
[email protected]029c83b62013-01-24 05:28:204811
4812 HttpRequestInfo request2;
4813 request2.method = "GET";
bncce36dca22015-04-21 22:11:234814 request2.url = GURL("https://www.example.org/2");
[email protected]029c83b62013-01-24 05:28:204815
4816 // Configure against proxy server "myproxy:70".
rdsmith82957ad2015-09-16 19:42:034817 session_deps_.proxy_service =
4818 ProxyService::CreateFixedFromPacResult("PROXY myproxy:70");
vishal.b62985ca92015-04-17 08:45:514819 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:074820 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:094821 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]029c83b62013-01-24 05:28:204822
4823 // Since we have proxy, should try to establish tunnel.
4824 MockWrite data_writes1[] = {
rsleevidb16bb02015-11-12 23:47:174825 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
4826 "Host: www.example.org:443\r\n"
4827 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]029c83b62013-01-24 05:28:204828
rsleevidb16bb02015-11-12 23:47:174829 MockWrite("GET /1 HTTP/1.1\r\n"
4830 "Host: www.example.org\r\n"
4831 "Connection: keep-alive\r\n\r\n"),
[email protected]029c83b62013-01-24 05:28:204832
rsleevidb16bb02015-11-12 23:47:174833 MockWrite("GET /2 HTTP/1.1\r\n"
4834 "Host: www.example.org\r\n"
4835 "Connection: keep-alive\r\n\r\n"),
[email protected]029c83b62013-01-24 05:28:204836 };
4837
4838 // The proxy responds to the connect with a 407, using a persistent
4839 // connection.
4840 MockRead data_reads1[] = {
4841 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
4842
4843 MockRead("HTTP/1.1 200 OK\r\n"),
4844 MockRead("Content-Length: 1\r\n\r\n"),
4845 MockRead(SYNCHRONOUS, "1"),
4846
4847 MockRead("HTTP/1.1 200 OK\r\n"),
4848 MockRead("Content-Length: 2\r\n\r\n"),
4849 MockRead(SYNCHRONOUS, "22"),
4850 };
4851
4852 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
4853 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:074854 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]029c83b62013-01-24 05:28:204855 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:074856 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]029c83b62013-01-24 05:28:204857
4858 TestCompletionCallback callback1;
bnc87dcefc2017-05-25 12:47:584859 auto trans1 =
Jeremy Roman0579ed62017-08-29 15:56:194860 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]029c83b62013-01-24 05:28:204861
4862 int rv = trans1->Start(&request1, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:014863 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]029c83b62013-01-24 05:28:204864
4865 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:014866 EXPECT_THAT(rv, IsOk());
[email protected]029c83b62013-01-24 05:28:204867
4868 const HttpResponseInfo* response1 = trans1->GetResponseInfo();
wezca1070932016-05-26 20:30:524869 ASSERT_TRUE(response1);
4870 ASSERT_TRUE(response1->headers);
[email protected]029c83b62013-01-24 05:28:204871 EXPECT_EQ(1, response1->headers->GetContentLength());
4872
4873 LoadTimingInfo load_timing_info1;
4874 EXPECT_TRUE(trans1->GetLoadTimingInfo(&load_timing_info1));
4875 TestLoadTimingNotReusedWithPac(load_timing_info1,
4876 CONNECT_TIMING_HAS_SSL_TIMES);
4877
4878 trans1.reset();
4879
4880 TestCompletionCallback callback2;
bnc87dcefc2017-05-25 12:47:584881 auto trans2 =
Jeremy Roman0579ed62017-08-29 15:56:194882 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]029c83b62013-01-24 05:28:204883
4884 rv = trans2->Start(&request2, callback2.callback(), log.bound());
robpercival214763f2016-07-01 23:27:014885 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]029c83b62013-01-24 05:28:204886
4887 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:014888 EXPECT_THAT(rv, IsOk());
[email protected]029c83b62013-01-24 05:28:204889
4890 const HttpResponseInfo* response2 = trans2->GetResponseInfo();
wezca1070932016-05-26 20:30:524891 ASSERT_TRUE(response2);
4892 ASSERT_TRUE(response2->headers);
[email protected]029c83b62013-01-24 05:28:204893 EXPECT_EQ(2, response2->headers->GetContentLength());
4894
4895 LoadTimingInfo load_timing_info2;
4896 EXPECT_TRUE(trans2->GetLoadTimingInfo(&load_timing_info2));
4897 TestLoadTimingReusedWithPac(load_timing_info2);
4898
4899 EXPECT_EQ(load_timing_info1.socket_log_id, load_timing_info2.socket_log_id);
4900
4901 trans2.reset();
4902 session->CloseAllConnections();
4903}
4904
[email protected]2df19bb2010-08-25 20:13:464905// Test a simple get through an HTTPS Proxy.
bncd16676a2016-07-20 16:23:014906TEST_F(HttpNetworkTransactionTest, HttpsProxyGet) {
[email protected]cb9bf6ca2011-01-28 13:15:274907 HttpRequestInfo request;
4908 request.method = "GET";
bncce36dca22015-04-21 22:11:234909 request.url = GURL("http://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:274910
[email protected]2df19bb2010-08-25 20:13:464911 // Configure against https proxy server "proxy:70".
rdsmith82957ad2015-09-16 19:42:034912 session_deps_.proxy_service = ProxyService::CreateFixed("https://proxy:70");
vishal.b62985ca92015-04-17 08:45:514913 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:074914 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:094915 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]2df19bb2010-08-25 20:13:464916
[email protected]2df19bb2010-08-25 20:13:464917 // Since we have proxy, should use full url
4918 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:234919 MockWrite(
4920 "GET http://www.example.org/ HTTP/1.1\r\n"
4921 "Host: www.example.org\r\n"
4922 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]2df19bb2010-08-25 20:13:464923 };
4924
4925 MockRead data_reads1[] = {
4926 MockRead("HTTP/1.1 200 OK\r\n"),
4927 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
4928 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:064929 MockRead(SYNCHRONOUS, OK),
[email protected]2df19bb2010-08-25 20:13:464930 };
4931
4932 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
4933 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:074934 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8ddf8322012-02-23 18:08:064935 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:074936 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]2df19bb2010-08-25 20:13:464937
[email protected]49639fa2011-12-20 23:22:414938 TestCompletionCallback callback1;
[email protected]2df19bb2010-08-25 20:13:464939
bnc691fda62016-08-12 00:43:164940 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]0b0bf032010-09-21 18:08:504941
bnc691fda62016-08-12 00:43:164942 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:014943 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2df19bb2010-08-25 20:13:464944
4945 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:014946 EXPECT_THAT(rv, IsOk());
[email protected]2df19bb2010-08-25 20:13:464947
[email protected]58e32bb2013-01-21 18:23:254948 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:164949 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]58e32bb2013-01-21 18:23:254950 TestLoadTimingNotReused(load_timing_info,
4951 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
4952
bnc691fda62016-08-12 00:43:164953 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:524954 ASSERT_TRUE(response);
[email protected]2df19bb2010-08-25 20:13:464955
tbansal2ecbbc72016-10-06 17:15:474956 EXPECT_TRUE(response->proxy_server.is_https());
[email protected]2df19bb2010-08-25 20:13:464957 EXPECT_TRUE(response->headers->IsKeepAlive());
4958 EXPECT_EQ(200, response->headers->response_code());
4959 EXPECT_EQ(100, response->headers->GetContentLength());
4960 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
4961
4962 // The password prompt info should not be set.
wezca1070932016-05-26 20:30:524963 EXPECT_FALSE(response->auth_challenge);
[email protected]2df19bb2010-08-25 20:13:464964}
4965
[email protected]7642b5ae2010-09-01 20:55:174966// Test a SPDY get through an HTTPS Proxy.
bncd16676a2016-07-20 16:23:014967TEST_F(HttpNetworkTransactionTest, HttpsProxySpdyGet) {
[email protected]cb9bf6ca2011-01-28 13:15:274968 HttpRequestInfo request;
4969 request.method = "GET";
bncce36dca22015-04-21 22:11:234970 request.url = GURL("http://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:274971
[email protected]7642b5ae2010-09-01 20:55:174972 // Configure against https proxy server "proxy:70".
rdsmith82957ad2015-09-16 19:42:034973 session_deps_.proxy_service = ProxyService::CreateFixed("https://proxy:70");
vishal.b62985ca92015-04-17 08:45:514974 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:074975 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:094976 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]7642b5ae2010-09-01 20:55:174977
bncce36dca22015-04-21 22:11:234978 // fetch http://www.example.org/ via SPDY
bncdf80d44fd2016-07-15 20:27:414979 SpdySerializedFrame req(
bncb26024382016-06-29 02:39:454980 spdy_util_.ConstructSpdyGet("http://www.example.org/", 1, LOWEST));
bncdf80d44fd2016-07-15 20:27:414981 MockWrite spdy_writes[] = {CreateMockWrite(req, 0)};
[email protected]7642b5ae2010-09-01 20:55:174982
bnc42331402016-07-25 13:36:154983 SpdySerializedFrame resp(spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
bncdf80d44fd2016-07-15 20:27:414984 SpdySerializedFrame data(spdy_util_.ConstructSpdyDataFrame(1, true));
[email protected]7642b5ae2010-09-01 20:55:174985 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:414986 CreateMockRead(resp, 1), CreateMockRead(data, 2), MockRead(ASYNC, 0, 3),
[email protected]7642b5ae2010-09-01 20:55:174987 };
4988
rch8e6c6c42015-05-01 14:05:134989 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
4990 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:074991 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]7642b5ae2010-09-01 20:55:174992
[email protected]8ddf8322012-02-23 18:08:064993 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:364994 ssl.next_proto = kProtoHTTP2;
[email protected]bb88e1d32013-05-03 23:11:074995 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]7642b5ae2010-09-01 20:55:174996
[email protected]49639fa2011-12-20 23:22:414997 TestCompletionCallback callback1;
[email protected]7642b5ae2010-09-01 20:55:174998
bnc691fda62016-08-12 00:43:164999 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]0b0bf032010-09-21 18:08:505000
bnc691fda62016-08-12 00:43:165001 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:015002 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]7642b5ae2010-09-01 20:55:175003
5004 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:015005 EXPECT_THAT(rv, IsOk());
[email protected]7642b5ae2010-09-01 20:55:175006
[email protected]58e32bb2013-01-21 18:23:255007 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:165008 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]58e32bb2013-01-21 18:23:255009 TestLoadTimingNotReused(load_timing_info,
5010 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
5011
bnc691fda62016-08-12 00:43:165012 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:525013 ASSERT_TRUE(response);
tbansal2ecbbc72016-10-06 17:15:475014 EXPECT_TRUE(response->proxy_server.is_https());
wezca1070932016-05-26 20:30:525015 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:025016 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]7642b5ae2010-09-01 20:55:175017
5018 std::string response_data;
bnc691fda62016-08-12 00:43:165019 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
[email protected]448d4ca52012-03-04 04:12:235020 EXPECT_EQ(kUploadData, response_data);
[email protected]7642b5ae2010-09-01 20:55:175021}
5022
[email protected]1c173852014-06-19 12:51:505023// Verifies that a session which races and wins against the owning transaction
5024// (completing prior to host resolution), doesn't fail the transaction.
5025// Regression test for crbug.com/334413.
bncd16676a2016-07-20 16:23:015026TEST_F(HttpNetworkTransactionTest, HttpsProxySpdyGetWithSessionRace) {
[email protected]1c173852014-06-19 12:51:505027 HttpRequestInfo request;
5028 request.method = "GET";
bncce36dca22015-04-21 22:11:235029 request.url = GURL("http://www.example.org/");
[email protected]1c173852014-06-19 12:51:505030
5031 // Configure SPDY proxy server "proxy:70".
rdsmith82957ad2015-09-16 19:42:035032 session_deps_.proxy_service = ProxyService::CreateFixed("https://proxy:70");
vishal.b62985ca92015-04-17 08:45:515033 BoundTestNetLog log;
[email protected]1c173852014-06-19 12:51:505034 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:095035 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]1c173852014-06-19 12:51:505036
bncce36dca22015-04-21 22:11:235037 // Fetch http://www.example.org/ through the SPDY proxy.
bncdf80d44fd2016-07-15 20:27:415038 SpdySerializedFrame req(
bncb26024382016-06-29 02:39:455039 spdy_util_.ConstructSpdyGet("http://www.example.org/", 1, LOWEST));
bncdf80d44fd2016-07-15 20:27:415040 MockWrite spdy_writes[] = {CreateMockWrite(req, 0)};
[email protected]1c173852014-06-19 12:51:505041
bnc42331402016-07-25 13:36:155042 SpdySerializedFrame resp(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
bncdf80d44fd2016-07-15 20:27:415043 SpdySerializedFrame data(spdy_util_.ConstructSpdyDataFrame(1, true));
[email protected]1c173852014-06-19 12:51:505044 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:415045 CreateMockRead(resp, 1), CreateMockRead(data, 2), MockRead(ASYNC, 0, 3),
[email protected]1c173852014-06-19 12:51:505046 };
5047
rch8e6c6c42015-05-01 14:05:135048 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
5049 arraysize(spdy_writes));
[email protected]1c173852014-06-19 12:51:505050 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
5051
5052 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:365053 ssl.next_proto = kProtoHTTP2;
[email protected]1c173852014-06-19 12:51:505054 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
5055
5056 TestCompletionCallback callback1;
5057
bnc691fda62016-08-12 00:43:165058 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]1c173852014-06-19 12:51:505059
5060 // Stall the hostname resolution begun by the transaction.
5061 session_deps_.host_resolver->set_synchronous_mode(false);
5062 session_deps_.host_resolver->set_ondemand_mode(true);
5063
bnc691fda62016-08-12 00:43:165064 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:015065 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]1c173852014-06-19 12:51:505066
5067 // Race a session to the proxy, which completes first.
5068 session_deps_.host_resolver->set_ondemand_mode(false);
5069 SpdySessionKey key(
5070 HostPortPair("proxy", 70), ProxyServer::Direct(), PRIVACY_MODE_DISABLED);
5071 base::WeakPtr<SpdySession> spdy_session =
Bence Béky0ef1556e2017-06-30 19:52:525072 CreateSpdySession(session.get(), key, log.bound());
[email protected]1c173852014-06-19 12:51:505073
5074 // Unstall the resolution begun by the transaction.
5075 session_deps_.host_resolver->set_ondemand_mode(true);
5076 session_deps_.host_resolver->ResolveAllPending();
5077
5078 EXPECT_FALSE(callback1.have_result());
5079 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:015080 EXPECT_THAT(rv, IsOk());
[email protected]1c173852014-06-19 12:51:505081
bnc691fda62016-08-12 00:43:165082 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:525083 ASSERT_TRUE(response);
5084 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:025085 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]1c173852014-06-19 12:51:505086
5087 std::string response_data;
bnc691fda62016-08-12 00:43:165088 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
[email protected]1c173852014-06-19 12:51:505089 EXPECT_EQ(kUploadData, response_data);
5090}
5091
[email protected]dc7bd1c52010-11-12 00:01:135092// Test a SPDY get through an HTTPS Proxy.
bncd16676a2016-07-20 16:23:015093TEST_F(HttpNetworkTransactionTest, HttpsProxySpdyGetWithProxyAuth) {
[email protected]cb9bf6ca2011-01-28 13:15:275094 HttpRequestInfo request;
5095 request.method = "GET";
bncce36dca22015-04-21 22:11:235096 request.url = GURL("http://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:275097
[email protected]79cb5c12011-09-12 13:12:045098 // Configure against https proxy server "myproxy:70".
rdsmith82957ad2015-09-16 19:42:035099 session_deps_.proxy_service = ProxyService::CreateFixed("https://myproxy:70");
vishal.b62985ca92015-04-17 08:45:515100 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:075101 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:095102 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]dc7bd1c52010-11-12 00:01:135103
[email protected]dc7bd1c52010-11-12 00:01:135104 // The first request will be a bare GET, the second request will be a
5105 // GET with a Proxy-Authorization header.
bncb26024382016-06-29 02:39:455106 spdy_util_.set_default_url(request.url);
bncdf80d44fd2016-07-15 20:27:415107 SpdySerializedFrame req_get(
bnc38dcd392016-02-09 23:19:495108 spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST, false));
rdsmithebb50aa2015-11-12 03:44:385109 spdy_util_.UpdateWithStreamDestruction(1);
[email protected]dc7bd1c52010-11-12 00:01:135110 const char* const kExtraAuthorizationHeaders[] = {
[email protected]cdf8f7e72013-05-23 10:56:465111 "proxy-authorization", "Basic Zm9vOmJhcg=="
[email protected]dc7bd1c52010-11-12 00:01:135112 };
bncdf80d44fd2016-07-15 20:27:415113 SpdySerializedFrame req_get_authorization(spdy_util_.ConstructSpdyGet(
5114 kExtraAuthorizationHeaders, arraysize(kExtraAuthorizationHeaders) / 2, 3,
5115 LOWEST, false));
[email protected]dc7bd1c52010-11-12 00:01:135116 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:415117 CreateMockWrite(req_get, 0), CreateMockWrite(req_get_authorization, 3),
[email protected]dc7bd1c52010-11-12 00:01:135118 };
5119
5120 // The first response is a 407 proxy authentication challenge, and the second
5121 // response will be a 200 response since the second request includes a valid
5122 // Authorization header.
5123 const char* const kExtraAuthenticationHeaders[] = {
[email protected]cdf8f7e72013-05-23 10:56:465124 "proxy-authenticate", "Basic realm=\"MyRealm1\""
[email protected]dc7bd1c52010-11-12 00:01:135125 };
bnc42331402016-07-25 13:36:155126 SpdySerializedFrame resp_authentication(spdy_util_.ConstructSpdyReplyError(
bncc9f762a2016-12-06 20:38:235127 "407", kExtraAuthenticationHeaders,
bncdf80d44fd2016-07-15 20:27:415128 arraysize(kExtraAuthenticationHeaders) / 2, 1));
5129 SpdySerializedFrame body_authentication(
5130 spdy_util_.ConstructSpdyDataFrame(1, true));
bnc42331402016-07-25 13:36:155131 SpdySerializedFrame resp_data(spdy_util_.ConstructSpdyGetReply(NULL, 0, 3));
bncdf80d44fd2016-07-15 20:27:415132 SpdySerializedFrame body_data(spdy_util_.ConstructSpdyDataFrame(3, true));
[email protected]dc7bd1c52010-11-12 00:01:135133 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:415134 CreateMockRead(resp_authentication, 1),
bnceb9aa7112017-01-05 01:03:465135 CreateMockRead(body_authentication, 2, SYNCHRONOUS),
bncdf80d44fd2016-07-15 20:27:415136 CreateMockRead(resp_data, 4),
5137 CreateMockRead(body_data, 5),
rch8e6c6c42015-05-01 14:05:135138 MockRead(ASYNC, 0, 6),
[email protected]dc7bd1c52010-11-12 00:01:135139 };
5140
rch8e6c6c42015-05-01 14:05:135141 SequencedSocketData data(spdy_reads, arraysize(spdy_reads), spdy_writes,
5142 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:075143 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]dc7bd1c52010-11-12 00:01:135144
[email protected]8ddf8322012-02-23 18:08:065145 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:365146 ssl.next_proto = kProtoHTTP2;
[email protected]bb88e1d32013-05-03 23:11:075147 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]dc7bd1c52010-11-12 00:01:135148
[email protected]49639fa2011-12-20 23:22:415149 TestCompletionCallback callback1;
[email protected]dc7bd1c52010-11-12 00:01:135150
bnc691fda62016-08-12 00:43:165151 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]dc7bd1c52010-11-12 00:01:135152
bnc691fda62016-08-12 00:43:165153 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:015154 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]dc7bd1c52010-11-12 00:01:135155
5156 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:015157 EXPECT_THAT(rv, IsOk());
[email protected]dc7bd1c52010-11-12 00:01:135158
bnc691fda62016-08-12 00:43:165159 const HttpResponseInfo* const response = trans.GetResponseInfo();
[email protected]dc7bd1c52010-11-12 00:01:135160
wezca1070932016-05-26 20:30:525161 ASSERT_TRUE(response);
5162 ASSERT_TRUE(response->headers);
[email protected]dc7bd1c52010-11-12 00:01:135163 EXPECT_EQ(407, response->headers->response_code());
5164 EXPECT_TRUE(response->was_fetched_via_spdy);
asanka098c0092016-06-16 20:18:435165 EXPECT_TRUE(CheckBasicSecureProxyAuth(response->auth_challenge.get()));
[email protected]dc7bd1c52010-11-12 00:01:135166
[email protected]49639fa2011-12-20 23:22:415167 TestCompletionCallback callback2;
[email protected]dc7bd1c52010-11-12 00:01:135168
bnc691fda62016-08-12 00:43:165169 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar), callback2.callback());
robpercival214763f2016-07-01 23:27:015170 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]dc7bd1c52010-11-12 00:01:135171
5172 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:015173 EXPECT_THAT(rv, IsOk());
[email protected]dc7bd1c52010-11-12 00:01:135174
bnc691fda62016-08-12 00:43:165175 const HttpResponseInfo* const response_restart = trans.GetResponseInfo();
[email protected]dc7bd1c52010-11-12 00:01:135176
wezca1070932016-05-26 20:30:525177 ASSERT_TRUE(response_restart);
5178 ASSERT_TRUE(response_restart->headers);
[email protected]dc7bd1c52010-11-12 00:01:135179 EXPECT_EQ(200, response_restart->headers->response_code());
5180 // The password prompt info should not be set.
wezca1070932016-05-26 20:30:525181 EXPECT_FALSE(response_restart->auth_challenge);
[email protected]dc7bd1c52010-11-12 00:01:135182}
5183
[email protected]d9da5fe2010-10-13 22:37:165184// Test a SPDY CONNECT through an HTTPS Proxy to an HTTPS (non-SPDY) Server.
bncd16676a2016-07-20 16:23:015185TEST_F(HttpNetworkTransactionTest, HttpsProxySpdyConnectHttps) {
[email protected]cb9bf6ca2011-01-28 13:15:275186 HttpRequestInfo request;
5187 request.method = "GET";
bncce36dca22015-04-21 22:11:235188 request.url = GURL("https://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:275189
[email protected]d9da5fe2010-10-13 22:37:165190 // Configure against https proxy server "proxy:70".
rdsmith82957ad2015-09-16 19:42:035191 session_deps_.proxy_service = ProxyService::CreateFixed("https://proxy:70");
vishal.b62985ca92015-04-17 08:45:515192 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:075193 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:095194 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]d9da5fe2010-10-13 22:37:165195
bnc691fda62016-08-12 00:43:165196 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]d9da5fe2010-10-13 22:37:165197
bncce36dca22015-04-21 22:11:235198 // CONNECT to www.example.org:443 via SPDY
bncdf80d44fd2016-07-15 20:27:415199 SpdySerializedFrame connect(spdy_util_.ConstructSpdyConnect(
bncce36dca22015-04-21 22:11:235200 NULL, 0, 1, LOWEST, HostPortPair("www.example.org", 443)));
5201 // fetch https://www.example.org/ via HTTP
[email protected]d9da5fe2010-10-13 22:37:165202
bncce36dca22015-04-21 22:11:235203 const char get[] =
5204 "GET / HTTP/1.1\r\n"
5205 "Host: www.example.org\r\n"
5206 "Connection: keep-alive\r\n\r\n";
bncdf80d44fd2016-07-15 20:27:415207 SpdySerializedFrame wrapped_get(
5208 spdy_util_.ConstructSpdyDataFrame(1, get, strlen(get), false));
bnc42331402016-07-25 13:36:155209 SpdySerializedFrame conn_resp(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
[email protected]d9da5fe2010-10-13 22:37:165210 const char resp[] = "HTTP/1.1 200 OK\r\n"
5211 "Content-Length: 10\r\n\r\n";
bncdf80d44fd2016-07-15 20:27:415212 SpdySerializedFrame wrapped_get_resp(
5213 spdy_util_.ConstructSpdyDataFrame(1, resp, strlen(resp), false));
5214 SpdySerializedFrame wrapped_body(
5215 spdy_util_.ConstructSpdyDataFrame(1, "1234567890", 10, false));
5216 SpdySerializedFrame window_update(
5217 spdy_util_.ConstructSpdyWindowUpdate(1, wrapped_get_resp.size()));
[email protected]8d2f7012012-02-16 00:08:045218
5219 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:415220 CreateMockWrite(connect, 0), CreateMockWrite(wrapped_get, 2),
5221 CreateMockWrite(window_update, 6),
[email protected]8d2f7012012-02-16 00:08:045222 };
5223
[email protected]d9da5fe2010-10-13 22:37:165224 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:415225 CreateMockRead(conn_resp, 1, ASYNC),
5226 CreateMockRead(wrapped_get_resp, 3, ASYNC),
5227 CreateMockRead(wrapped_body, 4, ASYNC),
5228 CreateMockRead(wrapped_body, 5, ASYNC),
rch8e6c6c42015-05-01 14:05:135229 MockRead(ASYNC, 0, 7),
[email protected]d9da5fe2010-10-13 22:37:165230 };
5231
rch8e6c6c42015-05-01 14:05:135232 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
5233 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:075234 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]d9da5fe2010-10-13 22:37:165235
[email protected]8ddf8322012-02-23 18:08:065236 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:365237 ssl.next_proto = kProtoHTTP2;
[email protected]bb88e1d32013-05-03 23:11:075238 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]8ddf8322012-02-23 18:08:065239 SSLSocketDataProvider ssl2(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:075240 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
[email protected]d9da5fe2010-10-13 22:37:165241
[email protected]49639fa2011-12-20 23:22:415242 TestCompletionCallback callback1;
[email protected]d9da5fe2010-10-13 22:37:165243
bnc691fda62016-08-12 00:43:165244 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:015245 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]d9da5fe2010-10-13 22:37:165246
5247 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:015248 ASSERT_THAT(rv, IsOk());
[email protected]d9da5fe2010-10-13 22:37:165249
[email protected]58e32bb2013-01-21 18:23:255250 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:165251 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]58e32bb2013-01-21 18:23:255252 TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_SSL_TIMES);
5253
bnc691fda62016-08-12 00:43:165254 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:525255 ASSERT_TRUE(response);
5256 ASSERT_TRUE(response->headers);
[email protected]d9da5fe2010-10-13 22:37:165257 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
5258
5259 std::string response_data;
bnc691fda62016-08-12 00:43:165260 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
[email protected]d9da5fe2010-10-13 22:37:165261 EXPECT_EQ("1234567890", response_data);
5262}
5263
5264// Test a SPDY CONNECT through an HTTPS Proxy to a SPDY server.
bncd16676a2016-07-20 16:23:015265TEST_F(HttpNetworkTransactionTest, HttpsProxySpdyConnectSpdy) {
5266 SpdyTestUtil spdy_util_wrapped;
rdsmithebb50aa2015-11-12 03:44:385267
[email protected]cb9bf6ca2011-01-28 13:15:275268 HttpRequestInfo request;
5269 request.method = "GET";
bncce36dca22015-04-21 22:11:235270 request.url = GURL("https://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:275271
[email protected]d9da5fe2010-10-13 22:37:165272 // Configure against https proxy server "proxy:70".
rdsmith82957ad2015-09-16 19:42:035273 session_deps_.proxy_service = ProxyService::CreateFixed("https://proxy:70");
vishal.b62985ca92015-04-17 08:45:515274 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:075275 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:095276 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]d9da5fe2010-10-13 22:37:165277
bnc691fda62016-08-12 00:43:165278 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]d9da5fe2010-10-13 22:37:165279
bncce36dca22015-04-21 22:11:235280 // CONNECT to www.example.org:443 via SPDY
bncdf80d44fd2016-07-15 20:27:415281 SpdySerializedFrame connect(spdy_util_.ConstructSpdyConnect(
bncce36dca22015-04-21 22:11:235282 NULL, 0, 1, LOWEST, HostPortPair("www.example.org", 443)));
5283 // fetch https://www.example.org/ via SPDY
5284 const char kMyUrl[] = "https://www.example.org/";
bncdf80d44fd2016-07-15 20:27:415285 SpdySerializedFrame get(
bnc38dcd392016-02-09 23:19:495286 spdy_util_wrapped.ConstructSpdyGet(kMyUrl, 1, LOWEST));
bncdf80d44fd2016-07-15 20:27:415287 SpdySerializedFrame wrapped_get(spdy_util_.ConstructWrappedSpdyFrame(get, 1));
bnc42331402016-07-25 13:36:155288 SpdySerializedFrame conn_resp(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
bncdf80d44fd2016-07-15 20:27:415289 SpdySerializedFrame get_resp(
bnc42331402016-07-25 13:36:155290 spdy_util_wrapped.ConstructSpdyGetReply(NULL, 0, 1));
bncdf80d44fd2016-07-15 20:27:415291 SpdySerializedFrame wrapped_get_resp(
[email protected]23e482282013-06-14 16:08:025292 spdy_util_.ConstructWrappedSpdyFrame(get_resp, 1));
bncdf80d44fd2016-07-15 20:27:415293 SpdySerializedFrame body(spdy_util_wrapped.ConstructSpdyDataFrame(1, true));
5294 SpdySerializedFrame wrapped_body(
[email protected]23e482282013-06-14 16:08:025295 spdy_util_.ConstructWrappedSpdyFrame(body, 1));
bncdf80d44fd2016-07-15 20:27:415296 SpdySerializedFrame window_update_get_resp(
5297 spdy_util_.ConstructSpdyWindowUpdate(1, wrapped_get_resp.size()));
5298 SpdySerializedFrame window_update_body(
5299 spdy_util_.ConstructSpdyWindowUpdate(1, wrapped_body.size()));
[email protected]8d2f7012012-02-16 00:08:045300
5301 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:415302 CreateMockWrite(connect, 0), CreateMockWrite(wrapped_get, 2),
5303 CreateMockWrite(window_update_get_resp, 6),
5304 CreateMockWrite(window_update_body, 7),
[email protected]8d2f7012012-02-16 00:08:045305 };
5306
[email protected]d9da5fe2010-10-13 22:37:165307 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:415308 CreateMockRead(conn_resp, 1, ASYNC),
rch32320842015-05-16 15:57:095309 MockRead(ASYNC, ERR_IO_PENDING, 3),
bncdf80d44fd2016-07-15 20:27:415310 CreateMockRead(wrapped_get_resp, 4, ASYNC),
5311 CreateMockRead(wrapped_body, 5, ASYNC),
rch8e6c6c42015-05-01 14:05:135312 MockRead(ASYNC, 0, 8),
[email protected]d9da5fe2010-10-13 22:37:165313 };
5314
rch32320842015-05-16 15:57:095315 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
5316 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:075317 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]d9da5fe2010-10-13 22:37:165318
[email protected]8ddf8322012-02-23 18:08:065319 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:365320 ssl.next_proto = kProtoHTTP2;
[email protected]bb88e1d32013-05-03 23:11:075321 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]8ddf8322012-02-23 18:08:065322 SSLSocketDataProvider ssl2(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:365323 ssl2.next_proto = kProtoHTTP2;
[email protected]bb88e1d32013-05-03 23:11:075324 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
[email protected]d9da5fe2010-10-13 22:37:165325
[email protected]49639fa2011-12-20 23:22:415326 TestCompletionCallback callback1;
[email protected]d9da5fe2010-10-13 22:37:165327
bnc691fda62016-08-12 00:43:165328 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:015329 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]d9da5fe2010-10-13 22:37:165330
rch32320842015-05-16 15:57:095331 // Allow the SpdyProxyClientSocket's write callback to complete.
fdoray92e35a72016-06-10 15:54:555332 base::RunLoop().RunUntilIdle();
rch32320842015-05-16 15:57:095333 // Now allow the read of the response to complete.
mmenkee24011922015-12-17 22:12:595334 spdy_data.Resume();
[email protected]d9da5fe2010-10-13 22:37:165335 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:015336 EXPECT_THAT(rv, IsOk());
[email protected]d9da5fe2010-10-13 22:37:165337
[email protected]58e32bb2013-01-21 18:23:255338 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:165339 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]58e32bb2013-01-21 18:23:255340 TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_SSL_TIMES);
5341
bnc691fda62016-08-12 00:43:165342 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:525343 ASSERT_TRUE(response);
5344 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:025345 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]d9da5fe2010-10-13 22:37:165346
5347 std::string response_data;
bnc691fda62016-08-12 00:43:165348 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
[email protected]448d4ca52012-03-04 04:12:235349 EXPECT_EQ(kUploadData, response_data);
[email protected]d9da5fe2010-10-13 22:37:165350}
5351
5352// Test a SPDY CONNECT failure through an HTTPS Proxy.
bncd16676a2016-07-20 16:23:015353TEST_F(HttpNetworkTransactionTest, HttpsProxySpdyConnectFailure) {
[email protected]cb9bf6ca2011-01-28 13:15:275354 HttpRequestInfo request;
5355 request.method = "GET";
bncce36dca22015-04-21 22:11:235356 request.url = GURL("https://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:275357
[email protected]d9da5fe2010-10-13 22:37:165358 // Configure against https proxy server "proxy:70".
rdsmith82957ad2015-09-16 19:42:035359 session_deps_.proxy_service = ProxyService::CreateFixed("https://proxy:70");
vishal.b62985ca92015-04-17 08:45:515360 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:075361 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:095362 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]d9da5fe2010-10-13 22:37:165363
bnc691fda62016-08-12 00:43:165364 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]d9da5fe2010-10-13 22:37:165365
bncce36dca22015-04-21 22:11:235366 // CONNECT to www.example.org:443 via SPDY
bncdf80d44fd2016-07-15 20:27:415367 SpdySerializedFrame connect(spdy_util_.ConstructSpdyConnect(
bncce36dca22015-04-21 22:11:235368 NULL, 0, 1, LOWEST, HostPortPair("www.example.org", 443)));
bncdf80d44fd2016-07-15 20:27:415369 SpdySerializedFrame get(
diannahu9904e272017-02-03 14:40:085370 spdy_util_.ConstructSpdyRstStream(1, ERROR_CODE_CANCEL));
[email protected]d9da5fe2010-10-13 22:37:165371
5372 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:415373 CreateMockWrite(connect, 0), CreateMockWrite(get, 2),
[email protected]d9da5fe2010-10-13 22:37:165374 };
5375
bnc42331402016-07-25 13:36:155376 SpdySerializedFrame resp(spdy_util_.ConstructSpdyReplyError(1));
bncdf80d44fd2016-07-15 20:27:415377 SpdySerializedFrame data(spdy_util_.ConstructSpdyDataFrame(1, true));
[email protected]d9da5fe2010-10-13 22:37:165378 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:415379 CreateMockRead(resp, 1, ASYNC), MockRead(ASYNC, 0, 3),
[email protected]d9da5fe2010-10-13 22:37:165380 };
5381
rch8e6c6c42015-05-01 14:05:135382 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
5383 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:075384 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]d9da5fe2010-10-13 22:37:165385
[email protected]8ddf8322012-02-23 18:08:065386 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:365387 ssl.next_proto = kProtoHTTP2;
[email protected]bb88e1d32013-05-03 23:11:075388 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]8ddf8322012-02-23 18:08:065389 SSLSocketDataProvider ssl2(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:365390 ssl2.next_proto = kProtoHTTP2;
[email protected]bb88e1d32013-05-03 23:11:075391 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
[email protected]d9da5fe2010-10-13 22:37:165392
[email protected]49639fa2011-12-20 23:22:415393 TestCompletionCallback callback1;
[email protected]d9da5fe2010-10-13 22:37:165394
bnc691fda62016-08-12 00:43:165395 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:015396 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]d9da5fe2010-10-13 22:37:165397
5398 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:015399 EXPECT_THAT(rv, IsError(ERR_TUNNEL_CONNECTION_FAILED));
[email protected]d9da5fe2010-10-13 22:37:165400
ttuttle960fcbf2016-04-19 13:26:325401 // TODO(juliatuttle): Anything else to check here?
[email protected]d9da5fe2010-10-13 22:37:165402}
5403
[email protected]f6c63db52013-02-02 00:35:225404// Test load timing in the case of two HTTPS (non-SPDY) requests through a SPDY
5405// HTTPS Proxy to different servers.
bncd16676a2016-07-20 16:23:015406TEST_F(HttpNetworkTransactionTest,
[email protected]f6c63db52013-02-02 00:35:225407 HttpsProxySpdyConnectHttpsLoadTimingTwoRequestsTwoServers) {
5408 // Configure against https proxy server "proxy:70".
rdsmith82957ad2015-09-16 19:42:035409 session_deps_.proxy_service = ProxyService::CreateFixed("https://proxy:70");
vishal.b62985ca92015-04-17 08:45:515410 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:075411 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:095412 std::unique_ptr<HttpNetworkSession> session(
mmenke11eb5152015-06-09 14:50:505413 SpdySessionDependencies::SpdyCreateSession(&session_deps_));
[email protected]f6c63db52013-02-02 00:35:225414
5415 HttpRequestInfo request1;
5416 request1.method = "GET";
bncce36dca22015-04-21 22:11:235417 request1.url = GURL("https://www.example.org/");
[email protected]f6c63db52013-02-02 00:35:225418 request1.load_flags = 0;
5419
5420 HttpRequestInfo request2;
5421 request2.method = "GET";
bncce36dca22015-04-21 22:11:235422 request2.url = GURL("https://mail.example.org/");
[email protected]f6c63db52013-02-02 00:35:225423 request2.load_flags = 0;
5424
bncce36dca22015-04-21 22:11:235425 // CONNECT to www.example.org:443 via SPDY.
bncdf80d44fd2016-07-15 20:27:415426 SpdySerializedFrame connect1(spdy_util_.ConstructSpdyConnect(
bncce36dca22015-04-21 22:11:235427 NULL, 0, 1, LOWEST, HostPortPair("www.example.org", 443)));
bnc42331402016-07-25 13:36:155428 SpdySerializedFrame conn_resp1(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
[email protected]f6c63db52013-02-02 00:35:225429
bncce36dca22015-04-21 22:11:235430 // Fetch https://www.example.org/ via HTTP.
5431 const char get1[] =
5432 "GET / HTTP/1.1\r\n"
5433 "Host: www.example.org\r\n"
[email protected]f6c63db52013-02-02 00:35:225434 "Connection: keep-alive\r\n\r\n";
bncdf80d44fd2016-07-15 20:27:415435 SpdySerializedFrame wrapped_get1(
5436 spdy_util_.ConstructSpdyDataFrame(1, get1, strlen(get1), false));
[email protected]f6c63db52013-02-02 00:35:225437 const char resp1[] = "HTTP/1.1 200 OK\r\n"
5438 "Content-Length: 1\r\n\r\n";
bncdf80d44fd2016-07-15 20:27:415439 SpdySerializedFrame wrapped_get_resp1(
5440 spdy_util_.ConstructSpdyDataFrame(1, resp1, strlen(resp1), false));
5441 SpdySerializedFrame wrapped_body1(
5442 spdy_util_.ConstructSpdyDataFrame(1, "1", 1, false));
5443 SpdySerializedFrame window_update(
5444 spdy_util_.ConstructSpdyWindowUpdate(1, wrapped_get_resp1.size()));
[email protected]f6c63db52013-02-02 00:35:225445
bncce36dca22015-04-21 22:11:235446 // CONNECT to mail.example.org:443 via SPDY.
[email protected]745aa9c2014-06-27 02:21:295447 SpdyHeaderBlock connect2_block;
Bence Békybda82952017-10-02 17:35:275448 connect2_block[kHttp2MethodHeader] = "CONNECT";
5449 connect2_block[kHttp2AuthorityHeader] = "mail.example.org:443";
bnc42331402016-07-25 13:36:155450 SpdySerializedFrame connect2(spdy_util_.ConstructSpdyHeaders(
5451 3, std::move(connect2_block), LOWEST, false));
[email protected]601e03f12014-04-06 16:26:395452
bnc42331402016-07-25 13:36:155453 SpdySerializedFrame conn_resp2(spdy_util_.ConstructSpdyGetReply(NULL, 0, 3));
[email protected]f6c63db52013-02-02 00:35:225454
bncce36dca22015-04-21 22:11:235455 // Fetch https://mail.example.org/ via HTTP.
5456 const char get2[] =
5457 "GET / HTTP/1.1\r\n"
5458 "Host: mail.example.org\r\n"
[email protected]f6c63db52013-02-02 00:35:225459 "Connection: keep-alive\r\n\r\n";
bncdf80d44fd2016-07-15 20:27:415460 SpdySerializedFrame wrapped_get2(
5461 spdy_util_.ConstructSpdyDataFrame(3, get2, strlen(get2), false));
[email protected]f6c63db52013-02-02 00:35:225462 const char resp2[] = "HTTP/1.1 200 OK\r\n"
5463 "Content-Length: 2\r\n\r\n";
bncdf80d44fd2016-07-15 20:27:415464 SpdySerializedFrame wrapped_get_resp2(
5465 spdy_util_.ConstructSpdyDataFrame(3, resp2, strlen(resp2), false));
5466 SpdySerializedFrame wrapped_body2(
5467 spdy_util_.ConstructSpdyDataFrame(3, "22", 2, false));
[email protected]f6c63db52013-02-02 00:35:225468
5469 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:415470 CreateMockWrite(connect1, 0), CreateMockWrite(wrapped_get1, 2),
5471 CreateMockWrite(connect2, 5), CreateMockWrite(wrapped_get2, 7),
[email protected]f6c63db52013-02-02 00:35:225472 };
5473
5474 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:415475 CreateMockRead(conn_resp1, 1, ASYNC),
5476 CreateMockRead(wrapped_get_resp1, 3, ASYNC),
5477 CreateMockRead(wrapped_body1, 4, ASYNC),
5478 CreateMockRead(conn_resp2, 6, ASYNC),
5479 CreateMockRead(wrapped_get_resp2, 8, ASYNC),
5480 CreateMockRead(wrapped_body2, 9, ASYNC),
5481 MockRead(ASYNC, 0, 10),
[email protected]f6c63db52013-02-02 00:35:225482 };
5483
mmenke11eb5152015-06-09 14:50:505484 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
5485 arraysize(spdy_writes));
5486 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]f6c63db52013-02-02 00:35:225487
5488 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:365489 ssl.next_proto = kProtoHTTP2;
mmenke11eb5152015-06-09 14:50:505490 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]f6c63db52013-02-02 00:35:225491 SSLSocketDataProvider ssl2(ASYNC, OK);
mmenke11eb5152015-06-09 14:50:505492 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
[email protected]f6c63db52013-02-02 00:35:225493 SSLSocketDataProvider ssl3(ASYNC, OK);
mmenke11eb5152015-06-09 14:50:505494 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl3);
[email protected]f6c63db52013-02-02 00:35:225495
5496 TestCompletionCallback callback;
5497
bnc691fda62016-08-12 00:43:165498 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:205499 int rv = trans.Start(&request1, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:015500 EXPECT_THAT(callback.GetResult(rv), IsOk());
[email protected]f6c63db52013-02-02 00:35:225501
5502 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:165503 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]f6c63db52013-02-02 00:35:225504 TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_SSL_TIMES);
5505
bnc691fda62016-08-12 00:43:165506 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:525507 ASSERT_TRUE(response);
5508 ASSERT_TRUE(response->headers);
[email protected]f6c63db52013-02-02 00:35:225509 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
5510
5511 std::string response_data;
ttuttle859dc7a2015-04-23 19:42:295512 scoped_refptr<IOBuffer> buf(new IOBuffer(256));
bnc691fda62016-08-12 00:43:165513 rv = trans.Read(buf.get(), 256, callback.callback());
mmenke11eb5152015-06-09 14:50:505514 EXPECT_EQ(1, callback.GetResult(rv));
[email protected]f6c63db52013-02-02 00:35:225515
bnc691fda62016-08-12 00:43:165516 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:205517 rv = trans2.Start(&request2, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:015518 EXPECT_THAT(callback.GetResult(rv), IsOk());
[email protected]f6c63db52013-02-02 00:35:225519
5520 LoadTimingInfo load_timing_info2;
bnc691fda62016-08-12 00:43:165521 EXPECT_TRUE(trans2.GetLoadTimingInfo(&load_timing_info2));
[email protected]f6c63db52013-02-02 00:35:225522 // Even though the SPDY connection is reused, a new tunnelled connection has
5523 // to be created, so the socket's load timing looks like a fresh connection.
5524 TestLoadTimingNotReused(load_timing_info2, CONNECT_TIMING_HAS_SSL_TIMES);
5525
5526 // The requests should have different IDs, since they each are using their own
5527 // separate stream.
5528 EXPECT_NE(load_timing_info.socket_log_id, load_timing_info2.socket_log_id);
5529
bnc691fda62016-08-12 00:43:165530 rv = trans2.Read(buf.get(), 256, callback.callback());
mmenke11eb5152015-06-09 14:50:505531 EXPECT_EQ(2, callback.GetResult(rv));
[email protected]f6c63db52013-02-02 00:35:225532}
5533
5534// Test load timing in the case of two HTTPS (non-SPDY) requests through a SPDY
5535// HTTPS Proxy to the same server.
bncd16676a2016-07-20 16:23:015536TEST_F(HttpNetworkTransactionTest,
[email protected]f6c63db52013-02-02 00:35:225537 HttpsProxySpdyConnectHttpsLoadTimingTwoRequestsSameServer) {
5538 // Configure against https proxy server "proxy:70".
rdsmith82957ad2015-09-16 19:42:035539 session_deps_.proxy_service = ProxyService::CreateFixed("https://proxy:70");
vishal.b62985ca92015-04-17 08:45:515540 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:075541 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:095542 std::unique_ptr<HttpNetworkSession> session(
mmenke11eb5152015-06-09 14:50:505543 SpdySessionDependencies::SpdyCreateSession(&session_deps_));
[email protected]f6c63db52013-02-02 00:35:225544
5545 HttpRequestInfo request1;
5546 request1.method = "GET";
bncce36dca22015-04-21 22:11:235547 request1.url = GURL("https://www.example.org/");
[email protected]f6c63db52013-02-02 00:35:225548 request1.load_flags = 0;
5549
5550 HttpRequestInfo request2;
5551 request2.method = "GET";
bncce36dca22015-04-21 22:11:235552 request2.url = GURL("https://www.example.org/2");
[email protected]f6c63db52013-02-02 00:35:225553 request2.load_flags = 0;
5554
bncce36dca22015-04-21 22:11:235555 // CONNECT to www.example.org:443 via SPDY.
bncdf80d44fd2016-07-15 20:27:415556 SpdySerializedFrame connect1(spdy_util_.ConstructSpdyConnect(
bncce36dca22015-04-21 22:11:235557 NULL, 0, 1, LOWEST, HostPortPair("www.example.org", 443)));
bnc42331402016-07-25 13:36:155558 SpdySerializedFrame conn_resp1(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
[email protected]f6c63db52013-02-02 00:35:225559
bncce36dca22015-04-21 22:11:235560 // Fetch https://www.example.org/ via HTTP.
5561 const char get1[] =
5562 "GET / HTTP/1.1\r\n"
5563 "Host: www.example.org\r\n"
[email protected]f6c63db52013-02-02 00:35:225564 "Connection: keep-alive\r\n\r\n";
bncdf80d44fd2016-07-15 20:27:415565 SpdySerializedFrame wrapped_get1(
5566 spdy_util_.ConstructSpdyDataFrame(1, get1, strlen(get1), false));
[email protected]f6c63db52013-02-02 00:35:225567 const char resp1[] = "HTTP/1.1 200 OK\r\n"
5568 "Content-Length: 1\r\n\r\n";
bncdf80d44fd2016-07-15 20:27:415569 SpdySerializedFrame wrapped_get_resp1(
5570 spdy_util_.ConstructSpdyDataFrame(1, resp1, strlen(resp1), false));
5571 SpdySerializedFrame wrapped_body1(
5572 spdy_util_.ConstructSpdyDataFrame(1, "1", 1, false));
5573 SpdySerializedFrame window_update(
5574 spdy_util_.ConstructSpdyWindowUpdate(1, wrapped_get_resp1.size()));
[email protected]f6c63db52013-02-02 00:35:225575
bncce36dca22015-04-21 22:11:235576 // Fetch https://www.example.org/2 via HTTP.
5577 const char get2[] =
5578 "GET /2 HTTP/1.1\r\n"
5579 "Host: www.example.org\r\n"
[email protected]f6c63db52013-02-02 00:35:225580 "Connection: keep-alive\r\n\r\n";
bncdf80d44fd2016-07-15 20:27:415581 SpdySerializedFrame wrapped_get2(
5582 spdy_util_.ConstructSpdyDataFrame(1, get2, strlen(get2), false));
[email protected]f6c63db52013-02-02 00:35:225583 const char resp2[] = "HTTP/1.1 200 OK\r\n"
5584 "Content-Length: 2\r\n\r\n";
bncdf80d44fd2016-07-15 20:27:415585 SpdySerializedFrame wrapped_get_resp2(
5586 spdy_util_.ConstructSpdyDataFrame(1, resp2, strlen(resp2), false));
5587 SpdySerializedFrame wrapped_body2(
5588 spdy_util_.ConstructSpdyDataFrame(1, "22", 2, false));
[email protected]f6c63db52013-02-02 00:35:225589
5590 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:415591 CreateMockWrite(connect1, 0), CreateMockWrite(wrapped_get1, 2),
5592 CreateMockWrite(wrapped_get2, 5),
[email protected]f6c63db52013-02-02 00:35:225593 };
5594
5595 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:415596 CreateMockRead(conn_resp1, 1, ASYNC),
5597 CreateMockRead(wrapped_get_resp1, 3, ASYNC),
bnceb9aa7112017-01-05 01:03:465598 CreateMockRead(wrapped_body1, 4, SYNCHRONOUS),
bncdf80d44fd2016-07-15 20:27:415599 CreateMockRead(wrapped_get_resp2, 6, ASYNC),
bnceb9aa7112017-01-05 01:03:465600 CreateMockRead(wrapped_body2, 7, SYNCHRONOUS),
bncdf80d44fd2016-07-15 20:27:415601 MockRead(ASYNC, 0, 8),
[email protected]f6c63db52013-02-02 00:35:225602 };
5603
mmenke11eb5152015-06-09 14:50:505604 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
5605 arraysize(spdy_writes));
5606 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]f6c63db52013-02-02 00:35:225607
5608 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:365609 ssl.next_proto = kProtoHTTP2;
mmenke11eb5152015-06-09 14:50:505610 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]f6c63db52013-02-02 00:35:225611 SSLSocketDataProvider ssl2(ASYNC, OK);
mmenke11eb5152015-06-09 14:50:505612 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
[email protected]f6c63db52013-02-02 00:35:225613
5614 TestCompletionCallback callback;
5615
bnc87dcefc2017-05-25 12:47:585616 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:195617 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:205618 int rv = trans->Start(&request1, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:015619 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]f6c63db52013-02-02 00:35:225620
5621 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:015622 EXPECT_THAT(rv, IsOk());
[email protected]f6c63db52013-02-02 00:35:225623
5624 LoadTimingInfo load_timing_info;
5625 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
5626 TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_SSL_TIMES);
5627
5628 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:525629 ASSERT_TRUE(response);
5630 ASSERT_TRUE(response->headers);
[email protected]f6c63db52013-02-02 00:35:225631 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
5632
5633 std::string response_data;
ttuttle859dc7a2015-04-23 19:42:295634 scoped_refptr<IOBuffer> buf(new IOBuffer(256));
[email protected]90499482013-06-01 00:39:505635 EXPECT_EQ(1, trans->Read(buf.get(), 256, callback.callback()));
[email protected]f6c63db52013-02-02 00:35:225636 trans.reset();
5637
bnc87dcefc2017-05-25 12:47:585638 auto trans2 =
Jeremy Roman0579ed62017-08-29 15:56:195639 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:205640 rv = trans2->Start(&request2, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:015641 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]f6c63db52013-02-02 00:35:225642
[email protected]f6c63db52013-02-02 00:35:225643 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:015644 EXPECT_THAT(rv, IsOk());
[email protected]f6c63db52013-02-02 00:35:225645
5646 LoadTimingInfo load_timing_info2;
5647 EXPECT_TRUE(trans2->GetLoadTimingInfo(&load_timing_info2));
5648 TestLoadTimingReused(load_timing_info2);
5649
5650 // The requests should have the same ID.
5651 EXPECT_EQ(load_timing_info.socket_log_id, load_timing_info2.socket_log_id);
5652
[email protected]90499482013-06-01 00:39:505653 EXPECT_EQ(2, trans2->Read(buf.get(), 256, callback.callback()));
[email protected]f6c63db52013-02-02 00:35:225654}
5655
5656// Test load timing in the case of of two HTTP requests through a SPDY HTTPS
5657// Proxy to different servers.
bncd16676a2016-07-20 16:23:015658TEST_F(HttpNetworkTransactionTest, HttpsProxySpdyLoadTimingTwoHttpRequests) {
[email protected]f6c63db52013-02-02 00:35:225659 // Configure against https proxy server "proxy:70".
rdsmith82957ad2015-09-16 19:42:035660 session_deps_.proxy_service = ProxyService::CreateFixed("https://proxy:70");
vishal.b62985ca92015-04-17 08:45:515661 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:075662 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:095663 std::unique_ptr<HttpNetworkSession> session(
mmenke11eb5152015-06-09 14:50:505664 SpdySessionDependencies::SpdyCreateSession(&session_deps_));
[email protected]f6c63db52013-02-02 00:35:225665
5666 HttpRequestInfo request1;
5667 request1.method = "GET";
bncce36dca22015-04-21 22:11:235668 request1.url = GURL("http://www.example.org/");
[email protected]f6c63db52013-02-02 00:35:225669 request1.load_flags = 0;
5670
5671 HttpRequestInfo request2;
5672 request2.method = "GET";
bncce36dca22015-04-21 22:11:235673 request2.url = GURL("http://mail.example.org/");
[email protected]f6c63db52013-02-02 00:35:225674 request2.load_flags = 0;
5675
bncce36dca22015-04-21 22:11:235676 // http://www.example.org/
bnc086b39e12016-06-24 13:05:265677 SpdyHeaderBlock headers(
bncce36dca22015-04-21 22:11:235678 spdy_util_.ConstructGetHeaderBlockForProxy("http://www.example.org/"));
bncdf80d44fd2016-07-15 20:27:415679 SpdySerializedFrame get1(
bnc42331402016-07-25 13:36:155680 spdy_util_.ConstructSpdyHeaders(1, std::move(headers), LOWEST, true));
5681 SpdySerializedFrame get_resp1(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
bncdf80d44fd2016-07-15 20:27:415682 SpdySerializedFrame body1(spdy_util_.ConstructSpdyDataFrame(1, "1", 1, true));
rdsmithebb50aa2015-11-12 03:44:385683 spdy_util_.UpdateWithStreamDestruction(1);
[email protected]f6c63db52013-02-02 00:35:225684
bncce36dca22015-04-21 22:11:235685 // http://mail.example.org/
bnc086b39e12016-06-24 13:05:265686 SpdyHeaderBlock headers2(
bncce36dca22015-04-21 22:11:235687 spdy_util_.ConstructGetHeaderBlockForProxy("http://mail.example.org/"));
bncdf80d44fd2016-07-15 20:27:415688 SpdySerializedFrame get2(
bnc42331402016-07-25 13:36:155689 spdy_util_.ConstructSpdyHeaders(3, std::move(headers2), LOWEST, true));
5690 SpdySerializedFrame get_resp2(spdy_util_.ConstructSpdyGetReply(NULL, 0, 3));
bncdf80d44fd2016-07-15 20:27:415691 SpdySerializedFrame body2(
5692 spdy_util_.ConstructSpdyDataFrame(3, "22", 2, true));
[email protected]f6c63db52013-02-02 00:35:225693
5694 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:415695 CreateMockWrite(get1, 0), CreateMockWrite(get2, 3),
[email protected]f6c63db52013-02-02 00:35:225696 };
5697
5698 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:415699 CreateMockRead(get_resp1, 1, ASYNC),
5700 CreateMockRead(body1, 2, ASYNC),
5701 CreateMockRead(get_resp2, 4, ASYNC),
5702 CreateMockRead(body2, 5, ASYNC),
5703 MockRead(ASYNC, 0, 6),
[email protected]f6c63db52013-02-02 00:35:225704 };
5705
mmenke11eb5152015-06-09 14:50:505706 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
5707 arraysize(spdy_writes));
5708 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]f6c63db52013-02-02 00:35:225709
5710 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:365711 ssl.next_proto = kProtoHTTP2;
mmenke11eb5152015-06-09 14:50:505712 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]f6c63db52013-02-02 00:35:225713
5714 TestCompletionCallback callback;
5715
bnc87dcefc2017-05-25 12:47:585716 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:195717 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:205718 int rv = trans->Start(&request1, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:015719 EXPECT_THAT(callback.GetResult(rv), IsOk());
[email protected]f6c63db52013-02-02 00:35:225720
5721 LoadTimingInfo load_timing_info;
5722 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
5723 TestLoadTimingNotReused(load_timing_info,
5724 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
5725
5726 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:525727 ASSERT_TRUE(response);
5728 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:025729 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]f6c63db52013-02-02 00:35:225730
5731 std::string response_data;
ttuttle859dc7a2015-04-23 19:42:295732 scoped_refptr<IOBuffer> buf(new IOBuffer(256));
mmenke11eb5152015-06-09 14:50:505733 rv = trans->Read(buf.get(), 256, callback.callback());
5734 EXPECT_EQ(1, callback.GetResult(rv));
[email protected]f6c63db52013-02-02 00:35:225735 // Delete the first request, so the second one can reuse the socket.
5736 trans.reset();
5737
bnc691fda62016-08-12 00:43:165738 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:205739 rv = trans2.Start(&request2, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:015740 EXPECT_THAT(callback.GetResult(rv), IsOk());
[email protected]f6c63db52013-02-02 00:35:225741
5742 LoadTimingInfo load_timing_info2;
bnc691fda62016-08-12 00:43:165743 EXPECT_TRUE(trans2.GetLoadTimingInfo(&load_timing_info2));
[email protected]f6c63db52013-02-02 00:35:225744 TestLoadTimingReused(load_timing_info2);
5745
5746 // The requests should have the same ID.
5747 EXPECT_EQ(load_timing_info.socket_log_id, load_timing_info2.socket_log_id);
5748
bnc691fda62016-08-12 00:43:165749 rv = trans2.Read(buf.get(), 256, callback.callback());
mmenke11eb5152015-06-09 14:50:505750 EXPECT_EQ(2, callback.GetResult(rv));
[email protected]f6c63db52013-02-02 00:35:225751}
5752
[email protected]2df19bb2010-08-25 20:13:465753// Test the challenge-response-retry sequence through an HTTPS Proxy
bncd16676a2016-07-20 16:23:015754TEST_F(HttpNetworkTransactionTest, HttpsProxyAuthRetry) {
[email protected]2df19bb2010-08-25 20:13:465755 HttpRequestInfo request;
5756 request.method = "GET";
bncce36dca22015-04-21 22:11:235757 request.url = GURL("http://www.example.org/");
[email protected]2df19bb2010-08-25 20:13:465758 // when the no authentication data flag is set.
ttuttle859dc7a2015-04-23 19:42:295759 request.load_flags = LOAD_DO_NOT_SEND_AUTH_DATA;
[email protected]2df19bb2010-08-25 20:13:465760
[email protected]79cb5c12011-09-12 13:12:045761 // Configure against https proxy server "myproxy:70".
rdsmith82957ad2015-09-16 19:42:035762 session_deps_.proxy_service = ProxyService::CreateFixed("https://myproxy:70");
vishal.b62985ca92015-04-17 08:45:515763 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:075764 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:095765 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:275766
[email protected]2df19bb2010-08-25 20:13:465767 // Since we have proxy, should use full url
5768 MockWrite data_writes1[] = {
bnc691fda62016-08-12 00:43:165769 MockWrite("GET http://www.example.org/ HTTP/1.1\r\n"
5770 "Host: www.example.org\r\n"
5771 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]2df19bb2010-08-25 20:13:465772
bnc691fda62016-08-12 00:43:165773 // After calling trans.RestartWithAuth(), this is the request we should
bncce36dca22015-04-21 22:11:235774 // be issuing -- the final header line contains the credentials.
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"
5778 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]2df19bb2010-08-25 20:13:465779 };
5780
5781 // The proxy responds to the GET with a 407, using a persistent
5782 // connection.
5783 MockRead data_reads1[] = {
5784 // No credentials.
5785 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
5786 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
5787 MockRead("Proxy-Connection: keep-alive\r\n"),
5788 MockRead("Content-Length: 0\r\n\r\n"),
5789
5790 MockRead("HTTP/1.1 200 OK\r\n"),
5791 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
5792 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:065793 MockRead(SYNCHRONOUS, OK),
[email protected]2df19bb2010-08-25 20:13:465794 };
5795
5796 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
5797 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:075798 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8ddf8322012-02-23 18:08:065799 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:075800 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]2df19bb2010-08-25 20:13:465801
[email protected]49639fa2011-12-20 23:22:415802 TestCompletionCallback callback1;
[email protected]2df19bb2010-08-25 20:13:465803
bnc691fda62016-08-12 00:43:165804 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]0b0bf032010-09-21 18:08:505805
bnc691fda62016-08-12 00:43:165806 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:015807 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2df19bb2010-08-25 20:13:465808
5809 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:015810 EXPECT_THAT(rv, IsOk());
[email protected]2df19bb2010-08-25 20:13:465811
[email protected]58e32bb2013-01-21 18:23:255812 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:165813 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]58e32bb2013-01-21 18:23:255814 TestLoadTimingNotReused(load_timing_info,
5815 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
5816
bnc691fda62016-08-12 00:43:165817 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:525818 ASSERT_TRUE(response);
5819 ASSERT_TRUE(response->headers);
[email protected]2df19bb2010-08-25 20:13:465820 EXPECT_EQ(407, response->headers->response_code());
5821 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
asanka098c0092016-06-16 20:18:435822 EXPECT_TRUE(CheckBasicSecureProxyAuth(response->auth_challenge.get()));
[email protected]2df19bb2010-08-25 20:13:465823
[email protected]49639fa2011-12-20 23:22:415824 TestCompletionCallback callback2;
[email protected]2df19bb2010-08-25 20:13:465825
bnc691fda62016-08-12 00:43:165826 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar), callback2.callback());
robpercival214763f2016-07-01 23:27:015827 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2df19bb2010-08-25 20:13:465828
5829 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:015830 EXPECT_THAT(rv, IsOk());
[email protected]2df19bb2010-08-25 20:13:465831
[email protected]58e32bb2013-01-21 18:23:255832 load_timing_info = LoadTimingInfo();
bnc691fda62016-08-12 00:43:165833 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]58e32bb2013-01-21 18:23:255834 // Retrying with HTTP AUTH is considered to be reusing a socket.
5835 TestLoadTimingReused(load_timing_info);
5836
bnc691fda62016-08-12 00:43:165837 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:525838 ASSERT_TRUE(response);
[email protected]2df19bb2010-08-25 20:13:465839
5840 EXPECT_TRUE(response->headers->IsKeepAlive());
5841 EXPECT_EQ(200, response->headers->response_code());
5842 EXPECT_EQ(100, response->headers->GetContentLength());
5843 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
5844
5845 // The password prompt info should not be set.
wezca1070932016-05-26 20:30:525846 EXPECT_FALSE(response->auth_challenge);
[email protected]2df19bb2010-08-25 20:13:465847}
5848
[email protected]23e482282013-06-14 16:08:025849void HttpNetworkTransactionTest::ConnectStatusHelperWithExpectedStatus(
[email protected]c744cf22009-02-27 07:28:085850 const MockRead& status, int expected_status) {
[email protected]1c773ea12009-04-28 19:58:425851 HttpRequestInfo request;
[email protected]c744cf22009-02-27 07:28:085852 request.method = "GET";
bncce36dca22015-04-21 22:11:235853 request.url = GURL("https://www.example.org/");
[email protected]c744cf22009-02-27 07:28:085854
[email protected]cb9bf6ca2011-01-28 13:15:275855 // Configure against proxy server "myproxy:70".
rdsmith82957ad2015-09-16 19:42:035856 session_deps_.proxy_service = ProxyService::CreateFixed("myproxy:70");
danakj1fd259a02016-04-16 03:17:095857 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:275858
[email protected]c744cf22009-02-27 07:28:085859 // Since we have proxy, should try to establish tunnel.
5860 MockWrite data_writes[] = {
rsleevidb16bb02015-11-12 23:47:175861 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
5862 "Host: www.example.org:443\r\n"
5863 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]c744cf22009-02-27 07:28:085864 };
5865
5866 MockRead data_reads[] = {
mmenked39192ee2015-12-09 00:57:235867 status, MockRead("Content-Length: 10\r\n\r\n"),
5868 // No response body because the test stops reading here.
5869 MockRead(SYNCHRONOUS, ERR_UNEXPECTED),
[email protected]c744cf22009-02-27 07:28:085870 };
5871
[email protected]31a2bfe2010-02-09 08:03:395872 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
5873 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:075874 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]c744cf22009-02-27 07:28:085875
[email protected]49639fa2011-12-20 23:22:415876 TestCompletionCallback callback;
[email protected]c744cf22009-02-27 07:28:085877
bnc691fda62016-08-12 00:43:165878 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]0b0bf032010-09-21 18:08:505879
tfarina42834112016-09-22 13:38:205880 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:015881 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]c744cf22009-02-27 07:28:085882
5883 rv = callback.WaitForResult();
5884 EXPECT_EQ(expected_status, rv);
5885}
5886
[email protected]23e482282013-06-14 16:08:025887void HttpNetworkTransactionTest::ConnectStatusHelper(
[email protected]448d4ca52012-03-04 04:12:235888 const MockRead& status) {
[email protected]c744cf22009-02-27 07:28:085889 ConnectStatusHelperWithExpectedStatus(
[email protected]1c773ea12009-04-28 19:58:425890 status, ERR_TUNNEL_CONNECTION_FAILED);
[email protected]c744cf22009-02-27 07:28:085891}
5892
bncd16676a2016-07-20 16:23:015893TEST_F(HttpNetworkTransactionTest, ConnectStatus100) {
[email protected]c744cf22009-02-27 07:28:085894 ConnectStatusHelper(MockRead("HTTP/1.1 100 Continue\r\n"));
5895}
5896
bncd16676a2016-07-20 16:23:015897TEST_F(HttpNetworkTransactionTest, ConnectStatus101) {
[email protected]c744cf22009-02-27 07:28:085898 ConnectStatusHelper(MockRead("HTTP/1.1 101 Switching Protocols\r\n"));
5899}
5900
bncd16676a2016-07-20 16:23:015901TEST_F(HttpNetworkTransactionTest, ConnectStatus201) {
[email protected]c744cf22009-02-27 07:28:085902 ConnectStatusHelper(MockRead("HTTP/1.1 201 Created\r\n"));
5903}
5904
bncd16676a2016-07-20 16:23:015905TEST_F(HttpNetworkTransactionTest, ConnectStatus202) {
[email protected]c744cf22009-02-27 07:28:085906 ConnectStatusHelper(MockRead("HTTP/1.1 202 Accepted\r\n"));
5907}
5908
bncd16676a2016-07-20 16:23:015909TEST_F(HttpNetworkTransactionTest, ConnectStatus203) {
[email protected]c744cf22009-02-27 07:28:085910 ConnectStatusHelper(
5911 MockRead("HTTP/1.1 203 Non-Authoritative Information\r\n"));
5912}
5913
bncd16676a2016-07-20 16:23:015914TEST_F(HttpNetworkTransactionTest, ConnectStatus204) {
[email protected]c744cf22009-02-27 07:28:085915 ConnectStatusHelper(MockRead("HTTP/1.1 204 No Content\r\n"));
5916}
5917
bncd16676a2016-07-20 16:23:015918TEST_F(HttpNetworkTransactionTest, ConnectStatus205) {
[email protected]c744cf22009-02-27 07:28:085919 ConnectStatusHelper(MockRead("HTTP/1.1 205 Reset Content\r\n"));
5920}
5921
bncd16676a2016-07-20 16:23:015922TEST_F(HttpNetworkTransactionTest, ConnectStatus206) {
[email protected]c744cf22009-02-27 07:28:085923 ConnectStatusHelper(MockRead("HTTP/1.1 206 Partial Content\r\n"));
5924}
5925
bncd16676a2016-07-20 16:23:015926TEST_F(HttpNetworkTransactionTest, ConnectStatus300) {
[email protected]c744cf22009-02-27 07:28:085927 ConnectStatusHelper(MockRead("HTTP/1.1 300 Multiple Choices\r\n"));
5928}
5929
bncd16676a2016-07-20 16:23:015930TEST_F(HttpNetworkTransactionTest, ConnectStatus301) {
[email protected]c744cf22009-02-27 07:28:085931 ConnectStatusHelper(MockRead("HTTP/1.1 301 Moved Permanently\r\n"));
5932}
5933
bncd16676a2016-07-20 16:23:015934TEST_F(HttpNetworkTransactionTest, ConnectStatus302) {
[email protected]c744cf22009-02-27 07:28:085935 ConnectStatusHelper(MockRead("HTTP/1.1 302 Found\r\n"));
5936}
5937
bncd16676a2016-07-20 16:23:015938TEST_F(HttpNetworkTransactionTest, ConnectStatus303) {
[email protected]c744cf22009-02-27 07:28:085939 ConnectStatusHelper(MockRead("HTTP/1.1 303 See Other\r\n"));
5940}
5941
bncd16676a2016-07-20 16:23:015942TEST_F(HttpNetworkTransactionTest, ConnectStatus304) {
[email protected]c744cf22009-02-27 07:28:085943 ConnectStatusHelper(MockRead("HTTP/1.1 304 Not Modified\r\n"));
5944}
5945
bncd16676a2016-07-20 16:23:015946TEST_F(HttpNetworkTransactionTest, ConnectStatus305) {
[email protected]c744cf22009-02-27 07:28:085947 ConnectStatusHelper(MockRead("HTTP/1.1 305 Use Proxy\r\n"));
5948}
5949
bncd16676a2016-07-20 16:23:015950TEST_F(HttpNetworkTransactionTest, ConnectStatus306) {
[email protected]c744cf22009-02-27 07:28:085951 ConnectStatusHelper(MockRead("HTTP/1.1 306\r\n"));
5952}
5953
bncd16676a2016-07-20 16:23:015954TEST_F(HttpNetworkTransactionTest, ConnectStatus307) {
[email protected]c744cf22009-02-27 07:28:085955 ConnectStatusHelper(MockRead("HTTP/1.1 307 Temporary Redirect\r\n"));
5956}
5957
bncd16676a2016-07-20 16:23:015958TEST_F(HttpNetworkTransactionTest, ConnectStatus308) {
[email protected]0a17aab32014-04-24 03:32:375959 ConnectStatusHelper(MockRead("HTTP/1.1 308 Permanent Redirect\r\n"));
5960}
5961
bncd16676a2016-07-20 16:23:015962TEST_F(HttpNetworkTransactionTest, ConnectStatus400) {
[email protected]c744cf22009-02-27 07:28:085963 ConnectStatusHelper(MockRead("HTTP/1.1 400 Bad Request\r\n"));
5964}
5965
bncd16676a2016-07-20 16:23:015966TEST_F(HttpNetworkTransactionTest, ConnectStatus401) {
[email protected]c744cf22009-02-27 07:28:085967 ConnectStatusHelper(MockRead("HTTP/1.1 401 Unauthorized\r\n"));
5968}
5969
bncd16676a2016-07-20 16:23:015970TEST_F(HttpNetworkTransactionTest, ConnectStatus402) {
[email protected]c744cf22009-02-27 07:28:085971 ConnectStatusHelper(MockRead("HTTP/1.1 402 Payment Required\r\n"));
5972}
5973
bncd16676a2016-07-20 16:23:015974TEST_F(HttpNetworkTransactionTest, ConnectStatus403) {
[email protected]c744cf22009-02-27 07:28:085975 ConnectStatusHelper(MockRead("HTTP/1.1 403 Forbidden\r\n"));
5976}
5977
bncd16676a2016-07-20 16:23:015978TEST_F(HttpNetworkTransactionTest, ConnectStatus404) {
[email protected]c744cf22009-02-27 07:28:085979 ConnectStatusHelper(MockRead("HTTP/1.1 404 Not Found\r\n"));
5980}
5981
bncd16676a2016-07-20 16:23:015982TEST_F(HttpNetworkTransactionTest, ConnectStatus405) {
[email protected]c744cf22009-02-27 07:28:085983 ConnectStatusHelper(MockRead("HTTP/1.1 405 Method Not Allowed\r\n"));
5984}
5985
bncd16676a2016-07-20 16:23:015986TEST_F(HttpNetworkTransactionTest, ConnectStatus406) {
[email protected]c744cf22009-02-27 07:28:085987 ConnectStatusHelper(MockRead("HTTP/1.1 406 Not Acceptable\r\n"));
5988}
5989
bncd16676a2016-07-20 16:23:015990TEST_F(HttpNetworkTransactionTest, ConnectStatus407) {
[email protected]c744cf22009-02-27 07:28:085991 ConnectStatusHelperWithExpectedStatus(
5992 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
[email protected]a7ea8832010-07-12 17:54:545993 ERR_PROXY_AUTH_UNSUPPORTED);
[email protected]c744cf22009-02-27 07:28:085994}
5995
bncd16676a2016-07-20 16:23:015996TEST_F(HttpNetworkTransactionTest, ConnectStatus408) {
[email protected]c744cf22009-02-27 07:28:085997 ConnectStatusHelper(MockRead("HTTP/1.1 408 Request Timeout\r\n"));
5998}
5999
bncd16676a2016-07-20 16:23:016000TEST_F(HttpNetworkTransactionTest, ConnectStatus409) {
[email protected]c744cf22009-02-27 07:28:086001 ConnectStatusHelper(MockRead("HTTP/1.1 409 Conflict\r\n"));
6002}
6003
bncd16676a2016-07-20 16:23:016004TEST_F(HttpNetworkTransactionTest, ConnectStatus410) {
[email protected]c744cf22009-02-27 07:28:086005 ConnectStatusHelper(MockRead("HTTP/1.1 410 Gone\r\n"));
6006}
6007
bncd16676a2016-07-20 16:23:016008TEST_F(HttpNetworkTransactionTest, ConnectStatus411) {
[email protected]c744cf22009-02-27 07:28:086009 ConnectStatusHelper(MockRead("HTTP/1.1 411 Length Required\r\n"));
6010}
6011
bncd16676a2016-07-20 16:23:016012TEST_F(HttpNetworkTransactionTest, ConnectStatus412) {
[email protected]c744cf22009-02-27 07:28:086013 ConnectStatusHelper(MockRead("HTTP/1.1 412 Precondition Failed\r\n"));
6014}
6015
bncd16676a2016-07-20 16:23:016016TEST_F(HttpNetworkTransactionTest, ConnectStatus413) {
[email protected]c744cf22009-02-27 07:28:086017 ConnectStatusHelper(MockRead("HTTP/1.1 413 Request Entity Too Large\r\n"));
6018}
6019
bncd16676a2016-07-20 16:23:016020TEST_F(HttpNetworkTransactionTest, ConnectStatus414) {
[email protected]c744cf22009-02-27 07:28:086021 ConnectStatusHelper(MockRead("HTTP/1.1 414 Request-URI Too Long\r\n"));
6022}
6023
bncd16676a2016-07-20 16:23:016024TEST_F(HttpNetworkTransactionTest, ConnectStatus415) {
[email protected]c744cf22009-02-27 07:28:086025 ConnectStatusHelper(MockRead("HTTP/1.1 415 Unsupported Media Type\r\n"));
6026}
6027
bncd16676a2016-07-20 16:23:016028TEST_F(HttpNetworkTransactionTest, ConnectStatus416) {
[email protected]c744cf22009-02-27 07:28:086029 ConnectStatusHelper(
6030 MockRead("HTTP/1.1 416 Requested Range Not Satisfiable\r\n"));
6031}
6032
bncd16676a2016-07-20 16:23:016033TEST_F(HttpNetworkTransactionTest, ConnectStatus417) {
[email protected]c744cf22009-02-27 07:28:086034 ConnectStatusHelper(MockRead("HTTP/1.1 417 Expectation Failed\r\n"));
6035}
6036
bncd16676a2016-07-20 16:23:016037TEST_F(HttpNetworkTransactionTest, ConnectStatus500) {
[email protected]c744cf22009-02-27 07:28:086038 ConnectStatusHelper(MockRead("HTTP/1.1 500 Internal Server Error\r\n"));
6039}
6040
bncd16676a2016-07-20 16:23:016041TEST_F(HttpNetworkTransactionTest, ConnectStatus501) {
[email protected]c744cf22009-02-27 07:28:086042 ConnectStatusHelper(MockRead("HTTP/1.1 501 Not Implemented\r\n"));
6043}
6044
bncd16676a2016-07-20 16:23:016045TEST_F(HttpNetworkTransactionTest, ConnectStatus502) {
[email protected]c744cf22009-02-27 07:28:086046 ConnectStatusHelper(MockRead("HTTP/1.1 502 Bad Gateway\r\n"));
6047}
6048
bncd16676a2016-07-20 16:23:016049TEST_F(HttpNetworkTransactionTest, ConnectStatus503) {
[email protected]c744cf22009-02-27 07:28:086050 ConnectStatusHelper(MockRead("HTTP/1.1 503 Service Unavailable\r\n"));
6051}
6052
bncd16676a2016-07-20 16:23:016053TEST_F(HttpNetworkTransactionTest, ConnectStatus504) {
[email protected]c744cf22009-02-27 07:28:086054 ConnectStatusHelper(MockRead("HTTP/1.1 504 Gateway Timeout\r\n"));
6055}
6056
bncd16676a2016-07-20 16:23:016057TEST_F(HttpNetworkTransactionTest, ConnectStatus505) {
[email protected]c744cf22009-02-27 07:28:086058 ConnectStatusHelper(MockRead("HTTP/1.1 505 HTTP Version Not Supported\r\n"));
6059}
6060
[email protected]038e9a32008-10-08 22:40:166061// Test the flow when both the proxy server AND origin server require
6062// authentication. Again, this uses basic auth for both since that is
6063// the simplest to mock.
bncd16676a2016-07-20 16:23:016064TEST_F(HttpNetworkTransactionTest, BasicAuthProxyThenServer) {
[email protected]cb9bf6ca2011-01-28 13:15:276065 HttpRequestInfo request;
6066 request.method = "GET";
bncce36dca22015-04-21 22:11:236067 request.url = GURL("http://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:276068
[email protected]038e9a32008-10-08 22:40:166069 // Configure against proxy server "myproxy:70".
rdsmith82957ad2015-09-16 19:42:036070 session_deps_.proxy_service = ProxyService::CreateFixed("myproxy:70");
danakj1fd259a02016-04-16 03:17:096071 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]3fe8d2f82013-10-17 08:56:076072
bnc691fda62016-08-12 00:43:166073 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]038e9a32008-10-08 22:40:166074
[email protected]f9ee6b52008-11-08 06:46:236075 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:236076 MockWrite(
6077 "GET http://www.example.org/ HTTP/1.1\r\n"
6078 "Host: www.example.org\r\n"
6079 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:236080 };
6081
[email protected]038e9a32008-10-08 22:40:166082 MockRead data_reads1[] = {
6083 MockRead("HTTP/1.0 407 Unauthorized\r\n"),
6084 // Give a couple authenticate options (only the middle one is actually
6085 // supported).
[email protected]22927ad2009-09-21 19:56:196086 MockRead("Proxy-Authenticate: Basic invalid\r\n"), // Malformed.
[email protected]038e9a32008-10-08 22:40:166087 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
6088 MockRead("Proxy-Authenticate: UNSUPPORTED realm=\"FOO\"\r\n"),
6089 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
6090 // Large content-length -- won't matter, as connection will be reset.
6091 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:066092 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]038e9a32008-10-08 22:40:166093 };
6094
bnc691fda62016-08-12 00:43:166095 // After calling trans.RestartWithAuth() the first time, this is the
[email protected]038e9a32008-10-08 22:40:166096 // request we should be issuing -- the final header line contains the
6097 // proxy's credentials.
6098 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:236099 MockWrite(
6100 "GET http://www.example.org/ HTTP/1.1\r\n"
6101 "Host: www.example.org\r\n"
6102 "Proxy-Connection: keep-alive\r\n"
6103 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]038e9a32008-10-08 22:40:166104 };
6105
6106 // Now the proxy server lets the request pass through to origin server.
6107 // The origin server responds with a 401.
6108 MockRead data_reads2[] = {
6109 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
6110 // Note: We are using the same realm-name as the proxy server. This is
6111 // completely valid, as realms are unique across hosts.
6112 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
6113 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
6114 MockRead("Content-Length: 2000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:066115 MockRead(SYNCHRONOUS, ERR_FAILED), // Won't be reached.
[email protected]038e9a32008-10-08 22:40:166116 };
6117
bnc691fda62016-08-12 00:43:166118 // After calling trans.RestartWithAuth() the second time, we should send
[email protected]038e9a32008-10-08 22:40:166119 // the credentials for both the proxy and origin server.
6120 MockWrite data_writes3[] = {
bncce36dca22015-04-21 22:11:236121 MockWrite(
6122 "GET http://www.example.org/ HTTP/1.1\r\n"
6123 "Host: www.example.org\r\n"
6124 "Proxy-Connection: keep-alive\r\n"
6125 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n"
6126 "Authorization: Basic Zm9vMjpiYXIy\r\n\r\n"),
[email protected]038e9a32008-10-08 22:40:166127 };
6128
6129 // Lastly we get the desired content.
6130 MockRead data_reads3[] = {
6131 MockRead("HTTP/1.0 200 OK\r\n"),
6132 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
6133 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:066134 MockRead(SYNCHRONOUS, OK),
[email protected]038e9a32008-10-08 22:40:166135 };
6136
[email protected]31a2bfe2010-02-09 08:03:396137 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
6138 data_writes1, arraysize(data_writes1));
6139 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
6140 data_writes2, arraysize(data_writes2));
6141 StaticSocketDataProvider data3(data_reads3, arraysize(data_reads3),
6142 data_writes3, arraysize(data_writes3));
[email protected]bb88e1d32013-05-03 23:11:076143 session_deps_.socket_factory->AddSocketDataProvider(&data1);
6144 session_deps_.socket_factory->AddSocketDataProvider(&data2);
6145 session_deps_.socket_factory->AddSocketDataProvider(&data3);
[email protected]038e9a32008-10-08 22:40:166146
[email protected]49639fa2011-12-20 23:22:416147 TestCompletionCallback callback1;
[email protected]038e9a32008-10-08 22:40:166148
tfarina42834112016-09-22 13:38:206149 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:016150 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]038e9a32008-10-08 22:40:166151
6152 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:016153 EXPECT_THAT(rv, IsOk());
[email protected]038e9a32008-10-08 22:40:166154
bnc691fda62016-08-12 00:43:166155 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:526156 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:046157 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
[email protected]038e9a32008-10-08 22:40:166158
[email protected]49639fa2011-12-20 23:22:416159 TestCompletionCallback callback2;
[email protected]038e9a32008-10-08 22:40:166160
bnc691fda62016-08-12 00:43:166161 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar), callback2.callback());
robpercival214763f2016-07-01 23:27:016162 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]038e9a32008-10-08 22:40:166163
6164 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:016165 EXPECT_THAT(rv, IsOk());
[email protected]038e9a32008-10-08 22:40:166166
bnc691fda62016-08-12 00:43:166167 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:526168 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:046169 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]038e9a32008-10-08 22:40:166170
[email protected]49639fa2011-12-20 23:22:416171 TestCompletionCallback callback3;
[email protected]038e9a32008-10-08 22:40:166172
bnc691fda62016-08-12 00:43:166173 rv = trans.RestartWithAuth(AuthCredentials(kFoo2, kBar2),
6174 callback3.callback());
robpercival214763f2016-07-01 23:27:016175 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]038e9a32008-10-08 22:40:166176
6177 rv = callback3.WaitForResult();
robpercival214763f2016-07-01 23:27:016178 EXPECT_THAT(rv, IsOk());
[email protected]038e9a32008-10-08 22:40:166179
bnc691fda62016-08-12 00:43:166180 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:526181 EXPECT_FALSE(response->auth_challenge);
[email protected]038e9a32008-10-08 22:40:166182 EXPECT_EQ(100, response->headers->GetContentLength());
[email protected]038e9a32008-10-08 22:40:166183}
[email protected]4ddaf2502008-10-23 18:26:196184
[email protected]ea9dc9a2009-09-05 00:43:326185// For the NTLM implementation using SSPI, we skip the NTLM tests since we
6186// can't hook into its internals to cause it to generate predictable NTLM
6187// authorization headers.
6188#if defined(NTLM_PORTABLE)
Zentaro Kavanagh5b27a6e22017-09-25 23:00:376189// The NTLM authentication unit tests are based on known test data from the
6190// [MS-NLMP] Specification [1]. These tests are primarily of the authentication
6191// flow rather than the implementation of the NTLM protocol. See net/ntlm
6192// for the implementation and testing of the protocol.
6193//
6194// [1] https://msdn.microsoft.com/en-us/library/cc236621.aspx
[email protected]385a4672009-03-11 22:21:296195
6196// Enter the correct password and authenticate successfully.
Zentaro Kavanagh5b27a6e22017-09-25 23:00:376197TEST_F(HttpNetworkTransactionTest, NTLMAuthV1) {
[email protected]1c773ea12009-04-28 19:58:426198 HttpRequestInfo request;
[email protected]3f918782009-02-28 01:29:246199 request.method = "GET";
Bence Béky83eb3512017-09-05 12:56:096200 request.url = GURL("https://172.22.68.17/kids/login.aspx");
[email protected]2217aa22013-10-11 03:03:546201
6202 // Ensure load is not disrupted by flags which suppress behaviour specific
6203 // to other auth schemes.
6204 request.load_flags = LOAD_DO_NOT_USE_EMBEDDED_IDENTITY;
[email protected]3f918782009-02-28 01:29:246205
Zentaro Kavanagh6ccee512017-09-28 18:34:096206 HttpAuthHandlerNTLM::ScopedProcSetter proc_setter(
6207 MockGetMSTime, MockGenerateRandom, MockGetHostName);
danakj1fd259a02016-04-16 03:17:096208 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:276209
Zentaro Kavanagh5b27a6e22017-09-25 23:00:376210 // Generate the NTLM messages based on known test data.
6211 std::string negotiate_msg;
6212 std::string challenge_msg;
6213 std::string authenticate_msg;
6214 base::Base64Encode(
6215 base::StringPiece(
6216 reinterpret_cast<const char*>(ntlm::test::kExpectedNegotiateMsg),
6217 arraysize(ntlm::test::kExpectedNegotiateMsg)),
6218 &negotiate_msg);
6219 base::Base64Encode(base::StringPiece(reinterpret_cast<const char*>(
6220 ntlm::test::kChallengeMsgV1),
6221 arraysize(ntlm::test::kChallengeMsgV1)),
6222 &challenge_msg);
6223 base::Base64Encode(
6224 base::StringPiece(
Zentaro Kavanagh6ccee512017-09-28 18:34:096225 reinterpret_cast<const char*>(
6226 ntlm::test::kExpectedAuthenticateMsgSpecResponseV1),
6227 arraysize(ntlm::test::kExpectedAuthenticateMsgSpecResponseV1)),
Zentaro Kavanagh5b27a6e22017-09-25 23:00:376228 &authenticate_msg);
6229
[email protected]3f918782009-02-28 01:29:246230 MockWrite data_writes1[] = {
6231 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
6232 "Host: 172.22.68.17\r\n"
6233 "Connection: keep-alive\r\n\r\n"),
6234 };
6235
6236 MockRead data_reads1[] = {
6237 MockRead("HTTP/1.1 401 Access Denied\r\n"),
[email protected]aef04272010-06-28 18:03:046238 // Negotiate and NTLM are often requested together. However, we only want
6239 // to test NTLM. Since Negotiate is preferred over NTLM, we have to skip
6240 // the header that requests Negotiate for this test.
[email protected]3f918782009-02-28 01:29:246241 MockRead("WWW-Authenticate: NTLM\r\n"),
6242 MockRead("Connection: close\r\n"),
6243 MockRead("Content-Length: 42\r\n"),
[email protected]076c85082009-04-10 23:21:366244 MockRead("Content-Type: text/html\r\n\r\n"),
[email protected]3f918782009-02-28 01:29:246245 // Missing content -- won't matter, as connection will be reset.
[email protected]3f918782009-02-28 01:29:246246 };
6247
6248 MockWrite data_writes2[] = {
bnc691fda62016-08-12 00:43:166249 // After restarting with a null identity, this is the
6250 // request we should be issuing -- the final header line contains a Type
6251 // 1 message.
6252 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
6253 "Host: 172.22.68.17\r\n"
6254 "Connection: keep-alive\r\n"
Zentaro Kavanagh5b27a6e22017-09-25 23:00:376255 "Authorization: NTLM "),
6256 MockWrite(negotiate_msg.c_str()), MockWrite("\r\n\r\n"),
[email protected]3f918782009-02-28 01:29:246257
bnc691fda62016-08-12 00:43:166258 // After calling trans.RestartWithAuth(), we should send a Type 3 message
Zentaro Kavanagh5b27a6e22017-09-25 23:00:376259 // (using correct credentials). The second request continues on the
6260 // same connection.
bnc691fda62016-08-12 00:43:166261 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
6262 "Host: 172.22.68.17\r\n"
6263 "Connection: keep-alive\r\n"
Zentaro Kavanagh5b27a6e22017-09-25 23:00:376264 "Authorization: NTLM "),
6265 MockWrite(authenticate_msg.c_str()), MockWrite("\r\n\r\n"),
[email protected]3f918782009-02-28 01:29:246266 };
6267
6268 MockRead data_reads2[] = {
Bence Béky1e4ef192017-09-18 19:58:026269 // The origin server responds with a Type 2 message.
6270 MockRead("HTTP/1.1 401 Access Denied\r\n"),
Zentaro Kavanagh5b27a6e22017-09-25 23:00:376271 MockRead("WWW-Authenticate: NTLM "), MockRead(challenge_msg.c_str()),
6272 MockRead("\r\n"), MockRead("Content-Length: 42\r\n"),
Bence Béky1e4ef192017-09-18 19:58:026273 MockRead("Content-Type: text/html\r\n\r\n"),
6274 MockRead("You are not authorized to view this page\r\n"),
[email protected]3f918782009-02-28 01:29:246275
Bence Béky1e4ef192017-09-18 19:58:026276 // Lastly we get the desired content.
6277 MockRead("HTTP/1.1 200 OK\r\n"),
6278 MockRead("Content-Type: text/html; charset=utf-8\r\n"),
6279 MockRead("Content-Length: 14\r\n\r\n"), MockRead("Please Login\r\n"),
[email protected]3f918782009-02-28 01:29:246280 };
6281
[email protected]31a2bfe2010-02-09 08:03:396282 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
6283 data_writes1, arraysize(data_writes1));
6284 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
6285 data_writes2, arraysize(data_writes2));
[email protected]bb88e1d32013-05-03 23:11:076286 session_deps_.socket_factory->AddSocketDataProvider(&data1);
6287 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]3f918782009-02-28 01:29:246288
Bence Béky83eb3512017-09-05 12:56:096289 SSLSocketDataProvider ssl1(ASYNC, OK);
6290 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl1);
6291 SSLSocketDataProvider ssl2(ASYNC, OK);
6292 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
6293
[email protected]49639fa2011-12-20 23:22:416294 TestCompletionCallback callback1;
[email protected]3f918782009-02-28 01:29:246295
bnc691fda62016-08-12 00:43:166296 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]0b0bf032010-09-21 18:08:506297
tfarina42834112016-09-22 13:38:206298 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:016299 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]3f918782009-02-28 01:29:246300
6301 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:016302 EXPECT_THAT(rv, IsOk());
[email protected]3f918782009-02-28 01:29:246303
bnc691fda62016-08-12 00:43:166304 EXPECT_FALSE(trans.IsReadyToRestartForAuth());
[email protected]0757e7702009-03-27 04:00:226305
bnc691fda62016-08-12 00:43:166306 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:526307 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:046308 EXPECT_TRUE(CheckNTLMServerAuth(response->auth_challenge.get()));
[email protected]3f918782009-02-28 01:29:246309
[email protected]49639fa2011-12-20 23:22:416310 TestCompletionCallback callback2;
[email protected]10af5fe72011-01-31 16:17:256311
Zentaro Kavanagh5b27a6e22017-09-25 23:00:376312 rv = trans.RestartWithAuth(
6313 AuthCredentials(ntlm::test::kDomainUserCombined, ntlm::test::kPassword),
6314 callback2.callback());
robpercival214763f2016-07-01 23:27:016315 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]10af5fe72011-01-31 16:17:256316
6317 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:016318 EXPECT_THAT(rv, IsOk());
[email protected]10af5fe72011-01-31 16:17:256319
bnc691fda62016-08-12 00:43:166320 EXPECT_TRUE(trans.IsReadyToRestartForAuth());
[email protected]10af5fe72011-01-31 16:17:256321
bnc691fda62016-08-12 00:43:166322 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:526323 ASSERT_TRUE(response);
6324 EXPECT_FALSE(response->auth_challenge);
[email protected]10af5fe72011-01-31 16:17:256325
[email protected]49639fa2011-12-20 23:22:416326 TestCompletionCallback callback3;
[email protected]3f918782009-02-28 01:29:246327
bnc691fda62016-08-12 00:43:166328 rv = trans.RestartWithAuth(AuthCredentials(), callback3.callback());
robpercival214763f2016-07-01 23:27:016329 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]3f918782009-02-28 01:29:246330
[email protected]0757e7702009-03-27 04:00:226331 rv = callback3.WaitForResult();
robpercival214763f2016-07-01 23:27:016332 EXPECT_THAT(rv, IsOk());
[email protected]3f918782009-02-28 01:29:246333
bnc691fda62016-08-12 00:43:166334 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:526335 ASSERT_TRUE(response);
6336 EXPECT_FALSE(response->auth_challenge);
Bence Béky1e4ef192017-09-18 19:58:026337 EXPECT_EQ(14, response->headers->GetContentLength());
6338
6339 std::string response_data;
6340 rv = ReadTransaction(&trans, &response_data);
6341 EXPECT_THAT(rv, IsOk());
6342 EXPECT_EQ("Please Login\r\n", response_data);
6343
6344 EXPECT_TRUE(data1.AllReadDataConsumed());
6345 EXPECT_TRUE(data1.AllWriteDataConsumed());
6346 EXPECT_TRUE(data2.AllReadDataConsumed());
6347 EXPECT_TRUE(data2.AllWriteDataConsumed());
[email protected]3f918782009-02-28 01:29:246348}
6349
[email protected]385a4672009-03-11 22:21:296350// Enter a wrong password, and then the correct one.
Zentaro Kavanagh5b27a6e22017-09-25 23:00:376351TEST_F(HttpNetworkTransactionTest, NTLMAuthV1WrongThenRightPassword) {
[email protected]1c773ea12009-04-28 19:58:426352 HttpRequestInfo request;
[email protected]385a4672009-03-11 22:21:296353 request.method = "GET";
Bence Béky83eb3512017-09-05 12:56:096354 request.url = GURL("https://172.22.68.17/kids/login.aspx");
[email protected]385a4672009-03-11 22:21:296355
Zentaro Kavanagh6ccee512017-09-28 18:34:096356 HttpAuthHandlerNTLM::ScopedProcSetter proc_setter(
6357 MockGetMSTime, MockGenerateRandom, MockGetHostName);
danakj1fd259a02016-04-16 03:17:096358 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:276359
Zentaro Kavanagh5b27a6e22017-09-25 23:00:376360 // Generate the NTLM messages based on known test data.
6361 std::string negotiate_msg;
6362 std::string challenge_msg;
6363 std::string authenticate_msg;
6364 base::Base64Encode(
6365 base::StringPiece(
6366 reinterpret_cast<const char*>(ntlm::test::kExpectedNegotiateMsg),
6367 arraysize(ntlm::test::kExpectedNegotiateMsg)),
6368 &negotiate_msg);
6369 base::Base64Encode(base::StringPiece(reinterpret_cast<const char*>(
6370 ntlm::test::kChallengeMsgV1),
6371 arraysize(ntlm::test::kChallengeMsgV1)),
6372 &challenge_msg);
6373 base::Base64Encode(
6374 base::StringPiece(
Zentaro Kavanagh6ccee512017-09-28 18:34:096375 reinterpret_cast<const char*>(
6376 ntlm::test::kExpectedAuthenticateMsgSpecResponseV1),
6377 arraysize(ntlm::test::kExpectedAuthenticateMsgSpecResponseV1)),
Zentaro Kavanagh5b27a6e22017-09-25 23:00:376378 &authenticate_msg);
6379
6380 // The authenticate message when |kWrongPassword| is sent.
6381 std::string wrong_password_authenticate_msg(
6382 "TlRMTVNTUAADAAAAGAAYAEAAAAAYABgAWAAAAAwADABwAAAACAAIAHwAAAAQABAAhAAAAAAA"
6383 "AABAAAAAA4IIAKqqqqqqqqqqAAAAAAAAAAAAAAAAAAAAAF2npafgDxlql9qxEIhLlsuuJIEd"
6384 "NQHk7kQAbwBtAGEAaQBuAFUAcwBlAHIAQwBPAE0AUABVAFQARQBSAA==");
6385
6386 // Sanity check that this is the same as |authenticate_msg| except for the
6387 // 24 bytes (32 encoded chars) of the NTLM Response.
6388 ASSERT_EQ(authenticate_msg.length(),
6389 wrong_password_authenticate_msg.length());
Zentaro Kavanagh6ccee512017-09-28 18:34:096390 ASSERT_EQ(authenticate_msg.length(), 200u);
Zentaro Kavanagh5b27a6e22017-09-25 23:00:376391 ASSERT_EQ(base::StringPiece(authenticate_msg.data(), 117),
6392 base::StringPiece(wrong_password_authenticate_msg.data(), 117));
6393 ASSERT_EQ(
6394 base::StringPiece(authenticate_msg.data() + 149, 51),
6395 base::StringPiece(wrong_password_authenticate_msg.data() + 149, 51));
6396
[email protected]385a4672009-03-11 22:21:296397 MockWrite data_writes1[] = {
6398 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
6399 "Host: 172.22.68.17\r\n"
6400 "Connection: keep-alive\r\n\r\n"),
6401 };
6402
6403 MockRead data_reads1[] = {
6404 MockRead("HTTP/1.1 401 Access Denied\r\n"),
[email protected]aef04272010-06-28 18:03:046405 // Negotiate and NTLM are often requested together. However, we only want
6406 // to test NTLM. Since Negotiate is preferred over NTLM, we have to skip
6407 // the header that requests Negotiate for this test.
[email protected]385a4672009-03-11 22:21:296408 MockRead("WWW-Authenticate: NTLM\r\n"),
6409 MockRead("Connection: close\r\n"),
6410 MockRead("Content-Length: 42\r\n"),
[email protected]076c85082009-04-10 23:21:366411 MockRead("Content-Type: text/html\r\n\r\n"),
[email protected]385a4672009-03-11 22:21:296412 // Missing content -- won't matter, as connection will be reset.
[email protected]385a4672009-03-11 22:21:296413 };
6414
6415 MockWrite data_writes2[] = {
bnc691fda62016-08-12 00:43:166416 // After restarting with a null identity, this is the
6417 // request we should be issuing -- the final header line contains a Type
6418 // 1 message.
6419 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
6420 "Host: 172.22.68.17\r\n"
6421 "Connection: keep-alive\r\n"
Zentaro Kavanagh5b27a6e22017-09-25 23:00:376422 "Authorization: NTLM "),
6423 MockWrite(negotiate_msg.c_str()), MockWrite("\r\n\r\n"),
[email protected]385a4672009-03-11 22:21:296424
bnc691fda62016-08-12 00:43:166425 // After calling trans.RestartWithAuth(), we should send a Type 3 message
Zentaro Kavanagh5b27a6e22017-09-25 23:00:376426 // (using incorrect credentials). The second request continues on the
6427 // same connection.
bnc691fda62016-08-12 00:43:166428 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
6429 "Host: 172.22.68.17\r\n"
6430 "Connection: keep-alive\r\n"
Zentaro Kavanagh5b27a6e22017-09-25 23:00:376431 "Authorization: NTLM "),
6432 MockWrite(wrong_password_authenticate_msg.c_str()), MockWrite("\r\n\r\n"),
[email protected]385a4672009-03-11 22:21:296433 };
6434
6435 MockRead data_reads2[] = {
Zentaro Kavanagh5b27a6e22017-09-25 23:00:376436 // The origin server responds with a Type 2 message.
6437 MockRead("HTTP/1.1 401 Access Denied\r\n"),
6438 MockRead("WWW-Authenticate: NTLM "), MockRead(challenge_msg.c_str()),
6439 MockRead("\r\n"), MockRead("Content-Length: 42\r\n"),
6440 MockRead("Content-Type: text/html\r\n\r\n"),
6441 MockRead("You are not authorized to view this page\r\n"),
[email protected]385a4672009-03-11 22:21:296442
Zentaro Kavanagh5b27a6e22017-09-25 23:00:376443 // Wrong password.
6444 MockRead("HTTP/1.1 401 Access Denied\r\n"),
6445 MockRead("WWW-Authenticate: NTLM\r\n"), MockRead("Connection: close\r\n"),
6446 MockRead("Content-Length: 42\r\n"),
6447 MockRead("Content-Type: text/html\r\n\r\n"),
6448 // Missing content -- won't matter, as connection will be reset.
[email protected]385a4672009-03-11 22:21:296449 };
6450
6451 MockWrite data_writes3[] = {
bnc691fda62016-08-12 00:43:166452 // After restarting with a null identity, this is the
6453 // request we should be issuing -- the final header line contains a Type
6454 // 1 message.
6455 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
6456 "Host: 172.22.68.17\r\n"
6457 "Connection: keep-alive\r\n"
Zentaro Kavanagh5b27a6e22017-09-25 23:00:376458 "Authorization: NTLM "),
6459 MockWrite(negotiate_msg.c_str()), MockWrite("\r\n\r\n"),
[email protected]385a4672009-03-11 22:21:296460
bnc691fda62016-08-12 00:43:166461 // After calling trans.RestartWithAuth(), we should send a Type 3 message
6462 // (the credentials for the origin server). The second request continues
6463 // on the same connection.
6464 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
6465 "Host: 172.22.68.17\r\n"
6466 "Connection: keep-alive\r\n"
Zentaro Kavanagh5b27a6e22017-09-25 23:00:376467 "Authorization: NTLM "),
6468 MockWrite(authenticate_msg.c_str()), MockWrite("\r\n\r\n"),
[email protected]385a4672009-03-11 22:21:296469 };
6470
6471 MockRead data_reads3[] = {
Bence Béky1e4ef192017-09-18 19:58:026472 // The origin server responds with a Type 2 message.
6473 MockRead("HTTP/1.1 401 Access Denied\r\n"),
Zentaro Kavanagh5b27a6e22017-09-25 23:00:376474 MockRead("WWW-Authenticate: NTLM "), MockRead(challenge_msg.c_str()),
6475 MockRead("\r\n"), MockRead("Content-Length: 42\r\n"),
Bence Béky1e4ef192017-09-18 19:58:026476 MockRead("Content-Type: text/html\r\n\r\n"),
6477 MockRead("You are not authorized to view this page\r\n"),
[email protected]385a4672009-03-11 22:21:296478
Bence Béky1e4ef192017-09-18 19:58:026479 // Lastly we get the desired content.
6480 MockRead("HTTP/1.1 200 OK\r\n"),
6481 MockRead("Content-Type: text/html; charset=utf-8\r\n"),
6482 MockRead("Content-Length: 14\r\n\r\n"), MockRead("Please Login\r\n"),
[email protected]385a4672009-03-11 22:21:296483 };
6484
[email protected]31a2bfe2010-02-09 08:03:396485 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
6486 data_writes1, arraysize(data_writes1));
6487 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
6488 data_writes2, arraysize(data_writes2));
6489 StaticSocketDataProvider data3(data_reads3, arraysize(data_reads3),
6490 data_writes3, arraysize(data_writes3));
[email protected]bb88e1d32013-05-03 23:11:076491 session_deps_.socket_factory->AddSocketDataProvider(&data1);
6492 session_deps_.socket_factory->AddSocketDataProvider(&data2);
6493 session_deps_.socket_factory->AddSocketDataProvider(&data3);
[email protected]385a4672009-03-11 22:21:296494
Bence Béky83eb3512017-09-05 12:56:096495 SSLSocketDataProvider ssl1(ASYNC, OK);
6496 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl1);
6497 SSLSocketDataProvider ssl2(ASYNC, OK);
6498 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
6499 SSLSocketDataProvider ssl3(ASYNC, OK);
6500 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl3);
6501
[email protected]49639fa2011-12-20 23:22:416502 TestCompletionCallback callback1;
[email protected]385a4672009-03-11 22:21:296503
bnc691fda62016-08-12 00:43:166504 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]0b0bf032010-09-21 18:08:506505
tfarina42834112016-09-22 13:38:206506 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:016507 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]385a4672009-03-11 22:21:296508
6509 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:016510 EXPECT_THAT(rv, IsOk());
[email protected]385a4672009-03-11 22:21:296511
bnc691fda62016-08-12 00:43:166512 EXPECT_FALSE(trans.IsReadyToRestartForAuth());
[email protected]385a4672009-03-11 22:21:296513
bnc691fda62016-08-12 00:43:166514 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:526515 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:046516 EXPECT_TRUE(CheckNTLMServerAuth(response->auth_challenge.get()));
[email protected]385a4672009-03-11 22:21:296517
[email protected]49639fa2011-12-20 23:22:416518 TestCompletionCallback callback2;
[email protected]385a4672009-03-11 22:21:296519
[email protected]0757e7702009-03-27 04:00:226520 // Enter the wrong password.
Zentaro Kavanagh5b27a6e22017-09-25 23:00:376521 rv = trans.RestartWithAuth(
6522 AuthCredentials(ntlm::test::kDomainUserCombined, kWrongPassword),
6523 callback2.callback());
robpercival214763f2016-07-01 23:27:016524 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]385a4672009-03-11 22:21:296525
[email protected]10af5fe72011-01-31 16:17:256526 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:016527 EXPECT_THAT(rv, IsOk());
[email protected]385a4672009-03-11 22:21:296528
bnc691fda62016-08-12 00:43:166529 EXPECT_TRUE(trans.IsReadyToRestartForAuth());
[email protected]49639fa2011-12-20 23:22:416530 TestCompletionCallback callback3;
bnc691fda62016-08-12 00:43:166531 rv = trans.RestartWithAuth(AuthCredentials(), callback3.callback());
robpercival214763f2016-07-01 23:27:016532 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]10af5fe72011-01-31 16:17:256533 rv = callback3.WaitForResult();
robpercival214763f2016-07-01 23:27:016534 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:166535 EXPECT_FALSE(trans.IsReadyToRestartForAuth());
[email protected]0757e7702009-03-27 04:00:226536
bnc691fda62016-08-12 00:43:166537 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:526538 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:046539 EXPECT_TRUE(CheckNTLMServerAuth(response->auth_challenge.get()));
[email protected]0757e7702009-03-27 04:00:226540
[email protected]49639fa2011-12-20 23:22:416541 TestCompletionCallback callback4;
[email protected]0757e7702009-03-27 04:00:226542
6543 // Now enter the right password.
Zentaro Kavanagh5b27a6e22017-09-25 23:00:376544 rv = trans.RestartWithAuth(
6545 AuthCredentials(ntlm::test::kDomainUserCombined, ntlm::test::kPassword),
6546 callback4.callback());
robpercival214763f2016-07-01 23:27:016547 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]10af5fe72011-01-31 16:17:256548
6549 rv = callback4.WaitForResult();
robpercival214763f2016-07-01 23:27:016550 EXPECT_THAT(rv, IsOk());
[email protected]10af5fe72011-01-31 16:17:256551
bnc691fda62016-08-12 00:43:166552 EXPECT_TRUE(trans.IsReadyToRestartForAuth());
[email protected]10af5fe72011-01-31 16:17:256553
[email protected]49639fa2011-12-20 23:22:416554 TestCompletionCallback callback5;
[email protected]10af5fe72011-01-31 16:17:256555
6556 // One more roundtrip
bnc691fda62016-08-12 00:43:166557 rv = trans.RestartWithAuth(AuthCredentials(), callback5.callback());
robpercival214763f2016-07-01 23:27:016558 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]0757e7702009-03-27 04:00:226559
6560 rv = callback5.WaitForResult();
robpercival214763f2016-07-01 23:27:016561 EXPECT_THAT(rv, IsOk());
[email protected]0757e7702009-03-27 04:00:226562
bnc691fda62016-08-12 00:43:166563 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:526564 EXPECT_FALSE(response->auth_challenge);
Bence Béky1e4ef192017-09-18 19:58:026565 EXPECT_EQ(14, response->headers->GetContentLength());
6566
6567 std::string response_data;
6568 rv = ReadTransaction(&trans, &response_data);
6569 EXPECT_THAT(rv, IsOk());
6570 EXPECT_EQ("Please Login\r\n", response_data);
6571
6572 EXPECT_TRUE(data1.AllReadDataConsumed());
6573 EXPECT_TRUE(data1.AllWriteDataConsumed());
6574 EXPECT_TRUE(data2.AllReadDataConsumed());
6575 EXPECT_TRUE(data2.AllWriteDataConsumed());
6576 EXPECT_TRUE(data3.AllReadDataConsumed());
6577 EXPECT_TRUE(data3.AllWriteDataConsumed());
[email protected]385a4672009-03-11 22:21:296578}
Bence Béky83eb3512017-09-05 12:56:096579
Bence Béky3238f2e12017-09-22 22:44:496580// Server requests NTLM authentication, which is not supported over HTTP/2.
6581// Subsequent request with authorization header should be sent over HTTP/1.1.
Bence Béky83eb3512017-09-05 12:56:096582TEST_F(HttpNetworkTransactionTest, NTLMOverHttp2) {
Zentaro Kavanagh6ccee512017-09-28 18:34:096583 HttpAuthHandlerNTLM::ScopedProcSetter proc_setter(
6584 MockGetMSTime, MockGenerateRandom, MockGetHostName);
Bence Béky83eb3512017-09-05 12:56:096585
6586 const char* kUrl = "https://172.22.68.17/kids/login.aspx";
6587
6588 HttpRequestInfo request;
6589 request.method = "GET";
6590 request.url = GURL(kUrl);
6591
6592 // First request without credentials.
6593 SpdyHeaderBlock request_headers0(spdy_util_.ConstructGetHeaderBlock(kUrl));
6594 SpdySerializedFrame request0(spdy_util_.ConstructSpdyHeaders(
6595 1, std::move(request_headers0), LOWEST, true));
6596
6597 SpdyHeaderBlock response_headers0;
Bence Békybda82952017-10-02 17:35:276598 response_headers0[kHttp2StatusHeader] = "401";
Bence Béky83eb3512017-09-05 12:56:096599 response_headers0["www-authenticate"] = "NTLM";
6600 SpdySerializedFrame resp(spdy_util_.ConstructSpdyResponseHeaders(
6601 1, std::move(response_headers0), true));
6602
Zentaro Kavanagh5b27a6e22017-09-25 23:00:376603 // Stream 1 is closed.
6604 spdy_util_.UpdateWithStreamDestruction(1);
6605
6606 // Generate the NTLM messages based on known test data.
6607 std::string negotiate_msg;
6608 std::string challenge_msg;
6609 std::string authenticate_msg;
6610 base::Base64Encode(
6611 base::StringPiece(
6612 reinterpret_cast<const char*>(ntlm::test::kExpectedNegotiateMsg),
6613 arraysize(ntlm::test::kExpectedNegotiateMsg)),
6614 &negotiate_msg);
6615 base::Base64Encode(base::StringPiece(reinterpret_cast<const char*>(
6616 ntlm::test::kChallengeMsgV1),
6617 arraysize(ntlm::test::kChallengeMsgV1)),
6618 &challenge_msg);
6619 base::Base64Encode(
6620 base::StringPiece(
Zentaro Kavanagh6ccee512017-09-28 18:34:096621 reinterpret_cast<const char*>(
6622 ntlm::test::kExpectedAuthenticateMsgSpecResponseV1),
6623 arraysize(ntlm::test::kExpectedAuthenticateMsgSpecResponseV1)),
Zentaro Kavanagh5b27a6e22017-09-25 23:00:376624 &authenticate_msg);
6625
6626 // Retry with authorization header.
6627 SpdyHeaderBlock request_headers1(spdy_util_.ConstructGetHeaderBlock(kUrl));
6628 request_headers1["authorization"] = std::string("NTLM ") + negotiate_msg;
6629 SpdySerializedFrame request1(spdy_util_.ConstructSpdyHeaders(
6630 3, std::move(request_headers1), LOWEST, true));
6631
6632 SpdySerializedFrame rst(
6633 spdy_util_.ConstructSpdyRstStream(3, ERROR_CODE_HTTP_1_1_REQUIRED));
6634
Bence Béky3238f2e12017-09-22 22:44:496635 MockWrite writes0[] = {CreateMockWrite(request0, 0)};
6636 MockRead reads0[] = {CreateMockRead(resp, 1), MockRead(ASYNC, 0, 2)};
Bence Béky83eb3512017-09-05 12:56:096637
6638 // Retry yet again using HTTP/1.1.
6639 MockWrite writes1[] = {
6640 // After restarting with a null identity, this is the
6641 // request we should be issuing -- the final header line contains a Type
6642 // 1 message.
6643 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
6644 "Host: 172.22.68.17\r\n"
6645 "Connection: keep-alive\r\n"
Zentaro Kavanagh5b27a6e22017-09-25 23:00:376646 "Authorization: NTLM "),
6647 MockWrite(negotiate_msg.c_str()), MockWrite("\r\n\r\n"),
Bence Béky83eb3512017-09-05 12:56:096648
6649 // After calling trans.RestartWithAuth(), we should send a Type 3 message
6650 // (the credentials for the origin server). The second request continues
6651 // on the same connection.
6652 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
6653 "Host: 172.22.68.17\r\n"
6654 "Connection: keep-alive\r\n"
Zentaro Kavanagh5b27a6e22017-09-25 23:00:376655 "Authorization: NTLM "),
6656 MockWrite(authenticate_msg.c_str()), MockWrite("\r\n\r\n"),
Bence Béky83eb3512017-09-05 12:56:096657 };
6658
6659 MockRead reads1[] = {
6660 // The origin server responds with a Type 2 message.
6661 MockRead("HTTP/1.1 401 Access Denied\r\n"),
Zentaro Kavanagh5b27a6e22017-09-25 23:00:376662 MockRead("WWW-Authenticate: NTLM "), MockRead(challenge_msg.c_str()),
6663 MockRead("\r\n"), MockRead("Content-Length: 42\r\n"),
Bence Béky83eb3512017-09-05 12:56:096664 MockRead("Content-Type: text/html\r\n\r\n"),
6665 MockRead("You are not authorized to view this page\r\n"),
6666
6667 // Lastly we get the desired content.
6668 MockRead("HTTP/1.1 200 OK\r\n"),
6669 MockRead("Content-Type: text/html; charset=utf-8\r\n"),
Bence Béky1e4ef192017-09-18 19:58:026670 MockRead("Content-Length: 14\r\n\r\n"), MockRead("Please Login\r\n"),
Bence Béky83eb3512017-09-05 12:56:096671 };
6672 SequencedSocketData data0(reads0, arraysize(reads0), writes0,
6673 arraysize(writes0));
6674 StaticSocketDataProvider data1(reads1, arraysize(reads1), writes1,
6675 arraysize(writes1));
6676 session_deps_.socket_factory->AddSocketDataProvider(&data0);
6677 session_deps_.socket_factory->AddSocketDataProvider(&data1);
6678
6679 SSLSocketDataProvider ssl0(ASYNC, OK);
6680 ssl0.next_proto = kProtoHTTP2;
6681 SSLSocketDataProvider ssl1(ASYNC, OK);
6682 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl0);
6683 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl1);
6684
6685 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
6686 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
6687
6688 TestCompletionCallback callback1;
6689 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
6690 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
6691
6692 rv = callback1.WaitForResult();
6693 EXPECT_THAT(rv, IsOk());
6694
6695 EXPECT_FALSE(trans.IsReadyToRestartForAuth());
6696
6697 const HttpResponseInfo* response = trans.GetResponseInfo();
6698 ASSERT_TRUE(response);
6699 EXPECT_TRUE(CheckNTLMServerAuth(response->auth_challenge.get()));
6700
6701 TestCompletionCallback callback2;
6702
Zentaro Kavanagh5b27a6e22017-09-25 23:00:376703 rv = trans.RestartWithAuth(
6704 AuthCredentials(ntlm::test::kDomainUserCombined, ntlm::test::kPassword),
6705 callback2.callback());
Bence Béky83eb3512017-09-05 12:56:096706 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
6707
6708 rv = callback2.WaitForResult();
6709 EXPECT_THAT(rv, IsOk());
6710
6711 EXPECT_TRUE(trans.IsReadyToRestartForAuth());
6712
6713 response = trans.GetResponseInfo();
6714 ASSERT_TRUE(response);
6715 EXPECT_FALSE(response->auth_challenge);
6716
6717 TestCompletionCallback callback3;
6718
6719 rv = trans.RestartWithAuth(AuthCredentials(), callback3.callback());
6720 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
6721
6722 rv = callback3.WaitForResult();
6723 EXPECT_THAT(rv, IsOk());
6724
6725 response = trans.GetResponseInfo();
6726 ASSERT_TRUE(response);
6727 EXPECT_FALSE(response->auth_challenge);
Bence Béky1e4ef192017-09-18 19:58:026728 EXPECT_EQ(14, response->headers->GetContentLength());
6729
6730 std::string response_data;
6731 rv = ReadTransaction(&trans, &response_data);
6732 EXPECT_THAT(rv, IsOk());
6733 EXPECT_EQ("Please Login\r\n", response_data);
6734
6735 EXPECT_TRUE(data0.AllReadDataConsumed());
6736 EXPECT_TRUE(data0.AllWriteDataConsumed());
6737 EXPECT_TRUE(data1.AllReadDataConsumed());
6738 EXPECT_TRUE(data1.AllWriteDataConsumed());
Bence Béky83eb3512017-09-05 12:56:096739}
[email protected]ea9dc9a2009-09-05 00:43:326740#endif // NTLM_PORTABLE
[email protected]385a4672009-03-11 22:21:296741
[email protected]4ddaf2502008-10-23 18:26:196742// Test reading a server response which has only headers, and no body.
6743// After some maximum number of bytes is consumed, the transaction should
6744// fail with ERR_RESPONSE_HEADERS_TOO_BIG.
bncd16676a2016-07-20 16:23:016745TEST_F(HttpNetworkTransactionTest, LargeHeadersNoBody) {
[email protected]1c773ea12009-04-28 19:58:426746 HttpRequestInfo request;
[email protected]4ddaf2502008-10-23 18:26:196747 request.method = "GET";
bncce36dca22015-04-21 22:11:236748 request.url = GURL("http://www.example.org/");
[email protected]4ddaf2502008-10-23 18:26:196749
danakj1fd259a02016-04-16 03:17:096750 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:166751 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:276752
[email protected]b75b7b2f2009-10-06 00:54:536753 // Respond with 300 kb of headers (we should fail after 256 kb).
[email protected]15a5ccf82008-10-23 19:57:436754 std::string large_headers_string;
[email protected]b75b7b2f2009-10-06 00:54:536755 FillLargeHeadersString(&large_headers_string, 300 * 1024);
[email protected]4ddaf2502008-10-23 18:26:196756
6757 MockRead data_reads[] = {
6758 MockRead("HTTP/1.0 200 OK\r\n"),
[email protected]8ddf8322012-02-23 18:08:066759 MockRead(ASYNC, large_headers_string.data(), large_headers_string.size()),
[email protected]4ddaf2502008-10-23 18:26:196760 MockRead("\r\nBODY"),
[email protected]8ddf8322012-02-23 18:08:066761 MockRead(SYNCHRONOUS, OK),
[email protected]4ddaf2502008-10-23 18:26:196762 };
[email protected]31a2bfe2010-02-09 08:03:396763 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:076764 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]4ddaf2502008-10-23 18:26:196765
[email protected]49639fa2011-12-20 23:22:416766 TestCompletionCallback callback;
[email protected]4ddaf2502008-10-23 18:26:196767
tfarina42834112016-09-22 13:38:206768 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:016769 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]4ddaf2502008-10-23 18:26:196770
6771 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:016772 EXPECT_THAT(rv, IsError(ERR_RESPONSE_HEADERS_TOO_BIG));
[email protected]4ddaf2502008-10-23 18:26:196773}
[email protected]f4e426b2008-11-05 00:24:496774
6775// Make sure that we don't try to reuse a TCPClientSocket when failing to
6776// establish tunnel.
6777// http://code.google.com/p/chromium/issues/detail?id=3772
bncd16676a2016-07-20 16:23:016778TEST_F(HttpNetworkTransactionTest, DontRecycleTransportSocketForSSLTunnel) {
[email protected]cb9bf6ca2011-01-28 13:15:276779 HttpRequestInfo request;
6780 request.method = "GET";
bncce36dca22015-04-21 22:11:236781 request.url = GURL("https://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:276782
[email protected]f4e426b2008-11-05 00:24:496783 // Configure against proxy server "myproxy:70".
rdsmith82957ad2015-09-16 19:42:036784 session_deps_.proxy_service = ProxyService::CreateFixed("myproxy:70");
[email protected]db8f44c2008-12-13 04:52:016785
danakj1fd259a02016-04-16 03:17:096786 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]f4e426b2008-11-05 00:24:496787
bnc87dcefc2017-05-25 12:47:586788 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:196789 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]f4e426b2008-11-05 00:24:496790
[email protected]f4e426b2008-11-05 00:24:496791 // Since we have proxy, should try to establish tunnel.
6792 MockWrite data_writes1[] = {
rsleevidb16bb02015-11-12 23:47:176793 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
6794 "Host: www.example.org:443\r\n"
6795 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]f4e426b2008-11-05 00:24:496796 };
6797
[email protected]77848d12008-11-14 00:00:226798 // The proxy responds to the connect with a 404, using a persistent
[email protected]f4e426b2008-11-05 00:24:496799 // connection. Usually a proxy would return 501 (not implemented),
6800 // or 200 (tunnel established).
6801 MockRead data_reads1[] = {
mmenked39192ee2015-12-09 00:57:236802 MockRead("HTTP/1.1 404 Not Found\r\n"),
6803 MockRead("Content-Length: 10\r\n\r\n"),
6804 MockRead(SYNCHRONOUS, ERR_UNEXPECTED),
[email protected]f4e426b2008-11-05 00:24:496805 };
6806
[email protected]31a2bfe2010-02-09 08:03:396807 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
6808 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:076809 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]f4e426b2008-11-05 00:24:496810
[email protected]49639fa2011-12-20 23:22:416811 TestCompletionCallback callback1;
[email protected]f4e426b2008-11-05 00:24:496812
tfarina42834112016-09-22 13:38:206813 int rv = trans->Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:016814 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]f4e426b2008-11-05 00:24:496815
6816 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:016817 EXPECT_THAT(rv, IsError(ERR_TUNNEL_CONNECTION_FAILED));
[email protected]f4e426b2008-11-05 00:24:496818
[email protected]b4404c02009-04-10 16:38:526819 // Empty the current queue. This is necessary because idle sockets are
6820 // added to the connection pool asynchronously with a PostTask.
fdoray92e35a72016-06-10 15:54:556821 base::RunLoop().RunUntilIdle();
[email protected]b4404c02009-04-10 16:38:526822
[email protected]f4e426b2008-11-05 00:24:496823 // We now check to make sure the TCPClientSocket was not added back to
6824 // the pool.
[email protected]90499482013-06-01 00:39:506825 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]f4e426b2008-11-05 00:24:496826 trans.reset();
fdoray92e35a72016-06-10 15:54:556827 base::RunLoop().RunUntilIdle();
[email protected]f4e426b2008-11-05 00:24:496828 // Make sure that the socket didn't get recycled after calling the destructor.
[email protected]90499482013-06-01 00:39:506829 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]f4e426b2008-11-05 00:24:496830}
[email protected]372d34a2008-11-05 21:30:516831
[email protected]1b157c02009-04-21 01:55:406832// Make sure that we recycle a socket after reading all of the response body.
bncd16676a2016-07-20 16:23:016833TEST_F(HttpNetworkTransactionTest, RecycleSocket) {
[email protected]1c773ea12009-04-28 19:58:426834 HttpRequestInfo request;
[email protected]1b157c02009-04-21 01:55:406835 request.method = "GET";
bncce36dca22015-04-21 22:11:236836 request.url = GURL("http://www.example.org/");
[email protected]1b157c02009-04-21 01:55:406837
danakj1fd259a02016-04-16 03:17:096838 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:276839
bnc691fda62016-08-12 00:43:166840 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:276841
[email protected]1b157c02009-04-21 01:55:406842 MockRead data_reads[] = {
6843 // A part of the response body is received with the response headers.
6844 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 11\r\n\r\nhel"),
6845 // The rest of the response body is received in two parts.
6846 MockRead("lo"),
6847 MockRead(" world"),
6848 MockRead("junk"), // Should not be read!!
[email protected]8ddf8322012-02-23 18:08:066849 MockRead(SYNCHRONOUS, OK),
[email protected]1b157c02009-04-21 01:55:406850 };
6851
[email protected]31a2bfe2010-02-09 08:03:396852 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:076853 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1b157c02009-04-21 01:55:406854
[email protected]49639fa2011-12-20 23:22:416855 TestCompletionCallback callback;
[email protected]1b157c02009-04-21 01:55:406856
tfarina42834112016-09-22 13:38:206857 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:016858 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]1b157c02009-04-21 01:55:406859
6860 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:016861 EXPECT_THAT(rv, IsOk());
[email protected]1b157c02009-04-21 01:55:406862
bnc691fda62016-08-12 00:43:166863 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:526864 ASSERT_TRUE(response);
[email protected]1b157c02009-04-21 01:55:406865
wezca1070932016-05-26 20:30:526866 EXPECT_TRUE(response->headers);
[email protected]1b157c02009-04-21 01:55:406867 std::string status_line = response->headers->GetStatusLine();
6868 EXPECT_EQ("HTTP/1.1 200 OK", status_line);
6869
[email protected]90499482013-06-01 00:39:506870 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]1b157c02009-04-21 01:55:406871
6872 std::string response_data;
bnc691fda62016-08-12 00:43:166873 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:016874 EXPECT_THAT(rv, IsOk());
[email protected]1b157c02009-04-21 01:55:406875 EXPECT_EQ("hello world", response_data);
6876
6877 // Empty the current queue. This is necessary because idle sockets are
6878 // added to the connection pool asynchronously with a PostTask.
fdoray92e35a72016-06-10 15:54:556879 base::RunLoop().RunUntilIdle();
[email protected]1b157c02009-04-21 01:55:406880
6881 // We now check to make sure the socket was added back to the pool.
[email protected]90499482013-06-01 00:39:506882 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]1b157c02009-04-21 01:55:406883}
6884
[email protected]76a505b2010-08-25 06:23:006885// Make sure that we recycle a SSL socket after reading all of the response
6886// body.
bncd16676a2016-07-20 16:23:016887TEST_F(HttpNetworkTransactionTest, RecycleSSLSocket) {
[email protected]76a505b2010-08-25 06:23:006888 HttpRequestInfo request;
6889 request.method = "GET";
bncce36dca22015-04-21 22:11:236890 request.url = GURL("https://www.example.org/");
[email protected]76a505b2010-08-25 06:23:006891
6892 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:236893 MockWrite(
6894 "GET / HTTP/1.1\r\n"
6895 "Host: www.example.org\r\n"
6896 "Connection: keep-alive\r\n\r\n"),
[email protected]76a505b2010-08-25 06:23:006897 };
6898
6899 MockRead data_reads[] = {
6900 MockRead("HTTP/1.1 200 OK\r\n"),
6901 MockRead("Content-Length: 11\r\n\r\n"),
6902 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:066903 MockRead(SYNCHRONOUS, OK),
[email protected]76a505b2010-08-25 06:23:006904 };
6905
[email protected]8ddf8322012-02-23 18:08:066906 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:076907 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]76a505b2010-08-25 06:23:006908
6909 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
6910 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:076911 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]76a505b2010-08-25 06:23:006912
[email protected]49639fa2011-12-20 23:22:416913 TestCompletionCallback callback;
[email protected]76a505b2010-08-25 06:23:006914
danakj1fd259a02016-04-16 03:17:096915 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:166916 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]76a505b2010-08-25 06:23:006917
tfarina42834112016-09-22 13:38:206918 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
[email protected]76a505b2010-08-25 06:23:006919
robpercival214763f2016-07-01 23:27:016920 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
6921 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]76a505b2010-08-25 06:23:006922
bnc691fda62016-08-12 00:43:166923 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:526924 ASSERT_TRUE(response);
6925 ASSERT_TRUE(response->headers);
[email protected]76a505b2010-08-25 06:23:006926 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
6927
[email protected]90499482013-06-01 00:39:506928 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]76a505b2010-08-25 06:23:006929
6930 std::string response_data;
bnc691fda62016-08-12 00:43:166931 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:016932 EXPECT_THAT(rv, IsOk());
[email protected]76a505b2010-08-25 06:23:006933 EXPECT_EQ("hello world", response_data);
6934
6935 // Empty the current queue. This is necessary because idle sockets are
6936 // added to the connection pool asynchronously with a PostTask.
fdoray92e35a72016-06-10 15:54:556937 base::RunLoop().RunUntilIdle();
[email protected]76a505b2010-08-25 06:23:006938
6939 // We now check to make sure the socket was added back to the pool.
[email protected]90499482013-06-01 00:39:506940 EXPECT_EQ(1, GetIdleSocketCountInSSLSocketPool(session.get()));
[email protected]76a505b2010-08-25 06:23:006941}
6942
6943// Grab a SSL socket, use it, and put it back into the pool. Then, reuse it
6944// from the pool and make sure that we recover okay.
bncd16676a2016-07-20 16:23:016945TEST_F(HttpNetworkTransactionTest, RecycleDeadSSLSocket) {
[email protected]76a505b2010-08-25 06:23:006946 HttpRequestInfo request;
6947 request.method = "GET";
bncce36dca22015-04-21 22:11:236948 request.url = GURL("https://www.example.org/");
[email protected]76a505b2010-08-25 06:23:006949
6950 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:236951 MockWrite(
6952 "GET / HTTP/1.1\r\n"
6953 "Host: www.example.org\r\n"
6954 "Connection: keep-alive\r\n\r\n"),
6955 MockWrite(
6956 "GET / HTTP/1.1\r\n"
6957 "Host: www.example.org\r\n"
6958 "Connection: keep-alive\r\n\r\n"),
[email protected]76a505b2010-08-25 06:23:006959 };
6960
6961 MockRead data_reads[] = {
mmenke911ee0222015-12-04 03:58:426962 MockRead("HTTP/1.1 200 OK\r\n"), MockRead("Content-Length: 11\r\n\r\n"),
6963 MockRead("hello world"), MockRead(ASYNC, ERR_CONNECTION_CLOSED)};
[email protected]76a505b2010-08-25 06:23:006964
[email protected]8ddf8322012-02-23 18:08:066965 SSLSocketDataProvider ssl(ASYNC, OK);
6966 SSLSocketDataProvider ssl2(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:076967 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
6968 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
[email protected]76a505b2010-08-25 06:23:006969
6970 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
6971 data_writes, arraysize(data_writes));
6972 StaticSocketDataProvider data2(data_reads, arraysize(data_reads),
6973 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:076974 session_deps_.socket_factory->AddSocketDataProvider(&data);
6975 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]76a505b2010-08-25 06:23:006976
[email protected]49639fa2011-12-20 23:22:416977 TestCompletionCallback callback;
[email protected]76a505b2010-08-25 06:23:006978
danakj1fd259a02016-04-16 03:17:096979 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc87dcefc2017-05-25 12:47:586980 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:196981 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]76a505b2010-08-25 06:23:006982
tfarina42834112016-09-22 13:38:206983 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
[email protected]76a505b2010-08-25 06:23:006984
robpercival214763f2016-07-01 23:27:016985 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
6986 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]76a505b2010-08-25 06:23:006987
6988 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:526989 ASSERT_TRUE(response);
6990 ASSERT_TRUE(response->headers);
[email protected]76a505b2010-08-25 06:23:006991 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
6992
[email protected]90499482013-06-01 00:39:506993 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]76a505b2010-08-25 06:23:006994
6995 std::string response_data;
6996 rv = ReadTransaction(trans.get(), &response_data);
robpercival214763f2016-07-01 23:27:016997 EXPECT_THAT(rv, IsOk());
[email protected]76a505b2010-08-25 06:23:006998 EXPECT_EQ("hello world", response_data);
6999
7000 // Empty the current queue. This is necessary because idle sockets are
7001 // added to the connection pool asynchronously with a PostTask.
fdoray92e35a72016-06-10 15:54:557002 base::RunLoop().RunUntilIdle();
[email protected]76a505b2010-08-25 06:23:007003
7004 // We now check to make sure the socket was added back to the pool.
[email protected]90499482013-06-01 00:39:507005 EXPECT_EQ(1, GetIdleSocketCountInSSLSocketPool(session.get()));
[email protected]76a505b2010-08-25 06:23:007006
7007 // Now start the second transaction, which should reuse the previous socket.
7008
bnc87dcefc2017-05-25 12:47:587009 trans =
Jeremy Roman0579ed62017-08-29 15:56:197010 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]76a505b2010-08-25 06:23:007011
tfarina42834112016-09-22 13:38:207012 rv = trans->Start(&request, callback.callback(), NetLogWithSource());
[email protected]76a505b2010-08-25 06:23:007013
robpercival214763f2016-07-01 23:27:017014 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
7015 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]76a505b2010-08-25 06:23:007016
7017 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:527018 ASSERT_TRUE(response);
7019 ASSERT_TRUE(response->headers);
[email protected]76a505b2010-08-25 06:23:007020 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
7021
[email protected]90499482013-06-01 00:39:507022 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]76a505b2010-08-25 06:23:007023
7024 rv = ReadTransaction(trans.get(), &response_data);
robpercival214763f2016-07-01 23:27:017025 EXPECT_THAT(rv, IsOk());
[email protected]76a505b2010-08-25 06:23:007026 EXPECT_EQ("hello world", response_data);
7027
7028 // Empty the current queue. This is necessary because idle sockets are
7029 // added to the connection pool asynchronously with a PostTask.
fdoray92e35a72016-06-10 15:54:557030 base::RunLoop().RunUntilIdle();
[email protected]76a505b2010-08-25 06:23:007031
7032 // We now check to make sure the socket was added back to the pool.
[email protected]90499482013-06-01 00:39:507033 EXPECT_EQ(1, GetIdleSocketCountInSSLSocketPool(session.get()));
[email protected]76a505b2010-08-25 06:23:007034}
7035
maksim.sisov0adf8592016-07-15 06:25:567036// Grab a socket, use it, and put it back into the pool. Then, make
7037// low memory notification and ensure the socket pool is flushed.
bncd16676a2016-07-20 16:23:017038TEST_F(HttpNetworkTransactionTest, FlushSocketPoolOnLowMemoryNotifications) {
maksim.sisov0adf8592016-07-15 06:25:567039 HttpRequestInfo request;
7040 request.method = "GET";
7041 request.url = GURL("http://www.example.org/");
7042 request.load_flags = 0;
7043
7044 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
7045
bnc691fda62016-08-12 00:43:167046 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
maksim.sisov0adf8592016-07-15 06:25:567047
7048 MockRead data_reads[] = {
7049 // A part of the response body is received with the response headers.
7050 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 11\r\n\r\nhel"),
7051 // The rest of the response body is received in two parts.
7052 MockRead("lo"), MockRead(" world"),
7053 MockRead("junk"), // Should not be read!!
7054 MockRead(SYNCHRONOUS, OK),
7055 };
7056
7057 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
7058 session_deps_.socket_factory->AddSocketDataProvider(&data);
7059
7060 TestCompletionCallback callback;
7061
tfarina42834112016-09-22 13:38:207062 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
maksim.sisov0adf8592016-07-15 06:25:567063 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
7064
7065 EXPECT_THAT(callback.GetResult(rv), IsOk());
7066
bnc691fda62016-08-12 00:43:167067 const HttpResponseInfo* response = trans.GetResponseInfo();
maksim.sisov0adf8592016-07-15 06:25:567068 ASSERT_TRUE(response);
7069 EXPECT_TRUE(response->headers);
7070 std::string status_line = response->headers->GetStatusLine();
7071 EXPECT_EQ("HTTP/1.1 200 OK", status_line);
7072
7073 // Make memory critical notification and ensure the transaction still has been
7074 // operating right.
7075 base::MemoryPressureListener::NotifyMemoryPressure(
7076 base::MemoryPressureListener::MEMORY_PRESSURE_LEVEL_CRITICAL);
7077 base::RunLoop().RunUntilIdle();
7078
7079 // Socket should not be flushed as long as it is not idle.
7080 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
7081
7082 std::string response_data;
bnc691fda62016-08-12 00:43:167083 rv = ReadTransaction(&trans, &response_data);
maksim.sisov0adf8592016-07-15 06:25:567084 EXPECT_THAT(rv, IsOk());
7085 EXPECT_EQ("hello world", response_data);
7086
7087 // Empty the current queue. This is necessary because idle sockets are
7088 // added to the connection pool asynchronously with a PostTask.
7089 base::RunLoop().RunUntilIdle();
7090
7091 // We now check to make sure the socket was added back to the pool.
7092 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
7093
7094 // Idle sockets should be flushed now.
7095 base::MemoryPressureListener::NotifyMemoryPressure(
7096 base::MemoryPressureListener::MEMORY_PRESSURE_LEVEL_CRITICAL);
7097 base::RunLoop().RunUntilIdle();
7098
7099 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
7100}
7101
yucliu48f235d2018-01-11 00:59:557102// Disable idle socket closing on memory pressure.
7103// Grab a socket, use it, and put it back into the pool. Then, make
7104// low memory notification and ensure the socket pool is NOT flushed.
7105TEST_F(HttpNetworkTransactionTest, NoFlushSocketPoolOnLowMemoryNotifications) {
7106 HttpRequestInfo request;
7107 request.method = "GET";
7108 request.url = GURL("http://www.example.org/");
7109 request.load_flags = 0;
7110
7111 // Disable idle socket closing on memory pressure.
7112 session_deps_.disable_idle_sockets_close_on_memory_pressure = true;
7113 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
7114
7115 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
7116
7117 MockRead data_reads[] = {
7118 // A part of the response body is received with the response headers.
7119 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 11\r\n\r\nhel"),
7120 // The rest of the response body is received in two parts.
7121 MockRead("lo"), MockRead(" world"),
7122 MockRead("junk"), // Should not be read!!
7123 MockRead(SYNCHRONOUS, OK),
7124 };
7125
7126 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
7127 session_deps_.socket_factory->AddSocketDataProvider(&data);
7128
7129 TestCompletionCallback callback;
7130
7131 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
7132 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
7133
7134 EXPECT_THAT(callback.GetResult(rv), IsOk());
7135
7136 const HttpResponseInfo* response = trans.GetResponseInfo();
7137 ASSERT_TRUE(response);
7138 EXPECT_TRUE(response->headers);
7139 std::string status_line = response->headers->GetStatusLine();
7140 EXPECT_EQ("HTTP/1.1 200 OK", status_line);
7141
7142 // Make memory critical notification and ensure the transaction still has been
7143 // operating right.
7144 base::MemoryPressureListener::NotifyMemoryPressure(
7145 base::MemoryPressureListener::MEMORY_PRESSURE_LEVEL_CRITICAL);
7146 base::RunLoop().RunUntilIdle();
7147
7148 // Socket should not be flushed as long as it is not idle.
7149 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
7150
7151 std::string response_data;
7152 rv = ReadTransaction(&trans, &response_data);
7153 EXPECT_THAT(rv, IsOk());
7154 EXPECT_EQ("hello world", response_data);
7155
7156 // Empty the current queue. This is necessary because idle sockets are
7157 // added to the connection pool asynchronously with a PostTask.
7158 base::RunLoop().RunUntilIdle();
7159
7160 // We now check to make sure the socket was added back to the pool.
7161 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
7162
7163 // Idle sockets should NOT be flushed on moderate memory pressure.
7164 base::MemoryPressureListener::NotifyMemoryPressure(
7165 base::MemoryPressureListener::MEMORY_PRESSURE_LEVEL_MODERATE);
7166 base::RunLoop().RunUntilIdle();
7167
7168 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
7169
7170 // Idle sockets should NOT be flushed on critical memory pressure.
7171 base::MemoryPressureListener::NotifyMemoryPressure(
7172 base::MemoryPressureListener::MEMORY_PRESSURE_LEVEL_CRITICAL);
7173 base::RunLoop().RunUntilIdle();
7174
7175 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
7176}
7177
maksim.sisov0adf8592016-07-15 06:25:567178// Grab an SSL socket, use it, and put it back into the pool. Then, make
7179// low memory notification and ensure the socket pool is flushed.
bncd16676a2016-07-20 16:23:017180TEST_F(HttpNetworkTransactionTest, FlushSSLSocketPoolOnLowMemoryNotifications) {
maksim.sisov0adf8592016-07-15 06:25:567181 HttpRequestInfo request;
7182 request.method = "GET";
7183 request.url = GURL("https://www.example.org/");
7184 request.load_flags = 0;
7185
7186 MockWrite data_writes[] = {
7187 MockWrite("GET / HTTP/1.1\r\n"
7188 "Host: www.example.org\r\n"
7189 "Connection: keep-alive\r\n\r\n"),
7190 };
7191
7192 MockRead data_reads[] = {
7193 MockRead("HTTP/1.1 200 OK\r\n"), MockRead("Content-Length: 11\r\n\r\n"),
7194 MockRead("hello world"), MockRead(ASYNC, ERR_CONNECTION_CLOSED)};
7195
7196 SSLSocketDataProvider ssl(ASYNC, OK);
7197 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
7198
7199 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
7200 arraysize(data_writes));
7201 session_deps_.socket_factory->AddSocketDataProvider(&data);
7202
7203 TestCompletionCallback callback;
7204
7205 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:167206 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
maksim.sisov0adf8592016-07-15 06:25:567207
7208 EXPECT_EQ(0, GetIdleSocketCountInSSLSocketPool(session.get()));
tfarina42834112016-09-22 13:38:207209 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
maksim.sisov0adf8592016-07-15 06:25:567210
7211 EXPECT_THAT(callback.GetResult(rv), IsOk());
7212
bnc691fda62016-08-12 00:43:167213 const HttpResponseInfo* response = trans.GetResponseInfo();
maksim.sisov0adf8592016-07-15 06:25:567214 ASSERT_TRUE(response);
7215 ASSERT_TRUE(response->headers);
7216 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
7217
7218 // Make memory critical notification and ensure the transaction still has been
7219 // operating right.
7220 base::MemoryPressureListener::NotifyMemoryPressure(
7221 base::MemoryPressureListener::MEMORY_PRESSURE_LEVEL_CRITICAL);
7222 base::RunLoop().RunUntilIdle();
7223
7224 EXPECT_EQ(0, GetIdleSocketCountInSSLSocketPool(session.get()));
7225
7226 std::string response_data;
bnc691fda62016-08-12 00:43:167227 rv = ReadTransaction(&trans, &response_data);
maksim.sisov0adf8592016-07-15 06:25:567228 EXPECT_THAT(rv, IsOk());
7229 EXPECT_EQ("hello world", response_data);
7230
7231 // Empty the current queue. This is necessary because idle sockets are
7232 // added to the connection pool asynchronously with a PostTask.
7233 base::RunLoop().RunUntilIdle();
7234
7235 // We now check to make sure the socket was added back to the pool.
7236 EXPECT_EQ(1, GetIdleSocketCountInSSLSocketPool(session.get()));
7237
7238 // Make memory notification once again and ensure idle socket is closed.
7239 base::MemoryPressureListener::NotifyMemoryPressure(
7240 base::MemoryPressureListener::MEMORY_PRESSURE_LEVEL_CRITICAL);
7241 base::RunLoop().RunUntilIdle();
7242
7243 EXPECT_EQ(0, GetIdleSocketCountInSSLSocketPool(session.get()));
7244}
7245
[email protected]b4404c02009-04-10 16:38:527246// Make sure that we recycle a socket after a zero-length response.
7247// http://crbug.com/9880
bncd16676a2016-07-20 16:23:017248TEST_F(HttpNetworkTransactionTest, RecycleSocketAfterZeroContentLength) {
[email protected]1c773ea12009-04-28 19:58:427249 HttpRequestInfo request;
[email protected]b4404c02009-04-10 16:38:527250 request.method = "GET";
bncce36dca22015-04-21 22:11:237251 request.url = GURL(
7252 "http://www.example.org/csi?v=3&s=web&action=&"
7253 "tran=undefined&ei=mAXcSeegAo-SMurloeUN&"
7254 "e=17259,18167,19592,19773,19981,20133,20173,20233&"
7255 "rt=prt.2642,ol.2649,xjs.2951");
[email protected]b4404c02009-04-10 16:38:527256
danakj1fd259a02016-04-16 03:17:097257 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:277258
[email protected]b4404c02009-04-10 16:38:527259 MockRead data_reads[] = {
7260 MockRead("HTTP/1.1 204 No Content\r\n"
7261 "Content-Length: 0\r\n"
7262 "Content-Type: text/html\r\n\r\n"),
7263 MockRead("junk"), // Should not be read!!
[email protected]8ddf8322012-02-23 18:08:067264 MockRead(SYNCHRONOUS, OK),
[email protected]b4404c02009-04-10 16:38:527265 };
7266
[email protected]31a2bfe2010-02-09 08:03:397267 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:077268 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]b4404c02009-04-10 16:38:527269
mmenkecc2298e2015-12-07 18:20:187270 // Transaction must be created after the MockReads, so it's destroyed before
7271 // them.
bnc691fda62016-08-12 00:43:167272 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
mmenkecc2298e2015-12-07 18:20:187273
[email protected]49639fa2011-12-20 23:22:417274 TestCompletionCallback callback;
[email protected]b4404c02009-04-10 16:38:527275
tfarina42834112016-09-22 13:38:207276 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:017277 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]b4404c02009-04-10 16:38:527278
7279 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:017280 EXPECT_THAT(rv, IsOk());
[email protected]b4404c02009-04-10 16:38:527281
bnc691fda62016-08-12 00:43:167282 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:527283 ASSERT_TRUE(response);
[email protected]b4404c02009-04-10 16:38:527284
wezca1070932016-05-26 20:30:527285 EXPECT_TRUE(response->headers);
[email protected]b4404c02009-04-10 16:38:527286 std::string status_line = response->headers->GetStatusLine();
7287 EXPECT_EQ("HTTP/1.1 204 No Content", status_line);
7288
[email protected]90499482013-06-01 00:39:507289 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]b4404c02009-04-10 16:38:527290
7291 std::string response_data;
bnc691fda62016-08-12 00:43:167292 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:017293 EXPECT_THAT(rv, IsOk());
[email protected]b4404c02009-04-10 16:38:527294 EXPECT_EQ("", response_data);
7295
7296 // Empty the current queue. This is necessary because idle sockets are
7297 // added to the connection pool asynchronously with a PostTask.
fdoray92e35a72016-06-10 15:54:557298 base::RunLoop().RunUntilIdle();
[email protected]b4404c02009-04-10 16:38:527299
7300 // We now check to make sure the socket was added back to the pool.
[email protected]90499482013-06-01 00:39:507301 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]b4404c02009-04-10 16:38:527302}
7303
bncd16676a2016-07-20 16:23:017304TEST_F(HttpNetworkTransactionTest, ResendRequestOnWriteBodyError) {
danakj1fd259a02016-04-16 03:17:097305 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:227306 element_readers.push_back(
Jeremy Roman0579ed62017-08-29 15:56:197307 std::make_unique<UploadBytesElementReader>("foo", 3));
olli.raula6df48b2a2015-11-26 07:40:227308 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]329b68b2012-11-14 17:54:277309
[email protected]1c773ea12009-04-28 19:58:427310 HttpRequestInfo request[2];
[email protected]372d34a2008-11-05 21:30:517311 // Transaction 1: a GET request that succeeds. The socket is recycled
7312 // after use.
7313 request[0].method = "GET";
7314 request[0].url = GURL("http://www.google.com/");
7315 request[0].load_flags = 0;
7316 // Transaction 2: a POST request. Reuses the socket kept alive from
7317 // transaction 1. The first attempts fails when writing the POST data.
7318 // This causes the transaction to retry with a new socket. The second
7319 // attempt succeeds.
7320 request[1].method = "POST";
7321 request[1].url = GURL("http://www.google.com/login.cgi");
[email protected]329b68b2012-11-14 17:54:277322 request[1].upload_data_stream = &upload_data_stream;
[email protected]372d34a2008-11-05 21:30:517323 request[1].load_flags = 0;
7324
danakj1fd259a02016-04-16 03:17:097325 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]372d34a2008-11-05 21:30:517326
7327 // The first socket is used for transaction 1 and the first attempt of
7328 // transaction 2.
7329
7330 // The response of transaction 1.
7331 MockRead data_reads1[] = {
7332 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 11\r\n\r\n"),
7333 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:067334 MockRead(SYNCHRONOUS, OK),
[email protected]372d34a2008-11-05 21:30:517335 };
7336 // The mock write results of transaction 1 and the first attempt of
7337 // transaction 2.
7338 MockWrite data_writes1[] = {
[email protected]8ddf8322012-02-23 18:08:067339 MockWrite(SYNCHRONOUS, 64), // GET
7340 MockWrite(SYNCHRONOUS, 93), // POST
7341 MockWrite(SYNCHRONOUS, ERR_CONNECTION_ABORTED), // POST data
[email protected]372d34a2008-11-05 21:30:517342 };
[email protected]31a2bfe2010-02-09 08:03:397343 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
7344 data_writes1, arraysize(data_writes1));
[email protected]372d34a2008-11-05 21:30:517345
7346 // The second socket is used for the second attempt of transaction 2.
7347
7348 // The response of transaction 2.
7349 MockRead data_reads2[] = {
7350 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 7\r\n\r\n"),
7351 MockRead("welcome"),
[email protected]8ddf8322012-02-23 18:08:067352 MockRead(SYNCHRONOUS, OK),
[email protected]372d34a2008-11-05 21:30:517353 };
7354 // The mock write results of the second attempt of transaction 2.
7355 MockWrite data_writes2[] = {
[email protected]8ddf8322012-02-23 18:08:067356 MockWrite(SYNCHRONOUS, 93), // POST
7357 MockWrite(SYNCHRONOUS, 3), // POST data
[email protected]372d34a2008-11-05 21:30:517358 };
[email protected]31a2bfe2010-02-09 08:03:397359 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
7360 data_writes2, arraysize(data_writes2));
[email protected]372d34a2008-11-05 21:30:517361
[email protected]bb88e1d32013-05-03 23:11:077362 session_deps_.socket_factory->AddSocketDataProvider(&data1);
7363 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]372d34a2008-11-05 21:30:517364
thestig9d3bb0c2015-01-24 00:49:517365 const char* const kExpectedResponseData[] = {
[email protected]372d34a2008-11-05 21:30:517366 "hello world", "welcome"
7367 };
7368
7369 for (int i = 0; i < 2; ++i) {
bnc691fda62016-08-12 00:43:167370 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]372d34a2008-11-05 21:30:517371
[email protected]49639fa2011-12-20 23:22:417372 TestCompletionCallback callback;
[email protected]372d34a2008-11-05 21:30:517373
tfarina42834112016-09-22 13:38:207374 int rv = trans.Start(&request[i], callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:017375 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]372d34a2008-11-05 21:30:517376
7377 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:017378 EXPECT_THAT(rv, IsOk());
[email protected]372d34a2008-11-05 21:30:517379
bnc691fda62016-08-12 00:43:167380 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:527381 ASSERT_TRUE(response);
[email protected]372d34a2008-11-05 21:30:517382
wezca1070932016-05-26 20:30:527383 EXPECT_TRUE(response->headers);
[email protected]372d34a2008-11-05 21:30:517384 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
7385
7386 std::string response_data;
bnc691fda62016-08-12 00:43:167387 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:017388 EXPECT_THAT(rv, IsOk());
[email protected]372d34a2008-11-05 21:30:517389 EXPECT_EQ(kExpectedResponseData[i], response_data);
7390 }
7391}
[email protected]f9ee6b52008-11-08 06:46:237392
7393// Test the request-challenge-retry sequence for basic auth when there is
7394// an identity in the URL. The request should be sent as normal, but when
[email protected]2262e3a2012-05-22 16:08:167395// it fails the identity from the URL is used to answer the challenge.
bncd16676a2016-07-20 16:23:017396TEST_F(HttpNetworkTransactionTest, AuthIdentityInURL) {
[email protected]1c773ea12009-04-28 19:58:427397 HttpRequestInfo request;
[email protected]f9ee6b52008-11-08 06:46:237398 request.method = "GET";
bncce36dca22015-04-21 22:11:237399 request.url = GURL("http://foo:b@[email protected]/");
[email protected]7b08ba62012-02-10 20:19:417400 request.load_flags = LOAD_NORMAL;
[email protected]a97cca42009-08-14 01:00:297401
danakj1fd259a02016-04-16 03:17:097402 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:167403 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:277404
[email protected]a97cca42009-08-14 01:00:297405 // The password contains an escaped character -- for this test to pass it
7406 // will need to be unescaped by HttpNetworkTransaction.
7407 EXPECT_EQ("b%40r", request.url.password());
7408
[email protected]f9ee6b52008-11-08 06:46:237409 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:237410 MockWrite(
7411 "GET / HTTP/1.1\r\n"
7412 "Host: www.example.org\r\n"
7413 "Connection: keep-alive\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:237414 };
7415
7416 MockRead data_reads1[] = {
7417 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
7418 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
7419 MockRead("Content-Length: 10\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067420 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]f9ee6b52008-11-08 06:46:237421 };
7422
[email protected]2262e3a2012-05-22 16:08:167423 // After the challenge above, the transaction will be restarted using the
7424 // identity from the url (foo, b@r) to answer the challenge.
7425 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:237426 MockWrite(
7427 "GET / HTTP/1.1\r\n"
7428 "Host: www.example.org\r\n"
7429 "Connection: keep-alive\r\n"
7430 "Authorization: Basic Zm9vOmJAcg==\r\n\r\n"),
[email protected]2262e3a2012-05-22 16:08:167431 };
7432
7433 MockRead data_reads2[] = {
7434 MockRead("HTTP/1.0 200 OK\r\n"),
7435 MockRead("Content-Length: 100\r\n\r\n"),
7436 MockRead(SYNCHRONOUS, OK),
7437 };
7438
[email protected]31a2bfe2010-02-09 08:03:397439 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
7440 data_writes1, arraysize(data_writes1));
[email protected]2262e3a2012-05-22 16:08:167441 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
7442 data_writes2, arraysize(data_writes2));
[email protected]bb88e1d32013-05-03 23:11:077443 session_deps_.socket_factory->AddSocketDataProvider(&data1);
7444 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]f9ee6b52008-11-08 06:46:237445
[email protected]49639fa2011-12-20 23:22:417446 TestCompletionCallback callback1;
tfarina42834112016-09-22 13:38:207447 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:017448 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]f9ee6b52008-11-08 06:46:237449 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:017450 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:167451 EXPECT_TRUE(trans.IsReadyToRestartForAuth());
[email protected]2262e3a2012-05-22 16:08:167452
7453 TestCompletionCallback callback2;
bnc691fda62016-08-12 00:43:167454 rv = trans.RestartWithAuth(AuthCredentials(), callback2.callback());
robpercival214763f2016-07-01 23:27:017455 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2262e3a2012-05-22 16:08:167456 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:017457 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:167458 EXPECT_FALSE(trans.IsReadyToRestartForAuth());
[email protected]0757e7702009-03-27 04:00:227459
bnc691fda62016-08-12 00:43:167460 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:527461 ASSERT_TRUE(response);
[email protected]2262e3a2012-05-22 16:08:167462
7463 // There is no challenge info, since the identity in URL worked.
wezca1070932016-05-26 20:30:527464 EXPECT_FALSE(response->auth_challenge);
[email protected]2262e3a2012-05-22 16:08:167465
7466 EXPECT_EQ(100, response->headers->GetContentLength());
7467
7468 // Empty the current queue.
fdoray92e35a72016-06-10 15:54:557469 base::RunLoop().RunUntilIdle();
[email protected]2262e3a2012-05-22 16:08:167470}
7471
7472// Test the request-challenge-retry sequence for basic auth when there is an
7473// incorrect identity in the URL. The identity from the URL should be used only
7474// once.
bncd16676a2016-07-20 16:23:017475TEST_F(HttpNetworkTransactionTest, WrongAuthIdentityInURL) {
[email protected]2262e3a2012-05-22 16:08:167476 HttpRequestInfo request;
7477 request.method = "GET";
7478 // Note: the URL has a username:password in it. The password "baz" is
7479 // wrong (should be "bar").
bncce36dca22015-04-21 22:11:237480 request.url = GURL("http://foo:[email protected]/");
[email protected]2262e3a2012-05-22 16:08:167481
7482 request.load_flags = LOAD_NORMAL;
7483
danakj1fd259a02016-04-16 03:17:097484 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:167485 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]2262e3a2012-05-22 16:08:167486
7487 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:237488 MockWrite(
7489 "GET / HTTP/1.1\r\n"
7490 "Host: www.example.org\r\n"
7491 "Connection: keep-alive\r\n\r\n"),
[email protected]2262e3a2012-05-22 16:08:167492 };
7493
7494 MockRead data_reads1[] = {
7495 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
7496 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
7497 MockRead("Content-Length: 10\r\n\r\n"),
7498 MockRead(SYNCHRONOUS, ERR_FAILED),
7499 };
7500
7501 // After the challenge above, the transaction will be restarted using the
7502 // identity from the url (foo, baz) to answer the challenge.
7503 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:237504 MockWrite(
7505 "GET / HTTP/1.1\r\n"
7506 "Host: www.example.org\r\n"
7507 "Connection: keep-alive\r\n"
7508 "Authorization: Basic Zm9vOmJheg==\r\n\r\n"),
[email protected]2262e3a2012-05-22 16:08:167509 };
7510
7511 MockRead data_reads2[] = {
7512 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
7513 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
7514 MockRead("Content-Length: 10\r\n\r\n"),
7515 MockRead(SYNCHRONOUS, ERR_FAILED),
7516 };
7517
7518 // After the challenge above, the transaction will be restarted using the
7519 // identity supplied by the user (foo, bar) to answer the challenge.
7520 MockWrite data_writes3[] = {
bncce36dca22015-04-21 22:11:237521 MockWrite(
7522 "GET / HTTP/1.1\r\n"
7523 "Host: www.example.org\r\n"
7524 "Connection: keep-alive\r\n"
7525 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]2262e3a2012-05-22 16:08:167526 };
7527
7528 MockRead data_reads3[] = {
7529 MockRead("HTTP/1.0 200 OK\r\n"),
7530 MockRead("Content-Length: 100\r\n\r\n"),
7531 MockRead(SYNCHRONOUS, OK),
7532 };
7533
7534 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
7535 data_writes1, arraysize(data_writes1));
7536 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
7537 data_writes2, arraysize(data_writes2));
7538 StaticSocketDataProvider data3(data_reads3, arraysize(data_reads3),
7539 data_writes3, arraysize(data_writes3));
[email protected]bb88e1d32013-05-03 23:11:077540 session_deps_.socket_factory->AddSocketDataProvider(&data1);
7541 session_deps_.socket_factory->AddSocketDataProvider(&data2);
7542 session_deps_.socket_factory->AddSocketDataProvider(&data3);
[email protected]2262e3a2012-05-22 16:08:167543
7544 TestCompletionCallback callback1;
7545
tfarina42834112016-09-22 13:38:207546 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:017547 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2262e3a2012-05-22 16:08:167548
7549 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:017550 EXPECT_THAT(rv, IsOk());
[email protected]2262e3a2012-05-22 16:08:167551
bnc691fda62016-08-12 00:43:167552 EXPECT_TRUE(trans.IsReadyToRestartForAuth());
[email protected]2262e3a2012-05-22 16:08:167553 TestCompletionCallback callback2;
bnc691fda62016-08-12 00:43:167554 rv = trans.RestartWithAuth(AuthCredentials(), callback2.callback());
robpercival214763f2016-07-01 23:27:017555 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2262e3a2012-05-22 16:08:167556 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:017557 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:167558 EXPECT_FALSE(trans.IsReadyToRestartForAuth());
[email protected]2262e3a2012-05-22 16:08:167559
bnc691fda62016-08-12 00:43:167560 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:527561 ASSERT_TRUE(response);
[email protected]2262e3a2012-05-22 16:08:167562 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
7563
7564 TestCompletionCallback callback3;
bnc691fda62016-08-12 00:43:167565 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar), callback3.callback());
robpercival214763f2016-07-01 23:27:017566 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2262e3a2012-05-22 16:08:167567 rv = callback3.WaitForResult();
robpercival214763f2016-07-01 23:27:017568 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:167569 EXPECT_FALSE(trans.IsReadyToRestartForAuth());
[email protected]2262e3a2012-05-22 16:08:167570
bnc691fda62016-08-12 00:43:167571 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:527572 ASSERT_TRUE(response);
[email protected]2262e3a2012-05-22 16:08:167573
7574 // There is no challenge info, since the identity worked.
wezca1070932016-05-26 20:30:527575 EXPECT_FALSE(response->auth_challenge);
[email protected]2262e3a2012-05-22 16:08:167576
7577 EXPECT_EQ(100, response->headers->GetContentLength());
7578
[email protected]ea9dc9a2009-09-05 00:43:327579 // Empty the current queue.
fdoray92e35a72016-06-10 15:54:557580 base::RunLoop().RunUntilIdle();
[email protected]ea9dc9a2009-09-05 00:43:327581}
7582
[email protected]2217aa22013-10-11 03:03:547583
7584// Test the request-challenge-retry sequence for basic auth when there is a
7585// correct identity in the URL, but its use is being suppressed. The identity
7586// from the URL should never be used.
bncd16676a2016-07-20 16:23:017587TEST_F(HttpNetworkTransactionTest, AuthIdentityInURLSuppressed) {
[email protected]2217aa22013-10-11 03:03:547588 HttpRequestInfo request;
7589 request.method = "GET";
bncce36dca22015-04-21 22:11:237590 request.url = GURL("http://foo:[email protected]/");
[email protected]2217aa22013-10-11 03:03:547591 request.load_flags = LOAD_DO_NOT_USE_EMBEDDED_IDENTITY;
7592
danakj1fd259a02016-04-16 03:17:097593 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:167594 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]2217aa22013-10-11 03:03:547595
7596 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:237597 MockWrite(
7598 "GET / HTTP/1.1\r\n"
7599 "Host: www.example.org\r\n"
7600 "Connection: keep-alive\r\n\r\n"),
[email protected]2217aa22013-10-11 03:03:547601 };
7602
7603 MockRead data_reads1[] = {
7604 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
7605 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
7606 MockRead("Content-Length: 10\r\n\r\n"),
7607 MockRead(SYNCHRONOUS, ERR_FAILED),
7608 };
7609
7610 // After the challenge above, the transaction will be restarted using the
7611 // identity supplied by the user, not the one in the URL, to answer the
7612 // challenge.
7613 MockWrite data_writes3[] = {
bncce36dca22015-04-21 22:11:237614 MockWrite(
7615 "GET / HTTP/1.1\r\n"
7616 "Host: www.example.org\r\n"
7617 "Connection: keep-alive\r\n"
7618 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]2217aa22013-10-11 03:03:547619 };
7620
7621 MockRead data_reads3[] = {
7622 MockRead("HTTP/1.0 200 OK\r\n"),
7623 MockRead("Content-Length: 100\r\n\r\n"),
7624 MockRead(SYNCHRONOUS, OK),
7625 };
7626
7627 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
7628 data_writes1, arraysize(data_writes1));
7629 StaticSocketDataProvider data3(data_reads3, arraysize(data_reads3),
7630 data_writes3, arraysize(data_writes3));
7631 session_deps_.socket_factory->AddSocketDataProvider(&data1);
7632 session_deps_.socket_factory->AddSocketDataProvider(&data3);
7633
7634 TestCompletionCallback callback1;
tfarina42834112016-09-22 13:38:207635 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:017636 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2217aa22013-10-11 03:03:547637 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:017638 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:167639 EXPECT_FALSE(trans.IsReadyToRestartForAuth());
[email protected]2217aa22013-10-11 03:03:547640
bnc691fda62016-08-12 00:43:167641 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:527642 ASSERT_TRUE(response);
[email protected]2217aa22013-10-11 03:03:547643 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
7644
7645 TestCompletionCallback callback3;
bnc691fda62016-08-12 00:43:167646 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar), callback3.callback());
robpercival214763f2016-07-01 23:27:017647 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2217aa22013-10-11 03:03:547648 rv = callback3.WaitForResult();
robpercival214763f2016-07-01 23:27:017649 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:167650 EXPECT_FALSE(trans.IsReadyToRestartForAuth());
[email protected]2217aa22013-10-11 03:03:547651
bnc691fda62016-08-12 00:43:167652 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:527653 ASSERT_TRUE(response);
[email protected]2217aa22013-10-11 03:03:547654
7655 // There is no challenge info, since the identity worked.
wezca1070932016-05-26 20:30:527656 EXPECT_FALSE(response->auth_challenge);
[email protected]2217aa22013-10-11 03:03:547657 EXPECT_EQ(100, response->headers->GetContentLength());
7658
7659 // Empty the current queue.
fdoray92e35a72016-06-10 15:54:557660 base::RunLoop().RunUntilIdle();
[email protected]2217aa22013-10-11 03:03:547661}
7662
[email protected]f9ee6b52008-11-08 06:46:237663// Test that previously tried username/passwords for a realm get re-used.
bncd16676a2016-07-20 16:23:017664TEST_F(HttpNetworkTransactionTest, BasicAuthCacheAndPreauth) {
danakj1fd259a02016-04-16 03:17:097665 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]f9ee6b52008-11-08 06:46:237666
7667 // Transaction 1: authenticate (foo, bar) on MyRealm1
7668 {
[email protected]1c773ea12009-04-28 19:58:427669 HttpRequestInfo request;
[email protected]f9ee6b52008-11-08 06:46:237670 request.method = "GET";
bncce36dca22015-04-21 22:11:237671 request.url = GURL("http://www.example.org/x/y/z");
[email protected]f9ee6b52008-11-08 06:46:237672
bnc691fda62016-08-12 00:43:167673 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:277674
[email protected]f9ee6b52008-11-08 06:46:237675 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:237676 MockWrite(
7677 "GET /x/y/z HTTP/1.1\r\n"
7678 "Host: www.example.org\r\n"
7679 "Connection: keep-alive\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:237680 };
7681
7682 MockRead data_reads1[] = {
7683 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
7684 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
7685 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067686 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]f9ee6b52008-11-08 06:46:237687 };
7688
7689 // Resend with authorization (username=foo, password=bar)
7690 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:237691 MockWrite(
7692 "GET /x/y/z HTTP/1.1\r\n"
7693 "Host: www.example.org\r\n"
7694 "Connection: keep-alive\r\n"
7695 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:237696 };
7697
7698 // Sever accepts the authorization.
7699 MockRead data_reads2[] = {
7700 MockRead("HTTP/1.0 200 OK\r\n"),
7701 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067702 MockRead(SYNCHRONOUS, OK),
[email protected]f9ee6b52008-11-08 06:46:237703 };
7704
[email protected]31a2bfe2010-02-09 08:03:397705 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
7706 data_writes1, arraysize(data_writes1));
7707 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
7708 data_writes2, arraysize(data_writes2));
[email protected]bb88e1d32013-05-03 23:11:077709 session_deps_.socket_factory->AddSocketDataProvider(&data1);
7710 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]f9ee6b52008-11-08 06:46:237711
[email protected]49639fa2011-12-20 23:22:417712 TestCompletionCallback callback1;
[email protected]f9ee6b52008-11-08 06:46:237713
tfarina42834112016-09-22 13:38:207714 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:017715 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]f9ee6b52008-11-08 06:46:237716
7717 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:017718 EXPECT_THAT(rv, IsOk());
[email protected]f9ee6b52008-11-08 06:46:237719
bnc691fda62016-08-12 00:43:167720 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:527721 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:047722 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]f9ee6b52008-11-08 06:46:237723
[email protected]49639fa2011-12-20 23:22:417724 TestCompletionCallback callback2;
[email protected]f9ee6b52008-11-08 06:46:237725
bnc691fda62016-08-12 00:43:167726 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar),
7727 callback2.callback());
robpercival214763f2016-07-01 23:27:017728 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]f9ee6b52008-11-08 06:46:237729
7730 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:017731 EXPECT_THAT(rv, IsOk());
[email protected]f9ee6b52008-11-08 06:46:237732
bnc691fda62016-08-12 00:43:167733 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:527734 ASSERT_TRUE(response);
7735 EXPECT_FALSE(response->auth_challenge);
[email protected]f9ee6b52008-11-08 06:46:237736 EXPECT_EQ(100, response->headers->GetContentLength());
7737 }
7738
7739 // ------------------------------------------------------------------------
7740
7741 // Transaction 2: authenticate (foo2, bar2) on MyRealm2
7742 {
[email protected]1c773ea12009-04-28 19:58:427743 HttpRequestInfo request;
[email protected]f9ee6b52008-11-08 06:46:237744 request.method = "GET";
7745 // Note that Transaction 1 was at /x/y/z, so this is in the same
7746 // protection space as MyRealm1.
bncce36dca22015-04-21 22:11:237747 request.url = GURL("http://www.example.org/x/y/a/b");
[email protected]f9ee6b52008-11-08 06:46:237748
bnc691fda62016-08-12 00:43:167749 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:277750
[email protected]f9ee6b52008-11-08 06:46:237751 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:237752 MockWrite(
7753 "GET /x/y/a/b HTTP/1.1\r\n"
7754 "Host: www.example.org\r\n"
7755 "Connection: keep-alive\r\n"
7756 // Send preemptive authorization for MyRealm1
7757 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:237758 };
7759
7760 // The server didn't like the preemptive authorization, and
7761 // challenges us for a different realm (MyRealm2).
7762 MockRead data_reads1[] = {
7763 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
7764 MockRead("WWW-Authenticate: Basic realm=\"MyRealm2\"\r\n"),
7765 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067766 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]f9ee6b52008-11-08 06:46:237767 };
7768
7769 // Resend with authorization for MyRealm2 (username=foo2, password=bar2)
7770 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:237771 MockWrite(
7772 "GET /x/y/a/b HTTP/1.1\r\n"
7773 "Host: www.example.org\r\n"
7774 "Connection: keep-alive\r\n"
7775 "Authorization: Basic Zm9vMjpiYXIy\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:237776 };
7777
7778 // Sever accepts the authorization.
7779 MockRead data_reads2[] = {
7780 MockRead("HTTP/1.0 200 OK\r\n"),
7781 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067782 MockRead(SYNCHRONOUS, OK),
[email protected]f9ee6b52008-11-08 06:46:237783 };
7784
[email protected]31a2bfe2010-02-09 08:03:397785 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
7786 data_writes1, arraysize(data_writes1));
7787 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
7788 data_writes2, arraysize(data_writes2));
[email protected]bb88e1d32013-05-03 23:11:077789 session_deps_.socket_factory->AddSocketDataProvider(&data1);
7790 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]f9ee6b52008-11-08 06:46:237791
[email protected]49639fa2011-12-20 23:22:417792 TestCompletionCallback callback1;
[email protected]f9ee6b52008-11-08 06:46:237793
tfarina42834112016-09-22 13:38:207794 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:017795 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]f9ee6b52008-11-08 06:46:237796
7797 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:017798 EXPECT_THAT(rv, IsOk());
[email protected]f9ee6b52008-11-08 06:46:237799
bnc691fda62016-08-12 00:43:167800 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:527801 ASSERT_TRUE(response);
7802 ASSERT_TRUE(response->auth_challenge);
[email protected]79cb5c12011-09-12 13:12:047803 EXPECT_FALSE(response->auth_challenge->is_proxy);
asanka098c0092016-06-16 20:18:437804 EXPECT_EQ("http://www.example.org",
7805 response->auth_challenge->challenger.Serialize());
[email protected]79cb5c12011-09-12 13:12:047806 EXPECT_EQ("MyRealm2", response->auth_challenge->realm);
aberentbba302d2015-12-03 10:20:197807 EXPECT_EQ(kBasicAuthScheme, response->auth_challenge->scheme);
[email protected]f9ee6b52008-11-08 06:46:237808
[email protected]49639fa2011-12-20 23:22:417809 TestCompletionCallback callback2;
[email protected]f9ee6b52008-11-08 06:46:237810
bnc691fda62016-08-12 00:43:167811 rv = trans.RestartWithAuth(AuthCredentials(kFoo2, kBar2),
7812 callback2.callback());
robpercival214763f2016-07-01 23:27:017813 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]f9ee6b52008-11-08 06:46:237814
7815 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:017816 EXPECT_THAT(rv, IsOk());
[email protected]f9ee6b52008-11-08 06:46:237817
bnc691fda62016-08-12 00:43:167818 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:527819 ASSERT_TRUE(response);
7820 EXPECT_FALSE(response->auth_challenge);
[email protected]f9ee6b52008-11-08 06:46:237821 EXPECT_EQ(100, response->headers->GetContentLength());
7822 }
7823
7824 // ------------------------------------------------------------------------
7825
7826 // Transaction 3: Resend a request in MyRealm's protection space --
7827 // succeed with preemptive authorization.
7828 {
[email protected]1c773ea12009-04-28 19:58:427829 HttpRequestInfo request;
[email protected]f9ee6b52008-11-08 06:46:237830 request.method = "GET";
bncce36dca22015-04-21 22:11:237831 request.url = GURL("http://www.example.org/x/y/z2");
[email protected]f9ee6b52008-11-08 06:46:237832
bnc691fda62016-08-12 00:43:167833 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:277834
[email protected]f9ee6b52008-11-08 06:46:237835 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:237836 MockWrite(
7837 "GET /x/y/z2 HTTP/1.1\r\n"
7838 "Host: www.example.org\r\n"
7839 "Connection: keep-alive\r\n"
7840 // The authorization for MyRealm1 gets sent preemptively
7841 // (since the url is in the same protection space)
7842 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:237843 };
7844
7845 // Sever accepts the preemptive authorization
7846 MockRead data_reads1[] = {
7847 MockRead("HTTP/1.0 200 OK\r\n"),
7848 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067849 MockRead(SYNCHRONOUS, OK),
[email protected]f9ee6b52008-11-08 06:46:237850 };
7851
[email protected]31a2bfe2010-02-09 08:03:397852 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
7853 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:077854 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]f9ee6b52008-11-08 06:46:237855
[email protected]49639fa2011-12-20 23:22:417856 TestCompletionCallback callback1;
[email protected]f9ee6b52008-11-08 06:46:237857
tfarina42834112016-09-22 13:38:207858 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:017859 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]f9ee6b52008-11-08 06:46:237860
7861 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:017862 EXPECT_THAT(rv, IsOk());
[email protected]f9ee6b52008-11-08 06:46:237863
bnc691fda62016-08-12 00:43:167864 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:527865 ASSERT_TRUE(response);
[email protected]f9ee6b52008-11-08 06:46:237866
wezca1070932016-05-26 20:30:527867 EXPECT_FALSE(response->auth_challenge);
[email protected]f9ee6b52008-11-08 06:46:237868 EXPECT_EQ(100, response->headers->GetContentLength());
7869 }
7870
7871 // ------------------------------------------------------------------------
7872
7873 // Transaction 4: request another URL in MyRealm (however the
7874 // url is not known to belong to the protection space, so no pre-auth).
7875 {
[email protected]1c773ea12009-04-28 19:58:427876 HttpRequestInfo request;
[email protected]f9ee6b52008-11-08 06:46:237877 request.method = "GET";
bncce36dca22015-04-21 22:11:237878 request.url = GURL("http://www.example.org/x/1");
[email protected]f9ee6b52008-11-08 06:46:237879
bnc691fda62016-08-12 00:43:167880 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:277881
[email protected]f9ee6b52008-11-08 06:46:237882 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:237883 MockWrite(
7884 "GET /x/1 HTTP/1.1\r\n"
7885 "Host: www.example.org\r\n"
7886 "Connection: keep-alive\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:237887 };
7888
7889 MockRead data_reads1[] = {
7890 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
7891 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
7892 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067893 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]f9ee6b52008-11-08 06:46:237894 };
7895
7896 // Resend with authorization from MyRealm's cache.
7897 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:237898 MockWrite(
7899 "GET /x/1 HTTP/1.1\r\n"
7900 "Host: www.example.org\r\n"
7901 "Connection: keep-alive\r\n"
7902 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:237903 };
7904
7905 // Sever accepts the authorization.
7906 MockRead data_reads2[] = {
7907 MockRead("HTTP/1.0 200 OK\r\n"),
7908 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067909 MockRead(SYNCHRONOUS, OK),
[email protected]f9ee6b52008-11-08 06:46:237910 };
7911
[email protected]31a2bfe2010-02-09 08:03:397912 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
7913 data_writes1, arraysize(data_writes1));
7914 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
7915 data_writes2, arraysize(data_writes2));
[email protected]bb88e1d32013-05-03 23:11:077916 session_deps_.socket_factory->AddSocketDataProvider(&data1);
7917 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]f9ee6b52008-11-08 06:46:237918
[email protected]49639fa2011-12-20 23:22:417919 TestCompletionCallback callback1;
[email protected]f9ee6b52008-11-08 06:46:237920
tfarina42834112016-09-22 13:38:207921 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:017922 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]f9ee6b52008-11-08 06:46:237923
7924 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:017925 EXPECT_THAT(rv, IsOk());
[email protected]f9ee6b52008-11-08 06:46:237926
bnc691fda62016-08-12 00:43:167927 EXPECT_TRUE(trans.IsReadyToRestartForAuth());
[email protected]49639fa2011-12-20 23:22:417928 TestCompletionCallback callback2;
bnc691fda62016-08-12 00:43:167929 rv = trans.RestartWithAuth(AuthCredentials(), callback2.callback());
robpercival214763f2016-07-01 23:27:017930 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]0757e7702009-03-27 04:00:227931 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:017932 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:167933 EXPECT_FALSE(trans.IsReadyToRestartForAuth());
[email protected]0757e7702009-03-27 04:00:227934
bnc691fda62016-08-12 00:43:167935 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:527936 ASSERT_TRUE(response);
7937 EXPECT_FALSE(response->auth_challenge);
[email protected]f9ee6b52008-11-08 06:46:237938 EXPECT_EQ(100, response->headers->GetContentLength());
7939 }
7940
7941 // ------------------------------------------------------------------------
7942
7943 // Transaction 5: request a URL in MyRealm, but the server rejects the
7944 // cached identity. Should invalidate and re-prompt.
7945 {
[email protected]1c773ea12009-04-28 19:58:427946 HttpRequestInfo request;
[email protected]f9ee6b52008-11-08 06:46:237947 request.method = "GET";
bncce36dca22015-04-21 22:11:237948 request.url = GURL("http://www.example.org/p/q/t");
[email protected]f9ee6b52008-11-08 06:46:237949
bnc691fda62016-08-12 00:43:167950 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:277951
[email protected]f9ee6b52008-11-08 06:46:237952 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:237953 MockWrite(
7954 "GET /p/q/t HTTP/1.1\r\n"
7955 "Host: www.example.org\r\n"
7956 "Connection: keep-alive\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:237957 };
7958
7959 MockRead data_reads1[] = {
7960 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
7961 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
7962 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067963 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]f9ee6b52008-11-08 06:46:237964 };
7965
7966 // Resend with authorization from cache for MyRealm.
7967 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:237968 MockWrite(
7969 "GET /p/q/t HTTP/1.1\r\n"
7970 "Host: www.example.org\r\n"
7971 "Connection: keep-alive\r\n"
7972 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:237973 };
7974
7975 // Sever rejects the authorization.
7976 MockRead data_reads2[] = {
7977 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
7978 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
7979 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067980 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]f9ee6b52008-11-08 06:46:237981 };
7982
7983 // At this point we should prompt for new credentials for MyRealm.
7984 // Restart with username=foo3, password=foo4.
7985 MockWrite data_writes3[] = {
bncce36dca22015-04-21 22:11:237986 MockWrite(
7987 "GET /p/q/t HTTP/1.1\r\n"
7988 "Host: www.example.org\r\n"
7989 "Connection: keep-alive\r\n"
7990 "Authorization: Basic Zm9vMzpiYXIz\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:237991 };
7992
7993 // Sever accepts the authorization.
7994 MockRead data_reads3[] = {
7995 MockRead("HTTP/1.0 200 OK\r\n"),
7996 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067997 MockRead(SYNCHRONOUS, OK),
[email protected]f9ee6b52008-11-08 06:46:237998 };
7999
[email protected]31a2bfe2010-02-09 08:03:398000 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
8001 data_writes1, arraysize(data_writes1));
8002 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
8003 data_writes2, arraysize(data_writes2));
8004 StaticSocketDataProvider data3(data_reads3, arraysize(data_reads3),
8005 data_writes3, arraysize(data_writes3));
[email protected]bb88e1d32013-05-03 23:11:078006 session_deps_.socket_factory->AddSocketDataProvider(&data1);
8007 session_deps_.socket_factory->AddSocketDataProvider(&data2);
8008 session_deps_.socket_factory->AddSocketDataProvider(&data3);
[email protected]f9ee6b52008-11-08 06:46:238009
[email protected]49639fa2011-12-20 23:22:418010 TestCompletionCallback callback1;
[email protected]f9ee6b52008-11-08 06:46:238011
tfarina42834112016-09-22 13:38:208012 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:018013 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]f9ee6b52008-11-08 06:46:238014
8015 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:018016 EXPECT_THAT(rv, IsOk());
[email protected]f9ee6b52008-11-08 06:46:238017
bnc691fda62016-08-12 00:43:168018 EXPECT_TRUE(trans.IsReadyToRestartForAuth());
[email protected]49639fa2011-12-20 23:22:418019 TestCompletionCallback callback2;
bnc691fda62016-08-12 00:43:168020 rv = trans.RestartWithAuth(AuthCredentials(), callback2.callback());
robpercival214763f2016-07-01 23:27:018021 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]0757e7702009-03-27 04:00:228022 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:018023 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:168024 EXPECT_FALSE(trans.IsReadyToRestartForAuth());
[email protected]0757e7702009-03-27 04:00:228025
bnc691fda62016-08-12 00:43:168026 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:528027 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:048028 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]f9ee6b52008-11-08 06:46:238029
[email protected]49639fa2011-12-20 23:22:418030 TestCompletionCallback callback3;
[email protected]f9ee6b52008-11-08 06:46:238031
bnc691fda62016-08-12 00:43:168032 rv = trans.RestartWithAuth(AuthCredentials(kFoo3, kBar3),
8033 callback3.callback());
robpercival214763f2016-07-01 23:27:018034 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]f9ee6b52008-11-08 06:46:238035
[email protected]0757e7702009-03-27 04:00:228036 rv = callback3.WaitForResult();
robpercival214763f2016-07-01 23:27:018037 EXPECT_THAT(rv, IsOk());
[email protected]f9ee6b52008-11-08 06:46:238038
bnc691fda62016-08-12 00:43:168039 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:528040 ASSERT_TRUE(response);
8041 EXPECT_FALSE(response->auth_challenge);
[email protected]f9ee6b52008-11-08 06:46:238042 EXPECT_EQ(100, response->headers->GetContentLength());
8043 }
8044}
[email protected]89ceba9a2009-03-21 03:46:068045
[email protected]3c32c5f2010-05-18 15:18:128046// Tests that nonce count increments when multiple auth attempts
8047// are started with the same nonce.
bncd16676a2016-07-20 16:23:018048TEST_F(HttpNetworkTransactionTest, DigestPreAuthNonceCount) {
[email protected]54fea2562010-11-17 14:40:448049 HttpAuthHandlerDigest::Factory* digest_factory =
8050 new HttpAuthHandlerDigest::Factory();
8051 HttpAuthHandlerDigest::FixedNonceGenerator* nonce_generator =
8052 new HttpAuthHandlerDigest::FixedNonceGenerator("0123456789abcdef");
8053 digest_factory->set_nonce_generator(nonce_generator);
[email protected]bb88e1d32013-05-03 23:11:078054 session_deps_.http_auth_handler_factory.reset(digest_factory);
danakj1fd259a02016-04-16 03:17:098055 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]3c32c5f2010-05-18 15:18:128056
8057 // Transaction 1: authenticate (foo, bar) on MyRealm1
8058 {
[email protected]3c32c5f2010-05-18 15:18:128059 HttpRequestInfo request;
8060 request.method = "GET";
bncce36dca22015-04-21 22:11:238061 request.url = GURL("http://www.example.org/x/y/z");
[email protected]3c32c5f2010-05-18 15:18:128062
bnc691fda62016-08-12 00:43:168063 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:278064
[email protected]3c32c5f2010-05-18 15:18:128065 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:238066 MockWrite(
8067 "GET /x/y/z HTTP/1.1\r\n"
8068 "Host: www.example.org\r\n"
8069 "Connection: keep-alive\r\n\r\n"),
[email protected]3c32c5f2010-05-18 15:18:128070 };
8071
8072 MockRead data_reads1[] = {
8073 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
8074 MockRead("WWW-Authenticate: Digest realm=\"digestive\", nonce=\"OU812\", "
8075 "algorithm=MD5, qop=\"auth\"\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:068076 MockRead(SYNCHRONOUS, OK),
[email protected]3c32c5f2010-05-18 15:18:128077 };
8078
8079 // Resend with authorization (username=foo, password=bar)
8080 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:238081 MockWrite(
8082 "GET /x/y/z HTTP/1.1\r\n"
8083 "Host: www.example.org\r\n"
8084 "Connection: keep-alive\r\n"
8085 "Authorization: Digest username=\"foo\", realm=\"digestive\", "
8086 "nonce=\"OU812\", uri=\"/x/y/z\", algorithm=MD5, "
8087 "response=\"03ffbcd30add722589c1de345d7a927f\", qop=auth, "
8088 "nc=00000001, cnonce=\"0123456789abcdef\"\r\n\r\n"),
[email protected]3c32c5f2010-05-18 15:18:128089 };
8090
8091 // Sever accepts the authorization.
8092 MockRead data_reads2[] = {
zmo9528c9f42015-08-04 22:12:088093 MockRead("HTTP/1.0 200 OK\r\n"),
8094 MockRead(SYNCHRONOUS, OK),
[email protected]3c32c5f2010-05-18 15:18:128095 };
8096
8097 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
8098 data_writes1, arraysize(data_writes1));
8099 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
8100 data_writes2, arraysize(data_writes2));
[email protected]bb88e1d32013-05-03 23:11:078101 session_deps_.socket_factory->AddSocketDataProvider(&data1);
8102 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]3c32c5f2010-05-18 15:18:128103
[email protected]49639fa2011-12-20 23:22:418104 TestCompletionCallback callback1;
[email protected]3c32c5f2010-05-18 15:18:128105
tfarina42834112016-09-22 13:38:208106 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:018107 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]3c32c5f2010-05-18 15:18:128108
8109 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:018110 EXPECT_THAT(rv, IsOk());
[email protected]3c32c5f2010-05-18 15:18:128111
bnc691fda62016-08-12 00:43:168112 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:528113 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:048114 EXPECT_TRUE(CheckDigestServerAuth(response->auth_challenge.get()));
[email protected]3c32c5f2010-05-18 15:18:128115
[email protected]49639fa2011-12-20 23:22:418116 TestCompletionCallback callback2;
[email protected]3c32c5f2010-05-18 15:18:128117
bnc691fda62016-08-12 00:43:168118 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar),
8119 callback2.callback());
robpercival214763f2016-07-01 23:27:018120 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]3c32c5f2010-05-18 15:18:128121
8122 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:018123 EXPECT_THAT(rv, IsOk());
[email protected]3c32c5f2010-05-18 15:18:128124
bnc691fda62016-08-12 00:43:168125 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:528126 ASSERT_TRUE(response);
8127 EXPECT_FALSE(response->auth_challenge);
[email protected]3c32c5f2010-05-18 15:18:128128 }
8129
8130 // ------------------------------------------------------------------------
8131
8132 // Transaction 2: Request another resource in digestive's protection space.
8133 // This will preemptively add an Authorization header which should have an
8134 // "nc" value of 2 (as compared to 1 in the first use.
8135 {
[email protected]3c32c5f2010-05-18 15:18:128136 HttpRequestInfo request;
8137 request.method = "GET";
8138 // Note that Transaction 1 was at /x/y/z, so this is in the same
8139 // protection space as digest.
bncce36dca22015-04-21 22:11:238140 request.url = GURL("http://www.example.org/x/y/a/b");
[email protected]3c32c5f2010-05-18 15:18:128141
bnc691fda62016-08-12 00:43:168142 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:278143
[email protected]3c32c5f2010-05-18 15:18:128144 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:238145 MockWrite(
8146 "GET /x/y/a/b HTTP/1.1\r\n"
8147 "Host: www.example.org\r\n"
8148 "Connection: keep-alive\r\n"
8149 "Authorization: Digest username=\"foo\", realm=\"digestive\", "
8150 "nonce=\"OU812\", uri=\"/x/y/a/b\", algorithm=MD5, "
8151 "response=\"d6f9a2c07d1c5df7b89379dca1269b35\", qop=auth, "
8152 "nc=00000002, cnonce=\"0123456789abcdef\"\r\n\r\n"),
[email protected]3c32c5f2010-05-18 15:18:128153 };
8154
8155 // Sever accepts the authorization.
8156 MockRead data_reads1[] = {
8157 MockRead("HTTP/1.0 200 OK\r\n"),
8158 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:068159 MockRead(SYNCHRONOUS, OK),
[email protected]3c32c5f2010-05-18 15:18:128160 };
8161
8162 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
8163 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:078164 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]3c32c5f2010-05-18 15:18:128165
[email protected]49639fa2011-12-20 23:22:418166 TestCompletionCallback callback1;
[email protected]3c32c5f2010-05-18 15:18:128167
tfarina42834112016-09-22 13:38:208168 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:018169 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]3c32c5f2010-05-18 15:18:128170
8171 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:018172 EXPECT_THAT(rv, IsOk());
[email protected]3c32c5f2010-05-18 15:18:128173
bnc691fda62016-08-12 00:43:168174 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:528175 ASSERT_TRUE(response);
8176 EXPECT_FALSE(response->auth_challenge);
[email protected]3c32c5f2010-05-18 15:18:128177 }
8178}
8179
[email protected]89ceba9a2009-03-21 03:46:068180// Test the ResetStateForRestart() private method.
bncd16676a2016-07-20 16:23:018181TEST_F(HttpNetworkTransactionTest, ResetStateForRestart) {
[email protected]89ceba9a2009-03-21 03:46:068182 // Create a transaction (the dependencies aren't important).
danakj1fd259a02016-04-16 03:17:098183 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:168184 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]89ceba9a2009-03-21 03:46:068185
8186 // Setup some state (which we expect ResetStateForRestart() will clear).
bnc691fda62016-08-12 00:43:168187 trans.read_buf_ = new IOBuffer(15);
8188 trans.read_buf_len_ = 15;
8189 trans.request_headers_.SetHeader("Authorization", "NTLM");
[email protected]89ceba9a2009-03-21 03:46:068190
8191 // Setup state in response_
bnc691fda62016-08-12 00:43:168192 HttpResponseInfo* response = &trans.response_;
[email protected]0877e3d2009-10-17 22:29:578193 response->auth_challenge = new AuthChallengeInfo();
[email protected]70d66502011-09-23 00:55:088194 response->ssl_info.cert_status = static_cast<CertStatus>(-1); // Nonsensical.
[email protected]0877e3d2009-10-17 22:29:578195 response->response_time = base::Time::Now();
8196 response->was_cached = true; // (Wouldn't ever actually be true...)
[email protected]89ceba9a2009-03-21 03:46:068197
8198 { // Setup state for response_.vary_data
8199 HttpRequestInfo request;
8200 std::string temp("HTTP/1.1 200 OK\nVary: foo, bar\n\n");
8201 std::replace(temp.begin(), temp.end(), '\n', '\0');
[email protected]ad8e04a2010-11-01 04:16:278202 scoped_refptr<HttpResponseHeaders> headers(new HttpResponseHeaders(temp));
[email protected]8c76ae22010-04-20 22:15:438203 request.extra_headers.SetHeader("Foo", "1");
8204 request.extra_headers.SetHeader("bar", "23");
[email protected]90499482013-06-01 00:39:508205 EXPECT_TRUE(response->vary_data.Init(request, *headers.get()));
[email protected]89ceba9a2009-03-21 03:46:068206 }
8207
8208 // Cause the above state to be reset.
bnc691fda62016-08-12 00:43:168209 trans.ResetStateForRestart();
[email protected]89ceba9a2009-03-21 03:46:068210
8211 // Verify that the state that needed to be reset, has been reset.
bnc691fda62016-08-12 00:43:168212 EXPECT_FALSE(trans.read_buf_);
8213 EXPECT_EQ(0, trans.read_buf_len_);
8214 EXPECT_TRUE(trans.request_headers_.IsEmpty());
wezca1070932016-05-26 20:30:528215 EXPECT_FALSE(response->auth_challenge);
8216 EXPECT_FALSE(response->headers);
[email protected]34f40942010-10-04 00:34:048217 EXPECT_FALSE(response->was_cached);
[email protected]70d66502011-09-23 00:55:088218 EXPECT_EQ(0U, response->ssl_info.cert_status);
[email protected]0877e3d2009-10-17 22:29:578219 EXPECT_FALSE(response->vary_data.is_valid());
[email protected]89ceba9a2009-03-21 03:46:068220}
8221
[email protected]bacff652009-03-31 17:50:338222// Test HTTPS connections to a site with a bad certificate
bncd16676a2016-07-20 16:23:018223TEST_F(HttpNetworkTransactionTest, HTTPSBadCertificate) {
[email protected]bacff652009-03-31 17:50:338224 HttpRequestInfo request;
8225 request.method = "GET";
bncce36dca22015-04-21 22:11:238226 request.url = GURL("https://www.example.org/");
[email protected]bacff652009-03-31 17:50:338227
danakj1fd259a02016-04-16 03:17:098228 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:168229 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:278230
[email protected]bacff652009-03-31 17:50:338231 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:238232 MockWrite(
8233 "GET / HTTP/1.1\r\n"
8234 "Host: www.example.org\r\n"
8235 "Connection: keep-alive\r\n\r\n"),
[email protected]bacff652009-03-31 17:50:338236 };
8237
8238 MockRead data_reads[] = {
8239 MockRead("HTTP/1.0 200 OK\r\n"),
8240 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
8241 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:068242 MockRead(SYNCHRONOUS, OK),
[email protected]bacff652009-03-31 17:50:338243 };
8244
[email protected]5ecc992a42009-11-11 01:41:598245 StaticSocketDataProvider ssl_bad_certificate;
[email protected]31a2bfe2010-02-09 08:03:398246 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
8247 data_writes, arraysize(data_writes));
[email protected]8ddf8322012-02-23 18:08:068248 SSLSocketDataProvider ssl_bad(ASYNC, ERR_CERT_AUTHORITY_INVALID);
8249 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bacff652009-03-31 17:50:338250
[email protected]bb88e1d32013-05-03 23:11:078251 session_deps_.socket_factory->AddSocketDataProvider(&ssl_bad_certificate);
8252 session_deps_.socket_factory->AddSocketDataProvider(&data);
8253 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_bad);
8254 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]bacff652009-03-31 17:50:338255
[email protected]49639fa2011-12-20 23:22:418256 TestCompletionCallback callback;
[email protected]bacff652009-03-31 17:50:338257
tfarina42834112016-09-22 13:38:208258 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:018259 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]bacff652009-03-31 17:50:338260
8261 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:018262 EXPECT_THAT(rv, IsError(ERR_CERT_AUTHORITY_INVALID));
[email protected]bacff652009-03-31 17:50:338263
bnc691fda62016-08-12 00:43:168264 rv = trans.RestartIgnoringLastError(callback.callback());
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, IsOk());
[email protected]bacff652009-03-31 17:50:338269
bnc691fda62016-08-12 00:43:168270 const HttpResponseInfo* response = trans.GetResponseInfo();
[email protected]bacff652009-03-31 17:50:338271
wezca1070932016-05-26 20:30:528272 ASSERT_TRUE(response);
[email protected]bacff652009-03-31 17:50:338273 EXPECT_EQ(100, response->headers->GetContentLength());
8274}
8275
8276// Test HTTPS connections to a site with a bad certificate, going through a
8277// proxy
bncd16676a2016-07-20 16:23:018278TEST_F(HttpNetworkTransactionTest, HTTPSBadCertificateViaProxy) {
rdsmith82957ad2015-09-16 19:42:038279 session_deps_.proxy_service = ProxyService::CreateFixed("myproxy:70");
[email protected]bacff652009-03-31 17:50:338280
8281 HttpRequestInfo request;
8282 request.method = "GET";
bncce36dca22015-04-21 22:11:238283 request.url = GURL("https://www.example.org/");
[email protected]bacff652009-03-31 17:50:338284
8285 MockWrite proxy_writes[] = {
rsleevidb16bb02015-11-12 23:47:178286 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
8287 "Host: www.example.org:443\r\n"
8288 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]bacff652009-03-31 17:50:338289 };
8290
8291 MockRead proxy_reads[] = {
8292 MockRead("HTTP/1.0 200 Connected\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:068293 MockRead(SYNCHRONOUS, OK)
[email protected]bacff652009-03-31 17:50:338294 };
8295
8296 MockWrite data_writes[] = {
rsleevidb16bb02015-11-12 23:47:178297 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
8298 "Host: www.example.org:443\r\n"
8299 "Proxy-Connection: keep-alive\r\n\r\n"),
8300 MockWrite("GET / HTTP/1.1\r\n"
8301 "Host: www.example.org\r\n"
8302 "Connection: keep-alive\r\n\r\n"),
[email protected]bacff652009-03-31 17:50:338303 };
8304
8305 MockRead data_reads[] = {
8306 MockRead("HTTP/1.0 200 Connected\r\n\r\n"),
8307 MockRead("HTTP/1.0 200 OK\r\n"),
8308 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
8309 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:068310 MockRead(SYNCHRONOUS, OK),
[email protected]bacff652009-03-31 17:50:338311 };
8312
[email protected]31a2bfe2010-02-09 08:03:398313 StaticSocketDataProvider ssl_bad_certificate(
8314 proxy_reads, arraysize(proxy_reads),
8315 proxy_writes, arraysize(proxy_writes));
8316 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
8317 data_writes, arraysize(data_writes));
[email protected]8ddf8322012-02-23 18:08:068318 SSLSocketDataProvider ssl_bad(ASYNC, ERR_CERT_AUTHORITY_INVALID);
8319 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bacff652009-03-31 17:50:338320
[email protected]bb88e1d32013-05-03 23:11:078321 session_deps_.socket_factory->AddSocketDataProvider(&ssl_bad_certificate);
8322 session_deps_.socket_factory->AddSocketDataProvider(&data);
8323 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_bad);
8324 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]bacff652009-03-31 17:50:338325
[email protected]49639fa2011-12-20 23:22:418326 TestCompletionCallback callback;
[email protected]bacff652009-03-31 17:50:338327
8328 for (int i = 0; i < 2; i++) {
[email protected]bb88e1d32013-05-03 23:11:078329 session_deps_.socket_factory->ResetNextMockIndexes();
[email protected]bacff652009-03-31 17:50:338330
danakj1fd259a02016-04-16 03:17:098331 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:168332 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]bacff652009-03-31 17:50:338333
tfarina42834112016-09-22 13:38:208334 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:018335 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]bacff652009-03-31 17:50:338336
8337 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:018338 EXPECT_THAT(rv, IsError(ERR_CERT_AUTHORITY_INVALID));
[email protected]bacff652009-03-31 17:50:338339
bnc691fda62016-08-12 00:43:168340 rv = trans.RestartIgnoringLastError(callback.callback());
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, IsOk());
[email protected]bacff652009-03-31 17:50:338345
bnc691fda62016-08-12 00:43:168346 const HttpResponseInfo* response = trans.GetResponseInfo();
[email protected]bacff652009-03-31 17:50:338347
wezca1070932016-05-26 20:30:528348 ASSERT_TRUE(response);
[email protected]bacff652009-03-31 17:50:338349 EXPECT_EQ(100, response->headers->GetContentLength());
8350 }
8351}
8352
[email protected]2df19bb2010-08-25 20:13:468353
8354// Test HTTPS connections to a site, going through an HTTPS proxy
bncd16676a2016-07-20 16:23:018355TEST_F(HttpNetworkTransactionTest, HTTPSViaHttpsProxy) {
rdsmith82957ad2015-09-16 19:42:038356 session_deps_.proxy_service =
8357 ProxyService::CreateFixedFromPacResult("HTTPS proxy:70");
vishal.b62985ca92015-04-17 08:45:518358 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:078359 session_deps_.net_log = &net_log;
[email protected]2df19bb2010-08-25 20:13:468360
8361 HttpRequestInfo request;
8362 request.method = "GET";
bncce36dca22015-04-21 22:11:238363 request.url = GURL("https://www.example.org/");
[email protected]2df19bb2010-08-25 20:13:468364
8365 MockWrite data_writes[] = {
rsleevidb16bb02015-11-12 23:47:178366 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
8367 "Host: www.example.org:443\r\n"
8368 "Proxy-Connection: keep-alive\r\n\r\n"),
8369 MockWrite("GET / HTTP/1.1\r\n"
8370 "Host: www.example.org\r\n"
8371 "Connection: keep-alive\r\n\r\n"),
[email protected]2df19bb2010-08-25 20:13:468372 };
8373
8374 MockRead data_reads[] = {
8375 MockRead("HTTP/1.0 200 Connected\r\n\r\n"),
8376 MockRead("HTTP/1.1 200 OK\r\n"),
8377 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
8378 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:068379 MockRead(SYNCHRONOUS, OK),
[email protected]2df19bb2010-08-25 20:13:468380 };
8381
8382 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
8383 data_writes, arraysize(data_writes));
[email protected]8ddf8322012-02-23 18:08:068384 SSLSocketDataProvider proxy_ssl(ASYNC, OK); // SSL to the proxy
8385 SSLSocketDataProvider tunnel_ssl(ASYNC, OK); // SSL through the tunnel
[email protected]2df19bb2010-08-25 20:13:468386
[email protected]bb88e1d32013-05-03 23:11:078387 session_deps_.socket_factory->AddSocketDataProvider(&data);
8388 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy_ssl);
8389 session_deps_.socket_factory->AddSSLSocketDataProvider(&tunnel_ssl);
[email protected]2df19bb2010-08-25 20:13:468390
[email protected]49639fa2011-12-20 23:22:418391 TestCompletionCallback callback;
[email protected]2df19bb2010-08-25 20:13:468392
danakj1fd259a02016-04-16 03:17:098393 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:168394 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]2df19bb2010-08-25 20:13:468395
tfarina42834112016-09-22 13:38:208396 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:018397 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2df19bb2010-08-25 20:13:468398
8399 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:018400 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:168401 const HttpResponseInfo* response = trans.GetResponseInfo();
[email protected]2df19bb2010-08-25 20:13:468402
wezca1070932016-05-26 20:30:528403 ASSERT_TRUE(response);
[email protected]2df19bb2010-08-25 20:13:468404
tbansal2ecbbc72016-10-06 17:15:478405 EXPECT_TRUE(response->proxy_server.is_https());
[email protected]2df19bb2010-08-25 20:13:468406 EXPECT_TRUE(response->headers->IsKeepAlive());
8407 EXPECT_EQ(200, response->headers->response_code());
8408 EXPECT_EQ(100, response->headers->GetContentLength());
8409 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
[email protected]029c83b62013-01-24 05:28:208410
8411 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:168412 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]029c83b62013-01-24 05:28:208413 TestLoadTimingNotReusedWithPac(load_timing_info,
8414 CONNECT_TIMING_HAS_SSL_TIMES);
[email protected]2df19bb2010-08-25 20:13:468415}
8416
[email protected]511f6f52010-12-17 03:58:298417// Test an HTTPS Proxy's ability to redirect a CONNECT request
bncd16676a2016-07-20 16:23:018418TEST_F(HttpNetworkTransactionTest, RedirectOfHttpsConnectViaHttpsProxy) {
rdsmith82957ad2015-09-16 19:42:038419 session_deps_.proxy_service =
8420 ProxyService::CreateFixedFromPacResult("HTTPS proxy:70");
vishal.b62985ca92015-04-17 08:45:518421 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:078422 session_deps_.net_log = &net_log;
[email protected]511f6f52010-12-17 03:58:298423
8424 HttpRequestInfo request;
8425 request.method = "GET";
bncce36dca22015-04-21 22:11:238426 request.url = GURL("https://www.example.org/");
[email protected]511f6f52010-12-17 03:58:298427
8428 MockWrite data_writes[] = {
rsleevidb16bb02015-11-12 23:47:178429 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
8430 "Host: www.example.org:443\r\n"
8431 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]511f6f52010-12-17 03:58:298432 };
8433
8434 MockRead data_reads[] = {
8435 MockRead("HTTP/1.1 302 Redirect\r\n"),
8436 MockRead("Location: http://login.example.com/\r\n"),
8437 MockRead("Content-Length: 0\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:068438 MockRead(SYNCHRONOUS, OK),
[email protected]511f6f52010-12-17 03:58:298439 };
8440
8441 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
8442 data_writes, arraysize(data_writes));
[email protected]8ddf8322012-02-23 18:08:068443 SSLSocketDataProvider proxy_ssl(ASYNC, OK); // SSL to the proxy
[email protected]511f6f52010-12-17 03:58:298444
[email protected]bb88e1d32013-05-03 23:11:078445 session_deps_.socket_factory->AddSocketDataProvider(&data);
8446 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy_ssl);
[email protected]511f6f52010-12-17 03:58:298447
[email protected]49639fa2011-12-20 23:22:418448 TestCompletionCallback callback;
[email protected]511f6f52010-12-17 03:58:298449
danakj1fd259a02016-04-16 03:17:098450 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:168451 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]511f6f52010-12-17 03:58:298452
tfarina42834112016-09-22 13:38:208453 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:018454 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]511f6f52010-12-17 03:58:298455
8456 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:018457 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:168458 const HttpResponseInfo* response = trans.GetResponseInfo();
[email protected]511f6f52010-12-17 03:58:298459
wezca1070932016-05-26 20:30:528460 ASSERT_TRUE(response);
[email protected]511f6f52010-12-17 03:58:298461
8462 EXPECT_EQ(302, response->headers->response_code());
8463 std::string url;
8464 EXPECT_TRUE(response->headers->IsRedirect(&url));
8465 EXPECT_EQ("http://login.example.com/", url);
[email protected]029c83b62013-01-24 05:28:208466
8467 // In the case of redirects from proxies, HttpNetworkTransaction returns
8468 // timing for the proxy connection instead of the connection to the host,
8469 // and no send / receive times.
8470 // See HttpNetworkTransaction::OnHttpsProxyTunnelResponse.
8471 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:168472 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]029c83b62013-01-24 05:28:208473
8474 EXPECT_FALSE(load_timing_info.socket_reused);
mikecironef22f9812016-10-04 03:40:198475 EXPECT_NE(NetLogSource::kInvalidId, load_timing_info.socket_log_id);
[email protected]029c83b62013-01-24 05:28:208476
8477 EXPECT_FALSE(load_timing_info.proxy_resolve_start.is_null());
8478 EXPECT_LE(load_timing_info.proxy_resolve_start,
8479 load_timing_info.proxy_resolve_end);
8480 EXPECT_LE(load_timing_info.proxy_resolve_end,
8481 load_timing_info.connect_timing.connect_start);
8482 ExpectConnectTimingHasTimes(
8483 load_timing_info.connect_timing,
8484 CONNECT_TIMING_HAS_DNS_TIMES | CONNECT_TIMING_HAS_SSL_TIMES);
8485
8486 EXPECT_TRUE(load_timing_info.send_start.is_null());
8487 EXPECT_TRUE(load_timing_info.send_end.is_null());
8488 EXPECT_TRUE(load_timing_info.receive_headers_end.is_null());
[email protected]511f6f52010-12-17 03:58:298489}
8490
8491// Test an HTTPS (SPDY) Proxy's ability to redirect a CONNECT request
bncd16676a2016-07-20 16:23:018492TEST_F(HttpNetworkTransactionTest, RedirectOfHttpsConnectViaSpdyProxy) {
rdsmith82957ad2015-09-16 19:42:038493 session_deps_.proxy_service = ProxyService::CreateFixed("https://proxy:70");
[email protected]511f6f52010-12-17 03:58:298494
8495 HttpRequestInfo request;
8496 request.method = "GET";
bncce36dca22015-04-21 22:11:238497 request.url = GURL("https://www.example.org/");
[email protected]511f6f52010-12-17 03:58:298498
bncdf80d44fd2016-07-15 20:27:418499 SpdySerializedFrame conn(spdy_util_.ConstructSpdyConnect(
bncce36dca22015-04-21 22:11:238500 NULL, 0, 1, LOWEST, HostPortPair("www.example.org", 443)));
bncdf80d44fd2016-07-15 20:27:418501 SpdySerializedFrame goaway(
diannahu9904e272017-02-03 14:40:088502 spdy_util_.ConstructSpdyRstStream(1, ERROR_CODE_CANCEL));
[email protected]511f6f52010-12-17 03:58:298503 MockWrite data_writes[] = {
bncdf80d44fd2016-07-15 20:27:418504 CreateMockWrite(conn, 0, SYNCHRONOUS),
8505 CreateMockWrite(goaway, 2, SYNCHRONOUS),
[email protected]511f6f52010-12-17 03:58:298506 };
8507
8508 static const char* const kExtraHeaders[] = {
8509 "location",
8510 "http://login.example.com/",
8511 };
bnc42331402016-07-25 13:36:158512 SpdySerializedFrame resp(spdy_util_.ConstructSpdyReplyError(
bncc9f762a2016-12-06 20:38:238513 "302", kExtraHeaders, arraysize(kExtraHeaders) / 2, 1));
[email protected]511f6f52010-12-17 03:58:298514 MockRead data_reads[] = {
bncdf80d44fd2016-07-15 20:27:418515 CreateMockRead(resp, 1), MockRead(ASYNC, 0, 3), // EOF
[email protected]511f6f52010-12-17 03:58:298516 };
8517
rch8e6c6c42015-05-01 14:05:138518 SequencedSocketData data(data_reads, arraysize(data_reads), data_writes,
8519 arraysize(data_writes));
[email protected]8ddf8322012-02-23 18:08:068520 SSLSocketDataProvider proxy_ssl(ASYNC, OK); // SSL to the proxy
bnc3cf2a592016-08-11 14:48:368521 proxy_ssl.next_proto = kProtoHTTP2;
[email protected]511f6f52010-12-17 03:58:298522
[email protected]bb88e1d32013-05-03 23:11:078523 session_deps_.socket_factory->AddSocketDataProvider(&data);
8524 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy_ssl);
[email protected]511f6f52010-12-17 03:58:298525
[email protected]49639fa2011-12-20 23:22:418526 TestCompletionCallback callback;
[email protected]511f6f52010-12-17 03:58:298527
danakj1fd259a02016-04-16 03:17:098528 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:168529 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]511f6f52010-12-17 03:58:298530
tfarina42834112016-09-22 13:38:208531 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:018532 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]511f6f52010-12-17 03:58:298533
8534 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:018535 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:168536 const HttpResponseInfo* response = trans.GetResponseInfo();
[email protected]511f6f52010-12-17 03:58:298537
wezca1070932016-05-26 20:30:528538 ASSERT_TRUE(response);
[email protected]511f6f52010-12-17 03:58:298539
8540 EXPECT_EQ(302, response->headers->response_code());
8541 std::string url;
8542 EXPECT_TRUE(response->headers->IsRedirect(&url));
8543 EXPECT_EQ("http://login.example.com/", url);
8544}
8545
[email protected]4eddbc732012-08-09 05:40:178546// Test that an HTTPS proxy's response to a CONNECT request is filtered.
bncd16676a2016-07-20 16:23:018547TEST_F(HttpNetworkTransactionTest, ErrorResponseToHttpsConnectViaHttpsProxy) {
rdsmith82957ad2015-09-16 19:42:038548 session_deps_.proxy_service = ProxyService::CreateFixed("https://proxy:70");
[email protected]511f6f52010-12-17 03:58:298549
8550 HttpRequestInfo request;
8551 request.method = "GET";
bncce36dca22015-04-21 22:11:238552 request.url = GURL("https://www.example.org/");
[email protected]511f6f52010-12-17 03:58:298553
8554 MockWrite data_writes[] = {
rsleevidb16bb02015-11-12 23:47:178555 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
8556 "Host: www.example.org:443\r\n"
8557 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]511f6f52010-12-17 03:58:298558 };
8559
8560 MockRead data_reads[] = {
8561 MockRead("HTTP/1.1 404 Not Found\r\n"),
8562 MockRead("Content-Length: 23\r\n\r\n"),
8563 MockRead("The host does not exist"),
[email protected]8ddf8322012-02-23 18:08:068564 MockRead(SYNCHRONOUS, OK),
[email protected]511f6f52010-12-17 03:58:298565 };
8566
8567 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
8568 data_writes, arraysize(data_writes));
[email protected]8ddf8322012-02-23 18:08:068569 SSLSocketDataProvider proxy_ssl(ASYNC, OK); // SSL to the proxy
[email protected]511f6f52010-12-17 03:58:298570
[email protected]bb88e1d32013-05-03 23:11:078571 session_deps_.socket_factory->AddSocketDataProvider(&data);
8572 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy_ssl);
[email protected]511f6f52010-12-17 03:58:298573
[email protected]49639fa2011-12-20 23:22:418574 TestCompletionCallback callback;
[email protected]511f6f52010-12-17 03:58:298575
danakj1fd259a02016-04-16 03:17:098576 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:168577 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]511f6f52010-12-17 03:58:298578
tfarina42834112016-09-22 13:38:208579 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:018580 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]511f6f52010-12-17 03:58:298581
8582 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:018583 EXPECT_THAT(rv, IsError(ERR_TUNNEL_CONNECTION_FAILED));
[email protected]511f6f52010-12-17 03:58:298584
ttuttle960fcbf2016-04-19 13:26:328585 // TODO(juliatuttle): Anything else to check here?
[email protected]511f6f52010-12-17 03:58:298586}
8587
[email protected]4eddbc732012-08-09 05:40:178588// Test that a SPDY proxy's response to a CONNECT request is filtered.
bncd16676a2016-07-20 16:23:018589TEST_F(HttpNetworkTransactionTest, ErrorResponseToHttpsConnectViaSpdyProxy) {
rdsmith82957ad2015-09-16 19:42:038590 session_deps_.proxy_service = ProxyService::CreateFixed("https://proxy:70");
[email protected]511f6f52010-12-17 03:58:298591
8592 HttpRequestInfo request;
8593 request.method = "GET";
bncce36dca22015-04-21 22:11:238594 request.url = GURL("https://www.example.org/");
[email protected]511f6f52010-12-17 03:58:298595
bncdf80d44fd2016-07-15 20:27:418596 SpdySerializedFrame conn(spdy_util_.ConstructSpdyConnect(
bncce36dca22015-04-21 22:11:238597 NULL, 0, 1, LOWEST, HostPortPair("www.example.org", 443)));
bncdf80d44fd2016-07-15 20:27:418598 SpdySerializedFrame rst(
diannahu9904e272017-02-03 14:40:088599 spdy_util_.ConstructSpdyRstStream(1, ERROR_CODE_CANCEL));
[email protected]511f6f52010-12-17 03:58:298600 MockWrite data_writes[] = {
bncdf80d44fd2016-07-15 20:27:418601 CreateMockWrite(conn, 0), CreateMockWrite(rst, 3),
[email protected]511f6f52010-12-17 03:58:298602 };
8603
8604 static const char* const kExtraHeaders[] = {
8605 "location",
8606 "http://login.example.com/",
8607 };
bnc42331402016-07-25 13:36:158608 SpdySerializedFrame resp(spdy_util_.ConstructSpdyReplyError(
bncc9f762a2016-12-06 20:38:238609 "404", kExtraHeaders, arraysize(kExtraHeaders) / 2, 1));
bncdf80d44fd2016-07-15 20:27:418610 SpdySerializedFrame body(spdy_util_.ConstructSpdyDataFrame(
bncb03b1092016-04-06 11:19:558611 1, "The host does not exist", 23, true));
[email protected]511f6f52010-12-17 03:58:298612 MockRead data_reads[] = {
bncdf80d44fd2016-07-15 20:27:418613 CreateMockRead(resp, 1), CreateMockRead(body, 2),
rch8e6c6c42015-05-01 14:05:138614 MockRead(ASYNC, 0, 4), // EOF
[email protected]511f6f52010-12-17 03:58:298615 };
8616
rch8e6c6c42015-05-01 14:05:138617 SequencedSocketData data(data_reads, arraysize(data_reads), data_writes,
8618 arraysize(data_writes));
[email protected]8ddf8322012-02-23 18:08:068619 SSLSocketDataProvider proxy_ssl(ASYNC, OK); // SSL to the proxy
bnc3cf2a592016-08-11 14:48:368620 proxy_ssl.next_proto = kProtoHTTP2;
[email protected]511f6f52010-12-17 03:58:298621
[email protected]bb88e1d32013-05-03 23:11:078622 session_deps_.socket_factory->AddSocketDataProvider(&data);
8623 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy_ssl);
[email protected]511f6f52010-12-17 03:58:298624
[email protected]49639fa2011-12-20 23:22:418625 TestCompletionCallback callback;
[email protected]511f6f52010-12-17 03:58:298626
danakj1fd259a02016-04-16 03:17:098627 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:168628 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]511f6f52010-12-17 03:58:298629
tfarina42834112016-09-22 13:38:208630 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:018631 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]511f6f52010-12-17 03:58:298632
8633 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:018634 EXPECT_THAT(rv, IsError(ERR_TUNNEL_CONNECTION_FAILED));
[email protected]511f6f52010-12-17 03:58:298635
ttuttle960fcbf2016-04-19 13:26:328636 // TODO(juliatuttle): Anything else to check here?
[email protected]511f6f52010-12-17 03:58:298637}
8638
[email protected]0c5fb722012-02-28 11:50:358639// Test the request-challenge-retry sequence for basic auth, through
8640// a SPDY proxy over a single SPDY session.
bncd16676a2016-07-20 16:23:018641TEST_F(HttpNetworkTransactionTest, BasicAuthSpdyProxy) {
[email protected]0c5fb722012-02-28 11:50:358642 HttpRequestInfo request;
8643 request.method = "GET";
bncce36dca22015-04-21 22:11:238644 request.url = GURL("https://www.example.org/");
[email protected]0c5fb722012-02-28 11:50:358645 // when the no authentication data flag is set.
ttuttle859dc7a2015-04-23 19:42:298646 request.load_flags = LOAD_DO_NOT_SEND_AUTH_DATA;
[email protected]0c5fb722012-02-28 11:50:358647
8648 // Configure against https proxy server "myproxy:70".
rdsmith82957ad2015-09-16 19:42:038649 session_deps_.proxy_service =
8650 ProxyService::CreateFixedFromPacResult("HTTPS myproxy:70");
vishal.b62985ca92015-04-17 08:45:518651 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:078652 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:098653 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]0c5fb722012-02-28 11:50:358654
8655 // Since we have proxy, should try to establish tunnel.
bncdf80d44fd2016-07-15 20:27:418656 SpdySerializedFrame req(spdy_util_.ConstructSpdyConnect(
bncce36dca22015-04-21 22:11:238657 NULL, 0, 1, LOWEST, HostPortPair("www.example.org", 443)));
bncdf80d44fd2016-07-15 20:27:418658 SpdySerializedFrame rst(
diannahu9904e272017-02-03 14:40:088659 spdy_util_.ConstructSpdyRstStream(1, ERROR_CODE_CANCEL));
rdsmithebb50aa2015-11-12 03:44:388660 spdy_util_.UpdateWithStreamDestruction(1);
[email protected]0c5fb722012-02-28 11:50:358661
bnc691fda62016-08-12 00:43:168662 // After calling trans.RestartWithAuth(), this is the request we should
[email protected]0c5fb722012-02-28 11:50:358663 // be issuing -- the final header line contains the credentials.
8664 const char* const kAuthCredentials[] = {
8665 "proxy-authorization", "Basic Zm9vOmJhcg==",
8666 };
bncdf80d44fd2016-07-15 20:27:418667 SpdySerializedFrame connect2(spdy_util_.ConstructSpdyConnect(
lgarrona91df87f2014-12-05 00:51:348668 kAuthCredentials, arraysize(kAuthCredentials) / 2, 3, LOWEST,
bncce36dca22015-04-21 22:11:238669 HostPortPair("www.example.org", 443)));
8670 // fetch https://www.example.org/ via HTTP
8671 const char get[] =
8672 "GET / HTTP/1.1\r\n"
8673 "Host: www.example.org\r\n"
8674 "Connection: keep-alive\r\n\r\n";
bncdf80d44fd2016-07-15 20:27:418675 SpdySerializedFrame wrapped_get(
8676 spdy_util_.ConstructSpdyDataFrame(3, get, strlen(get), false));
[email protected]0c5fb722012-02-28 11:50:358677
8678 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:418679 CreateMockWrite(req, 0, ASYNC), CreateMockWrite(rst, 2, ASYNC),
8680 CreateMockWrite(connect2, 3), CreateMockWrite(wrapped_get, 5),
[email protected]0c5fb722012-02-28 11:50:358681 };
8682
8683 // The proxy responds to the connect with a 407, using a persistent
8684 // connection.
thestig9d3bb0c2015-01-24 00:49:518685 const char kAuthStatus[] = "407";
[email protected]0c5fb722012-02-28 11:50:358686 const char* const kAuthChallenge[] = {
[email protected]0c5fb722012-02-28 11:50:358687 "proxy-authenticate", "Basic realm=\"MyRealm1\"",
8688 };
bnc42331402016-07-25 13:36:158689 SpdySerializedFrame conn_auth_resp(spdy_util_.ConstructSpdyReplyError(
bncdf80d44fd2016-07-15 20:27:418690 kAuthStatus, kAuthChallenge, arraysize(kAuthChallenge) / 2, 1));
[email protected]0c5fb722012-02-28 11:50:358691
bnc42331402016-07-25 13:36:158692 SpdySerializedFrame conn_resp(spdy_util_.ConstructSpdyGetReply(NULL, 0, 3));
[email protected]0c5fb722012-02-28 11:50:358693 const char resp[] = "HTTP/1.1 200 OK\r\n"
8694 "Content-Length: 5\r\n\r\n";
8695
bncdf80d44fd2016-07-15 20:27:418696 SpdySerializedFrame wrapped_get_resp(
8697 spdy_util_.ConstructSpdyDataFrame(3, resp, strlen(resp), false));
8698 SpdySerializedFrame wrapped_body(
8699 spdy_util_.ConstructSpdyDataFrame(3, "hello", 5, false));
[email protected]0c5fb722012-02-28 11:50:358700 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:418701 CreateMockRead(conn_auth_resp, 1, ASYNC),
8702 CreateMockRead(conn_resp, 4, ASYNC),
8703 CreateMockRead(wrapped_get_resp, 6, ASYNC),
8704 CreateMockRead(wrapped_body, 7, ASYNC),
rch8e6c6c42015-05-01 14:05:138705 MockRead(ASYNC, OK, 8), // EOF. May or may not be read.
[email protected]0c5fb722012-02-28 11:50:358706 };
8707
rch8e6c6c42015-05-01 14:05:138708 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
8709 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:078710 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]0c5fb722012-02-28 11:50:358711 // Negotiate SPDY to the proxy
8712 SSLSocketDataProvider proxy(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:368713 proxy.next_proto = kProtoHTTP2;
[email protected]bb88e1d32013-05-03 23:11:078714 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy);
[email protected]0c5fb722012-02-28 11:50:358715 // Vanilla SSL to the server
8716 SSLSocketDataProvider server(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:078717 session_deps_.socket_factory->AddSSLSocketDataProvider(&server);
[email protected]0c5fb722012-02-28 11:50:358718
8719 TestCompletionCallback callback1;
8720
bnc87dcefc2017-05-25 12:47:588721 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:198722 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]0c5fb722012-02-28 11:50:358723
8724 int rv = trans->Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:018725 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]0c5fb722012-02-28 11:50:358726
8727 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:018728 EXPECT_THAT(rv, IsOk());
mmenke43758e62015-05-04 21:09:468729 TestNetLogEntry::List entries;
[email protected]0c5fb722012-02-28 11:50:358730 log.GetEntries(&entries);
8731 size_t pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:008732 entries, 0, NetLogEventType::HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
8733 NetLogEventPhase::NONE);
[email protected]0c5fb722012-02-28 11:50:358734 ExpectLogContainsSomewhere(
8735 entries, pos,
mikecirone8b85c432016-09-08 19:11:008736 NetLogEventType::HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
8737 NetLogEventPhase::NONE);
[email protected]0c5fb722012-02-28 11:50:358738
8739 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:528740 ASSERT_TRUE(response);
8741 ASSERT_TRUE(response->headers);
[email protected]0c5fb722012-02-28 11:50:358742 EXPECT_EQ(407, response->headers->response_code());
8743 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
wezca1070932016-05-26 20:30:528744 EXPECT_TRUE(response->auth_challenge);
asanka098c0092016-06-16 20:18:438745 EXPECT_TRUE(CheckBasicSecureProxyAuth(response->auth_challenge.get()));
[email protected]0c5fb722012-02-28 11:50:358746
8747 TestCompletionCallback callback2;
8748
8749 rv = trans->RestartWithAuth(AuthCredentials(kFoo, kBar),
8750 callback2.callback());
robpercival214763f2016-07-01 23:27:018751 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]0c5fb722012-02-28 11:50:358752
8753 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:018754 EXPECT_THAT(rv, IsOk());
[email protected]0c5fb722012-02-28 11:50:358755
8756 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:528757 ASSERT_TRUE(response);
[email protected]0c5fb722012-02-28 11:50:358758
8759 EXPECT_TRUE(response->headers->IsKeepAlive());
8760 EXPECT_EQ(200, response->headers->response_code());
8761 EXPECT_EQ(5, response->headers->GetContentLength());
8762 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
8763
8764 // The password prompt info should not be set.
wezca1070932016-05-26 20:30:528765 EXPECT_FALSE(response->auth_challenge);
[email protected]0c5fb722012-02-28 11:50:358766
[email protected]029c83b62013-01-24 05:28:208767 LoadTimingInfo load_timing_info;
8768 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
8769 TestLoadTimingNotReusedWithPac(load_timing_info,
8770 CONNECT_TIMING_HAS_SSL_TIMES);
8771
[email protected]0c5fb722012-02-28 11:50:358772 trans.reset();
8773 session->CloseAllConnections();
8774}
8775
[email protected]7c6f7ba2012-04-03 04:09:298776// Test that an explicitly trusted SPDY proxy can push a resource from an
8777// origin that is different from that of its associated resource.
bncd16676a2016-07-20 16:23:018778TEST_F(HttpNetworkTransactionTest, CrossOriginSPDYProxyPush) {
tbansal28e68f82016-02-04 02:56:158779 // Configure the proxy delegate to allow cross-origin SPDY pushes.
Jeremy Roman0579ed62017-08-29 15:56:198780 auto proxy_delegate = std::make_unique<TestProxyDelegate>();
tbansal28e68f82016-02-04 02:56:158781 proxy_delegate->set_trusted_spdy_proxy(net::ProxyServer::FromURI(
8782 "https://myproxy:443", net::ProxyServer::SCHEME_HTTP));
[email protected]7c6f7ba2012-04-03 04:09:298783 HttpRequestInfo request;
8784 HttpRequestInfo push_request;
8785
[email protected]7c6f7ba2012-04-03 04:09:298786 request.method = "GET";
bncce36dca22015-04-21 22:11:238787 request.url = GURL("http://www.example.org/");
[email protected]7c6f7ba2012-04-03 04:09:298788 push_request.method = "GET";
8789 push_request.url = GURL("http://www.another-origin.com/foo.dat");
8790
tbansal28e68f82016-02-04 02:56:158791 // Configure against https proxy server "myproxy:443".
rdsmith82957ad2015-09-16 19:42:038792 session_deps_.proxy_service =
tbansal28e68f82016-02-04 02:56:158793 ProxyService::CreateFixedFromPacResult("HTTPS myproxy:443");
vishal.b62985ca92015-04-17 08:45:518794 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:078795 session_deps_.net_log = log.bound().net_log();
[email protected]61b4efc2012-04-27 18:12:508796
inlinechan894515af2016-12-09 02:40:108797 session_deps_.proxy_delegate = std::move(proxy_delegate);
[email protected]61b4efc2012-04-27 18:12:508798
danakj1fd259a02016-04-16 03:17:098799 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]7c6f7ba2012-04-03 04:09:298800
bncdf80d44fd2016-07-15 20:27:418801 SpdySerializedFrame stream1_syn(
bncb26024382016-06-29 02:39:458802 spdy_util_.ConstructSpdyGet("http://www.example.org/", 1, LOWEST));
tombergan5d22c182017-01-11 02:05:358803 SpdySerializedFrame stream2_priority(
8804 spdy_util_.ConstructSpdyPriority(2, 1, IDLE, true));
[email protected]7c6f7ba2012-04-03 04:09:298805
8806 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:418807 CreateMockWrite(stream1_syn, 0, ASYNC),
tombergan5d22c182017-01-11 02:05:358808 CreateMockWrite(stream2_priority, 3, ASYNC),
[email protected]7c6f7ba2012-04-03 04:09:298809 };
8810
Bence Béky7bf94362018-01-10 13:19:368811 SpdySerializedFrame stream2_syn(spdy_util_.ConstructSpdyPush(
8812 NULL, 0, 2, 1, "http://www.another-origin.com/foo.dat"));
8813
bncdf80d44fd2016-07-15 20:27:418814 SpdySerializedFrame stream1_reply(
bnc42331402016-07-25 13:36:158815 spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
[email protected]7c6f7ba2012-04-03 04:09:298816
bncdf80d44fd2016-07-15 20:27:418817 SpdySerializedFrame stream1_body(spdy_util_.ConstructSpdyDataFrame(1, true));
[email protected]7c6f7ba2012-04-03 04:09:298818
[email protected]8a0fc822013-06-27 20:52:438819 const char kPushedData[] = "pushed";
bncdf80d44fd2016-07-15 20:27:418820 SpdySerializedFrame stream2_body(spdy_util_.ConstructSpdyDataFrame(
8821 2, kPushedData, strlen(kPushedData), true));
[email protected]7c6f7ba2012-04-03 04:09:298822
8823 MockRead spdy_reads[] = {
Bence Béky7bf94362018-01-10 13:19:368824 CreateMockRead(stream2_syn, 1, ASYNC),
8825 CreateMockRead(stream1_reply, 2, ASYNC),
tombergan5d22c182017-01-11 02:05:358826 CreateMockRead(stream1_body, 4, ASYNC),
8827 CreateMockRead(stream2_body, 5, ASYNC),
8828 MockRead(SYNCHRONOUS, ERR_IO_PENDING, 6), // Force a hang
[email protected]7c6f7ba2012-04-03 04:09:298829 };
8830
rch8e6c6c42015-05-01 14:05:138831 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
8832 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:078833 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]7c6f7ba2012-04-03 04:09:298834 // Negotiate SPDY to the proxy
8835 SSLSocketDataProvider proxy(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:368836 proxy.next_proto = kProtoHTTP2;
[email protected]bb88e1d32013-05-03 23:11:078837 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy);
[email protected]7c6f7ba2012-04-03 04:09:298838
bnc87dcefc2017-05-25 12:47:588839 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:198840 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]7c6f7ba2012-04-03 04:09:298841 TestCompletionCallback callback;
8842 int rv = trans->Start(&request, callback.callback(), log.bound());
robpercival214763f2016-07-01 23:27:018843 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]7c6f7ba2012-04-03 04:09:298844
8845 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:018846 EXPECT_THAT(rv, IsOk());
[email protected]7c6f7ba2012-04-03 04:09:298847 const HttpResponseInfo* response = trans->GetResponseInfo();
8848
bnc87dcefc2017-05-25 12:47:588849 auto push_trans =
Jeremy Roman0579ed62017-08-29 15:56:198850 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]90499482013-06-01 00:39:508851 rv = push_trans->Start(&push_request, callback.callback(), log.bound());
robpercival214763f2016-07-01 23:27:018852 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]7c6f7ba2012-04-03 04:09:298853
8854 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:018855 EXPECT_THAT(rv, IsOk());
[email protected]7c6f7ba2012-04-03 04:09:298856 const HttpResponseInfo* push_response = push_trans->GetResponseInfo();
8857
wezca1070932016-05-26 20:30:528858 ASSERT_TRUE(response);
[email protected]7c6f7ba2012-04-03 04:09:298859 EXPECT_TRUE(response->headers->IsKeepAlive());
8860
8861 EXPECT_EQ(200, response->headers->response_code());
8862 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
8863
8864 std::string response_data;
8865 rv = ReadTransaction(trans.get(), &response_data);
robpercival214763f2016-07-01 23:27:018866 EXPECT_THAT(rv, IsOk());
[email protected]7c6f7ba2012-04-03 04:09:298867 EXPECT_EQ("hello!", response_data);
8868
[email protected]029c83b62013-01-24 05:28:208869 LoadTimingInfo load_timing_info;
8870 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
8871 TestLoadTimingNotReusedWithPac(load_timing_info,
8872 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
8873
[email protected]7c6f7ba2012-04-03 04:09:298874 // Verify the pushed stream.
wezca1070932016-05-26 20:30:528875 EXPECT_TRUE(push_response->headers);
[email protected]7c6f7ba2012-04-03 04:09:298876 EXPECT_EQ(200, push_response->headers->response_code());
8877
8878 rv = ReadTransaction(push_trans.get(), &response_data);
robpercival214763f2016-07-01 23:27:018879 EXPECT_THAT(rv, IsOk());
[email protected]7c6f7ba2012-04-03 04:09:298880 EXPECT_EQ("pushed", response_data);
8881
[email protected]029c83b62013-01-24 05:28:208882 LoadTimingInfo push_load_timing_info;
8883 EXPECT_TRUE(push_trans->GetLoadTimingInfo(&push_load_timing_info));
8884 TestLoadTimingReusedWithPac(push_load_timing_info);
8885 // The transactions should share a socket ID, despite being for different
8886 // origins.
8887 EXPECT_EQ(load_timing_info.socket_log_id,
8888 push_load_timing_info.socket_log_id);
8889
[email protected]7c6f7ba2012-04-03 04:09:298890 trans.reset();
8891 push_trans.reset();
8892 session->CloseAllConnections();
8893}
8894
[email protected]8c843192012-04-05 07:15:008895// Test that an explicitly trusted SPDY proxy cannot push HTTPS content.
bncd16676a2016-07-20 16:23:018896TEST_F(HttpNetworkTransactionTest, CrossOriginProxyPushCorrectness) {
tbansal28e68f82016-02-04 02:56:158897 // Configure the proxy delegate to allow cross-origin SPDY pushes.
Jeremy Roman0579ed62017-08-29 15:56:198898 auto proxy_delegate = std::make_unique<TestProxyDelegate>();
tbansal28e68f82016-02-04 02:56:158899 proxy_delegate->set_trusted_spdy_proxy(net::ProxyServer::FromURI(
8900 "https://myproxy:443", net::ProxyServer::SCHEME_HTTP));
[email protected]8c843192012-04-05 07:15:008901 HttpRequestInfo request;
8902
8903 request.method = "GET";
bncce36dca22015-04-21 22:11:238904 request.url = GURL("http://www.example.org/");
[email protected]8c843192012-04-05 07:15:008905
tbansal28e68f82016-02-04 02:56:158906 session_deps_.proxy_service =
8907 ProxyService::CreateFixed("https://myproxy:443");
vishal.b62985ca92015-04-17 08:45:518908 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:078909 session_deps_.net_log = log.bound().net_log();
[email protected]61b4efc2012-04-27 18:12:508910
8911 // Enable cross-origin push.
inlinechan894515af2016-12-09 02:40:108912 session_deps_.proxy_delegate = std::move(proxy_delegate);
[email protected]61b4efc2012-04-27 18:12:508913
danakj1fd259a02016-04-16 03:17:098914 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]8c843192012-04-05 07:15:008915
bncdf80d44fd2016-07-15 20:27:418916 SpdySerializedFrame stream1_syn(
bncb26024382016-06-29 02:39:458917 spdy_util_.ConstructSpdyGet("http://www.example.org/", 1, LOWEST));
[email protected]8c843192012-04-05 07:15:008918
bncdf80d44fd2016-07-15 20:27:418919 SpdySerializedFrame push_rst(
diannahu9904e272017-02-03 14:40:088920 spdy_util_.ConstructSpdyRstStream(2, ERROR_CODE_REFUSED_STREAM));
[email protected]8c843192012-04-05 07:15:008921
8922 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:418923 CreateMockWrite(stream1_syn, 0, ASYNC), CreateMockWrite(push_rst, 3),
[email protected]8c843192012-04-05 07:15:008924 };
8925
bncdf80d44fd2016-07-15 20:27:418926 SpdySerializedFrame stream1_reply(
bnc42331402016-07-25 13:36:158927 spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
[email protected]8c843192012-04-05 07:15:008928
bncdf80d44fd2016-07-15 20:27:418929 SpdySerializedFrame stream1_body(spdy_util_.ConstructSpdyDataFrame(1, true));
[email protected]8c843192012-04-05 07:15:008930
bncdf80d44fd2016-07-15 20:27:418931 SpdySerializedFrame stream2_syn(spdy_util_.ConstructSpdyPush(
bncb03b1092016-04-06 11:19:558932 NULL, 0, 2, 1, "https://www.another-origin.com/foo.dat"));
[email protected]8c843192012-04-05 07:15:008933
8934 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:418935 CreateMockRead(stream1_reply, 1, ASYNC),
8936 CreateMockRead(stream2_syn, 2, ASYNC),
8937 CreateMockRead(stream1_body, 4, ASYNC),
mmenkee24011922015-12-17 22:12:598938 MockRead(SYNCHRONOUS, ERR_IO_PENDING, 5), // Force a hang
[email protected]8c843192012-04-05 07:15:008939 };
8940
rch8e6c6c42015-05-01 14:05:138941 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
8942 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:078943 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]8c843192012-04-05 07:15:008944 // Negotiate SPDY to the proxy
8945 SSLSocketDataProvider proxy(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:368946 proxy.next_proto = kProtoHTTP2;
[email protected]bb88e1d32013-05-03 23:11:078947 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy);
[email protected]8c843192012-04-05 07:15:008948
bnc87dcefc2017-05-25 12:47:588949 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:198950 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]8c843192012-04-05 07:15:008951 TestCompletionCallback callback;
8952 int rv = trans->Start(&request, callback.callback(), log.bound());
robpercival214763f2016-07-01 23:27:018953 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]8c843192012-04-05 07:15:008954
8955 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:018956 EXPECT_THAT(rv, IsOk());
[email protected]8c843192012-04-05 07:15:008957 const HttpResponseInfo* response = trans->GetResponseInfo();
8958
wezca1070932016-05-26 20:30:528959 ASSERT_TRUE(response);
[email protected]8c843192012-04-05 07:15:008960 EXPECT_TRUE(response->headers->IsKeepAlive());
8961
8962 EXPECT_EQ(200, response->headers->response_code());
8963 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
8964
8965 std::string response_data;
8966 rv = ReadTransaction(trans.get(), &response_data);
robpercival214763f2016-07-01 23:27:018967 EXPECT_THAT(rv, IsOk());
[email protected]8c843192012-04-05 07:15:008968 EXPECT_EQ("hello!", response_data);
8969
8970 trans.reset();
8971 session->CloseAllConnections();
8972}
8973
tbansal8ef1d3e2016-02-03 04:05:428974// Test that an explicitly trusted SPDY proxy can push same-origin HTTPS
8975// resources.
bncd16676a2016-07-20 16:23:018976TEST_F(HttpNetworkTransactionTest, SameOriginProxyPushCorrectness) {
tbansal28e68f82016-02-04 02:56:158977 // Configure the proxy delegate to allow cross-origin SPDY pushes.
Jeremy Roman0579ed62017-08-29 15:56:198978 auto proxy_delegate = std::make_unique<TestProxyDelegate>();
tbansal28e68f82016-02-04 02:56:158979 proxy_delegate->set_trusted_spdy_proxy(
8980 net::ProxyServer::FromURI("myproxy:70", net::ProxyServer::SCHEME_HTTP));
8981
tbansal8ef1d3e2016-02-03 04:05:428982 HttpRequestInfo request;
8983
8984 request.method = "GET";
8985 request.url = GURL("http://www.example.org/");
8986
8987 // Configure against https proxy server "myproxy:70".
8988 session_deps_.proxy_service = ProxyService::CreateFixed("https://myproxy:70");
8989 BoundTestNetLog log;
8990 session_deps_.net_log = log.bound().net_log();
8991
8992 // Enable cross-origin push.
inlinechan894515af2016-12-09 02:40:108993 session_deps_.proxy_delegate = std::move(proxy_delegate);
tbansal8ef1d3e2016-02-03 04:05:428994
danakj1fd259a02016-04-16 03:17:098995 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
tbansal8ef1d3e2016-02-03 04:05:428996
bncdf80d44fd2016-07-15 20:27:418997 SpdySerializedFrame stream1_syn(
bncb26024382016-06-29 02:39:458998 spdy_util_.ConstructSpdyGet("http://www.example.org/", 1, LOWEST));
tombergan5d22c182017-01-11 02:05:358999 SpdySerializedFrame stream2_priority(
9000 spdy_util_.ConstructSpdyPriority(2, 1, IDLE, true));
tbansal8ef1d3e2016-02-03 04:05:429001
9002 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:419003 CreateMockWrite(stream1_syn, 0, ASYNC),
tombergan5d22c182017-01-11 02:05:359004 CreateMockWrite(stream2_priority, 3, ASYNC),
tbansal8ef1d3e2016-02-03 04:05:429005 };
9006
bncdf80d44fd2016-07-15 20:27:419007 SpdySerializedFrame stream1_reply(
bnc42331402016-07-25 13:36:159008 spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
tbansal8ef1d3e2016-02-03 04:05:429009
bncdf80d44fd2016-07-15 20:27:419010 SpdySerializedFrame stream2_syn(spdy_util_.ConstructSpdyPush(
Bence Béky096cf052017-08-08 23:55:339011 nullptr, 0, 2, 1, "http://www.example.org/foo.dat"));
bnc38dcd392016-02-09 23:19:499012
bncdf80d44fd2016-07-15 20:27:419013 SpdySerializedFrame stream1_body(spdy_util_.ConstructSpdyDataFrame(1, true));
tbansal8ef1d3e2016-02-03 04:05:429014
bncdf80d44fd2016-07-15 20:27:419015 SpdySerializedFrame stream2_reply(
bnc42331402016-07-25 13:36:159016 spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
tbansal8ef1d3e2016-02-03 04:05:429017
bncdf80d44fd2016-07-15 20:27:419018 SpdySerializedFrame stream2_body(spdy_util_.ConstructSpdyDataFrame(1, true));
tbansal8ef1d3e2016-02-03 04:05:429019
9020 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:419021 CreateMockRead(stream1_reply, 1, ASYNC),
9022 CreateMockRead(stream2_syn, 2, ASYNC),
tombergan5d22c182017-01-11 02:05:359023 CreateMockRead(stream1_body, 4, ASYNC),
9024 CreateMockRead(stream2_body, 5, ASYNC),
9025 MockRead(SYNCHRONOUS, ERR_IO_PENDING, 6), // Force a hang
tbansal8ef1d3e2016-02-03 04:05:429026 };
9027
9028 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
9029 arraysize(spdy_writes));
9030 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
9031 // Negotiate SPDY to the proxy
9032 SSLSocketDataProvider proxy(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:369033 proxy.next_proto = kProtoHTTP2;
tbansal8ef1d3e2016-02-03 04:05:429034 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy);
9035
bnc87dcefc2017-05-25 12:47:589036 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:199037 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
tbansal8ef1d3e2016-02-03 04:05:429038 TestCompletionCallback callback;
9039 int rv = trans->Start(&request, callback.callback(), log.bound());
robpercival214763f2016-07-01 23:27:019040 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
tbansal8ef1d3e2016-02-03 04:05:429041
9042 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:019043 EXPECT_THAT(rv, IsOk());
tbansal8ef1d3e2016-02-03 04:05:429044 const HttpResponseInfo* response = trans->GetResponseInfo();
9045
wezca1070932016-05-26 20:30:529046 ASSERT_TRUE(response);
tbansal8ef1d3e2016-02-03 04:05:429047 EXPECT_TRUE(response->headers->IsKeepAlive());
9048
9049 EXPECT_EQ(200, response->headers->response_code());
9050 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
9051
9052 std::string response_data;
9053 rv = ReadTransaction(trans.get(), &response_data);
robpercival214763f2016-07-01 23:27:019054 EXPECT_THAT(rv, IsOk());
tbansal8ef1d3e2016-02-03 04:05:429055 EXPECT_EQ("hello!", response_data);
9056
9057 trans.reset();
9058 session->CloseAllConnections();
9059}
9060
[email protected]2df19bb2010-08-25 20:13:469061// Test HTTPS connections to a site with a bad certificate, going through an
9062// HTTPS proxy
bncd16676a2016-07-20 16:23:019063TEST_F(HttpNetworkTransactionTest, HTTPSBadCertificateViaHttpsProxy) {
rdsmith82957ad2015-09-16 19:42:039064 session_deps_.proxy_service = ProxyService::CreateFixed("https://proxy:70");
[email protected]2df19bb2010-08-25 20:13:469065
9066 HttpRequestInfo request;
9067 request.method = "GET";
bncce36dca22015-04-21 22:11:239068 request.url = GURL("https://www.example.org/");
[email protected]2df19bb2010-08-25 20:13:469069
9070 // Attempt to fetch the URL from a server with a bad cert
9071 MockWrite bad_cert_writes[] = {
rsleevidb16bb02015-11-12 23:47:179072 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
9073 "Host: www.example.org:443\r\n"
9074 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]2df19bb2010-08-25 20:13:469075 };
9076
9077 MockRead bad_cert_reads[] = {
9078 MockRead("HTTP/1.0 200 Connected\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:069079 MockRead(SYNCHRONOUS, OK)
[email protected]2df19bb2010-08-25 20:13:469080 };
9081
9082 // Attempt to fetch the URL with a good cert
9083 MockWrite good_data_writes[] = {
rsleevidb16bb02015-11-12 23:47:179084 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
9085 "Host: www.example.org:443\r\n"
9086 "Proxy-Connection: keep-alive\r\n\r\n"),
9087 MockWrite("GET / HTTP/1.1\r\n"
9088 "Host: www.example.org\r\n"
9089 "Connection: keep-alive\r\n\r\n"),
[email protected]2df19bb2010-08-25 20:13:469090 };
9091
9092 MockRead good_cert_reads[] = {
9093 MockRead("HTTP/1.0 200 Connected\r\n\r\n"),
9094 MockRead("HTTP/1.0 200 OK\r\n"),
9095 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
9096 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:069097 MockRead(SYNCHRONOUS, OK),
[email protected]2df19bb2010-08-25 20:13:469098 };
9099
9100 StaticSocketDataProvider ssl_bad_certificate(
9101 bad_cert_reads, arraysize(bad_cert_reads),
9102 bad_cert_writes, arraysize(bad_cert_writes));
9103 StaticSocketDataProvider data(good_cert_reads, arraysize(good_cert_reads),
9104 good_data_writes, arraysize(good_data_writes));
[email protected]8ddf8322012-02-23 18:08:069105 SSLSocketDataProvider ssl_bad(ASYNC, ERR_CERT_AUTHORITY_INVALID);
9106 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]2df19bb2010-08-25 20:13:469107
9108 // SSL to the proxy, then CONNECT request, then SSL with bad certificate
[email protected]bb88e1d32013-05-03 23:11:079109 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
9110 session_deps_.socket_factory->AddSocketDataProvider(&ssl_bad_certificate);
9111 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_bad);
[email protected]2df19bb2010-08-25 20:13:469112
9113 // SSL to the proxy, then CONNECT request, then valid SSL certificate
[email protected]bb88e1d32013-05-03 23:11:079114 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
9115 session_deps_.socket_factory->AddSocketDataProvider(&data);
9116 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]2df19bb2010-08-25 20:13:469117
[email protected]49639fa2011-12-20 23:22:419118 TestCompletionCallback callback;
[email protected]2df19bb2010-08-25 20:13:469119
danakj1fd259a02016-04-16 03:17:099120 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:169121 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]2df19bb2010-08-25 20:13:469122
tfarina42834112016-09-22 13:38:209123 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:019124 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2df19bb2010-08-25 20:13:469125
9126 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:019127 EXPECT_THAT(rv, IsError(ERR_CERT_AUTHORITY_INVALID));
[email protected]2df19bb2010-08-25 20:13:469128
bnc691fda62016-08-12 00:43:169129 rv = trans.RestartIgnoringLastError(callback.callback());
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, IsOk());
[email protected]2df19bb2010-08-25 20:13:469134
bnc691fda62016-08-12 00:43:169135 const HttpResponseInfo* response = trans.GetResponseInfo();
[email protected]2df19bb2010-08-25 20:13:469136
wezca1070932016-05-26 20:30:529137 ASSERT_TRUE(response);
[email protected]2df19bb2010-08-25 20:13:469138 EXPECT_EQ(100, response->headers->GetContentLength());
9139}
9140
bncd16676a2016-07-20 16:23:019141TEST_F(HttpNetworkTransactionTest, BuildRequest_UserAgent) {
[email protected]1c773ea12009-04-28 19:58:429142 HttpRequestInfo request;
9143 request.method = "GET";
bncce36dca22015-04-21 22:11:239144 request.url = GURL("http://www.example.org/");
[email protected]8c76ae22010-04-20 22:15:439145 request.extra_headers.SetHeader(HttpRequestHeaders::kUserAgent,
9146 "Chromium Ultra Awesome X Edition");
[email protected]1c773ea12009-04-28 19:58:429147
danakj1fd259a02016-04-16 03:17:099148 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:169149 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:279150
[email protected]1c773ea12009-04-28 19:58:429151 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:239152 MockWrite(
9153 "GET / HTTP/1.1\r\n"
9154 "Host: www.example.org\r\n"
9155 "Connection: keep-alive\r\n"
9156 "User-Agent: Chromium Ultra Awesome X Edition\r\n\r\n"),
[email protected]1c773ea12009-04-28 19:58:429157 };
9158
9159 // Lastly, the server responds with the actual content.
9160 MockRead data_reads[] = {
9161 MockRead("HTTP/1.0 200 OK\r\n"),
9162 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
9163 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:069164 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:429165 };
9166
[email protected]31a2bfe2010-02-09 08:03:399167 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
9168 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:079169 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:429170
[email protected]49639fa2011-12-20 23:22:419171 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:429172
tfarina42834112016-09-22 13:38:209173 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:019174 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]1c773ea12009-04-28 19:58:429175
9176 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:019177 EXPECT_THAT(rv, IsOk());
[email protected]1c773ea12009-04-28 19:58:429178}
9179
bncd16676a2016-07-20 16:23:019180TEST_F(HttpNetworkTransactionTest, BuildRequest_UserAgentOverTunnel) {
[email protected]da81f132010-08-18 23:39:299181 HttpRequestInfo request;
9182 request.method = "GET";
bncce36dca22015-04-21 22:11:239183 request.url = GURL("https://www.example.org/");
[email protected]da81f132010-08-18 23:39:299184 request.extra_headers.SetHeader(HttpRequestHeaders::kUserAgent,
9185 "Chromium Ultra Awesome X Edition");
9186
rdsmith82957ad2015-09-16 19:42:039187 session_deps_.proxy_service = ProxyService::CreateFixed("myproxy:70");
danakj1fd259a02016-04-16 03:17:099188 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:169189 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:279190
[email protected]da81f132010-08-18 23:39:299191 MockWrite data_writes[] = {
rsleevidb16bb02015-11-12 23:47:179192 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
9193 "Host: www.example.org:443\r\n"
9194 "Proxy-Connection: keep-alive\r\n"
9195 "User-Agent: Chromium Ultra Awesome X Edition\r\n\r\n"),
[email protected]da81f132010-08-18 23:39:299196 };
9197 MockRead data_reads[] = {
9198 // Return an error, so the transaction stops here (this test isn't
9199 // interested in the rest).
9200 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
9201 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
9202 MockRead("Proxy-Connection: close\r\n\r\n"),
9203 };
9204
9205 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
9206 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:079207 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]da81f132010-08-18 23:39:299208
[email protected]49639fa2011-12-20 23:22:419209 TestCompletionCallback callback;
[email protected]da81f132010-08-18 23:39:299210
tfarina42834112016-09-22 13:38:209211 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:019212 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]da81f132010-08-18 23:39:299213
9214 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:019215 EXPECT_THAT(rv, IsOk());
[email protected]da81f132010-08-18 23:39:299216}
9217
bncd16676a2016-07-20 16:23:019218TEST_F(HttpNetworkTransactionTest, BuildRequest_Referer) {
[email protected]1c773ea12009-04-28 19:58:429219 HttpRequestInfo request;
9220 request.method = "GET";
bncce36dca22015-04-21 22:11:239221 request.url = GURL("http://www.example.org/");
[email protected]c10450102011-06-27 09:06:169222 request.extra_headers.SetHeader(HttpRequestHeaders::kReferer,
9223 "http://the.previous.site.com/");
[email protected]1c773ea12009-04-28 19:58:429224
danakj1fd259a02016-04-16 03:17:099225 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:169226 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:279227
[email protected]1c773ea12009-04-28 19:58:429228 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:239229 MockWrite(
9230 "GET / HTTP/1.1\r\n"
9231 "Host: www.example.org\r\n"
9232 "Connection: keep-alive\r\n"
9233 "Referer: http://the.previous.site.com/\r\n\r\n"),
[email protected]1c773ea12009-04-28 19:58:429234 };
9235
9236 // Lastly, the server responds with the actual content.
9237 MockRead data_reads[] = {
9238 MockRead("HTTP/1.0 200 OK\r\n"),
9239 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
9240 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:069241 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:429242 };
9243
[email protected]31a2bfe2010-02-09 08:03:399244 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
9245 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:079246 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:429247
[email protected]49639fa2011-12-20 23:22:419248 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:429249
tfarina42834112016-09-22 13:38:209250 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:019251 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]1c773ea12009-04-28 19:58:429252
9253 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:019254 EXPECT_THAT(rv, IsOk());
[email protected]1c773ea12009-04-28 19:58:429255}
9256
bncd16676a2016-07-20 16:23:019257TEST_F(HttpNetworkTransactionTest, BuildRequest_PostContentLengthZero) {
[email protected]1c773ea12009-04-28 19:58:429258 HttpRequestInfo request;
9259 request.method = "POST";
bncce36dca22015-04-21 22:11:239260 request.url = GURL("http://www.example.org/");
[email protected]1c773ea12009-04-28 19:58:429261
danakj1fd259a02016-04-16 03:17:099262 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:169263 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:279264
[email protected]1c773ea12009-04-28 19:58:429265 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:239266 MockWrite(
9267 "POST / HTTP/1.1\r\n"
9268 "Host: www.example.org\r\n"
9269 "Connection: keep-alive\r\n"
9270 "Content-Length: 0\r\n\r\n"),
[email protected]1c773ea12009-04-28 19:58:429271 };
9272
9273 // Lastly, the server responds with the actual content.
9274 MockRead data_reads[] = {
9275 MockRead("HTTP/1.0 200 OK\r\n"),
9276 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
9277 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:069278 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:429279 };
9280
[email protected]31a2bfe2010-02-09 08:03:399281 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
9282 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:079283 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:429284
[email protected]49639fa2011-12-20 23:22:419285 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:429286
tfarina42834112016-09-22 13:38:209287 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:019288 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]1c773ea12009-04-28 19:58:429289
9290 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:019291 EXPECT_THAT(rv, IsOk());
[email protected]1c773ea12009-04-28 19:58:429292}
9293
bncd16676a2016-07-20 16:23:019294TEST_F(HttpNetworkTransactionTest, BuildRequest_PutContentLengthZero) {
[email protected]1c773ea12009-04-28 19:58:429295 HttpRequestInfo request;
9296 request.method = "PUT";
bncce36dca22015-04-21 22:11:239297 request.url = GURL("http://www.example.org/");
[email protected]1c773ea12009-04-28 19:58:429298
danakj1fd259a02016-04-16 03:17:099299 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:169300 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:279301
[email protected]1c773ea12009-04-28 19:58:429302 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:239303 MockWrite(
9304 "PUT / HTTP/1.1\r\n"
9305 "Host: www.example.org\r\n"
9306 "Connection: keep-alive\r\n"
9307 "Content-Length: 0\r\n\r\n"),
[email protected]1c773ea12009-04-28 19:58:429308 };
9309
9310 // Lastly, the server responds with the actual content.
9311 MockRead data_reads[] = {
9312 MockRead("HTTP/1.0 200 OK\r\n"),
9313 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
9314 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:069315 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:429316 };
9317
[email protected]31a2bfe2010-02-09 08:03:399318 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
9319 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:079320 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:429321
[email protected]49639fa2011-12-20 23:22:419322 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:429323
tfarina42834112016-09-22 13:38:209324 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:019325 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]1c773ea12009-04-28 19:58:429326
9327 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:019328 EXPECT_THAT(rv, IsOk());
[email protected]1c773ea12009-04-28 19:58:429329}
9330
bncd16676a2016-07-20 16:23:019331TEST_F(HttpNetworkTransactionTest, BuildRequest_HeadContentLengthZero) {
[email protected]1c773ea12009-04-28 19:58:429332 HttpRequestInfo request;
9333 request.method = "HEAD";
bncce36dca22015-04-21 22:11:239334 request.url = GURL("http://www.example.org/");
[email protected]1c773ea12009-04-28 19:58:429335
danakj1fd259a02016-04-16 03:17:099336 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:169337 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:279338
[email protected]1c773ea12009-04-28 19:58:429339 MockWrite data_writes[] = {
csharrisonf473dd192015-08-18 13:54:139340 MockWrite("HEAD / HTTP/1.1\r\n"
9341 "Host: www.example.org\r\n"
9342 "Connection: keep-alive\r\n\r\n"),
[email protected]1c773ea12009-04-28 19:58:429343 };
9344
9345 // Lastly, the server responds with the actual content.
9346 MockRead data_reads[] = {
9347 MockRead("HTTP/1.0 200 OK\r\n"),
9348 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
9349 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:069350 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:429351 };
9352
[email protected]31a2bfe2010-02-09 08:03:399353 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
9354 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:079355 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:429356
[email protected]49639fa2011-12-20 23:22:419357 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:429358
tfarina42834112016-09-22 13:38:209359 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:019360 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]1c773ea12009-04-28 19:58:429361
9362 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:019363 EXPECT_THAT(rv, IsOk());
[email protected]1c773ea12009-04-28 19:58:429364}
9365
bncd16676a2016-07-20 16:23:019366TEST_F(HttpNetworkTransactionTest, BuildRequest_CacheControlNoCache) {
[email protected]1c773ea12009-04-28 19:58:429367 HttpRequestInfo request;
9368 request.method = "GET";
bncce36dca22015-04-21 22:11:239369 request.url = GURL("http://www.example.org/");
[email protected]1c773ea12009-04-28 19:58:429370 request.load_flags = LOAD_BYPASS_CACHE;
9371
danakj1fd259a02016-04-16 03:17:099372 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:169373 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:279374
[email protected]1c773ea12009-04-28 19:58:429375 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:239376 MockWrite(
9377 "GET / HTTP/1.1\r\n"
9378 "Host: www.example.org\r\n"
9379 "Connection: keep-alive\r\n"
9380 "Pragma: no-cache\r\n"
9381 "Cache-Control: no-cache\r\n\r\n"),
[email protected]1c773ea12009-04-28 19:58:429382 };
9383
9384 // Lastly, the server responds with the actual content.
9385 MockRead data_reads[] = {
9386 MockRead("HTTP/1.0 200 OK\r\n"),
9387 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
9388 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:069389 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:429390 };
9391
[email protected]31a2bfe2010-02-09 08:03:399392 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
9393 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:079394 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:429395
[email protected]49639fa2011-12-20 23:22:419396 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:429397
tfarina42834112016-09-22 13:38:209398 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:019399 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]1c773ea12009-04-28 19:58:429400
9401 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:019402 EXPECT_THAT(rv, IsOk());
[email protected]1c773ea12009-04-28 19:58:429403}
9404
bncd16676a2016-07-20 16:23:019405TEST_F(HttpNetworkTransactionTest, BuildRequest_CacheControlValidateCache) {
[email protected]1c773ea12009-04-28 19:58:429406 HttpRequestInfo request;
9407 request.method = "GET";
bncce36dca22015-04-21 22:11:239408 request.url = GURL("http://www.example.org/");
[email protected]1c773ea12009-04-28 19:58:429409 request.load_flags = LOAD_VALIDATE_CACHE;
9410
danakj1fd259a02016-04-16 03:17:099411 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:169412 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:279413
[email protected]1c773ea12009-04-28 19:58:429414 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:239415 MockWrite(
9416 "GET / HTTP/1.1\r\n"
9417 "Host: www.example.org\r\n"
9418 "Connection: keep-alive\r\n"
9419 "Cache-Control: max-age=0\r\n\r\n"),
[email protected]1c773ea12009-04-28 19:58:429420 };
9421
9422 // Lastly, the server responds with the actual content.
9423 MockRead data_reads[] = {
9424 MockRead("HTTP/1.0 200 OK\r\n"),
9425 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
9426 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:069427 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:429428 };
9429
[email protected]31a2bfe2010-02-09 08:03:399430 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
9431 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:079432 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:429433
[email protected]49639fa2011-12-20 23:22:419434 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:429435
tfarina42834112016-09-22 13:38:209436 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:019437 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]1c773ea12009-04-28 19:58:429438
9439 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:019440 EXPECT_THAT(rv, IsOk());
[email protected]1c773ea12009-04-28 19:58:429441}
9442
bncd16676a2016-07-20 16:23:019443TEST_F(HttpNetworkTransactionTest, BuildRequest_ExtraHeaders) {
[email protected]1c773ea12009-04-28 19:58:429444 HttpRequestInfo request;
9445 request.method = "GET";
bncce36dca22015-04-21 22:11:239446 request.url = GURL("http://www.example.org/");
[email protected]8c76ae22010-04-20 22:15:439447 request.extra_headers.SetHeader("FooHeader", "Bar");
[email protected]1c773ea12009-04-28 19:58:429448
danakj1fd259a02016-04-16 03:17:099449 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:169450 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:279451
[email protected]1c773ea12009-04-28 19:58:429452 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:239453 MockWrite(
9454 "GET / HTTP/1.1\r\n"
9455 "Host: www.example.org\r\n"
9456 "Connection: keep-alive\r\n"
9457 "FooHeader: Bar\r\n\r\n"),
[email protected]1c773ea12009-04-28 19:58:429458 };
9459
9460 // Lastly, the server responds with the actual content.
9461 MockRead data_reads[] = {
9462 MockRead("HTTP/1.0 200 OK\r\n"),
9463 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
9464 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:069465 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:429466 };
9467
[email protected]31a2bfe2010-02-09 08:03:399468 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
9469 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:079470 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:429471
[email protected]49639fa2011-12-20 23:22:419472 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:429473
tfarina42834112016-09-22 13:38:209474 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:019475 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]1c773ea12009-04-28 19:58:429476
9477 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:019478 EXPECT_THAT(rv, IsOk());
[email protected]1c773ea12009-04-28 19:58:429479}
9480
bncd16676a2016-07-20 16:23:019481TEST_F(HttpNetworkTransactionTest, BuildRequest_ExtraHeadersStripped) {
[email protected]270c6412010-03-29 22:02:479482 HttpRequestInfo request;
9483 request.method = "GET";
bncce36dca22015-04-21 22:11:239484 request.url = GURL("http://www.example.org/");
[email protected]8c76ae22010-04-20 22:15:439485 request.extra_headers.SetHeader("referer", "www.foo.com");
9486 request.extra_headers.SetHeader("hEllo", "Kitty");
9487 request.extra_headers.SetHeader("FoO", "bar");
[email protected]270c6412010-03-29 22:02:479488
danakj1fd259a02016-04-16 03:17:099489 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:169490 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:279491
[email protected]270c6412010-03-29 22:02:479492 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:239493 MockWrite(
9494 "GET / HTTP/1.1\r\n"
9495 "Host: www.example.org\r\n"
9496 "Connection: keep-alive\r\n"
9497 "referer: www.foo.com\r\n"
9498 "hEllo: Kitty\r\n"
9499 "FoO: bar\r\n\r\n"),
[email protected]270c6412010-03-29 22:02:479500 };
9501
9502 // Lastly, the server responds with the actual content.
9503 MockRead data_reads[] = {
9504 MockRead("HTTP/1.0 200 OK\r\n"),
9505 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
9506 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:069507 MockRead(SYNCHRONOUS, OK),
[email protected]270c6412010-03-29 22:02:479508 };
9509
9510 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
9511 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:079512 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]270c6412010-03-29 22:02:479513
[email protected]49639fa2011-12-20 23:22:419514 TestCompletionCallback callback;
[email protected]270c6412010-03-29 22:02:479515
tfarina42834112016-09-22 13:38:209516 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:019517 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]270c6412010-03-29 22:02:479518
9519 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:019520 EXPECT_THAT(rv, IsOk());
[email protected]270c6412010-03-29 22:02:479521}
9522
bncd16676a2016-07-20 16:23:019523TEST_F(HttpNetworkTransactionTest, SOCKS4_HTTP_GET) {
[email protected]cb9bf6ca2011-01-28 13:15:279524 HttpRequestInfo request;
9525 request.method = "GET";
bncce36dca22015-04-21 22:11:239526 request.url = GURL("http://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:279527
rdsmith82957ad2015-09-16 19:42:039528 session_deps_.proxy_service =
9529 ProxyService::CreateFixedFromPacResult("SOCKS myproxy:1080");
vishal.b62985ca92015-04-17 08:45:519530 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:079531 session_deps_.net_log = &net_log;
[email protected]3cd17242009-06-23 02:59:029532
danakj1fd259a02016-04-16 03:17:099533 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:169534 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]3cd17242009-06-23 02:59:029535
[email protected]3cd17242009-06-23 02:59:029536 char write_buffer[] = { 0x04, 0x01, 0x00, 0x50, 127, 0, 0, 1, 0 };
9537 char read_buffer[] = { 0x00, 0x5A, 0x00, 0x00, 0, 0, 0, 0 };
9538
9539 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:239540 MockWrite(ASYNC, write_buffer, arraysize(write_buffer)),
9541 MockWrite(
9542 "GET / HTTP/1.1\r\n"
9543 "Host: www.example.org\r\n"
9544 "Connection: keep-alive\r\n\r\n")};
[email protected]3cd17242009-06-23 02:59:029545
9546 MockRead data_reads[] = {
[email protected]8ddf8322012-02-23 18:08:069547 MockRead(ASYNC, read_buffer, arraysize(read_buffer)),
[email protected]3cd17242009-06-23 02:59:029548 MockRead("HTTP/1.0 200 OK\r\n"),
9549 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n\r\n"),
9550 MockRead("Payload"),
[email protected]8ddf8322012-02-23 18:08:069551 MockRead(SYNCHRONOUS, OK)
[email protected]3cd17242009-06-23 02:59:029552 };
9553
[email protected]31a2bfe2010-02-09 08:03:399554 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
9555 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:079556 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]3cd17242009-06-23 02:59:029557
[email protected]49639fa2011-12-20 23:22:419558 TestCompletionCallback callback;
[email protected]3cd17242009-06-23 02:59:029559
tfarina42834112016-09-22 13:38:209560 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:019561 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]3cd17242009-06-23 02:59:029562
9563 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:019564 EXPECT_THAT(rv, IsOk());
[email protected]3cd17242009-06-23 02:59:029565
bnc691fda62016-08-12 00:43:169566 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:529567 ASSERT_TRUE(response);
[email protected]3cd17242009-06-23 02:59:029568
tbansal2ecbbc72016-10-06 17:15:479569 EXPECT_EQ(ProxyServer::SCHEME_SOCKS4, response->proxy_server.scheme());
[email protected]029c83b62013-01-24 05:28:209570 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:169571 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]029c83b62013-01-24 05:28:209572 TestLoadTimingNotReusedWithPac(load_timing_info,
9573 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
9574
[email protected]3cd17242009-06-23 02:59:029575 std::string response_text;
bnc691fda62016-08-12 00:43:169576 rv = ReadTransaction(&trans, &response_text);
robpercival214763f2016-07-01 23:27:019577 EXPECT_THAT(rv, IsOk());
[email protected]3cd17242009-06-23 02:59:029578 EXPECT_EQ("Payload", response_text);
9579}
9580
bncd16676a2016-07-20 16:23:019581TEST_F(HttpNetworkTransactionTest, SOCKS4_SSL_GET) {
[email protected]cb9bf6ca2011-01-28 13:15:279582 HttpRequestInfo request;
9583 request.method = "GET";
bncce36dca22015-04-21 22:11:239584 request.url = GURL("https://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:279585
rdsmith82957ad2015-09-16 19:42:039586 session_deps_.proxy_service =
9587 ProxyService::CreateFixedFromPacResult("SOCKS myproxy:1080");
vishal.b62985ca92015-04-17 08:45:519588 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:079589 session_deps_.net_log = &net_log;
[email protected]3cd17242009-06-23 02:59:029590
danakj1fd259a02016-04-16 03:17:099591 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:169592 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]3cd17242009-06-23 02:59:029593
[email protected]3cd17242009-06-23 02:59:029594 unsigned char write_buffer[] = { 0x04, 0x01, 0x01, 0xBB, 127, 0, 0, 1, 0 };
9595 unsigned char read_buffer[] = { 0x00, 0x5A, 0x00, 0x00, 0, 0, 0, 0 };
9596
9597 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:239598 MockWrite(ASYNC, reinterpret_cast<char*>(write_buffer),
9599 arraysize(write_buffer)),
9600 MockWrite(
9601 "GET / HTTP/1.1\r\n"
9602 "Host: www.example.org\r\n"
9603 "Connection: keep-alive\r\n\r\n")};
[email protected]3cd17242009-06-23 02:59:029604
9605 MockRead data_reads[] = {
[email protected]f871ee152012-07-27 19:02:019606 MockRead(ASYNC, reinterpret_cast<char*>(read_buffer),
9607 arraysize(read_buffer)),
[email protected]e0c27be2009-07-15 13:09:359608 MockRead("HTTP/1.0 200 OK\r\n"),
9609 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n\r\n"),
9610 MockRead("Payload"),
[email protected]8ddf8322012-02-23 18:08:069611 MockRead(SYNCHRONOUS, OK)
[email protected]e0c27be2009-07-15 13:09:359612 };
9613
[email protected]31a2bfe2010-02-09 08:03:399614 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
9615 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:079616 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]e0c27be2009-07-15 13:09:359617
[email protected]8ddf8322012-02-23 18:08:069618 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:079619 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]e0c27be2009-07-15 13:09:359620
[email protected]49639fa2011-12-20 23:22:419621 TestCompletionCallback callback;
[email protected]e0c27be2009-07-15 13:09:359622
tfarina42834112016-09-22 13:38:209623 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:019624 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]e0c27be2009-07-15 13:09:359625
9626 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:019627 EXPECT_THAT(rv, IsOk());
[email protected]e0c27be2009-07-15 13:09:359628
[email protected]029c83b62013-01-24 05:28:209629 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:169630 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]029c83b62013-01-24 05:28:209631 TestLoadTimingNotReusedWithPac(load_timing_info,
9632 CONNECT_TIMING_HAS_SSL_TIMES);
9633
bnc691fda62016-08-12 00:43:169634 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:529635 ASSERT_TRUE(response);
tbansal2ecbbc72016-10-06 17:15:479636 EXPECT_EQ(ProxyServer::SCHEME_SOCKS4, response->proxy_server.scheme());
[email protected]e0c27be2009-07-15 13:09:359637
9638 std::string response_text;
bnc691fda62016-08-12 00:43:169639 rv = ReadTransaction(&trans, &response_text);
robpercival214763f2016-07-01 23:27:019640 EXPECT_THAT(rv, IsOk());
[email protected]e0c27be2009-07-15 13:09:359641 EXPECT_EQ("Payload", response_text);
9642}
9643
bncd16676a2016-07-20 16:23:019644TEST_F(HttpNetworkTransactionTest, SOCKS4_HTTP_GET_no_PAC) {
[email protected]029c83b62013-01-24 05:28:209645 HttpRequestInfo request;
9646 request.method = "GET";
bncce36dca22015-04-21 22:11:239647 request.url = GURL("http://www.example.org/");
[email protected]029c83b62013-01-24 05:28:209648
rdsmith82957ad2015-09-16 19:42:039649 session_deps_.proxy_service =
9650 ProxyService::CreateFixed("socks4://myproxy:1080");
vishal.b62985ca92015-04-17 08:45:519651 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:079652 session_deps_.net_log = &net_log;
[email protected]029c83b62013-01-24 05:28:209653
danakj1fd259a02016-04-16 03:17:099654 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:169655 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]029c83b62013-01-24 05:28:209656
9657 char write_buffer[] = { 0x04, 0x01, 0x00, 0x50, 127, 0, 0, 1, 0 };
9658 char read_buffer[] = { 0x00, 0x5A, 0x00, 0x00, 0, 0, 0, 0 };
9659
9660 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:239661 MockWrite(ASYNC, write_buffer, arraysize(write_buffer)),
9662 MockWrite(
9663 "GET / HTTP/1.1\r\n"
9664 "Host: www.example.org\r\n"
9665 "Connection: keep-alive\r\n\r\n")};
[email protected]029c83b62013-01-24 05:28:209666
9667 MockRead data_reads[] = {
9668 MockRead(ASYNC, read_buffer, arraysize(read_buffer)),
9669 MockRead("HTTP/1.0 200 OK\r\n"),
9670 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n\r\n"),
9671 MockRead("Payload"),
9672 MockRead(SYNCHRONOUS, OK)
9673 };
9674
9675 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
9676 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:079677 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]029c83b62013-01-24 05:28:209678
9679 TestCompletionCallback callback;
9680
tfarina42834112016-09-22 13:38:209681 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:019682 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]029c83b62013-01-24 05:28:209683
9684 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:019685 EXPECT_THAT(rv, IsOk());
[email protected]029c83b62013-01-24 05:28:209686
bnc691fda62016-08-12 00:43:169687 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:529688 ASSERT_TRUE(response);
[email protected]029c83b62013-01-24 05:28:209689
9690 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:169691 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]029c83b62013-01-24 05:28:209692 TestLoadTimingNotReused(load_timing_info,
9693 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
9694
9695 std::string response_text;
bnc691fda62016-08-12 00:43:169696 rv = ReadTransaction(&trans, &response_text);
robpercival214763f2016-07-01 23:27:019697 EXPECT_THAT(rv, IsOk());
[email protected]029c83b62013-01-24 05:28:209698 EXPECT_EQ("Payload", response_text);
9699}
9700
bncd16676a2016-07-20 16:23:019701TEST_F(HttpNetworkTransactionTest, SOCKS5_HTTP_GET) {
[email protected]cb9bf6ca2011-01-28 13:15:279702 HttpRequestInfo request;
9703 request.method = "GET";
bncce36dca22015-04-21 22:11:239704 request.url = GURL("http://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:279705
rdsmith82957ad2015-09-16 19:42:039706 session_deps_.proxy_service =
9707 ProxyService::CreateFixedFromPacResult("SOCKS5 myproxy:1080");
vishal.b62985ca92015-04-17 08:45:519708 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:079709 session_deps_.net_log = &net_log;
[email protected]e0c27be2009-07-15 13:09:359710
danakj1fd259a02016-04-16 03:17:099711 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:169712 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]e0c27be2009-07-15 13:09:359713
[email protected]e0c27be2009-07-15 13:09:359714 const char kSOCKS5GreetRequest[] = { 0x05, 0x01, 0x00 };
9715 const char kSOCKS5GreetResponse[] = { 0x05, 0x00 };
[email protected]f209dba2009-12-18 00:24:379716 const char kSOCKS5OkRequest[] = {
bncce36dca22015-04-21 22:11:239717 0x05, // Version
9718 0x01, // Command (CONNECT)
9719 0x00, // Reserved.
9720 0x03, // Address type (DOMAINNAME).
9721 0x0F, // Length of domain (15)
9722 'w', 'w', 'w', '.', 'e', 'x', 'a', 'm', 'p', 'l', 'e', // Domain string
9723 '.', 'o', 'r', 'g', 0x00, 0x50, // 16-bit port (80)
[email protected]f209dba2009-12-18 00:24:379724 };
[email protected]e0c27be2009-07-15 13:09:359725 const char kSOCKS5OkResponse[] =
9726 { 0x05, 0x00, 0x00, 0x01, 127, 0, 0, 1, 0x00, 0x50 };
9727
9728 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:239729 MockWrite(ASYNC, kSOCKS5GreetRequest, arraysize(kSOCKS5GreetRequest)),
9730 MockWrite(ASYNC, kSOCKS5OkRequest, arraysize(kSOCKS5OkRequest)),
9731 MockWrite(
9732 "GET / HTTP/1.1\r\n"
9733 "Host: www.example.org\r\n"
9734 "Connection: keep-alive\r\n\r\n")};
[email protected]e0c27be2009-07-15 13:09:359735
9736 MockRead data_reads[] = {
[email protected]f871ee152012-07-27 19:02:019737 MockRead(ASYNC, kSOCKS5GreetResponse, arraysize(kSOCKS5GreetResponse)),
9738 MockRead(ASYNC, kSOCKS5OkResponse, arraysize(kSOCKS5OkResponse)),
[email protected]e0c27be2009-07-15 13:09:359739 MockRead("HTTP/1.0 200 OK\r\n"),
9740 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n\r\n"),
9741 MockRead("Payload"),
[email protected]8ddf8322012-02-23 18:08:069742 MockRead(SYNCHRONOUS, OK)
[email protected]e0c27be2009-07-15 13:09:359743 };
9744
[email protected]31a2bfe2010-02-09 08:03:399745 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
9746 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:079747 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]e0c27be2009-07-15 13:09:359748
[email protected]49639fa2011-12-20 23:22:419749 TestCompletionCallback callback;
[email protected]e0c27be2009-07-15 13:09:359750
tfarina42834112016-09-22 13:38:209751 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:019752 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]e0c27be2009-07-15 13:09:359753
9754 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:019755 EXPECT_THAT(rv, IsOk());
[email protected]e0c27be2009-07-15 13:09:359756
bnc691fda62016-08-12 00:43:169757 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:529758 ASSERT_TRUE(response);
tbansal2ecbbc72016-10-06 17:15:479759 EXPECT_EQ(ProxyServer::SCHEME_SOCKS5, response->proxy_server.scheme());
[email protected]e0c27be2009-07-15 13:09:359760
[email protected]029c83b62013-01-24 05:28:209761 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:169762 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]029c83b62013-01-24 05:28:209763 TestLoadTimingNotReusedWithPac(load_timing_info,
9764 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
9765
[email protected]e0c27be2009-07-15 13:09:359766 std::string response_text;
bnc691fda62016-08-12 00:43:169767 rv = ReadTransaction(&trans, &response_text);
robpercival214763f2016-07-01 23:27:019768 EXPECT_THAT(rv, IsOk());
[email protected]e0c27be2009-07-15 13:09:359769 EXPECT_EQ("Payload", response_text);
9770}
9771
bncd16676a2016-07-20 16:23:019772TEST_F(HttpNetworkTransactionTest, SOCKS5_SSL_GET) {
[email protected]cb9bf6ca2011-01-28 13:15:279773 HttpRequestInfo request;
9774 request.method = "GET";
bncce36dca22015-04-21 22:11:239775 request.url = GURL("https://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:279776
rdsmith82957ad2015-09-16 19:42:039777 session_deps_.proxy_service =
9778 ProxyService::CreateFixedFromPacResult("SOCKS5 myproxy:1080");
vishal.b62985ca92015-04-17 08:45:519779 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:079780 session_deps_.net_log = &net_log;
[email protected]e0c27be2009-07-15 13:09:359781
danakj1fd259a02016-04-16 03:17:099782 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:169783 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]e0c27be2009-07-15 13:09:359784
[email protected]e0c27be2009-07-15 13:09:359785 const char kSOCKS5GreetRequest[] = { 0x05, 0x01, 0x00 };
9786 const char kSOCKS5GreetResponse[] = { 0x05, 0x00 };
[email protected]f209dba2009-12-18 00:24:379787 const unsigned char kSOCKS5OkRequest[] = {
bncce36dca22015-04-21 22:11:239788 0x05, // Version
9789 0x01, // Command (CONNECT)
9790 0x00, // Reserved.
9791 0x03, // Address type (DOMAINNAME).
9792 0x0F, // Length of domain (15)
9793 'w', 'w', 'w', '.', 'e', 'x', 'a', 'm', 'p', 'l', 'e', // Domain string
9794 '.', 'o', 'r', 'g', 0x01, 0xBB, // 16-bit port (443)
[email protected]f209dba2009-12-18 00:24:379795 };
9796
[email protected]e0c27be2009-07-15 13:09:359797 const char kSOCKS5OkResponse[] =
9798 { 0x05, 0x00, 0x00, 0x01, 0, 0, 0, 0, 0x00, 0x00 };
9799
9800 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:239801 MockWrite(ASYNC, kSOCKS5GreetRequest, arraysize(kSOCKS5GreetRequest)),
9802 MockWrite(ASYNC, reinterpret_cast<const char*>(kSOCKS5OkRequest),
9803 arraysize(kSOCKS5OkRequest)),
9804 MockWrite(
9805 "GET / HTTP/1.1\r\n"
9806 "Host: www.example.org\r\n"
9807 "Connection: keep-alive\r\n\r\n")};
[email protected]e0c27be2009-07-15 13:09:359808
9809 MockRead data_reads[] = {
[email protected]f871ee152012-07-27 19:02:019810 MockRead(ASYNC, kSOCKS5GreetResponse, arraysize(kSOCKS5GreetResponse)),
9811 MockRead(ASYNC, kSOCKS5OkResponse, arraysize(kSOCKS5OkResponse)),
[email protected]3cd17242009-06-23 02:59:029812 MockRead("HTTP/1.0 200 OK\r\n"),
9813 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n\r\n"),
9814 MockRead("Payload"),
[email protected]8ddf8322012-02-23 18:08:069815 MockRead(SYNCHRONOUS, OK)
[email protected]3cd17242009-06-23 02:59:029816 };
9817
[email protected]31a2bfe2010-02-09 08:03:399818 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
9819 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:079820 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]3cd17242009-06-23 02:59:029821
[email protected]8ddf8322012-02-23 18:08:069822 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:079823 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]3cd17242009-06-23 02:59:029824
[email protected]49639fa2011-12-20 23:22:419825 TestCompletionCallback callback;
[email protected]3cd17242009-06-23 02:59:029826
tfarina42834112016-09-22 13:38:209827 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:019828 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]3cd17242009-06-23 02:59:029829
9830 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:019831 EXPECT_THAT(rv, IsOk());
[email protected]3cd17242009-06-23 02:59:029832
bnc691fda62016-08-12 00:43:169833 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:529834 ASSERT_TRUE(response);
tbansal2ecbbc72016-10-06 17:15:479835 EXPECT_EQ(ProxyServer::SCHEME_SOCKS5, response->proxy_server.scheme());
[email protected]3cd17242009-06-23 02:59:029836
[email protected]029c83b62013-01-24 05:28:209837 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:169838 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]029c83b62013-01-24 05:28:209839 TestLoadTimingNotReusedWithPac(load_timing_info,
9840 CONNECT_TIMING_HAS_SSL_TIMES);
9841
[email protected]3cd17242009-06-23 02:59:029842 std::string response_text;
bnc691fda62016-08-12 00:43:169843 rv = ReadTransaction(&trans, &response_text);
robpercival214763f2016-07-01 23:27:019844 EXPECT_THAT(rv, IsOk());
[email protected]3cd17242009-06-23 02:59:029845 EXPECT_EQ("Payload", response_text);
9846}
9847
[email protected]448d4ca52012-03-04 04:12:239848namespace {
9849
[email protected]04e5be32009-06-26 20:00:319850// Tests that for connection endpoints the group names are correctly set.
[email protected]2d731a32010-04-29 01:04:069851
9852struct GroupNameTest {
9853 std::string proxy_server;
9854 std::string url;
9855 std::string expected_group_name;
[email protected]e60e47a2010-07-14 03:37:189856 bool ssl;
[email protected]2d731a32010-04-29 01:04:069857};
9858
danakj1fd259a02016-04-16 03:17:099859std::unique_ptr<HttpNetworkSession> SetupSessionForGroupNameTests(
[email protected]bb88e1d32013-05-03 23:11:079860 SpdySessionDependencies* session_deps_) {
danakj1fd259a02016-04-16 03:17:099861 std::unique_ptr<HttpNetworkSession> session(CreateSession(session_deps_));
[email protected]2d731a32010-04-29 01:04:069862
bnc525e175a2016-06-20 12:36:409863 HttpServerProperties* http_server_properties =
[email protected]17291a022011-10-10 07:32:539864 session->http_server_properties();
bnc3472afd2016-11-17 15:27:219865 AlternativeService alternative_service(kProtoHTTP2, "", 444);
bnc7dc7e1b42015-07-28 14:43:129866 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:219867 http_server_properties->SetHttp2AlternativeService(
bncaa60ff402016-06-22 19:12:429868 url::SchemeHostPort("https", "host.with.alternate", 443),
zhongyi3d4a55e72016-04-22 20:36:469869 alternative_service, expiration);
[email protected]2d731a32010-04-29 01:04:069870
9871 return session;
9872}
9873
mmenkee65e7af2015-10-13 17:16:429874int GroupNameTransactionHelper(const std::string& url,
9875 HttpNetworkSession* session) {
[email protected]2d731a32010-04-29 01:04:069876 HttpRequestInfo request;
9877 request.method = "GET";
9878 request.url = GURL(url);
[email protected]2d731a32010-04-29 01:04:069879
bnc691fda62016-08-12 00:43:169880 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session);
[email protected]cb9bf6ca2011-01-28 13:15:279881
[email protected]49639fa2011-12-20 23:22:419882 TestCompletionCallback callback;
[email protected]2d731a32010-04-29 01:04:069883
9884 // We do not complete this request, the dtor will clean the transaction up.
tfarina42834112016-09-22 13:38:209885 return trans.Start(&request, callback.callback(), NetLogWithSource());
[email protected]2d731a32010-04-29 01:04:069886}
9887
[email protected]448d4ca52012-03-04 04:12:239888} // namespace
9889
bncd16676a2016-07-20 16:23:019890TEST_F(HttpNetworkTransactionTest, GroupNameForDirectConnections) {
[email protected]2d731a32010-04-29 01:04:069891 const GroupNameTest tests[] = {
bncce36dca22015-04-21 22:11:239892 {
9893 "", // unused
9894 "http://www.example.org/direct",
9895 "www.example.org:80",
9896 false,
9897 },
9898 {
9899 "", // unused
9900 "http://[2001:1418:13:1::25]/direct",
9901 "[2001:1418:13:1::25]:80",
9902 false,
9903 },
[email protected]04e5be32009-06-26 20:00:319904
bncce36dca22015-04-21 22:11:239905 // SSL Tests
9906 {
9907 "", // unused
9908 "https://www.example.org/direct_ssl",
9909 "ssl/www.example.org:443",
9910 true,
9911 },
9912 {
9913 "", // unused
9914 "https://[2001:1418:13:1::25]/direct",
9915 "ssl/[2001:1418:13:1::25]:443",
9916 true,
9917 },
9918 {
9919 "", // unused
bncaa60ff402016-06-22 19:12:429920 "https://host.with.alternate/direct",
bncce36dca22015-04-21 22:11:239921 "ssl/host.with.alternate:443",
9922 true,
9923 },
[email protected]2d731a32010-04-29 01:04:069924 };
[email protected]2ff8b312010-04-26 22:20:549925
viettrungluue4a8b882014-10-16 06:17:389926 for (size_t i = 0; i < arraysize(tests); ++i) {
rdsmith82957ad2015-09-16 19:42:039927 session_deps_.proxy_service =
9928 ProxyService::CreateFixed(tests[i].proxy_server);
danakj1fd259a02016-04-16 03:17:099929 std::unique_ptr<HttpNetworkSession> session(
bnca9b9e222016-07-11 20:10:409930 SetupSessionForGroupNameTests(&session_deps_));
[email protected]2d731a32010-04-29 01:04:069931
mmenkee65e7af2015-10-13 17:16:429932 HttpNetworkSessionPeer peer(session.get());
[email protected]ab739042011-04-07 15:22:289933 CaptureGroupNameTransportSocketPool* transport_conn_pool =
bnc87dcefc2017-05-25 12:47:589934 new CaptureGroupNameTransportSocketPool(nullptr, nullptr);
[email protected]2431756e2010-09-29 20:26:139935 CaptureGroupNameSSLSocketPool* ssl_conn_pool =
bnc87dcefc2017-05-25 12:47:589936 new CaptureGroupNameSSLSocketPool(nullptr, nullptr);
Jeremy Roman0579ed62017-08-29 15:56:199937 auto mock_pool_manager = std::make_unique<MockClientSocketPoolManager>();
[email protected]a42dbd142011-11-17 16:42:029938 mock_pool_manager->SetTransportSocketPool(transport_conn_pool);
9939 mock_pool_manager->SetSSLSocketPool(ssl_conn_pool);
dchengc7eeda422015-12-26 03:56:489940 peer.SetClientSocketPoolManager(std::move(mock_pool_manager));
[email protected]2d731a32010-04-29 01:04:069941
9942 EXPECT_EQ(ERR_IO_PENDING,
mmenkee65e7af2015-10-13 17:16:429943 GroupNameTransactionHelper(tests[i].url, session.get()));
[email protected]e60e47a2010-07-14 03:37:189944 if (tests[i].ssl)
9945 EXPECT_EQ(tests[i].expected_group_name,
9946 ssl_conn_pool->last_group_name_received());
9947 else
9948 EXPECT_EQ(tests[i].expected_group_name,
[email protected]ab739042011-04-07 15:22:289949 transport_conn_pool->last_group_name_received());
[email protected]2d731a32010-04-29 01:04:069950 }
[email protected]2d731a32010-04-29 01:04:069951}
9952
bncd16676a2016-07-20 16:23:019953TEST_F(HttpNetworkTransactionTest, GroupNameForHTTPProxyConnections) {
[email protected]2d731a32010-04-29 01:04:069954 const GroupNameTest tests[] = {
bncce36dca22015-04-21 22:11:239955 {
Matt Menked1eb6d42018-01-17 04:54:069956 "http_proxy", "http://www.example.org/http_proxy_normal",
9957 "http_proxy/www.example.org:80", false,
bncce36dca22015-04-21 22:11:239958 },
[email protected]2d731a32010-04-29 01:04:069959
bncce36dca22015-04-21 22:11:239960 // SSL Tests
9961 {
Matt Menked1eb6d42018-01-17 04:54:069962 "http_proxy", "https://www.example.org/http_connect_ssl",
9963 "http_proxy/ssl/www.example.org:443", true,
bncce36dca22015-04-21 22:11:239964 },
[email protected]af3490e2010-10-16 21:02:299965
bncce36dca22015-04-21 22:11:239966 {
Matt Menked1eb6d42018-01-17 04:54:069967 "http_proxy", "https://host.with.alternate/direct",
9968 "http_proxy/ssl/host.with.alternate:443", true,
bncce36dca22015-04-21 22:11:239969 },
[email protected]45499252013-01-23 17:12:569970
bncce36dca22015-04-21 22:11:239971 {
Matt Menked1eb6d42018-01-17 04:54:069972 "http_proxy", "ftp://ftp.google.com/http_proxy_normal",
9973 "http_proxy/ftp/ftp.google.com:21", false,
bncce36dca22015-04-21 22:11:239974 },
[email protected]2d731a32010-04-29 01:04:069975 };
9976
viettrungluue4a8b882014-10-16 06:17:389977 for (size_t i = 0; i < arraysize(tests); ++i) {
rdsmith82957ad2015-09-16 19:42:039978 session_deps_.proxy_service =
9979 ProxyService::CreateFixed(tests[i].proxy_server);
danakj1fd259a02016-04-16 03:17:099980 std::unique_ptr<HttpNetworkSession> session(
bnca9b9e222016-07-11 20:10:409981 SetupSessionForGroupNameTests(&session_deps_));
[email protected]2d731a32010-04-29 01:04:069982
mmenkee65e7af2015-10-13 17:16:429983 HttpNetworkSessionPeer peer(session.get());
[email protected]2d731a32010-04-29 01:04:069984
[email protected]e60e47a2010-07-14 03:37:189985 HostPortPair proxy_host("http_proxy", 80);
[email protected]2431756e2010-09-29 20:26:139986 CaptureGroupNameHttpProxySocketPool* http_proxy_pool =
[email protected]9e1bdd32011-02-03 21:48:349987 new CaptureGroupNameHttpProxySocketPool(NULL, NULL);
[email protected]2431756e2010-09-29 20:26:139988 CaptureGroupNameSSLSocketPool* ssl_conn_pool =
[email protected]9e1bdd32011-02-03 21:48:349989 new CaptureGroupNameSSLSocketPool(NULL, NULL);
Jeremy Roman0579ed62017-08-29 15:56:199990 auto mock_pool_manager = std::make_unique<MockClientSocketPoolManager>();
aviadef3442016-10-03 18:50:399991 mock_pool_manager->SetSocketPoolForHTTPProxy(
9992 proxy_host, base::WrapUnique(http_proxy_pool));
9993 mock_pool_manager->SetSocketPoolForSSLWithProxy(
9994 proxy_host, base::WrapUnique(ssl_conn_pool));
dchengc7eeda422015-12-26 03:56:489995 peer.SetClientSocketPoolManager(std::move(mock_pool_manager));
[email protected]2d731a32010-04-29 01:04:069996
9997 EXPECT_EQ(ERR_IO_PENDING,
mmenkee65e7af2015-10-13 17:16:429998 GroupNameTransactionHelper(tests[i].url, session.get()));
[email protected]e60e47a2010-07-14 03:37:189999 if (tests[i].ssl)
10000 EXPECT_EQ(tests[i].expected_group_name,
10001 ssl_conn_pool->last_group_name_received());
10002 else
10003 EXPECT_EQ(tests[i].expected_group_name,
10004 http_proxy_pool->last_group_name_received());
[email protected]2d731a32010-04-29 01:04:0610005 }
[email protected]2d731a32010-04-29 01:04:0610006}
10007
bncd16676a2016-07-20 16:23:0110008TEST_F(HttpNetworkTransactionTest, GroupNameForSOCKSConnections) {
[email protected]2d731a32010-04-29 01:04:0610009 const GroupNameTest tests[] = {
bncce36dca22015-04-21 22:11:2310010 {
10011 "socks4://socks_proxy:1080",
10012 "http://www.example.org/socks4_direct",
10013 "socks4/www.example.org:80",
10014 false,
10015 },
10016 {
10017 "socks5://socks_proxy:1080",
10018 "http://www.example.org/socks5_direct",
10019 "socks5/www.example.org:80",
10020 false,
10021 },
[email protected]2d731a32010-04-29 01:04:0610022
bncce36dca22015-04-21 22:11:2310023 // SSL Tests
10024 {
10025 "socks4://socks_proxy:1080",
10026 "https://www.example.org/socks4_ssl",
10027 "socks4/ssl/www.example.org:443",
10028 true,
10029 },
10030 {
10031 "socks5://socks_proxy:1080",
10032 "https://www.example.org/socks5_ssl",
10033 "socks5/ssl/www.example.org:443",
10034 true,
10035 },
[email protected]af3490e2010-10-16 21:02:2910036
bncce36dca22015-04-21 22:11:2310037 {
10038 "socks4://socks_proxy:1080",
bncaa60ff402016-06-22 19:12:4210039 "https://host.with.alternate/direct",
bncce36dca22015-04-21 22:11:2310040 "socks4/ssl/host.with.alternate:443",
10041 true,
10042 },
[email protected]04e5be32009-06-26 20:00:3110043 };
10044
viettrungluue4a8b882014-10-16 06:17:3810045 for (size_t i = 0; i < arraysize(tests); ++i) {
rdsmith82957ad2015-09-16 19:42:0310046 session_deps_.proxy_service =
10047 ProxyService::CreateFixed(tests[i].proxy_server);
danakj1fd259a02016-04-16 03:17:0910048 std::unique_ptr<HttpNetworkSession> session(
bnca9b9e222016-07-11 20:10:4010049 SetupSessionForGroupNameTests(&session_deps_));
[email protected]8b114dd72011-03-25 05:33:0210050
mmenkee65e7af2015-10-13 17:16:4210051 HttpNetworkSessionPeer peer(session.get());
[email protected]04e5be32009-06-26 20:00:3110052
[email protected]e60e47a2010-07-14 03:37:1810053 HostPortPair proxy_host("socks_proxy", 1080);
[email protected]2431756e2010-09-29 20:26:1310054 CaptureGroupNameSOCKSSocketPool* socks_conn_pool =
[email protected]9e1bdd32011-02-03 21:48:3410055 new CaptureGroupNameSOCKSSocketPool(NULL, NULL);
[email protected]2431756e2010-09-29 20:26:1310056 CaptureGroupNameSSLSocketPool* ssl_conn_pool =
[email protected]9e1bdd32011-02-03 21:48:3410057 new CaptureGroupNameSSLSocketPool(NULL, NULL);
Jeremy Roman0579ed62017-08-29 15:56:1910058 auto mock_pool_manager = std::make_unique<MockClientSocketPoolManager>();
aviadef3442016-10-03 18:50:3910059 mock_pool_manager->SetSocketPoolForSOCKSProxy(
10060 proxy_host, base::WrapUnique(socks_conn_pool));
10061 mock_pool_manager->SetSocketPoolForSSLWithProxy(
10062 proxy_host, base::WrapUnique(ssl_conn_pool));
dchengc7eeda422015-12-26 03:56:4810063 peer.SetClientSocketPoolManager(std::move(mock_pool_manager));
[email protected]04e5be32009-06-26 20:00:3110064
bnc691fda62016-08-12 00:43:1610065 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]04e5be32009-06-26 20:00:3110066
[email protected]2d731a32010-04-29 01:04:0610067 EXPECT_EQ(ERR_IO_PENDING,
mmenkee65e7af2015-10-13 17:16:4210068 GroupNameTransactionHelper(tests[i].url, session.get()));
[email protected]e60e47a2010-07-14 03:37:1810069 if (tests[i].ssl)
10070 EXPECT_EQ(tests[i].expected_group_name,
10071 ssl_conn_pool->last_group_name_received());
10072 else
10073 EXPECT_EQ(tests[i].expected_group_name,
10074 socks_conn_pool->last_group_name_received());
[email protected]04e5be32009-06-26 20:00:3110075 }
10076}
10077
bncd16676a2016-07-20 16:23:0110078TEST_F(HttpNetworkTransactionTest, ReconsiderProxyAfterFailedConnection) {
[email protected]cb9bf6ca2011-01-28 13:15:2710079 HttpRequestInfo request;
10080 request.method = "GET";
bncce36dca22015-04-21 22:11:2310081 request.url = GURL("http://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:2710082
rdsmith82957ad2015-09-16 19:42:0310083 session_deps_.proxy_service =
10084 ProxyService::CreateFixed("myproxy:70;foobar:80");
[email protected]b59ff372009-07-15 22:04:3210085
[email protected]69719062010-01-05 20:09:2110086 // This simulates failure resolving all hostnames; that means we will fail
10087 // connecting to both proxies (myproxy:70 and foobar:80).
[email protected]bb88e1d32013-05-03 23:11:0710088 session_deps_.host_resolver->rules()->AddSimulatedFailure("*");
[email protected]b59ff372009-07-15 22:04:3210089
danakj1fd259a02016-04-16 03:17:0910090 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1610091 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]9172a982009-06-06 00:30:2510092
[email protected]49639fa2011-12-20 23:22:4110093 TestCompletionCallback callback;
[email protected]9172a982009-06-06 00:30:2510094
tfarina42834112016-09-22 13:38:2010095 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110096 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]9172a982009-06-06 00:30:2510097
[email protected]9172a982009-06-06 00:30:2510098 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0110099 EXPECT_THAT(rv, IsError(ERR_PROXY_CONNECTION_FAILED));
[email protected]9172a982009-06-06 00:30:2510100}
10101
[email protected]685af592010-05-11 19:31:2410102// Base test to make sure that when the load flags for a request specify to
10103// bypass the cache, the DNS cache is not used.
[email protected]23e482282013-06-14 16:08:0210104void HttpNetworkTransactionTest::BypassHostCacheOnRefreshHelper(
[email protected]bb88e1d32013-05-03 23:11:0710105 int load_flags) {
[email protected]cb9bf6ca2011-01-28 13:15:2710106 // Issue a request, asking to bypass the cache(s).
maksim.sisov31452af2016-07-27 06:38:1010107 HttpRequestInfo request_info;
10108 request_info.method = "GET";
10109 request_info.load_flags = load_flags;
10110 request_info.url = GURL("http://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:2710111
[email protected]a2c2fb92009-07-18 07:31:0410112 // Select a host resolver that does caching.
Jeremy Roman0579ed62017-08-29 15:56:1910113 session_deps_.host_resolver = std::make_unique<MockCachingHostResolver>();
[email protected]b59ff372009-07-15 22:04:3210114
danakj1fd259a02016-04-16 03:17:0910115 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1610116 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]3b9cca42009-06-16 01:08:2810117
bncce36dca22015-04-21 22:11:2310118 // Warm up the host cache so it has an entry for "www.example.org".
[email protected]3b9cca42009-06-16 01:08:2810119 AddressList addrlist;
[email protected]aa22b242011-11-16 18:58:2910120 TestCompletionCallback callback;
maksim.sisov31452af2016-07-27 06:38:1010121 std::unique_ptr<HostResolver::Request> request1;
[email protected]bb88e1d32013-05-03 23:11:0710122 int rv = session_deps_.host_resolver->Resolve(
bncce36dca22015-04-21 22:11:2310123 HostResolver::RequestInfo(HostPortPair("www.example.org", 80)),
maksim.sisov31452af2016-07-27 06:38:1010124 DEFAULT_PRIORITY, &addrlist, callback.callback(), &request1,
tfarina42834112016-09-22 13:38:2010125 NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110126 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]6e78dfb2011-07-28 21:34:4710127 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0110128 EXPECT_THAT(rv, IsOk());
[email protected]3b9cca42009-06-16 01:08:2810129
10130 // Verify that it was added to host cache, by doing a subsequent async lookup
10131 // and confirming it completes synchronously.
maksim.sisov31452af2016-07-27 06:38:1010132 std::unique_ptr<HostResolver::Request> request2;
[email protected]bb88e1d32013-05-03 23:11:0710133 rv = session_deps_.host_resolver->Resolve(
bncce36dca22015-04-21 22:11:2310134 HostResolver::RequestInfo(HostPortPair("www.example.org", 80)),
maksim.sisov31452af2016-07-27 06:38:1010135 DEFAULT_PRIORITY, &addrlist, callback.callback(), &request2,
tfarina42834112016-09-22 13:38:2010136 NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110137 ASSERT_THAT(rv, IsOk());
[email protected]3b9cca42009-06-16 01:08:2810138
bncce36dca22015-04-21 22:11:2310139 // Inject a failure the next time that "www.example.org" is resolved. This way
[email protected]3b9cca42009-06-16 01:08:2810140 // we can tell if the next lookup hit the cache, or the "network".
10141 // (cache --> success, "network" --> failure).
bncce36dca22015-04-21 22:11:2310142 session_deps_.host_resolver->rules()->AddSimulatedFailure("www.example.org");
[email protected]3b9cca42009-06-16 01:08:2810143
10144 // Connect up a mock socket which will fail with ERR_UNEXPECTED during the
10145 // first read -- this won't be reached as the host resolution will fail first.
[email protected]8ddf8322012-02-23 18:08:0610146 MockRead data_reads[] = { MockRead(SYNCHRONOUS, ERR_UNEXPECTED) };
[email protected]31a2bfe2010-02-09 08:03:3910147 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0710148 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]3b9cca42009-06-16 01:08:2810149
[email protected]3b9cca42009-06-16 01:08:2810150 // Run the request.
tfarina42834112016-09-22 13:38:2010151 rv = trans.Start(&request_info, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110152 ASSERT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]49639fa2011-12-20 23:22:4110153 rv = callback.WaitForResult();
[email protected]3b9cca42009-06-16 01:08:2810154
10155 // If we bypassed the cache, we would have gotten a failure while resolving
bncce36dca22015-04-21 22:11:2310156 // "www.example.org".
robpercival214763f2016-07-01 23:27:0110157 EXPECT_THAT(rv, IsError(ERR_NAME_NOT_RESOLVED));
[email protected]3b9cca42009-06-16 01:08:2810158}
10159
[email protected]685af592010-05-11 19:31:2410160// There are multiple load flags that should trigger the host cache bypass.
10161// Test each in isolation:
bncd16676a2016-07-20 16:23:0110162TEST_F(HttpNetworkTransactionTest, BypassHostCacheOnRefresh1) {
[email protected]685af592010-05-11 19:31:2410163 BypassHostCacheOnRefreshHelper(LOAD_BYPASS_CACHE);
10164}
10165
bncd16676a2016-07-20 16:23:0110166TEST_F(HttpNetworkTransactionTest, BypassHostCacheOnRefresh2) {
[email protected]685af592010-05-11 19:31:2410167 BypassHostCacheOnRefreshHelper(LOAD_VALIDATE_CACHE);
10168}
10169
bncd16676a2016-07-20 16:23:0110170TEST_F(HttpNetworkTransactionTest, BypassHostCacheOnRefresh3) {
[email protected]685af592010-05-11 19:31:2410171 BypassHostCacheOnRefreshHelper(LOAD_DISABLE_CACHE);
10172}
10173
[email protected]0877e3d2009-10-17 22:29:5710174// Make sure we can handle an error when writing the request.
bncd16676a2016-07-20 16:23:0110175TEST_F(HttpNetworkTransactionTest, RequestWriteError) {
[email protected]0877e3d2009-10-17 22:29:5710176 HttpRequestInfo request;
10177 request.method = "GET";
10178 request.url = GURL("http://www.foo.com/");
[email protected]0877e3d2009-10-17 22:29:5710179
10180 MockWrite write_failure[] = {
[email protected]8ddf8322012-02-23 18:08:0610181 MockWrite(ASYNC, ERR_CONNECTION_RESET),
[email protected]0877e3d2009-10-17 22:29:5710182 };
[email protected]31a2bfe2010-02-09 08:03:3910183 StaticSocketDataProvider data(NULL, 0,
10184 write_failure, arraysize(write_failure));
[email protected]bb88e1d32013-05-03 23:11:0710185 session_deps_.socket_factory->AddSocketDataProvider(&data);
danakj1fd259a02016-04-16 03:17:0910186 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]0877e3d2009-10-17 22:29:5710187
[email protected]49639fa2011-12-20 23:22:4110188 TestCompletionCallback callback;
[email protected]0877e3d2009-10-17 22:29:5710189
bnc691fda62016-08-12 00:43:1610190 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]0877e3d2009-10-17 22:29:5710191
tfarina42834112016-09-22 13:38:2010192 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110193 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]0877e3d2009-10-17 22:29:5710194
10195 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0110196 EXPECT_THAT(rv, IsError(ERR_CONNECTION_RESET));
ttuttled9dbc652015-09-29 20:00:5910197
10198 IPEndPoint endpoint;
bnc691fda62016-08-12 00:43:1610199 EXPECT_TRUE(trans.GetRemoteEndpoint(&endpoint));
ttuttled9dbc652015-09-29 20:00:5910200 EXPECT_LT(0u, endpoint.address().size());
[email protected]0877e3d2009-10-17 22:29:5710201}
10202
zmo9528c9f42015-08-04 22:12:0810203// Check that a connection closed after the start of the headers finishes ok.
bncd16676a2016-07-20 16:23:0110204TEST_F(HttpNetworkTransactionTest, ConnectionClosedAfterStartOfHeaders) {
[email protected]0877e3d2009-10-17 22:29:5710205 HttpRequestInfo request;
10206 request.method = "GET";
10207 request.url = GURL("http://www.foo.com/");
[email protected]0877e3d2009-10-17 22:29:5710208
10209 MockRead data_reads[] = {
10210 MockRead("HTTP/1."),
[email protected]8ddf8322012-02-23 18:08:0610211 MockRead(SYNCHRONOUS, OK),
[email protected]0877e3d2009-10-17 22:29:5710212 };
10213
[email protected]31a2bfe2010-02-09 08:03:3910214 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0710215 session_deps_.socket_factory->AddSocketDataProvider(&data);
danakj1fd259a02016-04-16 03:17:0910216 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]0877e3d2009-10-17 22:29:5710217
[email protected]49639fa2011-12-20 23:22:4110218 TestCompletionCallback callback;
[email protected]0877e3d2009-10-17 22:29:5710219
bnc691fda62016-08-12 00:43:1610220 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]0877e3d2009-10-17 22:29:5710221
tfarina42834112016-09-22 13:38:2010222 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110223 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]0877e3d2009-10-17 22:29:5710224
10225 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0110226 EXPECT_THAT(rv, IsOk());
zmo9528c9f42015-08-04 22:12:0810227
bnc691fda62016-08-12 00:43:1610228 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5210229 ASSERT_TRUE(response);
zmo9528c9f42015-08-04 22:12:0810230
wezca1070932016-05-26 20:30:5210231 EXPECT_TRUE(response->headers);
zmo9528c9f42015-08-04 22:12:0810232 EXPECT_EQ("HTTP/1.0 200 OK", response->headers->GetStatusLine());
10233
10234 std::string response_data;
bnc691fda62016-08-12 00:43:1610235 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:0110236 EXPECT_THAT(rv, IsOk());
zmo9528c9f42015-08-04 22:12:0810237 EXPECT_EQ("", response_data);
ttuttled9dbc652015-09-29 20:00:5910238
10239 IPEndPoint endpoint;
bnc691fda62016-08-12 00:43:1610240 EXPECT_TRUE(trans.GetRemoteEndpoint(&endpoint));
ttuttled9dbc652015-09-29 20:00:5910241 EXPECT_LT(0u, endpoint.address().size());
[email protected]0877e3d2009-10-17 22:29:5710242}
10243
10244// Make sure that a dropped connection while draining the body for auth
10245// restart does the right thing.
bncd16676a2016-07-20 16:23:0110246TEST_F(HttpNetworkTransactionTest, DrainResetOK) {
[email protected]0877e3d2009-10-17 22:29:5710247 HttpRequestInfo request;
10248 request.method = "GET";
bncce36dca22015-04-21 22:11:2310249 request.url = GURL("http://www.example.org/");
[email protected]0877e3d2009-10-17 22:29:5710250
10251 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:2310252 MockWrite(
10253 "GET / HTTP/1.1\r\n"
10254 "Host: www.example.org\r\n"
10255 "Connection: keep-alive\r\n\r\n"),
[email protected]0877e3d2009-10-17 22:29:5710256 };
10257
10258 MockRead data_reads1[] = {
10259 MockRead("HTTP/1.1 401 Unauthorized\r\n"),
10260 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
10261 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
10262 MockRead("Content-Length: 14\r\n\r\n"),
10263 MockRead("Unauth"),
[email protected]8ddf8322012-02-23 18:08:0610264 MockRead(ASYNC, ERR_CONNECTION_RESET),
[email protected]0877e3d2009-10-17 22:29:5710265 };
10266
[email protected]31a2bfe2010-02-09 08:03:3910267 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
10268 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:0710269 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]0877e3d2009-10-17 22:29:5710270
bnc691fda62016-08-12 00:43:1610271 // After calling trans.RestartWithAuth(), this is the request we should
[email protected]0877e3d2009-10-17 22:29:5710272 // be issuing -- the final header line contains the credentials.
10273 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:2310274 MockWrite(
10275 "GET / HTTP/1.1\r\n"
10276 "Host: www.example.org\r\n"
10277 "Connection: keep-alive\r\n"
10278 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]0877e3d2009-10-17 22:29:5710279 };
10280
10281 // Lastly, the server responds with the actual content.
10282 MockRead data_reads2[] = {
10283 MockRead("HTTP/1.1 200 OK\r\n"),
10284 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
10285 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:0610286 MockRead(SYNCHRONOUS, OK),
[email protected]0877e3d2009-10-17 22:29:5710287 };
10288
[email protected]31a2bfe2010-02-09 08:03:3910289 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
10290 data_writes2, arraysize(data_writes2));
[email protected]bb88e1d32013-05-03 23:11:0710291 session_deps_.socket_factory->AddSocketDataProvider(&data2);
danakj1fd259a02016-04-16 03:17:0910292 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]0877e3d2009-10-17 22:29:5710293
[email protected]49639fa2011-12-20 23:22:4110294 TestCompletionCallback callback1;
[email protected]0877e3d2009-10-17 22:29:5710295
bnc691fda62016-08-12 00:43:1610296 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]0b0bf032010-09-21 18:08:5010297
tfarina42834112016-09-22 13:38:2010298 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110299 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]0877e3d2009-10-17 22:29:5710300
10301 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:0110302 EXPECT_THAT(rv, IsOk());
[email protected]0877e3d2009-10-17 22:29:5710303
bnc691fda62016-08-12 00:43:1610304 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5210305 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:0410306 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]0877e3d2009-10-17 22:29:5710307
[email protected]49639fa2011-12-20 23:22:4110308 TestCompletionCallback callback2;
[email protected]0877e3d2009-10-17 22:29:5710309
bnc691fda62016-08-12 00:43:1610310 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar), callback2.callback());
robpercival214763f2016-07-01 23:27:0110311 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]0877e3d2009-10-17 22:29:5710312
10313 rv = callback2.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 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5210317 ASSERT_TRUE(response);
10318 EXPECT_FALSE(response->auth_challenge);
[email protected]0877e3d2009-10-17 22:29:5710319 EXPECT_EQ(100, response->headers->GetContentLength());
10320}
10321
10322// Test HTTPS connections going through a proxy that sends extra data.
bncd16676a2016-07-20 16:23:0110323TEST_F(HttpNetworkTransactionTest, HTTPSViaProxyWithExtraData) {
rdsmith82957ad2015-09-16 19:42:0310324 session_deps_.proxy_service = ProxyService::CreateFixed("myproxy:70");
[email protected]0877e3d2009-10-17 22:29:5710325
10326 HttpRequestInfo request;
10327 request.method = "GET";
bncce36dca22015-04-21 22:11:2310328 request.url = GURL("https://www.example.org/");
[email protected]0877e3d2009-10-17 22:29:5710329
10330 MockRead proxy_reads[] = {
10331 MockRead("HTTP/1.0 200 Connected\r\n\r\nExtra data"),
[email protected]8ddf8322012-02-23 18:08:0610332 MockRead(SYNCHRONOUS, OK)
[email protected]0877e3d2009-10-17 22:29:5710333 };
10334
[email protected]31a2bfe2010-02-09 08:03:3910335 StaticSocketDataProvider data(proxy_reads, arraysize(proxy_reads), NULL, 0);
[email protected]8ddf8322012-02-23 18:08:0610336 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]0877e3d2009-10-17 22:29:5710337
[email protected]bb88e1d32013-05-03 23:11:0710338 session_deps_.socket_factory->AddSocketDataProvider(&data);
10339 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]0877e3d2009-10-17 22:29:5710340
[email protected]49639fa2011-12-20 23:22:4110341 TestCompletionCallback callback;
[email protected]0877e3d2009-10-17 22:29:5710342
[email protected]bb88e1d32013-05-03 23:11:0710343 session_deps_.socket_factory->ResetNextMockIndexes();
[email protected]0877e3d2009-10-17 22:29:5710344
danakj1fd259a02016-04-16 03:17:0910345 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1610346 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]0877e3d2009-10-17 22:29:5710347
tfarina42834112016-09-22 13:38:2010348 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110349 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]0877e3d2009-10-17 22:29:5710350
10351 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0110352 EXPECT_THAT(rv, IsError(ERR_TUNNEL_CONNECTION_FAILED));
[email protected]0877e3d2009-10-17 22:29:5710353}
10354
bncd16676a2016-07-20 16:23:0110355TEST_F(HttpNetworkTransactionTest, LargeContentLengthThenClose) {
[email protected]9492e4a2010-02-24 00:58:4610356 HttpRequestInfo request;
10357 request.method = "GET";
bncce36dca22015-04-21 22:11:2310358 request.url = GURL("http://www.example.org/");
[email protected]9492e4a2010-02-24 00:58:4610359
danakj1fd259a02016-04-16 03:17:0910360 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1610361 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:2710362
[email protected]e22e1362009-11-23 21:31:1210363 MockRead data_reads[] = {
10364 MockRead("HTTP/1.0 200 OK\r\nContent-Length:6719476739\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:0610365 MockRead(SYNCHRONOUS, OK),
[email protected]e22e1362009-11-23 21:31:1210366 };
[email protected]9492e4a2010-02-24 00:58:4610367
10368 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0710369 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]9492e4a2010-02-24 00:58:4610370
[email protected]49639fa2011-12-20 23:22:4110371 TestCompletionCallback callback;
[email protected]9492e4a2010-02-24 00:58:4610372
tfarina42834112016-09-22 13:38:2010373 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110374 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]9492e4a2010-02-24 00:58:4610375
robpercival214763f2016-07-01 23:27:0110376 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]9492e4a2010-02-24 00:58:4610377
bnc691fda62016-08-12 00:43:1610378 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5210379 ASSERT_TRUE(response);
[email protected]9492e4a2010-02-24 00:58:4610380
wezca1070932016-05-26 20:30:5210381 EXPECT_TRUE(response->headers);
[email protected]9492e4a2010-02-24 00:58:4610382 EXPECT_EQ("HTTP/1.0 200 OK", response->headers->GetStatusLine());
10383
10384 std::string response_data;
bnc691fda62016-08-12 00:43:1610385 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:0110386 EXPECT_THAT(rv, IsError(ERR_CONTENT_LENGTH_MISMATCH));
[email protected]e22e1362009-11-23 21:31:1210387}
10388
bncd16676a2016-07-20 16:23:0110389TEST_F(HttpNetworkTransactionTest, UploadFileSmallerThanLength) {
[email protected]6cdfd7f2013-02-08 20:40:1510390 base::FilePath temp_file_path;
[email protected]03d9afc02013-12-03 17:55:5210391 ASSERT_TRUE(base::CreateTemporaryFile(&temp_file_path));
avibf0746c2015-12-09 19:53:1410392 const uint64_t kFakeSize = 100000; // file is actually blank
[email protected]d98961652012-09-11 20:27:2110393 UploadFileElementReader::ScopedOverridingContentLengthForTests
10394 overriding_content_length(kFakeSize);
[email protected]95d88ffe2010-02-04 21:25:3310395
danakj1fd259a02016-04-16 03:17:0910396 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
Jeremy Roman0579ed62017-08-29 15:56:1910397 element_readers.push_back(std::make_unique<UploadFileElementReader>(
avibf0746c2015-12-09 19:53:1410398 base::ThreadTaskRunnerHandle::Get().get(), temp_file_path, 0,
ricea2deef682016-09-09 08:04:0710399 std::numeric_limits<uint64_t>::max(), base::Time()));
olli.raula6df48b2a2015-11-26 07:40:2210400 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]329b68b2012-11-14 17:54:2710401
10402 HttpRequestInfo request;
10403 request.method = "POST";
bncce36dca22015-04-21 22:11:2310404 request.url = GURL("http://www.example.org/upload");
[email protected]329b68b2012-11-14 17:54:2710405 request.upload_data_stream = &upload_data_stream;
[email protected]329b68b2012-11-14 17:54:2710406
danakj1fd259a02016-04-16 03:17:0910407 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1610408 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]95d88ffe2010-02-04 21:25:3310409
10410 MockRead data_reads[] = {
10411 MockRead("HTTP/1.0 200 OK\r\n\r\n"),
10412 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:0610413 MockRead(SYNCHRONOUS, OK),
[email protected]95d88ffe2010-02-04 21:25:3310414 };
[email protected]31a2bfe2010-02-09 08:03:3910415 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0710416 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]95d88ffe2010-02-04 21:25:3310417
[email protected]49639fa2011-12-20 23:22:4110418 TestCompletionCallback callback;
[email protected]95d88ffe2010-02-04 21:25:3310419
tfarina42834112016-09-22 13:38:2010420 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110421 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]95d88ffe2010-02-04 21:25:3310422
10423 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0110424 EXPECT_THAT(rv, IsError(ERR_UPLOAD_FILE_CHANGED));
[email protected]95d88ffe2010-02-04 21:25:3310425
bnc691fda62016-08-12 00:43:1610426 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5210427 ASSERT_TRUE(response);
[email protected]95d88ffe2010-02-04 21:25:3310428
maksim.sisove869bf52016-06-23 17:11:5210429 EXPECT_FALSE(response->headers);
[email protected]95d88ffe2010-02-04 21:25:3310430
[email protected]dd3aa792013-07-16 19:10:2310431 base::DeleteFile(temp_file_path, false);
[email protected]95d88ffe2010-02-04 21:25:3310432}
10433
bncd16676a2016-07-20 16:23:0110434TEST_F(HttpNetworkTransactionTest, UploadUnreadableFile) {
[email protected]6cdfd7f2013-02-08 20:40:1510435 base::FilePath temp_file;
[email protected]03d9afc02013-12-03 17:55:5210436 ASSERT_TRUE(base::CreateTemporaryFile(&temp_file));
[email protected]6624b4622010-03-29 19:58:3610437 std::string temp_file_content("Unreadable file.");
lazyboy8df84fc2017-04-12 02:12:4810438 ASSERT_EQ(static_cast<int>(temp_file_content.length()),
10439 base::WriteFile(temp_file, temp_file_content.c_str(),
10440 temp_file_content.length()));
[email protected]92be8eb2014-08-07 22:57:1110441 ASSERT_TRUE(base::MakeFileUnreadable(temp_file));
[email protected]6624b4622010-03-29 19:58:3610442
danakj1fd259a02016-04-16 03:17:0910443 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
Jeremy Roman0579ed62017-08-29 15:56:1910444 element_readers.push_back(std::make_unique<UploadFileElementReader>(
avibf0746c2015-12-09 19:53:1410445 base::ThreadTaskRunnerHandle::Get().get(), temp_file, 0,
ricea2deef682016-09-09 08:04:0710446 std::numeric_limits<uint64_t>::max(), base::Time()));
olli.raula6df48b2a2015-11-26 07:40:2210447 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]329b68b2012-11-14 17:54:2710448
10449 HttpRequestInfo request;
10450 request.method = "POST";
bncce36dca22015-04-21 22:11:2310451 request.url = GURL("http://www.example.org/upload");
[email protected]329b68b2012-11-14 17:54:2710452 request.upload_data_stream = &upload_data_stream;
[email protected]329b68b2012-11-14 17:54:2710453
[email protected]999dd8c2013-11-12 06:45:5410454 // If we try to upload an unreadable file, the transaction should fail.
danakj1fd259a02016-04-16 03:17:0910455 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1610456 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]6624b4622010-03-29 19:58:3610457
[email protected]999dd8c2013-11-12 06:45:5410458 StaticSocketDataProvider data(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0710459 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]6624b4622010-03-29 19:58:3610460
[email protected]49639fa2011-12-20 23:22:4110461 TestCompletionCallback callback;
[email protected]6624b4622010-03-29 19:58:3610462
tfarina42834112016-09-22 13:38:2010463 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110464 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]6624b4622010-03-29 19:58:3610465
10466 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0110467 EXPECT_THAT(rv, IsError(ERR_ACCESS_DENIED));
[email protected]6624b4622010-03-29 19:58:3610468
[email protected]dd3aa792013-07-16 19:10:2310469 base::DeleteFile(temp_file, false);
[email protected]6624b4622010-03-29 19:58:3610470}
10471
bncd16676a2016-07-20 16:23:0110472TEST_F(HttpNetworkTransactionTest, CancelDuringInitRequestBody) {
[email protected]02cad5d2013-10-02 08:14:0310473 class FakeUploadElementReader : public UploadElementReader {
10474 public:
Chris Watkins7a41d3552017-12-01 02:13:2710475 FakeUploadElementReader() = default;
10476 ~FakeUploadElementReader() override = default;
[email protected]02cad5d2013-10-02 08:14:0310477
10478 const CompletionCallback& callback() const { return callback_; }
10479
10480 // UploadElementReader overrides:
dchengb03027d2014-10-21 12:00:2010481 int Init(const CompletionCallback& callback) override {
[email protected]02cad5d2013-10-02 08:14:0310482 callback_ = callback;
10483 return ERR_IO_PENDING;
10484 }
avibf0746c2015-12-09 19:53:1410485 uint64_t GetContentLength() const override { return 0; }
10486 uint64_t BytesRemaining() const override { return 0; }
dchengb03027d2014-10-21 12:00:2010487 int Read(IOBuffer* buf,
10488 int buf_length,
10489 const CompletionCallback& callback) override {
[email protected]02cad5d2013-10-02 08:14:0310490 return ERR_FAILED;
10491 }
10492
10493 private:
10494 CompletionCallback callback_;
10495 };
10496
10497 FakeUploadElementReader* fake_reader = new FakeUploadElementReader;
danakj1fd259a02016-04-16 03:17:0910498 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
10499 element_readers.push_back(base::WrapUnique(fake_reader));
olli.raula6df48b2a2015-11-26 07:40:2210500 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]02cad5d2013-10-02 08:14:0310501
10502 HttpRequestInfo request;
10503 request.method = "POST";
bncce36dca22015-04-21 22:11:2310504 request.url = GURL("http://www.example.org/upload");
[email protected]02cad5d2013-10-02 08:14:0310505 request.upload_data_stream = &upload_data_stream;
[email protected]02cad5d2013-10-02 08:14:0310506
danakj1fd259a02016-04-16 03:17:0910507 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc87dcefc2017-05-25 12:47:5810508 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:1910509 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]02cad5d2013-10-02 08:14:0310510
10511 StaticSocketDataProvider data;
10512 session_deps_.socket_factory->AddSocketDataProvider(&data);
10513
10514 TestCompletionCallback callback;
tfarina42834112016-09-22 13:38:2010515 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110516 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
fdoray92e35a72016-06-10 15:54:5510517 base::RunLoop().RunUntilIdle();
[email protected]02cad5d2013-10-02 08:14:0310518
10519 // Transaction is pending on request body initialization.
10520 ASSERT_FALSE(fake_reader->callback().is_null());
10521
10522 // Return Init()'s result after the transaction gets destroyed.
10523 trans.reset();
10524 fake_reader->callback().Run(OK); // Should not crash.
10525}
10526
[email protected]aeefc9e82010-02-19 16:18:2710527// Tests that changes to Auth realms are treated like auth rejections.
bncd16676a2016-07-20 16:23:0110528TEST_F(HttpNetworkTransactionTest, ChangeAuthRealms) {
[email protected]aeefc9e82010-02-19 16:18:2710529 HttpRequestInfo request;
10530 request.method = "GET";
bncce36dca22015-04-21 22:11:2310531 request.url = GURL("http://www.example.org/");
[email protected]aeefc9e82010-02-19 16:18:2710532
10533 // First transaction will request a resource and receive a Basic challenge
10534 // with realm="first_realm".
10535 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:2310536 MockWrite(
10537 "GET / HTTP/1.1\r\n"
10538 "Host: www.example.org\r\n"
10539 "Connection: keep-alive\r\n"
10540 "\r\n"),
[email protected]aeefc9e82010-02-19 16:18:2710541 };
10542 MockRead data_reads1[] = {
10543 MockRead("HTTP/1.1 401 Unauthorized\r\n"
10544 "WWW-Authenticate: Basic realm=\"first_realm\"\r\n"
10545 "\r\n"),
10546 };
10547
bnc691fda62016-08-12 00:43:1610548 // After calling trans.RestartWithAuth(), provide an Authentication header
[email protected]aeefc9e82010-02-19 16:18:2710549 // for first_realm. The server will reject and provide a challenge with
10550 // second_realm.
10551 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:2310552 MockWrite(
10553 "GET / HTTP/1.1\r\n"
10554 "Host: www.example.org\r\n"
10555 "Connection: keep-alive\r\n"
10556 "Authorization: Basic Zmlyc3Q6YmF6\r\n"
10557 "\r\n"),
[email protected]aeefc9e82010-02-19 16:18:2710558 };
10559 MockRead data_reads2[] = {
10560 MockRead("HTTP/1.1 401 Unauthorized\r\n"
10561 "WWW-Authenticate: Basic realm=\"second_realm\"\r\n"
10562 "\r\n"),
10563 };
10564
10565 // This again fails, and goes back to first_realm. Make sure that the
10566 // entry is removed from cache.
10567 MockWrite data_writes3[] = {
bncce36dca22015-04-21 22:11:2310568 MockWrite(
10569 "GET / HTTP/1.1\r\n"
10570 "Host: www.example.org\r\n"
10571 "Connection: keep-alive\r\n"
10572 "Authorization: Basic c2Vjb25kOmZvdQ==\r\n"
10573 "\r\n"),
[email protected]aeefc9e82010-02-19 16:18:2710574 };
10575 MockRead data_reads3[] = {
10576 MockRead("HTTP/1.1 401 Unauthorized\r\n"
10577 "WWW-Authenticate: Basic realm=\"first_realm\"\r\n"
10578 "\r\n"),
10579 };
10580
10581 // Try one last time (with the correct password) and get the resource.
10582 MockWrite data_writes4[] = {
bncce36dca22015-04-21 22:11:2310583 MockWrite(
10584 "GET / HTTP/1.1\r\n"
10585 "Host: www.example.org\r\n"
10586 "Connection: keep-alive\r\n"
10587 "Authorization: Basic Zmlyc3Q6YmFy\r\n"
10588 "\r\n"),
[email protected]aeefc9e82010-02-19 16:18:2710589 };
10590 MockRead data_reads4[] = {
10591 MockRead("HTTP/1.1 200 OK\r\n"
10592 "Content-Type: text/html; charset=iso-8859-1\r\n"
[email protected]0b0bf032010-09-21 18:08:5010593 "Content-Length: 5\r\n"
10594 "\r\n"
10595 "hello"),
[email protected]aeefc9e82010-02-19 16:18:2710596 };
10597
10598 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
10599 data_writes1, arraysize(data_writes1));
10600 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
10601 data_writes2, arraysize(data_writes2));
10602 StaticSocketDataProvider data3(data_reads3, arraysize(data_reads3),
10603 data_writes3, arraysize(data_writes3));
10604 StaticSocketDataProvider data4(data_reads4, arraysize(data_reads4),
10605 data_writes4, arraysize(data_writes4));
[email protected]bb88e1d32013-05-03 23:11:0710606 session_deps_.socket_factory->AddSocketDataProvider(&data1);
10607 session_deps_.socket_factory->AddSocketDataProvider(&data2);
10608 session_deps_.socket_factory->AddSocketDataProvider(&data3);
10609 session_deps_.socket_factory->AddSocketDataProvider(&data4);
[email protected]aeefc9e82010-02-19 16:18:2710610
[email protected]49639fa2011-12-20 23:22:4110611 TestCompletionCallback callback1;
[email protected]aeefc9e82010-02-19 16:18:2710612
danakj1fd259a02016-04-16 03:17:0910613 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1610614 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]0b0bf032010-09-21 18:08:5010615
[email protected]aeefc9e82010-02-19 16:18:2710616 // Issue the first request with Authorize headers. There should be a
10617 // password prompt for first_realm waiting to be filled in after the
10618 // transaction completes.
tfarina42834112016-09-22 13:38:2010619 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110620 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]aeefc9e82010-02-19 16:18:2710621 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:0110622 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:1610623 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5210624 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:0410625 const AuthChallengeInfo* challenge = response->auth_challenge.get();
wezca1070932016-05-26 20:30:5210626 ASSERT_TRUE(challenge);
[email protected]79cb5c12011-09-12 13:12:0410627 EXPECT_FALSE(challenge->is_proxy);
asanka098c0092016-06-16 20:18:4310628 EXPECT_EQ("http://www.example.org", challenge->challenger.Serialize());
[email protected]79cb5c12011-09-12 13:12:0410629 EXPECT_EQ("first_realm", challenge->realm);
aberentbba302d2015-12-03 10:20:1910630 EXPECT_EQ(kBasicAuthScheme, challenge->scheme);
[email protected]aeefc9e82010-02-19 16:18:2710631
10632 // Issue the second request with an incorrect password. There should be a
10633 // password prompt for second_realm waiting to be filled in after the
10634 // transaction completes.
[email protected]49639fa2011-12-20 23:22:4110635 TestCompletionCallback callback2;
bnc691fda62016-08-12 00:43:1610636 rv = trans.RestartWithAuth(AuthCredentials(kFirst, kBaz),
10637 callback2.callback());
robpercival214763f2016-07-01 23:27:0110638 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]aeefc9e82010-02-19 16:18:2710639 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:0110640 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:1610641 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5210642 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:0410643 challenge = response->auth_challenge.get();
wezca1070932016-05-26 20:30:5210644 ASSERT_TRUE(challenge);
[email protected]79cb5c12011-09-12 13:12:0410645 EXPECT_FALSE(challenge->is_proxy);
asanka098c0092016-06-16 20:18:4310646 EXPECT_EQ("http://www.example.org", challenge->challenger.Serialize());
[email protected]79cb5c12011-09-12 13:12:0410647 EXPECT_EQ("second_realm", challenge->realm);
aberentbba302d2015-12-03 10:20:1910648 EXPECT_EQ(kBasicAuthScheme, challenge->scheme);
[email protected]aeefc9e82010-02-19 16:18:2710649
10650 // Issue the third request with another incorrect password. There should be
10651 // a password prompt for first_realm waiting to be filled in. If the password
10652 // prompt is not present, it indicates that the HttpAuthCacheEntry for
10653 // first_realm was not correctly removed.
[email protected]49639fa2011-12-20 23:22:4110654 TestCompletionCallback callback3;
bnc691fda62016-08-12 00:43:1610655 rv = trans.RestartWithAuth(AuthCredentials(kSecond, kFou),
10656 callback3.callback());
robpercival214763f2016-07-01 23:27:0110657 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]aeefc9e82010-02-19 16:18:2710658 rv = callback3.WaitForResult();
robpercival214763f2016-07-01 23:27:0110659 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:1610660 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5210661 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:0410662 challenge = response->auth_challenge.get();
wezca1070932016-05-26 20:30:5210663 ASSERT_TRUE(challenge);
[email protected]79cb5c12011-09-12 13:12:0410664 EXPECT_FALSE(challenge->is_proxy);
asanka098c0092016-06-16 20:18:4310665 EXPECT_EQ("http://www.example.org", challenge->challenger.Serialize());
[email protected]79cb5c12011-09-12 13:12:0410666 EXPECT_EQ("first_realm", challenge->realm);
aberentbba302d2015-12-03 10:20:1910667 EXPECT_EQ(kBasicAuthScheme, challenge->scheme);
[email protected]aeefc9e82010-02-19 16:18:2710668
10669 // Issue the fourth request with the correct password and username.
[email protected]49639fa2011-12-20 23:22:4110670 TestCompletionCallback callback4;
bnc691fda62016-08-12 00:43:1610671 rv = trans.RestartWithAuth(AuthCredentials(kFirst, kBar),
10672 callback4.callback());
robpercival214763f2016-07-01 23:27:0110673 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]aeefc9e82010-02-19 16:18:2710674 rv = callback4.WaitForResult();
robpercival214763f2016-07-01 23:27:0110675 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:1610676 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5210677 ASSERT_TRUE(response);
10678 EXPECT_FALSE(response->auth_challenge);
[email protected]aeefc9e82010-02-19 16:18:2710679}
10680
Bence Béky230ac612017-08-30 19:17:0810681// Regression test for https://crbug.com/754395.
10682TEST_F(HttpNetworkTransactionTest, IgnoreAltSvcWithInvalidCert) {
10683 MockRead data_reads[] = {
10684 MockRead("HTTP/1.1 200 OK\r\n"),
10685 MockRead(kAlternativeServiceHttpHeader),
10686 MockRead("\r\n"),
10687 MockRead("hello world"),
10688 MockRead(SYNCHRONOUS, OK),
10689 };
10690
10691 HttpRequestInfo request;
10692 request.method = "GET";
10693 request.url = GURL("https://www.example.org/");
10694
10695 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
10696 session_deps_.socket_factory->AddSocketDataProvider(&data);
10697
10698 SSLSocketDataProvider ssl(ASYNC, OK);
Ryan Sleevi4f832092017-11-21 23:25:4910699 ssl.ssl_info.cert =
10700 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem");
10701 ASSERT_TRUE(ssl.ssl_info.cert);
10702 ssl.ssl_info.cert_status = CERT_STATUS_COMMON_NAME_INVALID;
Bence Béky230ac612017-08-30 19:17:0810703 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
10704
10705 TestCompletionCallback callback;
10706
10707 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
10708 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
10709
10710 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
10711 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
10712
10713 url::SchemeHostPort test_server(request.url);
10714 HttpServerProperties* http_server_properties =
10715 session->http_server_properties();
10716 EXPECT_TRUE(
10717 http_server_properties->GetAlternativeServiceInfos(test_server).empty());
10718
10719 EXPECT_THAT(callback.WaitForResult(), IsOk());
10720
10721 const HttpResponseInfo* response = trans.GetResponseInfo();
10722 ASSERT_TRUE(response);
10723 ASSERT_TRUE(response->headers);
10724 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
10725 EXPECT_FALSE(response->was_fetched_via_spdy);
10726 EXPECT_FALSE(response->was_alpn_negotiated);
10727
10728 std::string response_data;
10729 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
10730 EXPECT_EQ("hello world", response_data);
10731
10732 EXPECT_TRUE(
10733 http_server_properties->GetAlternativeServiceInfos(test_server).empty());
10734}
10735
bncd16676a2016-07-20 16:23:0110736TEST_F(HttpNetworkTransactionTest, HonorAlternativeServiceHeader) {
bncc958faa2015-07-31 18:14:5210737 MockRead data_reads[] = {
10738 MockRead("HTTP/1.1 200 OK\r\n"),
bnc2df4b522016-07-08 18:17:4310739 MockRead(kAlternativeServiceHttpHeader),
bncc958faa2015-07-31 18:14:5210740 MockRead("\r\n"),
10741 MockRead("hello world"),
10742 MockRead(SYNCHRONOUS, OK),
10743 };
10744
10745 HttpRequestInfo request;
10746 request.method = "GET";
bncb26024382016-06-29 02:39:4510747 request.url = GURL("https://www.example.org/");
bncc958faa2015-07-31 18:14:5210748
10749 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
bncc958faa2015-07-31 18:14:5210750 session_deps_.socket_factory->AddSocketDataProvider(&data);
10751
bncb26024382016-06-29 02:39:4510752 SSLSocketDataProvider ssl(ASYNC, OK);
Ryan Sleevi4f832092017-11-21 23:25:4910753 ssl.ssl_info.cert =
10754 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem");
10755 ASSERT_TRUE(ssl.ssl_info.cert);
bncb26024382016-06-29 02:39:4510756 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
10757
bncc958faa2015-07-31 18:14:5210758 TestCompletionCallback callback;
10759
danakj1fd259a02016-04-16 03:17:0910760 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1610761 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
bncc958faa2015-07-31 18:14:5210762
tfarina42834112016-09-22 13:38:2010763 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110764 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
bncc958faa2015-07-31 18:14:5210765
bncb26024382016-06-29 02:39:4510766 url::SchemeHostPort test_server(request.url);
bnc525e175a2016-06-20 12:36:4010767 HttpServerProperties* http_server_properties =
10768 session->http_server_properties();
zhongyic4de03032017-05-19 04:07:3410769 EXPECT_TRUE(
10770 http_server_properties->GetAlternativeServiceInfos(test_server).empty());
bncc958faa2015-07-31 18:14:5210771
robpercival214763f2016-07-01 23:27:0110772 EXPECT_THAT(callback.WaitForResult(), IsOk());
bncc958faa2015-07-31 18:14:5210773
bnc691fda62016-08-12 00:43:1610774 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5210775 ASSERT_TRUE(response);
10776 ASSERT_TRUE(response->headers);
bncc958faa2015-07-31 18:14:5210777 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
10778 EXPECT_FALSE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5210779 EXPECT_FALSE(response->was_alpn_negotiated);
bncc958faa2015-07-31 18:14:5210780
10781 std::string response_data;
bnc691fda62016-08-12 00:43:1610782 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
bncc958faa2015-07-31 18:14:5210783 EXPECT_EQ("hello world", response_data);
10784
zhongyic4de03032017-05-19 04:07:3410785 AlternativeServiceInfoVector alternative_service_info_vector =
10786 http_server_properties->GetAlternativeServiceInfos(test_server);
10787 ASSERT_EQ(1u, alternative_service_info_vector.size());
10788 AlternativeService alternative_service(kProtoHTTP2, "mail.example.org", 443);
10789 EXPECT_EQ(alternative_service,
zhongyi422ce352017-06-09 23:28:5410790 alternative_service_info_vector[0].alternative_service());
bncc958faa2015-07-31 18:14:5210791}
10792
bnce3dd56f2016-06-01 10:37:1110793// Regression test for https://crbug.com/615497.
bncd16676a2016-07-20 16:23:0110794TEST_F(HttpNetworkTransactionTest,
bnce3dd56f2016-06-01 10:37:1110795 DoNotParseAlternativeServiceHeaderOnInsecureRequest) {
bnce3dd56f2016-06-01 10:37:1110796 MockRead data_reads[] = {
10797 MockRead("HTTP/1.1 200 OK\r\n"),
bnc2df4b522016-07-08 18:17:4310798 MockRead(kAlternativeServiceHttpHeader),
bnce3dd56f2016-06-01 10:37:1110799 MockRead("\r\n"),
10800 MockRead("hello world"),
10801 MockRead(SYNCHRONOUS, OK),
10802 };
10803
10804 HttpRequestInfo request;
10805 request.method = "GET";
10806 request.url = GURL("http://www.example.org/");
10807 request.load_flags = 0;
10808
10809 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
10810 session_deps_.socket_factory->AddSocketDataProvider(&data);
10811
10812 TestCompletionCallback callback;
10813
10814 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1610815 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
bnce3dd56f2016-06-01 10:37:1110816
10817 url::SchemeHostPort test_server(request.url);
bnc525e175a2016-06-20 12:36:4010818 HttpServerProperties* http_server_properties =
10819 session->http_server_properties();
zhongyic4de03032017-05-19 04:07:3410820 EXPECT_TRUE(
10821 http_server_properties->GetAlternativeServiceInfos(test_server).empty());
bnce3dd56f2016-06-01 10:37:1110822
tfarina42834112016-09-22 13:38:2010823 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110824 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
10825 EXPECT_THAT(callback.WaitForResult(), IsOk());
bnce3dd56f2016-06-01 10:37:1110826
bnc691fda62016-08-12 00:43:1610827 const HttpResponseInfo* response = trans.GetResponseInfo();
bnce3dd56f2016-06-01 10:37:1110828 ASSERT_TRUE(response);
10829 ASSERT_TRUE(response->headers);
10830 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
10831 EXPECT_FALSE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5210832 EXPECT_FALSE(response->was_alpn_negotiated);
bnce3dd56f2016-06-01 10:37:1110833
10834 std::string response_data;
bnc691fda62016-08-12 00:43:1610835 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
bnce3dd56f2016-06-01 10:37:1110836 EXPECT_EQ("hello world", response_data);
10837
zhongyic4de03032017-05-19 04:07:3410838 EXPECT_TRUE(
10839 http_server_properties->GetAlternativeServiceInfos(test_server).empty());
bnce3dd56f2016-06-01 10:37:1110840}
10841
bnca86731e2017-04-17 12:31:2810842// HTTP/2 Alternative Services should be disabled by default.
bnc8bef8da22016-05-30 01:28:2510843// TODO(bnc): Remove when https://crbug.com/615413 is fixed.
bncd16676a2016-07-20 16:23:0110844TEST_F(HttpNetworkTransactionTest,
bnc8bef8da22016-05-30 01:28:2510845 DisableHTTP2AlternativeServicesWithDifferentHost) {
bnca86731e2017-04-17 12:31:2810846 session_deps_.enable_http2_alternative_service = false;
bncb26024382016-06-29 02:39:4510847
bnc8bef8da22016-05-30 01:28:2510848 HttpRequestInfo request;
10849 request.method = "GET";
bncb26024382016-06-29 02:39:4510850 request.url = GURL("https://www.example.org/");
bnc8bef8da22016-05-30 01:28:2510851 request.load_flags = 0;
10852
10853 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
10854 StaticSocketDataProvider first_data;
10855 first_data.set_connect_data(mock_connect);
10856 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
bncb26024382016-06-29 02:39:4510857 SSLSocketDataProvider ssl_http11(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3610858 ssl_http11.next_proto = kProtoHTTP11;
bncb26024382016-06-29 02:39:4510859 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_http11);
bnc8bef8da22016-05-30 01:28:2510860
10861 MockRead data_reads[] = {
10862 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello world"),
10863 MockRead(ASYNC, OK),
10864 };
10865 StaticSocketDataProvider second_data(data_reads, arraysize(data_reads), NULL,
10866 0);
10867 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
10868
10869 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
10870
bnc525e175a2016-06-20 12:36:4010871 HttpServerProperties* http_server_properties =
bnc8bef8da22016-05-30 01:28:2510872 session->http_server_properties();
bnc3472afd2016-11-17 15:27:2110873 AlternativeService alternative_service(kProtoHTTP2, "different.example.org",
10874 444);
bnc8bef8da22016-05-30 01:28:2510875 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:2110876 http_server_properties->SetHttp2AlternativeService(
bnc8bef8da22016-05-30 01:28:2510877 url::SchemeHostPort(request.url), alternative_service, expiration);
10878
bnc691fda62016-08-12 00:43:1610879 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
bnc8bef8da22016-05-30 01:28:2510880 TestCompletionCallback callback;
10881
tfarina42834112016-09-22 13:38:2010882 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
bnc8bef8da22016-05-30 01:28:2510883 // Alternative service is not used, request fails.
robpercival214763f2016-07-01 23:27:0110884 EXPECT_THAT(callback.GetResult(rv), IsError(ERR_CONNECTION_REFUSED));
bnc8bef8da22016-05-30 01:28:2510885}
10886
bnce3dd56f2016-06-01 10:37:1110887// Regression test for https://crbug.com/615497:
10888// Alternative Services should be disabled for http origin.
bncd16676a2016-07-20 16:23:0110889TEST_F(HttpNetworkTransactionTest,
bnce3dd56f2016-06-01 10:37:1110890 DisableAlternativeServicesForInsecureOrigin) {
bnce3dd56f2016-06-01 10:37:1110891 HttpRequestInfo request;
10892 request.method = "GET";
10893 request.url = GURL("http://www.example.org/");
10894 request.load_flags = 0;
10895
10896 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
10897 StaticSocketDataProvider first_data;
10898 first_data.set_connect_data(mock_connect);
10899 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
10900
10901 MockRead data_reads[] = {
10902 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello world"),
10903 MockRead(ASYNC, OK),
10904 };
10905 StaticSocketDataProvider second_data(data_reads, arraysize(data_reads), NULL,
10906 0);
10907 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
10908
10909 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
10910
bnc525e175a2016-06-20 12:36:4010911 HttpServerProperties* http_server_properties =
bnce3dd56f2016-06-01 10:37:1110912 session->http_server_properties();
bnc3472afd2016-11-17 15:27:2110913 AlternativeService alternative_service(kProtoHTTP2, "", 444);
bnce3dd56f2016-06-01 10:37:1110914 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:2110915 http_server_properties->SetHttp2AlternativeService(
bnce3dd56f2016-06-01 10:37:1110916 url::SchemeHostPort(request.url), alternative_service, expiration);
10917
bnc691fda62016-08-12 00:43:1610918 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
bnce3dd56f2016-06-01 10:37:1110919 TestCompletionCallback callback;
10920
tfarina42834112016-09-22 13:38:2010921 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
bnce3dd56f2016-06-01 10:37:1110922 // Alternative service is not used, request fails.
robpercival214763f2016-07-01 23:27:0110923 EXPECT_THAT(callback.GetResult(rv), IsError(ERR_CONNECTION_REFUSED));
bnce3dd56f2016-06-01 10:37:1110924}
10925
bncd16676a2016-07-20 16:23:0110926TEST_F(HttpNetworkTransactionTest, ClearAlternativeServices) {
bnc4f575852015-10-14 18:35:0810927 // Set an alternative service for origin.
danakj1fd259a02016-04-16 03:17:0910928 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc525e175a2016-06-20 12:36:4010929 HttpServerProperties* http_server_properties =
10930 session->http_server_properties();
bncb26024382016-06-29 02:39:4510931 url::SchemeHostPort test_server("https", "www.example.org", 443);
bnc3472afd2016-11-17 15:27:2110932 AlternativeService alternative_service(kProtoQUIC, "", 80);
bnc4f575852015-10-14 18:35:0810933 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:2110934 http_server_properties->SetQuicAlternativeService(
10935 test_server, alternative_service, expiration,
10936 session->params().quic_supported_versions);
zhongyic4de03032017-05-19 04:07:3410937 EXPECT_EQ(
10938 1u,
10939 http_server_properties->GetAlternativeServiceInfos(test_server).size());
bnc4f575852015-10-14 18:35:0810940
10941 // Send a clear header.
10942 MockRead data_reads[] = {
10943 MockRead("HTTP/1.1 200 OK\r\n"),
10944 MockRead("Alt-Svc: clear\r\n"),
10945 MockRead("\r\n"),
10946 MockRead("hello world"),
10947 MockRead(SYNCHRONOUS, OK),
10948 };
10949 StaticSocketDataProvider data(data_reads, arraysize(data_reads), nullptr, 0);
10950 session_deps_.socket_factory->AddSocketDataProvider(&data);
10951
bncb26024382016-06-29 02:39:4510952 SSLSocketDataProvider ssl(ASYNC, OK);
Ryan Sleevi4f832092017-11-21 23:25:4910953 ssl.ssl_info.cert =
10954 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem");
10955 ASSERT_TRUE(ssl.ssl_info.cert);
bncb26024382016-06-29 02:39:4510956 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
10957
bnc4f575852015-10-14 18:35:0810958 HttpRequestInfo request;
10959 request.method = "GET";
bncb26024382016-06-29 02:39:4510960 request.url = GURL("https://www.example.org/");
bnc4f575852015-10-14 18:35:0810961
10962 TestCompletionCallback callback;
10963
bnc691fda62016-08-12 00:43:1610964 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
bnc4f575852015-10-14 18:35:0810965
tfarina42834112016-09-22 13:38:2010966 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110967 EXPECT_THAT(callback.GetResult(rv), IsOk());
bnc4f575852015-10-14 18:35:0810968
bnc691fda62016-08-12 00:43:1610969 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5210970 ASSERT_TRUE(response);
10971 ASSERT_TRUE(response->headers);
bnc4f575852015-10-14 18:35:0810972 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
10973 EXPECT_FALSE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5210974 EXPECT_FALSE(response->was_alpn_negotiated);
bnc4f575852015-10-14 18:35:0810975
10976 std::string response_data;
bnc691fda62016-08-12 00:43:1610977 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
bnc4f575852015-10-14 18:35:0810978 EXPECT_EQ("hello world", response_data);
10979
zhongyic4de03032017-05-19 04:07:3410980 EXPECT_TRUE(
10981 http_server_properties->GetAlternativeServiceInfos(test_server).empty());
bnc4f575852015-10-14 18:35:0810982}
10983
bncd16676a2016-07-20 16:23:0110984TEST_F(HttpNetworkTransactionTest, HonorMultipleAlternativeServiceHeaders) {
bncc958faa2015-07-31 18:14:5210985 MockRead data_reads[] = {
10986 MockRead("HTTP/1.1 200 OK\r\n"),
bnc2df4b522016-07-08 18:17:4310987 MockRead("Alt-Svc: h2=\"www.example.com:443\","),
10988 MockRead("h2=\":1234\"\r\n\r\n"),
bncc958faa2015-07-31 18:14:5210989 MockRead("hello world"),
10990 MockRead(SYNCHRONOUS, OK),
10991 };
10992
10993 HttpRequestInfo request;
10994 request.method = "GET";
bncb26024382016-06-29 02:39:4510995 request.url = GURL("https://www.example.org/");
bncc958faa2015-07-31 18:14:5210996
10997 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
bncc958faa2015-07-31 18:14:5210998 session_deps_.socket_factory->AddSocketDataProvider(&data);
10999
bncb26024382016-06-29 02:39:4511000 SSLSocketDataProvider ssl(ASYNC, OK);
Ryan Sleevi4f832092017-11-21 23:25:4911001 ssl.ssl_info.cert =
11002 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem");
11003 ASSERT_TRUE(ssl.ssl_info.cert);
bncb26024382016-06-29 02:39:4511004 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
11005
bncc958faa2015-07-31 18:14:5211006 TestCompletionCallback callback;
11007
danakj1fd259a02016-04-16 03:17:0911008 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1611009 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
bncc958faa2015-07-31 18:14:5211010
tfarina42834112016-09-22 13:38:2011011 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0111012 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
bncc958faa2015-07-31 18:14:5211013
bncb26024382016-06-29 02:39:4511014 url::SchemeHostPort test_server("https", "www.example.org", 443);
bnc525e175a2016-06-20 12:36:4011015 HttpServerProperties* http_server_properties =
11016 session->http_server_properties();
zhongyic4de03032017-05-19 04:07:3411017 EXPECT_TRUE(
11018 http_server_properties->GetAlternativeServiceInfos(test_server).empty());
bncc958faa2015-07-31 18:14:5211019
robpercival214763f2016-07-01 23:27:0111020 EXPECT_THAT(callback.WaitForResult(), IsOk());
bncc958faa2015-07-31 18:14:5211021
bnc691fda62016-08-12 00:43:1611022 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5211023 ASSERT_TRUE(response);
11024 ASSERT_TRUE(response->headers);
bncc958faa2015-07-31 18:14:5211025 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
11026 EXPECT_FALSE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5211027 EXPECT_FALSE(response->was_alpn_negotiated);
bncc958faa2015-07-31 18:14:5211028
11029 std::string response_data;
bnc691fda62016-08-12 00:43:1611030 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
bncc958faa2015-07-31 18:14:5211031 EXPECT_EQ("hello world", response_data);
11032
zhongyic4de03032017-05-19 04:07:3411033 AlternativeServiceInfoVector alternative_service_info_vector =
11034 http_server_properties->GetAlternativeServiceInfos(test_server);
11035 ASSERT_EQ(2u, alternative_service_info_vector.size());
11036
11037 AlternativeService alternative_service(kProtoHTTP2, "www.example.com", 443);
11038 EXPECT_EQ(alternative_service,
zhongyi422ce352017-06-09 23:28:5411039 alternative_service_info_vector[0].alternative_service());
zhongyic4de03032017-05-19 04:07:3411040 AlternativeService alternative_service_2(kProtoHTTP2, "www.example.org",
11041 1234);
11042 EXPECT_EQ(alternative_service_2,
zhongyi422ce352017-06-09 23:28:5411043 alternative_service_info_vector[1].alternative_service());
bncc958faa2015-07-31 18:14:5211044}
11045
bncd16676a2016-07-20 16:23:0111046TEST_F(HttpNetworkTransactionTest, IdentifyQuicBroken) {
zhongyi3d4a55e72016-04-22 20:36:4611047 url::SchemeHostPort server("https", "origin.example.org", 443);
zhongyi48704c182015-12-07 07:52:0211048 HostPortPair alternative("alternative.example.org", 443);
11049 std::string origin_url = "https://origin.example.org:443";
11050 std::string alternative_url = "https://alternative.example.org:443";
11051
11052 // Negotiate HTTP/1.1 with alternative.example.org.
11053 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3611054 ssl.next_proto = kProtoHTTP11;
zhongyi48704c182015-12-07 07:52:0211055 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
11056
11057 // HTTP/1.1 data for request.
11058 MockWrite http_writes[] = {
11059 MockWrite("GET / HTTP/1.1\r\n"
11060 "Host: alternative.example.org\r\n"
11061 "Connection: keep-alive\r\n\r\n"),
11062 };
11063
11064 MockRead http_reads[] = {
11065 MockRead("HTTP/1.1 200 OK\r\n"
11066 "Content-Type: text/html; charset=iso-8859-1\r\n"
11067 "Content-Length: 40\r\n\r\n"
11068 "first HTTP/1.1 response from alternative"),
11069 };
11070 StaticSocketDataProvider http_data(http_reads, arraysize(http_reads),
11071 http_writes, arraysize(http_writes));
11072 session_deps_.socket_factory->AddSocketDataProvider(&http_data);
11073
11074 StaticSocketDataProvider data_refused;
11075 data_refused.set_connect_data(MockConnect(ASYNC, ERR_CONNECTION_REFUSED));
11076 session_deps_.socket_factory->AddSocketDataProvider(&data_refused);
11077
zhongyi3d4a55e72016-04-22 20:36:4611078 // Set up a QUIC alternative service for server.
danakj1fd259a02016-04-16 03:17:0911079 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc525e175a2016-06-20 12:36:4011080 HttpServerProperties* http_server_properties =
zhongyi48704c182015-12-07 07:52:0211081 session->http_server_properties();
bnc3472afd2016-11-17 15:27:2111082 AlternativeService alternative_service(kProtoQUIC, alternative);
zhongyi48704c182015-12-07 07:52:0211083 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:2111084 http_server_properties->SetQuicAlternativeService(
11085 server, alternative_service, expiration,
11086 HttpNetworkSession::Params().quic_supported_versions);
zhongyi48704c182015-12-07 07:52:0211087 // Mark the QUIC alternative service as broken.
11088 http_server_properties->MarkAlternativeServiceBroken(alternative_service);
11089
zhongyi48704c182015-12-07 07:52:0211090 HttpRequestInfo request;
krasinc06a72a2016-12-21 03:42:4611091 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
zhongyi48704c182015-12-07 07:52:0211092 request.method = "GET";
11093 request.url = GURL(origin_url);
zhongyi48704c182015-12-07 07:52:0211094 TestCompletionCallback callback;
11095 NetErrorDetails details;
11096 EXPECT_FALSE(details.quic_broken);
11097
tfarina42834112016-09-22 13:38:2011098 trans.Start(&request, callback.callback(), NetLogWithSource());
bnc691fda62016-08-12 00:43:1611099 trans.PopulateNetErrorDetails(&details);
zhongyi48704c182015-12-07 07:52:0211100 EXPECT_TRUE(details.quic_broken);
11101}
11102
bncd16676a2016-07-20 16:23:0111103TEST_F(HttpNetworkTransactionTest, IdentifyQuicNotBroken) {
zhongyi3d4a55e72016-04-22 20:36:4611104 url::SchemeHostPort server("https", "origin.example.org", 443);
zhongyi48704c182015-12-07 07:52:0211105 HostPortPair alternative1("alternative1.example.org", 443);
11106 HostPortPair alternative2("alternative2.example.org", 443);
11107 std::string origin_url = "https://origin.example.org:443";
11108 std::string alternative_url1 = "https://alternative1.example.org:443";
11109 std::string alternative_url2 = "https://alternative2.example.org:443";
11110
11111 // Negotiate HTTP/1.1 with alternative1.example.org.
11112 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3611113 ssl.next_proto = kProtoHTTP11;
zhongyi48704c182015-12-07 07:52:0211114 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
11115
11116 // HTTP/1.1 data for request.
11117 MockWrite http_writes[] = {
11118 MockWrite("GET / HTTP/1.1\r\n"
11119 "Host: alternative1.example.org\r\n"
11120 "Connection: keep-alive\r\n\r\n"),
11121 };
11122
11123 MockRead http_reads[] = {
11124 MockRead("HTTP/1.1 200 OK\r\n"
11125 "Content-Type: text/html; charset=iso-8859-1\r\n"
11126 "Content-Length: 40\r\n\r\n"
11127 "first HTTP/1.1 response from alternative1"),
11128 };
11129 StaticSocketDataProvider http_data(http_reads, arraysize(http_reads),
11130 http_writes, arraysize(http_writes));
11131 session_deps_.socket_factory->AddSocketDataProvider(&http_data);
11132
11133 StaticSocketDataProvider data_refused;
11134 data_refused.set_connect_data(MockConnect(ASYNC, ERR_CONNECTION_REFUSED));
11135 session_deps_.socket_factory->AddSocketDataProvider(&data_refused);
11136
danakj1fd259a02016-04-16 03:17:0911137 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc525e175a2016-06-20 12:36:4011138 HttpServerProperties* http_server_properties =
zhongyi48704c182015-12-07 07:52:0211139 session->http_server_properties();
11140
zhongyi3d4a55e72016-04-22 20:36:4611141 // Set up two QUIC alternative services for server.
zhongyi48704c182015-12-07 07:52:0211142 AlternativeServiceInfoVector alternative_service_info_vector;
11143 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
11144
bnc3472afd2016-11-17 15:27:2111145 AlternativeService alternative_service1(kProtoQUIC, alternative1);
zhongyie537a002017-06-27 16:48:2111146 alternative_service_info_vector.push_back(
11147 AlternativeServiceInfo::CreateQuicAlternativeServiceInfo(
11148 alternative_service1, expiration,
11149 session->params().quic_supported_versions));
bnc3472afd2016-11-17 15:27:2111150 AlternativeService alternative_service2(kProtoQUIC, alternative2);
zhongyie537a002017-06-27 16:48:2111151 alternative_service_info_vector.push_back(
11152 AlternativeServiceInfo::CreateQuicAlternativeServiceInfo(
11153 alternative_service2, expiration,
11154 session->params().quic_supported_versions));
zhongyi48704c182015-12-07 07:52:0211155
11156 http_server_properties->SetAlternativeServices(
zhongyi3d4a55e72016-04-22 20:36:4611157 server, alternative_service_info_vector);
zhongyi48704c182015-12-07 07:52:0211158
11159 // Mark one of the QUIC alternative service as broken.
11160 http_server_properties->MarkAlternativeServiceBroken(alternative_service1);
zhongyic4de03032017-05-19 04:07:3411161 EXPECT_EQ(2u,
11162 http_server_properties->GetAlternativeServiceInfos(server).size());
zhongyi48704c182015-12-07 07:52:0211163
zhongyi48704c182015-12-07 07:52:0211164 HttpRequestInfo request;
krasinc06a72a2016-12-21 03:42:4611165 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
zhongyi48704c182015-12-07 07:52:0211166 request.method = "GET";
11167 request.url = GURL(origin_url);
zhongyi48704c182015-12-07 07:52:0211168 TestCompletionCallback callback;
11169 NetErrorDetails details;
11170 EXPECT_FALSE(details.quic_broken);
11171
tfarina42834112016-09-22 13:38:2011172 trans.Start(&request, callback.callback(), NetLogWithSource());
bnc691fda62016-08-12 00:43:1611173 trans.PopulateNetErrorDetails(&details);
zhongyi48704c182015-12-07 07:52:0211174 EXPECT_FALSE(details.quic_broken);
11175}
11176
bncd16676a2016-07-20 16:23:0111177TEST_F(HttpNetworkTransactionTest, MarkBrokenAlternateProtocolAndFallback) {
[email protected]564b4912010-03-09 16:30:4211178 HttpRequestInfo request;
11179 request.method = "GET";
bncb26024382016-06-29 02:39:4511180 request.url = GURL("https://www.example.org/");
[email protected]564b4912010-03-09 16:30:4211181
[email protected]d973e99a2012-02-17 21:02:3611182 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
[email protected]564b4912010-03-09 16:30:4211183 StaticSocketDataProvider first_data;
11184 first_data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:0711185 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
bncb26024382016-06-29 02:39:4511186 SSLSocketDataProvider ssl_http11(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3611187 ssl_http11.next_proto = kProtoHTTP11;
bncb26024382016-06-29 02:39:4511188 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_http11);
[email protected]564b4912010-03-09 16:30:4211189
11190 MockRead data_reads[] = {
11191 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
11192 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:0611193 MockRead(ASYNC, OK),
[email protected]564b4912010-03-09 16:30:4211194 };
11195 StaticSocketDataProvider second_data(
11196 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0711197 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
[email protected]564b4912010-03-09 16:30:4211198
danakj1fd259a02016-04-16 03:17:0911199 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]564b4912010-03-09 16:30:4211200
bnc525e175a2016-06-20 12:36:4011201 HttpServerProperties* http_server_properties =
[email protected]17291a022011-10-10 07:32:5311202 session->http_server_properties();
zhongyi3d4a55e72016-04-22 20:36:4611203 const url::SchemeHostPort server(request.url);
[email protected]3912662a32011-10-04 00:51:1111204 // Port must be < 1024, or the header will be ignored (since initial port was
11205 // port 80 (another restricted port).
zhongyie537a002017-06-27 16:48:2111206 // Port is ignored by MockConnect anyway.
11207 const AlternativeService alternative_service(kProtoHTTP2, "www.example.org",
11208 666);
bnc7dc7e1b42015-07-28 14:43:1211209 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:2111210 http_server_properties->SetHttp2AlternativeService(
11211 server, alternative_service, expiration);
[email protected]564b4912010-03-09 16:30:4211212
bnc691fda62016-08-12 00:43:1611213 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]49639fa2011-12-20 23:22:4111214 TestCompletionCallback callback;
[email protected]564b4912010-03-09 16:30:4211215
tfarina42834112016-09-22 13:38:2011216 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0111217 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
11218 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]564b4912010-03-09 16:30:4211219
bnc691fda62016-08-12 00:43:1611220 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5211221 ASSERT_TRUE(response);
11222 ASSERT_TRUE(response->headers);
[email protected]564b4912010-03-09 16:30:4211223 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
11224
11225 std::string response_data;
bnc691fda62016-08-12 00:43:1611226 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
[email protected]564b4912010-03-09 16:30:4211227 EXPECT_EQ("hello world", response_data);
11228
zhongyic4de03032017-05-19 04:07:3411229 const AlternativeServiceInfoVector alternative_service_info_vector =
11230 http_server_properties->GetAlternativeServiceInfos(server);
11231 ASSERT_EQ(1u, alternative_service_info_vector.size());
11232 EXPECT_EQ(alternative_service,
zhongyi422ce352017-06-09 23:28:5411233 alternative_service_info_vector[0].alternative_service());
zhongyic4de03032017-05-19 04:07:3411234 EXPECT_TRUE(
11235 http_server_properties->IsAlternativeServiceBroken(alternative_service));
[email protected]564b4912010-03-09 16:30:4211236}
11237
bnc55ff9da2015-08-19 18:42:3511238// Ensure that we are not allowed to redirect traffic via an alternate protocol
11239// to an unrestricted (port >= 1024) when the original traffic was on a
11240// restricted port (port < 1024). Ensure that we can redirect in all other
11241// cases.
bncd16676a2016-07-20 16:23:0111242TEST_F(HttpNetworkTransactionTest, AlternateProtocolPortRestrictedBlocked) {
[email protected]3912662a32011-10-04 00:51:1111243 HttpRequestInfo restricted_port_request;
11244 restricted_port_request.method = "GET";
bncb26024382016-06-29 02:39:4511245 restricted_port_request.url = GURL("https://www.example.org:1023/");
[email protected]3912662a32011-10-04 00:51:1111246 restricted_port_request.load_flags = 0;
11247
[email protected]d973e99a2012-02-17 21:02:3611248 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
[email protected]3912662a32011-10-04 00:51:1111249 StaticSocketDataProvider first_data;
11250 first_data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:0711251 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
[email protected]3912662a32011-10-04 00:51:1111252
11253 MockRead data_reads[] = {
11254 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
11255 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:0611256 MockRead(ASYNC, OK),
[email protected]3912662a32011-10-04 00:51:1111257 };
11258 StaticSocketDataProvider second_data(
11259 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0711260 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
bncb26024382016-06-29 02:39:4511261 SSLSocketDataProvider ssl_http11(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3611262 ssl_http11.next_proto = kProtoHTTP11;
bncb26024382016-06-29 02:39:4511263 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_http11);
[email protected]3912662a32011-10-04 00:51:1111264
danakj1fd259a02016-04-16 03:17:0911265 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]3912662a32011-10-04 00:51:1111266
bnc525e175a2016-06-20 12:36:4011267 HttpServerProperties* http_server_properties =
[email protected]17291a022011-10-10 07:32:5311268 session->http_server_properties();
[email protected]3912662a32011-10-04 00:51:1111269 const int kUnrestrictedAlternatePort = 1024;
bnc3472afd2016-11-17 15:27:2111270 AlternativeService alternative_service(kProtoHTTP2, "www.example.org",
11271 kUnrestrictedAlternatePort);
bnc7dc7e1b42015-07-28 14:43:1211272 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:2111273 http_server_properties->SetHttp2AlternativeService(
zhongyi3d4a55e72016-04-22 20:36:4611274 url::SchemeHostPort(restricted_port_request.url), alternative_service,
rchdc7b9052016-03-17 20:51:5011275 expiration);
[email protected]3912662a32011-10-04 00:51:1111276
bnc691fda62016-08-12 00:43:1611277 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]49639fa2011-12-20 23:22:4111278 TestCompletionCallback callback;
[email protected]3912662a32011-10-04 00:51:1111279
tfarina42834112016-09-22 13:38:2011280 int rv = trans.Start(&restricted_port_request, callback.callback(),
11281 NetLogWithSource());
robpercival214763f2016-07-01 23:27:0111282 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]3912662a32011-10-04 00:51:1111283 // Invalid change to unrestricted port should fail.
robpercival214763f2016-07-01 23:27:0111284 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_CONNECTION_REFUSED));
[email protected]c54c6962013-02-01 04:53:1911285}
[email protected]3912662a32011-10-04 00:51:1111286
bnc55ff9da2015-08-19 18:42:3511287// Ensure that we are allowed to redirect traffic via an alternate protocol to
11288// an unrestricted (port >= 1024) when the original traffic was on a restricted
11289// port (port < 1024) if we set |enable_user_alternate_protocol_ports|.
bncd16676a2016-07-20 16:23:0111290TEST_F(HttpNetworkTransactionTest, AlternateProtocolPortRestrictedPermitted) {
[email protected]bb88e1d32013-05-03 23:11:0711291 session_deps_.enable_user_alternate_protocol_ports = true;
[email protected]c54c6962013-02-01 04:53:1911292
11293 HttpRequestInfo restricted_port_request;
11294 restricted_port_request.method = "GET";
bncb26024382016-06-29 02:39:4511295 restricted_port_request.url = GURL("https://www.example.org:1023/");
[email protected]c54c6962013-02-01 04:53:1911296 restricted_port_request.load_flags = 0;
11297
11298 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
11299 StaticSocketDataProvider first_data;
11300 first_data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:0711301 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
[email protected]c54c6962013-02-01 04:53:1911302
11303 MockRead data_reads[] = {
11304 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
11305 MockRead("hello world"),
11306 MockRead(ASYNC, OK),
11307 };
11308 StaticSocketDataProvider second_data(
11309 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0711310 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
bncb26024382016-06-29 02:39:4511311 SSLSocketDataProvider ssl_http11(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3611312 ssl_http11.next_proto = kProtoHTTP11;
bncb26024382016-06-29 02:39:4511313 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_http11);
[email protected]c54c6962013-02-01 04:53:1911314
danakj1fd259a02016-04-16 03:17:0911315 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]c54c6962013-02-01 04:53:1911316
bnc525e175a2016-06-20 12:36:4011317 HttpServerProperties* http_server_properties =
[email protected]c54c6962013-02-01 04:53:1911318 session->http_server_properties();
11319 const int kUnrestrictedAlternatePort = 1024;
bnc3472afd2016-11-17 15:27:2111320 AlternativeService alternative_service(kProtoHTTP2, "www.example.org",
11321 kUnrestrictedAlternatePort);
bnc7dc7e1b42015-07-28 14:43:1211322 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:2111323 http_server_properties->SetHttp2AlternativeService(
zhongyi3d4a55e72016-04-22 20:36:4611324 url::SchemeHostPort(restricted_port_request.url), alternative_service,
rchdc7b9052016-03-17 20:51:5011325 expiration);
[email protected]c54c6962013-02-01 04:53:1911326
bnc691fda62016-08-12 00:43:1611327 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]c54c6962013-02-01 04:53:1911328 TestCompletionCallback callback;
11329
tfarina42834112016-09-22 13:38:2011330 EXPECT_EQ(ERR_IO_PENDING,
11331 trans.Start(&restricted_port_request, callback.callback(),
11332 NetLogWithSource()));
[email protected]c54c6962013-02-01 04:53:1911333 // Change to unrestricted port should succeed.
robpercival214763f2016-07-01 23:27:0111334 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]3912662a32011-10-04 00:51:1111335}
11336
bnc55ff9da2015-08-19 18:42:3511337// Ensure that we are not allowed to redirect traffic via an alternate protocol
11338// to an unrestricted (port >= 1024) when the original traffic was on a
11339// restricted port (port < 1024). Ensure that we can redirect in all other
11340// cases.
bncd16676a2016-07-20 16:23:0111341TEST_F(HttpNetworkTransactionTest, AlternateProtocolPortRestrictedAllowed) {
[email protected]3912662a32011-10-04 00:51:1111342 HttpRequestInfo restricted_port_request;
11343 restricted_port_request.method = "GET";
bncb26024382016-06-29 02:39:4511344 restricted_port_request.url = GURL("https://www.example.org:1023/");
[email protected]3912662a32011-10-04 00:51:1111345 restricted_port_request.load_flags = 0;
11346
[email protected]d973e99a2012-02-17 21:02:3611347 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
[email protected]3912662a32011-10-04 00:51:1111348 StaticSocketDataProvider first_data;
11349 first_data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:0711350 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
[email protected]3912662a32011-10-04 00:51:1111351
11352 MockRead data_reads[] = {
11353 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
11354 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:0611355 MockRead(ASYNC, OK),
[email protected]3912662a32011-10-04 00:51:1111356 };
11357 StaticSocketDataProvider second_data(
11358 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0711359 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
[email protected]3912662a32011-10-04 00:51:1111360
bncb26024382016-06-29 02:39:4511361 SSLSocketDataProvider ssl(ASYNC, OK);
11362 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
11363
danakj1fd259a02016-04-16 03:17:0911364 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]3912662a32011-10-04 00:51:1111365
bnc525e175a2016-06-20 12:36:4011366 HttpServerProperties* http_server_properties =
[email protected]17291a022011-10-10 07:32:5311367 session->http_server_properties();
[email protected]3912662a32011-10-04 00:51:1111368 const int kRestrictedAlternatePort = 80;
bnc3472afd2016-11-17 15:27:2111369 AlternativeService alternative_service(kProtoHTTP2, "www.example.org",
11370 kRestrictedAlternatePort);
bnc7dc7e1b42015-07-28 14:43:1211371 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:2111372 http_server_properties->SetHttp2AlternativeService(
zhongyi3d4a55e72016-04-22 20:36:4611373 url::SchemeHostPort(restricted_port_request.url), alternative_service,
rchdc7b9052016-03-17 20:51:5011374 expiration);
[email protected]3912662a32011-10-04 00:51:1111375
bnc691fda62016-08-12 00:43:1611376 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]49639fa2011-12-20 23:22:4111377 TestCompletionCallback callback;
[email protected]3912662a32011-10-04 00:51:1111378
tfarina42834112016-09-22 13:38:2011379 int rv = trans.Start(&restricted_port_request, callback.callback(),
11380 NetLogWithSource());
robpercival214763f2016-07-01 23:27:0111381 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]3912662a32011-10-04 00:51:1111382 // Valid change to restricted port should pass.
robpercival214763f2016-07-01 23:27:0111383 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]3912662a32011-10-04 00:51:1111384}
11385
bnc55ff9da2015-08-19 18:42:3511386// Ensure that we are not allowed to redirect traffic via an alternate protocol
11387// to an unrestricted (port >= 1024) when the original traffic was on a
11388// restricted port (port < 1024). Ensure that we can redirect in all other
11389// cases.
bncd16676a2016-07-20 16:23:0111390TEST_F(HttpNetworkTransactionTest, AlternateProtocolPortUnrestrictedAllowed1) {
[email protected]3912662a32011-10-04 00:51:1111391 HttpRequestInfo unrestricted_port_request;
11392 unrestricted_port_request.method = "GET";
bncb26024382016-06-29 02:39:4511393 unrestricted_port_request.url = GURL("https://www.example.org:1024/");
[email protected]3912662a32011-10-04 00:51:1111394 unrestricted_port_request.load_flags = 0;
11395
[email protected]d973e99a2012-02-17 21:02:3611396 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
[email protected]3912662a32011-10-04 00:51:1111397 StaticSocketDataProvider first_data;
11398 first_data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:0711399 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
[email protected]3912662a32011-10-04 00:51:1111400
11401 MockRead data_reads[] = {
11402 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
11403 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:0611404 MockRead(ASYNC, OK),
[email protected]3912662a32011-10-04 00:51:1111405 };
11406 StaticSocketDataProvider second_data(
11407 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0711408 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
bncb26024382016-06-29 02:39:4511409 SSLSocketDataProvider ssl_http11(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3611410 ssl_http11.next_proto = kProtoHTTP11;
bncb26024382016-06-29 02:39:4511411 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_http11);
[email protected]3912662a32011-10-04 00:51:1111412
danakj1fd259a02016-04-16 03:17:0911413 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]3912662a32011-10-04 00:51:1111414
bnc525e175a2016-06-20 12:36:4011415 HttpServerProperties* http_server_properties =
[email protected]17291a022011-10-10 07:32:5311416 session->http_server_properties();
[email protected]3912662a32011-10-04 00:51:1111417 const int kRestrictedAlternatePort = 80;
bnc3472afd2016-11-17 15:27:2111418 AlternativeService alternative_service(kProtoHTTP2, "www.example.org",
11419 kRestrictedAlternatePort);
bnc7dc7e1b42015-07-28 14:43:1211420 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:2111421 http_server_properties->SetHttp2AlternativeService(
zhongyi3d4a55e72016-04-22 20:36:4611422 url::SchemeHostPort(unrestricted_port_request.url), alternative_service,
rchdc7b9052016-03-17 20:51:5011423 expiration);
[email protected]3912662a32011-10-04 00:51:1111424
bnc691fda62016-08-12 00:43:1611425 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]49639fa2011-12-20 23:22:4111426 TestCompletionCallback callback;
[email protected]3912662a32011-10-04 00:51:1111427
bnc691fda62016-08-12 00:43:1611428 int rv = trans.Start(&unrestricted_port_request, callback.callback(),
tfarina42834112016-09-22 13:38:2011429 NetLogWithSource());
robpercival214763f2016-07-01 23:27:0111430 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]3912662a32011-10-04 00:51:1111431 // Valid change to restricted port should pass.
robpercival214763f2016-07-01 23:27:0111432 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]3912662a32011-10-04 00:51:1111433}
11434
bnc55ff9da2015-08-19 18:42:3511435// Ensure that we are not allowed to redirect traffic via an alternate protocol
11436// to an unrestricted (port >= 1024) when the original traffic was on a
11437// restricted port (port < 1024). Ensure that we can redirect in all other
11438// cases.
bncd16676a2016-07-20 16:23:0111439TEST_F(HttpNetworkTransactionTest, AlternateProtocolPortUnrestrictedAllowed2) {
[email protected]3912662a32011-10-04 00:51:1111440 HttpRequestInfo unrestricted_port_request;
11441 unrestricted_port_request.method = "GET";
bncb26024382016-06-29 02:39:4511442 unrestricted_port_request.url = GURL("https://www.example.org:1024/");
[email protected]3912662a32011-10-04 00:51:1111443 unrestricted_port_request.load_flags = 0;
11444
[email protected]d973e99a2012-02-17 21:02:3611445 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
[email protected]3912662a32011-10-04 00:51:1111446 StaticSocketDataProvider first_data;
11447 first_data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:0711448 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
[email protected]3912662a32011-10-04 00:51:1111449
11450 MockRead data_reads[] = {
11451 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
11452 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:0611453 MockRead(ASYNC, OK),
[email protected]3912662a32011-10-04 00:51:1111454 };
11455 StaticSocketDataProvider second_data(
11456 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0711457 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
[email protected]3912662a32011-10-04 00:51:1111458
bncb26024382016-06-29 02:39:4511459 SSLSocketDataProvider ssl(ASYNC, OK);
11460 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
11461
danakj1fd259a02016-04-16 03:17:0911462 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]3912662a32011-10-04 00:51:1111463
bnc525e175a2016-06-20 12:36:4011464 HttpServerProperties* http_server_properties =
[email protected]17291a022011-10-10 07:32:5311465 session->http_server_properties();
bnc0bbb02622015-07-23 10:06:2211466 const int kUnrestrictedAlternatePort = 1025;
bnc3472afd2016-11-17 15:27:2111467 AlternativeService alternative_service(kProtoHTTP2, "www.example.org",
11468 kUnrestrictedAlternatePort);
bnc7dc7e1b42015-07-28 14:43:1211469 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:2111470 http_server_properties->SetHttp2AlternativeService(
zhongyi3d4a55e72016-04-22 20:36:4611471 url::SchemeHostPort(unrestricted_port_request.url), alternative_service,
rchdc7b9052016-03-17 20:51:5011472 expiration);
[email protected]3912662a32011-10-04 00:51:1111473
bnc691fda62016-08-12 00:43:1611474 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]49639fa2011-12-20 23:22:4111475 TestCompletionCallback callback;
[email protected]3912662a32011-10-04 00:51:1111476
bnc691fda62016-08-12 00:43:1611477 int rv = trans.Start(&unrestricted_port_request, callback.callback(),
tfarina42834112016-09-22 13:38:2011478 NetLogWithSource());
robpercival214763f2016-07-01 23:27:0111479 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]3912662a32011-10-04 00:51:1111480 // Valid change to an unrestricted port should pass.
robpercival214763f2016-07-01 23:27:0111481 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]3912662a32011-10-04 00:51:1111482}
11483
bnc55ff9da2015-08-19 18:42:3511484// Ensure that we are not allowed to redirect traffic via an alternate protocol
11485// to an unsafe port, and that we resume the second HttpStreamFactoryImpl::Job
11486// once the alternate protocol request fails.
bncd16676a2016-07-20 16:23:0111487TEST_F(HttpNetworkTransactionTest, AlternateProtocolUnsafeBlocked) {
[email protected]eb6234e2012-01-19 01:50:0211488 HttpRequestInfo request;
11489 request.method = "GET";
bncce36dca22015-04-21 22:11:2311490 request.url = GURL("http://www.example.org/");
[email protected]eb6234e2012-01-19 01:50:0211491
11492 // The alternate protocol request will error out before we attempt to connect,
11493 // so only the standard HTTP request will try to connect.
11494 MockRead data_reads[] = {
11495 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
11496 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:0611497 MockRead(ASYNC, OK),
[email protected]eb6234e2012-01-19 01:50:0211498 };
11499 StaticSocketDataProvider data(
11500 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0711501 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]eb6234e2012-01-19 01:50:0211502
danakj1fd259a02016-04-16 03:17:0911503 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]eb6234e2012-01-19 01:50:0211504
bnc525e175a2016-06-20 12:36:4011505 HttpServerProperties* http_server_properties =
[email protected]eb6234e2012-01-19 01:50:0211506 session->http_server_properties();
11507 const int kUnsafePort = 7;
bnc3472afd2016-11-17 15:27:2111508 AlternativeService alternative_service(kProtoHTTP2, "www.example.org",
11509 kUnsafePort);
bnc7dc7e1b42015-07-28 14:43:1211510 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:2111511 http_server_properties->SetHttp2AlternativeService(
zhongyi3d4a55e72016-04-22 20:36:4611512 url::SchemeHostPort(request.url), alternative_service, expiration);
[email protected]eb6234e2012-01-19 01:50:0211513
bnc691fda62016-08-12 00:43:1611514 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]eb6234e2012-01-19 01:50:0211515 TestCompletionCallback callback;
11516
tfarina42834112016-09-22 13:38:2011517 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0111518 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]eb6234e2012-01-19 01:50:0211519 // The HTTP request should succeed.
robpercival214763f2016-07-01 23:27:0111520 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]eb6234e2012-01-19 01:50:0211521
bnc691fda62016-08-12 00:43:1611522 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5211523 ASSERT_TRUE(response);
11524 ASSERT_TRUE(response->headers);
[email protected]eb6234e2012-01-19 01:50:0211525 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
11526
11527 std::string response_data;
bnc691fda62016-08-12 00:43:1611528 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
[email protected]eb6234e2012-01-19 01:50:0211529 EXPECT_EQ("hello world", response_data);
11530}
11531
bncd16676a2016-07-20 16:23:0111532TEST_F(HttpNetworkTransactionTest, UseAlternateProtocolForNpnSpdy) {
[email protected]2ff8b312010-04-26 22:20:5411533 HttpRequestInfo request;
11534 request.method = "GET";
bncb26024382016-06-29 02:39:4511535 request.url = GURL("https://www.example.org/");
[email protected]2ff8b312010-04-26 22:20:5411536
11537 MockRead data_reads[] = {
bncc958faa2015-07-31 18:14:5211538 MockRead("HTTP/1.1 200 OK\r\n"),
bnc2df4b522016-07-08 18:17:4311539 MockRead(kAlternativeServiceHttpHeader),
bncc958faa2015-07-31 18:14:5211540 MockRead("\r\n"),
11541 MockRead("hello world"),
11542 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
11543 MockRead(ASYNC, OK)};
[email protected]2ff8b312010-04-26 22:20:5411544
11545 StaticSocketDataProvider first_transaction(
11546 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0711547 session_deps_.socket_factory->AddSocketDataProvider(&first_transaction);
bncb26024382016-06-29 02:39:4511548 SSLSocketDataProvider ssl_http11(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3611549 ssl_http11.next_proto = kProtoHTTP11;
bncb26024382016-06-29 02:39:4511550 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_http11);
[email protected]2ff8b312010-04-26 22:20:5411551
bnc032658ba2016-09-26 18:17:1511552 AddSSLSocketData();
[email protected]2ff8b312010-04-26 22:20:5411553
bncdf80d44fd2016-07-15 20:27:4111554 SpdySerializedFrame req(
bncb26024382016-06-29 02:39:4511555 spdy_util_.ConstructSpdyGet("https://www.example.org/", 1, LOWEST));
bncdf80d44fd2016-07-15 20:27:4111556 MockWrite spdy_writes[] = {CreateMockWrite(req, 0)};
[email protected]2ff8b312010-04-26 22:20:5411557
bnc42331402016-07-25 13:36:1511558 SpdySerializedFrame resp(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
bncdf80d44fd2016-07-15 20:27:4111559 SpdySerializedFrame data(spdy_util_.ConstructSpdyDataFrame(1, true));
[email protected]2ff8b312010-04-26 22:20:5411560 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:4111561 CreateMockRead(resp, 1), CreateMockRead(data, 2), MockRead(ASYNC, 0, 3),
[email protected]2ff8b312010-04-26 22:20:5411562 };
11563
rch8e6c6c42015-05-01 14:05:1311564 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
11565 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:0711566 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]2ff8b312010-04-26 22:20:5411567
[email protected]d973e99a2012-02-17 21:02:3611568 MockConnect never_finishing_connect(SYNCHRONOUS, ERR_IO_PENDING);
[email protected]2d6728692011-03-12 01:39:5511569 StaticSocketDataProvider hanging_non_alternate_protocol_socket(
11570 NULL, 0, NULL, 0);
11571 hanging_non_alternate_protocol_socket.set_connect_data(
11572 never_finishing_connect);
[email protected]bb88e1d32013-05-03 23:11:0711573 session_deps_.socket_factory->AddSocketDataProvider(
[email protected]2d6728692011-03-12 01:39:5511574 &hanging_non_alternate_protocol_socket);
11575
[email protected]49639fa2011-12-20 23:22:4111576 TestCompletionCallback callback;
[email protected]2ff8b312010-04-26 22:20:5411577
danakj1fd259a02016-04-16 03:17:0911578 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc87dcefc2017-05-25 12:47:5811579 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:1911580 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]2ff8b312010-04-26 22:20:5411581
tfarina42834112016-09-22 13:38:2011582 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0111583 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
11584 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]2ff8b312010-04-26 22:20:5411585
11586 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5211587 ASSERT_TRUE(response);
11588 ASSERT_TRUE(response->headers);
[email protected]2ff8b312010-04-26 22:20:5411589 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
11590
11591 std::string response_data;
robpercival214763f2016-07-01 23:27:0111592 ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
[email protected]2ff8b312010-04-26 22:20:5411593 EXPECT_EQ("hello world", response_data);
11594
bnc87dcefc2017-05-25 12:47:5811595 trans =
Jeremy Roman0579ed62017-08-29 15:56:1911596 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]2ff8b312010-04-26 22:20:5411597
tfarina42834112016-09-22 13:38:2011598 rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0111599 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
11600 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]2ff8b312010-04-26 22:20:5411601
11602 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5211603 ASSERT_TRUE(response);
11604 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0211605 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]65041fa2010-05-21 06:56:5311606 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5211607 EXPECT_TRUE(response->was_alpn_negotiated);
[email protected]2ff8b312010-04-26 22:20:5411608
robpercival214763f2016-07-01 23:27:0111609 ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
[email protected]2ff8b312010-04-26 22:20:5411610 EXPECT_EQ("hello!", response_data);
[email protected]2ff8b312010-04-26 22:20:5411611}
11612
bncd16676a2016-07-20 16:23:0111613TEST_F(HttpNetworkTransactionTest, AlternateProtocolWithSpdyLateBinding) {
[email protected]2d6728692011-03-12 01:39:5511614 HttpRequestInfo request;
11615 request.method = "GET";
bncb26024382016-06-29 02:39:4511616 request.url = GURL("https://www.example.org/");
[email protected]2d6728692011-03-12 01:39:5511617
bncb26024382016-06-29 02:39:4511618 // First transaction receives Alt-Svc header over HTTP/1.1.
[email protected]2d6728692011-03-12 01:39:5511619 MockRead data_reads[] = {
bncc958faa2015-07-31 18:14:5211620 MockRead("HTTP/1.1 200 OK\r\n"),
bnc2df4b522016-07-08 18:17:4311621 MockRead(kAlternativeServiceHttpHeader),
bncc958faa2015-07-31 18:14:5211622 MockRead("\r\n"),
11623 MockRead("hello world"),
11624 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
11625 MockRead(ASYNC, OK),
[email protected]2d6728692011-03-12 01:39:5511626 };
11627
bncb26024382016-06-29 02:39:4511628 StaticSocketDataProvider http11_data(data_reads, arraysize(data_reads), NULL,
11629 0);
11630 session_deps_.socket_factory->AddSocketDataProvider(&http11_data);
[email protected]2d6728692011-03-12 01:39:5511631
bncb26024382016-06-29 02:39:4511632 SSLSocketDataProvider ssl_http11(ASYNC, OK);
Ryan Sleevi4f832092017-11-21 23:25:4911633 ssl_http11.ssl_info.cert =
11634 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem");
11635 ASSERT_TRUE(ssl_http11.ssl_info.cert);
bncb26024382016-06-29 02:39:4511636 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_http11);
11637
11638 // Second transaction starts an alternative and a non-alternative Job.
11639 // Both sockets hang.
[email protected]d973e99a2012-02-17 21:02:3611640 MockConnect never_finishing_connect(SYNCHRONOUS, ERR_IO_PENDING);
mmenkecc2298e2015-12-07 18:20:1811641 StaticSocketDataProvider hanging_socket1(NULL, 0, NULL, 0);
11642 hanging_socket1.set_connect_data(never_finishing_connect);
mmenkecc2298e2015-12-07 18:20:1811643 session_deps_.socket_factory->AddSocketDataProvider(&hanging_socket1);
11644
11645 StaticSocketDataProvider hanging_socket2(NULL, 0, NULL, 0);
11646 hanging_socket2.set_connect_data(never_finishing_connect);
11647 session_deps_.socket_factory->AddSocketDataProvider(&hanging_socket2);
[email protected]2d6728692011-03-12 01:39:5511648
bncb26024382016-06-29 02:39:4511649 // Third transaction starts an alternative and a non-alternative job.
11650 // The non-alternative job hangs, but the alternative one succeeds.
11651 // The second transaction, still pending, binds to this socket.
bncdf80d44fd2016-07-15 20:27:4111652 SpdySerializedFrame req1(
bncb26024382016-06-29 02:39:4511653 spdy_util_.ConstructSpdyGet("https://www.example.org/", 1, LOWEST));
bncdf80d44fd2016-07-15 20:27:4111654 SpdySerializedFrame req2(
bncb26024382016-06-29 02:39:4511655 spdy_util_.ConstructSpdyGet("https://www.example.org/", 3, LOWEST));
[email protected]2d6728692011-03-12 01:39:5511656 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:4111657 CreateMockWrite(req1, 0), CreateMockWrite(req2, 1),
[email protected]2d6728692011-03-12 01:39:5511658 };
bnc42331402016-07-25 13:36:1511659 SpdySerializedFrame resp1(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
bncdf80d44fd2016-07-15 20:27:4111660 SpdySerializedFrame data1(spdy_util_.ConstructSpdyDataFrame(1, true));
bnc42331402016-07-25 13:36:1511661 SpdySerializedFrame resp2(spdy_util_.ConstructSpdyGetReply(NULL, 0, 3));
bncdf80d44fd2016-07-15 20:27:4111662 SpdySerializedFrame data2(spdy_util_.ConstructSpdyDataFrame(3, true));
[email protected]2d6728692011-03-12 01:39:5511663 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:4111664 CreateMockRead(resp1, 2), CreateMockRead(data1, 3),
11665 CreateMockRead(resp2, 4), CreateMockRead(data2, 5),
rch8e6c6c42015-05-01 14:05:1311666 MockRead(ASYNC, 0, 6),
[email protected]2d6728692011-03-12 01:39:5511667 };
11668
rch8e6c6c42015-05-01 14:05:1311669 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
11670 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:0711671 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]2d6728692011-03-12 01:39:5511672
bnc032658ba2016-09-26 18:17:1511673 AddSSLSocketData();
bncb26024382016-06-29 02:39:4511674
mmenkecc2298e2015-12-07 18:20:1811675 StaticSocketDataProvider hanging_socket3(NULL, 0, NULL, 0);
11676 hanging_socket3.set_connect_data(never_finishing_connect);
11677 session_deps_.socket_factory->AddSocketDataProvider(&hanging_socket3);
[email protected]2d6728692011-03-12 01:39:5511678
danakj1fd259a02016-04-16 03:17:0911679 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]49639fa2011-12-20 23:22:4111680 TestCompletionCallback callback1;
[email protected]90499482013-06-01 00:39:5011681 HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
[email protected]2d6728692011-03-12 01:39:5511682
tfarina42834112016-09-22 13:38:2011683 int rv = trans1.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0111684 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
11685 EXPECT_THAT(callback1.WaitForResult(), IsOk());
[email protected]2d6728692011-03-12 01:39:5511686
11687 const HttpResponseInfo* response = trans1.GetResponseInfo();
wezca1070932016-05-26 20:30:5211688 ASSERT_TRUE(response);
11689 ASSERT_TRUE(response->headers);
[email protected]2d6728692011-03-12 01:39:5511690 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
11691
11692 std::string response_data;
robpercival214763f2016-07-01 23:27:0111693 ASSERT_THAT(ReadTransaction(&trans1, &response_data), IsOk());
[email protected]2d6728692011-03-12 01:39:5511694 EXPECT_EQ("hello world", response_data);
11695
[email protected]49639fa2011-12-20 23:22:4111696 TestCompletionCallback callback2;
[email protected]90499482013-06-01 00:39:5011697 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:2011698 rv = trans2.Start(&request, callback2.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0111699 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2d6728692011-03-12 01:39:5511700
[email protected]49639fa2011-12-20 23:22:4111701 TestCompletionCallback callback3;
[email protected]90499482013-06-01 00:39:5011702 HttpNetworkTransaction trans3(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:2011703 rv = trans3.Start(&request, callback3.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0111704 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2d6728692011-03-12 01:39:5511705
robpercival214763f2016-07-01 23:27:0111706 EXPECT_THAT(callback2.WaitForResult(), IsOk());
11707 EXPECT_THAT(callback3.WaitForResult(), IsOk());
[email protected]2d6728692011-03-12 01:39:5511708
11709 response = trans2.GetResponseInfo();
wezca1070932016-05-26 20:30:5211710 ASSERT_TRUE(response);
11711 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0211712 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]2d6728692011-03-12 01:39:5511713 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5211714 EXPECT_TRUE(response->was_alpn_negotiated);
robpercival214763f2016-07-01 23:27:0111715 ASSERT_THAT(ReadTransaction(&trans2, &response_data), IsOk());
[email protected]2d6728692011-03-12 01:39:5511716 EXPECT_EQ("hello!", response_data);
11717
11718 response = trans3.GetResponseInfo();
wezca1070932016-05-26 20:30:5211719 ASSERT_TRUE(response);
11720 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0211721 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]2d6728692011-03-12 01:39:5511722 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5211723 EXPECT_TRUE(response->was_alpn_negotiated);
robpercival214763f2016-07-01 23:27:0111724 ASSERT_THAT(ReadTransaction(&trans3, &response_data), IsOk());
[email protected]2d6728692011-03-12 01:39:5511725 EXPECT_EQ("hello!", response_data);
[email protected]2d6728692011-03-12 01:39:5511726}
11727
bncd16676a2016-07-20 16:23:0111728TEST_F(HttpNetworkTransactionTest, StallAlternativeServiceForNpnSpdy) {
[email protected]2d6728692011-03-12 01:39:5511729 HttpRequestInfo request;
11730 request.method = "GET";
bncb26024382016-06-29 02:39:4511731 request.url = GURL("https://www.example.org/");
[email protected]2d6728692011-03-12 01:39:5511732
11733 MockRead data_reads[] = {
bncc958faa2015-07-31 18:14:5211734 MockRead("HTTP/1.1 200 OK\r\n"),
bnc2df4b522016-07-08 18:17:4311735 MockRead(kAlternativeServiceHttpHeader),
bncc958faa2015-07-31 18:14:5211736 MockRead("\r\n"),
11737 MockRead("hello world"),
11738 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
11739 MockRead(ASYNC, OK),
[email protected]2d6728692011-03-12 01:39:5511740 };
11741
11742 StaticSocketDataProvider first_transaction(
11743 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0711744 session_deps_.socket_factory->AddSocketDataProvider(&first_transaction);
[email protected]2d6728692011-03-12 01:39:5511745
[email protected]8ddf8322012-02-23 18:08:0611746 SSLSocketDataProvider ssl(ASYNC, OK);
Ryan Sleevi4f832092017-11-21 23:25:4911747 ssl.ssl_info.cert =
11748 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem");
11749 ASSERT_TRUE(ssl.ssl_info.cert);
[email protected]bb88e1d32013-05-03 23:11:0711750 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]2d6728692011-03-12 01:39:5511751
[email protected]d973e99a2012-02-17 21:02:3611752 MockConnect never_finishing_connect(SYNCHRONOUS, ERR_IO_PENDING);
[email protected]2d6728692011-03-12 01:39:5511753 StaticSocketDataProvider hanging_alternate_protocol_socket(
11754 NULL, 0, NULL, 0);
11755 hanging_alternate_protocol_socket.set_connect_data(
11756 never_finishing_connect);
[email protected]bb88e1d32013-05-03 23:11:0711757 session_deps_.socket_factory->AddSocketDataProvider(
[email protected]2d6728692011-03-12 01:39:5511758 &hanging_alternate_protocol_socket);
11759
bncb26024382016-06-29 02:39:4511760 // 2nd request is just a copy of the first one, over HTTP/1.1 again.
mmenkecc2298e2015-12-07 18:20:1811761 StaticSocketDataProvider second_transaction(data_reads, arraysize(data_reads),
11762 NULL, 0);
11763 session_deps_.socket_factory->AddSocketDataProvider(&second_transaction);
bncb26024382016-06-29 02:39:4511764 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]2d6728692011-03-12 01:39:5511765
[email protected]49639fa2011-12-20 23:22:4111766 TestCompletionCallback callback;
[email protected]2d6728692011-03-12 01:39:5511767
danakj1fd259a02016-04-16 03:17:0911768 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc87dcefc2017-05-25 12:47:5811769 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:1911770 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]2d6728692011-03-12 01:39:5511771
tfarina42834112016-09-22 13:38:2011772 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0111773 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
11774 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]2d6728692011-03-12 01:39:5511775
11776 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5211777 ASSERT_TRUE(response);
11778 ASSERT_TRUE(response->headers);
[email protected]2d6728692011-03-12 01:39:5511779 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
11780
11781 std::string response_data;
robpercival214763f2016-07-01 23:27:0111782 ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
[email protected]2d6728692011-03-12 01:39:5511783 EXPECT_EQ("hello world", response_data);
11784
bnc87dcefc2017-05-25 12:47:5811785 trans =
Jeremy Roman0579ed62017-08-29 15:56:1911786 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]2d6728692011-03-12 01:39:5511787
tfarina42834112016-09-22 13:38:2011788 rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0111789 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
11790 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]2d6728692011-03-12 01:39:5511791
11792 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5211793 ASSERT_TRUE(response);
11794 ASSERT_TRUE(response->headers);
[email protected]2d6728692011-03-12 01:39:5511795 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
11796 EXPECT_FALSE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5211797 EXPECT_FALSE(response->was_alpn_negotiated);
[email protected]2d6728692011-03-12 01:39:5511798
robpercival214763f2016-07-01 23:27:0111799 ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
[email protected]2d6728692011-03-12 01:39:5511800 EXPECT_EQ("hello world", response_data);
[email protected]2d6728692011-03-12 01:39:5511801}
11802
[email protected]631f1322010-04-30 17:59:1111803class CapturingProxyResolver : public ProxyResolver {
11804 public:
Chris Watkins7a41d3552017-12-01 02:13:2711805 CapturingProxyResolver() = default;
11806 ~CapturingProxyResolver() override = default;
[email protected]631f1322010-04-30 17:59:1111807
dchengb03027d2014-10-21 12:00:2011808 int GetProxyForURL(const GURL& url,
11809 ProxyInfo* results,
11810 const CompletionCallback& callback,
maksim.sisov7e157262016-10-20 11:19:5511811 std::unique_ptr<Request>* request,
tfarina42834112016-09-22 13:38:2011812 const NetLogWithSource& net_log) override {
[email protected]fae7669f2010-08-02 21:49:4011813 ProxyServer proxy_server(ProxyServer::SCHEME_HTTP,
11814 HostPortPair("myproxy", 80));
[email protected]d911f1b2010-05-05 22:39:4211815 results->UseProxyServer(proxy_server);
[email protected]631f1322010-04-30 17:59:1111816 resolved_.push_back(url);
[email protected]d911f1b2010-05-05 22:39:4211817 return OK;
[email protected]631f1322010-04-30 17:59:1111818 }
11819
[email protected]24476402010-07-20 20:55:1711820 const std::vector<GURL>& resolved() const { return resolved_; }
11821
11822 private:
[email protected]631f1322010-04-30 17:59:1111823 std::vector<GURL> resolved_;
11824
11825 DISALLOW_COPY_AND_ASSIGN(CapturingProxyResolver);
11826};
11827
sammce64b2362015-04-29 03:50:2311828class CapturingProxyResolverFactory : public ProxyResolverFactory {
11829 public:
11830 explicit CapturingProxyResolverFactory(CapturingProxyResolver* resolver)
11831 : ProxyResolverFactory(false), resolver_(resolver) {}
11832
11833 int CreateProxyResolver(
11834 const scoped_refptr<ProxyResolverScriptData>& pac_script,
danakj1fd259a02016-04-16 03:17:0911835 std::unique_ptr<ProxyResolver>* resolver,
sammce64b2362015-04-29 03:50:2311836 const net::CompletionCallback& callback,
danakj1fd259a02016-04-16 03:17:0911837 std::unique_ptr<Request>* request) override {
Jeremy Roman0579ed62017-08-29 15:56:1911838 *resolver = std::make_unique<ForwardingProxyResolver>(resolver_);
sammce64b2362015-04-29 03:50:2311839 return OK;
11840 }
11841
11842 private:
11843 ProxyResolver* resolver_;
11844};
11845
bnc2e884782016-08-11 19:45:1911846// Test that proxy is resolved using the origin url,
11847// regardless of the alternative server.
11848TEST_F(HttpNetworkTransactionTest, UseOriginNotAlternativeForProxy) {
11849 // Configure proxy to bypass www.example.org, which is the origin URL.
11850 ProxyConfig proxy_config;
11851 proxy_config.proxy_rules().ParseFromString("myproxy:70");
11852 proxy_config.proxy_rules().bypass_rules.AddRuleFromString("www.example.org");
11853 auto proxy_config_service =
Jeremy Roman0579ed62017-08-29 15:56:1911854 std::make_unique<ProxyConfigServiceFixed>(proxy_config);
bnc2e884782016-08-11 19:45:1911855
11856 CapturingProxyResolver capturing_proxy_resolver;
Jeremy Roman0579ed62017-08-29 15:56:1911857 auto proxy_resolver_factory = std::make_unique<CapturingProxyResolverFactory>(
bnc2e884782016-08-11 19:45:1911858 &capturing_proxy_resolver);
11859
11860 TestNetLog net_log;
11861
Jeremy Roman0579ed62017-08-29 15:56:1911862 session_deps_.proxy_service = std::make_unique<ProxyService>(
bnc2e884782016-08-11 19:45:1911863 std::move(proxy_config_service), std::move(proxy_resolver_factory),
11864 &net_log);
11865
11866 session_deps_.net_log = &net_log;
11867
11868 // Configure alternative service with a hostname that is not bypassed by the
11869 // proxy.
11870 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
11871 HttpServerProperties* http_server_properties =
11872 session->http_server_properties();
11873 url::SchemeHostPort server("https", "www.example.org", 443);
11874 HostPortPair alternative("www.example.com", 443);
bnc3472afd2016-11-17 15:27:2111875 AlternativeService alternative_service(kProtoHTTP2, alternative);
bnc2e884782016-08-11 19:45:1911876 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:2111877 http_server_properties->SetHttp2AlternativeService(
11878 server, alternative_service, expiration);
bnc2e884782016-08-11 19:45:1911879
11880 // Non-alternative job should hang.
11881 MockConnect never_finishing_connect(SYNCHRONOUS, ERR_IO_PENDING);
11882 StaticSocketDataProvider hanging_alternate_protocol_socket(nullptr, 0,
11883 nullptr, 0);
11884 hanging_alternate_protocol_socket.set_connect_data(never_finishing_connect);
11885 session_deps_.socket_factory->AddSocketDataProvider(
11886 &hanging_alternate_protocol_socket);
11887
bnc032658ba2016-09-26 18:17:1511888 AddSSLSocketData();
bnc2e884782016-08-11 19:45:1911889
11890 HttpRequestInfo request;
11891 request.method = "GET";
11892 request.url = GURL("https://www.example.org/");
11893 request.load_flags = 0;
11894
11895 SpdySerializedFrame req(
11896 spdy_util_.ConstructSpdyGet("https://www.example.org/", 1, LOWEST));
11897
11898 MockWrite spdy_writes[] = {CreateMockWrite(req, 0)};
11899
11900 SpdySerializedFrame resp(spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
11901 SpdySerializedFrame data(spdy_util_.ConstructSpdyDataFrame(1, true));
11902 MockRead spdy_reads[] = {
11903 CreateMockRead(resp, 1), CreateMockRead(data, 2), MockRead(ASYNC, 0, 3),
11904 };
11905
11906 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
11907 arraysize(spdy_writes));
11908 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
11909
11910 TestCompletionCallback callback;
11911
11912 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
11913
tfarina42834112016-09-22 13:38:2011914 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
bnc2e884782016-08-11 19:45:1911915 EXPECT_THAT(callback.GetResult(rv), IsOk());
11916
11917 const HttpResponseInfo* response = trans.GetResponseInfo();
11918 ASSERT_TRUE(response);
11919 ASSERT_TRUE(response->headers);
11920 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
11921 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5211922 EXPECT_TRUE(response->was_alpn_negotiated);
bnc2e884782016-08-11 19:45:1911923
11924 std::string response_data;
11925 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
11926 EXPECT_EQ("hello!", response_data);
11927
11928 // Origin host bypasses proxy, no resolution should have happened.
11929 ASSERT_TRUE(capturing_proxy_resolver.resolved().empty());
11930}
11931
bncd16676a2016-07-20 16:23:0111932TEST_F(HttpNetworkTransactionTest, UseAlternativeServiceForTunneledNpnSpdy) {
[email protected]631f1322010-04-30 17:59:1111933 ProxyConfig proxy_config;
[email protected]d911f1b2010-05-05 22:39:4211934 proxy_config.set_auto_detect(true);
11935 proxy_config.set_pac_url(GURL("http://fooproxyurl"));
[email protected]2227c692010-05-04 15:36:1111936
sammc5dd160c2015-04-02 02:43:1311937 CapturingProxyResolver capturing_proxy_resolver;
Jeremy Roman0579ed62017-08-29 15:56:1911938 session_deps_.proxy_service = std::make_unique<ProxyService>(
11939 std::make_unique<ProxyConfigServiceFixed>(proxy_config),
11940 std::make_unique<CapturingProxyResolverFactory>(
bnc87dcefc2017-05-25 12:47:5811941 &capturing_proxy_resolver),
11942 nullptr);
vishal.b62985ca92015-04-17 08:45:5111943 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:0711944 session_deps_.net_log = &net_log;
[email protected]631f1322010-04-30 17:59:1111945
11946 HttpRequestInfo request;
11947 request.method = "GET";
bncb26024382016-06-29 02:39:4511948 request.url = GURL("https://www.example.org/");
[email protected]631f1322010-04-30 17:59:1111949
11950 MockRead data_reads[] = {
bncc958faa2015-07-31 18:14:5211951 MockRead("HTTP/1.1 200 OK\r\n"),
bnc2df4b522016-07-08 18:17:4311952 MockRead(kAlternativeServiceHttpHeader),
bncc958faa2015-07-31 18:14:5211953 MockRead("\r\n"),
11954 MockRead("hello world"),
11955 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
11956 MockRead(ASYNC, OK),
[email protected]631f1322010-04-30 17:59:1111957 };
11958
11959 StaticSocketDataProvider first_transaction(
11960 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0711961 session_deps_.socket_factory->AddSocketDataProvider(&first_transaction);
bncb26024382016-06-29 02:39:4511962 SSLSocketDataProvider ssl_http11(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3611963 ssl_http11.next_proto = kProtoHTTP11;
bncb26024382016-06-29 02:39:4511964 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_http11);
[email protected]631f1322010-04-30 17:59:1111965
bnc032658ba2016-09-26 18:17:1511966 AddSSLSocketData();
[email protected]631f1322010-04-30 17:59:1111967
bncdf80d44fd2016-07-15 20:27:4111968 SpdySerializedFrame req(
bncb26024382016-06-29 02:39:4511969 spdy_util_.ConstructSpdyGet("https://www.example.org/", 1, LOWEST));
[email protected]631f1322010-04-30 17:59:1111970 MockWrite spdy_writes[] = {
rch8e6c6c42015-05-01 14:05:1311971 MockWrite(ASYNC, 0,
bnc8bef8da22016-05-30 01:28:2511972 "CONNECT www.example.org:443 HTTP/1.1\r\n"
11973 "Host: www.example.org:443\r\n"
rch8e6c6c42015-05-01 14:05:1311974 "Proxy-Connection: keep-alive\r\n\r\n"),
bncdf80d44fd2016-07-15 20:27:4111975 CreateMockWrite(req, 2),
[email protected]631f1322010-04-30 17:59:1111976 };
11977
[email protected]d911f1b2010-05-05 22:39:4211978 const char kCONNECTResponse[] = "HTTP/1.1 200 Connected\r\n\r\n";
11979
bnc42331402016-07-25 13:36:1511980 SpdySerializedFrame resp(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
bncdf80d44fd2016-07-15 20:27:4111981 SpdySerializedFrame data(spdy_util_.ConstructSpdyDataFrame(1, true));
[email protected]631f1322010-04-30 17:59:1111982 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:4111983 MockRead(ASYNC, 1, kCONNECTResponse), CreateMockRead(resp, 3),
11984 CreateMockRead(data, 4), MockRead(SYNCHRONOUS, ERR_IO_PENDING, 5),
[email protected]631f1322010-04-30 17:59:1111985 };
11986
rch8e6c6c42015-05-01 14:05:1311987 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
11988 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:0711989 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]631f1322010-04-30 17:59:1111990
[email protected]d973e99a2012-02-17 21:02:3611991 MockConnect never_finishing_connect(SYNCHRONOUS, ERR_IO_PENDING);
[email protected]2d6728692011-03-12 01:39:5511992 StaticSocketDataProvider hanging_non_alternate_protocol_socket(
11993 NULL, 0, NULL, 0);
11994 hanging_non_alternate_protocol_socket.set_connect_data(
11995 never_finishing_connect);
[email protected]bb88e1d32013-05-03 23:11:0711996 session_deps_.socket_factory->AddSocketDataProvider(
[email protected]2d6728692011-03-12 01:39:5511997 &hanging_non_alternate_protocol_socket);
11998
[email protected]49639fa2011-12-20 23:22:4111999 TestCompletionCallback callback;
[email protected]631f1322010-04-30 17:59:1112000
danakj1fd259a02016-04-16 03:17:0912001 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc87dcefc2017-05-25 12:47:5812002 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:1912003 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]631f1322010-04-30 17:59:1112004
tfarina42834112016-09-22 13:38:2012005 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
mmenkea2dcd3bf2016-08-16 21:49:4112006 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
12007 EXPECT_THAT(callback.WaitForResult(), IsOk());
12008
12009 const HttpResponseInfo* response = trans->GetResponseInfo();
12010 ASSERT_TRUE(response);
12011 ASSERT_TRUE(response->headers);
12012 EXPECT_EQ("HTTP/0.9 200 OK", response->headers->GetStatusLine());
12013 EXPECT_FALSE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5212014 EXPECT_TRUE(response->was_alpn_negotiated);
mmenkea2dcd3bf2016-08-16 21:49:4112015
12016 std::string response_data;
12017 ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
12018 EXPECT_EQ("hello world", response_data);
[email protected]631f1322010-04-30 17:59:1112019
bnc87dcefc2017-05-25 12:47:5812020 trans =
Jeremy Roman0579ed62017-08-29 15:56:1912021 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]631f1322010-04-30 17:59:1112022
tfarina42834112016-09-22 13:38:2012023 rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0112024 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
12025 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]631f1322010-04-30 17:59:1112026
mmenkea2dcd3bf2016-08-16 21:49:4112027 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5212028 ASSERT_TRUE(response);
12029 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0212030 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]65041fa2010-05-21 06:56:5312031 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5212032 EXPECT_TRUE(response->was_alpn_negotiated);
[email protected]631f1322010-04-30 17:59:1112033
robpercival214763f2016-07-01 23:27:0112034 ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
[email protected]631f1322010-04-30 17:59:1112035 EXPECT_EQ("hello!", response_data);
bncb26024382016-06-29 02:39:4512036 ASSERT_EQ(2u, capturing_proxy_resolver.resolved().size());
12037 EXPECT_EQ("https://www.example.org/",
sammc5dd160c2015-04-02 02:43:1312038 capturing_proxy_resolver.resolved()[0].spec());
bncce36dca22015-04-21 22:11:2312039 EXPECT_EQ("https://www.example.org/",
sammc5dd160c2015-04-02 02:43:1312040 capturing_proxy_resolver.resolved()[1].spec());
[email protected]631f1322010-04-30 17:59:1112041
[email protected]029c83b62013-01-24 05:28:2012042 LoadTimingInfo load_timing_info;
12043 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
12044 TestLoadTimingNotReusedWithPac(load_timing_info,
12045 CONNECT_TIMING_HAS_SSL_TIMES);
[email protected]631f1322010-04-30 17:59:1112046}
[email protected]631f1322010-04-30 17:59:1112047
bncd16676a2016-07-20 16:23:0112048TEST_F(HttpNetworkTransactionTest,
bnc1c196c6e2016-05-28 13:51:4812049 UseAlternativeServiceForNpnSpdyWithExistingSpdySession) {
[email protected]2ff8b312010-04-26 22:20:5412050 HttpRequestInfo request;
12051 request.method = "GET";
bncb26024382016-06-29 02:39:4512052 request.url = GURL("https://www.example.org/");
[email protected]2ff8b312010-04-26 22:20:5412053
12054 MockRead data_reads[] = {
bncc958faa2015-07-31 18:14:5212055 MockRead("HTTP/1.1 200 OK\r\n"),
bnc2df4b522016-07-08 18:17:4312056 MockRead(kAlternativeServiceHttpHeader),
bncc958faa2015-07-31 18:14:5212057 MockRead("\r\n"),
12058 MockRead("hello world"),
12059 MockRead(ASYNC, OK),
[email protected]2ff8b312010-04-26 22:20:5412060 };
12061
12062 StaticSocketDataProvider first_transaction(
12063 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0712064 session_deps_.socket_factory->AddSocketDataProvider(&first_transaction);
bncb26024382016-06-29 02:39:4512065 SSLSocketDataProvider ssl_http11(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3612066 ssl_http11.next_proto = kProtoHTTP11;
bncb26024382016-06-29 02:39:4512067 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_http11);
[email protected]2ff8b312010-04-26 22:20:5412068
bnc032658ba2016-09-26 18:17:1512069 AddSSLSocketData();
[email protected]2ff8b312010-04-26 22:20:5412070
bncdf80d44fd2016-07-15 20:27:4112071 SpdySerializedFrame req(
bncb26024382016-06-29 02:39:4512072 spdy_util_.ConstructSpdyGet("https://www.example.org/", 1, LOWEST));
bncdf80d44fd2016-07-15 20:27:4112073 MockWrite spdy_writes[] = {CreateMockWrite(req, 0)};
[email protected]2ff8b312010-04-26 22:20:5412074
bnc42331402016-07-25 13:36:1512075 SpdySerializedFrame resp(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
bncdf80d44fd2016-07-15 20:27:4112076 SpdySerializedFrame data(spdy_util_.ConstructSpdyDataFrame(1, true));
[email protected]2ff8b312010-04-26 22:20:5412077 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:4112078 CreateMockRead(resp, 1), CreateMockRead(data, 2), MockRead(ASYNC, 0, 3),
[email protected]2ff8b312010-04-26 22:20:5412079 };
12080
rch8e6c6c42015-05-01 14:05:1312081 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
12082 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:0712083 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]2ff8b312010-04-26 22:20:5412084
[email protected]83039bb2011-12-09 18:43:5512085 TestCompletionCallback callback;
[email protected]2ff8b312010-04-26 22:20:5412086
danakj1fd259a02016-04-16 03:17:0912087 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]2ff8b312010-04-26 22:20:5412088
bnc87dcefc2017-05-25 12:47:5812089 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:1912090 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]2ff8b312010-04-26 22:20:5412091
tfarina42834112016-09-22 13:38:2012092 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0112093 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
12094 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]2ff8b312010-04-26 22:20:5412095
12096 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5212097 ASSERT_TRUE(response);
12098 ASSERT_TRUE(response->headers);
[email protected]2ff8b312010-04-26 22:20:5412099 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
12100
12101 std::string response_data;
robpercival214763f2016-07-01 23:27:0112102 ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
[email protected]2ff8b312010-04-26 22:20:5412103 EXPECT_EQ("hello world", response_data);
12104
12105 // Set up an initial SpdySession in the pool to reuse.
bnc8bef8da22016-05-30 01:28:2512106 HostPortPair host_port_pair("www.example.org", 443);
[email protected]e6d017652013-05-17 18:01:4012107 SpdySessionKey key(host_port_pair, ProxyServer::Direct(),
[email protected]314b03992014-04-01 01:28:5312108 PRIVACY_MODE_DISABLED);
[email protected]795cbf82013-07-22 09:37:2712109 base::WeakPtr<SpdySession> spdy_session =
Bence Béky0ef1556e2017-06-30 19:52:5212110 CreateSpdySession(session.get(), key, NetLogWithSource());
[email protected]02b0c342010-09-25 21:09:3812111
bnc87dcefc2017-05-25 12:47:5812112 trans =
Jeremy Roman0579ed62017-08-29 15:56:1912113 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]2ff8b312010-04-26 22:20:5412114
tfarina42834112016-09-22 13:38:2012115 rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0112116 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
12117 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]2ff8b312010-04-26 22:20:5412118
12119 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5212120 ASSERT_TRUE(response);
12121 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0212122 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]65041fa2010-05-21 06:56:5312123 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5212124 EXPECT_TRUE(response->was_alpn_negotiated);
[email protected]2ff8b312010-04-26 22:20:5412125
robpercival214763f2016-07-01 23:27:0112126 ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
[email protected]2ff8b312010-04-26 22:20:5412127 EXPECT_EQ("hello!", response_data);
[email protected]564b4912010-03-09 16:30:4212128}
12129
[email protected]044de0642010-06-17 10:42:1512130// GenerateAuthToken is a mighty big test.
12131// It tests all permutation of GenerateAuthToken behavior:
12132// - Synchronous and Asynchronous completion.
12133// - OK or error on completion.
12134// - Direct connection, non-authenticating proxy, and authenticating proxy.
12135// - HTTP or HTTPS backend (to include proxy tunneling).
12136// - Non-authenticating and authenticating backend.
12137//
[email protected]fe3b7dc2012-02-03 19:52:0912138// In all, there are 44 reasonable permuations (for example, if there are
[email protected]044de0642010-06-17 10:42:1512139// problems generating an auth token for an authenticating proxy, we don't
12140// need to test all permutations of the backend server).
12141//
12142// The test proceeds by going over each of the configuration cases, and
12143// potentially running up to three rounds in each of the tests. The TestConfig
12144// specifies both the configuration for the test as well as the expectations
12145// for the results.
bncd16676a2016-07-20 16:23:0112146TEST_F(HttpNetworkTransactionTest, GenerateAuthToken) {
[email protected]0b0bf032010-09-21 18:08:5012147 static const char kServer[] = "http://www.example.com";
12148 static const char kSecureServer[] = "https://www.example.com";
12149 static const char kProxy[] = "myproxy:70";
[email protected]044de0642010-06-17 10:42:1512150
12151 enum AuthTiming {
12152 AUTH_NONE,
12153 AUTH_SYNC,
12154 AUTH_ASYNC,
12155 };
12156
12157 const MockWrite kGet(
12158 "GET / HTTP/1.1\r\n"
12159 "Host: www.example.com\r\n"
12160 "Connection: keep-alive\r\n\r\n");
12161 const MockWrite kGetProxy(
12162 "GET http://www.example.com/ HTTP/1.1\r\n"
12163 "Host: www.example.com\r\n"
12164 "Proxy-Connection: keep-alive\r\n\r\n");
12165 const MockWrite kGetAuth(
12166 "GET / HTTP/1.1\r\n"
12167 "Host: www.example.com\r\n"
12168 "Connection: keep-alive\r\n"
12169 "Authorization: auth_token\r\n\r\n");
12170 const MockWrite kGetProxyAuth(
12171 "GET http://www.example.com/ HTTP/1.1\r\n"
12172 "Host: www.example.com\r\n"
12173 "Proxy-Connection: keep-alive\r\n"
12174 "Proxy-Authorization: auth_token\r\n\r\n");
12175 const MockWrite kGetAuthThroughProxy(
12176 "GET http://www.example.com/ HTTP/1.1\r\n"
12177 "Host: www.example.com\r\n"
12178 "Proxy-Connection: keep-alive\r\n"
12179 "Authorization: auth_token\r\n\r\n");
12180 const MockWrite kGetAuthWithProxyAuth(
12181 "GET http://www.example.com/ HTTP/1.1\r\n"
12182 "Host: www.example.com\r\n"
12183 "Proxy-Connection: keep-alive\r\n"
12184 "Proxy-Authorization: auth_token\r\n"
12185 "Authorization: auth_token\r\n\r\n");
12186 const MockWrite kConnect(
12187 "CONNECT www.example.com:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:1712188 "Host: www.example.com:443\r\n"
[email protected]044de0642010-06-17 10:42:1512189 "Proxy-Connection: keep-alive\r\n\r\n");
12190 const MockWrite kConnectProxyAuth(
12191 "CONNECT www.example.com:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:1712192 "Host: www.example.com:443\r\n"
[email protected]044de0642010-06-17 10:42:1512193 "Proxy-Connection: keep-alive\r\n"
12194 "Proxy-Authorization: auth_token\r\n\r\n");
12195
12196 const MockRead kSuccess(
12197 "HTTP/1.1 200 OK\r\n"
12198 "Content-Type: text/html; charset=iso-8859-1\r\n"
12199 "Content-Length: 3\r\n\r\n"
12200 "Yes");
12201 const MockRead kFailure(
12202 "Should not be called.");
12203 const MockRead kServerChallenge(
12204 "HTTP/1.1 401 Unauthorized\r\n"
12205 "WWW-Authenticate: Mock realm=server\r\n"
12206 "Content-Type: text/html; charset=iso-8859-1\r\n"
12207 "Content-Length: 14\r\n\r\n"
12208 "Unauthorized\r\n");
12209 const MockRead kProxyChallenge(
12210 "HTTP/1.1 407 Unauthorized\r\n"
12211 "Proxy-Authenticate: Mock realm=proxy\r\n"
12212 "Proxy-Connection: close\r\n"
12213 "Content-Type: text/html; charset=iso-8859-1\r\n"
12214 "Content-Length: 14\r\n\r\n"
12215 "Unauthorized\r\n");
12216 const MockRead kProxyConnected(
12217 "HTTP/1.1 200 Connection Established\r\n\r\n");
12218
12219 // NOTE(cbentzel): I wanted TestReadWriteRound to be a simple struct with
12220 // no constructors, but the C++ compiler on Windows warns about
12221 // unspecified data in compound literals. So, moved to using constructors,
12222 // and TestRound's created with the default constructor should not be used.
12223 struct TestRound {
12224 TestRound()
12225 : expected_rv(ERR_UNEXPECTED),
12226 extra_write(NULL),
12227 extra_read(NULL) {
12228 }
12229 TestRound(const MockWrite& write_arg, const MockRead& read_arg,
12230 int expected_rv_arg)
12231 : write(write_arg),
12232 read(read_arg),
12233 expected_rv(expected_rv_arg),
12234 extra_write(NULL),
12235 extra_read(NULL) {
12236 }
12237 TestRound(const MockWrite& write_arg, const MockRead& read_arg,
12238 int expected_rv_arg, const MockWrite* extra_write_arg,
[email protected]f871ee152012-07-27 19:02:0112239 const MockRead* extra_read_arg)
[email protected]044de0642010-06-17 10:42:1512240 : write(write_arg),
12241 read(read_arg),
12242 expected_rv(expected_rv_arg),
12243 extra_write(extra_write_arg),
12244 extra_read(extra_read_arg) {
12245 }
12246 MockWrite write;
12247 MockRead read;
12248 int expected_rv;
12249 const MockWrite* extra_write;
12250 const MockRead* extra_read;
12251 };
12252
12253 static const int kNoSSL = 500;
12254
12255 struct TestConfig {
asanka463ca4262016-11-16 02:34:3112256 int line_number;
thestig9d3bb0c2015-01-24 00:49:5112257 const char* const proxy_url;
[email protected]044de0642010-06-17 10:42:1512258 AuthTiming proxy_auth_timing;
asanka463ca4262016-11-16 02:34:3112259 int first_generate_proxy_token_rv;
thestig9d3bb0c2015-01-24 00:49:5112260 const char* const server_url;
[email protected]044de0642010-06-17 10:42:1512261 AuthTiming server_auth_timing;
asanka463ca4262016-11-16 02:34:3112262 int first_generate_server_token_rv;
[email protected]044de0642010-06-17 10:42:1512263 int num_auth_rounds;
12264 int first_ssl_round;
asankae2257db2016-10-11 22:03:1612265 TestRound rounds[4];
[email protected]044de0642010-06-17 10:42:1512266 } test_configs[] = {
asankac93076192016-10-03 15:46:0212267 // Non-authenticating HTTP server with a direct connection.
asanka463ca4262016-11-16 02:34:3112268 {__LINE__,
12269 nullptr,
asankac93076192016-10-03 15:46:0212270 AUTH_NONE,
12271 OK,
12272 kServer,
12273 AUTH_NONE,
12274 OK,
12275 1,
12276 kNoSSL,
12277 {TestRound(kGet, kSuccess, OK)}},
12278 // Authenticating HTTP server with a direct connection.
asanka463ca4262016-11-16 02:34:3112279 {__LINE__,
12280 nullptr,
asankac93076192016-10-03 15:46:0212281 AUTH_NONE,
12282 OK,
12283 kServer,
12284 AUTH_SYNC,
12285 OK,
12286 2,
12287 kNoSSL,
12288 {TestRound(kGet, kServerChallenge, OK),
[email protected]044de0642010-06-17 10:42:1512289 TestRound(kGetAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112290 {__LINE__,
12291 nullptr,
asankac93076192016-10-03 15:46:0212292 AUTH_NONE,
12293 OK,
12294 kServer,
12295 AUTH_SYNC,
12296 ERR_INVALID_AUTH_CREDENTIALS,
asankae2257db2016-10-11 22:03:1612297 3,
12298 kNoSSL,
12299 {TestRound(kGet, kServerChallenge, OK),
12300 TestRound(kGet, kServerChallenge, OK),
12301 TestRound(kGetAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112302 {__LINE__,
12303 nullptr,
asankae2257db2016-10-11 22:03:1612304 AUTH_NONE,
12305 OK,
12306 kServer,
12307 AUTH_SYNC,
12308 ERR_UNSUPPORTED_AUTH_SCHEME,
12309 2,
12310 kNoSSL,
12311 {TestRound(kGet, kServerChallenge, OK), TestRound(kGet, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112312 {__LINE__,
12313 nullptr,
asankae2257db2016-10-11 22:03:1612314 AUTH_NONE,
12315 OK,
12316 kServer,
12317 AUTH_SYNC,
12318 ERR_UNDOCUMENTED_SECURITY_LIBRARY_STATUS,
12319 2,
12320 kNoSSL,
12321 {TestRound(kGet, kServerChallenge, OK), TestRound(kGet, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112322 {__LINE__,
12323 kProxy,
asankae2257db2016-10-11 22:03:1612324 AUTH_SYNC,
12325 ERR_FAILED,
12326 kServer,
12327 AUTH_NONE,
12328 OK,
12329 2,
12330 kNoSSL,
12331 {TestRound(kGetProxy, kProxyChallenge, OK),
12332 TestRound(kGetProxy, kFailure, ERR_FAILED)}},
asanka463ca4262016-11-16 02:34:3112333 {__LINE__,
12334 kProxy,
asankae2257db2016-10-11 22:03:1612335 AUTH_ASYNC,
12336 ERR_FAILED,
12337 kServer,
12338 AUTH_NONE,
12339 OK,
12340 2,
12341 kNoSSL,
12342 {TestRound(kGetProxy, kProxyChallenge, OK),
12343 TestRound(kGetProxy, kFailure, ERR_FAILED)}},
asanka463ca4262016-11-16 02:34:3112344 {__LINE__,
12345 nullptr,
asankae2257db2016-10-11 22:03:1612346 AUTH_NONE,
12347 OK,
12348 kServer,
12349 AUTH_SYNC,
12350 ERR_FAILED,
asankac93076192016-10-03 15:46:0212351 2,
12352 kNoSSL,
12353 {TestRound(kGet, kServerChallenge, OK),
asankae2257db2016-10-11 22:03:1612354 TestRound(kGet, kFailure, ERR_FAILED)}},
asanka463ca4262016-11-16 02:34:3112355 {__LINE__,
12356 nullptr,
asankae2257db2016-10-11 22:03:1612357 AUTH_NONE,
12358 OK,
12359 kServer,
12360 AUTH_ASYNC,
12361 ERR_FAILED,
12362 2,
12363 kNoSSL,
12364 {TestRound(kGet, kServerChallenge, OK),
12365 TestRound(kGet, kFailure, ERR_FAILED)}},
asanka463ca4262016-11-16 02:34:3112366 {__LINE__,
12367 nullptr,
asankac93076192016-10-03 15:46:0212368 AUTH_NONE,
12369 OK,
12370 kServer,
12371 AUTH_ASYNC,
12372 OK,
12373 2,
12374 kNoSSL,
12375 {TestRound(kGet, kServerChallenge, OK),
[email protected]044de0642010-06-17 10:42:1512376 TestRound(kGetAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112377 {__LINE__,
12378 nullptr,
asankac93076192016-10-03 15:46:0212379 AUTH_NONE,
12380 OK,
12381 kServer,
12382 AUTH_ASYNC,
12383 ERR_INVALID_AUTH_CREDENTIALS,
asankae2257db2016-10-11 22:03:1612384 3,
asankac93076192016-10-03 15:46:0212385 kNoSSL,
12386 {TestRound(kGet, kServerChallenge, OK),
asankae2257db2016-10-11 22:03:1612387 // The second round uses a HttpAuthHandlerMock that always succeeds.
12388 TestRound(kGet, kServerChallenge, OK),
12389 TestRound(kGetAuth, kSuccess, OK)}},
asankac93076192016-10-03 15:46:0212390 // Non-authenticating HTTP server through a non-authenticating proxy.
asanka463ca4262016-11-16 02:34:3112391 {__LINE__,
12392 kProxy,
asankac93076192016-10-03 15:46:0212393 AUTH_NONE,
12394 OK,
12395 kServer,
12396 AUTH_NONE,
12397 OK,
12398 1,
12399 kNoSSL,
12400 {TestRound(kGetProxy, kSuccess, OK)}},
12401 // Authenticating HTTP server through a non-authenticating proxy.
asanka463ca4262016-11-16 02:34:3112402 {__LINE__,
12403 kProxy,
asankac93076192016-10-03 15:46:0212404 AUTH_NONE,
12405 OK,
12406 kServer,
12407 AUTH_SYNC,
12408 OK,
12409 2,
12410 kNoSSL,
12411 {TestRound(kGetProxy, kServerChallenge, OK),
[email protected]044de0642010-06-17 10:42:1512412 TestRound(kGetAuthThroughProxy, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112413 {__LINE__,
12414 kProxy,
asankac93076192016-10-03 15:46:0212415 AUTH_NONE,
12416 OK,
12417 kServer,
12418 AUTH_SYNC,
12419 ERR_INVALID_AUTH_CREDENTIALS,
asankae2257db2016-10-11 22:03:1612420 3,
asankac93076192016-10-03 15:46:0212421 kNoSSL,
12422 {TestRound(kGetProxy, kServerChallenge, OK),
asankae2257db2016-10-11 22:03:1612423 TestRound(kGetProxy, kServerChallenge, OK),
12424 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_ASYNC,
12431 OK,
12432 2,
12433 kNoSSL,
12434 {TestRound(kGetProxy, kServerChallenge, OK),
[email protected]044de0642010-06-17 10:42:1512435 TestRound(kGetAuthThroughProxy, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112436 {__LINE__,
12437 kProxy,
asankac93076192016-10-03 15:46:0212438 AUTH_NONE,
12439 OK,
12440 kServer,
12441 AUTH_ASYNC,
12442 ERR_INVALID_AUTH_CREDENTIALS,
12443 2,
12444 kNoSSL,
12445 {TestRound(kGetProxy, kServerChallenge, OK),
asankae2257db2016-10-11 22:03:1612446 TestRound(kGetProxy, kSuccess, OK)}},
asankac93076192016-10-03 15:46:0212447 // Non-authenticating HTTP server through an authenticating proxy.
asanka463ca4262016-11-16 02:34:3112448 {__LINE__,
12449 kProxy,
asankac93076192016-10-03 15:46:0212450 AUTH_SYNC,
12451 OK,
12452 kServer,
12453 AUTH_NONE,
12454 OK,
12455 2,
12456 kNoSSL,
12457 {TestRound(kGetProxy, kProxyChallenge, OK),
[email protected]044de0642010-06-17 10:42:1512458 TestRound(kGetProxyAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112459 {__LINE__,
12460 kProxy,
asankac93076192016-10-03 15:46:0212461 AUTH_SYNC,
12462 ERR_INVALID_AUTH_CREDENTIALS,
12463 kServer,
12464 AUTH_NONE,
12465 OK,
12466 2,
12467 kNoSSL,
12468 {TestRound(kGetProxy, kProxyChallenge, OK),
asankae2257db2016-10-11 22:03:1612469 TestRound(kGetProxy, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112470 {__LINE__,
12471 kProxy,
asankac93076192016-10-03 15:46:0212472 AUTH_ASYNC,
12473 OK,
12474 kServer,
12475 AUTH_NONE,
12476 OK,
12477 2,
12478 kNoSSL,
12479 {TestRound(kGetProxy, kProxyChallenge, OK),
[email protected]044de0642010-06-17 10:42:1512480 TestRound(kGetProxyAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112481 {__LINE__,
12482 kProxy,
asankac93076192016-10-03 15:46:0212483 AUTH_ASYNC,
12484 ERR_INVALID_AUTH_CREDENTIALS,
12485 kServer,
12486 AUTH_NONE,
12487 OK,
12488 2,
12489 kNoSSL,
12490 {TestRound(kGetProxy, kProxyChallenge, OK),
asankae2257db2016-10-11 22:03:1612491 TestRound(kGetProxy, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112492 {__LINE__,
12493 kProxy,
12494 AUTH_ASYNC,
12495 ERR_INVALID_AUTH_CREDENTIALS,
12496 kServer,
12497 AUTH_NONE,
12498 OK,
12499 3,
12500 kNoSSL,
12501 {TestRound(kGetProxy, kProxyChallenge, OK),
12502 TestRound(kGetProxy, kProxyChallenge, OK),
12503 TestRound(kGetProxyAuth, kSuccess, OK)}},
asankac93076192016-10-03 15:46:0212504 // Authenticating HTTP server through an authenticating proxy.
asanka463ca4262016-11-16 02:34:3112505 {__LINE__,
12506 kProxy,
asankac93076192016-10-03 15:46:0212507 AUTH_SYNC,
12508 OK,
12509 kServer,
12510 AUTH_SYNC,
12511 OK,
12512 3,
12513 kNoSSL,
12514 {TestRound(kGetProxy, kProxyChallenge, OK),
[email protected]044de0642010-06-17 10:42:1512515 TestRound(kGetProxyAuth, kServerChallenge, OK),
12516 TestRound(kGetAuthWithProxyAuth, kSuccess, OK)}},
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 ERR_INVALID_AUTH_CREDENTIALS,
12524 3,
12525 kNoSSL,
12526 {TestRound(kGetProxy, kProxyChallenge, OK),
[email protected]044de0642010-06-17 10:42:1512527 TestRound(kGetProxyAuth, kServerChallenge, OK),
asankae2257db2016-10-11 22:03:1612528 TestRound(kGetProxyAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112529 {__LINE__,
12530 kProxy,
asankac93076192016-10-03 15:46:0212531 AUTH_ASYNC,
12532 OK,
12533 kServer,
12534 AUTH_SYNC,
12535 OK,
12536 3,
12537 kNoSSL,
12538 {TestRound(kGetProxy, kProxyChallenge, OK),
[email protected]044de0642010-06-17 10:42:1512539 TestRound(kGetProxyAuth, kServerChallenge, OK),
12540 TestRound(kGetAuthWithProxyAuth, 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 ERR_INVALID_AUTH_CREDENTIALS,
12548 3,
12549 kNoSSL,
12550 {TestRound(kGetProxy, kProxyChallenge, OK),
[email protected]044de0642010-06-17 10:42:1512551 TestRound(kGetProxyAuth, kServerChallenge, OK),
asankae2257db2016-10-11 22:03:1612552 TestRound(kGetProxyAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112553 {__LINE__,
12554 kProxy,
asankac93076192016-10-03 15:46:0212555 AUTH_SYNC,
12556 OK,
12557 kServer,
12558 AUTH_ASYNC,
12559 OK,
12560 3,
12561 kNoSSL,
12562 {TestRound(kGetProxy, kProxyChallenge, OK),
[email protected]044de0642010-06-17 10:42:1512563 TestRound(kGetProxyAuth, kServerChallenge, OK),
12564 TestRound(kGetAuthWithProxyAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112565 {__LINE__,
12566 kProxy,
12567 AUTH_SYNC,
12568 ERR_INVALID_AUTH_CREDENTIALS,
12569 kServer,
12570 AUTH_ASYNC,
12571 OK,
12572 4,
12573 kNoSSL,
12574 {TestRound(kGetProxy, kProxyChallenge, OK),
12575 TestRound(kGetProxy, kProxyChallenge, OK),
12576 TestRound(kGetProxyAuth, kServerChallenge, OK),
12577 TestRound(kGetAuthWithProxyAuth, kSuccess, OK)}},
12578 {__LINE__,
12579 kProxy,
asankac93076192016-10-03 15:46:0212580 AUTH_SYNC,
12581 OK,
12582 kServer,
12583 AUTH_ASYNC,
12584 ERR_INVALID_AUTH_CREDENTIALS,
12585 3,
12586 kNoSSL,
12587 {TestRound(kGetProxy, kProxyChallenge, OK),
[email protected]044de0642010-06-17 10:42:1512588 TestRound(kGetProxyAuth, kServerChallenge, OK),
asankae2257db2016-10-11 22:03:1612589 TestRound(kGetProxyAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112590 {__LINE__,
12591 kProxy,
asankac93076192016-10-03 15:46:0212592 AUTH_ASYNC,
12593 OK,
12594 kServer,
12595 AUTH_ASYNC,
12596 OK,
12597 3,
12598 kNoSSL,
12599 {TestRound(kGetProxy, kProxyChallenge, OK),
[email protected]044de0642010-06-17 10:42:1512600 TestRound(kGetProxyAuth, kServerChallenge, OK),
12601 TestRound(kGetAuthWithProxyAuth, 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 ERR_INVALID_AUTH_CREDENTIALS,
12609 3,
12610 kNoSSL,
12611 {TestRound(kGetProxy, kProxyChallenge, OK),
[email protected]044de0642010-06-17 10:42:1512612 TestRound(kGetProxyAuth, kServerChallenge, OK),
asankae2257db2016-10-11 22:03:1612613 TestRound(kGetProxyAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112614 {__LINE__,
12615 kProxy,
12616 AUTH_ASYNC,
12617 ERR_INVALID_AUTH_CREDENTIALS,
12618 kServer,
12619 AUTH_ASYNC,
12620 ERR_INVALID_AUTH_CREDENTIALS,
12621 4,
12622 kNoSSL,
12623 {TestRound(kGetProxy, kProxyChallenge, OK),
12624 TestRound(kGetProxy, kProxyChallenge, OK),
12625 TestRound(kGetProxyAuth, kServerChallenge, OK),
12626 TestRound(kGetProxyAuth, kSuccess, OK)}},
asankac93076192016-10-03 15:46:0212627 // Non-authenticating HTTPS server with a direct connection.
asanka463ca4262016-11-16 02:34:3112628 {__LINE__,
12629 nullptr,
asankac93076192016-10-03 15:46:0212630 AUTH_NONE,
12631 OK,
12632 kSecureServer,
12633 AUTH_NONE,
12634 OK,
12635 1,
12636 0,
12637 {TestRound(kGet, kSuccess, OK)}},
12638 // Authenticating HTTPS server with a direct connection.
asanka463ca4262016-11-16 02:34:3112639 {__LINE__,
12640 nullptr,
asankac93076192016-10-03 15:46:0212641 AUTH_NONE,
12642 OK,
12643 kSecureServer,
12644 AUTH_SYNC,
12645 OK,
12646 2,
12647 0,
12648 {TestRound(kGet, kServerChallenge, OK),
[email protected]044de0642010-06-17 10:42:1512649 TestRound(kGetAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112650 {__LINE__,
12651 nullptr,
asankac93076192016-10-03 15:46:0212652 AUTH_NONE,
12653 OK,
12654 kSecureServer,
12655 AUTH_SYNC,
12656 ERR_INVALID_AUTH_CREDENTIALS,
12657 2,
12658 0,
asankae2257db2016-10-11 22:03:1612659 {TestRound(kGet, kServerChallenge, OK), TestRound(kGet, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112660 {__LINE__,
12661 nullptr,
asankac93076192016-10-03 15:46:0212662 AUTH_NONE,
12663 OK,
12664 kSecureServer,
12665 AUTH_ASYNC,
12666 OK,
12667 2,
12668 0,
12669 {TestRound(kGet, kServerChallenge, OK),
[email protected]044de0642010-06-17 10:42:1512670 TestRound(kGetAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112671 {__LINE__,
12672 nullptr,
asankac93076192016-10-03 15:46:0212673 AUTH_NONE,
12674 OK,
12675 kSecureServer,
12676 AUTH_ASYNC,
12677 ERR_INVALID_AUTH_CREDENTIALS,
12678 2,
12679 0,
asankae2257db2016-10-11 22:03:1612680 {TestRound(kGet, kServerChallenge, OK), TestRound(kGet, kSuccess, OK)}},
asankac93076192016-10-03 15:46:0212681 // Non-authenticating HTTPS server with a non-authenticating proxy.
asanka463ca4262016-11-16 02:34:3112682 {__LINE__,
12683 kProxy,
asankac93076192016-10-03 15:46:0212684 AUTH_NONE,
12685 OK,
12686 kSecureServer,
12687 AUTH_NONE,
12688 OK,
12689 1,
12690 0,
12691 {TestRound(kConnect, kProxyConnected, OK, &kGet, &kSuccess)}},
12692 // Authenticating HTTPS server through a non-authenticating proxy.
asanka463ca4262016-11-16 02:34:3112693 {__LINE__,
12694 kProxy,
asankac93076192016-10-03 15:46:0212695 AUTH_NONE,
12696 OK,
12697 kSecureServer,
12698 AUTH_SYNC,
12699 OK,
12700 2,
12701 0,
12702 {TestRound(kConnect, kProxyConnected, OK, &kGet, &kServerChallenge),
[email protected]044de0642010-06-17 10:42:1512703 TestRound(kGetAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112704 {__LINE__,
12705 kProxy,
asankac93076192016-10-03 15:46:0212706 AUTH_NONE,
12707 OK,
12708 kSecureServer,
12709 AUTH_SYNC,
12710 ERR_INVALID_AUTH_CREDENTIALS,
12711 2,
12712 0,
12713 {TestRound(kConnect, kProxyConnected, OK, &kGet, &kServerChallenge),
asankae2257db2016-10-11 22:03:1612714 TestRound(kGet, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112715 {__LINE__,
12716 kProxy,
asankac93076192016-10-03 15:46:0212717 AUTH_NONE,
12718 OK,
12719 kSecureServer,
12720 AUTH_ASYNC,
12721 OK,
12722 2,
12723 0,
12724 {TestRound(kConnect, kProxyConnected, OK, &kGet, &kServerChallenge),
[email protected]044de0642010-06-17 10:42:1512725 TestRound(kGetAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112726 {__LINE__,
12727 kProxy,
asankac93076192016-10-03 15:46:0212728 AUTH_NONE,
12729 OK,
12730 kSecureServer,
12731 AUTH_ASYNC,
12732 ERR_INVALID_AUTH_CREDENTIALS,
12733 2,
12734 0,
12735 {TestRound(kConnect, kProxyConnected, OK, &kGet, &kServerChallenge),
asankae2257db2016-10-11 22:03:1612736 TestRound(kGet, kSuccess, OK)}},
asankac93076192016-10-03 15:46:0212737 // Non-Authenticating HTTPS server through an authenticating proxy.
asanka463ca4262016-11-16 02:34:3112738 {__LINE__,
12739 kProxy,
asankac93076192016-10-03 15:46:0212740 AUTH_SYNC,
12741 OK,
12742 kSecureServer,
12743 AUTH_NONE,
12744 OK,
12745 2,
12746 1,
12747 {TestRound(kConnect, kProxyChallenge, OK),
[email protected]044de0642010-06-17 10:42:1512748 TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet, &kSuccess)}},
asanka463ca4262016-11-16 02:34:3112749 {__LINE__,
12750 kProxy,
asankac93076192016-10-03 15:46:0212751 AUTH_SYNC,
12752 ERR_INVALID_AUTH_CREDENTIALS,
12753 kSecureServer,
12754 AUTH_NONE,
12755 OK,
12756 2,
12757 kNoSSL,
12758 {TestRound(kConnect, kProxyChallenge, OK),
asankae2257db2016-10-11 22:03:1612759 TestRound(kConnect, kProxyConnected, OK, &kGet, &kSuccess)}},
asanka463ca4262016-11-16 02:34:3112760 {__LINE__,
12761 kProxy,
asankae2257db2016-10-11 22:03:1612762 AUTH_SYNC,
12763 ERR_UNSUPPORTED_AUTH_SCHEME,
12764 kSecureServer,
12765 AUTH_NONE,
12766 OK,
12767 2,
12768 kNoSSL,
12769 {TestRound(kConnect, kProxyChallenge, OK),
12770 TestRound(kConnect, kProxyConnected, OK, &kGet, &kSuccess)}},
asanka463ca4262016-11-16 02:34:3112771 {__LINE__,
12772 kProxy,
asankae2257db2016-10-11 22:03:1612773 AUTH_SYNC,
12774 ERR_UNEXPECTED,
12775 kSecureServer,
12776 AUTH_NONE,
12777 OK,
12778 2,
12779 kNoSSL,
12780 {TestRound(kConnect, kProxyChallenge, OK),
12781 TestRound(kConnect, kProxyConnected, ERR_UNEXPECTED)}},
asanka463ca4262016-11-16 02:34:3112782 {__LINE__,
12783 kProxy,
asankac93076192016-10-03 15:46:0212784 AUTH_ASYNC,
12785 OK,
12786 kSecureServer,
12787 AUTH_NONE,
12788 OK,
12789 2,
12790 1,
12791 {TestRound(kConnect, kProxyChallenge, OK),
[email protected]044de0642010-06-17 10:42:1512792 TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet, &kSuccess)}},
asanka463ca4262016-11-16 02:34:3112793 {__LINE__,
12794 kProxy,
asankac93076192016-10-03 15:46:0212795 AUTH_ASYNC,
12796 ERR_INVALID_AUTH_CREDENTIALS,
12797 kSecureServer,
12798 AUTH_NONE,
12799 OK,
12800 2,
12801 kNoSSL,
12802 {TestRound(kConnect, kProxyChallenge, OK),
asankae2257db2016-10-11 22:03:1612803 TestRound(kConnect, kProxyConnected, OK, &kGet, &kSuccess)}},
asankac93076192016-10-03 15:46:0212804 // Authenticating HTTPS server through an authenticating proxy.
asanka463ca4262016-11-16 02:34:3112805 {__LINE__,
12806 kProxy,
asankac93076192016-10-03 15:46:0212807 AUTH_SYNC,
12808 OK,
12809 kSecureServer,
12810 AUTH_SYNC,
12811 OK,
12812 3,
12813 1,
12814 {TestRound(kConnect, kProxyChallenge, OK),
12815 TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet,
12816 &kServerChallenge),
[email protected]044de0642010-06-17 10:42:1512817 TestRound(kGetAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112818 {__LINE__,
12819 kProxy,
asankac93076192016-10-03 15:46:0212820 AUTH_SYNC,
12821 OK,
12822 kSecureServer,
12823 AUTH_SYNC,
12824 ERR_INVALID_AUTH_CREDENTIALS,
12825 3,
12826 1,
12827 {TestRound(kConnect, kProxyChallenge, OK),
12828 TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet,
12829 &kServerChallenge),
asankae2257db2016-10-11 22:03:1612830 TestRound(kGet, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112831 {__LINE__,
12832 kProxy,
asankac93076192016-10-03 15:46:0212833 AUTH_ASYNC,
12834 OK,
12835 kSecureServer,
12836 AUTH_SYNC,
12837 OK,
12838 3,
12839 1,
12840 {TestRound(kConnect, kProxyChallenge, OK),
12841 TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet,
12842 &kServerChallenge),
[email protected]044de0642010-06-17 10:42:1512843 TestRound(kGetAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112844 {__LINE__,
12845 kProxy,
asankac93076192016-10-03 15:46:0212846 AUTH_ASYNC,
12847 OK,
12848 kSecureServer,
12849 AUTH_SYNC,
12850 ERR_INVALID_AUTH_CREDENTIALS,
12851 3,
12852 1,
12853 {TestRound(kConnect, kProxyChallenge, OK),
12854 TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet,
12855 &kServerChallenge),
asankae2257db2016-10-11 22:03:1612856 TestRound(kGet, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112857 {__LINE__,
12858 kProxy,
asankac93076192016-10-03 15:46:0212859 AUTH_SYNC,
12860 OK,
12861 kSecureServer,
12862 AUTH_ASYNC,
12863 OK,
12864 3,
12865 1,
12866 {TestRound(kConnect, kProxyChallenge, OK),
12867 TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet,
12868 &kServerChallenge),
[email protected]044de0642010-06-17 10:42:1512869 TestRound(kGetAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112870 {__LINE__,
12871 kProxy,
asankac93076192016-10-03 15:46:0212872 AUTH_SYNC,
12873 OK,
12874 kSecureServer,
12875 AUTH_ASYNC,
12876 ERR_INVALID_AUTH_CREDENTIALS,
12877 3,
12878 1,
12879 {TestRound(kConnect, kProxyChallenge, OK),
12880 TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet,
12881 &kServerChallenge),
asankae2257db2016-10-11 22:03:1612882 TestRound(kGet, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112883 {__LINE__,
12884 kProxy,
asankac93076192016-10-03 15:46:0212885 AUTH_ASYNC,
12886 OK,
12887 kSecureServer,
12888 AUTH_ASYNC,
12889 OK,
12890 3,
12891 1,
12892 {TestRound(kConnect, kProxyChallenge, OK),
12893 TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet,
12894 &kServerChallenge),
[email protected]044de0642010-06-17 10:42:1512895 TestRound(kGetAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112896 {__LINE__,
12897 kProxy,
asankac93076192016-10-03 15:46:0212898 AUTH_ASYNC,
12899 OK,
12900 kSecureServer,
12901 AUTH_ASYNC,
12902 ERR_INVALID_AUTH_CREDENTIALS,
12903 3,
12904 1,
12905 {TestRound(kConnect, kProxyChallenge, OK),
12906 TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet,
12907 &kServerChallenge),
asankae2257db2016-10-11 22:03:1612908 TestRound(kGet, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112909 {__LINE__,
12910 kProxy,
12911 AUTH_ASYNC,
12912 ERR_INVALID_AUTH_CREDENTIALS,
12913 kSecureServer,
12914 AUTH_ASYNC,
12915 ERR_INVALID_AUTH_CREDENTIALS,
12916 4,
12917 2,
12918 {TestRound(kConnect, kProxyChallenge, OK),
12919 TestRound(kConnect, kProxyChallenge, OK),
12920 TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet,
12921 &kServerChallenge),
12922 TestRound(kGet, kSuccess, OK)}},
[email protected]044de0642010-06-17 10:42:1512923 };
12924
asanka463ca4262016-11-16 02:34:3112925 for (const auto& test_config : test_configs) {
12926 SCOPED_TRACE(::testing::Message() << "Test config at "
12927 << test_config.line_number);
[email protected]2d01c262011-08-11 23:07:0812928 HttpAuthHandlerMock::Factory* auth_factory(
12929 new HttpAuthHandlerMock::Factory());
[email protected]bb88e1d32013-05-03 23:11:0712930 session_deps_.http_auth_handler_factory.reset(auth_factory);
asanka5ffd5d72016-03-23 16:20:4912931 SSLInfo empty_ssl_info;
[email protected]65d34382010-07-01 18:12:2612932
12933 // Set up authentication handlers as necessary.
[email protected]044de0642010-06-17 10:42:1512934 if (test_config.proxy_auth_timing != AUTH_NONE) {
asanka463ca4262016-11-16 02:34:3112935 for (int n = 0; n < 3; n++) {
[email protected]2d01c262011-08-11 23:07:0812936 HttpAuthHandlerMock* auth_handler(new HttpAuthHandlerMock());
12937 std::string auth_challenge = "Mock realm=proxy";
12938 GURL origin(test_config.proxy_url);
[email protected]df41d0d82014-03-13 00:43:2412939 HttpAuthChallengeTokenizer tokenizer(auth_challenge.begin(),
12940 auth_challenge.end());
[email protected]2d01c262011-08-11 23:07:0812941 auth_handler->InitFromChallenge(&tokenizer, HttpAuth::AUTH_PROXY,
tfarina42834112016-09-22 13:38:2012942 empty_ssl_info, origin,
12943 NetLogWithSource());
[email protected]2d01c262011-08-11 23:07:0812944 auth_handler->SetGenerateExpectation(
12945 test_config.proxy_auth_timing == AUTH_ASYNC,
asanka463ca4262016-11-16 02:34:3112946 n == 0 ? test_config.first_generate_proxy_token_rv : OK);
[email protected]2d01c262011-08-11 23:07:0812947 auth_factory->AddMockHandler(auth_handler, HttpAuth::AUTH_PROXY);
12948 }
[email protected]044de0642010-06-17 10:42:1512949 }
12950 if (test_config.server_auth_timing != AUTH_NONE) {
[email protected]3fd9dae2010-06-21 11:39:0012951 HttpAuthHandlerMock* auth_handler(new HttpAuthHandlerMock());
[email protected]044de0642010-06-17 10:42:1512952 std::string auth_challenge = "Mock realm=server";
12953 GURL origin(test_config.server_url);
[email protected]df41d0d82014-03-13 00:43:2412954 HttpAuthChallengeTokenizer tokenizer(auth_challenge.begin(),
12955 auth_challenge.end());
[email protected]044de0642010-06-17 10:42:1512956 auth_handler->InitFromChallenge(&tokenizer, HttpAuth::AUTH_SERVER,
tfarina42834112016-09-22 13:38:2012957 empty_ssl_info, origin,
12958 NetLogWithSource());
[email protected]044de0642010-06-17 10:42:1512959 auth_handler->SetGenerateExpectation(
12960 test_config.server_auth_timing == AUTH_ASYNC,
asanka463ca4262016-11-16 02:34:3112961 test_config.first_generate_server_token_rv);
[email protected]2d01c262011-08-11 23:07:0812962 auth_factory->AddMockHandler(auth_handler, HttpAuth::AUTH_SERVER);
asankae2257db2016-10-11 22:03:1612963
12964 // The second handler always succeeds. It should only be used where there
12965 // are multiple auth sessions for server auth in the same network
12966 // transaction using the same auth scheme.
12967 std::unique_ptr<HttpAuthHandlerMock> second_handler =
Jeremy Roman0579ed62017-08-29 15:56:1912968 std::make_unique<HttpAuthHandlerMock>();
asankae2257db2016-10-11 22:03:1612969 second_handler->InitFromChallenge(&tokenizer, HttpAuth::AUTH_SERVER,
12970 empty_ssl_info, origin,
12971 NetLogWithSource());
12972 second_handler->SetGenerateExpectation(true, OK);
12973 auth_factory->AddMockHandler(second_handler.release(),
12974 HttpAuth::AUTH_SERVER);
[email protected]044de0642010-06-17 10:42:1512975 }
12976 if (test_config.proxy_url) {
rdsmith82957ad2015-09-16 19:42:0312977 session_deps_.proxy_service =
12978 ProxyService::CreateFixed(test_config.proxy_url);
[email protected]044de0642010-06-17 10:42:1512979 } else {
rdsmith82957ad2015-09-16 19:42:0312980 session_deps_.proxy_service = ProxyService::CreateDirect();
[email protected]044de0642010-06-17 10:42:1512981 }
12982
12983 HttpRequestInfo request;
12984 request.method = "GET";
12985 request.url = GURL(test_config.server_url);
[email protected]044de0642010-06-17 10:42:1512986
danakj1fd259a02016-04-16 03:17:0912987 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]044de0642010-06-17 10:42:1512988
rchcb68dc62015-05-21 04:45:3612989 SSLSocketDataProvider ssl_socket_data_provider(SYNCHRONOUS, OK);
12990
12991 std::vector<std::vector<MockRead>> mock_reads(1);
12992 std::vector<std::vector<MockWrite>> mock_writes(1);
[email protected]044de0642010-06-17 10:42:1512993 for (int round = 0; round < test_config.num_auth_rounds; ++round) {
davidben8c7089a2017-04-17 20:38:2212994 SCOPED_TRACE(round);
[email protected]044de0642010-06-17 10:42:1512995 const TestRound& read_write_round = test_config.rounds[round];
12996
12997 // Set up expected reads and writes.
rchcb68dc62015-05-21 04:45:3612998 mock_reads.back().push_back(read_write_round.read);
12999 mock_writes.back().push_back(read_write_round.write);
13000
13001 // kProxyChallenge uses Proxy-Connection: close which means that the
13002 // socket is closed and a new one will be created for the next request.
mmenkee71e15332015-10-07 16:39:5413003 if (read_write_round.read.data == kProxyChallenge.data) {
rchcb68dc62015-05-21 04:45:3613004 mock_reads.push_back(std::vector<MockRead>());
13005 mock_writes.push_back(std::vector<MockWrite>());
[email protected]044de0642010-06-17 10:42:1513006 }
13007
rchcb68dc62015-05-21 04:45:3613008 if (read_write_round.extra_read) {
13009 mock_reads.back().push_back(*read_write_round.extra_read);
[email protected]044de0642010-06-17 10:42:1513010 }
rchcb68dc62015-05-21 04:45:3613011 if (read_write_round.extra_write) {
13012 mock_writes.back().push_back(*read_write_round.extra_write);
13013 }
[email protected]044de0642010-06-17 10:42:1513014
13015 // Add an SSL sequence if necessary.
[email protected]044de0642010-06-17 10:42:1513016 if (round >= test_config.first_ssl_round)
[email protected]bb88e1d32013-05-03 23:11:0713017 session_deps_.socket_factory->AddSSLSocketDataProvider(
[email protected]044de0642010-06-17 10:42:1513018 &ssl_socket_data_provider);
rchcb68dc62015-05-21 04:45:3613019 }
[email protected]044de0642010-06-17 10:42:1513020
danakj1fd259a02016-04-16 03:17:0913021 std::vector<std::unique_ptr<StaticSocketDataProvider>> data_providers;
rchcb68dc62015-05-21 04:45:3613022 for (size_t i = 0; i < mock_reads.size(); ++i) {
Jeremy Roman0579ed62017-08-29 15:56:1913023 data_providers.push_back(std::make_unique<StaticSocketDataProvider>(
davidben5f8b6bc2015-11-25 03:19:5413024 mock_reads[i].data(), mock_reads[i].size(), mock_writes[i].data(),
bnc87dcefc2017-05-25 12:47:5813025 mock_writes[i].size()));
rchcb68dc62015-05-21 04:45:3613026 session_deps_.socket_factory->AddSocketDataProvider(
olli.raula525048c2015-12-10 07:38:3213027 data_providers.back().get());
rchcb68dc62015-05-21 04:45:3613028 }
13029
mmenkecc2298e2015-12-07 18:20:1813030 // Transaction must be created after DataProviders, so it's destroyed before
13031 // they are as well.
13032 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
13033
rchcb68dc62015-05-21 04:45:3613034 for (int round = 0; round < test_config.num_auth_rounds; ++round) {
davidben8c7089a2017-04-17 20:38:2213035 SCOPED_TRACE(round);
rchcb68dc62015-05-21 04:45:3613036 const TestRound& read_write_round = test_config.rounds[round];
[email protected]044de0642010-06-17 10:42:1513037 // Start or restart the transaction.
[email protected]49639fa2011-12-20 23:22:4113038 TestCompletionCallback callback;
[email protected]044de0642010-06-17 10:42:1513039 int rv;
13040 if (round == 0) {
tfarina42834112016-09-22 13:38:2013041 rv = trans.Start(&request, callback.callback(), NetLogWithSource());
[email protected]044de0642010-06-17 10:42:1513042 } else {
[email protected]49639fa2011-12-20 23:22:4113043 rv = trans.RestartWithAuth(
13044 AuthCredentials(kFoo, kBar), callback.callback());
[email protected]044de0642010-06-17 10:42:1513045 }
13046 if (rv == ERR_IO_PENDING)
13047 rv = callback.WaitForResult();
13048
13049 // Compare results with expected data.
asankae2257db2016-10-11 22:03:1613050 EXPECT_THAT(rv, IsError(read_write_round.expected_rv));
[email protected]0b0bf032010-09-21 18:08:5013051 const HttpResponseInfo* response = trans.GetResponseInfo();
ttuttlec0c828492015-05-15 01:25:5513052 if (read_write_round.expected_rv != OK) {
[email protected]044de0642010-06-17 10:42:1513053 EXPECT_EQ(round + 1, test_config.num_auth_rounds);
13054 continue;
13055 }
13056 if (round + 1 < test_config.num_auth_rounds) {
wezca1070932016-05-26 20:30:5213057 EXPECT_TRUE(response->auth_challenge);
[email protected]044de0642010-06-17 10:42:1513058 } else {
wezca1070932016-05-26 20:30:5213059 EXPECT_FALSE(response->auth_challenge);
asankae2257db2016-10-11 22:03:1613060 EXPECT_FALSE(trans.IsReadyToRestartForAuth());
[email protected]044de0642010-06-17 10:42:1513061 }
13062 }
[email protected]e5ae96a2010-04-14 20:12:4513063 }
13064}
13065
bncd16676a2016-07-20 16:23:0113066TEST_F(HttpNetworkTransactionTest, MultiRoundAuth) {
[email protected]c871bce92010-07-15 21:51:1413067 // Do multi-round authentication and make sure it works correctly.
[email protected]c871bce92010-07-15 21:51:1413068 HttpAuthHandlerMock::Factory* auth_factory(
13069 new HttpAuthHandlerMock::Factory());
[email protected]bb88e1d32013-05-03 23:11:0713070 session_deps_.http_auth_handler_factory.reset(auth_factory);
rdsmith82957ad2015-09-16 19:42:0313071 session_deps_.proxy_service = ProxyService::CreateDirect();
[email protected]bb88e1d32013-05-03 23:11:0713072 session_deps_.host_resolver->rules()->AddRule("www.example.com", "10.0.0.1");
13073 session_deps_.host_resolver->set_synchronous_mode(true);
[email protected]c871bce92010-07-15 21:51:1413074
13075 HttpAuthHandlerMock* auth_handler(new HttpAuthHandlerMock());
13076 auth_handler->set_connection_based(true);
13077 std::string auth_challenge = "Mock realm=server";
13078 GURL origin("http://www.example.com");
[email protected]df41d0d82014-03-13 00:43:2413079 HttpAuthChallengeTokenizer tokenizer(auth_challenge.begin(),
13080 auth_challenge.end());
asanka5ffd5d72016-03-23 16:20:4913081 SSLInfo empty_ssl_info;
[email protected]c871bce92010-07-15 21:51:1413082 auth_handler->InitFromChallenge(&tokenizer, HttpAuth::AUTH_SERVER,
tfarina42834112016-09-22 13:38:2013083 empty_ssl_info, origin, NetLogWithSource());
[email protected]2d01c262011-08-11 23:07:0813084 auth_factory->AddMockHandler(auth_handler, HttpAuth::AUTH_SERVER);
[email protected]c871bce92010-07-15 21:51:1413085
[email protected]c871bce92010-07-15 21:51:1413086 int rv = OK;
13087 const HttpResponseInfo* response = NULL;
13088 HttpRequestInfo request;
13089 request.method = "GET";
13090 request.url = origin;
[email protected]cb9bf6ca2011-01-28 13:15:2713091
danakj1fd259a02016-04-16 03:17:0913092 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]7ef4cbbb2011-02-06 11:19:1013093
13094 // Use a TCP Socket Pool with only one connection per group. This is used
13095 // to validate that the TCP socket is not released to the pool between
13096 // each round of multi-round authentication.
mmenkee65e7af2015-10-13 17:16:4213097 HttpNetworkSessionPeer session_peer(session.get());
[email protected]ab739042011-04-07 15:22:2813098 TransportClientSocketPool* transport_pool = new TransportClientSocketPool(
[email protected]7ef4cbbb2011-02-06 11:19:1013099 50, // Max sockets for pool
13100 1, // Max sockets per group
tbansal7b403bcc2016-04-13 22:33:2113101 session_deps_.host_resolver.get(), session_deps_.socket_factory.get(),
13102 NULL, session_deps_.net_log);
Jeremy Roman0579ed62017-08-29 15:56:1913103 auto mock_pool_manager = std::make_unique<MockClientSocketPoolManager>();
[email protected]a42dbd142011-11-17 16:42:0213104 mock_pool_manager->SetTransportSocketPool(transport_pool);
dchengc7eeda422015-12-26 03:56:4813105 session_peer.SetClientSocketPoolManager(std::move(mock_pool_manager));
[email protected]7ef4cbbb2011-02-06 11:19:1013106
bnc691fda62016-08-12 00:43:1613107 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]49639fa2011-12-20 23:22:4113108 TestCompletionCallback callback;
[email protected]c871bce92010-07-15 21:51:1413109
13110 const MockWrite kGet(
13111 "GET / HTTP/1.1\r\n"
13112 "Host: www.example.com\r\n"
13113 "Connection: keep-alive\r\n\r\n");
13114 const MockWrite kGetAuth(
13115 "GET / HTTP/1.1\r\n"
13116 "Host: www.example.com\r\n"
13117 "Connection: keep-alive\r\n"
13118 "Authorization: auth_token\r\n\r\n");
13119
13120 const MockRead kServerChallenge(
13121 "HTTP/1.1 401 Unauthorized\r\n"
13122 "WWW-Authenticate: Mock realm=server\r\n"
13123 "Content-Type: text/html; charset=iso-8859-1\r\n"
13124 "Content-Length: 14\r\n\r\n"
13125 "Unauthorized\r\n");
13126 const MockRead kSuccess(
13127 "HTTP/1.1 200 OK\r\n"
13128 "Content-Type: text/html; charset=iso-8859-1\r\n"
13129 "Content-Length: 3\r\n\r\n"
13130 "Yes");
13131
13132 MockWrite writes[] = {
13133 // First round
13134 kGet,
13135 // Second round
13136 kGetAuth,
13137 // Third round
13138 kGetAuth,
[email protected]eca50e122010-09-11 14:03:3013139 // Fourth round
[email protected]7ef4cbbb2011-02-06 11:19:1013140 kGetAuth,
13141 // Competing request
13142 kGet,
[email protected]c871bce92010-07-15 21:51:1413143 };
13144 MockRead reads[] = {
13145 // First round
13146 kServerChallenge,
13147 // Second round
13148 kServerChallenge,
13149 // Third round
[email protected]eca50e122010-09-11 14:03:3013150 kServerChallenge,
13151 // Fourth round
[email protected]c871bce92010-07-15 21:51:1413152 kSuccess,
[email protected]7ef4cbbb2011-02-06 11:19:1013153 // Competing response
13154 kSuccess,
[email protected]c871bce92010-07-15 21:51:1413155 };
13156 StaticSocketDataProvider data_provider(reads, arraysize(reads),
13157 writes, arraysize(writes));
[email protected]bb88e1d32013-05-03 23:11:0713158 session_deps_.socket_factory->AddSocketDataProvider(&data_provider);
[email protected]c871bce92010-07-15 21:51:1413159
thestig9d3bb0c2015-01-24 00:49:5113160 const char kSocketGroup[] = "www.example.com:80";
[email protected]7ef4cbbb2011-02-06 11:19:1013161
13162 // First round of authentication.
[email protected]c871bce92010-07-15 21:51:1413163 auth_handler->SetGenerateExpectation(false, OK);
tfarina42834112016-09-22 13:38:2013164 rv = trans.Start(&request, callback.callback(), NetLogWithSource());
[email protected]c871bce92010-07-15 21:51:1413165 if (rv == ERR_IO_PENDING)
13166 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0113167 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:1613168 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5213169 ASSERT_TRUE(response);
13170 EXPECT_TRUE(response->auth_challenge);
[email protected]ab739042011-04-07 15:22:2813171 EXPECT_EQ(0, transport_pool->IdleSocketCountInGroup(kSocketGroup));
asanka463ca4262016-11-16 02:34:3113172 EXPECT_EQ(HttpAuthHandlerMock::State::WAIT_FOR_GENERATE_AUTH_TOKEN,
13173 auth_handler->state());
[email protected]c871bce92010-07-15 21:51:1413174
[email protected]7ef4cbbb2011-02-06 11:19:1013175 // In between rounds, another request comes in for the same domain.
13176 // It should not be able to grab the TCP socket that trans has already
13177 // claimed.
bnc691fda62016-08-12 00:43:1613178 HttpNetworkTransaction trans_compete(DEFAULT_PRIORITY, session.get());
[email protected]49639fa2011-12-20 23:22:4113179 TestCompletionCallback callback_compete;
tfarina42834112016-09-22 13:38:2013180 rv = trans_compete.Start(&request, callback_compete.callback(),
13181 NetLogWithSource());
robpercival214763f2016-07-01 23:27:0113182 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]7ef4cbbb2011-02-06 11:19:1013183 // callback_compete.WaitForResult at this point would stall forever,
13184 // since the HttpNetworkTransaction does not release the request back to
13185 // the pool until after authentication completes.
13186
13187 // Second round of authentication.
[email protected]c871bce92010-07-15 21:51:1413188 auth_handler->SetGenerateExpectation(false, OK);
bnc691fda62016-08-12 00:43:1613189 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar), callback.callback());
[email protected]c871bce92010-07-15 21:51:1413190 if (rv == ERR_IO_PENDING)
13191 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0113192 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:1613193 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5213194 ASSERT_TRUE(response);
13195 EXPECT_FALSE(response->auth_challenge);
[email protected]ab739042011-04-07 15:22:2813196 EXPECT_EQ(0, transport_pool->IdleSocketCountInGroup(kSocketGroup));
asanka463ca4262016-11-16 02:34:3113197 EXPECT_EQ(HttpAuthHandlerMock::State::WAIT_FOR_GENERATE_AUTH_TOKEN,
13198 auth_handler->state());
[email protected]c871bce92010-07-15 21:51:1413199
[email protected]7ef4cbbb2011-02-06 11:19:1013200 // Third round of authentication.
[email protected]c871bce92010-07-15 21:51:1413201 auth_handler->SetGenerateExpectation(false, OK);
bnc691fda62016-08-12 00:43:1613202 rv = trans.RestartWithAuth(AuthCredentials(), callback.callback());
[email protected]c871bce92010-07-15 21:51:1413203 if (rv == ERR_IO_PENDING)
13204 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0113205 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:1613206 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5213207 ASSERT_TRUE(response);
13208 EXPECT_FALSE(response->auth_challenge);
[email protected]ab739042011-04-07 15:22:2813209 EXPECT_EQ(0, transport_pool->IdleSocketCountInGroup(kSocketGroup));
asanka463ca4262016-11-16 02:34:3113210 EXPECT_EQ(HttpAuthHandlerMock::State::WAIT_FOR_GENERATE_AUTH_TOKEN,
13211 auth_handler->state());
[email protected]eca50e122010-09-11 14:03:3013212
[email protected]7ef4cbbb2011-02-06 11:19:1013213 // Fourth round of authentication, which completes successfully.
[email protected]eca50e122010-09-11 14:03:3013214 auth_handler->SetGenerateExpectation(false, OK);
bnc691fda62016-08-12 00:43:1613215 rv = trans.RestartWithAuth(AuthCredentials(), callback.callback());
[email protected]eca50e122010-09-11 14:03:3013216 if (rv == ERR_IO_PENDING)
13217 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0113218 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:1613219 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5213220 ASSERT_TRUE(response);
13221 EXPECT_FALSE(response->auth_challenge);
[email protected]ab739042011-04-07 15:22:2813222 EXPECT_EQ(0, transport_pool->IdleSocketCountInGroup(kSocketGroup));
[email protected]7ef4cbbb2011-02-06 11:19:1013223
asanka463ca4262016-11-16 02:34:3113224 // In WAIT_FOR_CHALLENGE, although in reality the auth handler is done. A real
13225 // auth handler should transition to a DONE state in concert with the remote
13226 // server. But that's not something we can test here with a mock handler.
13227 EXPECT_EQ(HttpAuthHandlerMock::State::WAIT_FOR_CHALLENGE,
13228 auth_handler->state());
13229
[email protected]7ef4cbbb2011-02-06 11:19:1013230 // Read the body since the fourth round was successful. This will also
13231 // release the socket back to the pool.
13232 scoped_refptr<IOBufferWithSize> io_buf(new IOBufferWithSize(50));
bnc691fda62016-08-12 00:43:1613233 rv = trans.Read(io_buf.get(), io_buf->size(), callback.callback());
[email protected]7ef4cbbb2011-02-06 11:19:1013234 if (rv == ERR_IO_PENDING)
13235 rv = callback.WaitForResult();
13236 EXPECT_EQ(3, rv);
bnc691fda62016-08-12 00:43:1613237 rv = trans.Read(io_buf.get(), io_buf->size(), callback.callback());
[email protected]7ef4cbbb2011-02-06 11:19:1013238 EXPECT_EQ(0, rv);
13239 // There are still 0 idle sockets, since the trans_compete transaction
13240 // will be handed it immediately after trans releases it to the group.
[email protected]ab739042011-04-07 15:22:2813241 EXPECT_EQ(0, transport_pool->IdleSocketCountInGroup(kSocketGroup));
[email protected]7ef4cbbb2011-02-06 11:19:1013242
13243 // The competing request can now finish. Wait for the headers and then
13244 // read the body.
13245 rv = callback_compete.WaitForResult();
robpercival214763f2016-07-01 23:27:0113246 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:1613247 rv = trans_compete.Read(io_buf.get(), io_buf->size(), callback.callback());
[email protected]7ef4cbbb2011-02-06 11:19:1013248 if (rv == ERR_IO_PENDING)
13249 rv = callback.WaitForResult();
13250 EXPECT_EQ(3, rv);
bnc691fda62016-08-12 00:43:1613251 rv = trans_compete.Read(io_buf.get(), io_buf->size(), callback.callback());
[email protected]7ef4cbbb2011-02-06 11:19:1013252 EXPECT_EQ(0, rv);
13253
13254 // Finally, the socket is released to the group.
[email protected]ab739042011-04-07 15:22:2813255 EXPECT_EQ(1, transport_pool->IdleSocketCountInGroup(kSocketGroup));
[email protected]c871bce92010-07-15 21:51:1413256}
13257
[email protected]65041fa2010-05-21 06:56:5313258// This tests the case that a request is issued via http instead of spdy after
13259// npn is negotiated.
bncd16676a2016-07-20 16:23:0113260TEST_F(HttpNetworkTransactionTest, NpnWithHttpOverSSL) {
[email protected]65041fa2010-05-21 06:56:5313261 HttpRequestInfo request;
13262 request.method = "GET";
bncce36dca22015-04-21 22:11:2313263 request.url = GURL("https://www.example.org/");
[email protected]65041fa2010-05-21 06:56:5313264
13265 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:2313266 MockWrite(
13267 "GET / HTTP/1.1\r\n"
13268 "Host: www.example.org\r\n"
13269 "Connection: keep-alive\r\n\r\n"),
[email protected]65041fa2010-05-21 06:56:5313270 };
13271
13272 MockRead data_reads[] = {
bncc958faa2015-07-31 18:14:5213273 MockRead("HTTP/1.1 200 OK\r\n"),
bnc2df4b522016-07-08 18:17:4313274 MockRead(kAlternativeServiceHttpHeader),
bncc958faa2015-07-31 18:14:5213275 MockRead("\r\n"),
13276 MockRead("hello world"),
13277 MockRead(SYNCHRONOUS, OK),
[email protected]65041fa2010-05-21 06:56:5313278 };
13279
[email protected]8ddf8322012-02-23 18:08:0613280 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3613281 ssl.next_proto = kProtoHTTP11;
[email protected]65041fa2010-05-21 06:56:5313282
[email protected]bb88e1d32013-05-03 23:11:0713283 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]65041fa2010-05-21 06:56:5313284
13285 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
13286 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:0713287 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]65041fa2010-05-21 06:56:5313288
[email protected]49639fa2011-12-20 23:22:4113289 TestCompletionCallback callback;
[email protected]65041fa2010-05-21 06:56:5313290
danakj1fd259a02016-04-16 03:17:0913291 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1613292 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]65041fa2010-05-21 06:56:5313293
tfarina42834112016-09-22 13:38:2013294 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
[email protected]65041fa2010-05-21 06:56:5313295
robpercival214763f2016-07-01 23:27:0113296 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
13297 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]65041fa2010-05-21 06:56:5313298
bnc691fda62016-08-12 00:43:1613299 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5213300 ASSERT_TRUE(response);
13301 ASSERT_TRUE(response->headers);
[email protected]65041fa2010-05-21 06:56:5313302 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
13303
13304 std::string response_data;
bnc691fda62016-08-12 00:43:1613305 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
[email protected]65041fa2010-05-21 06:56:5313306 EXPECT_EQ("hello world", response_data);
13307
13308 EXPECT_FALSE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5213309 EXPECT_TRUE(response->was_alpn_negotiated);
[email protected]65041fa2010-05-21 06:56:5313310}
[email protected]26ef6582010-06-24 02:30:4713311
bnc55ff9da2015-08-19 18:42:3513312// Simulate the SSL handshake completing with an NPN negotiation followed by an
13313// immediate server closing of the socket.
13314// Regression test for https://crbug.com/46369.
bncd16676a2016-07-20 16:23:0113315TEST_F(HttpNetworkTransactionTest, SpdyPostNPNServerHangup) {
[email protected]26ef6582010-06-24 02:30:4713316 HttpRequestInfo request;
13317 request.method = "GET";
bncce36dca22015-04-21 22:11:2313318 request.url = GURL("https://www.example.org/");
[email protected]26ef6582010-06-24 02:30:4713319
[email protected]8ddf8322012-02-23 18:08:0613320 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3613321 ssl.next_proto = kProtoHTTP2;
[email protected]bb88e1d32013-05-03 23:11:0713322 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]26ef6582010-06-24 02:30:4713323
bncdf80d44fd2016-07-15 20:27:4113324 SpdySerializedFrame req(
bnc38dcd392016-02-09 23:19:4913325 spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST, true));
bncdf80d44fd2016-07-15 20:27:4113326 MockWrite spdy_writes[] = {CreateMockWrite(req, 1)};
[email protected]26ef6582010-06-24 02:30:4713327
13328 MockRead spdy_reads[] = {
[email protected]8ddf8322012-02-23 18:08:0613329 MockRead(SYNCHRONOUS, 0, 0) // Not async - return 0 immediately.
[email protected]26ef6582010-06-24 02:30:4713330 };
13331
rch8e6c6c42015-05-01 14:05:1313332 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
13333 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:0713334 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]26ef6582010-06-24 02:30:4713335
[email protected]49639fa2011-12-20 23:22:4113336 TestCompletionCallback callback;
[email protected]26ef6582010-06-24 02:30:4713337
danakj1fd259a02016-04-16 03:17:0913338 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1613339 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]26ef6582010-06-24 02:30:4713340
tfarina42834112016-09-22 13:38:2013341 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0113342 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
13343 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_CONNECTION_CLOSED));
[email protected]26ef6582010-06-24 02:30:4713344}
[email protected]65d34382010-07-01 18:12:2613345
[email protected]795cbf82013-07-22 09:37:2713346// A subclass of HttpAuthHandlerMock that records the request URL when
13347// it gets it. This is needed since the auth handler may get destroyed
13348// before we get a chance to query it.
13349class UrlRecordingHttpAuthHandlerMock : public HttpAuthHandlerMock {
13350 public:
13351 explicit UrlRecordingHttpAuthHandlerMock(GURL* url) : url_(url) {}
13352
Chris Watkins7a41d3552017-12-01 02:13:2713353 ~UrlRecordingHttpAuthHandlerMock() override = default;
[email protected]795cbf82013-07-22 09:37:2713354
13355 protected:
dchengb03027d2014-10-21 12:00:2013356 int GenerateAuthTokenImpl(const AuthCredentials* credentials,
13357 const HttpRequestInfo* request,
13358 const CompletionCallback& callback,
13359 std::string* auth_token) override {
[email protected]795cbf82013-07-22 09:37:2713360 *url_ = request->url;
13361 return HttpAuthHandlerMock::GenerateAuthTokenImpl(
13362 credentials, request, callback, auth_token);
13363 }
13364
13365 private:
13366 GURL* url_;
13367};
13368
[email protected]8e6441ca2010-08-19 05:56:3813369// Test that if we cancel the transaction as the connection is completing, that
13370// everything tears down correctly.
bncd16676a2016-07-20 16:23:0113371TEST_F(HttpNetworkTransactionTest, SimpleCancel) {
[email protected]8e6441ca2010-08-19 05:56:3813372 // Setup everything about the connection to complete synchronously, so that
13373 // after calling HttpNetworkTransaction::Start, the only thing we're waiting
13374 // for is the callback from the HttpStreamRequest.
13375 // Then cancel the transaction.
13376 // Verify that we don't crash.
[email protected]d973e99a2012-02-17 21:02:3613377 MockConnect mock_connect(SYNCHRONOUS, OK);
[email protected]8e6441ca2010-08-19 05:56:3813378 MockRead data_reads[] = {
[email protected]8ddf8322012-02-23 18:08:0613379 MockRead(SYNCHRONOUS, "HTTP/1.0 200 OK\r\n\r\n"),
13380 MockRead(SYNCHRONOUS, "hello world"),
13381 MockRead(SYNCHRONOUS, OK),
[email protected]8e6441ca2010-08-19 05:56:3813382 };
13383
[email protected]8e6441ca2010-08-19 05:56:3813384 HttpRequestInfo request;
13385 request.method = "GET";
bncce36dca22015-04-21 22:11:2313386 request.url = GURL("http://www.example.org/");
[email protected]8e6441ca2010-08-19 05:56:3813387
[email protected]bb88e1d32013-05-03 23:11:0713388 session_deps_.host_resolver->set_synchronous_mode(true);
danakj1fd259a02016-04-16 03:17:0913389 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc87dcefc2017-05-25 12:47:5813390 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:1913391 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:2713392
[email protected]8e6441ca2010-08-19 05:56:3813393 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
13394 data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:0713395 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]8e6441ca2010-08-19 05:56:3813396
[email protected]49639fa2011-12-20 23:22:4113397 TestCompletionCallback callback;
[email protected]8e6441ca2010-08-19 05:56:3813398
vishal.b62985ca92015-04-17 08:45:5113399 BoundTestNetLog log;
[email protected]49639fa2011-12-20 23:22:4113400 int rv = trans->Start(&request, callback.callback(), log.bound());
robpercival214763f2016-07-01 23:27:0113401 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]8e6441ca2010-08-19 05:56:3813402 trans.reset(); // Cancel the transaction here.
13403
fdoray92e35a72016-06-10 15:54:5513404 base::RunLoop().RunUntilIdle();
[email protected]f45c1ee2010-08-03 00:54:3013405}
13406
[email protected]ecab6e052014-05-16 14:58:1213407// Test that if a transaction is cancelled after receiving the headers, the
13408// stream is drained properly and added back to the socket pool. The main
13409// purpose of this test is to make sure that an HttpStreamParser can be read
13410// from after the HttpNetworkTransaction and the objects it owns have been
13411// deleted.
13412// See http://crbug.com/368418
bncd16676a2016-07-20 16:23:0113413TEST_F(HttpNetworkTransactionTest, CancelAfterHeaders) {
[email protected]ecab6e052014-05-16 14:58:1213414 MockRead data_reads[] = {
13415 MockRead(ASYNC, "HTTP/1.1 200 OK\r\n"),
13416 MockRead(ASYNC, "Content-Length: 2\r\n"),
13417 MockRead(ASYNC, "Connection: Keep-Alive\r\n\r\n"),
13418 MockRead(ASYNC, "1"),
13419 // 2 async reads are necessary to trigger a ReadResponseBody call after the
13420 // HttpNetworkTransaction has been deleted.
13421 MockRead(ASYNC, "2"),
13422 MockRead(SYNCHRONOUS, ERR_IO_PENDING), // Should never read this.
13423 };
13424 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
13425 session_deps_.socket_factory->AddSocketDataProvider(&data);
13426
danakj1fd259a02016-04-16 03:17:0913427 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]ecab6e052014-05-16 14:58:1213428
13429 {
13430 HttpRequestInfo request;
13431 request.method = "GET";
bncce36dca22015-04-21 22:11:2313432 request.url = GURL("http://www.example.org/");
[email protected]ecab6e052014-05-16 14:58:1213433
dcheng48459ac22014-08-26 00:46:4113434 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]ecab6e052014-05-16 14:58:1213435 TestCompletionCallback callback;
13436
tfarina42834112016-09-22 13:38:2013437 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0113438 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]ecab6e052014-05-16 14:58:1213439 callback.WaitForResult();
13440
13441 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5213442 ASSERT_TRUE(response);
13443 EXPECT_TRUE(response->headers);
[email protected]ecab6e052014-05-16 14:58:1213444 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
13445
13446 // The transaction and HttpRequestInfo are deleted.
13447 }
13448
13449 // Let the HttpResponseBodyDrainer drain the socket.
fdoray92e35a72016-06-10 15:54:5513450 base::RunLoop().RunUntilIdle();
[email protected]ecab6e052014-05-16 14:58:1213451
13452 // Socket should now be idle, waiting to be reused.
dcheng48459ac22014-08-26 00:46:4113453 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]ecab6e052014-05-16 14:58:1213454}
13455
[email protected]76a505b2010-08-25 06:23:0013456// Test a basic GET request through a proxy.
bncd16676a2016-07-20 16:23:0113457TEST_F(HttpNetworkTransactionTest, ProxyGet) {
rdsmith82957ad2015-09-16 19:42:0313458 session_deps_.proxy_service =
13459 ProxyService::CreateFixedFromPacResult("PROXY myproxy:70");
vishal.b62985ca92015-04-17 08:45:5113460 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:0713461 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:0913462 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]76a505b2010-08-25 06:23:0013463
[email protected]76a505b2010-08-25 06:23:0013464 HttpRequestInfo request;
13465 request.method = "GET";
bncce36dca22015-04-21 22:11:2313466 request.url = GURL("http://www.example.org/");
[email protected]76a505b2010-08-25 06:23:0013467
13468 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:2313469 MockWrite(
13470 "GET http://www.example.org/ HTTP/1.1\r\n"
13471 "Host: www.example.org\r\n"
13472 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]76a505b2010-08-25 06:23:0013473 };
13474
13475 MockRead data_reads1[] = {
13476 MockRead("HTTP/1.1 200 OK\r\n"),
13477 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
13478 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:0613479 MockRead(SYNCHRONOUS, OK),
[email protected]76a505b2010-08-25 06:23:0013480 };
13481
13482 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
13483 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:0713484 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]76a505b2010-08-25 06:23:0013485
[email protected]49639fa2011-12-20 23:22:4113486 TestCompletionCallback callback1;
[email protected]76a505b2010-08-25 06:23:0013487
bnc691fda62016-08-12 00:43:1613488 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
ryansturm49a8cb12016-06-15 16:51:0913489 BeforeHeadersSentHandler headers_handler;
bnc691fda62016-08-12 00:43:1613490 trans.SetBeforeHeadersSentCallback(
ryansturm49a8cb12016-06-15 16:51:0913491 base::Bind(&BeforeHeadersSentHandler::OnBeforeHeadersSent,
13492 base::Unretained(&headers_handler)));
[email protected]0b0bf032010-09-21 18:08:5013493
bnc691fda62016-08-12 00:43:1613494 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:0113495 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]76a505b2010-08-25 06:23:0013496
13497 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:0113498 EXPECT_THAT(rv, IsOk());
[email protected]76a505b2010-08-25 06:23:0013499
bnc691fda62016-08-12 00:43:1613500 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5213501 ASSERT_TRUE(response);
[email protected]76a505b2010-08-25 06:23:0013502
13503 EXPECT_TRUE(response->headers->IsKeepAlive());
13504 EXPECT_EQ(200, response->headers->response_code());
13505 EXPECT_EQ(100, response->headers->GetContentLength());
13506 EXPECT_TRUE(response->was_fetched_via_proxy);
tbansal2ecbbc72016-10-06 17:15:4713507 EXPECT_EQ(ProxyServer(ProxyServer::SCHEME_HTTP,
13508 HostPortPair::FromString("myproxy:70")),
13509 response->proxy_server);
ryansturm49a8cb12016-06-15 16:51:0913510 EXPECT_TRUE(headers_handler.observed_before_headers_sent());
13511 EXPECT_TRUE(headers_handler.observed_before_headers_sent_with_proxy());
13512 EXPECT_EQ("myproxy:70", headers_handler.observed_proxy_server_uri());
[email protected]76a505b2010-08-25 06:23:0013513 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
[email protected]029c83b62013-01-24 05:28:2013514
13515 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:1613516 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]029c83b62013-01-24 05:28:2013517 TestLoadTimingNotReusedWithPac(load_timing_info,
13518 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
[email protected]76a505b2010-08-25 06:23:0013519}
13520
13521// Test a basic HTTPS GET request through a proxy.
bncd16676a2016-07-20 16:23:0113522TEST_F(HttpNetworkTransactionTest, ProxyTunnelGet) {
rdsmith82957ad2015-09-16 19:42:0313523 session_deps_.proxy_service =
13524 ProxyService::CreateFixedFromPacResult("PROXY myproxy:70");
vishal.b62985ca92015-04-17 08:45:5113525 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:0713526 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:0913527 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]76a505b2010-08-25 06:23:0013528
[email protected]76a505b2010-08-25 06:23:0013529 HttpRequestInfo request;
13530 request.method = "GET";
bncce36dca22015-04-21 22:11:2313531 request.url = GURL("https://www.example.org/");
[email protected]76a505b2010-08-25 06:23:0013532
13533 // Since we have proxy, should try to establish tunnel.
13534 MockWrite data_writes1[] = {
rsleevidb16bb02015-11-12 23:47:1713535 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
13536 "Host: www.example.org:443\r\n"
13537 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]76a505b2010-08-25 06:23:0013538
rsleevidb16bb02015-11-12 23:47:1713539 MockWrite("GET / HTTP/1.1\r\n"
13540 "Host: www.example.org\r\n"
13541 "Connection: keep-alive\r\n\r\n"),
[email protected]76a505b2010-08-25 06:23:0013542 };
13543
13544 MockRead data_reads1[] = {
13545 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
13546
13547 MockRead("HTTP/1.1 200 OK\r\n"),
13548 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
13549 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:0613550 MockRead(SYNCHRONOUS, OK),
[email protected]76a505b2010-08-25 06:23:0013551 };
13552
13553 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
13554 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:0713555 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8ddf8322012-02-23 18:08:0613556 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:0713557 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]76a505b2010-08-25 06:23:0013558
[email protected]49639fa2011-12-20 23:22:4113559 TestCompletionCallback callback1;
[email protected]76a505b2010-08-25 06:23:0013560
bnc691fda62016-08-12 00:43:1613561 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
ryansturm49a8cb12016-06-15 16:51:0913562 BeforeHeadersSentHandler headers_handler;
bnc691fda62016-08-12 00:43:1613563 trans.SetBeforeHeadersSentCallback(
ryansturm49a8cb12016-06-15 16:51:0913564 base::Bind(&BeforeHeadersSentHandler::OnBeforeHeadersSent,
13565 base::Unretained(&headers_handler)));
[email protected]0b0bf032010-09-21 18:08:5013566
bnc691fda62016-08-12 00:43:1613567 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:0113568 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]76a505b2010-08-25 06:23:0013569
13570 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:0113571 EXPECT_THAT(rv, IsOk());
mmenke43758e62015-05-04 21:09:4613572 TestNetLogEntry::List entries;
[email protected]b2fcd0e2010-12-01 15:19:4013573 log.GetEntries(&entries);
[email protected]76a505b2010-08-25 06:23:0013574 size_t pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:0013575 entries, 0, NetLogEventType::HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
13576 NetLogEventPhase::NONE);
[email protected]76a505b2010-08-25 06:23:0013577 ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:4013578 entries, pos,
mikecirone8b85c432016-09-08 19:11:0013579 NetLogEventType::HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
13580 NetLogEventPhase::NONE);
[email protected]76a505b2010-08-25 06:23:0013581
bnc691fda62016-08-12 00:43:1613582 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5213583 ASSERT_TRUE(response);
[email protected]76a505b2010-08-25 06:23:0013584
13585 EXPECT_TRUE(response->headers->IsKeepAlive());
13586 EXPECT_EQ(200, response->headers->response_code());
13587 EXPECT_EQ(100, response->headers->GetContentLength());
13588 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
13589 EXPECT_TRUE(response->was_fetched_via_proxy);
tbansal2ecbbc72016-10-06 17:15:4713590 EXPECT_EQ(ProxyServer(ProxyServer::SCHEME_HTTP,
13591 HostPortPair::FromString("myproxy:70")),
13592 response->proxy_server);
ryansturm49a8cb12016-06-15 16:51:0913593 EXPECT_TRUE(headers_handler.observed_before_headers_sent());
13594 EXPECT_TRUE(headers_handler.observed_before_headers_sent_with_proxy());
13595 EXPECT_EQ("myproxy:70", headers_handler.observed_proxy_server_uri());
[email protected]029c83b62013-01-24 05:28:2013596
13597 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:1613598 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]029c83b62013-01-24 05:28:2013599 TestLoadTimingNotReusedWithPac(load_timing_info,
13600 CONNECT_TIMING_HAS_SSL_TIMES);
[email protected]76a505b2010-08-25 06:23:0013601}
13602
rsleevidb16bb02015-11-12 23:47:1713603// Test a basic HTTPS GET request through a proxy, connecting to an IPv6
13604// literal host.
bncd16676a2016-07-20 16:23:0113605TEST_F(HttpNetworkTransactionTest, ProxyTunnelGetIPv6) {
rsleevidb16bb02015-11-12 23:47:1713606 session_deps_.proxy_service =
13607 ProxyService::CreateFixedFromPacResult("PROXY myproxy:70");
13608 BoundTestNetLog log;
13609 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:0913610 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
rsleevidb16bb02015-11-12 23:47:1713611
13612 HttpRequestInfo request;
13613 request.method = "GET";
13614 request.url = GURL("https://[::1]:443/");
13615
13616 // Since we have proxy, should try to establish tunnel.
13617 MockWrite data_writes1[] = {
13618 MockWrite("CONNECT [::1]:443 HTTP/1.1\r\n"
13619 "Host: [::1]:443\r\n"
13620 "Proxy-Connection: keep-alive\r\n\r\n"),
13621
13622 MockWrite("GET / HTTP/1.1\r\n"
13623 "Host: [::1]\r\n"
13624 "Connection: keep-alive\r\n\r\n"),
13625 };
13626
13627 MockRead data_reads1[] = {
13628 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
13629
13630 MockRead("HTTP/1.1 200 OK\r\n"),
13631 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
13632 MockRead("Content-Length: 100\r\n\r\n"),
13633 MockRead(SYNCHRONOUS, OK),
13634 };
13635
13636 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
13637 data_writes1, arraysize(data_writes1));
13638 session_deps_.socket_factory->AddSocketDataProvider(&data1);
13639 SSLSocketDataProvider ssl(ASYNC, OK);
13640 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
13641
13642 TestCompletionCallback callback1;
13643
bnc691fda62016-08-12 00:43:1613644 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
rsleevidb16bb02015-11-12 23:47:1713645
bnc691fda62016-08-12 00:43:1613646 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:0113647 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
rsleevidb16bb02015-11-12 23:47:1713648
13649 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:0113650 EXPECT_THAT(rv, IsOk());
rsleevidb16bb02015-11-12 23:47:1713651 TestNetLogEntry::List entries;
13652 log.GetEntries(&entries);
13653 size_t pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:0013654 entries, 0, NetLogEventType::HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
13655 NetLogEventPhase::NONE);
rsleevidb16bb02015-11-12 23:47:1713656 ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:0013657 entries, pos,
13658 NetLogEventType::HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
13659 NetLogEventPhase::NONE);
rsleevidb16bb02015-11-12 23:47:1713660
bnc691fda62016-08-12 00:43:1613661 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5213662 ASSERT_TRUE(response);
rsleevidb16bb02015-11-12 23:47:1713663
13664 EXPECT_TRUE(response->headers->IsKeepAlive());
13665 EXPECT_EQ(200, response->headers->response_code());
13666 EXPECT_EQ(100, response->headers->GetContentLength());
13667 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
13668 EXPECT_TRUE(response->was_fetched_via_proxy);
tbansal2ecbbc72016-10-06 17:15:4713669 EXPECT_EQ(ProxyServer(ProxyServer::SCHEME_HTTP,
13670 HostPortPair::FromString("myproxy:70")),
13671 response->proxy_server);
rsleevidb16bb02015-11-12 23:47:1713672
13673 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:1613674 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
rsleevidb16bb02015-11-12 23:47:1713675 TestLoadTimingNotReusedWithPac(load_timing_info,
13676 CONNECT_TIMING_HAS_SSL_TIMES);
13677}
13678
[email protected]76a505b2010-08-25 06:23:0013679// Test a basic HTTPS GET request through a proxy, but the server hangs up
13680// while establishing the tunnel.
bncd16676a2016-07-20 16:23:0113681TEST_F(HttpNetworkTransactionTest, ProxyTunnelGetHangup) {
rdsmith82957ad2015-09-16 19:42:0313682 session_deps_.proxy_service = ProxyService::CreateFixed("myproxy:70");
vishal.b62985ca92015-04-17 08:45:5113683 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:0713684 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:0913685 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]76a505b2010-08-25 06:23:0013686
[email protected]76a505b2010-08-25 06:23:0013687 HttpRequestInfo request;
13688 request.method = "GET";
bncce36dca22015-04-21 22:11:2313689 request.url = GURL("https://www.example.org/");
[email protected]76a505b2010-08-25 06:23:0013690
13691 // Since we have proxy, should try to establish tunnel.
13692 MockWrite data_writes1[] = {
rsleevidb16bb02015-11-12 23:47:1713693 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
13694 "Host: www.example.org:443\r\n"
13695 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]76a505b2010-08-25 06:23:0013696
rsleevidb16bb02015-11-12 23:47:1713697 MockWrite("GET / HTTP/1.1\r\n"
13698 "Host: www.example.org\r\n"
13699 "Connection: keep-alive\r\n\r\n"),
[email protected]76a505b2010-08-25 06:23:0013700 };
13701
13702 MockRead data_reads1[] = {
[email protected]76a505b2010-08-25 06:23:0013703 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:0613704 MockRead(ASYNC, 0, 0), // EOF
[email protected]76a505b2010-08-25 06:23:0013705 };
13706
13707 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
13708 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:0713709 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8ddf8322012-02-23 18:08:0613710 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:0713711 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]76a505b2010-08-25 06:23:0013712
[email protected]49639fa2011-12-20 23:22:4113713 TestCompletionCallback callback1;
[email protected]76a505b2010-08-25 06:23:0013714
bnc691fda62016-08-12 00:43:1613715 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]0b0bf032010-09-21 18:08:5013716
bnc691fda62016-08-12 00:43:1613717 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:0113718 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]76a505b2010-08-25 06:23:0013719
13720 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:0113721 EXPECT_THAT(rv, IsError(ERR_EMPTY_RESPONSE));
mmenke43758e62015-05-04 21:09:4613722 TestNetLogEntry::List entries;
[email protected]b2fcd0e2010-12-01 15:19:4013723 log.GetEntries(&entries);
[email protected]76a505b2010-08-25 06:23:0013724 size_t pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:0013725 entries, 0, NetLogEventType::HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
13726 NetLogEventPhase::NONE);
[email protected]76a505b2010-08-25 06:23:0013727 ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:4013728 entries, pos,
mikecirone8b85c432016-09-08 19:11:0013729 NetLogEventType::HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
13730 NetLogEventPhase::NONE);
[email protected]76a505b2010-08-25 06:23:0013731}
13732
[email protected]749eefa82010-09-13 22:14:0313733// Test for crbug.com/55424.
bncd16676a2016-07-20 16:23:0113734TEST_F(HttpNetworkTransactionTest, PreconnectWithExistingSpdySession) {
bncdf80d44fd2016-07-15 20:27:4113735 SpdySerializedFrame req(
bnc38dcd392016-02-09 23:19:4913736 spdy_util_.ConstructSpdyGet("https://www.example.org", 1, LOWEST));
bncdf80d44fd2016-07-15 20:27:4113737 MockWrite spdy_writes[] = {CreateMockWrite(req, 0)};
[email protected]749eefa82010-09-13 22:14:0313738
bnc42331402016-07-25 13:36:1513739 SpdySerializedFrame resp(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
bncdf80d44fd2016-07-15 20:27:4113740 SpdySerializedFrame data(spdy_util_.ConstructSpdyDataFrame(1, true));
[email protected]749eefa82010-09-13 22:14:0313741 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:4113742 CreateMockRead(resp, 1), CreateMockRead(data, 2), MockRead(ASYNC, 0, 3),
[email protected]749eefa82010-09-13 22:14:0313743 };
13744
rch8e6c6c42015-05-01 14:05:1313745 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
13746 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:0713747 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]749eefa82010-09-13 22:14:0313748
[email protected]8ddf8322012-02-23 18:08:0613749 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3613750 ssl.next_proto = kProtoHTTP2;
[email protected]bb88e1d32013-05-03 23:11:0713751 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]749eefa82010-09-13 22:14:0313752
danakj1fd259a02016-04-16 03:17:0913753 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]749eefa82010-09-13 22:14:0313754
13755 // Set up an initial SpdySession in the pool to reuse.
bncce36dca22015-04-21 22:11:2313756 HostPortPair host_port_pair("www.example.org", 443);
[email protected]e6d017652013-05-17 18:01:4013757 SpdySessionKey key(host_port_pair, ProxyServer::Direct(),
[email protected]314b03992014-04-01 01:28:5313758 PRIVACY_MODE_DISABLED);
[email protected]795cbf82013-07-22 09:37:2713759 base::WeakPtr<SpdySession> spdy_session =
Bence Béky0ef1556e2017-06-30 19:52:5213760 CreateSpdySession(session.get(), key, NetLogWithSource());
[email protected]749eefa82010-09-13 22:14:0313761
13762 HttpRequestInfo request;
13763 request.method = "GET";
bncce36dca22015-04-21 22:11:2313764 request.url = GURL("https://www.example.org/");
[email protected]749eefa82010-09-13 22:14:0313765
13766 // This is the important line that marks this as a preconnect.
13767 request.motivation = HttpRequestInfo::PRECONNECT_MOTIVATED;
13768
bnc691fda62016-08-12 00:43:1613769 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]749eefa82010-09-13 22:14:0313770
[email protected]41d64e82013-07-03 22:44:2613771 TestCompletionCallback callback;
tfarina42834112016-09-22 13:38:2013772 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0113773 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
13774 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]749eefa82010-09-13 22:14:0313775}
13776
[email protected]73b8dd222010-11-11 19:55:2413777// Given a net error, cause that error to be returned from the first Write()
bnc691fda62016-08-12 00:43:1613778// call and verify that the HttpNetworkTransaction fails with that error.
[email protected]23e482282013-06-14 16:08:0213779void HttpNetworkTransactionTest::CheckErrorIsPassedBack(
[email protected]bb88e1d32013-05-03 23:11:0713780 int error, IoMode mode) {
ttuttle859dc7a2015-04-23 19:42:2913781 HttpRequestInfo request_info;
[email protected]cb9bf6ca2011-01-28 13:15:2713782 request_info.url = GURL("https://www.example.com/");
13783 request_info.method = "GET";
ttuttle859dc7a2015-04-23 19:42:2913784 request_info.load_flags = LOAD_NORMAL;
[email protected]cb9bf6ca2011-01-28 13:15:2713785
[email protected]8ddf8322012-02-23 18:08:0613786 SSLSocketDataProvider ssl_data(mode, OK);
ttuttle859dc7a2015-04-23 19:42:2913787 MockWrite data_writes[] = {
13788 MockWrite(mode, error),
[email protected]73b8dd222010-11-11 19:55:2413789 };
ttuttle859dc7a2015-04-23 19:42:2913790 StaticSocketDataProvider data(NULL, 0, data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:0713791 session_deps_.socket_factory->AddSocketDataProvider(&data);
13792 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data);
[email protected]73b8dd222010-11-11 19:55:2413793
danakj1fd259a02016-04-16 03:17:0913794 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1613795 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]73b8dd222010-11-11 19:55:2413796
[email protected]49639fa2011-12-20 23:22:4113797 TestCompletionCallback callback;
tfarina42834112016-09-22 13:38:2013798 int rv = trans.Start(&request_info, callback.callback(), NetLogWithSource());
ttuttle859dc7a2015-04-23 19:42:2913799 if (rv == ERR_IO_PENDING)
[email protected]73b8dd222010-11-11 19:55:2413800 rv = callback.WaitForResult();
13801 ASSERT_EQ(error, rv);
13802}
13803
bncd16676a2016-07-20 16:23:0113804TEST_F(HttpNetworkTransactionTest, SSLWriteCertError) {
[email protected]73b8dd222010-11-11 19:55:2413805 // Just check a grab bag of cert errors.
13806 static const int kErrors[] = {
13807 ERR_CERT_COMMON_NAME_INVALID,
13808 ERR_CERT_AUTHORITY_INVALID,
13809 ERR_CERT_DATE_INVALID,
13810 };
13811 for (size_t i = 0; i < arraysize(kErrors); i++) {
[email protected]8ddf8322012-02-23 18:08:0613812 CheckErrorIsPassedBack(kErrors[i], ASYNC);
13813 CheckErrorIsPassedBack(kErrors[i], SYNCHRONOUS);
[email protected]73b8dd222010-11-11 19:55:2413814 }
13815}
13816
[email protected]bd0b6772011-01-11 19:59:3013817// Ensure that a client certificate is removed from the SSL client auth
13818// cache when:
13819// 1) No proxy is involved.
13820// 2) TLS False Start is disabled.
13821// 3) The initial TLS handshake requests a client certificate.
13822// 4) The client supplies an invalid/unacceptable certificate.
bncd16676a2016-07-20 16:23:0113823TEST_F(HttpNetworkTransactionTest, ClientAuthCertCache_Direct_NoFalseStart) {
ttuttle859dc7a2015-04-23 19:42:2913824 HttpRequestInfo request_info;
[email protected]cb9bf6ca2011-01-28 13:15:2713825 request_info.url = GURL("https://www.example.com/");
13826 request_info.method = "GET";
ttuttle859dc7a2015-04-23 19:42:2913827 request_info.load_flags = LOAD_NORMAL;
[email protected]cb9bf6ca2011-01-28 13:15:2713828
[email protected]bd0b6772011-01-11 19:59:3013829 scoped_refptr<SSLCertRequestInfo> cert_request(new SSLCertRequestInfo());
[email protected]791879c2013-12-17 07:22:4113830 cert_request->host_and_port = HostPortPair("www.example.com", 443);
[email protected]bd0b6772011-01-11 19:59:3013831
13832 // [ssl_]data1 contains the data for the first SSL handshake. When a
13833 // CertificateRequest is received for the first time, the handshake will
13834 // be aborted to allow the caller to provide a certificate.
ttuttle859dc7a2015-04-23 19:42:2913835 SSLSocketDataProvider ssl_data1(ASYNC, ERR_SSL_CLIENT_AUTH_CERT_NEEDED);
[email protected]bd0b6772011-01-11 19:59:3013836 ssl_data1.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0713837 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data1);
ttuttle859dc7a2015-04-23 19:42:2913838 StaticSocketDataProvider data1(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0713839 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]bd0b6772011-01-11 19:59:3013840
13841 // [ssl_]data2 contains the data for the second SSL handshake. When TLS
13842 // False Start is not being used, the result of the SSL handshake will be
13843 // returned as part of the SSLClientSocket::Connect() call. This test
13844 // matches the result of a server sending a handshake_failure alert,
13845 // rather than a Finished message, because it requires a client
13846 // certificate and none was supplied.
ttuttle859dc7a2015-04-23 19:42:2913847 SSLSocketDataProvider ssl_data2(ASYNC, ERR_SSL_PROTOCOL_ERROR);
[email protected]bd0b6772011-01-11 19:59:3013848 ssl_data2.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0713849 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data2);
ttuttle859dc7a2015-04-23 19:42:2913850 StaticSocketDataProvider data2(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0713851 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]bd0b6772011-01-11 19:59:3013852
13853 // [ssl_]data3 contains the data for the third SSL handshake. When a
13854 // connection to a server fails during an SSL handshake,
davidbenb937d6c2015-05-14 04:53:4213855 // HttpNetworkTransaction will attempt to fallback to TLSv1.1 if the previous
13856 // connection was attempted with TLSv1.2. This is transparent to the caller
[email protected]bd0b6772011-01-11 19:59:3013857 // of the HttpNetworkTransaction. Because this test failure is due to
13858 // requiring a client certificate, this fallback handshake should also
13859 // fail.
ttuttle859dc7a2015-04-23 19:42:2913860 SSLSocketDataProvider ssl_data3(ASYNC, ERR_SSL_PROTOCOL_ERROR);
[email protected]bd0b6772011-01-11 19:59:3013861 ssl_data3.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0713862 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data3);
ttuttle859dc7a2015-04-23 19:42:2913863 StaticSocketDataProvider data3(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0713864 session_deps_.socket_factory->AddSocketDataProvider(&data3);
[email protected]bd0b6772011-01-11 19:59:3013865
[email protected]80c75f682012-05-26 16:22:1713866 // [ssl_]data4 contains the data for the fourth SSL handshake. When a
13867 // connection to a server fails during an SSL handshake,
davidbenb937d6c2015-05-14 04:53:4213868 // HttpNetworkTransaction will attempt to fallback to TLSv1 if the previous
13869 // connection was attempted with TLSv1.1. This is transparent to the caller
[email protected]80c75f682012-05-26 16:22:1713870 // of the HttpNetworkTransaction. Because this test failure is due to
13871 // requiring a client certificate, this fallback handshake should also
13872 // fail.
ttuttle859dc7a2015-04-23 19:42:2913873 SSLSocketDataProvider ssl_data4(ASYNC, ERR_SSL_PROTOCOL_ERROR);
[email protected]80c75f682012-05-26 16:22:1713874 ssl_data4.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0713875 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data4);
ttuttle859dc7a2015-04-23 19:42:2913876 StaticSocketDataProvider data4(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0713877 session_deps_.socket_factory->AddSocketDataProvider(&data4);
[email protected]80c75f682012-05-26 16:22:1713878
danakj1fd259a02016-04-16 03:17:0913879 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1613880 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]bd0b6772011-01-11 19:59:3013881
[email protected]bd0b6772011-01-11 19:59:3013882 // Begin the SSL handshake with the peer. This consumes ssl_data1.
[email protected]49639fa2011-12-20 23:22:4113883 TestCompletionCallback callback;
tfarina42834112016-09-22 13:38:2013884 int rv = trans.Start(&request_info, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0113885 ASSERT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]bd0b6772011-01-11 19:59:3013886
13887 // Complete the SSL handshake, which should abort due to requiring a
13888 // client certificate.
13889 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0113890 ASSERT_THAT(rv, IsError(ERR_SSL_CLIENT_AUTH_CERT_NEEDED));
[email protected]bd0b6772011-01-11 19:59:3013891
13892 // Indicate that no certificate should be supplied. From the perspective
13893 // of SSLClientCertCache, NULL is just as meaningful as a real
13894 // certificate, so this is the same as supply a
13895 // legitimate-but-unacceptable certificate.
bnc691fda62016-08-12 00:43:1613896 rv = trans.RestartWithCertificate(NULL, NULL, callback.callback());
robpercival214763f2016-07-01 23:27:0113897 ASSERT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]bd0b6772011-01-11 19:59:3013898
13899 // Ensure the certificate was added to the client auth cache before
13900 // allowing the connection to continue restarting.
13901 scoped_refptr<X509Certificate> client_cert;
svaldez7872fd02015-11-19 21:10:5413902 scoped_refptr<SSLPrivateKey> client_private_key;
[email protected]791879c2013-12-17 07:22:4113903 ASSERT_TRUE(session->ssl_client_auth_cache()->Lookup(
svaldez7872fd02015-11-19 21:10:5413904 HostPortPair("www.example.com", 443), &client_cert, &client_private_key));
wezca1070932016-05-26 20:30:5213905 ASSERT_FALSE(client_cert);
[email protected]bd0b6772011-01-11 19:59:3013906
13907 // Restart the handshake. This will consume ssl_data2, which fails, and
[email protected]80c75f682012-05-26 16:22:1713908 // then consume ssl_data3 and ssl_data4, both of which should also fail.
13909 // The result code is checked against what ssl_data4 should return.
[email protected]bd0b6772011-01-11 19:59:3013910 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0113911 ASSERT_THAT(rv, IsError(ERR_SSL_PROTOCOL_ERROR));
[email protected]bd0b6772011-01-11 19:59:3013912
13913 // Ensure that the client certificate is removed from the cache on a
13914 // handshake failure.
[email protected]791879c2013-12-17 07:22:4113915 ASSERT_FALSE(session->ssl_client_auth_cache()->Lookup(
svaldez7872fd02015-11-19 21:10:5413916 HostPortPair("www.example.com", 443), &client_cert, &client_private_key));
[email protected]bd0b6772011-01-11 19:59:3013917}
13918
13919// Ensure that a client certificate is removed from the SSL client auth
13920// cache when:
13921// 1) No proxy is involved.
13922// 2) TLS False Start is enabled.
13923// 3) The initial TLS handshake requests a client certificate.
13924// 4) The client supplies an invalid/unacceptable certificate.
bncd16676a2016-07-20 16:23:0113925TEST_F(HttpNetworkTransactionTest, ClientAuthCertCache_Direct_FalseStart) {
ttuttle859dc7a2015-04-23 19:42:2913926 HttpRequestInfo request_info;
[email protected]cb9bf6ca2011-01-28 13:15:2713927 request_info.url = GURL("https://www.example.com/");
13928 request_info.method = "GET";
ttuttle859dc7a2015-04-23 19:42:2913929 request_info.load_flags = LOAD_NORMAL;
[email protected]cb9bf6ca2011-01-28 13:15:2713930
[email protected]bd0b6772011-01-11 19:59:3013931 scoped_refptr<SSLCertRequestInfo> cert_request(new SSLCertRequestInfo());
[email protected]791879c2013-12-17 07:22:4113932 cert_request->host_and_port = HostPortPair("www.example.com", 443);
[email protected]bd0b6772011-01-11 19:59:3013933
13934 // When TLS False Start is used, SSLClientSocket::Connect() calls will
13935 // return successfully after reading up to the peer's Certificate message.
13936 // This is to allow the caller to call SSLClientSocket::Write(), which can
13937 // enqueue application data to be sent in the same packet as the
13938 // ChangeCipherSpec and Finished messages.
13939 // The actual handshake will be finished when SSLClientSocket::Read() is
13940 // called, which expects to process the peer's ChangeCipherSpec and
13941 // Finished messages. If there was an error negotiating with the peer,
13942 // such as due to the peer requiring a client certificate when none was
13943 // supplied, the alert sent by the peer won't be processed until Read() is
13944 // called.
13945
13946 // Like the non-False Start case, when a client certificate is requested by
13947 // the peer, the handshake is aborted during the Connect() call.
13948 // [ssl_]data1 represents the initial SSL handshake with the peer.
ttuttle859dc7a2015-04-23 19:42:2913949 SSLSocketDataProvider ssl_data1(ASYNC, ERR_SSL_CLIENT_AUTH_CERT_NEEDED);
[email protected]bd0b6772011-01-11 19:59:3013950 ssl_data1.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0713951 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data1);
ttuttle859dc7a2015-04-23 19:42:2913952 StaticSocketDataProvider data1(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0713953 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]bd0b6772011-01-11 19:59:3013954
13955 // When a client certificate is supplied, Connect() will not be aborted
13956 // when the peer requests the certificate. Instead, the handshake will
13957 // artificially succeed, allowing the caller to write the HTTP request to
13958 // the socket. The handshake messages are not processed until Read() is
13959 // called, which then detects that the handshake was aborted, due to the
13960 // peer sending a handshake_failure because it requires a client
13961 // certificate.
ttuttle859dc7a2015-04-23 19:42:2913962 SSLSocketDataProvider ssl_data2(ASYNC, OK);
[email protected]bd0b6772011-01-11 19:59:3013963 ssl_data2.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0713964 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data2);
ttuttle859dc7a2015-04-23 19:42:2913965 MockRead data2_reads[] = {
13966 MockRead(ASYNC /* async */, ERR_SSL_PROTOCOL_ERROR),
[email protected]bd0b6772011-01-11 19:59:3013967 };
ttuttle859dc7a2015-04-23 19:42:2913968 StaticSocketDataProvider data2(data2_reads, arraysize(data2_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0713969 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]bd0b6772011-01-11 19:59:3013970
13971 // As described in ClientAuthCertCache_Direct_NoFalseStart, [ssl_]data3 is
[email protected]80c75f682012-05-26 16:22:1713972 // the data for the SSL handshake once the TLSv1.1 connection falls back to
13973 // TLSv1. It has the same behaviour as [ssl_]data2.
ttuttle859dc7a2015-04-23 19:42:2913974 SSLSocketDataProvider ssl_data3(ASYNC, OK);
[email protected]bd0b6772011-01-11 19:59:3013975 ssl_data3.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0713976 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data3);
ttuttle859dc7a2015-04-23 19:42:2913977 StaticSocketDataProvider data3(data2_reads, arraysize(data2_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0713978 session_deps_.socket_factory->AddSocketDataProvider(&data3);
[email protected]bd0b6772011-01-11 19:59:3013979
[email protected]80c75f682012-05-26 16:22:1713980 // [ssl_]data4 is the data for the SSL handshake once the TLSv1 connection
13981 // falls back to SSLv3. It has the same behaviour as [ssl_]data2.
ttuttle859dc7a2015-04-23 19:42:2913982 SSLSocketDataProvider ssl_data4(ASYNC, OK);
[email protected]80c75f682012-05-26 16:22:1713983 ssl_data4.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0713984 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data4);
ttuttle859dc7a2015-04-23 19:42:2913985 StaticSocketDataProvider data4(data2_reads, arraysize(data2_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0713986 session_deps_.socket_factory->AddSocketDataProvider(&data4);
[email protected]80c75f682012-05-26 16:22:1713987
[email protected]7799de12013-05-30 05:52:5113988 // Need one more if TLSv1.2 is enabled.
ttuttle859dc7a2015-04-23 19:42:2913989 SSLSocketDataProvider ssl_data5(ASYNC, OK);
[email protected]7799de12013-05-30 05:52:5113990 ssl_data5.cert_request_info = cert_request.get();
13991 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data5);
ttuttle859dc7a2015-04-23 19:42:2913992 StaticSocketDataProvider data5(data2_reads, arraysize(data2_reads), NULL, 0);
[email protected]7799de12013-05-30 05:52:5113993 session_deps_.socket_factory->AddSocketDataProvider(&data5);
13994
danakj1fd259a02016-04-16 03:17:0913995 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1613996 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]bd0b6772011-01-11 19:59:3013997
[email protected]bd0b6772011-01-11 19:59:3013998 // Begin the initial SSL handshake.
[email protected]49639fa2011-12-20 23:22:4113999 TestCompletionCallback callback;
tfarina42834112016-09-22 13:38:2014000 int rv = trans.Start(&request_info, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0114001 ASSERT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]bd0b6772011-01-11 19:59:3014002
14003 // Complete the SSL handshake, which should abort due to requiring a
14004 // client certificate.
14005 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0114006 ASSERT_THAT(rv, IsError(ERR_SSL_CLIENT_AUTH_CERT_NEEDED));
[email protected]bd0b6772011-01-11 19:59:3014007
14008 // Indicate that no certificate should be supplied. From the perspective
14009 // of SSLClientCertCache, NULL is just as meaningful as a real
14010 // certificate, so this is the same as supply a
14011 // legitimate-but-unacceptable certificate.
bnc691fda62016-08-12 00:43:1614012 rv = trans.RestartWithCertificate(NULL, NULL, callback.callback());
robpercival214763f2016-07-01 23:27:0114013 ASSERT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]bd0b6772011-01-11 19:59:3014014
14015 // Ensure the certificate was added to the client auth cache before
14016 // allowing the connection to continue restarting.
14017 scoped_refptr<X509Certificate> client_cert;
svaldez7872fd02015-11-19 21:10:5414018 scoped_refptr<SSLPrivateKey> client_private_key;
[email protected]791879c2013-12-17 07:22:4114019 ASSERT_TRUE(session->ssl_client_auth_cache()->Lookup(
svaldez7872fd02015-11-19 21:10:5414020 HostPortPair("www.example.com", 443), &client_cert, &client_private_key));
wezca1070932016-05-26 20:30:5214021 ASSERT_FALSE(client_cert);
[email protected]bd0b6772011-01-11 19:59:3014022
[email protected]bd0b6772011-01-11 19:59:3014023 // Restart the handshake. This will consume ssl_data2, which fails, and
[email protected]80c75f682012-05-26 16:22:1714024 // then consume ssl_data3 and ssl_data4, both of which should also fail.
14025 // The result code is checked against what ssl_data4 should return.
[email protected]bd0b6772011-01-11 19:59:3014026 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0114027 ASSERT_THAT(rv, IsError(ERR_SSL_PROTOCOL_ERROR));
[email protected]bd0b6772011-01-11 19:59:3014028
14029 // Ensure that the client certificate is removed from the cache on a
14030 // handshake failure.
[email protected]791879c2013-12-17 07:22:4114031 ASSERT_FALSE(session->ssl_client_auth_cache()->Lookup(
svaldez7872fd02015-11-19 21:10:5414032 HostPortPair("www.example.com", 443), &client_cert, &client_private_key));
[email protected]bd0b6772011-01-11 19:59:3014033}
14034
[email protected]8c405132011-01-11 22:03:1814035// Ensure that a client certificate is removed from the SSL client auth
14036// cache when:
14037// 1) An HTTPS proxy is involved.
14038// 3) The HTTPS proxy requests a client certificate.
14039// 4) The client supplies an invalid/unacceptable certificate for the
14040// proxy.
14041// The test is repeated twice, first for connecting to an HTTPS endpoint,
14042// then for connecting to an HTTP endpoint.
bncd16676a2016-07-20 16:23:0114043TEST_F(HttpNetworkTransactionTest, ClientAuthCertCache_Proxy_Fail) {
rdsmith82957ad2015-09-16 19:42:0314044 session_deps_.proxy_service = ProxyService::CreateFixed("https://proxy:70");
vishal.b62985ca92015-04-17 08:45:5114045 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:0714046 session_deps_.net_log = log.bound().net_log();
[email protected]8c405132011-01-11 22:03:1814047
14048 scoped_refptr<SSLCertRequestInfo> cert_request(new SSLCertRequestInfo());
[email protected]791879c2013-12-17 07:22:4114049 cert_request->host_and_port = HostPortPair("proxy", 70);
[email protected]8c405132011-01-11 22:03:1814050
14051 // See ClientAuthCertCache_Direct_NoFalseStart for the explanation of
14052 // [ssl_]data[1-3]. Rather than represending the endpoint
14053 // (www.example.com:443), they represent failures with the HTTPS proxy
14054 // (proxy:70).
ttuttle859dc7a2015-04-23 19:42:2914055 SSLSocketDataProvider ssl_data1(ASYNC, ERR_SSL_CLIENT_AUTH_CERT_NEEDED);
[email protected]8c405132011-01-11 22:03:1814056 ssl_data1.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0714057 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data1);
ttuttle859dc7a2015-04-23 19:42:2914058 StaticSocketDataProvider data1(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0714059 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8c405132011-01-11 22:03:1814060
ttuttle859dc7a2015-04-23 19:42:2914061 SSLSocketDataProvider ssl_data2(ASYNC, ERR_SSL_PROTOCOL_ERROR);
[email protected]8c405132011-01-11 22:03:1814062 ssl_data2.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0714063 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data2);
ttuttle859dc7a2015-04-23 19:42:2914064 StaticSocketDataProvider data2(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0714065 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]8c405132011-01-11 22:03:1814066
[email protected]80c75f682012-05-26 16:22:1714067 // TODO(wtc): find out why this unit test doesn't need [ssl_]data3.
14068#if 0
ttuttle859dc7a2015-04-23 19:42:2914069 SSLSocketDataProvider ssl_data3(ASYNC, ERR_SSL_PROTOCOL_ERROR);
[email protected]8c405132011-01-11 22:03:1814070 ssl_data3.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0714071 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data3);
ttuttle859dc7a2015-04-23 19:42:2914072 StaticSocketDataProvider data3(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0714073 session_deps_.socket_factory->AddSocketDataProvider(&data3);
[email protected]80c75f682012-05-26 16:22:1714074#endif
[email protected]8c405132011-01-11 22:03:1814075
ttuttle859dc7a2015-04-23 19:42:2914076 HttpRequestInfo requests[2];
[email protected]8c405132011-01-11 22:03:1814077 requests[0].url = GURL("https://www.example.com/");
14078 requests[0].method = "GET";
ttuttle859dc7a2015-04-23 19:42:2914079 requests[0].load_flags = LOAD_NORMAL;
[email protected]8c405132011-01-11 22:03:1814080
14081 requests[1].url = GURL("http://www.example.com/");
14082 requests[1].method = "GET";
ttuttle859dc7a2015-04-23 19:42:2914083 requests[1].load_flags = LOAD_NORMAL;
[email protected]8c405132011-01-11 22:03:1814084
14085 for (size_t i = 0; i < arraysize(requests); ++i) {
[email protected]bb88e1d32013-05-03 23:11:0714086 session_deps_.socket_factory->ResetNextMockIndexes();
danakj1fd259a02016-04-16 03:17:0914087 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1614088 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]8c405132011-01-11 22:03:1814089
14090 // Begin the SSL handshake with the proxy.
[email protected]49639fa2011-12-20 23:22:4114091 TestCompletionCallback callback;
tfarina42834112016-09-22 13:38:2014092 int rv = trans.Start(&requests[i], callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0114093 ASSERT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]8c405132011-01-11 22:03:1814094
14095 // Complete the SSL handshake, which should abort due to requiring a
14096 // client certificate.
14097 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0114098 ASSERT_THAT(rv, IsError(ERR_SSL_CLIENT_AUTH_CERT_NEEDED));
[email protected]8c405132011-01-11 22:03:1814099
14100 // Indicate that no certificate should be supplied. From the perspective
14101 // of SSLClientCertCache, NULL is just as meaningful as a real
14102 // certificate, so this is the same as supply a
14103 // legitimate-but-unacceptable certificate.
bnc691fda62016-08-12 00:43:1614104 rv = trans.RestartWithCertificate(NULL, NULL, callback.callback());
robpercival214763f2016-07-01 23:27:0114105 ASSERT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]8c405132011-01-11 22:03:1814106
14107 // Ensure the certificate was added to the client auth cache before
14108 // allowing the connection to continue restarting.
14109 scoped_refptr<X509Certificate> client_cert;
svaldez7872fd02015-11-19 21:10:5414110 scoped_refptr<SSLPrivateKey> client_private_key;
[email protected]791879c2013-12-17 07:22:4114111 ASSERT_TRUE(session->ssl_client_auth_cache()->Lookup(
svaldez7872fd02015-11-19 21:10:5414112 HostPortPair("proxy", 70), &client_cert, &client_private_key));
wezca1070932016-05-26 20:30:5214113 ASSERT_FALSE(client_cert);
[email protected]8c405132011-01-11 22:03:1814114 // Ensure the certificate was NOT cached for the endpoint. This only
14115 // applies to HTTPS requests, but is fine to check for HTTP requests.
[email protected]791879c2013-12-17 07:22:4114116 ASSERT_FALSE(session->ssl_client_auth_cache()->Lookup(
svaldez7872fd02015-11-19 21:10:5414117 HostPortPair("www.example.com", 443), &client_cert,
14118 &client_private_key));
[email protected]8c405132011-01-11 22:03:1814119
14120 // Restart the handshake. This will consume ssl_data2, which fails, and
14121 // then consume ssl_data3, which should also fail. The result code is
14122 // checked against what ssl_data3 should return.
14123 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0114124 ASSERT_THAT(rv, IsError(ERR_PROXY_CONNECTION_FAILED));
[email protected]8c405132011-01-11 22:03:1814125
14126 // Now that the new handshake has failed, ensure that the client
14127 // certificate was removed from the client auth cache.
[email protected]791879c2013-12-17 07:22:4114128 ASSERT_FALSE(session->ssl_client_auth_cache()->Lookup(
svaldez7872fd02015-11-19 21:10:5414129 HostPortPair("proxy", 70), &client_cert, &client_private_key));
[email protected]791879c2013-12-17 07:22:4114130 ASSERT_FALSE(session->ssl_client_auth_cache()->Lookup(
svaldez7872fd02015-11-19 21:10:5414131 HostPortPair("www.example.com", 443), &client_cert,
14132 &client_private_key));
[email protected]8c405132011-01-11 22:03:1814133 }
14134}
14135
bncd16676a2016-07-20 16:23:0114136TEST_F(HttpNetworkTransactionTest, UseIPConnectionPooling) {
[email protected]e3ceb682011-06-28 23:55:4614137 // Set up a special HttpNetworkSession with a MockCachingHostResolver.
Jeremy Roman0579ed62017-08-29 15:56:1914138 session_deps_.host_resolver = std::make_unique<MockCachingHostResolver>();
danakj1fd259a02016-04-16 03:17:0914139 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]e3ceb682011-06-28 23:55:4614140
bnc032658ba2016-09-26 18:17:1514141 AddSSLSocketData();
[email protected]e3ceb682011-06-28 23:55:4614142
bncdf80d44fd2016-07-15 20:27:4114143 SpdySerializedFrame host1_req(
bnc38dcd392016-02-09 23:19:4914144 spdy_util_.ConstructSpdyGet("https://www.example.org", 1, LOWEST));
rdsmithebb50aa2015-11-12 03:44:3814145 spdy_util_.UpdateWithStreamDestruction(1);
bncdf80d44fd2016-07-15 20:27:4114146 SpdySerializedFrame host2_req(
bnca4d611d2016-09-22 19:55:3714147 spdy_util_.ConstructSpdyGet("https://mail.example.com", 3, LOWEST));
[email protected]e3ceb682011-06-28 23:55:4614148 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:4114149 CreateMockWrite(host1_req, 0), CreateMockWrite(host2_req, 3),
[email protected]e3ceb682011-06-28 23:55:4614150 };
bnc42331402016-07-25 13:36:1514151 SpdySerializedFrame host1_resp(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
bncdf80d44fd2016-07-15 20:27:4114152 SpdySerializedFrame host1_resp_body(
14153 spdy_util_.ConstructSpdyDataFrame(1, true));
bnc42331402016-07-25 13:36:1514154 SpdySerializedFrame host2_resp(spdy_util_.ConstructSpdyGetReply(NULL, 0, 3));
bncdf80d44fd2016-07-15 20:27:4114155 SpdySerializedFrame host2_resp_body(
14156 spdy_util_.ConstructSpdyDataFrame(3, true));
[email protected]e3ceb682011-06-28 23:55:4614157 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:4114158 CreateMockRead(host1_resp, 1), CreateMockRead(host1_resp_body, 2),
14159 CreateMockRead(host2_resp, 4), CreateMockRead(host2_resp_body, 5),
rch8e6c6c42015-05-01 14:05:1314160 MockRead(ASYNC, 0, 6),
[email protected]e3ceb682011-06-28 23:55:4614161 };
14162
eroman36d84e54432016-03-17 03:23:0214163 IPEndPoint peer_addr(IPAddress::IPv4Localhost(), 443);
[email protected]d2b5f092012-06-08 23:55:0214164 MockConnect connect(ASYNC, OK, peer_addr);
rch8e6c6c42015-05-01 14:05:1314165 SequencedSocketData spdy_data(connect, spdy_reads, arraysize(spdy_reads),
14166 spdy_writes, arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:0714167 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]e3ceb682011-06-28 23:55:4614168
[email protected]aa22b242011-11-16 18:58:2914169 TestCompletionCallback callback;
[email protected]e3ceb682011-06-28 23:55:4614170 HttpRequestInfo request1;
14171 request1.method = "GET";
bncce36dca22015-04-21 22:11:2314172 request1.url = GURL("https://www.example.org/");
[email protected]e3ceb682011-06-28 23:55:4614173 request1.load_flags = 0;
[email protected]90499482013-06-01 00:39:5014174 HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
[email protected]e3ceb682011-06-28 23:55:4614175
tfarina42834112016-09-22 13:38:2014176 int rv = trans1.Start(&request1, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0114177 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
14178 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]e3ceb682011-06-28 23:55:4614179
14180 const HttpResponseInfo* response = trans1.GetResponseInfo();
wezca1070932016-05-26 20:30:5214181 ASSERT_TRUE(response);
14182 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0214183 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]e3ceb682011-06-28 23:55:4614184
14185 std::string response_data;
robpercival214763f2016-07-01 23:27:0114186 ASSERT_THAT(ReadTransaction(&trans1, &response_data), IsOk());
[email protected]e3ceb682011-06-28 23:55:4614187 EXPECT_EQ("hello!", response_data);
14188
bnca4d611d2016-09-22 19:55:3714189 // Preload mail.example.com into HostCache.
14190 HostPortPair host_port("mail.example.com", 443);
[email protected]5109c1952013-08-20 18:44:1014191 HostResolver::RequestInfo resolve_info(host_port);
[email protected]e3ceb682011-06-28 23:55:4614192 AddressList ignored;
maksim.sisov31452af2016-07-27 06:38:1014193 std::unique_ptr<HostResolver::Request> request;
14194 rv = session_deps_.host_resolver->Resolve(resolve_info, DEFAULT_PRIORITY,
14195 &ignored, callback.callback(),
tfarina42834112016-09-22 13:38:2014196 &request, NetLogWithSource());
robpercival214763f2016-07-01 23:27:0114197 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]6e78dfb2011-07-28 21:34:4714198 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0114199 EXPECT_THAT(rv, IsOk());
[email protected]e3ceb682011-06-28 23:55:4614200
14201 HttpRequestInfo request2;
14202 request2.method = "GET";
bnca4d611d2016-09-22 19:55:3714203 request2.url = GURL("https://mail.example.com/");
[email protected]e3ceb682011-06-28 23:55:4614204 request2.load_flags = 0;
[email protected]90499482013-06-01 00:39:5014205 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
[email protected]e3ceb682011-06-28 23:55:4614206
tfarina42834112016-09-22 13:38:2014207 rv = trans2.Start(&request2, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0114208 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
14209 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]e3ceb682011-06-28 23:55:4614210
14211 response = trans2.GetResponseInfo();
wezca1070932016-05-26 20:30:5214212 ASSERT_TRUE(response);
14213 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0214214 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]e3ceb682011-06-28 23:55:4614215 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5214216 EXPECT_TRUE(response->was_alpn_negotiated);
robpercival214763f2016-07-01 23:27:0114217 ASSERT_THAT(ReadTransaction(&trans2, &response_data), IsOk());
[email protected]e3ceb682011-06-28 23:55:4614218 EXPECT_EQ("hello!", response_data);
[email protected]e3ceb682011-06-28 23:55:4614219}
14220
bncd16676a2016-07-20 16:23:0114221TEST_F(HttpNetworkTransactionTest, UseIPConnectionPoolingAfterResolution) {
[email protected]d2b5f092012-06-08 23:55:0214222 // Set up a special HttpNetworkSession with a MockCachingHostResolver.
Jeremy Roman0579ed62017-08-29 15:56:1914223 session_deps_.host_resolver = std::make_unique<MockCachingHostResolver>();
danakj1fd259a02016-04-16 03:17:0914224 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]d2b5f092012-06-08 23:55:0214225
bnc032658ba2016-09-26 18:17:1514226 AddSSLSocketData();
[email protected]d2b5f092012-06-08 23:55:0214227
bncdf80d44fd2016-07-15 20:27:4114228 SpdySerializedFrame host1_req(
bnc38dcd392016-02-09 23:19:4914229 spdy_util_.ConstructSpdyGet("https://www.example.org", 1, LOWEST));
rdsmithebb50aa2015-11-12 03:44:3814230 spdy_util_.UpdateWithStreamDestruction(1);
bncdf80d44fd2016-07-15 20:27:4114231 SpdySerializedFrame host2_req(
bnca4d611d2016-09-22 19:55:3714232 spdy_util_.ConstructSpdyGet("https://mail.example.com", 3, LOWEST));
[email protected]d2b5f092012-06-08 23:55:0214233 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:4114234 CreateMockWrite(host1_req, 0), CreateMockWrite(host2_req, 3),
[email protected]d2b5f092012-06-08 23:55:0214235 };
bnc42331402016-07-25 13:36:1514236 SpdySerializedFrame host1_resp(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
bncdf80d44fd2016-07-15 20:27:4114237 SpdySerializedFrame host1_resp_body(
14238 spdy_util_.ConstructSpdyDataFrame(1, true));
bnc42331402016-07-25 13:36:1514239 SpdySerializedFrame host2_resp(spdy_util_.ConstructSpdyGetReply(NULL, 0, 3));
bncdf80d44fd2016-07-15 20:27:4114240 SpdySerializedFrame host2_resp_body(
14241 spdy_util_.ConstructSpdyDataFrame(3, true));
[email protected]d2b5f092012-06-08 23:55:0214242 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:4114243 CreateMockRead(host1_resp, 1), CreateMockRead(host1_resp_body, 2),
14244 CreateMockRead(host2_resp, 4), CreateMockRead(host2_resp_body, 5),
rch8e6c6c42015-05-01 14:05:1314245 MockRead(ASYNC, 0, 6),
[email protected]d2b5f092012-06-08 23:55:0214246 };
14247
eroman36d84e54432016-03-17 03:23:0214248 IPEndPoint peer_addr(IPAddress::IPv4Localhost(), 443);
[email protected]d2b5f092012-06-08 23:55:0214249 MockConnect connect(ASYNC, OK, peer_addr);
rch8e6c6c42015-05-01 14:05:1314250 SequencedSocketData spdy_data(connect, spdy_reads, arraysize(spdy_reads),
14251 spdy_writes, arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:0714252 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]d2b5f092012-06-08 23:55:0214253
14254 TestCompletionCallback callback;
14255 HttpRequestInfo request1;
14256 request1.method = "GET";
bncce36dca22015-04-21 22:11:2314257 request1.url = GURL("https://www.example.org/");
[email protected]d2b5f092012-06-08 23:55:0214258 request1.load_flags = 0;
[email protected]90499482013-06-01 00:39:5014259 HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
[email protected]d2b5f092012-06-08 23:55:0214260
tfarina42834112016-09-22 13:38:2014261 int rv = trans1.Start(&request1, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0114262 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
14263 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]d2b5f092012-06-08 23:55:0214264
14265 const HttpResponseInfo* response = trans1.GetResponseInfo();
wezca1070932016-05-26 20:30:5214266 ASSERT_TRUE(response);
14267 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0214268 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]d2b5f092012-06-08 23:55:0214269
14270 std::string response_data;
robpercival214763f2016-07-01 23:27:0114271 ASSERT_THAT(ReadTransaction(&trans1, &response_data), IsOk());
[email protected]d2b5f092012-06-08 23:55:0214272 EXPECT_EQ("hello!", response_data);
14273
14274 HttpRequestInfo request2;
14275 request2.method = "GET";
bnca4d611d2016-09-22 19:55:3714276 request2.url = GURL("https://mail.example.com/");
[email protected]d2b5f092012-06-08 23:55:0214277 request2.load_flags = 0;
[email protected]90499482013-06-01 00:39:5014278 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
[email protected]d2b5f092012-06-08 23:55:0214279
tfarina42834112016-09-22 13:38:2014280 rv = trans2.Start(&request2, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0114281 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
14282 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]d2b5f092012-06-08 23:55:0214283
14284 response = trans2.GetResponseInfo();
wezca1070932016-05-26 20:30:5214285 ASSERT_TRUE(response);
14286 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0214287 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]d2b5f092012-06-08 23:55:0214288 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5214289 EXPECT_TRUE(response->was_alpn_negotiated);
robpercival214763f2016-07-01 23:27:0114290 ASSERT_THAT(ReadTransaction(&trans2, &response_data), IsOk());
[email protected]d2b5f092012-06-08 23:55:0214291 EXPECT_EQ("hello!", response_data);
[email protected]d2b5f092012-06-08 23:55:0214292}
14293
bnc8016c1f2017-03-31 02:11:2914294// Regression test for https://crbug.com/546991.
14295// The server might not be able to serve an IP pooled request, and might send a
14296// 421 Misdirected Request response status to indicate this.
14297// HttpNetworkTransaction should reset the request and retry without IP pooling.
14298TEST_F(HttpNetworkTransactionTest, RetryWithoutConnectionPooling) {
14299 // Two hosts resolve to the same IP address.
14300 const std::string ip_addr = "1.2.3.4";
14301 IPAddress ip;
14302 ASSERT_TRUE(ip.AssignFromIPLiteral(ip_addr));
14303 IPEndPoint peer_addr = IPEndPoint(ip, 443);
14304
Jeremy Roman0579ed62017-08-29 15:56:1914305 session_deps_.host_resolver = std::make_unique<MockCachingHostResolver>();
bnc8016c1f2017-03-31 02:11:2914306 session_deps_.host_resolver->rules()->AddRule("www.example.org", ip_addr);
14307 session_deps_.host_resolver->rules()->AddRule("mail.example.org", ip_addr);
14308
14309 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
14310
14311 // Two requests on the first connection.
14312 SpdySerializedFrame req1(
14313 spdy_util_.ConstructSpdyGet("https://www.example.org", 1, LOWEST));
14314 spdy_util_.UpdateWithStreamDestruction(1);
14315 SpdySerializedFrame req2(
14316 spdy_util_.ConstructSpdyGet("https://mail.example.org", 3, LOWEST));
14317 SpdySerializedFrame rst(
14318 spdy_util_.ConstructSpdyRstStream(3, ERROR_CODE_CANCEL));
14319 MockWrite writes1[] = {
14320 CreateMockWrite(req1, 0), CreateMockWrite(req2, 3),
14321 CreateMockWrite(rst, 6),
14322 };
14323
14324 // The first one succeeds, the second gets error 421 Misdirected Request.
14325 SpdySerializedFrame resp1(spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
14326 SpdySerializedFrame body1(spdy_util_.ConstructSpdyDataFrame(1, true));
14327 SpdyHeaderBlock response_headers;
Bence Békybda82952017-10-02 17:35:2714328 response_headers[kHttp2StatusHeader] = "421";
bnc8016c1f2017-03-31 02:11:2914329 SpdySerializedFrame resp2(
14330 spdy_util_.ConstructSpdyReply(3, std::move(response_headers)));
14331 MockRead reads1[] = {CreateMockRead(resp1, 1), CreateMockRead(body1, 2),
14332 CreateMockRead(resp2, 4), MockRead(ASYNC, 0, 5)};
14333
14334 MockConnect connect1(ASYNC, OK, peer_addr);
14335 SequencedSocketData data1(connect1, reads1, arraysize(reads1), writes1,
14336 arraysize(writes1));
14337 session_deps_.socket_factory->AddSocketDataProvider(&data1);
14338
14339 AddSSLSocketData();
14340
14341 // Retry the second request on a second connection.
14342 SpdyTestUtil spdy_util2;
14343 SpdySerializedFrame req3(
14344 spdy_util2.ConstructSpdyGet("https://mail.example.org", 1, LOWEST));
14345 MockWrite writes2[] = {
14346 CreateMockWrite(req3, 0),
14347 };
14348
14349 SpdySerializedFrame resp3(spdy_util2.ConstructSpdyGetReply(nullptr, 0, 1));
14350 SpdySerializedFrame body3(spdy_util2.ConstructSpdyDataFrame(1, true));
14351 MockRead reads2[] = {CreateMockRead(resp3, 1), CreateMockRead(body3, 2),
14352 MockRead(ASYNC, 0, 3)};
14353
14354 MockConnect connect2(ASYNC, OK, peer_addr);
14355 SequencedSocketData data2(connect2, reads2, arraysize(reads2), writes2,
14356 arraysize(writes2));
14357 session_deps_.socket_factory->AddSocketDataProvider(&data2);
14358
14359 AddSSLSocketData();
14360
14361 // Preload mail.example.org into HostCache.
14362 HostPortPair host_port("mail.example.org", 443);
14363 HostResolver::RequestInfo resolve_info(host_port);
14364 AddressList ignored;
14365 std::unique_ptr<HostResolver::Request> request;
14366 TestCompletionCallback callback;
14367 int rv = session_deps_.host_resolver->Resolve(resolve_info, DEFAULT_PRIORITY,
14368 &ignored, callback.callback(),
14369 &request, NetLogWithSource());
14370 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
14371 rv = callback.WaitForResult();
14372 EXPECT_THAT(rv, IsOk());
14373
14374 HttpRequestInfo request1;
14375 request1.method = "GET";
14376 request1.url = GURL("https://www.example.org/");
14377 request1.load_flags = 0;
14378 HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
14379
14380 rv = trans1.Start(&request1, callback.callback(), NetLogWithSource());
14381 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
14382 rv = callback.WaitForResult();
14383 EXPECT_THAT(rv, IsOk());
14384
14385 const HttpResponseInfo* response = trans1.GetResponseInfo();
14386 ASSERT_TRUE(response);
14387 ASSERT_TRUE(response->headers);
14388 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
14389 EXPECT_TRUE(response->was_fetched_via_spdy);
14390 EXPECT_TRUE(response->was_alpn_negotiated);
14391 std::string response_data;
14392 ASSERT_THAT(ReadTransaction(&trans1, &response_data), IsOk());
14393 EXPECT_EQ("hello!", response_data);
14394
14395 HttpRequestInfo request2;
14396 request2.method = "GET";
14397 request2.url = GURL("https://mail.example.org/");
14398 request2.load_flags = 0;
14399 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
14400
14401 BoundTestNetLog log;
14402 rv = trans2.Start(&request2, callback.callback(), log.bound());
14403 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
14404 rv = callback.WaitForResult();
14405 EXPECT_THAT(rv, IsOk());
14406
14407 response = trans2.GetResponseInfo();
14408 ASSERT_TRUE(response);
14409 ASSERT_TRUE(response->headers);
14410 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
14411 EXPECT_TRUE(response->was_fetched_via_spdy);
14412 EXPECT_TRUE(response->was_alpn_negotiated);
14413 ASSERT_THAT(ReadTransaction(&trans2, &response_data), IsOk());
14414 EXPECT_EQ("hello!", response_data);
14415
14416 TestNetLogEntry::List entries;
14417 log.GetEntries(&entries);
davidbence688ae2017-05-04 15:12:5914418 ExpectLogContainsSomewhere(
14419 entries, 0, NetLogEventType::HTTP_TRANSACTION_RESTART_MISDIRECTED_REQUEST,
bnc8016c1f2017-03-31 02:11:2914420 NetLogEventPhase::NONE);
davidbence688ae2017-05-04 15:12:5914421}
14422
14423// Test that HTTP 421 responses are properly returned to the caller if received
14424// on the retry as well. HttpNetworkTransaction should not infinite loop or lose
14425// portions of the response.
14426TEST_F(HttpNetworkTransactionTest, ReturnHTTP421OnRetry) {
14427 // Two hosts resolve to the same IP address.
14428 const std::string ip_addr = "1.2.3.4";
14429 IPAddress ip;
14430 ASSERT_TRUE(ip.AssignFromIPLiteral(ip_addr));
14431 IPEndPoint peer_addr = IPEndPoint(ip, 443);
14432
Jeremy Roman0579ed62017-08-29 15:56:1914433 session_deps_.host_resolver = std::make_unique<MockCachingHostResolver>();
davidbence688ae2017-05-04 15:12:5914434 session_deps_.host_resolver->rules()->AddRule("www.example.org", ip_addr);
14435 session_deps_.host_resolver->rules()->AddRule("mail.example.org", ip_addr);
14436
14437 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
14438
14439 // Two requests on the first connection.
14440 SpdySerializedFrame req1(
14441 spdy_util_.ConstructSpdyGet("https://www.example.org", 1, LOWEST));
14442 spdy_util_.UpdateWithStreamDestruction(1);
14443 SpdySerializedFrame req2(
14444 spdy_util_.ConstructSpdyGet("https://mail.example.org", 3, LOWEST));
14445 SpdySerializedFrame rst(
14446 spdy_util_.ConstructSpdyRstStream(3, ERROR_CODE_CANCEL));
14447 MockWrite writes1[] = {
14448 CreateMockWrite(req1, 0), CreateMockWrite(req2, 3),
14449 CreateMockWrite(rst, 6),
14450 };
14451
14452 // The first one succeeds, the second gets error 421 Misdirected Request.
14453 SpdySerializedFrame resp1(spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
14454 SpdySerializedFrame body1(spdy_util_.ConstructSpdyDataFrame(1, true));
14455 SpdyHeaderBlock response_headers;
Bence Békybda82952017-10-02 17:35:2714456 response_headers[kHttp2StatusHeader] = "421";
davidbence688ae2017-05-04 15:12:5914457 SpdySerializedFrame resp2(
14458 spdy_util_.ConstructSpdyReply(3, response_headers.Clone()));
14459 MockRead reads1[] = {CreateMockRead(resp1, 1), CreateMockRead(body1, 2),
14460 CreateMockRead(resp2, 4), MockRead(ASYNC, 0, 5)};
14461
14462 MockConnect connect1(ASYNC, OK, peer_addr);
14463 SequencedSocketData data1(connect1, reads1, arraysize(reads1), writes1,
14464 arraysize(writes1));
14465 session_deps_.socket_factory->AddSocketDataProvider(&data1);
14466
14467 AddSSLSocketData();
14468
14469 // Retry the second request on a second connection. It returns 421 Misdirected
14470 // Retry again.
14471 SpdyTestUtil spdy_util2;
14472 SpdySerializedFrame req3(
14473 spdy_util2.ConstructSpdyGet("https://mail.example.org", 1, LOWEST));
14474 MockWrite writes2[] = {
14475 CreateMockWrite(req3, 0),
14476 };
14477
14478 SpdySerializedFrame resp3(
14479 spdy_util2.ConstructSpdyReply(1, std::move(response_headers)));
14480 SpdySerializedFrame body3(spdy_util2.ConstructSpdyDataFrame(1, true));
14481 MockRead reads2[] = {CreateMockRead(resp3, 1), CreateMockRead(body3, 2),
14482 MockRead(ASYNC, 0, 3)};
14483
14484 MockConnect connect2(ASYNC, OK, peer_addr);
14485 SequencedSocketData data2(connect2, reads2, arraysize(reads2), writes2,
14486 arraysize(writes2));
14487 session_deps_.socket_factory->AddSocketDataProvider(&data2);
14488
14489 AddSSLSocketData();
14490
14491 // Preload mail.example.org into HostCache.
14492 HostPortPair host_port("mail.example.org", 443);
14493 HostResolver::RequestInfo resolve_info(host_port);
14494 AddressList ignored;
14495 std::unique_ptr<HostResolver::Request> request;
14496 TestCompletionCallback callback;
14497 int rv = session_deps_.host_resolver->Resolve(resolve_info, DEFAULT_PRIORITY,
14498 &ignored, callback.callback(),
14499 &request, NetLogWithSource());
14500 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
14501 rv = callback.WaitForResult();
14502 EXPECT_THAT(rv, IsOk());
14503
14504 HttpRequestInfo request1;
14505 request1.method = "GET";
14506 request1.url = GURL("https://www.example.org/");
14507 request1.load_flags = 0;
14508 HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
14509
14510 rv = trans1.Start(&request1, callback.callback(), NetLogWithSource());
14511 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
14512 rv = callback.WaitForResult();
14513 EXPECT_THAT(rv, IsOk());
14514
14515 const HttpResponseInfo* response = trans1.GetResponseInfo();
14516 ASSERT_TRUE(response);
14517 ASSERT_TRUE(response->headers);
14518 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
14519 EXPECT_TRUE(response->was_fetched_via_spdy);
14520 EXPECT_TRUE(response->was_alpn_negotiated);
14521 std::string response_data;
14522 ASSERT_THAT(ReadTransaction(&trans1, &response_data), IsOk());
14523 EXPECT_EQ("hello!", response_data);
14524
14525 HttpRequestInfo request2;
14526 request2.method = "GET";
14527 request2.url = GURL("https://mail.example.org/");
14528 request2.load_flags = 0;
14529 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
14530
14531 BoundTestNetLog log;
14532 rv = trans2.Start(&request2, callback.callback(), log.bound());
14533 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
14534 rv = callback.WaitForResult();
14535 EXPECT_THAT(rv, IsOk());
14536
14537 // After a retry, the 421 Misdirected Request is reported back up to the
14538 // caller.
14539 response = trans2.GetResponseInfo();
14540 ASSERT_TRUE(response);
14541 ASSERT_TRUE(response->headers);
14542 EXPECT_EQ("HTTP/1.1 421", response->headers->GetStatusLine());
14543 EXPECT_TRUE(response->was_fetched_via_spdy);
14544 EXPECT_TRUE(response->was_alpn_negotiated);
14545 EXPECT_TRUE(response->ssl_info.cert);
14546 ASSERT_THAT(ReadTransaction(&trans2, &response_data), IsOk());
14547 EXPECT_EQ("hello!", response_data);
bnc8016c1f2017-03-31 02:11:2914548}
14549
bnc6dcd8192017-05-25 20:11:5014550class OneTimeCachingHostResolver : public MockHostResolverBase {
[email protected]e3ceb682011-06-28 23:55:4614551 public:
14552 explicit OneTimeCachingHostResolver(const HostPortPair& host_port)
bnc6dcd8192017-05-25 20:11:5014553 : MockHostResolverBase(/* use_caching = */ true), host_port_(host_port) {}
Chris Watkins7a41d3552017-12-01 02:13:2714554 ~OneTimeCachingHostResolver() override = default;
[email protected]e3ceb682011-06-28 23:55:4614555
dchengb03027d2014-10-21 12:00:2014556 int ResolveFromCache(const RequestInfo& info,
14557 AddressList* addresses,
tfarina42834112016-09-22 13:38:2014558 const NetLogWithSource& net_log) override {
bnc6dcd8192017-05-25 20:11:5014559 int rv = MockHostResolverBase::ResolveFromCache(info, addresses, net_log);
[email protected]95a214c2011-08-04 21:50:4014560 if (rv == OK && info.host_port_pair().Equals(host_port_))
bnc6dcd8192017-05-25 20:11:5014561 GetHostCache()->clear();
[email protected]e3ceb682011-06-28 23:55:4614562 return rv;
14563 }
14564
[email protected]e3ceb682011-06-28 23:55:4614565 private:
[email protected]e3ceb682011-06-28 23:55:4614566 const HostPortPair host_port_;
14567};
14568
bncd16676a2016-07-20 16:23:0114569TEST_F(HttpNetworkTransactionTest,
mmenke5c642132015-06-02 16:05:1314570 UseIPConnectionPoolingWithHostCacheExpiration) {
[email protected]e3ceb682011-06-28 23:55:4614571 // Set up a special HttpNetworkSession with a OneTimeCachingHostResolver.
Jeremy Roman0579ed62017-08-29 15:56:1914572 session_deps_.host_resolver = std::make_unique<OneTimeCachingHostResolver>(
bnca4d611d2016-09-22 19:55:3714573 HostPortPair("mail.example.com", 443));
danakj1fd259a02016-04-16 03:17:0914574 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]e3ceb682011-06-28 23:55:4614575
bnc032658ba2016-09-26 18:17:1514576 AddSSLSocketData();
[email protected]e3ceb682011-06-28 23:55:4614577
bncdf80d44fd2016-07-15 20:27:4114578 SpdySerializedFrame host1_req(
bnc38dcd392016-02-09 23:19:4914579 spdy_util_.ConstructSpdyGet("https://www.example.org", 1, LOWEST));
rdsmithebb50aa2015-11-12 03:44:3814580 spdy_util_.UpdateWithStreamDestruction(1);
bncdf80d44fd2016-07-15 20:27:4114581 SpdySerializedFrame host2_req(
bnca4d611d2016-09-22 19:55:3714582 spdy_util_.ConstructSpdyGet("https://mail.example.com", 3, LOWEST));
[email protected]e3ceb682011-06-28 23:55:4614583 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:4114584 CreateMockWrite(host1_req, 0), CreateMockWrite(host2_req, 3),
[email protected]e3ceb682011-06-28 23:55:4614585 };
bnc42331402016-07-25 13:36:1514586 SpdySerializedFrame host1_resp(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
bncdf80d44fd2016-07-15 20:27:4114587 SpdySerializedFrame host1_resp_body(
14588 spdy_util_.ConstructSpdyDataFrame(1, true));
bnc42331402016-07-25 13:36:1514589 SpdySerializedFrame host2_resp(spdy_util_.ConstructSpdyGetReply(NULL, 0, 3));
bncdf80d44fd2016-07-15 20:27:4114590 SpdySerializedFrame host2_resp_body(
14591 spdy_util_.ConstructSpdyDataFrame(3, true));
[email protected]e3ceb682011-06-28 23:55:4614592 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:4114593 CreateMockRead(host1_resp, 1), CreateMockRead(host1_resp_body, 2),
14594 CreateMockRead(host2_resp, 4), CreateMockRead(host2_resp_body, 5),
rch8e6c6c42015-05-01 14:05:1314595 MockRead(ASYNC, 0, 6),
[email protected]e3ceb682011-06-28 23:55:4614596 };
14597
eroman36d84e54432016-03-17 03:23:0214598 IPEndPoint peer_addr(IPAddress::IPv4Localhost(), 443);
[email protected]d2b5f092012-06-08 23:55:0214599 MockConnect connect(ASYNC, OK, peer_addr);
rch8e6c6c42015-05-01 14:05:1314600 SequencedSocketData spdy_data(connect, spdy_reads, arraysize(spdy_reads),
14601 spdy_writes, arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:0714602 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]e3ceb682011-06-28 23:55:4614603
[email protected]aa22b242011-11-16 18:58:2914604 TestCompletionCallback callback;
[email protected]e3ceb682011-06-28 23:55:4614605 HttpRequestInfo request1;
14606 request1.method = "GET";
bncce36dca22015-04-21 22:11:2314607 request1.url = GURL("https://www.example.org/");
[email protected]e3ceb682011-06-28 23:55:4614608 request1.load_flags = 0;
[email protected]90499482013-06-01 00:39:5014609 HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
[email protected]e3ceb682011-06-28 23:55:4614610
tfarina42834112016-09-22 13:38:2014611 int rv = trans1.Start(&request1, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0114612 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
14613 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]e3ceb682011-06-28 23:55:4614614
14615 const HttpResponseInfo* response = trans1.GetResponseInfo();
wezca1070932016-05-26 20:30:5214616 ASSERT_TRUE(response);
14617 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0214618 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]e3ceb682011-06-28 23:55:4614619
14620 std::string response_data;
robpercival214763f2016-07-01 23:27:0114621 ASSERT_THAT(ReadTransaction(&trans1, &response_data), IsOk());
[email protected]e3ceb682011-06-28 23:55:4614622 EXPECT_EQ("hello!", response_data);
14623
14624 // Preload cache entries into HostCache.
bnca4d611d2016-09-22 19:55:3714625 HostResolver::RequestInfo resolve_info(HostPortPair("mail.example.com", 443));
[email protected]e3ceb682011-06-28 23:55:4614626 AddressList ignored;
maksim.sisov31452af2016-07-27 06:38:1014627 std::unique_ptr<HostResolver::Request> request;
bnc6dcd8192017-05-25 20:11:5014628 rv = session_deps_.host_resolver->Resolve(resolve_info, DEFAULT_PRIORITY,
14629 &ignored, callback.callback(),
14630 &request, NetLogWithSource());
robpercival214763f2016-07-01 23:27:0114631 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]6e78dfb2011-07-28 21:34:4714632 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0114633 EXPECT_THAT(rv, IsOk());
[email protected]e3ceb682011-06-28 23:55:4614634
14635 HttpRequestInfo request2;
14636 request2.method = "GET";
bnca4d611d2016-09-22 19:55:3714637 request2.url = GURL("https://mail.example.com/");
[email protected]e3ceb682011-06-28 23:55:4614638 request2.load_flags = 0;
[email protected]90499482013-06-01 00:39:5014639 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
[email protected]e3ceb682011-06-28 23:55:4614640
tfarina42834112016-09-22 13:38:2014641 rv = trans2.Start(&request2, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0114642 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
14643 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]e3ceb682011-06-28 23:55:4614644
14645 response = trans2.GetResponseInfo();
wezca1070932016-05-26 20:30:5214646 ASSERT_TRUE(response);
14647 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0214648 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]e3ceb682011-06-28 23:55:4614649 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5214650 EXPECT_TRUE(response->was_alpn_negotiated);
robpercival214763f2016-07-01 23:27:0114651 ASSERT_THAT(ReadTransaction(&trans2, &response_data), IsOk());
[email protected]e3ceb682011-06-28 23:55:4614652 EXPECT_EQ("hello!", response_data);
[email protected]e3ceb682011-06-28 23:55:4614653}
14654
bncd16676a2016-07-20 16:23:0114655TEST_F(HttpNetworkTransactionTest, DoNotUseSpdySessionForHttp) {
bncce36dca22015-04-21 22:11:2314656 const std::string https_url = "https://www.example.org:8080/";
14657 const std::string http_url = "http://www.example.org:8080/";
[email protected]8450d722012-07-02 19:14:0414658
14659 // SPDY GET for HTTPS URL
bncdf80d44fd2016-07-15 20:27:4114660 SpdySerializedFrame req1(
bnc38dcd392016-02-09 23:19:4914661 spdy_util_.ConstructSpdyGet(https_url.c_str(), 1, LOWEST));
[email protected]8450d722012-07-02 19:14:0414662
14663 MockWrite writes1[] = {
bncdf80d44fd2016-07-15 20:27:4114664 CreateMockWrite(req1, 0),
[email protected]8450d722012-07-02 19:14:0414665 };
14666
bnc42331402016-07-25 13:36:1514667 SpdySerializedFrame resp1(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
bncdf80d44fd2016-07-15 20:27:4114668 SpdySerializedFrame body1(spdy_util_.ConstructSpdyDataFrame(1, true));
14669 MockRead reads1[] = {CreateMockRead(resp1, 1), CreateMockRead(body1, 2),
mmenkee24011922015-12-17 22:12:5914670 MockRead(SYNCHRONOUS, ERR_IO_PENDING, 3)};
[email protected]8450d722012-07-02 19:14:0414671
rch8e6c6c42015-05-01 14:05:1314672 SequencedSocketData data1(reads1, arraysize(reads1), writes1,
14673 arraysize(writes1));
[email protected]8450d722012-07-02 19:14:0414674 MockConnect connect_data1(ASYNC, OK);
[email protected]dd54bd82012-07-19 23:44:5714675 data1.set_connect_data(connect_data1);
[email protected]8450d722012-07-02 19:14:0414676
14677 // HTTP GET for the HTTP URL
14678 MockWrite writes2[] = {
rch8e6c6c42015-05-01 14:05:1314679 MockWrite(ASYNC, 0,
lgarrona91df87f2014-12-05 00:51:3414680 "GET / HTTP/1.1\r\n"
bncce36dca22015-04-21 22:11:2314681 "Host: www.example.org:8080\r\n"
lgarrona91df87f2014-12-05 00:51:3414682 "Connection: keep-alive\r\n\r\n"),
[email protected]8450d722012-07-02 19:14:0414683 };
14684
14685 MockRead reads2[] = {
rch8e6c6c42015-05-01 14:05:1314686 MockRead(ASYNC, 1, "HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
14687 MockRead(ASYNC, 2, "hello"),
14688 MockRead(ASYNC, OK, 3),
[email protected]8450d722012-07-02 19:14:0414689 };
14690
rch8e6c6c42015-05-01 14:05:1314691 SequencedSocketData data2(reads2, arraysize(reads2), writes2,
14692 arraysize(writes2));
[email protected]8450d722012-07-02 19:14:0414693
[email protected]8450d722012-07-02 19:14:0414694 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3614695 ssl.next_proto = kProtoHTTP2;
[email protected]bb88e1d32013-05-03 23:11:0714696 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
14697 session_deps_.socket_factory->AddSocketDataProvider(&data1);
14698 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]8450d722012-07-02 19:14:0414699
danakj1fd259a02016-04-16 03:17:0914700 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]8450d722012-07-02 19:14:0414701
14702 // Start the first transaction to set up the SpdySession
14703 HttpRequestInfo request1;
14704 request1.method = "GET";
14705 request1.url = GURL(https_url);
[email protected]8450d722012-07-02 19:14:0414706 request1.load_flags = 0;
[email protected]90499482013-06-01 00:39:5014707 HttpNetworkTransaction trans1(LOWEST, session.get());
[email protected]8450d722012-07-02 19:14:0414708 TestCompletionCallback callback1;
14709 EXPECT_EQ(ERR_IO_PENDING,
tfarina42834112016-09-22 13:38:2014710 trans1.Start(&request1, callback1.callback(), NetLogWithSource()));
fdoray92e35a72016-06-10 15:54:5514711 base::RunLoop().RunUntilIdle();
[email protected]8450d722012-07-02 19:14:0414712
robpercival214763f2016-07-01 23:27:0114713 EXPECT_THAT(callback1.WaitForResult(), IsOk());
[email protected]8450d722012-07-02 19:14:0414714 EXPECT_TRUE(trans1.GetResponseInfo()->was_fetched_via_spdy);
14715
14716 // Now, start the HTTP request
14717 HttpRequestInfo request2;
14718 request2.method = "GET";
14719 request2.url = GURL(http_url);
[email protected]8450d722012-07-02 19:14:0414720 request2.load_flags = 0;
[email protected]90499482013-06-01 00:39:5014721 HttpNetworkTransaction trans2(MEDIUM, session.get());
[email protected]8450d722012-07-02 19:14:0414722 TestCompletionCallback callback2;
14723 EXPECT_EQ(ERR_IO_PENDING,
tfarina42834112016-09-22 13:38:2014724 trans2.Start(&request2, callback2.callback(), NetLogWithSource()));
fdoray92e35a72016-06-10 15:54:5514725 base::RunLoop().RunUntilIdle();
[email protected]8450d722012-07-02 19:14:0414726
robpercival214763f2016-07-01 23:27:0114727 EXPECT_THAT(callback2.WaitForResult(), IsOk());
[email protected]8450d722012-07-02 19:14:0414728 EXPECT_FALSE(trans2.GetResponseInfo()->was_fetched_via_spdy);
14729}
14730
bnc5452e2a2015-05-08 16:27:4214731// Alternative service requires HTTP/2 (or SPDY), but HTTP/1.1 is negotiated
14732// with the alternative server. That connection should not be used.
bncd16676a2016-07-20 16:23:0114733TEST_F(HttpNetworkTransactionTest, AlternativeServiceNotOnHttp11) {
bnc8bef8da22016-05-30 01:28:2514734 url::SchemeHostPort server("https", "www.example.org", 443);
14735 HostPortPair alternative("www.example.org", 444);
bnc5452e2a2015-05-08 16:27:4214736
bnc8bef8da22016-05-30 01:28:2514737 // Negotiate HTTP/1.1 with alternative.
bnc5452e2a2015-05-08 16:27:4214738 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3614739 ssl.next_proto = kProtoHTTP11;
bnc5452e2a2015-05-08 16:27:4214740 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
14741
14742 // No data should be read from the alternative, because HTTP/1.1 is
14743 // negotiated.
14744 StaticSocketDataProvider data;
14745 session_deps_.socket_factory->AddSocketDataProvider(&data);
14746
14747 // This test documents that an alternate Job should not be used if HTTP/1.1 is
zhongyi3d4a55e72016-04-22 20:36:4614748 // negotiated. In order to test this, a failed connection to the server is
bnc5452e2a2015-05-08 16:27:4214749 // mocked. This way the request relies on the alternate Job.
14750 StaticSocketDataProvider data_refused;
14751 data_refused.set_connect_data(MockConnect(ASYNC, ERR_CONNECTION_REFUSED));
14752 session_deps_.socket_factory->AddSocketDataProvider(&data_refused);
14753
zhongyi3d4a55e72016-04-22 20:36:4614754 // Set up alternative service for server.
danakj1fd259a02016-04-16 03:17:0914755 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc525e175a2016-06-20 12:36:4014756 HttpServerProperties* http_server_properties =
bnc5452e2a2015-05-08 16:27:4214757 session->http_server_properties();
bnc3472afd2016-11-17 15:27:2114758 AlternativeService alternative_service(kProtoHTTP2, alternative);
bnc7dc7e1b42015-07-28 14:43:1214759 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:2114760 http_server_properties->SetHttp2AlternativeService(
14761 server, alternative_service, expiration);
bnc5452e2a2015-05-08 16:27:4214762
bnc5452e2a2015-05-08 16:27:4214763 HttpRequestInfo request;
krasinc06a72a2016-12-21 03:42:4614764 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
bnc5452e2a2015-05-08 16:27:4214765 request.method = "GET";
bnc8bef8da22016-05-30 01:28:2514766 request.url = GURL("https://www.example.org:443");
bnc5452e2a2015-05-08 16:27:4214767 TestCompletionCallback callback;
14768
14769 // HTTP/2 (or SPDY) is required for alternative service, if HTTP/1.1 is
bnc94c92842016-09-21 15:22:5214770 // negotiated, the alternate Job should fail with ERR_ALPN_NEGOTIATION_FAILED.
tfarina42834112016-09-22 13:38:2014771 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
bnc94c92842016-09-21 15:22:5214772 EXPECT_THAT(callback.GetResult(rv), IsError(ERR_ALPN_NEGOTIATION_FAILED));
bnc5452e2a2015-05-08 16:27:4214773}
14774
bnc40448a532015-05-11 19:13:1414775// A request to a server with an alternative service fires two Jobs: one to the
zhongyi3d4a55e72016-04-22 20:36:4614776// server, and an alternate one to the alternative server. If the former
bnc40448a532015-05-11 19:13:1414777// succeeds, the request should succeed, even if the latter fails because
14778// HTTP/1.1 is negotiated which is insufficient for alternative service.
bncd16676a2016-07-20 16:23:0114779TEST_F(HttpNetworkTransactionTest, FailedAlternativeServiceIsNotUserVisible) {
bnc8bef8da22016-05-30 01:28:2514780 url::SchemeHostPort server("https", "www.example.org", 443);
14781 HostPortPair alternative("www.example.org", 444);
bnc40448a532015-05-11 19:13:1414782
14783 // Negotiate HTTP/1.1 with alternative.
14784 SSLSocketDataProvider alternative_ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3614785 alternative_ssl.next_proto = kProtoHTTP11;
bnc40448a532015-05-11 19:13:1414786 session_deps_.socket_factory->AddSSLSocketDataProvider(&alternative_ssl);
14787
14788 // No data should be read from the alternative, because HTTP/1.1 is
14789 // negotiated.
14790 StaticSocketDataProvider data;
14791 session_deps_.socket_factory->AddSocketDataProvider(&data);
14792
zhongyi3d4a55e72016-04-22 20:36:4614793 // Negotiate HTTP/1.1 with server.
bnc40448a532015-05-11 19:13:1414794 SSLSocketDataProvider origin_ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3614795 origin_ssl.next_proto = kProtoHTTP11;
bnc40448a532015-05-11 19:13:1414796 session_deps_.socket_factory->AddSSLSocketDataProvider(&origin_ssl);
14797
14798 MockWrite http_writes[] = {
bnc8bef8da22016-05-30 01:28:2514799 MockWrite("GET / HTTP/1.1\r\n"
14800 "Host: www.example.org\r\n"
14801 "Connection: keep-alive\r\n\r\n"),
14802 MockWrite("GET /second HTTP/1.1\r\n"
14803 "Host: www.example.org\r\n"
14804 "Connection: keep-alive\r\n\r\n"),
bnc40448a532015-05-11 19:13:1414805 };
14806
14807 MockRead http_reads[] = {
14808 MockRead("HTTP/1.1 200 OK\r\n"),
14809 MockRead("Content-Type: text/html\r\n"),
14810 MockRead("Content-Length: 6\r\n\r\n"),
14811 MockRead("foobar"),
14812 MockRead("HTTP/1.1 200 OK\r\n"),
14813 MockRead("Content-Type: text/html\r\n"),
14814 MockRead("Content-Length: 7\r\n\r\n"),
14815 MockRead("another"),
14816 };
14817 StaticSocketDataProvider http_data(http_reads, arraysize(http_reads),
14818 http_writes, arraysize(http_writes));
14819 session_deps_.socket_factory->AddSocketDataProvider(&http_data);
14820
zhongyi3d4a55e72016-04-22 20:36:4614821 // Set up alternative service for server.
danakj1fd259a02016-04-16 03:17:0914822 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc525e175a2016-06-20 12:36:4014823 HttpServerProperties* http_server_properties =
bnc40448a532015-05-11 19:13:1414824 session->http_server_properties();
bnc3472afd2016-11-17 15:27:2114825 AlternativeService alternative_service(kProtoHTTP2, alternative);
bnc7dc7e1b42015-07-28 14:43:1214826 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:2114827 http_server_properties->SetHttp2AlternativeService(
14828 server, alternative_service, expiration);
bnc40448a532015-05-11 19:13:1414829
14830 HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
14831 HttpRequestInfo request1;
14832 request1.method = "GET";
bnc8bef8da22016-05-30 01:28:2514833 request1.url = GURL("https://www.example.org:443");
bnc40448a532015-05-11 19:13:1414834 request1.load_flags = 0;
14835 TestCompletionCallback callback1;
14836
tfarina42834112016-09-22 13:38:2014837 int rv = trans1.Start(&request1, callback1.callback(), NetLogWithSource());
bnc40448a532015-05-11 19:13:1414838 rv = callback1.GetResult(rv);
robpercival214763f2016-07-01 23:27:0114839 EXPECT_THAT(rv, IsOk());
bnc40448a532015-05-11 19:13:1414840
14841 const HttpResponseInfo* response1 = trans1.GetResponseInfo();
wezca1070932016-05-26 20:30:5214842 ASSERT_TRUE(response1);
14843 ASSERT_TRUE(response1->headers);
bnc40448a532015-05-11 19:13:1414844 EXPECT_EQ("HTTP/1.1 200 OK", response1->headers->GetStatusLine());
14845
14846 std::string response_data1;
robpercival214763f2016-07-01 23:27:0114847 ASSERT_THAT(ReadTransaction(&trans1, &response_data1), IsOk());
bnc40448a532015-05-11 19:13:1414848 EXPECT_EQ("foobar", response_data1);
14849
14850 // Alternative should be marked as broken, because HTTP/1.1 is not sufficient
14851 // for alternative service.
14852 EXPECT_TRUE(
14853 http_server_properties->IsAlternativeServiceBroken(alternative_service));
14854
zhongyi3d4a55e72016-04-22 20:36:4614855 // Since |alternative_service| is broken, a second transaction to server
bnc40448a532015-05-11 19:13:1414856 // should not start an alternate Job. It should pool to existing connection
zhongyi3d4a55e72016-04-22 20:36:4614857 // to server.
bnc40448a532015-05-11 19:13:1414858 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
14859 HttpRequestInfo request2;
14860 request2.method = "GET";
bnc8bef8da22016-05-30 01:28:2514861 request2.url = GURL("https://www.example.org:443/second");
bnc40448a532015-05-11 19:13:1414862 request2.load_flags = 0;
14863 TestCompletionCallback callback2;
14864
tfarina42834112016-09-22 13:38:2014865 rv = trans2.Start(&request2, callback2.callback(), NetLogWithSource());
bnc40448a532015-05-11 19:13:1414866 rv = callback2.GetResult(rv);
robpercival214763f2016-07-01 23:27:0114867 EXPECT_THAT(rv, IsOk());
bnc40448a532015-05-11 19:13:1414868
14869 const HttpResponseInfo* response2 = trans2.GetResponseInfo();
wezca1070932016-05-26 20:30:5214870 ASSERT_TRUE(response2);
14871 ASSERT_TRUE(response2->headers);
bnc40448a532015-05-11 19:13:1414872 EXPECT_EQ("HTTP/1.1 200 OK", response2->headers->GetStatusLine());
14873
14874 std::string response_data2;
robpercival214763f2016-07-01 23:27:0114875 ASSERT_THAT(ReadTransaction(&trans2, &response_data2), IsOk());
bnc40448a532015-05-11 19:13:1414876 EXPECT_EQ("another", response_data2);
14877}
14878
bnc5452e2a2015-05-08 16:27:4214879// Alternative service requires HTTP/2 (or SPDY), but there is already a
14880// HTTP/1.1 socket open to the alternative server. That socket should not be
14881// used.
bncd16676a2016-07-20 16:23:0114882TEST_F(HttpNetworkTransactionTest, AlternativeServiceShouldNotPoolToHttp11) {
zhongyi3d4a55e72016-04-22 20:36:4614883 url::SchemeHostPort server("https", "origin.example.org", 443);
bnc5452e2a2015-05-08 16:27:4214884 HostPortPair alternative("alternative.example.org", 443);
14885 std::string origin_url = "https://origin.example.org:443";
14886 std::string alternative_url = "https://alternative.example.org:443";
14887
14888 // Negotiate HTTP/1.1 with alternative.example.org.
14889 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3614890 ssl.next_proto = kProtoHTTP11;
bnc5452e2a2015-05-08 16:27:4214891 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
14892
14893 // HTTP/1.1 data for |request1| and |request2|.
14894 MockWrite http_writes[] = {
14895 MockWrite(
14896 "GET / HTTP/1.1\r\n"
14897 "Host: alternative.example.org\r\n"
14898 "Connection: keep-alive\r\n\r\n"),
14899 MockWrite(
14900 "GET / HTTP/1.1\r\n"
14901 "Host: alternative.example.org\r\n"
14902 "Connection: keep-alive\r\n\r\n"),
14903 };
14904
14905 MockRead http_reads[] = {
14906 MockRead(
14907 "HTTP/1.1 200 OK\r\n"
14908 "Content-Type: text/html; charset=iso-8859-1\r\n"
14909 "Content-Length: 40\r\n\r\n"
14910 "first HTTP/1.1 response from alternative"),
14911 MockRead(
14912 "HTTP/1.1 200 OK\r\n"
14913 "Content-Type: text/html; charset=iso-8859-1\r\n"
14914 "Content-Length: 41\r\n\r\n"
14915 "second HTTP/1.1 response from alternative"),
14916 };
14917 StaticSocketDataProvider http_data(http_reads, arraysize(http_reads),
14918 http_writes, arraysize(http_writes));
14919 session_deps_.socket_factory->AddSocketDataProvider(&http_data);
14920
14921 // This test documents that an alternate Job should not pool to an already
14922 // existing HTTP/1.1 connection. In order to test this, a failed connection
zhongyi3d4a55e72016-04-22 20:36:4614923 // to the server is mocked. This way |request2| relies on the alternate Job.
bnc5452e2a2015-05-08 16:27:4214924 StaticSocketDataProvider data_refused;
14925 data_refused.set_connect_data(MockConnect(ASYNC, ERR_CONNECTION_REFUSED));
14926 session_deps_.socket_factory->AddSocketDataProvider(&data_refused);
14927
zhongyi3d4a55e72016-04-22 20:36:4614928 // Set up alternative service for server.
danakj1fd259a02016-04-16 03:17:0914929 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc525e175a2016-06-20 12:36:4014930 HttpServerProperties* http_server_properties =
bnc5452e2a2015-05-08 16:27:4214931 session->http_server_properties();
bnc3472afd2016-11-17 15:27:2114932 AlternativeService alternative_service(kProtoHTTP2, alternative);
bnc7dc7e1b42015-07-28 14:43:1214933 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:2114934 http_server_properties->SetHttp2AlternativeService(
14935 server, alternative_service, expiration);
bnc5452e2a2015-05-08 16:27:4214936
14937 // First transaction to alternative to open an HTTP/1.1 socket.
bnc5452e2a2015-05-08 16:27:4214938 HttpRequestInfo request1;
krasinc06a72a2016-12-21 03:42:4614939 HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
bnc5452e2a2015-05-08 16:27:4214940 request1.method = "GET";
14941 request1.url = GURL(alternative_url);
14942 request1.load_flags = 0;
14943 TestCompletionCallback callback1;
14944
tfarina42834112016-09-22 13:38:2014945 int rv = trans1.Start(&request1, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0114946 EXPECT_THAT(callback1.GetResult(rv), IsOk());
bnc691fda62016-08-12 00:43:1614947 const HttpResponseInfo* response1 = trans1.GetResponseInfo();
bnc5452e2a2015-05-08 16:27:4214948 ASSERT_TRUE(response1);
wezca1070932016-05-26 20:30:5214949 ASSERT_TRUE(response1->headers);
bnc5452e2a2015-05-08 16:27:4214950 EXPECT_EQ("HTTP/1.1 200 OK", response1->headers->GetStatusLine());
bnc94c92842016-09-21 15:22:5214951 EXPECT_TRUE(response1->was_alpn_negotiated);
bnc5452e2a2015-05-08 16:27:4214952 EXPECT_FALSE(response1->was_fetched_via_spdy);
14953 std::string response_data1;
bnc691fda62016-08-12 00:43:1614954 ASSERT_THAT(ReadTransaction(&trans1, &response_data1), IsOk());
bnc5452e2a2015-05-08 16:27:4214955 EXPECT_EQ("first HTTP/1.1 response from alternative", response_data1);
14956
14957 // Request for origin.example.org, which has an alternative service. This
14958 // will start two Jobs: the alternative looks for connections to pool to,
14959 // finds one which is HTTP/1.1, and should ignore it, and should not try to
zhongyi3d4a55e72016-04-22 20:36:4614960 // open other connections to alternative server. The Job to server fails, so
bnc5452e2a2015-05-08 16:27:4214961 // this request fails.
bnc5452e2a2015-05-08 16:27:4214962 HttpRequestInfo request2;
krasinc06a72a2016-12-21 03:42:4614963 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
bnc5452e2a2015-05-08 16:27:4214964 request2.method = "GET";
14965 request2.url = GURL(origin_url);
14966 request2.load_flags = 0;
14967 TestCompletionCallback callback2;
14968
tfarina42834112016-09-22 13:38:2014969 rv = trans2.Start(&request2, callback2.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0114970 EXPECT_THAT(callback2.GetResult(rv), IsError(ERR_CONNECTION_REFUSED));
bnc5452e2a2015-05-08 16:27:4214971
14972 // Another transaction to alternative. This is to test that the HTTP/1.1
14973 // socket is still open and in the pool.
bnc5452e2a2015-05-08 16:27:4214974 HttpRequestInfo request3;
krasinc06a72a2016-12-21 03:42:4614975 HttpNetworkTransaction trans3(DEFAULT_PRIORITY, session.get());
bnc5452e2a2015-05-08 16:27:4214976 request3.method = "GET";
14977 request3.url = GURL(alternative_url);
14978 request3.load_flags = 0;
14979 TestCompletionCallback callback3;
14980
tfarina42834112016-09-22 13:38:2014981 rv = trans3.Start(&request3, callback3.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0114982 EXPECT_THAT(callback3.GetResult(rv), IsOk());
bnc691fda62016-08-12 00:43:1614983 const HttpResponseInfo* response3 = trans3.GetResponseInfo();
bnc5452e2a2015-05-08 16:27:4214984 ASSERT_TRUE(response3);
wezca1070932016-05-26 20:30:5214985 ASSERT_TRUE(response3->headers);
bnc5452e2a2015-05-08 16:27:4214986 EXPECT_EQ("HTTP/1.1 200 OK", response3->headers->GetStatusLine());
bnc94c92842016-09-21 15:22:5214987 EXPECT_TRUE(response3->was_alpn_negotiated);
bnc5452e2a2015-05-08 16:27:4214988 EXPECT_FALSE(response3->was_fetched_via_spdy);
14989 std::string response_data3;
bnc691fda62016-08-12 00:43:1614990 ASSERT_THAT(ReadTransaction(&trans3, &response_data3), IsOk());
bnc5452e2a2015-05-08 16:27:4214991 EXPECT_EQ("second HTTP/1.1 response from alternative", response_data3);
14992}
14993
bncd16676a2016-07-20 16:23:0114994TEST_F(HttpNetworkTransactionTest, DoNotUseSpdySessionForHttpOverTunnel) {
bncce36dca22015-04-21 22:11:2314995 const std::string https_url = "https://www.example.org:8080/";
14996 const std::string http_url = "http://www.example.org:8080/";
[email protected]8450d722012-07-02 19:14:0414997
rdsmithebb50aa2015-11-12 03:44:3814998 // Separate SPDY util instance for naked and wrapped requests.
bncd16676a2016-07-20 16:23:0114999 SpdyTestUtil spdy_util_wrapped;
rdsmithebb50aa2015-11-12 03:44:3815000
[email protected]8450d722012-07-02 19:14:0415001 // SPDY GET for HTTPS URL (through CONNECT tunnel)
bncce36dca22015-04-21 22:11:2315002 const HostPortPair host_port_pair("www.example.org", 8080);
bncdf80d44fd2016-07-15 20:27:4115003 SpdySerializedFrame connect(
lgarrona91df87f2014-12-05 00:51:3415004 spdy_util_.ConstructSpdyConnect(NULL, 0, 1, LOWEST, host_port_pair));
bncdf80d44fd2016-07-15 20:27:4115005 SpdySerializedFrame req1(
bnc38dcd392016-02-09 23:19:4915006 spdy_util_wrapped.ConstructSpdyGet(https_url.c_str(), 1, LOWEST));
bncdf80d44fd2016-07-15 20:27:4115007 SpdySerializedFrame wrapped_req1(
[email protected]23e482282013-06-14 16:08:0215008 spdy_util_.ConstructWrappedSpdyFrame(req1, 1));
[email protected]601e03f12014-04-06 16:26:3915009
15010 // SPDY GET for HTTP URL (through the proxy, but not the tunnel).
[email protected]745aa9c2014-06-27 02:21:2915011 SpdyHeaderBlock req2_block;
Bence Békybda82952017-10-02 17:35:2715012 req2_block[kHttp2MethodHeader] = "GET";
15013 req2_block[kHttp2AuthorityHeader] = "www.example.org:8080";
15014 req2_block[kHttp2SchemeHeader] = "http";
15015 req2_block[kHttp2PathHeader] = "/";
bncdf80d44fd2016-07-15 20:27:4115016 SpdySerializedFrame req2(
bnc42331402016-07-25 13:36:1515017 spdy_util_.ConstructSpdyHeaders(3, std::move(req2_block), MEDIUM, true));
[email protected]8450d722012-07-02 19:14:0415018
15019 MockWrite writes1[] = {
bncdf80d44fd2016-07-15 20:27:4115020 CreateMockWrite(connect, 0), CreateMockWrite(wrapped_req1, 2),
15021 CreateMockWrite(req2, 6),
[email protected]8450d722012-07-02 19:14:0415022 };
15023
bncdf80d44fd2016-07-15 20:27:4115024 SpdySerializedFrame conn_resp(
bnc42331402016-07-25 13:36:1515025 spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
bncdf80d44fd2016-07-15 20:27:4115026 SpdySerializedFrame resp1(
bnc42331402016-07-25 13:36:1515027 spdy_util_wrapped.ConstructSpdyGetReply(nullptr, 0, 1));
bncdf80d44fd2016-07-15 20:27:4115028 SpdySerializedFrame body1(spdy_util_wrapped.ConstructSpdyDataFrame(1, true));
15029 SpdySerializedFrame wrapped_resp1(
rdsmithebb50aa2015-11-12 03:44:3815030 spdy_util_wrapped.ConstructWrappedSpdyFrame(resp1, 1));
bncdf80d44fd2016-07-15 20:27:4115031 SpdySerializedFrame wrapped_body1(
rdsmithebb50aa2015-11-12 03:44:3815032 spdy_util_wrapped.ConstructWrappedSpdyFrame(body1, 1));
bnc42331402016-07-25 13:36:1515033 SpdySerializedFrame resp2(spdy_util_.ConstructSpdyGetReply(NULL, 0, 3));
bncdf80d44fd2016-07-15 20:27:4115034 SpdySerializedFrame body2(spdy_util_.ConstructSpdyDataFrame(3, true));
mmenke666a6fea2015-12-19 04:16:3315035 MockRead reads1[] = {
bncdf80d44fd2016-07-15 20:27:4115036 CreateMockRead(conn_resp, 1),
mmenke666a6fea2015-12-19 04:16:3315037 MockRead(ASYNC, ERR_IO_PENDING, 3),
bncdf80d44fd2016-07-15 20:27:4115038 CreateMockRead(wrapped_resp1, 4),
15039 CreateMockRead(wrapped_body1, 5),
mmenke666a6fea2015-12-19 04:16:3315040 MockRead(ASYNC, ERR_IO_PENDING, 7),
bncdf80d44fd2016-07-15 20:27:4115041 CreateMockRead(resp2, 8),
15042 CreateMockRead(body2, 9),
mmenke666a6fea2015-12-19 04:16:3315043 MockRead(SYNCHRONOUS, ERR_IO_PENDING, 10),
15044 };
[email protected]8450d722012-07-02 19:14:0415045
mmenke666a6fea2015-12-19 04:16:3315046 SequencedSocketData data1(reads1, arraysize(reads1), writes1,
15047 arraysize(writes1));
[email protected]8450d722012-07-02 19:14:0415048 MockConnect connect_data1(ASYNC, OK);
[email protected]dd54bd82012-07-19 23:44:5715049 data1.set_connect_data(connect_data1);
[email protected]8450d722012-07-02 19:14:0415050
rdsmith82957ad2015-09-16 19:42:0315051 session_deps_.proxy_service =
15052 ProxyService::CreateFixedFromPacResult("HTTPS proxy:70");
vishal.b62985ca92015-04-17 08:45:5115053 TestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:0715054 session_deps_.net_log = &log;
[email protected]8450d722012-07-02 19:14:0415055 SSLSocketDataProvider ssl1(ASYNC, OK); // to the proxy
bnc3cf2a592016-08-11 14:48:3615056 ssl1.next_proto = kProtoHTTP2;
mmenke666a6fea2015-12-19 04:16:3315057 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl1);
[email protected]8450d722012-07-02 19:14:0415058 SSLSocketDataProvider ssl2(ASYNC, OK); // to the server
bnc3cf2a592016-08-11 14:48:3615059 ssl2.next_proto = kProtoHTTP2;
mmenke666a6fea2015-12-19 04:16:3315060 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
15061 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8450d722012-07-02 19:14:0415062
danakj1fd259a02016-04-16 03:17:0915063 std::unique_ptr<HttpNetworkSession> session = CreateSession(&session_deps_);
[email protected]8450d722012-07-02 19:14:0415064
15065 // Start the first transaction to set up the SpdySession
15066 HttpRequestInfo request1;
15067 request1.method = "GET";
15068 request1.url = GURL(https_url);
[email protected]8450d722012-07-02 19:14:0415069 request1.load_flags = 0;
[email protected]90499482013-06-01 00:39:5015070 HttpNetworkTransaction trans1(LOWEST, session.get());
[email protected]8450d722012-07-02 19:14:0415071 TestCompletionCallback callback1;
tfarina42834112016-09-22 13:38:2015072 int rv = trans1.Start(&request1, callback1.callback(), NetLogWithSource());
[email protected]8450d722012-07-02 19:14:0415073
mmenke666a6fea2015-12-19 04:16:3315074 // This pause is a hack to avoid running into https://crbug.com/497228.
15075 data1.RunUntilPaused();
15076 base::RunLoop().RunUntilIdle();
15077 data1.Resume();
robpercival214763f2016-07-01 23:27:0115078 EXPECT_THAT(callback1.GetResult(rv), IsOk());
[email protected]8450d722012-07-02 19:14:0415079 EXPECT_TRUE(trans1.GetResponseInfo()->was_fetched_via_spdy);
15080
[email protected]f6c63db52013-02-02 00:35:2215081 LoadTimingInfo load_timing_info1;
15082 EXPECT_TRUE(trans1.GetLoadTimingInfo(&load_timing_info1));
15083 TestLoadTimingNotReusedWithPac(load_timing_info1,
15084 CONNECT_TIMING_HAS_SSL_TIMES);
15085
mmenke666a6fea2015-12-19 04:16:3315086 // Now, start the HTTP request.
[email protected]8450d722012-07-02 19:14:0415087 HttpRequestInfo request2;
15088 request2.method = "GET";
15089 request2.url = GURL(http_url);
[email protected]8450d722012-07-02 19:14:0415090 request2.load_flags = 0;
[email protected]90499482013-06-01 00:39:5015091 HttpNetworkTransaction trans2(MEDIUM, session.get());
[email protected]8450d722012-07-02 19:14:0415092 TestCompletionCallback callback2;
tfarina42834112016-09-22 13:38:2015093 rv = trans2.Start(&request2, callback2.callback(), NetLogWithSource());
[email protected]8450d722012-07-02 19:14:0415094
mmenke666a6fea2015-12-19 04:16:3315095 // This pause is a hack to avoid running into https://crbug.com/497228.
15096 data1.RunUntilPaused();
15097 base::RunLoop().RunUntilIdle();
15098 data1.Resume();
robpercival214763f2016-07-01 23:27:0115099 EXPECT_THAT(callback2.GetResult(rv), IsOk());
mmenke666a6fea2015-12-19 04:16:3315100
[email protected]8450d722012-07-02 19:14:0415101 EXPECT_TRUE(trans2.GetResponseInfo()->was_fetched_via_spdy);
[email protected]f6c63db52013-02-02 00:35:2215102
15103 LoadTimingInfo load_timing_info2;
15104 EXPECT_TRUE(trans2.GetLoadTimingInfo(&load_timing_info2));
15105 // The established SPDY sessions is considered reused by the HTTP request.
15106 TestLoadTimingReusedWithPac(load_timing_info2);
15107 // HTTP requests over a SPDY session should have a different connection
15108 // socket_log_id than requests over a tunnel.
15109 EXPECT_NE(load_timing_info1.socket_log_id, load_timing_info2.socket_log_id);
[email protected]8450d722012-07-02 19:14:0415110}
15111
[email protected]2d88e7d2012-07-19 17:55:1715112// Test that in the case where we have a SPDY session to a SPDY proxy
15113// that we do not pool other origins that resolve to the same IP when
15114// the certificate does not match the new origin.
15115// http://crbug.com/134690
bncd16676a2016-07-20 16:23:0115116TEST_F(HttpNetworkTransactionTest, DoNotUseSpdySessionIfCertDoesNotMatch) {
bncce36dca22015-04-21 22:11:2315117 const std::string url1 = "http://www.example.org/";
15118 const std::string url2 = "https://news.example.org/";
[email protected]2d88e7d2012-07-19 17:55:1715119 const std::string ip_addr = "1.2.3.4";
15120
rdsmithebb50aa2015-11-12 03:44:3815121 // Second SpdyTestUtil instance for the second socket.
bncd16676a2016-07-20 16:23:0115122 SpdyTestUtil spdy_util_secure;
rdsmithebb50aa2015-11-12 03:44:3815123
[email protected]2d88e7d2012-07-19 17:55:1715124 // SPDY GET for HTTP URL (through SPDY proxy)
bnc086b39e12016-06-24 13:05:2615125 SpdyHeaderBlock headers(
bncce36dca22015-04-21 22:11:2315126 spdy_util_.ConstructGetHeaderBlockForProxy("http://www.example.org/"));
bncdf80d44fd2016-07-15 20:27:4115127 SpdySerializedFrame req1(
bnc42331402016-07-25 13:36:1515128 spdy_util_.ConstructSpdyHeaders(1, std::move(headers), LOWEST, true));
[email protected]2d88e7d2012-07-19 17:55:1715129
15130 MockWrite writes1[] = {
bncdf80d44fd2016-07-15 20:27:4115131 CreateMockWrite(req1, 0),
[email protected]2d88e7d2012-07-19 17:55:1715132 };
15133
bnc42331402016-07-25 13:36:1515134 SpdySerializedFrame resp1(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
bncdf80d44fd2016-07-15 20:27:4115135 SpdySerializedFrame body1(spdy_util_.ConstructSpdyDataFrame(1, true));
[email protected]2d88e7d2012-07-19 17:55:1715136 MockRead reads1[] = {
bncdf80d44fd2016-07-15 20:27:4115137 MockRead(ASYNC, ERR_IO_PENDING, 1), CreateMockRead(resp1, 2),
15138 CreateMockRead(body1, 3), MockRead(ASYNC, OK, 4), // EOF
[email protected]2d88e7d2012-07-19 17:55:1715139 };
15140
mmenke666a6fea2015-12-19 04:16:3315141 SequencedSocketData data1(reads1, arraysize(reads1), writes1,
15142 arraysize(writes1));
martijnfe9636e2016-02-06 14:33:3215143 IPAddress ip;
martijn654c8c42016-02-10 22:10:5915144 ASSERT_TRUE(ip.AssignFromIPLiteral(ip_addr));
[email protected]2d88e7d2012-07-19 17:55:1715145 IPEndPoint peer_addr = IPEndPoint(ip, 443);
15146 MockConnect connect_data1(ASYNC, OK, peer_addr);
mmenke666a6fea2015-12-19 04:16:3315147 data1.set_connect_data(connect_data1);
[email protected]2d88e7d2012-07-19 17:55:1715148
15149 // SPDY GET for HTTPS URL (direct)
bncdf80d44fd2016-07-15 20:27:4115150 SpdySerializedFrame req2(
bnc38dcd392016-02-09 23:19:4915151 spdy_util_secure.ConstructSpdyGet(url2.c_str(), 1, MEDIUM));
[email protected]2d88e7d2012-07-19 17:55:1715152
15153 MockWrite writes2[] = {
bncdf80d44fd2016-07-15 20:27:4115154 CreateMockWrite(req2, 0),
[email protected]2d88e7d2012-07-19 17:55:1715155 };
15156
bnc42331402016-07-25 13:36:1515157 SpdySerializedFrame resp2(spdy_util_secure.ConstructSpdyGetReply(NULL, 0, 1));
bncdf80d44fd2016-07-15 20:27:4115158 SpdySerializedFrame body2(spdy_util_secure.ConstructSpdyDataFrame(1, true));
15159 MockRead reads2[] = {CreateMockRead(resp2, 1), CreateMockRead(body2, 2),
mmenke666a6fea2015-12-19 04:16:3315160 MockRead(ASYNC, OK, 3)};
[email protected]2d88e7d2012-07-19 17:55:1715161
mmenke666a6fea2015-12-19 04:16:3315162 SequencedSocketData data2(reads2, arraysize(reads2), writes2,
15163 arraysize(writes2));
[email protected]2d88e7d2012-07-19 17:55:1715164 MockConnect connect_data2(ASYNC, OK);
mmenke666a6fea2015-12-19 04:16:3315165 data2.set_connect_data(connect_data2);
[email protected]2d88e7d2012-07-19 17:55:1715166
15167 // Set up a proxy config that sends HTTP requests to a proxy, and
15168 // all others direct.
15169 ProxyConfig proxy_config;
15170 proxy_config.proxy_rules().ParseFromString("http=https://proxy:443");
Jeremy Roman0579ed62017-08-29 15:56:1915171 session_deps_.proxy_service = std::make_unique<ProxyService>(
15172 std::make_unique<ProxyConfigServiceFixed>(proxy_config), nullptr,
bnc87dcefc2017-05-25 12:47:5815173 nullptr);
[email protected]2d88e7d2012-07-19 17:55:1715174
bncce36dca22015-04-21 22:11:2315175 SSLSocketDataProvider ssl1(ASYNC, OK); // to the proxy
bnc3cf2a592016-08-11 14:48:3615176 ssl1.next_proto = kProtoHTTP2;
[email protected]2d88e7d2012-07-19 17:55:1715177 // Load a valid cert. Note, that this does not need to
15178 // be valid for proxy because the MockSSLClientSocket does
15179 // not actually verify it. But SpdySession will use this
15180 // to see if it is valid for the new origin
Ryan Sleevi4f832092017-11-21 23:25:4915181 ssl1.ssl_info.cert =
15182 ImportCertFromFile(GetTestCertsDirectory(), "ok_cert.pem");
15183 ASSERT_TRUE(ssl1.ssl_info.cert);
mmenke666a6fea2015-12-19 04:16:3315184 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl1);
15185 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]2d88e7d2012-07-19 17:55:1715186
15187 SSLSocketDataProvider ssl2(ASYNC, OK); // to the server
bnc3cf2a592016-08-11 14:48:3615188 ssl2.next_proto = kProtoHTTP2;
mmenke666a6fea2015-12-19 04:16:3315189 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
15190 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]2d88e7d2012-07-19 17:55:1715191
Jeremy Roman0579ed62017-08-29 15:56:1915192 session_deps_.host_resolver = std::make_unique<MockCachingHostResolver>();
bncce36dca22015-04-21 22:11:2315193 session_deps_.host_resolver->rules()->AddRule("news.example.org", ip_addr);
[email protected]bb88e1d32013-05-03 23:11:0715194 session_deps_.host_resolver->rules()->AddRule("proxy", ip_addr);
[email protected]2d88e7d2012-07-19 17:55:1715195
danakj1fd259a02016-04-16 03:17:0915196 std::unique_ptr<HttpNetworkSession> session = CreateSession(&session_deps_);
[email protected]2d88e7d2012-07-19 17:55:1715197
15198 // Start the first transaction to set up the SpdySession
15199 HttpRequestInfo request1;
15200 request1.method = "GET";
15201 request1.url = GURL(url1);
[email protected]2d88e7d2012-07-19 17:55:1715202 request1.load_flags = 0;
[email protected]90499482013-06-01 00:39:5015203 HttpNetworkTransaction trans1(LOWEST, session.get());
[email protected]2d88e7d2012-07-19 17:55:1715204 TestCompletionCallback callback1;
15205 ASSERT_EQ(ERR_IO_PENDING,
tfarina42834112016-09-22 13:38:2015206 trans1.Start(&request1, callback1.callback(), NetLogWithSource()));
mmenke666a6fea2015-12-19 04:16:3315207 // This pause is a hack to avoid running into https://crbug.com/497228.
15208 data1.RunUntilPaused();
15209 base::RunLoop().RunUntilIdle();
15210 data1.Resume();
[email protected]2d88e7d2012-07-19 17:55:1715211
robpercival214763f2016-07-01 23:27:0115212 EXPECT_THAT(callback1.WaitForResult(), IsOk());
[email protected]2d88e7d2012-07-19 17:55:1715213 EXPECT_TRUE(trans1.GetResponseInfo()->was_fetched_via_spdy);
15214
15215 // Now, start the HTTP request
15216 HttpRequestInfo request2;
15217 request2.method = "GET";
15218 request2.url = GURL(url2);
[email protected]2d88e7d2012-07-19 17:55:1715219 request2.load_flags = 0;
[email protected]90499482013-06-01 00:39:5015220 HttpNetworkTransaction trans2(MEDIUM, session.get());
[email protected]2d88e7d2012-07-19 17:55:1715221 TestCompletionCallback callback2;
15222 EXPECT_EQ(ERR_IO_PENDING,
tfarina42834112016-09-22 13:38:2015223 trans2.Start(&request2, callback2.callback(), NetLogWithSource()));
fdoray92e35a72016-06-10 15:54:5515224 base::RunLoop().RunUntilIdle();
[email protected]2d88e7d2012-07-19 17:55:1715225
15226 ASSERT_TRUE(callback2.have_result());
robpercival214763f2016-07-01 23:27:0115227 EXPECT_THAT(callback2.WaitForResult(), IsOk());
[email protected]2d88e7d2012-07-19 17:55:1715228 EXPECT_TRUE(trans2.GetResponseInfo()->was_fetched_via_spdy);
15229}
15230
[email protected]85f97342013-04-17 06:12:2415231// Test to verify that a failed socket read (due to an ERR_CONNECTION_CLOSED
15232// error) in SPDY session, removes the socket from pool and closes the SPDY
15233// session. Verify that new url's from the same HttpNetworkSession (and a new
15234// SpdySession) do work. http://crbug.com/224701
bncd16676a2016-07-20 16:23:0115235TEST_F(HttpNetworkTransactionTest, ErrorSocketNotConnected) {
bncce36dca22015-04-21 22:11:2315236 const std::string https_url = "https://www.example.org/";
[email protected]85f97342013-04-17 06:12:2415237
15238 MockRead reads1[] = {
15239 MockRead(SYNCHRONOUS, ERR_CONNECTION_CLOSED, 0)
15240 };
15241
mmenke11eb5152015-06-09 14:50:5015242 SequencedSocketData data1(reads1, arraysize(reads1), NULL, 0);
[email protected]85f97342013-04-17 06:12:2415243
bncdf80d44fd2016-07-15 20:27:4115244 SpdySerializedFrame req2(
bnc38dcd392016-02-09 23:19:4915245 spdy_util_.ConstructSpdyGet(https_url.c_str(), 1, MEDIUM));
[email protected]85f97342013-04-17 06:12:2415246 MockWrite writes2[] = {
bncdf80d44fd2016-07-15 20:27:4115247 CreateMockWrite(req2, 0),
[email protected]85f97342013-04-17 06:12:2415248 };
15249
bnc42331402016-07-25 13:36:1515250 SpdySerializedFrame resp2(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
bncdf80d44fd2016-07-15 20:27:4115251 SpdySerializedFrame body2(spdy_util_.ConstructSpdyDataFrame(1, true));
[email protected]85f97342013-04-17 06:12:2415252 MockRead reads2[] = {
bncdf80d44fd2016-07-15 20:27:4115253 CreateMockRead(resp2, 1), CreateMockRead(body2, 2),
15254 MockRead(ASYNC, OK, 3) // EOF
[email protected]85f97342013-04-17 06:12:2415255 };
15256
mmenke11eb5152015-06-09 14:50:5015257 SequencedSocketData data2(reads2, arraysize(reads2), writes2,
15258 arraysize(writes2));
[email protected]85f97342013-04-17 06:12:2415259
[email protected]85f97342013-04-17 06:12:2415260 SSLSocketDataProvider ssl1(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3615261 ssl1.next_proto = kProtoHTTP2;
mmenke11eb5152015-06-09 14:50:5015262 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl1);
15263 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]85f97342013-04-17 06:12:2415264
15265 SSLSocketDataProvider ssl2(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3615266 ssl2.next_proto = kProtoHTTP2;
mmenke11eb5152015-06-09 14:50:5015267 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
15268 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]85f97342013-04-17 06:12:2415269
danakj1fd259a02016-04-16 03:17:0915270 std::unique_ptr<HttpNetworkSession> session(
mmenke11eb5152015-06-09 14:50:5015271 SpdySessionDependencies::SpdyCreateSession(&session_deps_));
[email protected]85f97342013-04-17 06:12:2415272
15273 // Start the first transaction to set up the SpdySession and verify that
15274 // connection was closed.
15275 HttpRequestInfo request1;
15276 request1.method = "GET";
15277 request1.url = GURL(https_url);
15278 request1.load_flags = 0;
[email protected]90499482013-06-01 00:39:5015279 HttpNetworkTransaction trans1(MEDIUM, session.get());
[email protected]85f97342013-04-17 06:12:2415280 TestCompletionCallback callback1;
15281 EXPECT_EQ(ERR_IO_PENDING,
tfarina42834112016-09-22 13:38:2015282 trans1.Start(&request1, callback1.callback(), NetLogWithSource()));
robpercival214763f2016-07-01 23:27:0115283 EXPECT_THAT(callback1.WaitForResult(), IsError(ERR_CONNECTION_CLOSED));
[email protected]85f97342013-04-17 06:12:2415284
15285 // Now, start the second request and make sure it succeeds.
15286 HttpRequestInfo request2;
15287 request2.method = "GET";
15288 request2.url = GURL(https_url);
15289 request2.load_flags = 0;
[email protected]90499482013-06-01 00:39:5015290 HttpNetworkTransaction trans2(MEDIUM, session.get());
[email protected]85f97342013-04-17 06:12:2415291 TestCompletionCallback callback2;
15292 EXPECT_EQ(ERR_IO_PENDING,
tfarina42834112016-09-22 13:38:2015293 trans2.Start(&request2, callback2.callback(), NetLogWithSource()));
[email protected]85f97342013-04-17 06:12:2415294
robpercival214763f2016-07-01 23:27:0115295 ASSERT_THAT(callback2.WaitForResult(), IsOk());
[email protected]85f97342013-04-17 06:12:2415296 EXPECT_TRUE(trans2.GetResponseInfo()->was_fetched_via_spdy);
15297}
15298
bncd16676a2016-07-20 16:23:0115299TEST_F(HttpNetworkTransactionTest, CloseIdleSpdySessionToOpenNewOne) {
[email protected]483fa202013-05-14 01:07:0315300 ClientSocketPoolManager::set_max_sockets_per_group(
15301 HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
15302 ClientSocketPoolManager::set_max_sockets_per_pool(
15303 HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
15304
15305 // Use two different hosts with different IPs so they don't get pooled.
15306 session_deps_.host_resolver->rules()->AddRule("www.a.com", "10.0.0.1");
15307 session_deps_.host_resolver->rules()->AddRule("www.b.com", "10.0.0.2");
danakj1fd259a02016-04-16 03:17:0915308 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]483fa202013-05-14 01:07:0315309
15310 SSLSocketDataProvider ssl1(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3615311 ssl1.next_proto = kProtoHTTP2;
[email protected]483fa202013-05-14 01:07:0315312 SSLSocketDataProvider ssl2(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3615313 ssl2.next_proto = kProtoHTTP2;
[email protected]483fa202013-05-14 01:07:0315314 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl1);
15315 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
15316
bncdf80d44fd2016-07-15 20:27:4115317 SpdySerializedFrame host1_req(
bnc38dcd392016-02-09 23:19:4915318 spdy_util_.ConstructSpdyGet("https://www.a.com", 1, DEFAULT_PRIORITY));
[email protected]483fa202013-05-14 01:07:0315319 MockWrite spdy1_writes[] = {
bncdf80d44fd2016-07-15 20:27:4115320 CreateMockWrite(host1_req, 0),
[email protected]483fa202013-05-14 01:07:0315321 };
bnc42331402016-07-25 13:36:1515322 SpdySerializedFrame host1_resp(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
bncdf80d44fd2016-07-15 20:27:4115323 SpdySerializedFrame host1_resp_body(
15324 spdy_util_.ConstructSpdyDataFrame(1, true));
[email protected]483fa202013-05-14 01:07:0315325 MockRead spdy1_reads[] = {
bncdf80d44fd2016-07-15 20:27:4115326 CreateMockRead(host1_resp, 1), CreateMockRead(host1_resp_body, 2),
mmenkee24011922015-12-17 22:12:5915327 MockRead(SYNCHRONOUS, ERR_IO_PENDING, 3),
[email protected]483fa202013-05-14 01:07:0315328 };
15329
rdsmithebb50aa2015-11-12 03:44:3815330 // Use a separate test instance for the separate SpdySession that will be
15331 // created.
bncd16676a2016-07-20 16:23:0115332 SpdyTestUtil spdy_util_2;
Jeremy Roman0579ed62017-08-29 15:56:1915333 auto spdy1_data = std::make_unique<SequencedSocketData>(
bnc87dcefc2017-05-25 12:47:5815334 spdy1_reads, arraysize(spdy1_reads), spdy1_writes,
15335 arraysize(spdy1_writes));
[email protected]483fa202013-05-14 01:07:0315336 session_deps_.socket_factory->AddSocketDataProvider(spdy1_data.get());
15337
bncdf80d44fd2016-07-15 20:27:4115338 SpdySerializedFrame host2_req(
bnc38dcd392016-02-09 23:19:4915339 spdy_util_2.ConstructSpdyGet("https://www.b.com", 1, DEFAULT_PRIORITY));
[email protected]483fa202013-05-14 01:07:0315340 MockWrite spdy2_writes[] = {
bncdf80d44fd2016-07-15 20:27:4115341 CreateMockWrite(host2_req, 0),
[email protected]483fa202013-05-14 01:07:0315342 };
bnc42331402016-07-25 13:36:1515343 SpdySerializedFrame host2_resp(spdy_util_2.ConstructSpdyGetReply(NULL, 0, 1));
bncdf80d44fd2016-07-15 20:27:4115344 SpdySerializedFrame host2_resp_body(
15345 spdy_util_2.ConstructSpdyDataFrame(1, true));
[email protected]483fa202013-05-14 01:07:0315346 MockRead spdy2_reads[] = {
bncdf80d44fd2016-07-15 20:27:4115347 CreateMockRead(host2_resp, 1), CreateMockRead(host2_resp_body, 2),
mmenkee24011922015-12-17 22:12:5915348 MockRead(SYNCHRONOUS, ERR_IO_PENDING, 3),
[email protected]483fa202013-05-14 01:07:0315349 };
15350
Jeremy Roman0579ed62017-08-29 15:56:1915351 auto spdy2_data = std::make_unique<SequencedSocketData>(
bnc87dcefc2017-05-25 12:47:5815352 spdy2_reads, arraysize(spdy2_reads), spdy2_writes,
15353 arraysize(spdy2_writes));
[email protected]483fa202013-05-14 01:07:0315354 session_deps_.socket_factory->AddSocketDataProvider(spdy2_data.get());
15355
15356 MockWrite http_write[] = {
15357 MockWrite("GET / HTTP/1.1\r\n"
15358 "Host: www.a.com\r\n"
15359 "Connection: keep-alive\r\n\r\n"),
15360 };
15361
15362 MockRead http_read[] = {
15363 MockRead("HTTP/1.1 200 OK\r\n"),
15364 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
15365 MockRead("Content-Length: 6\r\n\r\n"),
15366 MockRead("hello!"),
15367 };
15368 StaticSocketDataProvider http_data(http_read, arraysize(http_read),
15369 http_write, arraysize(http_write));
15370 session_deps_.socket_factory->AddSocketDataProvider(&http_data);
15371
15372 HostPortPair host_port_pair_a("www.a.com", 443);
[email protected]e6d017652013-05-17 18:01:4015373 SpdySessionKey spdy_session_key_a(
[email protected]314b03992014-04-01 01:28:5315374 host_port_pair_a, ProxyServer::Direct(), PRIVACY_MODE_DISABLED);
[email protected]483fa202013-05-14 01:07:0315375 EXPECT_FALSE(
[email protected]41d64e82013-07-03 22:44:2615376 HasSpdySession(session->spdy_session_pool(), spdy_session_key_a));
[email protected]483fa202013-05-14 01:07:0315377
15378 TestCompletionCallback callback;
15379 HttpRequestInfo request1;
15380 request1.method = "GET";
15381 request1.url = GURL("https://www.a.com/");
15382 request1.load_flags = 0;
bnc87dcefc2017-05-25 12:47:5815383 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:1915384 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]483fa202013-05-14 01:07:0315385
tfarina42834112016-09-22 13:38:2015386 int rv = trans->Start(&request1, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0115387 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
15388 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]483fa202013-05-14 01:07:0315389
15390 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5215391 ASSERT_TRUE(response);
15392 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0215393 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]483fa202013-05-14 01:07:0315394 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5215395 EXPECT_TRUE(response->was_alpn_negotiated);
[email protected]483fa202013-05-14 01:07:0315396
15397 std::string response_data;
robpercival214763f2016-07-01 23:27:0115398 ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
[email protected]483fa202013-05-14 01:07:0315399 EXPECT_EQ("hello!", response_data);
15400 trans.reset();
15401 EXPECT_TRUE(
[email protected]41d64e82013-07-03 22:44:2615402 HasSpdySession(session->spdy_session_pool(), spdy_session_key_a));
[email protected]483fa202013-05-14 01:07:0315403
15404 HostPortPair host_port_pair_b("www.b.com", 443);
[email protected]e6d017652013-05-17 18:01:4015405 SpdySessionKey spdy_session_key_b(
[email protected]314b03992014-04-01 01:28:5315406 host_port_pair_b, ProxyServer::Direct(), PRIVACY_MODE_DISABLED);
[email protected]483fa202013-05-14 01:07:0315407 EXPECT_FALSE(
[email protected]41d64e82013-07-03 22:44:2615408 HasSpdySession(session->spdy_session_pool(), spdy_session_key_b));
[email protected]483fa202013-05-14 01:07:0315409 HttpRequestInfo request2;
15410 request2.method = "GET";
15411 request2.url = GURL("https://www.b.com/");
15412 request2.load_flags = 0;
bnc87dcefc2017-05-25 12:47:5815413 trans =
Jeremy Roman0579ed62017-08-29 15:56:1915414 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]483fa202013-05-14 01:07:0315415
tfarina42834112016-09-22 13:38:2015416 rv = trans->Start(&request2, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0115417 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
15418 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]483fa202013-05-14 01:07:0315419
15420 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5215421 ASSERT_TRUE(response);
15422 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0215423 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]483fa202013-05-14 01:07:0315424 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5215425 EXPECT_TRUE(response->was_alpn_negotiated);
robpercival214763f2016-07-01 23:27:0115426 ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
[email protected]483fa202013-05-14 01:07:0315427 EXPECT_EQ("hello!", response_data);
15428 EXPECT_FALSE(
[email protected]41d64e82013-07-03 22:44:2615429 HasSpdySession(session->spdy_session_pool(), spdy_session_key_a));
[email protected]483fa202013-05-14 01:07:0315430 EXPECT_TRUE(
[email protected]41d64e82013-07-03 22:44:2615431 HasSpdySession(session->spdy_session_pool(), spdy_session_key_b));
[email protected]483fa202013-05-14 01:07:0315432
15433 HostPortPair host_port_pair_a1("www.a.com", 80);
[email protected]e6d017652013-05-17 18:01:4015434 SpdySessionKey spdy_session_key_a1(
[email protected]314b03992014-04-01 01:28:5315435 host_port_pair_a1, ProxyServer::Direct(), PRIVACY_MODE_DISABLED);
[email protected]483fa202013-05-14 01:07:0315436 EXPECT_FALSE(
[email protected]41d64e82013-07-03 22:44:2615437 HasSpdySession(session->spdy_session_pool(), spdy_session_key_a1));
[email protected]483fa202013-05-14 01:07:0315438 HttpRequestInfo request3;
15439 request3.method = "GET";
15440 request3.url = GURL("http://www.a.com/");
15441 request3.load_flags = 0;
bnc87dcefc2017-05-25 12:47:5815442 trans =
Jeremy Roman0579ed62017-08-29 15:56:1915443 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]483fa202013-05-14 01:07:0315444
tfarina42834112016-09-22 13:38:2015445 rv = trans->Start(&request3, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0115446 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
15447 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]483fa202013-05-14 01:07:0315448
15449 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5215450 ASSERT_TRUE(response);
15451 ASSERT_TRUE(response->headers);
[email protected]483fa202013-05-14 01:07:0315452 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
15453 EXPECT_FALSE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5215454 EXPECT_FALSE(response->was_alpn_negotiated);
robpercival214763f2016-07-01 23:27:0115455 ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
[email protected]483fa202013-05-14 01:07:0315456 EXPECT_EQ("hello!", response_data);
15457 EXPECT_FALSE(
[email protected]41d64e82013-07-03 22:44:2615458 HasSpdySession(session->spdy_session_pool(), spdy_session_key_a));
[email protected]483fa202013-05-14 01:07:0315459 EXPECT_FALSE(
[email protected]41d64e82013-07-03 22:44:2615460 HasSpdySession(session->spdy_session_pool(), spdy_session_key_b));
[email protected]483fa202013-05-14 01:07:0315461}
15462
bncd16676a2016-07-20 16:23:0115463TEST_F(HttpNetworkTransactionTest, HttpSyncConnectError) {
[email protected]79e1fd62013-06-20 06:50:0415464 HttpRequestInfo request;
15465 request.method = "GET";
bncce36dca22015-04-21 22:11:2315466 request.url = GURL("http://www.example.org/");
[email protected]79e1fd62013-06-20 06:50:0415467
danakj1fd259a02016-04-16 03:17:0915468 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1615469 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]79e1fd62013-06-20 06:50:0415470
ttuttled9dbc652015-09-29 20:00:5915471 MockConnect mock_connect(SYNCHRONOUS, ERR_NAME_NOT_RESOLVED);
[email protected]79e1fd62013-06-20 06:50:0415472 StaticSocketDataProvider data;
15473 data.set_connect_data(mock_connect);
15474 session_deps_.socket_factory->AddSocketDataProvider(&data);
15475
15476 TestCompletionCallback callback;
15477
tfarina42834112016-09-22 13:38:2015478 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0115479 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]79e1fd62013-06-20 06:50:0415480
15481 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0115482 EXPECT_THAT(rv, IsError(ERR_NAME_NOT_RESOLVED));
[email protected]79e1fd62013-06-20 06:50:0415483
[email protected]79e1fd62013-06-20 06:50:0415484 // We don't care whether this succeeds or fails, but it shouldn't crash.
15485 HttpRequestHeaders request_headers;
bnc691fda62016-08-12 00:43:1615486 trans.GetFullRequestHeaders(&request_headers);
ttuttle1f2d7e92015-04-28 16:17:4715487
15488 ConnectionAttempts attempts;
bnc691fda62016-08-12 00:43:1615489 trans.GetConnectionAttempts(&attempts);
ttuttle1f2d7e92015-04-28 16:17:4715490 ASSERT_EQ(1u, attempts.size());
robpercival214763f2016-07-01 23:27:0115491 EXPECT_THAT(attempts[0].result, IsError(ERR_NAME_NOT_RESOLVED));
ttuttled9dbc652015-09-29 20:00:5915492
15493 IPEndPoint endpoint;
bnc691fda62016-08-12 00:43:1615494 EXPECT_FALSE(trans.GetRemoteEndpoint(&endpoint));
ttuttled9dbc652015-09-29 20:00:5915495 EXPECT_TRUE(endpoint.address().empty());
[email protected]79e1fd62013-06-20 06:50:0415496}
15497
bncd16676a2016-07-20 16:23:0115498TEST_F(HttpNetworkTransactionTest, HttpAsyncConnectError) {
[email protected]79e1fd62013-06-20 06:50:0415499 HttpRequestInfo request;
15500 request.method = "GET";
bncce36dca22015-04-21 22:11:2315501 request.url = GURL("http://www.example.org/");
[email protected]79e1fd62013-06-20 06:50:0415502
danakj1fd259a02016-04-16 03:17:0915503 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1615504 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]79e1fd62013-06-20 06:50:0415505
ttuttled9dbc652015-09-29 20:00:5915506 MockConnect mock_connect(ASYNC, ERR_NAME_NOT_RESOLVED);
[email protected]79e1fd62013-06-20 06:50:0415507 StaticSocketDataProvider data;
15508 data.set_connect_data(mock_connect);
15509 session_deps_.socket_factory->AddSocketDataProvider(&data);
15510
15511 TestCompletionCallback callback;
15512
tfarina42834112016-09-22 13:38:2015513 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0115514 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]79e1fd62013-06-20 06:50:0415515
15516 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0115517 EXPECT_THAT(rv, IsError(ERR_NAME_NOT_RESOLVED));
[email protected]79e1fd62013-06-20 06:50:0415518
[email protected]79e1fd62013-06-20 06:50:0415519 // We don't care whether this succeeds or fails, but it shouldn't crash.
15520 HttpRequestHeaders request_headers;
bnc691fda62016-08-12 00:43:1615521 trans.GetFullRequestHeaders(&request_headers);
ttuttle1f2d7e92015-04-28 16:17:4715522
15523 ConnectionAttempts attempts;
bnc691fda62016-08-12 00:43:1615524 trans.GetConnectionAttempts(&attempts);
ttuttle1f2d7e92015-04-28 16:17:4715525 ASSERT_EQ(1u, attempts.size());
robpercival214763f2016-07-01 23:27:0115526 EXPECT_THAT(attempts[0].result, IsError(ERR_NAME_NOT_RESOLVED));
ttuttled9dbc652015-09-29 20:00:5915527
15528 IPEndPoint endpoint;
bnc691fda62016-08-12 00:43:1615529 EXPECT_FALSE(trans.GetRemoteEndpoint(&endpoint));
ttuttled9dbc652015-09-29 20:00:5915530 EXPECT_TRUE(endpoint.address().empty());
[email protected]79e1fd62013-06-20 06:50:0415531}
15532
bncd16676a2016-07-20 16:23:0115533TEST_F(HttpNetworkTransactionTest, HttpSyncWriteError) {
[email protected]79e1fd62013-06-20 06:50:0415534 HttpRequestInfo request;
15535 request.method = "GET";
bncce36dca22015-04-21 22:11:2315536 request.url = GURL("http://www.example.org/");
[email protected]79e1fd62013-06-20 06:50:0415537
danakj1fd259a02016-04-16 03:17:0915538 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1615539 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]79e1fd62013-06-20 06:50:0415540
15541 MockWrite data_writes[] = {
15542 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
15543 };
15544 MockRead data_reads[] = {
15545 MockRead(SYNCHRONOUS, ERR_UNEXPECTED), // Should not be reached.
15546 };
15547
15548 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
15549 data_writes, arraysize(data_writes));
15550 session_deps_.socket_factory->AddSocketDataProvider(&data);
15551
15552 TestCompletionCallback callback;
15553
tfarina42834112016-09-22 13:38:2015554 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0115555 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]79e1fd62013-06-20 06:50:0415556
15557 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0115558 EXPECT_THAT(rv, IsError(ERR_CONNECTION_RESET));
[email protected]79e1fd62013-06-20 06:50:0415559
[email protected]79e1fd62013-06-20 06:50:0415560 HttpRequestHeaders request_headers;
bnc691fda62016-08-12 00:43:1615561 EXPECT_TRUE(trans.GetFullRequestHeaders(&request_headers));
[email protected]79e1fd62013-06-20 06:50:0415562 EXPECT_TRUE(request_headers.HasHeader("Host"));
15563}
15564
bncd16676a2016-07-20 16:23:0115565TEST_F(HttpNetworkTransactionTest, HttpAsyncWriteError) {
[email protected]79e1fd62013-06-20 06:50:0415566 HttpRequestInfo request;
15567 request.method = "GET";
bncce36dca22015-04-21 22:11:2315568 request.url = GURL("http://www.example.org/");
[email protected]79e1fd62013-06-20 06:50:0415569
danakj1fd259a02016-04-16 03:17:0915570 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1615571 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]79e1fd62013-06-20 06:50:0415572
15573 MockWrite data_writes[] = {
15574 MockWrite(ASYNC, ERR_CONNECTION_RESET),
15575 };
15576 MockRead data_reads[] = {
15577 MockRead(SYNCHRONOUS, ERR_UNEXPECTED), // Should not be reached.
15578 };
15579
15580 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
15581 data_writes, arraysize(data_writes));
15582 session_deps_.socket_factory->AddSocketDataProvider(&data);
15583
15584 TestCompletionCallback callback;
15585
tfarina42834112016-09-22 13:38:2015586 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0115587 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]79e1fd62013-06-20 06:50:0415588
15589 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0115590 EXPECT_THAT(rv, IsError(ERR_CONNECTION_RESET));
[email protected]79e1fd62013-06-20 06:50:0415591
[email protected]79e1fd62013-06-20 06:50:0415592 HttpRequestHeaders request_headers;
bnc691fda62016-08-12 00:43:1615593 EXPECT_TRUE(trans.GetFullRequestHeaders(&request_headers));
[email protected]79e1fd62013-06-20 06:50:0415594 EXPECT_TRUE(request_headers.HasHeader("Host"));
15595}
15596
bncd16676a2016-07-20 16:23:0115597TEST_F(HttpNetworkTransactionTest, HttpSyncReadError) {
[email protected]79e1fd62013-06-20 06:50:0415598 HttpRequestInfo request;
15599 request.method = "GET";
bncce36dca22015-04-21 22:11:2315600 request.url = GURL("http://www.example.org/");
[email protected]79e1fd62013-06-20 06:50:0415601
danakj1fd259a02016-04-16 03:17:0915602 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1615603 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]79e1fd62013-06-20 06:50:0415604
15605 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:2315606 MockWrite(
15607 "GET / HTTP/1.1\r\n"
15608 "Host: www.example.org\r\n"
15609 "Connection: keep-alive\r\n\r\n"),
[email protected]79e1fd62013-06-20 06:50:0415610 };
15611 MockRead data_reads[] = {
15612 MockRead(SYNCHRONOUS, ERR_CONNECTION_RESET),
15613 };
15614
15615 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
15616 data_writes, arraysize(data_writes));
15617 session_deps_.socket_factory->AddSocketDataProvider(&data);
15618
15619 TestCompletionCallback callback;
15620
tfarina42834112016-09-22 13:38:2015621 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0115622 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]79e1fd62013-06-20 06:50:0415623
15624 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0115625 EXPECT_THAT(rv, IsError(ERR_CONNECTION_RESET));
[email protected]79e1fd62013-06-20 06:50:0415626
[email protected]79e1fd62013-06-20 06:50:0415627 HttpRequestHeaders request_headers;
bnc691fda62016-08-12 00:43:1615628 EXPECT_TRUE(trans.GetFullRequestHeaders(&request_headers));
[email protected]79e1fd62013-06-20 06:50:0415629 EXPECT_TRUE(request_headers.HasHeader("Host"));
15630}
15631
bncd16676a2016-07-20 16:23:0115632TEST_F(HttpNetworkTransactionTest, HttpAsyncReadError) {
[email protected]79e1fd62013-06-20 06:50:0415633 HttpRequestInfo request;
15634 request.method = "GET";
bncce36dca22015-04-21 22:11:2315635 request.url = GURL("http://www.example.org/");
[email protected]79e1fd62013-06-20 06:50:0415636
danakj1fd259a02016-04-16 03:17:0915637 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1615638 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]79e1fd62013-06-20 06:50:0415639
15640 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:2315641 MockWrite(
15642 "GET / HTTP/1.1\r\n"
15643 "Host: www.example.org\r\n"
15644 "Connection: keep-alive\r\n\r\n"),
[email protected]79e1fd62013-06-20 06:50:0415645 };
15646 MockRead data_reads[] = {
15647 MockRead(ASYNC, ERR_CONNECTION_RESET),
15648 };
15649
15650 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
15651 data_writes, arraysize(data_writes));
15652 session_deps_.socket_factory->AddSocketDataProvider(&data);
15653
15654 TestCompletionCallback callback;
15655
tfarina42834112016-09-22 13:38:2015656 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0115657 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]79e1fd62013-06-20 06:50:0415658
15659 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0115660 EXPECT_THAT(rv, IsError(ERR_CONNECTION_RESET));
[email protected]79e1fd62013-06-20 06:50:0415661
[email protected]79e1fd62013-06-20 06:50:0415662 HttpRequestHeaders request_headers;
bnc691fda62016-08-12 00:43:1615663 EXPECT_TRUE(trans.GetFullRequestHeaders(&request_headers));
[email protected]79e1fd62013-06-20 06:50:0415664 EXPECT_TRUE(request_headers.HasHeader("Host"));
15665}
15666
bncd16676a2016-07-20 16:23:0115667TEST_F(HttpNetworkTransactionTest, GetFullRequestHeadersIncludesExtraHeader) {
[email protected]79e1fd62013-06-20 06:50:0415668 HttpRequestInfo request;
15669 request.method = "GET";
bncce36dca22015-04-21 22:11:2315670 request.url = GURL("http://www.example.org/");
[email protected]79e1fd62013-06-20 06:50:0415671 request.extra_headers.SetHeader("X-Foo", "bar");
15672
danakj1fd259a02016-04-16 03:17:0915673 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1615674 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]79e1fd62013-06-20 06:50:0415675
15676 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:2315677 MockWrite(
15678 "GET / HTTP/1.1\r\n"
15679 "Host: www.example.org\r\n"
15680 "Connection: keep-alive\r\n"
15681 "X-Foo: bar\r\n\r\n"),
[email protected]79e1fd62013-06-20 06:50:0415682 };
15683 MockRead data_reads[] = {
15684 MockRead("HTTP/1.1 200 OK\r\n"
15685 "Content-Length: 5\r\n\r\n"
15686 "hello"),
15687 MockRead(ASYNC, ERR_UNEXPECTED),
15688 };
15689
15690 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
15691 data_writes, arraysize(data_writes));
15692 session_deps_.socket_factory->AddSocketDataProvider(&data);
15693
15694 TestCompletionCallback callback;
15695
tfarina42834112016-09-22 13:38:2015696 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0115697 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]79e1fd62013-06-20 06:50:0415698
15699 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0115700 EXPECT_THAT(rv, IsOk());
[email protected]79e1fd62013-06-20 06:50:0415701
15702 HttpRequestHeaders request_headers;
bnc691fda62016-08-12 00:43:1615703 EXPECT_TRUE(trans.GetFullRequestHeaders(&request_headers));
[email protected]79e1fd62013-06-20 06:50:0415704 std::string foo;
15705 EXPECT_TRUE(request_headers.GetHeader("X-Foo", &foo));
15706 EXPECT_EQ("bar", foo);
15707}
15708
[email protected]bf828982013-08-14 18:01:4715709namespace {
15710
yhiranoa7e05bb2014-11-06 05:40:3915711// Fake HttpStream that simply records calls to SetPriority().
15712class FakeStream : public HttpStream,
[email protected]e86839fd2013-08-14 18:29:0315713 public base::SupportsWeakPtr<FakeStream> {
15714 public:
15715 explicit FakeStream(RequestPriority priority) : priority_(priority) {}
Chris Watkins7a41d3552017-12-01 02:13:2715716 ~FakeStream() override = default;
[email protected]e86839fd2013-08-14 18:29:0315717
15718 RequestPriority priority() const { return priority_; }
15719
dchengb03027d2014-10-21 12:00:2015720 int InitializeStream(const HttpRequestInfo* request_info,
15721 RequestPriority priority,
tfarina42834112016-09-22 13:38:2015722 const NetLogWithSource& net_log,
dchengb03027d2014-10-21 12:00:2015723 const CompletionCallback& callback) override {
[email protected]e86839fd2013-08-14 18:29:0315724 return ERR_IO_PENDING;
15725 }
15726
dchengb03027d2014-10-21 12:00:2015727 int SendRequest(const HttpRequestHeaders& request_headers,
15728 HttpResponseInfo* response,
15729 const CompletionCallback& callback) override {
[email protected]e86839fd2013-08-14 18:29:0315730 ADD_FAILURE();
15731 return ERR_UNEXPECTED;
15732 }
15733
dchengb03027d2014-10-21 12:00:2015734 int ReadResponseHeaders(const CompletionCallback& callback) override {
[email protected]e86839fd2013-08-14 18:29:0315735 ADD_FAILURE();
15736 return ERR_UNEXPECTED;
15737 }
15738
dchengb03027d2014-10-21 12:00:2015739 int ReadResponseBody(IOBuffer* buf,
15740 int buf_len,
15741 const CompletionCallback& callback) override {
[email protected]e86839fd2013-08-14 18:29:0315742 ADD_FAILURE();
15743 return ERR_UNEXPECTED;
15744 }
15745
dchengb03027d2014-10-21 12:00:2015746 void Close(bool not_reusable) override {}
[email protected]e86839fd2013-08-14 18:29:0315747
dchengb03027d2014-10-21 12:00:2015748 bool IsResponseBodyComplete() const override {
[email protected]e86839fd2013-08-14 18:29:0315749 ADD_FAILURE();
15750 return false;
15751 }
15752
dchengb03027d2014-10-21 12:00:2015753 bool IsConnectionReused() const override {
[email protected]e86839fd2013-08-14 18:29:0315754 ADD_FAILURE();
15755 return false;
15756 }
15757
dchengb03027d2014-10-21 12:00:2015758 void SetConnectionReused() override { ADD_FAILURE(); }
[email protected]e86839fd2013-08-14 18:29:0315759
mmenkebd84c392015-09-02 14:12:3415760 bool CanReuseConnection() const override { return false; }
[email protected]e86839fd2013-08-14 18:29:0315761
sclittle4de1bab92015-09-22 21:28:2415762 int64_t GetTotalReceivedBytes() const override {
[email protected]bc92bc972013-12-13 08:32:5915763 ADD_FAILURE();
15764 return 0;
15765 }
15766
sclittlebe1ccf62015-09-02 19:40:3615767 int64_t GetTotalSentBytes() const override {
15768 ADD_FAILURE();
15769 return 0;
15770 }
15771
dchengb03027d2014-10-21 12:00:2015772 bool GetLoadTimingInfo(LoadTimingInfo* load_timing_info) const override {
[email protected]e86839fd2013-08-14 18:29:0315773 ADD_FAILURE();
15774 return false;
15775 }
15776
rchcd379012017-04-12 21:53:3215777 bool GetAlternativeService(
15778 AlternativeService* alternative_service) const override {
15779 ADD_FAILURE();
15780 return false;
15781 }
15782
dchengb03027d2014-10-21 12:00:2015783 void GetSSLInfo(SSLInfo* ssl_info) override { ADD_FAILURE(); }
15784
15785 void GetSSLCertRequestInfo(SSLCertRequestInfo* cert_request_info) override {
[email protected]e86839fd2013-08-14 18:29:0315786 ADD_FAILURE();
15787 }
15788
ttuttled9dbc652015-09-29 20:00:5915789 bool GetRemoteEndpoint(IPEndPoint* endpoint) override { return false; }
15790
nharper78e6d2b2016-09-21 05:42:3515791 Error GetTokenBindingSignature(crypto::ECPrivateKey* key,
15792 TokenBindingType tb_type,
15793 std::vector<uint8_t>* out) override {
nharperb7441ef2016-01-25 23:54:1415794 ADD_FAILURE();
15795 return ERR_NOT_IMPLEMENTED;
15796 }
15797
dchengb03027d2014-10-21 12:00:2015798 void Drain(HttpNetworkSession* session) override { ADD_FAILURE(); }
[email protected]e86839fd2013-08-14 18:29:0315799
zhongyica364fbb2015-12-12 03:39:1215800 void PopulateNetErrorDetails(NetErrorDetails* details) override { return; }
15801
dchengb03027d2014-10-21 12:00:2015802 void SetPriority(RequestPriority priority) override { priority_ = priority; }
[email protected]e86839fd2013-08-14 18:29:0315803
yhiranoa7e05bb2014-11-06 05:40:3915804 HttpStream* RenewStreamForAuth() override { return NULL; }
15805
Andrey Kosyakov83a6eee2017-08-14 19:20:0415806 void SetRequestHeadersCallback(RequestHeadersCallback callback) override {}
15807
[email protected]e86839fd2013-08-14 18:29:0315808 private:
15809 RequestPriority priority_;
15810
15811 DISALLOW_COPY_AND_ASSIGN(FakeStream);
15812};
15813
15814// Fake HttpStreamRequest that simply records calls to SetPriority()
15815// and vends FakeStreams with its current priority.
[email protected]bf828982013-08-14 18:01:4715816class FakeStreamRequest : public HttpStreamRequest,
15817 public base::SupportsWeakPtr<FakeStreamRequest> {
15818 public:
[email protected]e86839fd2013-08-14 18:29:0315819 FakeStreamRequest(RequestPriority priority,
15820 HttpStreamRequest::Delegate* delegate)
15821 : priority_(priority),
[email protected]831e4a32013-11-14 02:14:4415822 delegate_(delegate),
15823 websocket_stream_create_helper_(NULL) {}
15824
15825 FakeStreamRequest(RequestPriority priority,
15826 HttpStreamRequest::Delegate* delegate,
15827 WebSocketHandshakeStreamBase::CreateHelper* create_helper)
15828 : priority_(priority),
15829 delegate_(delegate),
15830 websocket_stream_create_helper_(create_helper) {}
[email protected]e86839fd2013-08-14 18:29:0315831
Chris Watkins7a41d3552017-12-01 02:13:2715832 ~FakeStreamRequest() override = default;
[email protected]bf828982013-08-14 18:01:4715833
15834 RequestPriority priority() const { return priority_; }
15835
[email protected]831e4a32013-11-14 02:14:4415836 const WebSocketHandshakeStreamBase::CreateHelper*
15837 websocket_stream_create_helper() const {
15838 return websocket_stream_create_helper_;
15839 }
15840
[email protected]e86839fd2013-08-14 18:29:0315841 // Create a new FakeStream and pass it to the request's
15842 // delegate. Returns a weak pointer to the FakeStream.
15843 base::WeakPtr<FakeStream> FinishStreamRequest() {
Jeremy Roman0579ed62017-08-29 15:56:1915844 auto fake_stream = std::make_unique<FakeStream>(priority_);
[email protected]e86839fd2013-08-14 18:29:0315845 // Do this before calling OnStreamReady() as OnStreamReady() may
15846 // immediately delete |fake_stream|.
15847 base::WeakPtr<FakeStream> weak_stream = fake_stream->AsWeakPtr();
bnc5029f4632017-06-08 16:19:0015848 delegate_->OnStreamReady(SSLConfig(), ProxyInfo(), std::move(fake_stream));
[email protected]e86839fd2013-08-14 18:29:0315849 return weak_stream;
15850 }
15851
asanka681f02d2017-02-22 17:06:3915852 int RestartTunnelWithProxyAuth() override {
[email protected]bf828982013-08-14 18:01:4715853 ADD_FAILURE();
15854 return ERR_UNEXPECTED;
15855 }
15856
dchengb03027d2014-10-21 12:00:2015857 LoadState GetLoadState() const override {
[email protected]bf828982013-08-14 18:01:4715858 ADD_FAILURE();
15859 return LoadState();
15860 }
15861
dchengb03027d2014-10-21 12:00:2015862 void SetPriority(RequestPriority priority) override { priority_ = priority; }
[email protected]bf828982013-08-14 18:01:4715863
bnc94c92842016-09-21 15:22:5215864 bool was_alpn_negotiated() const override { return false; }
[email protected]bf828982013-08-14 18:01:4715865
bnc6227b26e2016-08-12 02:00:4315866 NextProto negotiated_protocol() const override { return kProtoUnknown; }
[email protected]bf828982013-08-14 18:01:4715867
dchengb03027d2014-10-21 12:00:2015868 bool using_spdy() const override { return false; }
[email protected]bf828982013-08-14 18:01:4715869
ttuttle1f2d7e92015-04-28 16:17:4715870 const ConnectionAttempts& connection_attempts() const override {
15871 static ConnectionAttempts no_attempts;
15872 return no_attempts;
15873 }
15874
[email protected]bf828982013-08-14 18:01:4715875 private:
15876 RequestPriority priority_;
[email protected]e86839fd2013-08-14 18:29:0315877 HttpStreamRequest::Delegate* const delegate_;
[email protected]831e4a32013-11-14 02:14:4415878 WebSocketHandshakeStreamBase::CreateHelper* websocket_stream_create_helper_;
[email protected]bf828982013-08-14 18:01:4715879
15880 DISALLOW_COPY_AND_ASSIGN(FakeStreamRequest);
15881};
15882
15883// Fake HttpStreamFactory that vends FakeStreamRequests.
15884class FakeStreamFactory : public HttpStreamFactory {
15885 public:
Chris Watkins7a41d3552017-12-01 02:13:2715886 FakeStreamFactory() = default;
15887 ~FakeStreamFactory() override = default;
[email protected]bf828982013-08-14 18:01:4715888
15889 // Returns a WeakPtr<> to the last HttpStreamRequest returned by
15890 // RequestStream() (which may be NULL if it was destroyed already).
15891 base::WeakPtr<FakeStreamRequest> last_stream_request() {
15892 return last_stream_request_;
15893 }
15894
xunjieli96f2a402017-06-05 17:24:2715895 std::unique_ptr<HttpStreamRequest> RequestStream(
15896 const HttpRequestInfo& info,
15897 RequestPriority priority,
15898 const SSLConfig& server_ssl_config,
15899 const SSLConfig& proxy_ssl_config,
15900 HttpStreamRequest::Delegate* delegate,
15901 bool enable_ip_based_pooling,
15902 bool enable_alternative_services,
15903 const NetLogWithSource& net_log) override {
Jeremy Roman0579ed62017-08-29 15:56:1915904 auto fake_request = std::make_unique<FakeStreamRequest>(priority, delegate);
[email protected]bf828982013-08-14 18:01:4715905 last_stream_request_ = fake_request->AsWeakPtr();
xunjieli96f2a402017-06-05 17:24:2715906 return std::move(fake_request);
[email protected]bf828982013-08-14 18:01:4715907 }
15908
xunjieli96f2a402017-06-05 17:24:2715909 std::unique_ptr<HttpStreamRequest> RequestBidirectionalStreamImpl(
xunjieli11834f02015-12-22 04:27:0815910 const HttpRequestInfo& info,
15911 RequestPriority priority,
15912 const SSLConfig& server_ssl_config,
15913 const SSLConfig& proxy_ssl_config,
15914 HttpStreamRequest::Delegate* delegate,
bnc8016c1f2017-03-31 02:11:2915915 bool enable_ip_based_pooling,
bncaccd4962017-04-06 21:00:2615916 bool enable_alternative_services,
tfarina42834112016-09-22 13:38:2015917 const NetLogWithSource& net_log) override {
xunjieli11834f02015-12-22 04:27:0815918 NOTREACHED();
15919 return nullptr;
15920 }
15921
xunjieli96f2a402017-06-05 17:24:2715922 std::unique_ptr<HttpStreamRequest> RequestWebSocketHandshakeStream(
[email protected]bf828982013-08-14 18:01:4715923 const HttpRequestInfo& info,
15924 RequestPriority priority,
15925 const SSLConfig& server_ssl_config,
15926 const SSLConfig& proxy_ssl_config,
15927 HttpStreamRequest::Delegate* delegate,
[email protected]467086b2013-11-12 08:19:4615928 WebSocketHandshakeStreamBase::CreateHelper* create_helper,
bnc8016c1f2017-03-31 02:11:2915929 bool enable_ip_based_pooling,
bncaccd4962017-04-06 21:00:2615930 bool enable_alternative_services,
tfarina42834112016-09-22 13:38:2015931 const NetLogWithSource& net_log) override {
xunjieli96f2a402017-06-05 17:24:2715932 auto fake_request =
Jeremy Roman0579ed62017-08-29 15:56:1915933 std::make_unique<FakeStreamRequest>(priority, delegate, create_helper);
[email protected]831e4a32013-11-14 02:14:4415934 last_stream_request_ = fake_request->AsWeakPtr();
xunjieli96f2a402017-06-05 17:24:2715935 return std::move(fake_request);
[email protected]bf828982013-08-14 18:01:4715936 }
15937
dchengb03027d2014-10-21 12:00:2015938 void PreconnectStreams(int num_streams,
nharper8cdb0fb2016-04-22 21:34:5915939 const HttpRequestInfo& info) override {
[email protected]bf828982013-08-14 18:01:4715940 ADD_FAILURE();
15941 }
15942
dchengb03027d2014-10-21 12:00:2015943 const HostMappingRules* GetHostMappingRules() const override {
[email protected]bf828982013-08-14 18:01:4715944 ADD_FAILURE();
15945 return NULL;
15946 }
15947
xunjielif5267de2017-01-20 21:18:5715948 void DumpMemoryStats(base::trace_event::ProcessMemoryDump* pmd,
15949 const std::string& parent_absolute_name) const override {
15950 ADD_FAILURE();
15951 }
15952
[email protected]bf828982013-08-14 18:01:4715953 private:
15954 base::WeakPtr<FakeStreamRequest> last_stream_request_;
15955
15956 DISALLOW_COPY_AND_ASSIGN(FakeStreamFactory);
15957};
15958
Adam Rice425cf122015-01-19 06:18:2415959// TODO(ricea): Maybe unify this with the one in
15960// url_request_http_job_unittest.cc ?
15961class FakeWebSocketBasicHandshakeStream : public WebSocketHandshakeStreamBase {
15962 public:
danakj1fd259a02016-04-16 03:17:0915963 FakeWebSocketBasicHandshakeStream(
15964 std::unique_ptr<ClientSocketHandle> connection,
15965 bool using_proxy)
mmenkea7da6da2016-09-01 21:56:5215966 : state_(std::move(connection), using_proxy, false) {}
Adam Rice425cf122015-01-19 06:18:2415967
15968 // Fake implementation of HttpStreamBase methods.
15969 // This ends up being quite "real" because this object has to really send data
15970 // on the mock socket. It might be easier to use the real implementation, but
15971 // the fact that the WebSocket code is not compiled on iOS makes that
15972 // difficult.
15973 int InitializeStream(const HttpRequestInfo* request_info,
15974 RequestPriority priority,
tfarina42834112016-09-22 13:38:2015975 const NetLogWithSource& net_log,
Adam Rice425cf122015-01-19 06:18:2415976 const CompletionCallback& callback) override {
15977 state_.Initialize(request_info, priority, net_log, callback);
15978 return OK;
15979 }
15980
15981 int SendRequest(const HttpRequestHeaders& request_headers,
15982 HttpResponseInfo* response,
15983 const CompletionCallback& callback) override {
15984 return parser()->SendRequest(state_.GenerateRequestLine(), request_headers,
15985 response, callback);
15986 }
15987
15988 int ReadResponseHeaders(const CompletionCallback& callback) override {
15989 return parser()->ReadResponseHeaders(callback);
15990 }
15991
15992 int ReadResponseBody(IOBuffer* buf,
15993 int buf_len,
15994 const CompletionCallback& callback) override {
15995 NOTREACHED();
15996 return ERR_IO_PENDING;
15997 }
15998
15999 void Close(bool not_reusable) override {
16000 if (parser())
16001 parser()->Close(true);
16002 }
16003
16004 bool IsResponseBodyComplete() const override {
16005 NOTREACHED();
16006 return false;
16007 }
16008
Adam Rice425cf122015-01-19 06:18:2416009 bool IsConnectionReused() const override {
16010 NOTREACHED();
16011 return false;
16012 }
16013 void SetConnectionReused() override { NOTREACHED(); }
16014
mmenkebd84c392015-09-02 14:12:3416015 bool CanReuseConnection() const override { return false; }
Adam Rice425cf122015-01-19 06:18:2416016
sclittle4de1bab92015-09-22 21:28:2416017 int64_t GetTotalReceivedBytes() const override {
Adam Rice425cf122015-01-19 06:18:2416018 NOTREACHED();
16019 return 0;
16020 }
16021
sclittlebe1ccf62015-09-02 19:40:3616022 int64_t GetTotalSentBytes() const override {
16023 NOTREACHED();
16024 return 0;
16025 }
16026
Adam Rice425cf122015-01-19 06:18:2416027 bool GetLoadTimingInfo(LoadTimingInfo* load_timing_info) const override {
16028 NOTREACHED();
16029 return false;
16030 }
16031
rchcd379012017-04-12 21:53:3216032 bool GetAlternativeService(
16033 AlternativeService* alternative_service) const override {
16034 ADD_FAILURE();
16035 return false;
16036 }
16037
Adam Ricecb76ac62015-02-20 05:33:2516038 void GetSSLInfo(SSLInfo* ssl_info) override {}
Adam Rice425cf122015-01-19 06:18:2416039
16040 void GetSSLCertRequestInfo(SSLCertRequestInfo* cert_request_info) override {
16041 NOTREACHED();
16042 }
16043
ttuttled9dbc652015-09-29 20:00:5916044 bool GetRemoteEndpoint(IPEndPoint* endpoint) override { return false; }
16045
nharper78e6d2b2016-09-21 05:42:3516046 Error GetTokenBindingSignature(crypto::ECPrivateKey* key,
16047 TokenBindingType tb_type,
16048 std::vector<uint8_t>* out) override {
nharperb7441ef2016-01-25 23:54:1416049 ADD_FAILURE();
16050 return ERR_NOT_IMPLEMENTED;
16051 }
16052
Adam Rice425cf122015-01-19 06:18:2416053 void Drain(HttpNetworkSession* session) override { NOTREACHED(); }
16054
zhongyica364fbb2015-12-12 03:39:1216055 void PopulateNetErrorDetails(NetErrorDetails* details) override { return; }
16056
Adam Rice425cf122015-01-19 06:18:2416057 void SetPriority(RequestPriority priority) override { NOTREACHED(); }
16058
Adam Rice425cf122015-01-19 06:18:2416059 HttpStream* RenewStreamForAuth() override {
16060 NOTREACHED();
16061 return nullptr;
16062 }
16063
16064 // Fake implementation of WebSocketHandshakeStreamBase method(s)
danakj1fd259a02016-04-16 03:17:0916065 std::unique_ptr<WebSocketStream> Upgrade() override {
Adam Rice425cf122015-01-19 06:18:2416066 NOTREACHED();
danakj1fd259a02016-04-16 03:17:0916067 return std::unique_ptr<WebSocketStream>();
Adam Rice425cf122015-01-19 06:18:2416068 }
16069
16070 private:
16071 HttpStreamParser* parser() const { return state_.parser(); }
16072 HttpBasicState state_;
16073
16074 DISALLOW_COPY_AND_ASSIGN(FakeWebSocketBasicHandshakeStream);
16075};
16076
[email protected]831e4a32013-11-14 02:14:4416077// TODO(yhirano): Split this class out into a net/websockets file, if it is
16078// worth doing.
16079class FakeWebSocketStreamCreateHelper :
16080 public WebSocketHandshakeStreamBase::CreateHelper {
16081 public:
bnc615cf2f2017-05-19 18:53:2616082 std::unique_ptr<WebSocketHandshakeStreamBase> CreateBasicStream(
danakj1fd259a02016-04-16 03:17:0916083 std::unique_ptr<ClientSocketHandle> connection,
mostynbba063d6032014-10-09 11:01:1316084 bool using_proxy) override {
Jeremy Roman0579ed62017-08-29 15:56:1916085 return std::make_unique<FakeWebSocketBasicHandshakeStream>(
bnc615cf2f2017-05-19 18:53:2616086 std::move(connection), using_proxy);
[email protected]831e4a32013-11-14 02:14:4416087 }
16088
Chris Watkins7a41d3552017-12-01 02:13:2716089 ~FakeWebSocketStreamCreateHelper() override = default;
[email protected]831e4a32013-11-14 02:14:4416090
danakj1fd259a02016-04-16 03:17:0916091 virtual std::unique_ptr<WebSocketStream> Upgrade() {
[email protected]831e4a32013-11-14 02:14:4416092 NOTREACHED();
danakj1fd259a02016-04-16 03:17:0916093 return std::unique_ptr<WebSocketStream>();
[email protected]831e4a32013-11-14 02:14:4416094 }
16095};
16096
[email protected]bf828982013-08-14 18:01:4716097} // namespace
16098
16099// Make sure that HttpNetworkTransaction passes on its priority to its
16100// stream request on start.
bncd16676a2016-07-20 16:23:0116101TEST_F(HttpNetworkTransactionTest, SetStreamRequestPriorityOnStart) {
danakj1fd259a02016-04-16 03:17:0916102 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
mmenkee65e7af2015-10-13 17:16:4216103 HttpNetworkSessionPeer peer(session.get());
[email protected]bf828982013-08-14 18:01:4716104 FakeStreamFactory* fake_factory = new FakeStreamFactory();
danakj1fd259a02016-04-16 03:17:0916105 peer.SetHttpStreamFactory(std::unique_ptr<HttpStreamFactory>(fake_factory));
[email protected]bf828982013-08-14 18:01:4716106
krasinc06a72a2016-12-21 03:42:4616107 HttpRequestInfo request;
dcheng48459ac22014-08-26 00:46:4116108 HttpNetworkTransaction trans(LOW, session.get());
[email protected]bf828982013-08-14 18:01:4716109
wezca1070932016-05-26 20:30:5216110 ASSERT_FALSE(fake_factory->last_stream_request());
[email protected]bf828982013-08-14 18:01:4716111
[email protected]bf828982013-08-14 18:01:4716112 TestCompletionCallback callback;
16113 EXPECT_EQ(ERR_IO_PENDING,
tfarina42834112016-09-22 13:38:2016114 trans.Start(&request, callback.callback(), NetLogWithSource()));
[email protected]bf828982013-08-14 18:01:4716115
16116 base::WeakPtr<FakeStreamRequest> fake_request =
16117 fake_factory->last_stream_request();
wezca1070932016-05-26 20:30:5216118 ASSERT_TRUE(fake_request);
[email protected]bf828982013-08-14 18:01:4716119 EXPECT_EQ(LOW, fake_request->priority());
16120}
16121
16122// Make sure that HttpNetworkTransaction passes on its priority
16123// updates to its stream request.
bncd16676a2016-07-20 16:23:0116124TEST_F(HttpNetworkTransactionTest, SetStreamRequestPriority) {
danakj1fd259a02016-04-16 03:17:0916125 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
mmenkee65e7af2015-10-13 17:16:4216126 HttpNetworkSessionPeer peer(session.get());
[email protected]bf828982013-08-14 18:01:4716127 FakeStreamFactory* fake_factory = new FakeStreamFactory();
danakj1fd259a02016-04-16 03:17:0916128 peer.SetHttpStreamFactory(std::unique_ptr<HttpStreamFactory>(fake_factory));
[email protected]bf828982013-08-14 18:01:4716129
krasinc06a72a2016-12-21 03:42:4616130 HttpRequestInfo request;
dcheng48459ac22014-08-26 00:46:4116131 HttpNetworkTransaction trans(LOW, session.get());
[email protected]bf828982013-08-14 18:01:4716132
[email protected]bf828982013-08-14 18:01:4716133 TestCompletionCallback callback;
16134 EXPECT_EQ(ERR_IO_PENDING,
tfarina42834112016-09-22 13:38:2016135 trans.Start(&request, callback.callback(), NetLogWithSource()));
[email protected]bf828982013-08-14 18:01:4716136
16137 base::WeakPtr<FakeStreamRequest> fake_request =
16138 fake_factory->last_stream_request();
wezca1070932016-05-26 20:30:5216139 ASSERT_TRUE(fake_request);
[email protected]bf828982013-08-14 18:01:4716140 EXPECT_EQ(LOW, fake_request->priority());
16141
16142 trans.SetPriority(LOWEST);
wezca1070932016-05-26 20:30:5216143 ASSERT_TRUE(fake_request);
[email protected]bf828982013-08-14 18:01:4716144 EXPECT_EQ(LOWEST, fake_request->priority());
16145}
16146
[email protected]e86839fd2013-08-14 18:29:0316147// Make sure that HttpNetworkTransaction passes on its priority
16148// updates to its stream.
bncd16676a2016-07-20 16:23:0116149TEST_F(HttpNetworkTransactionTest, SetStreamPriority) {
danakj1fd259a02016-04-16 03:17:0916150 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
mmenkee65e7af2015-10-13 17:16:4216151 HttpNetworkSessionPeer peer(session.get());
[email protected]e86839fd2013-08-14 18:29:0316152 FakeStreamFactory* fake_factory = new FakeStreamFactory();
danakj1fd259a02016-04-16 03:17:0916153 peer.SetHttpStreamFactory(std::unique_ptr<HttpStreamFactory>(fake_factory));
[email protected]e86839fd2013-08-14 18:29:0316154
krasinc06a72a2016-12-21 03:42:4616155 HttpRequestInfo request;
dcheng48459ac22014-08-26 00:46:4116156 HttpNetworkTransaction trans(LOW, session.get());
[email protected]e86839fd2013-08-14 18:29:0316157
[email protected]e86839fd2013-08-14 18:29:0316158 TestCompletionCallback callback;
16159 EXPECT_EQ(ERR_IO_PENDING,
tfarina42834112016-09-22 13:38:2016160 trans.Start(&request, callback.callback(), NetLogWithSource()));
[email protected]e86839fd2013-08-14 18:29:0316161
16162 base::WeakPtr<FakeStreamRequest> fake_request =
16163 fake_factory->last_stream_request();
wezca1070932016-05-26 20:30:5216164 ASSERT_TRUE(fake_request);
[email protected]e86839fd2013-08-14 18:29:0316165 base::WeakPtr<FakeStream> fake_stream = fake_request->FinishStreamRequest();
wezca1070932016-05-26 20:30:5216166 ASSERT_TRUE(fake_stream);
[email protected]e86839fd2013-08-14 18:29:0316167 EXPECT_EQ(LOW, fake_stream->priority());
16168
16169 trans.SetPriority(LOWEST);
16170 EXPECT_EQ(LOWEST, fake_stream->priority());
16171}
16172
bncd16676a2016-07-20 16:23:0116173TEST_F(HttpNetworkTransactionTest, CreateWebSocketHandshakeStream) {
[email protected]831e4a32013-11-14 02:14:4416174 // The same logic needs to be tested for both ws: and wss: schemes, but this
16175 // test is already parameterised on NextProto, so it uses a loop to verify
16176 // that the different schemes work.
bncce36dca22015-04-21 22:11:2316177 std::string test_cases[] = {"ws://www.example.org/",
16178 "wss://www.example.org/"};
[email protected]831e4a32013-11-14 02:14:4416179 for (size_t i = 0; i < arraysize(test_cases); ++i) {
danakj1fd259a02016-04-16 03:17:0916180 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
mmenkee65e7af2015-10-13 17:16:4216181 HttpNetworkSessionPeer peer(session.get());
[email protected]831e4a32013-11-14 02:14:4416182 FakeStreamFactory* fake_factory = new FakeStreamFactory();
16183 FakeWebSocketStreamCreateHelper websocket_stream_create_helper;
Bence Béky8cae04e2018-01-15 18:37:0616184 peer.SetHttpStreamFactory(std::unique_ptr<HttpStreamFactory>(fake_factory));
[email protected]831e4a32013-11-14 02:14:4416185
krasinc06a72a2016-12-21 03:42:4616186 HttpRequestInfo request;
dcheng48459ac22014-08-26 00:46:4116187 HttpNetworkTransaction trans(LOW, session.get());
[email protected]831e4a32013-11-14 02:14:4416188 trans.SetWebSocketHandshakeStreamCreateHelper(
16189 &websocket_stream_create_helper);
16190
[email protected]831e4a32013-11-14 02:14:4416191 TestCompletionCallback callback;
16192 request.method = "GET";
16193 request.url = GURL(test_cases[i]);
16194
16195 EXPECT_EQ(ERR_IO_PENDING,
tfarina42834112016-09-22 13:38:2016196 trans.Start(&request, callback.callback(), NetLogWithSource()));
[email protected]831e4a32013-11-14 02:14:4416197
16198 base::WeakPtr<FakeStreamRequest> fake_request =
16199 fake_factory->last_stream_request();
wezca1070932016-05-26 20:30:5216200 ASSERT_TRUE(fake_request);
[email protected]831e4a32013-11-14 02:14:4416201 EXPECT_EQ(&websocket_stream_create_helper,
16202 fake_request->websocket_stream_create_helper());
16203 }
16204}
16205
[email protected]043b68c82013-08-22 23:41:5216206// Tests that when a used socket is returned to the SSL socket pool, it's closed
16207// if the transport socket pool is stalled on the global socket limit.
bncd16676a2016-07-20 16:23:0116208TEST_F(HttpNetworkTransactionTest, CloseSSLSocketOnIdleForHttpRequest) {
[email protected]043b68c82013-08-22 23:41:5216209 ClientSocketPoolManager::set_max_sockets_per_group(
16210 HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
16211 ClientSocketPoolManager::set_max_sockets_per_pool(
16212 HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
16213
16214 // Set up SSL request.
16215
16216 HttpRequestInfo ssl_request;
16217 ssl_request.method = "GET";
bncce36dca22015-04-21 22:11:2316218 ssl_request.url = GURL("https://www.example.org/");
[email protected]043b68c82013-08-22 23:41:5216219
16220 MockWrite ssl_writes[] = {
bncce36dca22015-04-21 22:11:2316221 MockWrite(
16222 "GET / HTTP/1.1\r\n"
16223 "Host: www.example.org\r\n"
16224 "Connection: keep-alive\r\n\r\n"),
[email protected]043b68c82013-08-22 23:41:5216225 };
16226 MockRead ssl_reads[] = {
16227 MockRead("HTTP/1.1 200 OK\r\n"),
16228 MockRead("Content-Length: 11\r\n\r\n"),
16229 MockRead("hello world"),
16230 MockRead(SYNCHRONOUS, OK),
16231 };
16232 StaticSocketDataProvider ssl_data(ssl_reads, arraysize(ssl_reads),
16233 ssl_writes, arraysize(ssl_writes));
16234 session_deps_.socket_factory->AddSocketDataProvider(&ssl_data);
16235
16236 SSLSocketDataProvider ssl(ASYNC, OK);
16237 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
16238
16239 // Set up HTTP request.
16240
16241 HttpRequestInfo http_request;
16242 http_request.method = "GET";
bncce36dca22015-04-21 22:11:2316243 http_request.url = GURL("http://www.example.org/");
[email protected]043b68c82013-08-22 23:41:5216244
16245 MockWrite http_writes[] = {
bncce36dca22015-04-21 22:11:2316246 MockWrite(
16247 "GET / HTTP/1.1\r\n"
16248 "Host: www.example.org\r\n"
16249 "Connection: keep-alive\r\n\r\n"),
[email protected]043b68c82013-08-22 23:41:5216250 };
16251 MockRead http_reads[] = {
16252 MockRead("HTTP/1.1 200 OK\r\n"),
16253 MockRead("Content-Length: 7\r\n\r\n"),
16254 MockRead("falafel"),
16255 MockRead(SYNCHRONOUS, OK),
16256 };
16257 StaticSocketDataProvider http_data(http_reads, arraysize(http_reads),
16258 http_writes, arraysize(http_writes));
16259 session_deps_.socket_factory->AddSocketDataProvider(&http_data);
16260
danakj1fd259a02016-04-16 03:17:0916261 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]043b68c82013-08-22 23:41:5216262
16263 // Start the SSL request.
16264 TestCompletionCallback ssl_callback;
bnc691fda62016-08-12 00:43:1616265 HttpNetworkTransaction ssl_trans(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:2016266 ASSERT_EQ(ERR_IO_PENDING,
16267 ssl_trans.Start(&ssl_request, ssl_callback.callback(),
16268 NetLogWithSource()));
[email protected]043b68c82013-08-22 23:41:5216269
16270 // Start the HTTP request. Pool should stall.
16271 TestCompletionCallback http_callback;
bnc691fda62016-08-12 00:43:1616272 HttpNetworkTransaction http_trans(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:2016273 ASSERT_EQ(ERR_IO_PENDING,
16274 http_trans.Start(&http_request, http_callback.callback(),
16275 NetLogWithSource()));
dcheng48459ac22014-08-26 00:46:4116276 EXPECT_TRUE(IsTransportSocketPoolStalled(session.get()));
[email protected]043b68c82013-08-22 23:41:5216277
16278 // Wait for response from SSL request.
robpercival214763f2016-07-01 23:27:0116279 ASSERT_THAT(ssl_callback.WaitForResult(), IsOk());
[email protected]043b68c82013-08-22 23:41:5216280 std::string response_data;
bnc691fda62016-08-12 00:43:1616281 ASSERT_THAT(ReadTransaction(&ssl_trans, &response_data), IsOk());
[email protected]043b68c82013-08-22 23:41:5216282 EXPECT_EQ("hello world", response_data);
16283
16284 // The SSL socket should automatically be closed, so the HTTP request can
16285 // start.
dcheng48459ac22014-08-26 00:46:4116286 EXPECT_EQ(0, GetIdleSocketCountInSSLSocketPool(session.get()));
16287 ASSERT_FALSE(IsTransportSocketPoolStalled(session.get()));
[email protected]043b68c82013-08-22 23:41:5216288
16289 // The HTTP request can now complete.
robpercival214763f2016-07-01 23:27:0116290 ASSERT_THAT(http_callback.WaitForResult(), IsOk());
bnc691fda62016-08-12 00:43:1616291 ASSERT_THAT(ReadTransaction(&http_trans, &response_data), IsOk());
[email protected]043b68c82013-08-22 23:41:5216292 EXPECT_EQ("falafel", response_data);
16293
dcheng48459ac22014-08-26 00:46:4116294 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]043b68c82013-08-22 23:41:5216295}
16296
16297// Tests that when a SSL connection is established but there's no corresponding
16298// request that needs it, the new socket is closed if the transport socket pool
16299// is stalled on the global socket limit.
bncd16676a2016-07-20 16:23:0116300TEST_F(HttpNetworkTransactionTest, CloseSSLSocketOnIdleForHttpRequest2) {
[email protected]043b68c82013-08-22 23:41:5216301 ClientSocketPoolManager::set_max_sockets_per_group(
16302 HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
16303 ClientSocketPoolManager::set_max_sockets_per_pool(
16304 HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
16305
16306 // Set up an ssl request.
16307
16308 HttpRequestInfo ssl_request;
16309 ssl_request.method = "GET";
16310 ssl_request.url = GURL("https://www.foopy.com/");
16311
16312 // No data will be sent on the SSL socket.
16313 StaticSocketDataProvider ssl_data;
16314 session_deps_.socket_factory->AddSocketDataProvider(&ssl_data);
16315
16316 SSLSocketDataProvider ssl(ASYNC, OK);
16317 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
16318
16319 // Set up HTTP request.
16320
16321 HttpRequestInfo http_request;
16322 http_request.method = "GET";
bncce36dca22015-04-21 22:11:2316323 http_request.url = GURL("http://www.example.org/");
[email protected]043b68c82013-08-22 23:41:5216324
16325 MockWrite http_writes[] = {
bncce36dca22015-04-21 22:11:2316326 MockWrite(
16327 "GET / HTTP/1.1\r\n"
16328 "Host: www.example.org\r\n"
16329 "Connection: keep-alive\r\n\r\n"),
[email protected]043b68c82013-08-22 23:41:5216330 };
16331 MockRead http_reads[] = {
16332 MockRead("HTTP/1.1 200 OK\r\n"),
16333 MockRead("Content-Length: 7\r\n\r\n"),
16334 MockRead("falafel"),
16335 MockRead(SYNCHRONOUS, OK),
16336 };
16337 StaticSocketDataProvider http_data(http_reads, arraysize(http_reads),
16338 http_writes, arraysize(http_writes));
16339 session_deps_.socket_factory->AddSocketDataProvider(&http_data);
16340
danakj1fd259a02016-04-16 03:17:0916341 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]043b68c82013-08-22 23:41:5216342
16343 // Preconnect an SSL socket. A preconnect is needed because connect jobs are
16344 // cancelled when a normal transaction is cancelled.
ttuttle859dc7a2015-04-23 19:42:2916345 HttpStreamFactory* http_stream_factory = session->http_stream_factory();
nharper8cdb0fb2016-04-22 21:34:5916346 http_stream_factory->PreconnectStreams(1, ssl_request);
dcheng48459ac22014-08-26 00:46:4116347 EXPECT_EQ(0, GetIdleSocketCountInSSLSocketPool(session.get()));
[email protected]043b68c82013-08-22 23:41:5216348
16349 // Start the HTTP request. Pool should stall.
16350 TestCompletionCallback http_callback;
bnc691fda62016-08-12 00:43:1616351 HttpNetworkTransaction http_trans(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:2016352 ASSERT_EQ(ERR_IO_PENDING,
16353 http_trans.Start(&http_request, http_callback.callback(),
16354 NetLogWithSource()));
dcheng48459ac22014-08-26 00:46:4116355 EXPECT_TRUE(IsTransportSocketPoolStalled(session.get()));
[email protected]043b68c82013-08-22 23:41:5216356
16357 // The SSL connection will automatically be closed once the connection is
16358 // established, to let the HTTP request start.
robpercival214763f2016-07-01 23:27:0116359 ASSERT_THAT(http_callback.WaitForResult(), IsOk());
[email protected]043b68c82013-08-22 23:41:5216360 std::string response_data;
bnc691fda62016-08-12 00:43:1616361 ASSERT_THAT(ReadTransaction(&http_trans, &response_data), IsOk());
[email protected]043b68c82013-08-22 23:41:5216362 EXPECT_EQ("falafel", response_data);
16363
dcheng48459ac22014-08-26 00:46:4116364 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]043b68c82013-08-22 23:41:5216365}
16366
bncd16676a2016-07-20 16:23:0116367TEST_F(HttpNetworkTransactionTest, PostReadsErrorResponseAfterReset) {
danakj1fd259a02016-04-16 03:17:0916368 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:2216369 element_readers.push_back(
Jeremy Roman0579ed62017-08-29 15:56:1916370 std::make_unique<UploadBytesElementReader>("foo", 3));
olli.raula6df48b2a2015-11-26 07:40:2216371 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]02d74a02014-04-23 18:10:5416372
16373 HttpRequestInfo request;
16374 request.method = "POST";
16375 request.url = GURL("http://www.foo.com/");
16376 request.upload_data_stream = &upload_data_stream;
[email protected]02d74a02014-04-23 18:10:5416377
danakj1fd259a02016-04-16 03:17:0916378 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1616379 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]02d74a02014-04-23 18:10:5416380 // Send headers successfully, but get an error while sending the body.
16381 MockWrite data_writes[] = {
16382 MockWrite("POST / HTTP/1.1\r\n"
16383 "Host: www.foo.com\r\n"
16384 "Connection: keep-alive\r\n"
16385 "Content-Length: 3\r\n\r\n"),
16386 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
16387 };
16388
16389 MockRead data_reads[] = {
16390 MockRead("HTTP/1.0 400 Not OK\r\n\r\n"),
16391 MockRead("hello world"),
16392 MockRead(SYNCHRONOUS, OK),
16393 };
16394 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
16395 arraysize(data_writes));
16396 session_deps_.socket_factory->AddSocketDataProvider(&data);
16397
16398 TestCompletionCallback callback;
16399
tfarina42834112016-09-22 13:38:2016400 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0116401 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]02d74a02014-04-23 18:10:5416402
16403 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0116404 EXPECT_THAT(rv, IsOk());
[email protected]02d74a02014-04-23 18:10:5416405
bnc691fda62016-08-12 00:43:1616406 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5216407 ASSERT_TRUE(response);
[email protected]02d74a02014-04-23 18:10:5416408
wezca1070932016-05-26 20:30:5216409 EXPECT_TRUE(response->headers);
[email protected]02d74a02014-04-23 18:10:5416410 EXPECT_EQ("HTTP/1.0 400 Not OK", response->headers->GetStatusLine());
16411
16412 std::string response_data;
bnc691fda62016-08-12 00:43:1616413 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:0116414 EXPECT_THAT(rv, IsOk());
[email protected]02d74a02014-04-23 18:10:5416415 EXPECT_EQ("hello world", response_data);
16416}
16417
16418// This test makes sure the retry logic doesn't trigger when reading an error
16419// response from a server that rejected a POST with a CONNECTION_RESET.
bncd16676a2016-07-20 16:23:0116420TEST_F(HttpNetworkTransactionTest,
[email protected]02d74a02014-04-23 18:10:5416421 PostReadsErrorResponseAfterResetOnReusedSocket) {
danakj1fd259a02016-04-16 03:17:0916422 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]02d74a02014-04-23 18:10:5416423 MockWrite data_writes[] = {
16424 MockWrite("GET / HTTP/1.1\r\n"
16425 "Host: www.foo.com\r\n"
16426 "Connection: keep-alive\r\n\r\n"),
16427 MockWrite("POST / HTTP/1.1\r\n"
16428 "Host: www.foo.com\r\n"
16429 "Connection: keep-alive\r\n"
16430 "Content-Length: 3\r\n\r\n"),
16431 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
16432 };
16433
16434 MockRead data_reads[] = {
16435 MockRead("HTTP/1.1 200 Peachy\r\n"
16436 "Content-Length: 14\r\n\r\n"),
16437 MockRead("first response"),
16438 MockRead("HTTP/1.1 400 Not OK\r\n"
16439 "Content-Length: 15\r\n\r\n"),
16440 MockRead("second response"),
16441 MockRead(SYNCHRONOUS, OK),
16442 };
16443 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
16444 arraysize(data_writes));
16445 session_deps_.socket_factory->AddSocketDataProvider(&data);
16446
16447 TestCompletionCallback callback;
16448 HttpRequestInfo request1;
16449 request1.method = "GET";
16450 request1.url = GURL("http://www.foo.com/");
16451 request1.load_flags = 0;
16452
bnc87dcefc2017-05-25 12:47:5816453 auto trans1 =
Jeremy Roman0579ed62017-08-29 15:56:1916454 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:2016455 int rv = trans1->Start(&request1, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0116456 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]02d74a02014-04-23 18:10:5416457
16458 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0116459 EXPECT_THAT(rv, IsOk());
[email protected]02d74a02014-04-23 18:10:5416460
16461 const HttpResponseInfo* response1 = trans1->GetResponseInfo();
wezca1070932016-05-26 20:30:5216462 ASSERT_TRUE(response1);
[email protected]02d74a02014-04-23 18:10:5416463
wezca1070932016-05-26 20:30:5216464 EXPECT_TRUE(response1->headers);
[email protected]02d74a02014-04-23 18:10:5416465 EXPECT_EQ("HTTP/1.1 200 Peachy", response1->headers->GetStatusLine());
16466
16467 std::string response_data1;
16468 rv = ReadTransaction(trans1.get(), &response_data1);
robpercival214763f2016-07-01 23:27:0116469 EXPECT_THAT(rv, IsOk());
[email protected]02d74a02014-04-23 18:10:5416470 EXPECT_EQ("first response", response_data1);
16471 // Delete the transaction to release the socket back into the socket pool.
16472 trans1.reset();
16473
danakj1fd259a02016-04-16 03:17:0916474 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:2216475 element_readers.push_back(
Jeremy Roman0579ed62017-08-29 15:56:1916476 std::make_unique<UploadBytesElementReader>("foo", 3));
olli.raula6df48b2a2015-11-26 07:40:2216477 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]02d74a02014-04-23 18:10:5416478
16479 HttpRequestInfo request2;
16480 request2.method = "POST";
16481 request2.url = GURL("http://www.foo.com/");
16482 request2.upload_data_stream = &upload_data_stream;
16483 request2.load_flags = 0;
16484
bnc691fda62016-08-12 00:43:1616485 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:2016486 rv = trans2.Start(&request2, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0116487 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]02d74a02014-04-23 18:10:5416488
16489 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0116490 EXPECT_THAT(rv, IsOk());
[email protected]02d74a02014-04-23 18:10:5416491
bnc691fda62016-08-12 00:43:1616492 const HttpResponseInfo* response2 = trans2.GetResponseInfo();
wezca1070932016-05-26 20:30:5216493 ASSERT_TRUE(response2);
[email protected]02d74a02014-04-23 18:10:5416494
wezca1070932016-05-26 20:30:5216495 EXPECT_TRUE(response2->headers);
[email protected]02d74a02014-04-23 18:10:5416496 EXPECT_EQ("HTTP/1.1 400 Not OK", response2->headers->GetStatusLine());
16497
16498 std::string response_data2;
bnc691fda62016-08-12 00:43:1616499 rv = ReadTransaction(&trans2, &response_data2);
robpercival214763f2016-07-01 23:27:0116500 EXPECT_THAT(rv, IsOk());
[email protected]02d74a02014-04-23 18:10:5416501 EXPECT_EQ("second response", response_data2);
16502}
16503
bncd16676a2016-07-20 16:23:0116504TEST_F(HttpNetworkTransactionTest,
[email protected]02d74a02014-04-23 18:10:5416505 PostReadsErrorResponseAfterResetPartialBodySent) {
danakj1fd259a02016-04-16 03:17:0916506 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:2216507 element_readers.push_back(
Jeremy Roman0579ed62017-08-29 15:56:1916508 std::make_unique<UploadBytesElementReader>("foo", 3));
olli.raula6df48b2a2015-11-26 07:40:2216509 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]02d74a02014-04-23 18:10:5416510
16511 HttpRequestInfo request;
16512 request.method = "POST";
16513 request.url = GURL("http://www.foo.com/");
16514 request.upload_data_stream = &upload_data_stream;
[email protected]02d74a02014-04-23 18:10:5416515
danakj1fd259a02016-04-16 03:17:0916516 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1616517 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]02d74a02014-04-23 18:10:5416518 // Send headers successfully, but get an error while sending the body.
16519 MockWrite data_writes[] = {
16520 MockWrite("POST / HTTP/1.1\r\n"
16521 "Host: www.foo.com\r\n"
16522 "Connection: keep-alive\r\n"
16523 "Content-Length: 3\r\n\r\n"
16524 "fo"),
16525 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
16526 };
16527
16528 MockRead data_reads[] = {
16529 MockRead("HTTP/1.0 400 Not OK\r\n\r\n"),
16530 MockRead("hello world"),
16531 MockRead(SYNCHRONOUS, OK),
16532 };
16533 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
16534 arraysize(data_writes));
16535 session_deps_.socket_factory->AddSocketDataProvider(&data);
16536
16537 TestCompletionCallback callback;
16538
tfarina42834112016-09-22 13:38:2016539 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0116540 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]02d74a02014-04-23 18:10:5416541
16542 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0116543 EXPECT_THAT(rv, IsOk());
[email protected]02d74a02014-04-23 18:10:5416544
bnc691fda62016-08-12 00:43:1616545 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5216546 ASSERT_TRUE(response);
[email protected]02d74a02014-04-23 18:10:5416547
wezca1070932016-05-26 20:30:5216548 EXPECT_TRUE(response->headers);
[email protected]02d74a02014-04-23 18:10:5416549 EXPECT_EQ("HTTP/1.0 400 Not OK", response->headers->GetStatusLine());
16550
16551 std::string response_data;
bnc691fda62016-08-12 00:43:1616552 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:0116553 EXPECT_THAT(rv, IsOk());
[email protected]02d74a02014-04-23 18:10:5416554 EXPECT_EQ("hello world", response_data);
16555}
16556
16557// This tests the more common case than the previous test, where headers and
16558// body are not merged into a single request.
bncd16676a2016-07-20 16:23:0116559TEST_F(HttpNetworkTransactionTest, ChunkedPostReadsErrorResponseAfterReset) {
mmenkecbc2b712014-10-09 20:29:0716560 ChunkedUploadDataStream upload_data_stream(0);
[email protected]02d74a02014-04-23 18:10:5416561
16562 HttpRequestInfo request;
16563 request.method = "POST";
16564 request.url = GURL("http://www.foo.com/");
16565 request.upload_data_stream = &upload_data_stream;
[email protected]02d74a02014-04-23 18:10:5416566
danakj1fd259a02016-04-16 03:17:0916567 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1616568 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]02d74a02014-04-23 18:10:5416569 // Send headers successfully, but get an error while sending the body.
16570 MockWrite data_writes[] = {
16571 MockWrite("POST / HTTP/1.1\r\n"
16572 "Host: www.foo.com\r\n"
16573 "Connection: keep-alive\r\n"
16574 "Transfer-Encoding: chunked\r\n\r\n"),
16575 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
16576 };
16577
16578 MockRead data_reads[] = {
16579 MockRead("HTTP/1.0 400 Not OK\r\n\r\n"),
16580 MockRead("hello world"),
16581 MockRead(SYNCHRONOUS, OK),
16582 };
16583 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
16584 arraysize(data_writes));
16585 session_deps_.socket_factory->AddSocketDataProvider(&data);
16586
16587 TestCompletionCallback callback;
16588
tfarina42834112016-09-22 13:38:2016589 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0116590 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]02d74a02014-04-23 18:10:5416591 // Make sure the headers are sent before adding a chunk. This ensures that
16592 // they can't be merged with the body in a single send. Not currently
16593 // necessary since a chunked body is never merged with headers, but this makes
16594 // the test more future proof.
16595 base::RunLoop().RunUntilIdle();
16596
mmenkecbc2b712014-10-09 20:29:0716597 upload_data_stream.AppendData("last chunk", 10, true);
[email protected]02d74a02014-04-23 18:10:5416598
16599 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0116600 EXPECT_THAT(rv, IsOk());
[email protected]02d74a02014-04-23 18:10:5416601
bnc691fda62016-08-12 00:43:1616602 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5216603 ASSERT_TRUE(response);
[email protected]02d74a02014-04-23 18:10:5416604
wezca1070932016-05-26 20:30:5216605 EXPECT_TRUE(response->headers);
[email protected]02d74a02014-04-23 18:10:5416606 EXPECT_EQ("HTTP/1.0 400 Not OK", response->headers->GetStatusLine());
16607
16608 std::string response_data;
bnc691fda62016-08-12 00:43:1616609 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:0116610 EXPECT_THAT(rv, IsOk());
[email protected]02d74a02014-04-23 18:10:5416611 EXPECT_EQ("hello world", response_data);
16612}
16613
bncd16676a2016-07-20 16:23:0116614TEST_F(HttpNetworkTransactionTest, PostReadsErrorResponseAfterResetAnd100) {
danakj1fd259a02016-04-16 03:17:0916615 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:2216616 element_readers.push_back(
Jeremy Roman0579ed62017-08-29 15:56:1916617 std::make_unique<UploadBytesElementReader>("foo", 3));
olli.raula6df48b2a2015-11-26 07:40:2216618 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]02d74a02014-04-23 18:10:5416619
16620 HttpRequestInfo request;
16621 request.method = "POST";
16622 request.url = GURL("http://www.foo.com/");
16623 request.upload_data_stream = &upload_data_stream;
[email protected]02d74a02014-04-23 18:10:5416624
danakj1fd259a02016-04-16 03:17:0916625 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1616626 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]02d74a02014-04-23 18:10:5416627
16628 MockWrite data_writes[] = {
16629 MockWrite("POST / HTTP/1.1\r\n"
16630 "Host: www.foo.com\r\n"
16631 "Connection: keep-alive\r\n"
16632 "Content-Length: 3\r\n\r\n"),
16633 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
16634 };
16635
16636 MockRead data_reads[] = {
16637 MockRead("HTTP/1.0 100 Continue\r\n\r\n"),
16638 MockRead("HTTP/1.0 400 Not OK\r\n\r\n"),
16639 MockRead("hello world"),
16640 MockRead(SYNCHRONOUS, OK),
16641 };
16642 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
16643 arraysize(data_writes));
16644 session_deps_.socket_factory->AddSocketDataProvider(&data);
16645
16646 TestCompletionCallback callback;
16647
tfarina42834112016-09-22 13:38:2016648 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0116649 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]02d74a02014-04-23 18:10:5416650
16651 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0116652 EXPECT_THAT(rv, IsOk());
[email protected]02d74a02014-04-23 18:10:5416653
bnc691fda62016-08-12 00:43:1616654 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5216655 ASSERT_TRUE(response);
[email protected]02d74a02014-04-23 18:10:5416656
wezca1070932016-05-26 20:30:5216657 EXPECT_TRUE(response->headers);
[email protected]02d74a02014-04-23 18:10:5416658 EXPECT_EQ("HTTP/1.0 400 Not OK", response->headers->GetStatusLine());
16659
16660 std::string response_data;
bnc691fda62016-08-12 00:43:1616661 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:0116662 EXPECT_THAT(rv, IsOk());
[email protected]02d74a02014-04-23 18:10:5416663 EXPECT_EQ("hello world", response_data);
16664}
16665
bncd16676a2016-07-20 16:23:0116666TEST_F(HttpNetworkTransactionTest, PostIgnoresNonErrorResponseAfterReset) {
danakj1fd259a02016-04-16 03:17:0916667 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:2216668 element_readers.push_back(
Jeremy Roman0579ed62017-08-29 15:56:1916669 std::make_unique<UploadBytesElementReader>("foo", 3));
olli.raula6df48b2a2015-11-26 07:40:2216670 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]02d74a02014-04-23 18:10:5416671
16672 HttpRequestInfo request;
16673 request.method = "POST";
16674 request.url = GURL("http://www.foo.com/");
16675 request.upload_data_stream = &upload_data_stream;
[email protected]02d74a02014-04-23 18:10:5416676
danakj1fd259a02016-04-16 03:17:0916677 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1616678 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]02d74a02014-04-23 18:10:5416679 // Send headers successfully, but get an error while sending the body.
16680 MockWrite data_writes[] = {
16681 MockWrite("POST / HTTP/1.1\r\n"
16682 "Host: www.foo.com\r\n"
16683 "Connection: keep-alive\r\n"
16684 "Content-Length: 3\r\n\r\n"),
16685 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
16686 };
16687
16688 MockRead data_reads[] = {
16689 MockRead("HTTP/1.0 200 Just Dandy\r\n\r\n"),
16690 MockRead("hello world"),
16691 MockRead(SYNCHRONOUS, OK),
16692 };
16693 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
16694 arraysize(data_writes));
16695 session_deps_.socket_factory->AddSocketDataProvider(&data);
16696
16697 TestCompletionCallback callback;
16698
tfarina42834112016-09-22 13:38:2016699 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0116700 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]02d74a02014-04-23 18:10:5416701
16702 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0116703 EXPECT_THAT(rv, IsError(ERR_CONNECTION_RESET));
[email protected]02d74a02014-04-23 18:10:5416704}
16705
bncd16676a2016-07-20 16:23:0116706TEST_F(HttpNetworkTransactionTest,
[email protected]02d74a02014-04-23 18:10:5416707 PostIgnoresNonErrorResponseAfterResetAnd100) {
danakj1fd259a02016-04-16 03:17:0916708 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:2216709 element_readers.push_back(
Jeremy Roman0579ed62017-08-29 15:56:1916710 std::make_unique<UploadBytesElementReader>("foo", 3));
olli.raula6df48b2a2015-11-26 07:40:2216711 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]02d74a02014-04-23 18:10:5416712
16713 HttpRequestInfo request;
16714 request.method = "POST";
16715 request.url = GURL("http://www.foo.com/");
16716 request.upload_data_stream = &upload_data_stream;
[email protected]02d74a02014-04-23 18:10:5416717
danakj1fd259a02016-04-16 03:17:0916718 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1616719 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]02d74a02014-04-23 18:10:5416720 // Send headers successfully, but get an error while sending the body.
16721 MockWrite data_writes[] = {
16722 MockWrite("POST / HTTP/1.1\r\n"
16723 "Host: www.foo.com\r\n"
16724 "Connection: keep-alive\r\n"
16725 "Content-Length: 3\r\n\r\n"),
16726 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
16727 };
16728
16729 MockRead data_reads[] = {
16730 MockRead("HTTP/1.0 100 Continue\r\n\r\n"),
16731 MockRead("HTTP/1.0 302 Redirect\r\n"),
16732 MockRead("Location: http://somewhere-else.com/\r\n"),
16733 MockRead("Content-Length: 0\r\n\r\n"),
16734 MockRead(SYNCHRONOUS, OK),
16735 };
16736 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
16737 arraysize(data_writes));
16738 session_deps_.socket_factory->AddSocketDataProvider(&data);
16739
16740 TestCompletionCallback callback;
16741
tfarina42834112016-09-22 13:38:2016742 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0116743 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]02d74a02014-04-23 18:10:5416744
16745 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0116746 EXPECT_THAT(rv, IsError(ERR_CONNECTION_RESET));
[email protected]02d74a02014-04-23 18:10:5416747}
16748
bncd16676a2016-07-20 16:23:0116749TEST_F(HttpNetworkTransactionTest, PostIgnoresHttp09ResponseAfterReset) {
danakj1fd259a02016-04-16 03:17:0916750 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:2216751 element_readers.push_back(
Jeremy Roman0579ed62017-08-29 15:56:1916752 std::make_unique<UploadBytesElementReader>("foo", 3));
olli.raula6df48b2a2015-11-26 07:40:2216753 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]02d74a02014-04-23 18:10:5416754
16755 HttpRequestInfo request;
16756 request.method = "POST";
16757 request.url = GURL("http://www.foo.com/");
16758 request.upload_data_stream = &upload_data_stream;
[email protected]02d74a02014-04-23 18:10:5416759
danakj1fd259a02016-04-16 03:17:0916760 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1616761 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]02d74a02014-04-23 18:10:5416762 // Send headers successfully, but get an error while sending the body.
16763 MockWrite data_writes[] = {
16764 MockWrite("POST / HTTP/1.1\r\n"
16765 "Host: www.foo.com\r\n"
16766 "Connection: keep-alive\r\n"
16767 "Content-Length: 3\r\n\r\n"),
16768 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
16769 };
16770
16771 MockRead data_reads[] = {
16772 MockRead("HTTP 0.9 rocks!"),
16773 MockRead(SYNCHRONOUS, OK),
16774 };
16775 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
16776 arraysize(data_writes));
16777 session_deps_.socket_factory->AddSocketDataProvider(&data);
16778
16779 TestCompletionCallback callback;
16780
tfarina42834112016-09-22 13:38:2016781 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0116782 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]02d74a02014-04-23 18:10:5416783
16784 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0116785 EXPECT_THAT(rv, IsError(ERR_CONNECTION_RESET));
[email protected]02d74a02014-04-23 18:10:5416786}
16787
bncd16676a2016-07-20 16:23:0116788TEST_F(HttpNetworkTransactionTest, PostIgnoresPartial400HeadersAfterReset) {
danakj1fd259a02016-04-16 03:17:0916789 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:2216790 element_readers.push_back(
Jeremy Roman0579ed62017-08-29 15:56:1916791 std::make_unique<UploadBytesElementReader>("foo", 3));
olli.raula6df48b2a2015-11-26 07:40:2216792 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]02d74a02014-04-23 18:10:5416793
16794 HttpRequestInfo request;
16795 request.method = "POST";
16796 request.url = GURL("http://www.foo.com/");
16797 request.upload_data_stream = &upload_data_stream;
[email protected]02d74a02014-04-23 18:10:5416798
danakj1fd259a02016-04-16 03:17:0916799 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1616800 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]02d74a02014-04-23 18:10:5416801 // Send headers successfully, but get an error while sending the body.
16802 MockWrite data_writes[] = {
16803 MockWrite("POST / HTTP/1.1\r\n"
16804 "Host: www.foo.com\r\n"
16805 "Connection: keep-alive\r\n"
16806 "Content-Length: 3\r\n\r\n"),
16807 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
16808 };
16809
16810 MockRead data_reads[] = {
16811 MockRead("HTTP/1.0 400 Not a Full Response\r\n"),
16812 MockRead(SYNCHRONOUS, OK),
16813 };
16814 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
16815 arraysize(data_writes));
16816 session_deps_.socket_factory->AddSocketDataProvider(&data);
16817
16818 TestCompletionCallback callback;
16819
tfarina42834112016-09-22 13:38:2016820 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0116821 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]02d74a02014-04-23 18:10:5416822
16823 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0116824 EXPECT_THAT(rv, IsError(ERR_CONNECTION_RESET));
[email protected]02d74a02014-04-23 18:10:5416825}
16826
Adam Rice425cf122015-01-19 06:18:2416827// Verify that proxy headers are not sent to the destination server when
16828// establishing a tunnel for a secure WebSocket connection.
bncd16676a2016-07-20 16:23:0116829TEST_F(HttpNetworkTransactionTest, ProxyHeadersNotSentOverWssTunnel) {
Adam Rice425cf122015-01-19 06:18:2416830 HttpRequestInfo request;
16831 request.method = "GET";
bncce36dca22015-04-21 22:11:2316832 request.url = GURL("wss://www.example.org/");
Adam Rice425cf122015-01-19 06:18:2416833 AddWebSocketHeaders(&request.extra_headers);
16834
16835 // Configure against proxy server "myproxy:70".
rdsmith82957ad2015-09-16 19:42:0316836 session_deps_.proxy_service =
16837 ProxyService::CreateFixedFromPacResult("PROXY myproxy:70");
Adam Rice425cf122015-01-19 06:18:2416838
danakj1fd259a02016-04-16 03:17:0916839 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
Adam Rice425cf122015-01-19 06:18:2416840
16841 // Since a proxy is configured, try to establish a tunnel.
16842 MockWrite data_writes[] = {
rsleevidb16bb02015-11-12 23:47:1716843 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
16844 "Host: www.example.org:443\r\n"
16845 "Proxy-Connection: keep-alive\r\n\r\n"),
Adam Rice425cf122015-01-19 06:18:2416846
16847 // After calling trans->RestartWithAuth(), this is the request we should
16848 // be issuing -- the final header line contains the credentials.
rsleevidb16bb02015-11-12 23:47:1716849 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
16850 "Host: www.example.org:443\r\n"
16851 "Proxy-Connection: keep-alive\r\n"
16852 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
Adam Rice425cf122015-01-19 06:18:2416853
rsleevidb16bb02015-11-12 23:47:1716854 MockWrite("GET / HTTP/1.1\r\n"
16855 "Host: www.example.org\r\n"
16856 "Connection: Upgrade\r\n"
16857 "Upgrade: websocket\r\n"
16858 "Origin: http://www.example.org\r\n"
16859 "Sec-WebSocket-Version: 13\r\n"
16860 "Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==\r\n\r\n"),
Adam Rice425cf122015-01-19 06:18:2416861 };
16862
16863 // The proxy responds to the connect with a 407, using a persistent
16864 // connection.
16865 MockRead data_reads[] = {
16866 // No credentials.
16867 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
16868 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
mmenkee71e15332015-10-07 16:39:5416869 MockRead("Content-Length: 0\r\n"),
16870 MockRead("Proxy-Connection: keep-alive\r\n\r\n"),
Adam Rice425cf122015-01-19 06:18:2416871
16872 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
16873
16874 MockRead("HTTP/1.1 101 Switching Protocols\r\n"),
16875 MockRead("Upgrade: websocket\r\n"),
16876 MockRead("Connection: Upgrade\r\n"),
16877 MockRead("Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=\r\n\r\n"),
16878 };
16879
16880 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
16881 arraysize(data_writes));
16882 session_deps_.socket_factory->AddSocketDataProvider(&data);
16883 SSLSocketDataProvider ssl(ASYNC, OK);
16884 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
16885
bnc87dcefc2017-05-25 12:47:5816886 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:1916887 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
Adam Rice425cf122015-01-19 06:18:2416888 FakeWebSocketStreamCreateHelper websocket_stream_create_helper;
16889 trans->SetWebSocketHandshakeStreamCreateHelper(
16890 &websocket_stream_create_helper);
16891
16892 {
16893 TestCompletionCallback callback;
16894
tfarina42834112016-09-22 13:38:2016895 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0116896 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
Adam Rice425cf122015-01-19 06:18:2416897
16898 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0116899 EXPECT_THAT(rv, IsOk());
Adam Rice425cf122015-01-19 06:18:2416900 }
16901
16902 const HttpResponseInfo* response = trans->GetResponseInfo();
16903 ASSERT_TRUE(response);
wezca1070932016-05-26 20:30:5216904 ASSERT_TRUE(response->headers);
Adam Rice425cf122015-01-19 06:18:2416905 EXPECT_EQ(407, response->headers->response_code());
16906
16907 {
16908 TestCompletionCallback callback;
16909
16910 int rv = trans->RestartWithAuth(AuthCredentials(kFoo, kBar),
16911 callback.callback());
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 response = trans->GetResponseInfo();
16919 ASSERT_TRUE(response);
wezca1070932016-05-26 20:30:5216920 ASSERT_TRUE(response->headers);
Adam Rice425cf122015-01-19 06:18:2416921
16922 EXPECT_EQ(101, response->headers->response_code());
16923
16924 trans.reset();
16925 session->CloseAllConnections();
16926}
16927
16928// Verify that proxy headers are not sent to the destination server when
16929// establishing a tunnel for an insecure WebSocket connection.
16930// This requires the authentication info to be injected into the auth cache
16931// due to crbug.com/395064
16932// TODO(ricea): Change to use a 407 response once issue 395064 is fixed.
bncd16676a2016-07-20 16:23:0116933TEST_F(HttpNetworkTransactionTest, ProxyHeadersNotSentOverWsTunnel) {
Adam Rice425cf122015-01-19 06:18:2416934 HttpRequestInfo request;
16935 request.method = "GET";
bncce36dca22015-04-21 22:11:2316936 request.url = GURL("ws://www.example.org/");
Adam Rice425cf122015-01-19 06:18:2416937 AddWebSocketHeaders(&request.extra_headers);
16938
16939 // Configure against proxy server "myproxy:70".
rdsmith82957ad2015-09-16 19:42:0316940 session_deps_.proxy_service =
16941 ProxyService::CreateFixedFromPacResult("PROXY myproxy:70");
Adam Rice425cf122015-01-19 06:18:2416942
danakj1fd259a02016-04-16 03:17:0916943 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
Adam Rice425cf122015-01-19 06:18:2416944
16945 MockWrite data_writes[] = {
16946 // Try to establish a tunnel for the WebSocket connection, with
16947 // credentials. Because WebSockets have a separate set of socket pools,
16948 // they cannot and will not use the same TCP/IP connection as the
16949 // preflight HTTP request.
16950 MockWrite(
bncce36dca22015-04-21 22:11:2316951 "CONNECT www.example.org:80 HTTP/1.1\r\n"
16952 "Host: www.example.org:80\r\n"
Adam Rice425cf122015-01-19 06:18:2416953 "Proxy-Connection: keep-alive\r\n"
16954 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
16955
16956 MockWrite(
16957 "GET / HTTP/1.1\r\n"
bncce36dca22015-04-21 22:11:2316958 "Host: www.example.org\r\n"
Adam Rice425cf122015-01-19 06:18:2416959 "Connection: Upgrade\r\n"
16960 "Upgrade: websocket\r\n"
bncce36dca22015-04-21 22:11:2316961 "Origin: http://www.example.org\r\n"
Adam Rice425cf122015-01-19 06:18:2416962 "Sec-WebSocket-Version: 13\r\n"
16963 "Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==\r\n\r\n"),
16964 };
16965
16966 MockRead data_reads[] = {
16967 // HTTP CONNECT with credentials.
16968 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
16969
16970 // WebSocket connection established inside tunnel.
16971 MockRead("HTTP/1.1 101 Switching Protocols\r\n"),
16972 MockRead("Upgrade: websocket\r\n"),
16973 MockRead("Connection: Upgrade\r\n"),
16974 MockRead("Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=\r\n\r\n"),
16975 };
16976
16977 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
16978 arraysize(data_writes));
16979 session_deps_.socket_factory->AddSocketDataProvider(&data);
16980
16981 session->http_auth_cache()->Add(
16982 GURL("http://myproxy:70/"), "MyRealm1", HttpAuth::AUTH_SCHEME_BASIC,
16983 "Basic realm=MyRealm1", AuthCredentials(kFoo, kBar), "/");
16984
bnc87dcefc2017-05-25 12:47:5816985 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:1916986 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
Adam Rice425cf122015-01-19 06:18:2416987 FakeWebSocketStreamCreateHelper websocket_stream_create_helper;
16988 trans->SetWebSocketHandshakeStreamCreateHelper(
16989 &websocket_stream_create_helper);
16990
16991 TestCompletionCallback callback;
16992
tfarina42834112016-09-22 13:38:2016993 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0116994 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
Adam Rice425cf122015-01-19 06:18:2416995
16996 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0116997 EXPECT_THAT(rv, IsOk());
Adam Rice425cf122015-01-19 06:18:2416998
16999 const HttpResponseInfo* response = trans->GetResponseInfo();
17000 ASSERT_TRUE(response);
wezca1070932016-05-26 20:30:5217001 ASSERT_TRUE(response->headers);
Adam Rice425cf122015-01-19 06:18:2417002
17003 EXPECT_EQ(101, response->headers->response_code());
17004
17005 trans.reset();
17006 session->CloseAllConnections();
17007}
17008
bncd16676a2016-07-20 16:23:0117009TEST_F(HttpNetworkTransactionTest, TotalNetworkBytesPost) {
danakj1fd259a02016-04-16 03:17:0917010 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:2217011 element_readers.push_back(
Jeremy Roman0579ed62017-08-29 15:56:1917012 std::make_unique<UploadBytesElementReader>("foo", 3));
olli.raula6df48b2a2015-11-26 07:40:2217013 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
sclittlefb249892015-09-10 21:33:2217014
17015 HttpRequestInfo request;
17016 request.method = "POST";
17017 request.url = GURL("http://www.foo.com/");
17018 request.upload_data_stream = &upload_data_stream;
17019
danakj1fd259a02016-04-16 03:17:0917020 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1617021 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
sclittlefb249892015-09-10 21:33:2217022 MockWrite data_writes[] = {
17023 MockWrite("POST / HTTP/1.1\r\n"
17024 "Host: www.foo.com\r\n"
17025 "Connection: keep-alive\r\n"
17026 "Content-Length: 3\r\n\r\n"),
17027 MockWrite("foo"),
17028 };
17029
17030 MockRead data_reads[] = {
17031 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello world"),
17032 MockRead(SYNCHRONOUS, OK),
17033 };
17034 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
17035 arraysize(data_writes));
17036 session_deps_.socket_factory->AddSocketDataProvider(&data);
17037
17038 TestCompletionCallback callback;
17039
17040 EXPECT_EQ(ERR_IO_PENDING,
tfarina42834112016-09-22 13:38:2017041 trans.Start(&request, callback.callback(), NetLogWithSource()));
robpercival214763f2016-07-01 23:27:0117042 EXPECT_THAT(callback.WaitForResult(), IsOk());
sclittlefb249892015-09-10 21:33:2217043
17044 std::string response_data;
bnc691fda62016-08-12 00:43:1617045 EXPECT_THAT(ReadTransaction(&trans, &response_data), IsOk());
sclittlefb249892015-09-10 21:33:2217046
17047 EXPECT_EQ(CountWriteBytes(data_writes, arraysize(data_writes)),
bnc691fda62016-08-12 00:43:1617048 trans.GetTotalSentBytes());
sclittlefb249892015-09-10 21:33:2217049 EXPECT_EQ(CountReadBytes(data_reads, arraysize(data_reads)),
bnc691fda62016-08-12 00:43:1617050 trans.GetTotalReceivedBytes());
sclittlefb249892015-09-10 21:33:2217051}
17052
bncd16676a2016-07-20 16:23:0117053TEST_F(HttpNetworkTransactionTest, TotalNetworkBytesPost100Continue) {
danakj1fd259a02016-04-16 03:17:0917054 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:2217055 element_readers.push_back(
Jeremy Roman0579ed62017-08-29 15:56:1917056 std::make_unique<UploadBytesElementReader>("foo", 3));
olli.raula6df48b2a2015-11-26 07:40:2217057 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
sclittlefb249892015-09-10 21:33:2217058
17059 HttpRequestInfo request;
17060 request.method = "POST";
17061 request.url = GURL("http://www.foo.com/");
17062 request.upload_data_stream = &upload_data_stream;
17063
danakj1fd259a02016-04-16 03:17:0917064 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1617065 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
sclittlefb249892015-09-10 21:33:2217066 MockWrite data_writes[] = {
17067 MockWrite("POST / HTTP/1.1\r\n"
17068 "Host: www.foo.com\r\n"
17069 "Connection: keep-alive\r\n"
17070 "Content-Length: 3\r\n\r\n"),
17071 MockWrite("foo"),
17072 };
17073
17074 MockRead data_reads[] = {
17075 MockRead("HTTP/1.1 100 Continue\r\n\r\n"),
17076 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello world"),
17077 MockRead(SYNCHRONOUS, OK),
17078 };
17079 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
17080 arraysize(data_writes));
17081 session_deps_.socket_factory->AddSocketDataProvider(&data);
17082
17083 TestCompletionCallback callback;
17084
17085 EXPECT_EQ(ERR_IO_PENDING,
tfarina42834112016-09-22 13:38:2017086 trans.Start(&request, callback.callback(), NetLogWithSource()));
robpercival214763f2016-07-01 23:27:0117087 EXPECT_THAT(callback.WaitForResult(), IsOk());
sclittlefb249892015-09-10 21:33:2217088
17089 std::string response_data;
bnc691fda62016-08-12 00:43:1617090 EXPECT_THAT(ReadTransaction(&trans, &response_data), IsOk());
sclittlefb249892015-09-10 21:33:2217091
17092 EXPECT_EQ(CountWriteBytes(data_writes, arraysize(data_writes)),
bnc691fda62016-08-12 00:43:1617093 trans.GetTotalSentBytes());
sclittlefb249892015-09-10 21:33:2217094 EXPECT_EQ(CountReadBytes(data_reads, arraysize(data_reads)),
bnc691fda62016-08-12 00:43:1617095 trans.GetTotalReceivedBytes());
sclittlefb249892015-09-10 21:33:2217096}
17097
bncd16676a2016-07-20 16:23:0117098TEST_F(HttpNetworkTransactionTest, TotalNetworkBytesChunkedPost) {
sclittlefb249892015-09-10 21:33:2217099 ChunkedUploadDataStream upload_data_stream(0);
17100
17101 HttpRequestInfo request;
17102 request.method = "POST";
17103 request.url = GURL("http://www.foo.com/");
17104 request.upload_data_stream = &upload_data_stream;
17105
danakj1fd259a02016-04-16 03:17:0917106 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1617107 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
sclittlefb249892015-09-10 21:33:2217108 // Send headers successfully, but get an error while sending the body.
17109 MockWrite data_writes[] = {
17110 MockWrite("POST / HTTP/1.1\r\n"
17111 "Host: www.foo.com\r\n"
17112 "Connection: keep-alive\r\n"
17113 "Transfer-Encoding: chunked\r\n\r\n"),
17114 MockWrite("1\r\nf\r\n"), MockWrite("2\r\noo\r\n"), MockWrite("0\r\n\r\n"),
17115 };
17116
17117 MockRead data_reads[] = {
17118 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello world"),
17119 MockRead(SYNCHRONOUS, OK),
17120 };
17121 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
17122 arraysize(data_writes));
17123 session_deps_.socket_factory->AddSocketDataProvider(&data);
17124
17125 TestCompletionCallback callback;
17126
17127 EXPECT_EQ(ERR_IO_PENDING,
tfarina42834112016-09-22 13:38:2017128 trans.Start(&request, callback.callback(), NetLogWithSource()));
sclittlefb249892015-09-10 21:33:2217129
17130 base::RunLoop().RunUntilIdle();
17131 upload_data_stream.AppendData("f", 1, false);
17132
17133 base::RunLoop().RunUntilIdle();
17134 upload_data_stream.AppendData("oo", 2, true);
17135
robpercival214763f2016-07-01 23:27:0117136 EXPECT_THAT(callback.WaitForResult(), IsOk());
sclittlefb249892015-09-10 21:33:2217137
17138 std::string response_data;
bnc691fda62016-08-12 00:43:1617139 EXPECT_THAT(ReadTransaction(&trans, &response_data), IsOk());
sclittlefb249892015-09-10 21:33:2217140
17141 EXPECT_EQ(CountWriteBytes(data_writes, arraysize(data_writes)),
bnc691fda62016-08-12 00:43:1617142 trans.GetTotalSentBytes());
sclittlefb249892015-09-10 21:33:2217143 EXPECT_EQ(CountReadBytes(data_reads, arraysize(data_reads)),
bnc691fda62016-08-12 00:43:1617144 trans.GetTotalReceivedBytes());
sclittlefb249892015-09-10 21:33:2217145}
17146
rdsmith1d343be52016-10-21 20:37:5017147// Confirm that transactions whose throttle is created in (and stays in)
17148// the unthrottled state are not blocked.
17149TEST_F(HttpNetworkTransactionTest, ThrottlingUnthrottled) {
17150 TestNetworkStreamThrottler* throttler(nullptr);
17151 std::unique_ptr<HttpNetworkSession> session(
17152 CreateSessionWithThrottler(&session_deps_, &throttler));
17153
17154 // Send a simple request and make sure it goes through.
17155 HttpRequestInfo request;
17156 request.method = "GET";
17157 request.url = GURL("http://www.example.org/");
17158
bnc87dcefc2017-05-25 12:47:5817159 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:1917160 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
rdsmith1d343be52016-10-21 20:37:5017161
17162 MockWrite data_writes[] = {
17163 MockWrite("GET / HTTP/1.1\r\n"
17164 "Host: www.example.org\r\n"
17165 "Connection: keep-alive\r\n\r\n"),
17166 };
17167 MockRead data_reads[] = {
17168 MockRead("HTTP/1.0 200 OK\r\n\r\n"), MockRead("hello world"),
17169 MockRead(SYNCHRONOUS, OK),
17170 };
17171 StaticSocketDataProvider reads(data_reads, arraysize(data_reads), data_writes,
17172 arraysize(data_writes));
17173 session_deps_.socket_factory->AddSocketDataProvider(&reads);
17174
17175 TestCompletionCallback callback;
17176 trans->Start(&request, callback.callback(), NetLogWithSource());
17177 EXPECT_EQ(OK, callback.WaitForResult());
17178}
17179
17180// Confirm requests can be blocked by a throttler, and are resumed
17181// when the throttle is unblocked.
17182TEST_F(HttpNetworkTransactionTest, ThrottlingBasic) {
17183 TestNetworkStreamThrottler* throttler(nullptr);
17184 std::unique_ptr<HttpNetworkSession> session(
17185 CreateSessionWithThrottler(&session_deps_, &throttler));
17186
17187 // Send a simple request and make sure it goes through.
17188 HttpRequestInfo request;
17189 request.method = "GET";
17190 request.url = GURL("http://www.example.org/");
17191
17192 MockWrite data_writes[] = {
17193 MockWrite("GET / HTTP/1.1\r\n"
17194 "Host: www.example.org\r\n"
17195 "Connection: keep-alive\r\n\r\n"),
17196 };
17197 MockRead data_reads[] = {
17198 MockRead("HTTP/1.0 200 OK\r\n\r\n"), MockRead("hello world"),
17199 MockRead(SYNCHRONOUS, OK),
17200 };
17201 StaticSocketDataProvider reads(data_reads, arraysize(data_reads), data_writes,
17202 arraysize(data_writes));
17203 session_deps_.socket_factory->AddSocketDataProvider(&reads);
17204
17205 // Start a request that will be throttled at start; confirm it
17206 // doesn't complete.
17207 throttler->set_throttle_new_requests(true);
bnc87dcefc2017-05-25 12:47:5817208 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:1917209 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
rdsmith1d343be52016-10-21 20:37:5017210
17211 TestCompletionCallback callback;
17212 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
17213 EXPECT_EQ(ERR_IO_PENDING, rv);
17214
17215 base::RunLoop().RunUntilIdle();
17216 EXPECT_EQ(LOAD_STATE_THROTTLED, trans->GetLoadState());
17217 EXPECT_FALSE(callback.have_result());
17218
17219 // Confirm the request goes on to complete when unthrottled.
17220 throttler->UnthrottleAllRequests();
17221 base::RunLoop().RunUntilIdle();
17222 ASSERT_TRUE(callback.have_result());
17223 EXPECT_EQ(OK, callback.WaitForResult());
17224}
17225
17226// Destroy a request while it's throttled.
17227TEST_F(HttpNetworkTransactionTest, ThrottlingDestruction) {
17228 TestNetworkStreamThrottler* throttler(nullptr);
17229 std::unique_ptr<HttpNetworkSession> session(
17230 CreateSessionWithThrottler(&session_deps_, &throttler));
17231
17232 // Send a simple request and make sure it goes through.
17233 HttpRequestInfo request;
17234 request.method = "GET";
17235 request.url = GURL("http://www.example.org/");
17236
17237 MockWrite data_writes[] = {
17238 MockWrite("GET / HTTP/1.1\r\n"
17239 "Host: www.example.org\r\n"
17240 "Connection: keep-alive\r\n\r\n"),
17241 };
17242 MockRead data_reads[] = {
17243 MockRead("HTTP/1.0 200 OK\r\n\r\n"), MockRead("hello world"),
17244 MockRead(SYNCHRONOUS, OK),
17245 };
17246 StaticSocketDataProvider reads(data_reads, arraysize(data_reads), data_writes,
17247 arraysize(data_writes));
17248 session_deps_.socket_factory->AddSocketDataProvider(&reads);
17249
17250 // Start a request that will be throttled at start; confirm it
17251 // doesn't complete.
17252 throttler->set_throttle_new_requests(true);
bnc87dcefc2017-05-25 12:47:5817253 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:1917254 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
rdsmith1d343be52016-10-21 20:37:5017255
17256 TestCompletionCallback callback;
17257 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
17258 EXPECT_EQ(ERR_IO_PENDING, rv);
17259
17260 base::RunLoop().RunUntilIdle();
17261 EXPECT_EQ(LOAD_STATE_THROTTLED, trans->GetLoadState());
17262 EXPECT_FALSE(callback.have_result());
17263
17264 EXPECT_EQ(1u, throttler->num_outstanding_requests());
17265 trans.reset();
17266 EXPECT_EQ(0u, throttler->num_outstanding_requests());
17267}
17268
17269// Confirm the throttler receives SetPriority calls.
17270TEST_F(HttpNetworkTransactionTest, ThrottlingPrioritySet) {
17271 TestNetworkStreamThrottler* throttler(nullptr);
17272 std::unique_ptr<HttpNetworkSession> session(
17273 CreateSessionWithThrottler(&session_deps_, &throttler));
17274
17275 // Send a simple request and make sure it goes through.
17276 HttpRequestInfo request;
17277 request.method = "GET";
17278 request.url = GURL("http://www.example.org/");
17279
17280 MockWrite data_writes[] = {
17281 MockWrite("GET / HTTP/1.1\r\n"
17282 "Host: www.example.org\r\n"
17283 "Connection: keep-alive\r\n\r\n"),
17284 };
17285 MockRead data_reads[] = {
17286 MockRead("HTTP/1.0 200 OK\r\n\r\n"), MockRead("hello world"),
17287 MockRead(SYNCHRONOUS, OK),
17288 };
17289 StaticSocketDataProvider reads(data_reads, arraysize(data_reads), data_writes,
17290 arraysize(data_writes));
17291 session_deps_.socket_factory->AddSocketDataProvider(&reads);
17292
17293 throttler->set_throttle_new_requests(true);
Jeremy Roman0579ed62017-08-29 15:56:1917294 auto trans = std::make_unique<HttpNetworkTransaction>(IDLE, session.get());
rdsmith1d343be52016-10-21 20:37:5017295 // Start the transaction to associate a throttle with it.
17296 TestCompletionCallback callback;
17297 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
17298 EXPECT_EQ(ERR_IO_PENDING, rv);
17299
17300 EXPECT_EQ(0, throttler->num_set_priority_calls());
17301 trans->SetPriority(LOW);
17302 EXPECT_EQ(1, throttler->num_set_priority_calls());
17303 EXPECT_EQ(LOW, throttler->last_priority_set());
17304
17305 throttler->UnthrottleAllRequests();
17306 base::RunLoop().RunUntilIdle();
17307 ASSERT_TRUE(callback.have_result());
17308 EXPECT_EQ(OK, callback.WaitForResult());
17309}
17310
17311// Confirm that unthrottling from a SetPriority call by the
17312// throttler works properly.
17313TEST_F(HttpNetworkTransactionTest, ThrottlingPrioritySetUnthrottle) {
17314 TestNetworkStreamThrottler* throttler(nullptr);
17315 std::unique_ptr<HttpNetworkSession> session(
17316 CreateSessionWithThrottler(&session_deps_, &throttler));
17317
17318 // Send a simple request and make sure it goes through.
17319 HttpRequestInfo request;
17320 request.method = "GET";
17321 request.url = GURL("http://www.example.org/");
17322
17323 MockWrite data_writes[] = {
17324 MockWrite("GET / HTTP/1.1\r\n"
17325 "Host: www.example.org\r\n"
17326 "Connection: keep-alive\r\n\r\n"),
17327 };
17328 MockRead data_reads[] = {
17329 MockRead("HTTP/1.0 200 OK\r\n\r\n"), MockRead("hello world"),
17330 MockRead(SYNCHRONOUS, OK),
17331 };
17332 StaticSocketDataProvider reads(data_reads, arraysize(data_reads), data_writes,
17333 arraysize(data_writes));
17334 session_deps_.socket_factory->AddSocketDataProvider(&reads);
17335
17336 StaticSocketDataProvider reads1(data_reads, arraysize(data_reads),
17337 data_writes, arraysize(data_writes));
17338 session_deps_.socket_factory->AddSocketDataProvider(&reads1);
17339
17340 // Start a request that will be throttled at start; confirm it
17341 // doesn't complete.
17342 throttler->set_throttle_new_requests(true);
bnc87dcefc2017-05-25 12:47:5817343 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:1917344 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
rdsmith1d343be52016-10-21 20:37:5017345
17346 TestCompletionCallback callback;
17347 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
17348 EXPECT_EQ(ERR_IO_PENDING, rv);
17349
17350 base::RunLoop().RunUntilIdle();
17351 EXPECT_EQ(LOAD_STATE_THROTTLED, trans->GetLoadState());
17352 EXPECT_FALSE(callback.have_result());
17353
17354 // Create a new request, call SetPriority on it to unthrottle,
17355 // and make sure that allows the original request to complete.
Jeremy Roman0579ed62017-08-29 15:56:1917356 auto trans1 = std::make_unique<HttpNetworkTransaction>(LOW, session.get());
rdsmith1d343be52016-10-21 20:37:5017357 throttler->set_priority_change_closure(
17358 base::Bind(&TestNetworkStreamThrottler::UnthrottleAllRequests,
17359 base::Unretained(throttler)));
17360
17361 // Start the transaction to associate a throttle with it.
17362 TestCompletionCallback callback1;
17363 rv = trans1->Start(&request, callback1.callback(), NetLogWithSource());
17364 EXPECT_EQ(ERR_IO_PENDING, rv);
17365
17366 trans1->SetPriority(IDLE);
17367
17368 base::RunLoop().RunUntilIdle();
17369 ASSERT_TRUE(callback.have_result());
17370 EXPECT_EQ(OK, callback.WaitForResult());
17371 ASSERT_TRUE(callback1.have_result());
17372 EXPECT_EQ(OK, callback1.WaitForResult());
17373}
17374
17375// Transaction will be destroyed when the unique_ptr goes out of scope.
bnc87dcefc2017-05-25 12:47:5817376void DestroyTransaction(std::unique_ptr<HttpNetworkTransaction> transaction) {}
rdsmith1d343be52016-10-21 20:37:5017377
17378// Confirm that destroying a transaction from a SetPriority call by the
17379// throttler works properly.
17380TEST_F(HttpNetworkTransactionTest, ThrottlingPrioritySetDestroy) {
17381 TestNetworkStreamThrottler* throttler(nullptr);
17382 std::unique_ptr<HttpNetworkSession> session(
17383 CreateSessionWithThrottler(&session_deps_, &throttler));
17384
17385 // Send a simple request and make sure it goes through.
17386 HttpRequestInfo request;
17387 request.method = "GET";
17388 request.url = GURL("http://www.example.org/");
17389
17390 MockWrite data_writes[] = {
17391 MockWrite("GET / HTTP/1.1\r\n"
17392 "Host: www.example.org\r\n"
17393 "Connection: keep-alive\r\n\r\n"),
17394 };
17395 MockRead data_reads[] = {
17396 MockRead("HTTP/1.0 200 OK\r\n\r\n"), MockRead("hello world"),
17397 MockRead(SYNCHRONOUS, OK),
17398 };
17399 StaticSocketDataProvider reads(data_reads, arraysize(data_reads), data_writes,
17400 arraysize(data_writes));
17401 session_deps_.socket_factory->AddSocketDataProvider(&reads);
17402
17403 StaticSocketDataProvider reads1(data_reads, arraysize(data_reads),
17404 data_writes, arraysize(data_writes));
17405 session_deps_.socket_factory->AddSocketDataProvider(&reads1);
17406
17407 // Start a request that will be throttled at start; confirm it
17408 // doesn't complete.
17409 throttler->set_throttle_new_requests(true);
bnc87dcefc2017-05-25 12:47:5817410 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:1917411 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
rdsmith1d343be52016-10-21 20:37:5017412
17413 TestCompletionCallback callback;
17414 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
17415 EXPECT_EQ(ERR_IO_PENDING, rv);
17416
17417 base::RunLoop().RunUntilIdle();
17418 EXPECT_EQ(LOAD_STATE_THROTTLED, trans->GetLoadState());
17419 EXPECT_FALSE(callback.have_result());
17420
17421 // Arrange for the set priority call on the above transaction to delete
17422 // the transaction.
bnc87dcefc2017-05-25 12:47:5817423 HttpNetworkTransaction* trans_ptr(trans.get());
rdsmith1d343be52016-10-21 20:37:5017424 throttler->set_priority_change_closure(
17425 base::Bind(&DestroyTransaction, base::Passed(&trans)));
17426
17427 // Call it and check results (partially a "doesn't crash" test).
17428 trans_ptr->SetPriority(IDLE);
17429 trans_ptr = nullptr; // No longer a valid pointer.
17430
17431 base::RunLoop().RunUntilIdle();
17432 ASSERT_FALSE(callback.have_result());
17433}
17434
nharperb7441ef2016-01-25 23:54:1417435#if !defined(OS_IOS)
bncd16676a2016-07-20 16:23:0117436TEST_F(HttpNetworkTransactionTest, TokenBindingSpdy) {
nharperb7441ef2016-01-25 23:54:1417437 const std::string https_url = "https://www.example.com";
17438 HttpRequestInfo request;
17439 request.url = GURL(https_url);
17440 request.method = "GET";
17441
17442 SSLSocketDataProvider ssl(ASYNC, OK);
Ryan Sleevi4f832092017-11-21 23:25:4917443 ssl.ssl_info.token_binding_negotiated = true;
17444 ssl.ssl_info.token_binding_key_param = TB_PARAM_ECDSAP256;
bnc3cf2a592016-08-11 14:48:3617445 ssl.next_proto = kProtoHTTP2;
nharperb7441ef2016-01-25 23:54:1417446 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
17447
bnc42331402016-07-25 13:36:1517448 SpdySerializedFrame resp(spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
bncdf80d44fd2016-07-15 20:27:4117449 SpdySerializedFrame body(spdy_util_.ConstructSpdyDataFrame(1, true));
17450 MockRead reads[] = {CreateMockRead(resp), CreateMockRead(body),
nharperb7441ef2016-01-25 23:54:1417451 MockRead(ASYNC, ERR_IO_PENDING)};
17452 StaticSocketDataProvider data(reads, arraysize(reads), nullptr, 0);
17453 session_deps_.socket_factory->AddSocketDataProvider(&data);
bnc87dcefc2017-05-25 12:47:5817454 session_deps_.channel_id_service =
Jeremy Roman0579ed62017-08-29 15:56:1917455 std::make_unique<ChannelIDService>(new DefaultChannelIDStore(nullptr));
danakj1fd259a02016-04-16 03:17:0917456 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
nharperb7441ef2016-01-25 23:54:1417457
17458 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
17459 TestCompletionCallback callback;
17460 EXPECT_EQ(ERR_IO_PENDING,
tfarina42834112016-09-22 13:38:2017461 trans.Start(&request, callback.callback(), NetLogWithSource()));
fdorayf33fede2017-05-11 21:18:1017462
17463 NetTestSuite::GetScopedTaskEnvironment()->RunUntilIdle();
nharperb7441ef2016-01-25 23:54:1417464
17465 EXPECT_TRUE(trans.GetResponseInfo()->was_fetched_via_spdy);
17466 HttpRequestHeaders headers;
17467 ASSERT_TRUE(trans.GetFullRequestHeaders(&headers));
17468 EXPECT_TRUE(headers.HasHeader(HttpRequestHeaders::kTokenBinding));
17469}
17470#endif // !defined(OS_IOS)
17471
eustasc7d27da2017-04-06 10:33:2017472void CheckContentEncodingMatching(SpdySessionDependencies* session_deps,
17473 const std::string& accept_encoding,
17474 const std::string& content_encoding,
sky50576f32017-05-01 19:28:0317475 const std::string& location,
eustasc7d27da2017-04-06 10:33:2017476 bool should_match) {
17477 HttpRequestInfo request;
17478 request.method = "GET";
17479 request.url = GURL("http://www.foo.com/");
17480 request.extra_headers.SetHeader(HttpRequestHeaders::kAcceptEncoding,
17481 accept_encoding);
17482
17483 std::unique_ptr<HttpNetworkSession> session(CreateSession(session_deps));
17484 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
17485 // Send headers successfully, but get an error while sending the body.
17486 MockWrite data_writes[] = {
17487 MockWrite("GET / HTTP/1.1\r\n"
17488 "Host: www.foo.com\r\n"
17489 "Connection: keep-alive\r\n"
17490 "Accept-Encoding: "),
17491 MockWrite(accept_encoding.data()), MockWrite("\r\n\r\n"),
17492 };
17493
sky50576f32017-05-01 19:28:0317494 std::string response_code = "200 OK";
17495 std::string extra;
17496 if (!location.empty()) {
17497 response_code = "301 Redirect\r\nLocation: ";
17498 response_code.append(location);
17499 }
17500
eustasc7d27da2017-04-06 10:33:2017501 MockRead data_reads[] = {
sky50576f32017-05-01 19:28:0317502 MockRead("HTTP/1.0 "),
17503 MockRead(response_code.data()),
17504 MockRead("\r\nContent-Encoding: "),
17505 MockRead(content_encoding.data()),
17506 MockRead("\r\n\r\n"),
eustasc7d27da2017-04-06 10:33:2017507 MockRead(SYNCHRONOUS, OK),
17508 };
17509 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
17510 arraysize(data_writes));
17511 session_deps->socket_factory->AddSocketDataProvider(&data);
17512
17513 TestCompletionCallback callback;
17514
17515 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
17516 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
17517
17518 rv = callback.WaitForResult();
17519 if (should_match) {
17520 EXPECT_THAT(rv, IsOk());
17521 } else {
17522 EXPECT_THAT(rv, IsError(ERR_CONTENT_DECODING_FAILED));
17523 }
17524}
17525
17526TEST_F(HttpNetworkTransactionTest, MatchContentEncoding1) {
sky50576f32017-05-01 19:28:0317527 CheckContentEncodingMatching(&session_deps_, "gzip,sdch", "br", "", false);
eustasc7d27da2017-04-06 10:33:2017528}
17529
17530TEST_F(HttpNetworkTransactionTest, MatchContentEncoding2) {
sky50576f32017-05-01 19:28:0317531 CheckContentEncodingMatching(&session_deps_, "identity;q=1, *;q=0", "", "",
17532 true);
eustasc7d27da2017-04-06 10:33:2017533}
17534
17535TEST_F(HttpNetworkTransactionTest, MatchContentEncoding3) {
17536 CheckContentEncodingMatching(&session_deps_, "identity;q=1, *;q=0", "gzip",
sky50576f32017-05-01 19:28:0317537 "", false);
17538}
17539
17540TEST_F(HttpNetworkTransactionTest, MatchContentEncoding4) {
17541 CheckContentEncodingMatching(&session_deps_, "identity;q=1, *;q=0", "gzip",
17542 "www.foo.com/other", true);
eustasc7d27da2017-04-06 10:33:2017543}
17544
xunjieli96f2a402017-06-05 17:24:2717545TEST_F(HttpNetworkTransactionTest, ProxyResolutionFailsSync) {
17546 ProxyConfig proxy_config;
17547 proxy_config.set_pac_url(GURL("http://fooproxyurl"));
17548 proxy_config.set_pac_mandatory(true);
17549 MockAsyncProxyResolver resolver;
17550 session_deps_.proxy_service.reset(new ProxyService(
Jeremy Roman0579ed62017-08-29 15:56:1917551 std::make_unique<ProxyConfigServiceFixed>(proxy_config),
Bence Béky8f9d7d3952017-10-09 19:58:0417552 std::make_unique<FailingProxyResolverFactory>(), nullptr));
xunjieli96f2a402017-06-05 17:24:2717553
17554 HttpRequestInfo request;
17555 request.method = "GET";
17556 request.url = GURL("http://www.example.org/");
17557
17558 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
17559 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
17560
17561 TestCompletionCallback callback;
17562
17563 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
17564 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
17565 EXPECT_THAT(callback.WaitForResult(),
17566 IsError(ERR_MANDATORY_PROXY_CONFIGURATION_FAILED));
17567}
17568
17569TEST_F(HttpNetworkTransactionTest, ProxyResolutionFailsAsync) {
17570 ProxyConfig proxy_config;
17571 proxy_config.set_pac_url(GURL("http://fooproxyurl"));
17572 proxy_config.set_pac_mandatory(true);
17573 MockAsyncProxyResolverFactory* proxy_resolver_factory =
17574 new MockAsyncProxyResolverFactory(false);
17575 MockAsyncProxyResolver resolver;
17576 session_deps_.proxy_service.reset(
Jeremy Roman0579ed62017-08-29 15:56:1917577 new ProxyService(std::make_unique<ProxyConfigServiceFixed>(proxy_config),
xunjieli96f2a402017-06-05 17:24:2717578 base::WrapUnique(proxy_resolver_factory), nullptr));
17579 HttpRequestInfo request;
17580 request.method = "GET";
17581 request.url = GURL("http://www.example.org/");
17582
17583 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
17584 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
17585
17586 TestCompletionCallback callback;
17587 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
17588 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
17589
17590 proxy_resolver_factory->pending_requests()[0]->CompleteNowWithForwarder(
17591 ERR_FAILED, &resolver);
17592 EXPECT_THAT(callback.WaitForResult(),
17593 IsError(ERR_MANDATORY_PROXY_CONFIGURATION_FAILED));
17594}
17595
17596TEST_F(HttpNetworkTransactionTest, NoSupportedProxies) {
17597 session_deps_.proxy_service =
17598 ProxyService::CreateFixedFromPacResult("QUIC myproxy.org:443");
17599 session_deps_.enable_quic = false;
17600 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
17601
17602 HttpRequestInfo request;
17603 request.method = "GET";
17604 request.url = GURL("http://www.example.org/");
17605
17606 TestCompletionCallback callback;
17607 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
17608 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
17609 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
17610
17611 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_NO_SUPPORTED_PROXIES));
17612}
17613
[email protected]89ceba9a2009-03-21 03:46:0617614} // namespace net