blob: 95919a6d09b02ee503bbb98735a5307ca5f1ed98 [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;
572 ssl_.cert = ImportCertFromFile(GetTestCertsDirectory(), "spdy_pooling.pem");
573 ASSERT_TRUE(ssl_.cert);
574 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_);
575 }
576
[email protected]ff007e162009-05-23 09:13:15577 void ConnectStatusHelperWithExpectedStatus(const MockRead& status,
578 int expected_status);
initial.commit586acc5fe2008-07-26 22:42:52579
[email protected]ff007e162009-05-23 09:13:15580 void ConnectStatusHelper(const MockRead& status);
[email protected]bb88e1d32013-05-03 23:11:07581
582 void BypassHostCacheOnRefreshHelper(int load_flags);
583
584 void CheckErrorIsPassedBack(int error, IoMode mode);
585
[email protected]4bd46222013-05-14 19:32:23586 SpdyTestUtil spdy_util_;
[email protected]bb88e1d32013-05-03 23:11:07587 SpdySessionDependencies session_deps_;
bnc032658ba2016-09-26 18:17:15588 SSLSocketDataProvider ssl_;
[email protected]483fa202013-05-14 01:07:03589
590 // Original socket limits. Some tests set these. Safest to always restore
591 // them once each test has been run.
592 int old_max_group_sockets_;
593 int old_max_pool_sockets_;
[email protected]ff007e162009-05-23 09:13:15594};
[email protected]231d5a32008-09-13 00:45:27595
[email protected]448d4ca52012-03-04 04:12:23596namespace {
597
ryansturm49a8cb12016-06-15 16:51:09598class BeforeHeadersSentHandler {
[email protected]597a1ab2014-06-26 08:12:27599 public:
ryansturm49a8cb12016-06-15 16:51:09600 BeforeHeadersSentHandler()
601 : observed_before_headers_sent_with_proxy_(false),
602 observed_before_headers_sent_(false) {}
[email protected]597a1ab2014-06-26 08:12:27603
ryansturm49a8cb12016-06-15 16:51:09604 void OnBeforeHeadersSent(const ProxyInfo& proxy_info,
605 HttpRequestHeaders* request_headers) {
606 observed_before_headers_sent_ = true;
607 if (!proxy_info.is_http() && !proxy_info.is_https() &&
608 !proxy_info.is_quic()) {
609 return;
610 }
611 observed_before_headers_sent_with_proxy_ = true;
[email protected]597a1ab2014-06-26 08:12:27612 observed_proxy_server_uri_ = proxy_info.proxy_server().ToURI();
613 }
614
ryansturm49a8cb12016-06-15 16:51:09615 bool observed_before_headers_sent_with_proxy() const {
616 return observed_before_headers_sent_with_proxy_;
617 }
618
619 bool observed_before_headers_sent() const {
620 return observed_before_headers_sent_;
[email protected]597a1ab2014-06-26 08:12:27621 }
622
623 std::string observed_proxy_server_uri() const {
624 return observed_proxy_server_uri_;
625 }
626
627 private:
ryansturm49a8cb12016-06-15 16:51:09628 bool observed_before_headers_sent_with_proxy_;
629 bool observed_before_headers_sent_;
[email protected]597a1ab2014-06-26 08:12:27630 std::string observed_proxy_server_uri_;
631
ryansturm49a8cb12016-06-15 16:51:09632 DISALLOW_COPY_AND_ASSIGN(BeforeHeadersSentHandler);
[email protected]597a1ab2014-06-26 08:12:27633};
634
[email protected]15a5ccf82008-10-23 19:57:43635// Fill |str| with a long header list that consumes >= |size| bytes.
636void FillLargeHeadersString(std::string* str, int size) {
thestig9d3bb0c2015-01-24 00:49:51637 const char row[] =
[email protected]4ddaf2502008-10-23 18:26:19638 "SomeHeaderName: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx\r\n";
639 const int sizeof_row = strlen(row);
640 const int num_rows = static_cast<int>(
641 ceil(static_cast<float>(size) / sizeof_row));
642 const int sizeof_data = num_rows * sizeof_row;
643 DCHECK(sizeof_data >= size);
[email protected]15a5ccf82008-10-23 19:57:43644 str->reserve(sizeof_data);
[email protected]372d34a2008-11-05 21:30:51645
[email protected]4ddaf2502008-10-23 18:26:19646 for (int i = 0; i < num_rows; ++i)
[email protected]15a5ccf82008-10-23 19:57:43647 str->append(row, sizeof_row);
[email protected]4ddaf2502008-10-23 18:26:19648}
649
thakis84dff942015-07-28 20:47:38650#if defined(NTLM_PORTABLE)
Zentaro Kavanagh6ccee512017-09-28 18:34:09651uint64_t MockGetMSTime() {
652 // Tue, 23 May 2017 20:13:07 +0000
653 return 131400439870000000;
654}
655
[email protected]385a4672009-03-11 22:21:29656// Alternative functions that eliminate randomness and dependency on the local
657// host name so that the generated NTLM messages are reproducible.
Zentaro Kavanagh5b27a6e22017-09-25 23:00:37658void MockGenerateRandom(uint8_t* output, size_t n) {
659 // This is set to 0xaa because the client challenge for testing in
660 // [MS-NLMP] Section 4.2.1 is 8 bytes of 0xaa.
661 memset(output, 0xaa, n);
[email protected]385a4672009-03-11 22:21:29662}
663
[email protected]fe2bc6a2009-03-23 16:52:20664std::string MockGetHostName() {
Zentaro Kavanagh5b27a6e22017-09-25 23:00:37665 return ntlm::test::kHostnameAscii;
[email protected]385a4672009-03-11 22:21:29666}
thakis84dff942015-07-28 20:47:38667#endif // defined(NTLM_PORTABLE)
[email protected]385a4672009-03-11 22:21:29668
[email protected]e60e47a2010-07-14 03:37:18669template<typename ParentPool>
670class CaptureGroupNameSocketPool : public ParentPool {
[email protected]04e5be32009-06-26 20:00:31671 public:
[email protected]9e1bdd32011-02-03 21:48:34672 CaptureGroupNameSocketPool(HostResolver* host_resolver,
673 CertVerifier* cert_verifier);
[email protected]e60e47a2010-07-14 03:37:18674
[email protected]d80a4322009-08-14 07:07:49675 const std::string last_group_name_received() const {
676 return last_group_name_;
677 }
678
dmichaeld6e570d2014-12-18 22:30:57679 int RequestSocket(const std::string& group_name,
680 const void* socket_params,
681 RequestPriority priority,
mmenked3641e12016-01-28 16:06:15682 ClientSocketPool::RespectLimits respect_limits,
dmichaeld6e570d2014-12-18 22:30:57683 ClientSocketHandle* handle,
684 const CompletionCallback& callback,
tfarina42834112016-09-22 13:38:20685 const NetLogWithSource& net_log) override {
[email protected]04e5be32009-06-26 20:00:31686 last_group_name_ = group_name;
687 return ERR_IO_PENDING;
688 }
dmichaeld6e570d2014-12-18 22:30:57689 void CancelRequest(const std::string& group_name,
690 ClientSocketHandle* handle) override {}
691 void ReleaseSocket(const std::string& group_name,
danakj1fd259a02016-04-16 03:17:09692 std::unique_ptr<StreamSocket> socket,
dmichaeld6e570d2014-12-18 22:30:57693 int id) override {}
694 void CloseIdleSockets() override {}
xunjieli92feb332017-03-03 17:19:23695 void CloseIdleSocketsInGroup(const std::string& group_name) override {}
dmichaeld6e570d2014-12-18 22:30:57696 int IdleSocketCount() const override { return 0; }
697 int IdleSocketCountInGroup(const std::string& group_name) const override {
[email protected]04e5be32009-06-26 20:00:31698 return 0;
699 }
dmichaeld6e570d2014-12-18 22:30:57700 LoadState GetLoadState(const std::string& group_name,
701 const ClientSocketHandle* handle) const override {
[email protected]04e5be32009-06-26 20:00:31702 return LOAD_STATE_IDLE;
703 }
dmichaeld6e570d2014-12-18 22:30:57704 base::TimeDelta ConnectionTimeout() const override {
[email protected]a796bcec2010-03-22 17:17:26705 return base::TimeDelta();
706 }
[email protected]d80a4322009-08-14 07:07:49707
708 private:
[email protected]04e5be32009-06-26 20:00:31709 std::string last_group_name_;
710};
711
[email protected]ab739042011-04-07 15:22:28712typedef CaptureGroupNameSocketPool<TransportClientSocketPool>
713CaptureGroupNameTransportSocketPool;
[email protected]e772db3f2010-07-12 18:11:13714typedef CaptureGroupNameSocketPool<HttpProxyClientSocketPool>
715CaptureGroupNameHttpProxySocketPool;
[email protected]2d731a32010-04-29 01:04:06716typedef CaptureGroupNameSocketPool<SOCKSClientSocketPool>
[email protected]2227c692010-05-04 15:36:11717CaptureGroupNameSOCKSSocketPool;
[email protected]e60e47a2010-07-14 03:37:18718typedef CaptureGroupNameSocketPool<SSLClientSocketPool>
719CaptureGroupNameSSLSocketPool;
720
rkaplowd90695c2015-03-25 22:12:41721template <typename ParentPool>
[email protected]e60e47a2010-07-14 03:37:18722CaptureGroupNameSocketPool<ParentPool>::CaptureGroupNameSocketPool(
[email protected]9e1bdd32011-02-03 21:48:34723 HostResolver* host_resolver,
724 CertVerifier* /* cert_verifier */)
tbansal7b403bcc2016-04-13 22:33:21725 : ParentPool(0, 0, host_resolver, NULL, NULL, NULL) {}
[email protected]e60e47a2010-07-14 03:37:18726
hashimoto0d3e4fb2015-01-09 05:02:50727template <>
[email protected]2df19bb2010-08-25 20:13:46728CaptureGroupNameHttpProxySocketPool::CaptureGroupNameSocketPool(
hashimotodae13b02015-01-15 04:28:21729 HostResolver* /* host_resolver */,
[email protected]9e1bdd32011-02-03 21:48:34730 CertVerifier* /* cert_verifier */)
tbansal16196a1e2017-06-09 01:50:09731 : HttpProxyClientSocketPool(0, 0, NULL, NULL, NULL, NULL) {}
[email protected]2df19bb2010-08-25 20:13:46732
[email protected]007b3f82013-04-09 08:46:45733template <>
[email protected]e60e47a2010-07-14 03:37:18734CaptureGroupNameSSLSocketPool::CaptureGroupNameSocketPool(
hashimotodae13b02015-01-15 04:28:21735 HostResolver* /* host_resolver */,
[email protected]9e1bdd32011-02-03 21:48:34736 CertVerifier* cert_verifier)
[email protected]007b3f82013-04-09 08:46:45737 : SSLClientSocketPool(0,
738 0,
[email protected]007b3f82013-04-09 08:46:45739 cert_verifier,
740 NULL,
741 NULL,
[email protected]284303b62013-11-28 15:11:54742 NULL,
eranm6571b2b2014-12-03 15:53:23743 NULL,
[email protected]007b3f82013-04-09 08:46:45744 std::string(),
745 NULL,
746 NULL,
747 NULL,
748 NULL,
749 NULL,
[email protected]8e458552014-08-05 00:02:15750 NULL) {
751}
[email protected]2227c692010-05-04 15:36:11752
[email protected]231d5a32008-09-13 00:45:27753//-----------------------------------------------------------------------------
754
[email protected]79cb5c12011-09-12 13:12:04755// Helper functions for validating that AuthChallengeInfo's are correctly
756// configured for common cases.
757bool CheckBasicServerAuth(const AuthChallengeInfo* auth_challenge) {
758 if (!auth_challenge)
759 return false;
760 EXPECT_FALSE(auth_challenge->is_proxy);
asanka098c0092016-06-16 20:18:43761 EXPECT_EQ("http://www.example.org", auth_challenge->challenger.Serialize());
[email protected]79cb5c12011-09-12 13:12:04762 EXPECT_EQ("MyRealm1", auth_challenge->realm);
aberentbba302d2015-12-03 10:20:19763 EXPECT_EQ(kBasicAuthScheme, auth_challenge->scheme);
[email protected]79cb5c12011-09-12 13:12:04764 return true;
765}
766
767bool CheckBasicProxyAuth(const AuthChallengeInfo* auth_challenge) {
768 if (!auth_challenge)
769 return false;
770 EXPECT_TRUE(auth_challenge->is_proxy);
asanka098c0092016-06-16 20:18:43771 EXPECT_EQ("http://myproxy:70", auth_challenge->challenger.Serialize());
772 EXPECT_EQ("MyRealm1", auth_challenge->realm);
773 EXPECT_EQ(kBasicAuthScheme, auth_challenge->scheme);
774 return true;
775}
776
777bool CheckBasicSecureProxyAuth(const AuthChallengeInfo* auth_challenge) {
778 if (!auth_challenge)
779 return false;
780 EXPECT_TRUE(auth_challenge->is_proxy);
781 EXPECT_EQ("https://myproxy:70", auth_challenge->challenger.Serialize());
[email protected]79cb5c12011-09-12 13:12:04782 EXPECT_EQ("MyRealm1", auth_challenge->realm);
aberentbba302d2015-12-03 10:20:19783 EXPECT_EQ(kBasicAuthScheme, auth_challenge->scheme);
[email protected]79cb5c12011-09-12 13:12:04784 return true;
785}
786
787bool CheckDigestServerAuth(const AuthChallengeInfo* auth_challenge) {
788 if (!auth_challenge)
789 return false;
790 EXPECT_FALSE(auth_challenge->is_proxy);
asanka098c0092016-06-16 20:18:43791 EXPECT_EQ("http://www.example.org", auth_challenge->challenger.Serialize());
[email protected]79cb5c12011-09-12 13:12:04792 EXPECT_EQ("digestive", auth_challenge->realm);
aberentbba302d2015-12-03 10:20:19793 EXPECT_EQ(kDigestAuthScheme, auth_challenge->scheme);
[email protected]79cb5c12011-09-12 13:12:04794 return true;
795}
796
thakis84dff942015-07-28 20:47:38797#if defined(NTLM_PORTABLE)
[email protected]79cb5c12011-09-12 13:12:04798bool CheckNTLMServerAuth(const AuthChallengeInfo* auth_challenge) {
799 if (!auth_challenge)
800 return false;
801 EXPECT_FALSE(auth_challenge->is_proxy);
Bence Béky83eb3512017-09-05 12:56:09802 EXPECT_EQ("https://172.22.68.17", auth_challenge->challenger.Serialize());
[email protected]79cb5c12011-09-12 13:12:04803 EXPECT_EQ(std::string(), auth_challenge->realm);
aberentbba302d2015-12-03 10:20:19804 EXPECT_EQ(kNtlmAuthScheme, auth_challenge->scheme);
[email protected]79cb5c12011-09-12 13:12:04805 return true;
806}
thakis84dff942015-07-28 20:47:38807#endif // defined(NTLM_PORTABLE)
[email protected]79cb5c12011-09-12 13:12:04808
[email protected]448d4ca52012-03-04 04:12:23809} // namespace
810
bncd16676a2016-07-20 16:23:01811TEST_F(HttpNetworkTransactionTest, Basic) {
danakj1fd259a02016-04-16 03:17:09812 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:16813 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]231d5a32008-09-13 00:45:27814}
815
bncd16676a2016-07-20 16:23:01816TEST_F(HttpNetworkTransactionTest, SimpleGET) {
[email protected]231d5a32008-09-13 00:45:27817 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:35818 MockRead("HTTP/1.0 200 OK\r\n\r\n"),
819 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:06820 MockRead(SYNCHRONOUS, OK),
[email protected]231d5a32008-09-13 00:45:27821 };
[email protected]31a2bfe2010-02-09 08:03:39822 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
823 arraysize(data_reads));
robpercival214763f2016-07-01 23:27:01824 EXPECT_THAT(out.rv, IsOk());
[email protected]231d5a32008-09-13 00:45:27825 EXPECT_EQ("HTTP/1.0 200 OK", out.status_line);
826 EXPECT_EQ("hello world", out.response_data);
sclittlefb249892015-09-10 21:33:22827 int64_t reads_size = CountReadBytes(data_reads, arraysize(data_reads));
828 EXPECT_EQ(reads_size, out.total_received_bytes);
ttuttle1f2d7e92015-04-28 16:17:47829 EXPECT_EQ(0u, out.connection_attempts.size());
ttuttled9dbc652015-09-29 20:00:59830
831 EXPECT_FALSE(out.remote_endpoint_after_start.address().empty());
[email protected]231d5a32008-09-13 00:45:27832}
833
834// Response with no status line.
bncd16676a2016-07-20 16:23:01835TEST_F(HttpNetworkTransactionTest, SimpleGETNoHeaders) {
[email protected]231d5a32008-09-13 00:45:27836 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:35837 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:06838 MockRead(SYNCHRONOUS, OK),
[email protected]231d5a32008-09-13 00:45:27839 };
[email protected]31a2bfe2010-02-09 08:03:39840 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
841 arraysize(data_reads));
mmenkea2dcd3bf2016-08-16 21:49:41842 EXPECT_THAT(out.rv, IsOk());
843 EXPECT_EQ("HTTP/0.9 200 OK", out.status_line);
844 EXPECT_EQ("hello world", out.response_data);
845 int64_t reads_size = CountReadBytes(data_reads, arraysize(data_reads));
846 EXPECT_EQ(reads_size, out.total_received_bytes);
[email protected]231d5a32008-09-13 00:45:27847}
848
mmenkea7da6da2016-09-01 21:56:52849// Response with no status line, and a weird port. Should fail by default.
850TEST_F(HttpNetworkTransactionTest, SimpleGETNoHeadersWeirdPort) {
851 MockRead data_reads[] = {
852 MockRead("hello world"), MockRead(SYNCHRONOUS, OK),
853 };
854
855 StaticSocketDataProvider data(data_reads, arraysize(data_reads), nullptr, 0);
856 session_deps_.socket_factory->AddSocketDataProvider(&data);
857
858 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
859
krasinc06a72a2016-12-21 03:42:46860 HttpRequestInfo request;
bnc87dcefc2017-05-25 12:47:58861 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:19862 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
mmenkea7da6da2016-09-01 21:56:52863
mmenkea7da6da2016-09-01 21:56:52864 request.method = "GET";
865 request.url = GURL("http://www.example.com:2000/");
866 TestCompletionCallback callback;
tfarina42834112016-09-22 13:38:20867 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
mmenkea7da6da2016-09-01 21:56:52868 EXPECT_THAT(callback.GetResult(rv), IsError(ERR_INVALID_HTTP_RESPONSE));
869}
870
871// Response with no status line, and a weird port. Option to allow weird ports
872// enabled.
873TEST_F(HttpNetworkTransactionTest, SimpleGETNoHeadersWeirdPortAllowed) {
874 MockRead data_reads[] = {
875 MockRead("hello world"), MockRead(SYNCHRONOUS, OK),
876 };
877
878 StaticSocketDataProvider data(data_reads, arraysize(data_reads), nullptr, 0);
879 session_deps_.socket_factory->AddSocketDataProvider(&data);
880 session_deps_.http_09_on_non_default_ports_enabled = true;
881 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
882
krasinc06a72a2016-12-21 03:42:46883 HttpRequestInfo request;
bnc87dcefc2017-05-25 12:47:58884 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:19885 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
mmenkea7da6da2016-09-01 21:56:52886
mmenkea7da6da2016-09-01 21:56:52887 request.method = "GET";
888 request.url = GURL("http://www.example.com:2000/");
889 TestCompletionCallback callback;
tfarina42834112016-09-22 13:38:20890 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
mmenkea7da6da2016-09-01 21:56:52891 EXPECT_THAT(callback.GetResult(rv), IsOk());
892
893 const HttpResponseInfo* info = trans->GetResponseInfo();
894 ASSERT_TRUE(info->headers);
895 EXPECT_EQ("HTTP/0.9 200 OK", info->headers->GetStatusLine());
896
897 // Don't bother to read the body - that's verified elsewhere, important thing
898 // is that the option to allow HTTP/0.9 on non-default ports is respected.
899}
900
[email protected]231d5a32008-09-13 00:45:27901// Allow up to 4 bytes of junk to precede status line.
bncd16676a2016-07-20 16:23:01902TEST_F(HttpNetworkTransactionTest, StatusLineJunk3Bytes) {
[email protected]231d5a32008-09-13 00:45:27903 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:35904 MockRead("xxxHTTP/1.0 404 Not Found\nServer: blah\n\nDATA"),
[email protected]8ddf8322012-02-23 18:08:06905 MockRead(SYNCHRONOUS, OK),
[email protected]231d5a32008-09-13 00:45:27906 };
[email protected]31a2bfe2010-02-09 08:03:39907 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
908 arraysize(data_reads));
robpercival214763f2016-07-01 23:27:01909 EXPECT_THAT(out.rv, IsOk());
[email protected]231d5a32008-09-13 00:45:27910 EXPECT_EQ("HTTP/1.0 404 Not Found", out.status_line);
911 EXPECT_EQ("DATA", out.response_data);
sclittlefb249892015-09-10 21:33:22912 int64_t reads_size = CountReadBytes(data_reads, arraysize(data_reads));
913 EXPECT_EQ(reads_size, out.total_received_bytes);
[email protected]231d5a32008-09-13 00:45:27914}
915
916// Allow up to 4 bytes of junk to precede status line.
bncd16676a2016-07-20 16:23:01917TEST_F(HttpNetworkTransactionTest, StatusLineJunk4Bytes) {
[email protected]231d5a32008-09-13 00:45:27918 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:35919 MockRead("\n\nQJHTTP/1.0 404 Not Found\nServer: blah\n\nDATA"),
[email protected]8ddf8322012-02-23 18:08:06920 MockRead(SYNCHRONOUS, OK),
[email protected]231d5a32008-09-13 00:45:27921 };
[email protected]31a2bfe2010-02-09 08:03:39922 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
923 arraysize(data_reads));
robpercival214763f2016-07-01 23:27:01924 EXPECT_THAT(out.rv, IsOk());
[email protected]231d5a32008-09-13 00:45:27925 EXPECT_EQ("HTTP/1.0 404 Not Found", out.status_line);
926 EXPECT_EQ("DATA", out.response_data);
sclittlefb249892015-09-10 21:33:22927 int64_t reads_size = CountReadBytes(data_reads, arraysize(data_reads));
928 EXPECT_EQ(reads_size, out.total_received_bytes);
[email protected]231d5a32008-09-13 00:45:27929}
930
931// Beyond 4 bytes of slop and it should fail to find a status line.
bncd16676a2016-07-20 16:23:01932TEST_F(HttpNetworkTransactionTest, StatusLineJunk5Bytes) {
[email protected]231d5a32008-09-13 00:45:27933 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:35934 MockRead("xxxxxHTTP/1.1 404 Not Found\nServer: blah"),
[email protected]8ddf8322012-02-23 18:08:06935 MockRead(SYNCHRONOUS, OK),
[email protected]231d5a32008-09-13 00:45:27936 };
[email protected]31a2bfe2010-02-09 08:03:39937 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
938 arraysize(data_reads));
mmenkea2dcd3bf2016-08-16 21:49:41939 EXPECT_THAT(out.rv, IsOk());
940 EXPECT_EQ("HTTP/0.9 200 OK", out.status_line);
941 EXPECT_EQ("xxxxxHTTP/1.1 404 Not Found\nServer: blah", out.response_data);
942 int64_t reads_size = CountReadBytes(data_reads, arraysize(data_reads));
943 EXPECT_EQ(reads_size, out.total_received_bytes);
[email protected]231d5a32008-09-13 00:45:27944}
945
946// Same as StatusLineJunk4Bytes, except the read chunks are smaller.
bncd16676a2016-07-20 16:23:01947TEST_F(HttpNetworkTransactionTest, StatusLineJunk4Bytes_Slow) {
[email protected]231d5a32008-09-13 00:45:27948 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:35949 MockRead("\n"),
950 MockRead("\n"),
951 MockRead("Q"),
952 MockRead("J"),
953 MockRead("HTTP/1.0 404 Not Found\nServer: blah\n\nDATA"),
[email protected]8ddf8322012-02-23 18:08:06954 MockRead(SYNCHRONOUS, OK),
[email protected]231d5a32008-09-13 00:45:27955 };
[email protected]31a2bfe2010-02-09 08:03:39956 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
957 arraysize(data_reads));
robpercival214763f2016-07-01 23:27:01958 EXPECT_THAT(out.rv, IsOk());
[email protected]231d5a32008-09-13 00:45:27959 EXPECT_EQ("HTTP/1.0 404 Not Found", out.status_line);
960 EXPECT_EQ("DATA", out.response_data);
sclittlefb249892015-09-10 21:33:22961 int64_t reads_size = CountReadBytes(data_reads, arraysize(data_reads));
962 EXPECT_EQ(reads_size, out.total_received_bytes);
[email protected]231d5a32008-09-13 00:45:27963}
964
965// Close the connection before enough bytes to have a status line.
bncd16676a2016-07-20 16:23:01966TEST_F(HttpNetworkTransactionTest, StatusLinePartial) {
[email protected]231d5a32008-09-13 00:45:27967 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:35968 MockRead("HTT"),
[email protected]8ddf8322012-02-23 18:08:06969 MockRead(SYNCHRONOUS, OK),
[email protected]231d5a32008-09-13 00:45:27970 };
[email protected]31a2bfe2010-02-09 08:03:39971 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
972 arraysize(data_reads));
mmenkea2dcd3bf2016-08-16 21:49:41973 EXPECT_THAT(out.rv, IsOk());
974 EXPECT_EQ("HTTP/0.9 200 OK", out.status_line);
975 EXPECT_EQ("HTT", out.response_data);
976 int64_t reads_size = CountReadBytes(data_reads, arraysize(data_reads));
977 EXPECT_EQ(reads_size, out.total_received_bytes);
initial.commit586acc5fe2008-07-26 22:42:52978}
979
[email protected]f9d44aa2008-09-23 23:57:17980// Simulate a 204 response, lacking a Content-Length header, sent over a
981// persistent connection. The response should still terminate since a 204
982// cannot have a response body.
bncd16676a2016-07-20 16:23:01983TEST_F(HttpNetworkTransactionTest, StopsReading204) {
[email protected]b8015c42013-12-24 15:18:19984 char junk[] = "junk";
[email protected]f9d44aa2008-09-23 23:57:17985 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:35986 MockRead("HTTP/1.1 204 No Content\r\n\r\n"),
[email protected]b8015c42013-12-24 15:18:19987 MockRead(junk), // Should not be read!!
[email protected]8ddf8322012-02-23 18:08:06988 MockRead(SYNCHRONOUS, OK),
[email protected]f9d44aa2008-09-23 23:57:17989 };
[email protected]31a2bfe2010-02-09 08:03:39990 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
991 arraysize(data_reads));
robpercival214763f2016-07-01 23:27:01992 EXPECT_THAT(out.rv, IsOk());
[email protected]f9d44aa2008-09-23 23:57:17993 EXPECT_EQ("HTTP/1.1 204 No Content", out.status_line);
994 EXPECT_EQ("", out.response_data);
sclittlefb249892015-09-10 21:33:22995 int64_t reads_size = CountReadBytes(data_reads, arraysize(data_reads));
996 int64_t response_size = reads_size - strlen(junk);
997 EXPECT_EQ(response_size, out.total_received_bytes);
[email protected]f9d44aa2008-09-23 23:57:17998}
999
[email protected]0877e3d2009-10-17 22:29:571000// A simple request using chunked encoding with some extra data after.
bncd16676a2016-07-20 16:23:011001TEST_F(HttpNetworkTransactionTest, ChunkedEncoding) {
[email protected]b8015c42013-12-24 15:18:191002 std::string final_chunk = "0\r\n\r\n";
1003 std::string extra_data = "HTTP/1.1 200 OK\r\n";
1004 std::string last_read = final_chunk + extra_data;
[email protected]0877e3d2009-10-17 22:29:571005 MockRead data_reads[] = {
1006 MockRead("HTTP/1.1 200 OK\r\nTransfer-Encoding: chunked\r\n\r\n"),
1007 MockRead("5\r\nHello\r\n"),
1008 MockRead("1\r\n"),
1009 MockRead(" \r\n"),
1010 MockRead("5\r\nworld\r\n"),
[email protected]b8015c42013-12-24 15:18:191011 MockRead(last_read.data()),
[email protected]8ddf8322012-02-23 18:08:061012 MockRead(SYNCHRONOUS, OK),
[email protected]0877e3d2009-10-17 22:29:571013 };
[email protected]31a2bfe2010-02-09 08:03:391014 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
1015 arraysize(data_reads));
robpercival214763f2016-07-01 23:27:011016 EXPECT_THAT(out.rv, IsOk());
[email protected]0877e3d2009-10-17 22:29:571017 EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
1018 EXPECT_EQ("Hello world", out.response_data);
sclittlefb249892015-09-10 21:33:221019 int64_t reads_size = CountReadBytes(data_reads, arraysize(data_reads));
1020 int64_t response_size = reads_size - extra_data.size();
1021 EXPECT_EQ(response_size, out.total_received_bytes);
[email protected]0877e3d2009-10-17 22:29:571022}
1023
[email protected]9fe44f52010-09-23 18:36:001024// Next tests deal with http://crbug.com/56344.
1025
bncd16676a2016-07-20 16:23:011026TEST_F(HttpNetworkTransactionTest,
[email protected]9fe44f52010-09-23 18:36:001027 MultipleContentLengthHeadersNoTransferEncoding) {
1028 MockRead data_reads[] = {
1029 MockRead("HTTP/1.1 200 OK\r\n"),
1030 MockRead("Content-Length: 10\r\n"),
1031 MockRead("Content-Length: 5\r\n\r\n"),
1032 };
1033 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
1034 arraysize(data_reads));
robpercival214763f2016-07-01 23:27:011035 EXPECT_THAT(out.rv, IsError(ERR_RESPONSE_HEADERS_MULTIPLE_CONTENT_LENGTH));
[email protected]9fe44f52010-09-23 18:36:001036}
1037
bncd16676a2016-07-20 16:23:011038TEST_F(HttpNetworkTransactionTest,
[email protected]44b52042010-10-29 22:48:041039 DuplicateContentLengthHeadersNoTransferEncoding) {
1040 MockRead data_reads[] = {
1041 MockRead("HTTP/1.1 200 OK\r\n"),
1042 MockRead("Content-Length: 5\r\n"),
1043 MockRead("Content-Length: 5\r\n\r\n"),
1044 MockRead("Hello"),
1045 };
1046 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
1047 arraysize(data_reads));
robpercival214763f2016-07-01 23:27:011048 EXPECT_THAT(out.rv, IsOk());
[email protected]44b52042010-10-29 22:48:041049 EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
1050 EXPECT_EQ("Hello", out.response_data);
1051}
1052
bncd16676a2016-07-20 16:23:011053TEST_F(HttpNetworkTransactionTest,
[email protected]44b52042010-10-29 22:48:041054 ComplexContentLengthHeadersNoTransferEncoding) {
1055 // More than 2 dupes.
1056 {
1057 MockRead data_reads[] = {
1058 MockRead("HTTP/1.1 200 OK\r\n"),
1059 MockRead("Content-Length: 5\r\n"),
1060 MockRead("Content-Length: 5\r\n"),
1061 MockRead("Content-Length: 5\r\n\r\n"),
1062 MockRead("Hello"),
1063 };
1064 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
1065 arraysize(data_reads));
robpercival214763f2016-07-01 23:27:011066 EXPECT_THAT(out.rv, IsOk());
[email protected]44b52042010-10-29 22:48:041067 EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
1068 EXPECT_EQ("Hello", out.response_data);
1069 }
1070 // HTTP/1.0
1071 {
1072 MockRead data_reads[] = {
1073 MockRead("HTTP/1.0 200 OK\r\n"),
1074 MockRead("Content-Length: 5\r\n"),
1075 MockRead("Content-Length: 5\r\n"),
1076 MockRead("Content-Length: 5\r\n\r\n"),
1077 MockRead("Hello"),
1078 };
1079 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
1080 arraysize(data_reads));
robpercival214763f2016-07-01 23:27:011081 EXPECT_THAT(out.rv, IsOk());
[email protected]44b52042010-10-29 22:48:041082 EXPECT_EQ("HTTP/1.0 200 OK", out.status_line);
1083 EXPECT_EQ("Hello", out.response_data);
1084 }
1085 // 2 dupes and one mismatched.
1086 {
1087 MockRead data_reads[] = {
1088 MockRead("HTTP/1.1 200 OK\r\n"),
1089 MockRead("Content-Length: 10\r\n"),
1090 MockRead("Content-Length: 10\r\n"),
1091 MockRead("Content-Length: 5\r\n\r\n"),
1092 };
1093 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
1094 arraysize(data_reads));
robpercival214763f2016-07-01 23:27:011095 EXPECT_THAT(out.rv, IsError(ERR_RESPONSE_HEADERS_MULTIPLE_CONTENT_LENGTH));
[email protected]44b52042010-10-29 22:48:041096 }
1097}
1098
bncd16676a2016-07-20 16:23:011099TEST_F(HttpNetworkTransactionTest,
[email protected]9fe44f52010-09-23 18:36:001100 MultipleContentLengthHeadersTransferEncoding) {
1101 MockRead data_reads[] = {
1102 MockRead("HTTP/1.1 200 OK\r\n"),
1103 MockRead("Content-Length: 666\r\n"),
1104 MockRead("Content-Length: 1337\r\n"),
1105 MockRead("Transfer-Encoding: chunked\r\n\r\n"),
1106 MockRead("5\r\nHello\r\n"),
1107 MockRead("1\r\n"),
1108 MockRead(" \r\n"),
1109 MockRead("5\r\nworld\r\n"),
1110 MockRead("0\r\n\r\nHTTP/1.1 200 OK\r\n"),
[email protected]8ddf8322012-02-23 18:08:061111 MockRead(SYNCHRONOUS, OK),
[email protected]9fe44f52010-09-23 18:36:001112 };
1113 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
1114 arraysize(data_reads));
robpercival214763f2016-07-01 23:27:011115 EXPECT_THAT(out.rv, IsOk());
[email protected]9fe44f52010-09-23 18:36:001116 EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
1117 EXPECT_EQ("Hello world", out.response_data);
1118}
1119
[email protected]1628fe92011-10-04 23:04:551120// Next tests deal with http://crbug.com/98895.
1121
1122// Checks that a single Content-Disposition header results in no error.
bncd16676a2016-07-20 16:23:011123TEST_F(HttpNetworkTransactionTest, SingleContentDispositionHeader) {
[email protected]1628fe92011-10-04 23:04:551124 MockRead data_reads[] = {
1125 MockRead("HTTP/1.1 200 OK\r\n"),
1126 MockRead("Content-Disposition: attachment;filename=\"salutations.txt\"r\n"),
1127 MockRead("Content-Length: 5\r\n\r\n"),
1128 MockRead("Hello"),
1129 };
1130 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
1131 arraysize(data_reads));
robpercival214763f2016-07-01 23:27:011132 EXPECT_THAT(out.rv, IsOk());
[email protected]1628fe92011-10-04 23:04:551133 EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
1134 EXPECT_EQ("Hello", out.response_data);
1135}
1136
[email protected]54a9c6e52012-03-21 20:10:591137// Checks that two identical Content-Disposition headers result in no error.
bncd16676a2016-07-20 16:23:011138TEST_F(HttpNetworkTransactionTest, TwoIdenticalContentDispositionHeaders) {
[email protected]1628fe92011-10-04 23:04:551139 MockRead data_reads[] = {
1140 MockRead("HTTP/1.1 200 OK\r\n"),
1141 MockRead("Content-Disposition: attachment;filename=\"greetings.txt\"r\n"),
1142 MockRead("Content-Disposition: attachment;filename=\"greetings.txt\"r\n"),
1143 MockRead("Content-Length: 5\r\n\r\n"),
1144 MockRead("Hello"),
1145 };
1146 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
1147 arraysize(data_reads));
robpercival214763f2016-07-01 23:27:011148 EXPECT_THAT(out.rv, IsOk());
[email protected]54a9c6e52012-03-21 20:10:591149 EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
1150 EXPECT_EQ("Hello", out.response_data);
[email protected]1628fe92011-10-04 23:04:551151}
1152
1153// Checks that two distinct Content-Disposition headers result in an error.
bncd16676a2016-07-20 16:23:011154TEST_F(HttpNetworkTransactionTest, TwoDistinctContentDispositionHeaders) {
[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=\"greetings.txt\"r\n"),
1158 MockRead("Content-Disposition: attachment;filename=\"hi.txt\"r\n"),
1159 MockRead("Content-Length: 5\r\n\r\n"),
1160 MockRead("Hello"),
1161 };
1162 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
1163 arraysize(data_reads));
robpercival214763f2016-07-01 23:27:011164 EXPECT_THAT(out.rv,
1165 IsError(ERR_RESPONSE_HEADERS_MULTIPLE_CONTENT_DISPOSITION));
[email protected]1628fe92011-10-04 23:04:551166}
1167
[email protected]54a9c6e52012-03-21 20:10:591168// Checks that two identical Location headers result in no error.
1169// Also tests Location header behavior.
bncd16676a2016-07-20 16:23:011170TEST_F(HttpNetworkTransactionTest, TwoIdenticalLocationHeaders) {
[email protected]1628fe92011-10-04 23:04:551171 MockRead data_reads[] = {
1172 MockRead("HTTP/1.1 302 Redirect\r\n"),
1173 MockRead("Location: http://good.com/\r\n"),
[email protected]54a9c6e52012-03-21 20:10:591174 MockRead("Location: http://good.com/\r\n"),
[email protected]1628fe92011-10-04 23:04:551175 MockRead("Content-Length: 0\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:061176 MockRead(SYNCHRONOUS, OK),
[email protected]1628fe92011-10-04 23:04:551177 };
1178
1179 HttpRequestInfo request;
1180 request.method = "GET";
1181 request.url = GURL("http://redirect.com/");
[email protected]1628fe92011-10-04 23:04:551182
danakj1fd259a02016-04-16 03:17:091183 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:161184 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]1628fe92011-10-04 23:04:551185
1186 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:071187 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1628fe92011-10-04 23:04:551188
[email protected]49639fa2011-12-20 23:22:411189 TestCompletionCallback callback;
[email protected]1628fe92011-10-04 23:04:551190
tfarina42834112016-09-22 13:38:201191 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:011192 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]1628fe92011-10-04 23:04:551193
robpercival214763f2016-07-01 23:27:011194 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]1628fe92011-10-04 23:04:551195
bnc691fda62016-08-12 00:43:161196 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:521197 ASSERT_TRUE(response);
1198 ASSERT_TRUE(response->headers);
[email protected]1628fe92011-10-04 23:04:551199 EXPECT_EQ("HTTP/1.1 302 Redirect", response->headers->GetStatusLine());
1200 std::string url;
1201 EXPECT_TRUE(response->headers->IsRedirect(&url));
1202 EXPECT_EQ("http://good.com/", url);
tbansal2ecbbc72016-10-06 17:15:471203 EXPECT_TRUE(response->proxy_server.is_direct());
[email protected]1628fe92011-10-04 23:04:551204}
1205
[email protected]1628fe92011-10-04 23:04:551206// Checks that two distinct Location headers result in an error.
bncd16676a2016-07-20 16:23:011207TEST_F(HttpNetworkTransactionTest, TwoDistinctLocationHeaders) {
[email protected]1628fe92011-10-04 23:04:551208 MockRead data_reads[] = {
1209 MockRead("HTTP/1.1 302 Redirect\r\n"),
1210 MockRead("Location: http://good.com/\r\n"),
1211 MockRead("Location: http://evil.com/\r\n"),
1212 MockRead("Content-Length: 0\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:061213 MockRead(SYNCHRONOUS, OK),
[email protected]1628fe92011-10-04 23:04:551214 };
1215 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
1216 arraysize(data_reads));
robpercival214763f2016-07-01 23:27:011217 EXPECT_THAT(out.rv, IsError(ERR_RESPONSE_HEADERS_MULTIPLE_LOCATION));
[email protected]1628fe92011-10-04 23:04:551218}
1219
[email protected]ef0faf2e72009-03-05 23:27:231220// Do a request using the HEAD method. Verify that we don't try to read the
1221// message body (since HEAD has none).
bncd16676a2016-07-20 16:23:011222TEST_F(HttpNetworkTransactionTest, Head) {
[email protected]1c773ea12009-04-28 19:58:421223 HttpRequestInfo request;
[email protected]ef0faf2e72009-03-05 23:27:231224 request.method = "HEAD";
bncce36dca22015-04-21 22:11:231225 request.url = GURL("http://www.example.org/");
[email protected]ef0faf2e72009-03-05 23:27:231226
danakj1fd259a02016-04-16 03:17:091227 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:161228 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
ryansturm49a8cb12016-06-15 16:51:091229 BeforeHeadersSentHandler headers_handler;
bnc691fda62016-08-12 00:43:161230 trans.SetBeforeHeadersSentCallback(
ryansturm49a8cb12016-06-15 16:51:091231 base::Bind(&BeforeHeadersSentHandler::OnBeforeHeadersSent,
1232 base::Unretained(&headers_handler)));
[email protected]cb9bf6ca2011-01-28 13:15:271233
[email protected]ef0faf2e72009-03-05 23:27:231234 MockWrite data_writes1[] = {
csharrisonf473dd192015-08-18 13:54:131235 MockWrite("HEAD / HTTP/1.1\r\n"
1236 "Host: www.example.org\r\n"
1237 "Connection: keep-alive\r\n\r\n"),
[email protected]ef0faf2e72009-03-05 23:27:231238 };
1239 MockRead data_reads1[] = {
mmenked39192ee2015-12-09 00:57:231240 MockRead("HTTP/1.1 404 Not Found\r\n"), MockRead("Server: Blah\r\n"),
1241 MockRead("Content-Length: 1234\r\n\r\n"),
[email protected]ef0faf2e72009-03-05 23:27:231242
mmenked39192ee2015-12-09 00:57:231243 // No response body because the test stops reading here.
1244 MockRead(SYNCHRONOUS, ERR_UNEXPECTED),
[email protected]ef0faf2e72009-03-05 23:27:231245 };
1246
[email protected]31a2bfe2010-02-09 08:03:391247 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
1248 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:071249 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]ef0faf2e72009-03-05 23:27:231250
[email protected]49639fa2011-12-20 23:22:411251 TestCompletionCallback callback1;
[email protected]ef0faf2e72009-03-05 23:27:231252
tfarina42834112016-09-22 13:38:201253 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:011254 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]ef0faf2e72009-03-05 23:27:231255
1256 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:011257 EXPECT_THAT(rv, IsOk());
[email protected]ef0faf2e72009-03-05 23:27:231258
bnc691fda62016-08-12 00:43:161259 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:521260 ASSERT_TRUE(response);
[email protected]ef0faf2e72009-03-05 23:27:231261
1262 // Check that the headers got parsed.
wezca1070932016-05-26 20:30:521263 EXPECT_TRUE(response->headers);
[email protected]ef0faf2e72009-03-05 23:27:231264 EXPECT_EQ(1234, response->headers->GetContentLength());
1265 EXPECT_EQ("HTTP/1.1 404 Not Found", response->headers->GetStatusLine());
tbansal2ecbbc72016-10-06 17:15:471266 EXPECT_TRUE(response->proxy_server.is_direct());
ryansturm49a8cb12016-06-15 16:51:091267 EXPECT_TRUE(headers_handler.observed_before_headers_sent());
1268 EXPECT_FALSE(headers_handler.observed_before_headers_sent_with_proxy());
[email protected]ef0faf2e72009-03-05 23:27:231269
1270 std::string server_header;
olli.raulaee489a52016-01-25 08:37:101271 size_t iter = 0;
[email protected]ef0faf2e72009-03-05 23:27:231272 bool has_server_header = response->headers->EnumerateHeader(
1273 &iter, "Server", &server_header);
1274 EXPECT_TRUE(has_server_header);
1275 EXPECT_EQ("Blah", server_header);
1276
1277 // Reading should give EOF right away, since there is no message body
1278 // (despite non-zero content-length).
1279 std::string response_data;
bnc691fda62016-08-12 00:43:161280 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:011281 EXPECT_THAT(rv, IsOk());
[email protected]ef0faf2e72009-03-05 23:27:231282 EXPECT_EQ("", response_data);
1283}
1284
bncd16676a2016-07-20 16:23:011285TEST_F(HttpNetworkTransactionTest, ReuseConnection) {
danakj1fd259a02016-04-16 03:17:091286 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
initial.commit586acc5fe2008-07-26 22:42:521287
1288 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:351289 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
1290 MockRead("hello"),
1291 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
1292 MockRead("world"),
[email protected]8ddf8322012-02-23 18:08:061293 MockRead(SYNCHRONOUS, OK),
initial.commit586acc5fe2008-07-26 22:42:521294 };
[email protected]31a2bfe2010-02-09 08:03:391295 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:071296 session_deps_.socket_factory->AddSocketDataProvider(&data);
initial.commit586acc5fe2008-07-26 22:42:521297
[email protected]0b0bf032010-09-21 18:08:501298 const char* const kExpectedResponseData[] = {
initial.commit586acc5fe2008-07-26 22:42:521299 "hello", "world"
1300 };
1301
1302 for (int i = 0; i < 2; ++i) {
[email protected]1c773ea12009-04-28 19:58:421303 HttpRequestInfo request;
initial.commit586acc5fe2008-07-26 22:42:521304 request.method = "GET";
bncce36dca22015-04-21 22:11:231305 request.url = GURL("http://www.example.org/");
initial.commit586acc5fe2008-07-26 22:42:521306
bnc691fda62016-08-12 00:43:161307 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:271308
[email protected]49639fa2011-12-20 23:22:411309 TestCompletionCallback callback;
initial.commit586acc5fe2008-07-26 22:42:521310
tfarina42834112016-09-22 13:38:201311 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:011312 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
initial.commit586acc5fe2008-07-26 22:42:521313
1314 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:011315 EXPECT_THAT(rv, IsOk());
initial.commit586acc5fe2008-07-26 22:42:521316
bnc691fda62016-08-12 00:43:161317 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:521318 ASSERT_TRUE(response);
initial.commit586acc5fe2008-07-26 22:42:521319
wezca1070932016-05-26 20:30:521320 EXPECT_TRUE(response->headers);
[email protected]3d2a59b2008-09-26 19:44:251321 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
tbansal2ecbbc72016-10-06 17:15:471322 EXPECT_TRUE(response->proxy_server.is_direct());
initial.commit586acc5fe2008-07-26 22:42:521323
1324 std::string response_data;
bnc691fda62016-08-12 00:43:161325 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:011326 EXPECT_THAT(rv, IsOk());
[email protected]3d2a59b2008-09-26 19:44:251327 EXPECT_EQ(kExpectedResponseData[i], response_data);
initial.commit586acc5fe2008-07-26 22:42:521328 }
1329}
1330
bncd16676a2016-07-20 16:23:011331TEST_F(HttpNetworkTransactionTest, Ignores100) {
danakj1fd259a02016-04-16 03:17:091332 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:221333 element_readers.push_back(
Jeremy Roman0579ed62017-08-29 15:56:191334 std::make_unique<UploadBytesElementReader>("foo", 3));
olli.raula6df48b2a2015-11-26 07:40:221335 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]329b68b2012-11-14 17:54:271336
[email protected]1c773ea12009-04-28 19:58:421337 HttpRequestInfo request;
initial.commit586acc5fe2008-07-26 22:42:521338 request.method = "POST";
1339 request.url = GURL("http://www.foo.com/");
[email protected]329b68b2012-11-14 17:54:271340 request.upload_data_stream = &upload_data_stream;
initial.commit586acc5fe2008-07-26 22:42:521341
shivanishab9a143952016-09-19 17:23:411342 // Check the upload progress returned before initialization is correct.
1343 UploadProgress progress = request.upload_data_stream->GetUploadProgress();
1344 EXPECT_EQ(0u, progress.size());
1345 EXPECT_EQ(0u, progress.position());
1346
danakj1fd259a02016-04-16 03:17:091347 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:161348 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:271349
initial.commit586acc5fe2008-07-26 22:42:521350 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:351351 MockRead("HTTP/1.0 100 Continue\r\n\r\n"),
1352 MockRead("HTTP/1.0 200 OK\r\n\r\n"),
1353 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:061354 MockRead(SYNCHRONOUS, OK),
initial.commit586acc5fe2008-07-26 22:42:521355 };
[email protected]31a2bfe2010-02-09 08:03:391356 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:071357 session_deps_.socket_factory->AddSocketDataProvider(&data);
initial.commit586acc5fe2008-07-26 22:42:521358
[email protected]49639fa2011-12-20 23:22:411359 TestCompletionCallback callback;
initial.commit586acc5fe2008-07-26 22:42:521360
tfarina42834112016-09-22 13:38:201361 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:011362 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
initial.commit586acc5fe2008-07-26 22:42:521363
1364 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:011365 EXPECT_THAT(rv, IsOk());
initial.commit586acc5fe2008-07-26 22:42:521366
bnc691fda62016-08-12 00:43:161367 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:521368 ASSERT_TRUE(response);
initial.commit586acc5fe2008-07-26 22:42:521369
wezca1070932016-05-26 20:30:521370 EXPECT_TRUE(response->headers);
[email protected]3d2a59b2008-09-26 19:44:251371 EXPECT_EQ("HTTP/1.0 200 OK", response->headers->GetStatusLine());
initial.commit586acc5fe2008-07-26 22:42:521372
1373 std::string response_data;
bnc691fda62016-08-12 00:43:161374 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:011375 EXPECT_THAT(rv, IsOk());
[email protected]3d2a59b2008-09-26 19:44:251376 EXPECT_EQ("hello world", response_data);
initial.commit586acc5fe2008-07-26 22:42:521377}
1378
[email protected]3a2d3662009-03-27 03:49:141379// This test is almost the same as Ignores100 above, but the response contains
1380// a 102 instead of a 100. Also, instead of HTTP/1.0 the response is
[email protected]0877e3d2009-10-17 22:29:571381// HTTP/1.1 and the two status headers are read in one read.
bncd16676a2016-07-20 16:23:011382TEST_F(HttpNetworkTransactionTest, Ignores1xx) {
[email protected]1c773ea12009-04-28 19:58:421383 HttpRequestInfo request;
[email protected]3a2d3662009-03-27 03:49:141384 request.method = "GET";
1385 request.url = GURL("http://www.foo.com/");
[email protected]3a2d3662009-03-27 03:49:141386
danakj1fd259a02016-04-16 03:17:091387 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:161388 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:271389
[email protected]3a2d3662009-03-27 03:49:141390 MockRead data_reads[] = {
[email protected]0877e3d2009-10-17 22:29:571391 MockRead("HTTP/1.1 102 Unspecified status code\r\n\r\n"
1392 "HTTP/1.1 200 OK\r\n\r\n"),
[email protected]3a2d3662009-03-27 03:49:141393 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:061394 MockRead(SYNCHRONOUS, OK),
[email protected]3a2d3662009-03-27 03:49:141395 };
[email protected]31a2bfe2010-02-09 08:03:391396 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:071397 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]3a2d3662009-03-27 03:49:141398
[email protected]49639fa2011-12-20 23:22:411399 TestCompletionCallback callback;
[email protected]3a2d3662009-03-27 03:49:141400
tfarina42834112016-09-22 13:38:201401 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:011402 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]3a2d3662009-03-27 03:49:141403
1404 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:011405 EXPECT_THAT(rv, IsOk());
[email protected]3a2d3662009-03-27 03:49:141406
bnc691fda62016-08-12 00:43:161407 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:521408 ASSERT_TRUE(response);
[email protected]3a2d3662009-03-27 03:49:141409
wezca1070932016-05-26 20:30:521410 EXPECT_TRUE(response->headers);
[email protected]3a2d3662009-03-27 03:49:141411 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
1412
1413 std::string response_data;
bnc691fda62016-08-12 00:43:161414 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:011415 EXPECT_THAT(rv, IsOk());
[email protected]3a2d3662009-03-27 03:49:141416 EXPECT_EQ("hello world", response_data);
1417}
1418
bncd16676a2016-07-20 16:23:011419TEST_F(HttpNetworkTransactionTest, Incomplete100ThenEOF) {
zmo9528c9f42015-08-04 22:12:081420 HttpRequestInfo request;
1421 request.method = "POST";
1422 request.url = GURL("http://www.foo.com/");
zmo9528c9f42015-08-04 22:12:081423
danakj1fd259a02016-04-16 03:17:091424 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:161425 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
zmo9528c9f42015-08-04 22:12:081426
1427 MockRead data_reads[] = {
1428 MockRead(SYNCHRONOUS, "HTTP/1.0 100 Continue\r\n"),
1429 MockRead(ASYNC, 0),
[email protected]ee9410e72010-01-07 01:42:381430 };
zmo9528c9f42015-08-04 22:12:081431 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
1432 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]ee9410e72010-01-07 01:42:381433
zmo9528c9f42015-08-04 22:12:081434 TestCompletionCallback callback;
[email protected]ee9410e72010-01-07 01:42:381435
tfarina42834112016-09-22 13:38:201436 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:011437 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]ee9410e72010-01-07 01:42:381438
zmo9528c9f42015-08-04 22:12:081439 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:011440 EXPECT_THAT(rv, IsOk());
[email protected]ee9410e72010-01-07 01:42:381441
zmo9528c9f42015-08-04 22:12:081442 std::string response_data;
bnc691fda62016-08-12 00:43:161443 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:011444 EXPECT_THAT(rv, IsOk());
zmo9528c9f42015-08-04 22:12:081445 EXPECT_EQ("", response_data);
[email protected]ee9410e72010-01-07 01:42:381446}
1447
bncd16676a2016-07-20 16:23:011448TEST_F(HttpNetworkTransactionTest, EmptyResponse) {
[email protected]ee9410e72010-01-07 01:42:381449 HttpRequestInfo request;
1450 request.method = "POST";
1451 request.url = GURL("http://www.foo.com/");
[email protected]ee9410e72010-01-07 01:42:381452
danakj1fd259a02016-04-16 03:17:091453 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:161454 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:271455
[email protected]ee9410e72010-01-07 01:42:381456 MockRead data_reads[] = {
[email protected]8ddf8322012-02-23 18:08:061457 MockRead(ASYNC, 0),
[email protected]ee9410e72010-01-07 01:42:381458 };
[email protected]31a2bfe2010-02-09 08:03:391459 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:071460 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]ee9410e72010-01-07 01:42:381461
[email protected]49639fa2011-12-20 23:22:411462 TestCompletionCallback callback;
[email protected]ee9410e72010-01-07 01:42:381463
tfarina42834112016-09-22 13:38:201464 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:011465 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]ee9410e72010-01-07 01:42:381466
1467 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:011468 EXPECT_THAT(rv, IsError(ERR_EMPTY_RESPONSE));
[email protected]ee9410e72010-01-07 01:42:381469}
1470
[email protected]23e482282013-06-14 16:08:021471void HttpNetworkTransactionTest::KeepAliveConnectionResendRequestTest(
[email protected]202965992011-12-07 23:04:511472 const MockWrite* write_failure,
1473 const MockRead* read_failure) {
[email protected]1c773ea12009-04-28 19:58:421474 HttpRequestInfo request;
initial.commit586acc5fe2008-07-26 22:42:521475 request.method = "GET";
1476 request.url = GURL("http://www.foo.com/");
initial.commit586acc5fe2008-07-26 22:42:521477
vishal.b62985ca92015-04-17 08:45:511478 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:071479 session_deps_.net_log = &net_log;
danakj1fd259a02016-04-16 03:17:091480 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:271481
[email protected]202965992011-12-07 23:04:511482 // Written data for successfully sending both requests.
1483 MockWrite data1_writes[] = {
1484 MockWrite("GET / HTTP/1.1\r\n"
1485 "Host: www.foo.com\r\n"
1486 "Connection: keep-alive\r\n\r\n"),
1487 MockWrite("GET / HTTP/1.1\r\n"
1488 "Host: www.foo.com\r\n"
1489 "Connection: keep-alive\r\n\r\n")
1490 };
1491
1492 // Read results for the first request.
initial.commit586acc5fe2008-07-26 22:42:521493 MockRead data1_reads[] = {
[email protected]217e6022008-09-29 18:18:351494 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
1495 MockRead("hello"),
[email protected]8ddf8322012-02-23 18:08:061496 MockRead(ASYNC, OK),
initial.commit586acc5fe2008-07-26 22:42:521497 };
[email protected]202965992011-12-07 23:04:511498
1499 if (write_failure) {
[email protected]a34f61ee2014-03-18 20:59:491500 ASSERT_FALSE(read_failure);
[email protected]202965992011-12-07 23:04:511501 data1_writes[1] = *write_failure;
1502 } else {
1503 ASSERT_TRUE(read_failure);
1504 data1_reads[2] = *read_failure;
1505 }
1506
1507 StaticSocketDataProvider data1(data1_reads, arraysize(data1_reads),
1508 data1_writes, arraysize(data1_writes));
[email protected]bb88e1d32013-05-03 23:11:071509 session_deps_.socket_factory->AddSocketDataProvider(&data1);
initial.commit586acc5fe2008-07-26 22:42:521510
1511 MockRead data2_reads[] = {
[email protected]217e6022008-09-29 18:18:351512 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
1513 MockRead("world"),
[email protected]8ddf8322012-02-23 18:08:061514 MockRead(ASYNC, OK),
initial.commit586acc5fe2008-07-26 22:42:521515 };
[email protected]31a2bfe2010-02-09 08:03:391516 StaticSocketDataProvider data2(data2_reads, arraysize(data2_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:071517 session_deps_.socket_factory->AddSocketDataProvider(&data2);
initial.commit586acc5fe2008-07-26 22:42:521518
thestig9d3bb0c2015-01-24 00:49:511519 const char* const kExpectedResponseData[] = {
initial.commit586acc5fe2008-07-26 22:42:521520 "hello", "world"
1521 };
1522
mikecironef22f9812016-10-04 03:40:191523 uint32_t first_socket_log_id = NetLogSource::kInvalidId;
initial.commit586acc5fe2008-07-26 22:42:521524 for (int i = 0; i < 2; ++i) {
[email protected]49639fa2011-12-20 23:22:411525 TestCompletionCallback callback;
initial.commit586acc5fe2008-07-26 22:42:521526
bnc691fda62016-08-12 00:43:161527 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
initial.commit586acc5fe2008-07-26 22:42:521528
tfarina42834112016-09-22 13:38:201529 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:011530 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
initial.commit586acc5fe2008-07-26 22:42:521531
1532 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:011533 EXPECT_THAT(rv, IsOk());
initial.commit586acc5fe2008-07-26 22:42:521534
[email protected]58e32bb2013-01-21 18:23:251535 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:161536 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]58e32bb2013-01-21 18:23:251537 TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_DNS_TIMES);
1538 if (i == 0) {
1539 first_socket_log_id = load_timing_info.socket_log_id;
1540 } else {
1541 // The second request should be using a new socket.
1542 EXPECT_NE(first_socket_log_id, load_timing_info.socket_log_id);
1543 }
1544
bnc691fda62016-08-12 00:43:161545 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:521546 ASSERT_TRUE(response);
initial.commit586acc5fe2008-07-26 22:42:521547
wezca1070932016-05-26 20:30:521548 EXPECT_TRUE(response->headers);
tbansal2ecbbc72016-10-06 17:15:471549 EXPECT_TRUE(response->proxy_server.is_direct());
[email protected]3d2a59b2008-09-26 19:44:251550 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
initial.commit586acc5fe2008-07-26 22:42:521551
1552 std::string response_data;
bnc691fda62016-08-12 00:43:161553 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:011554 EXPECT_THAT(rv, IsOk());
[email protected]3d2a59b2008-09-26 19:44:251555 EXPECT_EQ(kExpectedResponseData[i], response_data);
initial.commit586acc5fe2008-07-26 22:42:521556 }
1557}
[email protected]3d2a59b2008-09-26 19:44:251558
[email protected]a34f61ee2014-03-18 20:59:491559void HttpNetworkTransactionTest::PreconnectErrorResendRequestTest(
1560 const MockWrite* write_failure,
[email protected]09356c652014-03-25 15:36:101561 const MockRead* read_failure,
1562 bool use_spdy) {
[email protected]a34f61ee2014-03-18 20:59:491563 HttpRequestInfo request;
1564 request.method = "GET";
[email protected]09356c652014-03-25 15:36:101565 request.url = GURL("https://www.foo.com/");
[email protected]a34f61ee2014-03-18 20:59:491566
vishal.b62985ca92015-04-17 08:45:511567 TestNetLog net_log;
[email protected]a34f61ee2014-03-18 20:59:491568 session_deps_.net_log = &net_log;
danakj1fd259a02016-04-16 03:17:091569 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]a34f61ee2014-03-18 20:59:491570
[email protected]09356c652014-03-25 15:36:101571 SSLSocketDataProvider ssl1(ASYNC, OK);
1572 SSLSocketDataProvider ssl2(ASYNC, OK);
1573 if (use_spdy) {
bnc3cf2a592016-08-11 14:48:361574 ssl1.next_proto = kProtoHTTP2;
1575 ssl2.next_proto = kProtoHTTP2;
[email protected]09356c652014-03-25 15:36:101576 }
1577 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl1);
1578 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
[email protected]a34f61ee2014-03-18 20:59:491579
[email protected]09356c652014-03-25 15:36:101580 // SPDY versions of the request and response.
bncdf80d44fd2016-07-15 20:27:411581 SpdySerializedFrame spdy_request(spdy_util_.ConstructSpdyGet(
bnc38dcd392016-02-09 23:19:491582 request.url.spec().c_str(), 1, DEFAULT_PRIORITY));
bncdf80d44fd2016-07-15 20:27:411583 SpdySerializedFrame spdy_response(
bnc42331402016-07-25 13:36:151584 spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
bncdf80d44fd2016-07-15 20:27:411585 SpdySerializedFrame spdy_data(
1586 spdy_util_.ConstructSpdyDataFrame(1, "hello", 5, true));
[email protected]a34f61ee2014-03-18 20:59:491587
[email protected]09356c652014-03-25 15:36:101588 // HTTP/1.1 versions of the request and response.
1589 const char kHttpRequest[] = "GET / HTTP/1.1\r\n"
1590 "Host: www.foo.com\r\n"
1591 "Connection: keep-alive\r\n\r\n";
1592 const char kHttpResponse[] = "HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n";
1593 const char kHttpData[] = "hello";
1594
1595 std::vector<MockRead> data1_reads;
1596 std::vector<MockWrite> data1_writes;
[email protected]a34f61ee2014-03-18 20:59:491597 if (write_failure) {
1598 ASSERT_FALSE(read_failure);
[email protected]09356c652014-03-25 15:36:101599 data1_writes.push_back(*write_failure);
1600 data1_reads.push_back(MockRead(ASYNC, OK));
[email protected]a34f61ee2014-03-18 20:59:491601 } else {
1602 ASSERT_TRUE(read_failure);
[email protected]09356c652014-03-25 15:36:101603 if (use_spdy) {
bncdf80d44fd2016-07-15 20:27:411604 data1_writes.push_back(CreateMockWrite(spdy_request));
[email protected]09356c652014-03-25 15:36:101605 } else {
1606 data1_writes.push_back(MockWrite(kHttpRequest));
1607 }
1608 data1_reads.push_back(*read_failure);
[email protected]a34f61ee2014-03-18 20:59:491609 }
1610
[email protected]09356c652014-03-25 15:36:101611 StaticSocketDataProvider data1(&data1_reads[0], data1_reads.size(),
1612 &data1_writes[0], data1_writes.size());
[email protected]a34f61ee2014-03-18 20:59:491613 session_deps_.socket_factory->AddSocketDataProvider(&data1);
1614
[email protected]09356c652014-03-25 15:36:101615 std::vector<MockRead> data2_reads;
1616 std::vector<MockWrite> data2_writes;
1617
1618 if (use_spdy) {
bncdf80d44fd2016-07-15 20:27:411619 data2_writes.push_back(CreateMockWrite(spdy_request, 0, ASYNC));
[email protected]09356c652014-03-25 15:36:101620
bncdf80d44fd2016-07-15 20:27:411621 data2_reads.push_back(CreateMockRead(spdy_response, 1, ASYNC));
1622 data2_reads.push_back(CreateMockRead(spdy_data, 2, ASYNC));
[email protected]09356c652014-03-25 15:36:101623 data2_reads.push_back(MockRead(ASYNC, OK, 3));
1624 } else {
1625 data2_writes.push_back(
1626 MockWrite(ASYNC, kHttpRequest, strlen(kHttpRequest), 0));
1627
1628 data2_reads.push_back(
1629 MockRead(ASYNC, kHttpResponse, strlen(kHttpResponse), 1));
1630 data2_reads.push_back(MockRead(ASYNC, kHttpData, strlen(kHttpData), 2));
1631 data2_reads.push_back(MockRead(ASYNC, OK, 3));
1632 }
rch8e6c6c42015-05-01 14:05:131633 SequencedSocketData data2(&data2_reads[0], data2_reads.size(),
1634 &data2_writes[0], data2_writes.size());
[email protected]a34f61ee2014-03-18 20:59:491635 session_deps_.socket_factory->AddSocketDataProvider(&data2);
1636
1637 // Preconnect a socket.
nharper8cdb0fb2016-04-22 21:34:591638 session->http_stream_factory()->PreconnectStreams(1, request);
[email protected]a34f61ee2014-03-18 20:59:491639 // Wait for the preconnect to complete.
1640 // TODO(davidben): Some way to wait for an idle socket count might be handy.
1641 base::RunLoop().RunUntilIdle();
[email protected]09356c652014-03-25 15:36:101642 EXPECT_EQ(1, GetIdleSocketCountInSSLSocketPool(session.get()));
[email protected]a34f61ee2014-03-18 20:59:491643
1644 // Make the request.
1645 TestCompletionCallback callback;
1646
bnc691fda62016-08-12 00:43:161647 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]a34f61ee2014-03-18 20:59:491648
tfarina42834112016-09-22 13:38:201649 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:011650 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]a34f61ee2014-03-18 20:59:491651
1652 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:011653 EXPECT_THAT(rv, IsOk());
[email protected]a34f61ee2014-03-18 20:59:491654
1655 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:161656 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]09356c652014-03-25 15:36:101657 TestLoadTimingNotReused(
1658 load_timing_info,
1659 CONNECT_TIMING_HAS_DNS_TIMES|CONNECT_TIMING_HAS_SSL_TIMES);
[email protected]a34f61ee2014-03-18 20:59:491660
bnc691fda62016-08-12 00:43:161661 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:521662 ASSERT_TRUE(response);
[email protected]a34f61ee2014-03-18 20:59:491663
wezca1070932016-05-26 20:30:521664 EXPECT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:021665 if (response->was_fetched_via_spdy) {
1666 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
1667 } else {
1668 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
1669 }
[email protected]a34f61ee2014-03-18 20:59:491670
1671 std::string response_data;
bnc691fda62016-08-12 00:43:161672 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:011673 EXPECT_THAT(rv, IsOk());
[email protected]09356c652014-03-25 15:36:101674 EXPECT_EQ(kHttpData, response_data);
[email protected]a34f61ee2014-03-18 20:59:491675}
1676
Biljith Jayan45a41722017-08-16 18:43:141677// Test that we do not retry indefinitely when a server sends an error like
1678// ERR_SPDY_PING_FAILED, ERR_SPDY_SERVER_REFUSED_STREAM,
1679// ERR_QUIC_HANDSHAKE_FAILED or ERR_QUIC_PROTOCOL_ERROR.
1680TEST_F(HttpNetworkTransactionTest, FiniteRetriesOnIOError) {
1681 HttpRequestInfo request;
1682 request.method = "GET";
1683 request.url = GURL("https://www.foo.com/");
1684
1685 // Check whether we give up after the third try.
1686
1687 // Construct an HTTP2 request and a "Go away" response.
1688 SpdySerializedFrame spdy_request(spdy_util_.ConstructSpdyGet(
1689 request.url.spec().c_str(), 1, DEFAULT_PRIORITY));
1690 SpdySerializedFrame spdy_response_go_away(spdy_util_.ConstructSpdyGoAway());
1691 MockRead data_read1 = CreateMockRead(spdy_response_go_away);
1692 MockWrite data_write = CreateMockWrite(spdy_request, 0);
1693
1694 // Three go away responses.
1695 StaticSocketDataProvider data1(&data_read1, 1, &data_write, 1);
1696 StaticSocketDataProvider data2(&data_read1, 1, &data_write, 1);
1697 StaticSocketDataProvider data3(&data_read1, 1, &data_write, 1);
1698
1699 session_deps_.socket_factory->AddSocketDataProvider(&data1);
1700 AddSSLSocketData();
1701 session_deps_.socket_factory->AddSocketDataProvider(&data2);
1702 AddSSLSocketData();
1703 session_deps_.socket_factory->AddSocketDataProvider(&data3);
1704 AddSSLSocketData();
1705
1706 TestCompletionCallback callback;
1707 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
1708 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
1709
1710 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
1711 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
1712
1713 rv = callback.WaitForResult();
1714 EXPECT_THAT(rv, IsError(ERR_SPDY_SERVER_REFUSED_STREAM));
1715}
1716
1717TEST_F(HttpNetworkTransactionTest, RetryTwiceOnIOError) {
1718 HttpRequestInfo request;
1719 request.method = "GET";
1720 request.url = GURL("https://www.foo.com/");
1721
1722 // Check whether we try atleast thrice before giving up.
1723
1724 // Construct an HTTP2 request and a "Go away" response.
1725 SpdySerializedFrame spdy_request(spdy_util_.ConstructSpdyGet(
1726 request.url.spec().c_str(), 1, DEFAULT_PRIORITY));
1727 SpdySerializedFrame spdy_response_go_away(spdy_util_.ConstructSpdyGoAway());
1728 MockRead data_read1 = CreateMockRead(spdy_response_go_away);
1729 MockWrite data_write = CreateMockWrite(spdy_request, 0);
1730
1731 // Construct a non error HTTP2 response.
1732 SpdySerializedFrame spdy_response_no_error(
1733 spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
1734 SpdySerializedFrame spdy_data(spdy_util_.ConstructSpdyDataFrame(1, true));
1735 MockRead data_read2[] = {CreateMockRead(spdy_response_no_error, 1),
1736 CreateMockRead(spdy_data, 2)};
1737
1738 // Two error responses.
1739 StaticSocketDataProvider data1(&data_read1, 1, &data_write, 1);
1740 StaticSocketDataProvider data2(&data_read1, 1, &data_write, 1);
1741 // Followed by a success response.
1742 SequencedSocketData data3(data_read2, 2, &data_write, 1);
1743
1744 session_deps_.socket_factory->AddSocketDataProvider(&data1);
1745 AddSSLSocketData();
1746 session_deps_.socket_factory->AddSocketDataProvider(&data2);
1747 AddSSLSocketData();
1748 session_deps_.socket_factory->AddSocketDataProvider(&data3);
1749 AddSSLSocketData();
1750
1751 TestCompletionCallback callback;
1752 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
1753 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
1754
1755 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
1756 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
1757
1758 rv = callback.WaitForResult();
1759 EXPECT_THAT(rv, IsOk());
1760}
1761
bncd16676a2016-07-20 16:23:011762TEST_F(HttpNetworkTransactionTest, KeepAliveConnectionNotConnectedOnWrite) {
[email protected]8ddf8322012-02-23 18:08:061763 MockWrite write_failure(ASYNC, ERR_SOCKET_NOT_CONNECTED);
[email protected]202965992011-12-07 23:04:511764 KeepAliveConnectionResendRequestTest(&write_failure, NULL);
1765}
1766
bncd16676a2016-07-20 16:23:011767TEST_F(HttpNetworkTransactionTest, KeepAliveConnectionReset) {
[email protected]8ddf8322012-02-23 18:08:061768 MockRead read_failure(ASYNC, ERR_CONNECTION_RESET);
[email protected]202965992011-12-07 23:04:511769 KeepAliveConnectionResendRequestTest(NULL, &read_failure);
[email protected]3d2a59b2008-09-26 19:44:251770}
1771
bncd16676a2016-07-20 16:23:011772TEST_F(HttpNetworkTransactionTest, KeepAliveConnectionEOF) {
[email protected]8ddf8322012-02-23 18:08:061773 MockRead read_failure(SYNCHRONOUS, OK); // EOF
[email protected]202965992011-12-07 23:04:511774 KeepAliveConnectionResendRequestTest(NULL, &read_failure);
[email protected]3d2a59b2008-09-26 19:44:251775}
1776
[email protected]d58ceea82014-06-04 10:55:541777// Make sure that on a 408 response (Request Timeout), the request is retried,
1778// if the socket was a reused keep alive socket.
bncd16676a2016-07-20 16:23:011779TEST_F(HttpNetworkTransactionTest, KeepAlive408) {
[email protected]d58ceea82014-06-04 10:55:541780 MockRead read_failure(SYNCHRONOUS,
1781 "HTTP/1.1 408 Request Timeout\r\n"
1782 "Connection: Keep-Alive\r\n"
1783 "Content-Length: 6\r\n\r\n"
1784 "Pickle");
1785 KeepAliveConnectionResendRequestTest(NULL, &read_failure);
1786}
1787
bncd16676a2016-07-20 16:23:011788TEST_F(HttpNetworkTransactionTest, PreconnectErrorNotConnectedOnWrite) {
[email protected]a34f61ee2014-03-18 20:59:491789 MockWrite write_failure(ASYNC, ERR_SOCKET_NOT_CONNECTED);
[email protected]09356c652014-03-25 15:36:101790 PreconnectErrorResendRequestTest(&write_failure, NULL, false);
[email protected]a34f61ee2014-03-18 20:59:491791}
1792
bncd16676a2016-07-20 16:23:011793TEST_F(HttpNetworkTransactionTest, PreconnectErrorReset) {
[email protected]a34f61ee2014-03-18 20:59:491794 MockRead read_failure(ASYNC, ERR_CONNECTION_RESET);
[email protected]09356c652014-03-25 15:36:101795 PreconnectErrorResendRequestTest(NULL, &read_failure, false);
[email protected]a34f61ee2014-03-18 20:59:491796}
1797
bncd16676a2016-07-20 16:23:011798TEST_F(HttpNetworkTransactionTest, PreconnectErrorEOF) {
[email protected]a34f61ee2014-03-18 20:59:491799 MockRead read_failure(SYNCHRONOUS, OK); // EOF
[email protected]09356c652014-03-25 15:36:101800 PreconnectErrorResendRequestTest(NULL, &read_failure, false);
1801}
1802
bncd16676a2016-07-20 16:23:011803TEST_F(HttpNetworkTransactionTest, PreconnectErrorAsyncEOF) {
[email protected]09356c652014-03-25 15:36:101804 MockRead read_failure(ASYNC, OK); // EOF
1805 PreconnectErrorResendRequestTest(NULL, &read_failure, false);
1806}
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 preconnected (UNUSED_IDLE) socket.
bncd16676a2016-07-20 16:23:011810TEST_F(HttpNetworkTransactionTest, RetryOnIdle408) {
[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 PreconnectErrorResendRequestTest(NULL, &read_failure, false);
1818}
1819
bncd16676a2016-07-20 16:23:011820TEST_F(HttpNetworkTransactionTest, SpdyPreconnectErrorNotConnectedOnWrite) {
[email protected]09356c652014-03-25 15:36:101821 MockWrite write_failure(ASYNC, ERR_SOCKET_NOT_CONNECTED);
1822 PreconnectErrorResendRequestTest(&write_failure, NULL, true);
1823}
1824
bncd16676a2016-07-20 16:23:011825TEST_F(HttpNetworkTransactionTest, SpdyPreconnectErrorReset) {
[email protected]09356c652014-03-25 15:36:101826 MockRead read_failure(ASYNC, ERR_CONNECTION_RESET);
1827 PreconnectErrorResendRequestTest(NULL, &read_failure, true);
1828}
1829
bncd16676a2016-07-20 16:23:011830TEST_F(HttpNetworkTransactionTest, SpdyPreconnectErrorEOF) {
[email protected]09356c652014-03-25 15:36:101831 MockRead read_failure(SYNCHRONOUS, OK); // EOF
1832 PreconnectErrorResendRequestTest(NULL, &read_failure, true);
1833}
1834
bncd16676a2016-07-20 16:23:011835TEST_F(HttpNetworkTransactionTest, SpdyPreconnectErrorAsyncEOF) {
[email protected]09356c652014-03-25 15:36:101836 MockRead read_failure(ASYNC, OK); // EOF
1837 PreconnectErrorResendRequestTest(NULL, &read_failure, true);
[email protected]a34f61ee2014-03-18 20:59:491838}
1839
bncd16676a2016-07-20 16:23:011840TEST_F(HttpNetworkTransactionTest, NonKeepAliveConnectionReset) {
[email protected]1c773ea12009-04-28 19:58:421841 HttpRequestInfo request;
[email protected]3d2a59b2008-09-26 19:44:251842 request.method = "GET";
bncce36dca22015-04-21 22:11:231843 request.url = GURL("http://www.example.org/");
[email protected]3d2a59b2008-09-26 19:44:251844
danakj1fd259a02016-04-16 03:17:091845 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:161846 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:271847
[email protected]3d2a59b2008-09-26 19:44:251848 MockRead data_reads[] = {
[email protected]8ddf8322012-02-23 18:08:061849 MockRead(ASYNC, ERR_CONNECTION_RESET),
[email protected]217e6022008-09-29 18:18:351850 MockRead("HTTP/1.0 200 OK\r\n\r\n"), // Should not be used
1851 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:061852 MockRead(SYNCHRONOUS, OK),
[email protected]3d2a59b2008-09-26 19:44:251853 };
[email protected]31a2bfe2010-02-09 08:03:391854 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:071855 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]3d2a59b2008-09-26 19:44:251856
[email protected]49639fa2011-12-20 23:22:411857 TestCompletionCallback callback;
[email protected]3d2a59b2008-09-26 19:44:251858
tfarina42834112016-09-22 13:38:201859 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:011860 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]3d2a59b2008-09-26 19:44:251861
1862 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:011863 EXPECT_THAT(rv, IsError(ERR_CONNECTION_RESET));
ttuttled9dbc652015-09-29 20:00:591864
1865 IPEndPoint endpoint;
bnc691fda62016-08-12 00:43:161866 EXPECT_TRUE(trans.GetRemoteEndpoint(&endpoint));
ttuttled9dbc652015-09-29 20:00:591867 EXPECT_LT(0u, endpoint.address().size());
[email protected]3d2a59b2008-09-26 19:44:251868}
1869
1870// What do various browsers do when the server closes a non-keepalive
1871// connection without sending any response header or body?
1872//
1873// IE7: error page
1874// Safari 3.1.2 (Windows): error page
1875// Firefox 3.0.1: blank page
1876// Opera 9.52: after five attempts, blank page
[email protected]1c773ea12009-04-28 19:58:421877// Us with WinHTTP: error page (ERR_INVALID_RESPONSE)
1878// Us: error page (EMPTY_RESPONSE)
bncd16676a2016-07-20 16:23:011879TEST_F(HttpNetworkTransactionTest, NonKeepAliveConnectionEOF) {
[email protected]3d2a59b2008-09-26 19:44:251880 MockRead data_reads[] = {
[email protected]8ddf8322012-02-23 18:08:061881 MockRead(SYNCHRONOUS, OK), // EOF
[email protected]217e6022008-09-29 18:18:351882 MockRead("HTTP/1.0 200 OK\r\n\r\n"), // Should not be used
1883 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:061884 MockRead(SYNCHRONOUS, OK),
[email protected]3d2a59b2008-09-26 19:44:251885 };
[email protected]31a2bfe2010-02-09 08:03:391886 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
1887 arraysize(data_reads));
robpercival214763f2016-07-01 23:27:011888 EXPECT_THAT(out.rv, IsError(ERR_EMPTY_RESPONSE));
[email protected]3d2a59b2008-09-26 19:44:251889}
[email protected]1826a402014-01-08 15:40:481890
[email protected]7a5378b2012-11-04 03:25:171891// Next 2 cases (KeepAliveEarlyClose and KeepAliveEarlyClose2) are regression
1892// tests. There was a bug causing HttpNetworkTransaction to hang in the
1893// destructor in such situations.
1894// See http://crbug.com/154712 and http://crbug.com/156609.
bncd16676a2016-07-20 16:23:011895TEST_F(HttpNetworkTransactionTest, KeepAliveEarlyClose) {
[email protected]7a5378b2012-11-04 03:25:171896 HttpRequestInfo request;
1897 request.method = "GET";
bncce36dca22015-04-21 22:11:231898 request.url = GURL("http://www.example.org/");
[email protected]7a5378b2012-11-04 03:25:171899
danakj1fd259a02016-04-16 03:17:091900 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc87dcefc2017-05-25 12:47:581901 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:191902 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]7a5378b2012-11-04 03:25:171903
1904 MockRead data_reads[] = {
1905 MockRead("HTTP/1.0 200 OK\r\n"),
1906 MockRead("Connection: keep-alive\r\n"),
1907 MockRead("Content-Length: 100\r\n\r\n"),
1908 MockRead("hello"),
1909 MockRead(SYNCHRONOUS, 0),
1910 };
1911 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:071912 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]7a5378b2012-11-04 03:25:171913
1914 TestCompletionCallback callback;
1915
tfarina42834112016-09-22 13:38:201916 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:011917 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]7a5378b2012-11-04 03:25:171918
1919 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:011920 EXPECT_THAT(rv, IsOk());
[email protected]7a5378b2012-11-04 03:25:171921
1922 scoped_refptr<IOBufferWithSize> io_buf(new IOBufferWithSize(100));
[email protected]90499482013-06-01 00:39:501923 rv = trans->Read(io_buf.get(), io_buf->size(), callback.callback());
[email protected]7a5378b2012-11-04 03:25:171924 if (rv == ERR_IO_PENDING)
1925 rv = callback.WaitForResult();
1926 EXPECT_EQ(5, rv);
[email protected]90499482013-06-01 00:39:501927 rv = trans->Read(io_buf.get(), io_buf->size(), callback.callback());
robpercival214763f2016-07-01 23:27:011928 EXPECT_THAT(rv, IsError(ERR_CONTENT_LENGTH_MISMATCH));
[email protected]7a5378b2012-11-04 03:25:171929
1930 trans.reset();
fdoray92e35a72016-06-10 15:54:551931 base::RunLoop().RunUntilIdle();
[email protected]7a5378b2012-11-04 03:25:171932 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
1933}
1934
bncd16676a2016-07-20 16:23:011935TEST_F(HttpNetworkTransactionTest, KeepAliveEarlyClose2) {
[email protected]7a5378b2012-11-04 03:25:171936 HttpRequestInfo request;
1937 request.method = "GET";
bncce36dca22015-04-21 22:11:231938 request.url = GURL("http://www.example.org/");
[email protected]7a5378b2012-11-04 03:25:171939
danakj1fd259a02016-04-16 03:17:091940 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc87dcefc2017-05-25 12:47:581941 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:191942 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]7a5378b2012-11-04 03:25:171943
1944 MockRead data_reads[] = {
1945 MockRead("HTTP/1.0 200 OK\r\n"),
1946 MockRead("Connection: keep-alive\r\n"),
1947 MockRead("Content-Length: 100\r\n\r\n"),
1948 MockRead(SYNCHRONOUS, 0),
1949 };
1950 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:071951 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]7a5378b2012-11-04 03:25:171952
1953 TestCompletionCallback callback;
1954
tfarina42834112016-09-22 13:38:201955 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:011956 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]7a5378b2012-11-04 03:25:171957
1958 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:011959 EXPECT_THAT(rv, IsOk());
[email protected]7a5378b2012-11-04 03:25:171960
1961 scoped_refptr<IOBufferWithSize> io_buf(new IOBufferWithSize(100));
[email protected]90499482013-06-01 00:39:501962 rv = trans->Read(io_buf.get(), io_buf->size(), callback.callback());
[email protected]7a5378b2012-11-04 03:25:171963 if (rv == ERR_IO_PENDING)
1964 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:011965 EXPECT_THAT(rv, IsError(ERR_CONTENT_LENGTH_MISMATCH));
[email protected]7a5378b2012-11-04 03:25:171966
1967 trans.reset();
fdoray92e35a72016-06-10 15:54:551968 base::RunLoop().RunUntilIdle();
[email protected]7a5378b2012-11-04 03:25:171969 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
1970}
1971
[email protected]0b0bf032010-09-21 18:08:501972// Test that we correctly reuse a keep-alive connection after not explicitly
1973// reading the body.
bncd16676a2016-07-20 16:23:011974TEST_F(HttpNetworkTransactionTest, KeepAliveAfterUnreadBody) {
[email protected]fc31d6a42010-06-24 18:05:131975 HttpRequestInfo request;
1976 request.method = "GET";
1977 request.url = GURL("http://www.foo.com/");
[email protected]fc31d6a42010-06-24 18:05:131978
vishal.b62985ca92015-04-17 08:45:511979 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:071980 session_deps_.net_log = &net_log;
danakj1fd259a02016-04-16 03:17:091981 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:271982
mmenkecc2298e2015-12-07 18:20:181983 const char* request_data =
1984 "GET / HTTP/1.1\r\n"
1985 "Host: www.foo.com\r\n"
1986 "Connection: keep-alive\r\n\r\n";
1987 MockWrite data_writes[] = {
1988 MockWrite(ASYNC, 0, request_data), MockWrite(ASYNC, 2, request_data),
1989 MockWrite(ASYNC, 4, request_data), MockWrite(ASYNC, 6, request_data),
1990 MockWrite(ASYNC, 8, request_data), MockWrite(ASYNC, 10, request_data),
1991 MockWrite(ASYNC, 12, request_data), MockWrite(ASYNC, 14, request_data),
1992 MockWrite(ASYNC, 17, request_data), MockWrite(ASYNC, 20, request_data),
1993 };
1994
[email protected]0b0bf032010-09-21 18:08:501995 // Note that because all these reads happen in the same
1996 // StaticSocketDataProvider, it shows that the same socket is being reused for
1997 // all transactions.
mmenkecc2298e2015-12-07 18:20:181998 MockRead data_reads[] = {
1999 MockRead(ASYNC, 1, "HTTP/1.1 204 No Content\r\n\r\n"),
2000 MockRead(ASYNC, 3, "HTTP/1.1 205 Reset Content\r\n\r\n"),
2001 MockRead(ASYNC, 5, "HTTP/1.1 304 Not Modified\r\n\r\n"),
2002 MockRead(ASYNC, 7,
2003 "HTTP/1.1 302 Found\r\n"
2004 "Content-Length: 0\r\n\r\n"),
2005 MockRead(ASYNC, 9,
2006 "HTTP/1.1 302 Found\r\n"
2007 "Content-Length: 5\r\n\r\n"
2008 "hello"),
2009 MockRead(ASYNC, 11,
2010 "HTTP/1.1 301 Moved Permanently\r\n"
2011 "Content-Length: 0\r\n\r\n"),
2012 MockRead(ASYNC, 13,
2013 "HTTP/1.1 301 Moved Permanently\r\n"
2014 "Content-Length: 5\r\n\r\n"
2015 "hello"),
[email protected]fc31d6a42010-06-24 18:05:132016
mmenkecc2298e2015-12-07 18:20:182017 // In the next two rounds, IsConnectedAndIdle returns false, due to
2018 // the set_busy_before_sync_reads(true) call, while the
2019 // HttpNetworkTransaction is being shut down, but the socket is still
2020 // reuseable. See http://crbug.com/544255.
2021 MockRead(ASYNC, 15,
2022 "HTTP/1.1 200 Hunky-Dory\r\n"
2023 "Content-Length: 5\r\n\r\n"),
2024 MockRead(SYNCHRONOUS, 16, "hello"),
[email protected]fc31d6a42010-06-24 18:05:132025
mmenkecc2298e2015-12-07 18:20:182026 MockRead(ASYNC, 18,
2027 "HTTP/1.1 200 Hunky-Dory\r\n"
2028 "Content-Length: 5\r\n\r\n"
2029 "he"),
2030 MockRead(SYNCHRONOUS, 19, "llo"),
2031
2032 // The body of the final request is actually read.
2033 MockRead(ASYNC, 21, "HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
2034 MockRead(ASYNC, 22, "hello"),
2035 };
2036 SequencedSocketData data(data_reads, arraysize(data_reads), data_writes,
2037 arraysize(data_writes));
2038 data.set_busy_before_sync_reads(true);
2039 session_deps_.socket_factory->AddSocketDataProvider(&data);
2040
2041 const int kNumUnreadBodies = arraysize(data_writes) - 1;
[email protected]0b0bf032010-09-21 18:08:502042 std::string response_lines[kNumUnreadBodies];
2043
mikecironef22f9812016-10-04 03:40:192044 uint32_t first_socket_log_id = NetLogSource::kInvalidId;
mmenkecc2298e2015-12-07 18:20:182045 for (size_t i = 0; i < kNumUnreadBodies; ++i) {
[email protected]49639fa2011-12-20 23:22:412046 TestCompletionCallback callback;
[email protected]fc31d6a42010-06-24 18:05:132047
Jeremy Roman0579ed62017-08-29 15:56:192048 auto trans = std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY,
bnc87dcefc2017-05-25 12:47:582049 session.get());
[email protected]fc31d6a42010-06-24 18:05:132050
tfarina42834112016-09-22 13:38:202051 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012052 EXPECT_THAT(callback.GetResult(rv), IsOk());
[email protected]fc31d6a42010-06-24 18:05:132053
[email protected]58e32bb2013-01-21 18:23:252054 LoadTimingInfo load_timing_info;
2055 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
2056 if (i == 0) {
2057 TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_DNS_TIMES);
2058 first_socket_log_id = load_timing_info.socket_log_id;
2059 } else {
2060 TestLoadTimingReused(load_timing_info);
2061 EXPECT_EQ(first_socket_log_id, load_timing_info.socket_log_id);
2062 }
2063
[email protected]fc31d6a42010-06-24 18:05:132064 const HttpResponseInfo* response = trans->GetResponseInfo();
mmenkecc2298e2015-12-07 18:20:182065 ASSERT_TRUE(response);
[email protected]fc31d6a42010-06-24 18:05:132066
mmenkecc2298e2015-12-07 18:20:182067 ASSERT_TRUE(response->headers);
[email protected]0b0bf032010-09-21 18:08:502068 response_lines[i] = response->headers->GetStatusLine();
2069
mmenkecc2298e2015-12-07 18:20:182070 // Delete the transaction without reading the response bodies. Then spin
2071 // the message loop, so the response bodies are drained.
2072 trans.reset();
2073 base::RunLoop().RunUntilIdle();
[email protected]fc31d6a42010-06-24 18:05:132074 }
[email protected]0b0bf032010-09-21 18:08:502075
2076 const char* const kStatusLines[] = {
mmenkecc2298e2015-12-07 18:20:182077 "HTTP/1.1 204 No Content",
2078 "HTTP/1.1 205 Reset Content",
2079 "HTTP/1.1 304 Not Modified",
2080 "HTTP/1.1 302 Found",
2081 "HTTP/1.1 302 Found",
2082 "HTTP/1.1 301 Moved Permanently",
2083 "HTTP/1.1 301 Moved Permanently",
2084 "HTTP/1.1 200 Hunky-Dory",
2085 "HTTP/1.1 200 Hunky-Dory",
[email protected]0b0bf032010-09-21 18:08:502086 };
2087
mostynb91e0da982015-01-20 19:17:272088 static_assert(kNumUnreadBodies == arraysize(kStatusLines),
2089 "forgot to update kStatusLines");
[email protected]0b0bf032010-09-21 18:08:502090
2091 for (int i = 0; i < kNumUnreadBodies; ++i)
2092 EXPECT_EQ(kStatusLines[i], response_lines[i]);
2093
[email protected]49639fa2011-12-20 23:22:412094 TestCompletionCallback callback;
bnc691fda62016-08-12 00:43:162095 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:202096 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012097 EXPECT_THAT(callback.GetResult(rv), IsOk());
bnc691fda62016-08-12 00:43:162098 const HttpResponseInfo* response = trans.GetResponseInfo();
mmenkecc2298e2015-12-07 18:20:182099 ASSERT_TRUE(response);
2100 ASSERT_TRUE(response->headers);
[email protected]0b0bf032010-09-21 18:08:502101 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
2102 std::string response_data;
bnc691fda62016-08-12 00:43:162103 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:012104 EXPECT_THAT(rv, IsOk());
[email protected]0b0bf032010-09-21 18:08:502105 EXPECT_EQ("hello", response_data);
[email protected]fc31d6a42010-06-24 18:05:132106}
2107
mmenke5f94fda2016-06-02 20:54:132108// Sockets that receive extra data after a response is complete should not be
2109// reused.
bncd16676a2016-07-20 16:23:012110TEST_F(HttpNetworkTransactionTest, KeepAliveWithUnusedData1) {
mmenke5f94fda2016-06-02 20:54:132111 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
2112 MockWrite data_writes1[] = {
2113 MockWrite("HEAD / HTTP/1.1\r\n"
2114 "Host: www.borked.com\r\n"
2115 "Connection: keep-alive\r\n\r\n"),
2116 };
2117
2118 MockRead data_reads1[] = {
2119 MockRead("HTTP/1.1 200 OK\r\n"
2120 "Connection: keep-alive\r\n"
2121 "Content-Length: 22\r\n\r\n"
2122 "This server is borked."),
2123 };
2124
2125 MockWrite data_writes2[] = {
2126 MockWrite("GET /foo HTTP/1.1\r\n"
2127 "Host: www.borked.com\r\n"
2128 "Connection: keep-alive\r\n\r\n"),
2129 };
2130
2131 MockRead data_reads2[] = {
2132 MockRead("HTTP/1.1 200 OK\r\n"
2133 "Content-Length: 3\r\n\r\n"
2134 "foo"),
2135 };
2136 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
2137 data_writes1, arraysize(data_writes1));
2138 session_deps_.socket_factory->AddSocketDataProvider(&data1);
2139 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
2140 data_writes2, arraysize(data_writes2));
2141 session_deps_.socket_factory->AddSocketDataProvider(&data2);
2142
2143 TestCompletionCallback callback;
2144 HttpRequestInfo request1;
2145 request1.method = "HEAD";
2146 request1.url = GURL("http://www.borked.com/");
2147
bnc87dcefc2017-05-25 12:47:582148 auto trans1 =
Jeremy Roman0579ed62017-08-29 15:56:192149 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:202150 int rv = trans1->Start(&request1, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012151 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenke5f94fda2016-06-02 20:54:132152
2153 const HttpResponseInfo* response1 = trans1->GetResponseInfo();
2154 ASSERT_TRUE(response1);
2155 ASSERT_TRUE(response1->headers);
2156 EXPECT_EQ(200, response1->headers->response_code());
2157 EXPECT_TRUE(response1->headers->IsKeepAlive());
2158
2159 std::string response_data1;
robpercival214763f2016-07-01 23:27:012160 EXPECT_THAT(ReadTransaction(trans1.get(), &response_data1), IsOk());
mmenke5f94fda2016-06-02 20:54:132161 EXPECT_EQ("", response_data1);
2162 // Deleting the transaction attempts to release the socket back into the
2163 // socket pool.
2164 trans1.reset();
2165
2166 HttpRequestInfo request2;
2167 request2.method = "GET";
2168 request2.url = GURL("http://www.borked.com/foo");
2169
bnc87dcefc2017-05-25 12:47:582170 auto trans2 =
Jeremy Roman0579ed62017-08-29 15:56:192171 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:202172 rv = trans2->Start(&request2, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012173 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenke5f94fda2016-06-02 20:54:132174
2175 const HttpResponseInfo* response2 = trans2->GetResponseInfo();
2176 ASSERT_TRUE(response2);
2177 ASSERT_TRUE(response2->headers);
2178 EXPECT_EQ(200, response2->headers->response_code());
2179
2180 std::string response_data2;
robpercival214763f2016-07-01 23:27:012181 EXPECT_THAT(ReadTransaction(trans2.get(), &response_data2), IsOk());
mmenke5f94fda2016-06-02 20:54:132182 EXPECT_EQ("foo", response_data2);
2183}
2184
bncd16676a2016-07-20 16:23:012185TEST_F(HttpNetworkTransactionTest, KeepAliveWithUnusedData2) {
mmenke5f94fda2016-06-02 20:54:132186 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
2187 MockWrite data_writes1[] = {
2188 MockWrite("GET / HTTP/1.1\r\n"
2189 "Host: www.borked.com\r\n"
2190 "Connection: keep-alive\r\n\r\n"),
2191 };
2192
2193 MockRead data_reads1[] = {
2194 MockRead("HTTP/1.1 200 OK\r\n"
2195 "Connection: keep-alive\r\n"
2196 "Content-Length: 22\r\n\r\n"
2197 "This server is borked."
2198 "Bonus data!"),
2199 };
2200
2201 MockWrite data_writes2[] = {
2202 MockWrite("GET /foo HTTP/1.1\r\n"
2203 "Host: www.borked.com\r\n"
2204 "Connection: keep-alive\r\n\r\n"),
2205 };
2206
2207 MockRead data_reads2[] = {
2208 MockRead("HTTP/1.1 200 OK\r\n"
2209 "Content-Length: 3\r\n\r\n"
2210 "foo"),
2211 };
2212 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
2213 data_writes1, arraysize(data_writes1));
2214 session_deps_.socket_factory->AddSocketDataProvider(&data1);
2215 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
2216 data_writes2, arraysize(data_writes2));
2217 session_deps_.socket_factory->AddSocketDataProvider(&data2);
2218
2219 TestCompletionCallback callback;
2220 HttpRequestInfo request1;
2221 request1.method = "GET";
2222 request1.url = GURL("http://www.borked.com/");
2223
bnc87dcefc2017-05-25 12:47:582224 auto trans1 =
Jeremy Roman0579ed62017-08-29 15:56:192225 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:202226 int rv = trans1->Start(&request1, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012227 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenke5f94fda2016-06-02 20:54:132228
2229 const HttpResponseInfo* response1 = trans1->GetResponseInfo();
2230 ASSERT_TRUE(response1);
2231 ASSERT_TRUE(response1->headers);
2232 EXPECT_EQ(200, response1->headers->response_code());
2233 EXPECT_TRUE(response1->headers->IsKeepAlive());
2234
2235 std::string response_data1;
robpercival214763f2016-07-01 23:27:012236 EXPECT_THAT(ReadTransaction(trans1.get(), &response_data1), IsOk());
mmenke5f94fda2016-06-02 20:54:132237 EXPECT_EQ("This server is borked.", response_data1);
2238 // Deleting the transaction attempts to release the socket back into the
2239 // socket pool.
2240 trans1.reset();
2241
2242 HttpRequestInfo request2;
2243 request2.method = "GET";
2244 request2.url = GURL("http://www.borked.com/foo");
2245
bnc87dcefc2017-05-25 12:47:582246 auto trans2 =
Jeremy Roman0579ed62017-08-29 15:56:192247 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:202248 rv = trans2->Start(&request2, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012249 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenke5f94fda2016-06-02 20:54:132250
2251 const HttpResponseInfo* response2 = trans2->GetResponseInfo();
2252 ASSERT_TRUE(response2);
2253 ASSERT_TRUE(response2->headers);
2254 EXPECT_EQ(200, response2->headers->response_code());
2255
2256 std::string response_data2;
robpercival214763f2016-07-01 23:27:012257 EXPECT_THAT(ReadTransaction(trans2.get(), &response_data2), IsOk());
mmenke5f94fda2016-06-02 20:54:132258 EXPECT_EQ("foo", response_data2);
2259}
2260
bncd16676a2016-07-20 16:23:012261TEST_F(HttpNetworkTransactionTest, KeepAliveWithUnusedData3) {
mmenke5f94fda2016-06-02 20:54:132262 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
2263 MockWrite data_writes1[] = {
2264 MockWrite("GET / HTTP/1.1\r\n"
2265 "Host: www.borked.com\r\n"
2266 "Connection: keep-alive\r\n\r\n"),
2267 };
2268
2269 MockRead data_reads1[] = {
2270 MockRead("HTTP/1.1 200 OK\r\n"
2271 "Connection: keep-alive\r\n"
2272 "Transfer-Encoding: chunked\r\n\r\n"),
2273 MockRead("16\r\nThis server is borked.\r\n"),
2274 MockRead("0\r\n\r\nBonus data!"),
2275 };
2276
2277 MockWrite data_writes2[] = {
2278 MockWrite("GET /foo HTTP/1.1\r\n"
2279 "Host: www.borked.com\r\n"
2280 "Connection: keep-alive\r\n\r\n"),
2281 };
2282
2283 MockRead data_reads2[] = {
2284 MockRead("HTTP/1.1 200 OK\r\n"
2285 "Content-Length: 3\r\n\r\n"
2286 "foo"),
2287 };
2288 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
2289 data_writes1, arraysize(data_writes1));
2290 session_deps_.socket_factory->AddSocketDataProvider(&data1);
2291 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
2292 data_writes2, arraysize(data_writes2));
2293 session_deps_.socket_factory->AddSocketDataProvider(&data2);
2294
2295 TestCompletionCallback callback;
2296 HttpRequestInfo request1;
2297 request1.method = "GET";
2298 request1.url = GURL("http://www.borked.com/");
2299
bnc87dcefc2017-05-25 12:47:582300 auto trans1 =
Jeremy Roman0579ed62017-08-29 15:56:192301 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:202302 int rv = trans1->Start(&request1, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012303 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenke5f94fda2016-06-02 20:54:132304
2305 const HttpResponseInfo* response1 = trans1->GetResponseInfo();
2306 ASSERT_TRUE(response1);
2307 ASSERT_TRUE(response1->headers);
2308 EXPECT_EQ(200, response1->headers->response_code());
2309 EXPECT_TRUE(response1->headers->IsKeepAlive());
2310
2311 std::string response_data1;
robpercival214763f2016-07-01 23:27:012312 EXPECT_THAT(ReadTransaction(trans1.get(), &response_data1), IsOk());
mmenke5f94fda2016-06-02 20:54:132313 EXPECT_EQ("This server is borked.", response_data1);
2314 // Deleting the transaction attempts to release the socket back into the
2315 // socket pool.
2316 trans1.reset();
2317
2318 HttpRequestInfo request2;
2319 request2.method = "GET";
2320 request2.url = GURL("http://www.borked.com/foo");
2321
bnc87dcefc2017-05-25 12:47:582322 auto trans2 =
Jeremy Roman0579ed62017-08-29 15:56:192323 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:202324 rv = trans2->Start(&request2, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012325 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenke5f94fda2016-06-02 20:54:132326
2327 const HttpResponseInfo* response2 = trans2->GetResponseInfo();
2328 ASSERT_TRUE(response2);
2329 ASSERT_TRUE(response2->headers);
2330 EXPECT_EQ(200, response2->headers->response_code());
2331
2332 std::string response_data2;
robpercival214763f2016-07-01 23:27:012333 EXPECT_THAT(ReadTransaction(trans2.get(), &response_data2), IsOk());
mmenke5f94fda2016-06-02 20:54:132334 EXPECT_EQ("foo", response_data2);
2335}
2336
2337// This is a little different from the others - it tests the case that the
2338// HttpStreamParser doesn't know if there's extra data on a socket or not when
2339// the HttpNetworkTransaction is torn down, because the response body hasn't
2340// been read from yet, but the request goes through the HttpResponseBodyDrainer.
bncd16676a2016-07-20 16:23:012341TEST_F(HttpNetworkTransactionTest, KeepAliveWithUnusedData4) {
mmenke5f94fda2016-06-02 20:54:132342 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
2343 MockWrite data_writes1[] = {
2344 MockWrite("GET / HTTP/1.1\r\n"
2345 "Host: www.borked.com\r\n"
2346 "Connection: keep-alive\r\n\r\n"),
2347 };
2348
2349 MockRead data_reads1[] = {
2350 MockRead("HTTP/1.1 200 OK\r\n"
2351 "Connection: keep-alive\r\n"
2352 "Transfer-Encoding: chunked\r\n\r\n"),
2353 MockRead("16\r\nThis server is borked.\r\n"),
2354 MockRead("0\r\n\r\nBonus data!"),
2355 };
2356 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
2357 data_writes1, arraysize(data_writes1));
2358 session_deps_.socket_factory->AddSocketDataProvider(&data1);
2359
2360 TestCompletionCallback callback;
2361 HttpRequestInfo request1;
2362 request1.method = "GET";
2363 request1.url = GURL("http://www.borked.com/");
2364
bnc87dcefc2017-05-25 12:47:582365 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:192366 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
bnc87dcefc2017-05-25 12:47:582367 int rv = trans->Start(&request1, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012368 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenke5f94fda2016-06-02 20:54:132369
bnc87dcefc2017-05-25 12:47:582370 const HttpResponseInfo* response1 = trans->GetResponseInfo();
mmenke5f94fda2016-06-02 20:54:132371 ASSERT_TRUE(response1);
2372 ASSERT_TRUE(response1->headers);
2373 EXPECT_EQ(200, response1->headers->response_code());
2374 EXPECT_TRUE(response1->headers->IsKeepAlive());
2375
2376 // Deleting the transaction creates an HttpResponseBodyDrainer to read the
2377 // response body.
bnc87dcefc2017-05-25 12:47:582378 trans.reset();
mmenke5f94fda2016-06-02 20:54:132379
2380 // Let the HttpResponseBodyDrainer drain the socket. It should determine the
2381 // socket can't be reused, rather than returning it to the socket pool.
2382 base::RunLoop().RunUntilIdle();
2383
2384 // There should be no idle sockets in the pool.
2385 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
2386}
2387
[email protected]038e9a32008-10-08 22:40:162388// Test the request-challenge-retry sequence for basic auth.
2389// (basic auth is the easiest to mock, because it has no randomness).
bncd16676a2016-07-20 16:23:012390TEST_F(HttpNetworkTransactionTest, BasicAuth) {
[email protected]1c773ea12009-04-28 19:58:422391 HttpRequestInfo request;
[email protected]038e9a32008-10-08 22:40:162392 request.method = "GET";
bncce36dca22015-04-21 22:11:232393 request.url = GURL("http://www.example.org/");
[email protected]038e9a32008-10-08 22:40:162394
vishal.b62985ca92015-04-17 08:45:512395 TestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:072396 session_deps_.net_log = &log;
danakj1fd259a02016-04-16 03:17:092397 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:162398 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:272399
[email protected]f9ee6b52008-11-08 06:46:232400 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:232401 MockWrite(
2402 "GET / HTTP/1.1\r\n"
2403 "Host: www.example.org\r\n"
2404 "Connection: keep-alive\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:232405 };
2406
[email protected]038e9a32008-10-08 22:40:162407 MockRead data_reads1[] = {
2408 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
2409 // Give a couple authenticate options (only the middle one is actually
2410 // supported).
[email protected]22927ad2009-09-21 19:56:192411 MockRead("WWW-Authenticate: Basic invalid\r\n"), // Malformed.
[email protected]038e9a32008-10-08 22:40:162412 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2413 MockRead("WWW-Authenticate: UNSUPPORTED realm=\"FOO\"\r\n"),
2414 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
2415 // Large content-length -- won't matter, as connection will be reset.
2416 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:062417 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]038e9a32008-10-08 22:40:162418 };
2419
2420 // After calling trans->RestartWithAuth(), this is the request we should
2421 // be issuing -- the final header line contains the credentials.
2422 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:232423 MockWrite(
2424 "GET / HTTP/1.1\r\n"
2425 "Host: www.example.org\r\n"
2426 "Connection: keep-alive\r\n"
2427 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]038e9a32008-10-08 22:40:162428 };
2429
2430 // Lastly, the server responds with the actual content.
2431 MockRead data_reads2[] = {
2432 MockRead("HTTP/1.0 200 OK\r\n"),
2433 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
2434 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:062435 MockRead(SYNCHRONOUS, OK),
[email protected]038e9a32008-10-08 22:40:162436 };
2437
[email protected]31a2bfe2010-02-09 08:03:392438 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
2439 data_writes1, arraysize(data_writes1));
2440 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
2441 data_writes2, arraysize(data_writes2));
[email protected]bb88e1d32013-05-03 23:11:072442 session_deps_.socket_factory->AddSocketDataProvider(&data1);
2443 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]038e9a32008-10-08 22:40:162444
[email protected]49639fa2011-12-20 23:22:412445 TestCompletionCallback callback1;
[email protected]038e9a32008-10-08 22:40:162446
tfarina42834112016-09-22 13:38:202447 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012448 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]038e9a32008-10-08 22:40:162449
2450 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:012451 EXPECT_THAT(rv, IsOk());
[email protected]038e9a32008-10-08 22:40:162452
[email protected]58e32bb2013-01-21 18:23:252453 LoadTimingInfo load_timing_info1;
bnc691fda62016-08-12 00:43:162454 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info1));
[email protected]58e32bb2013-01-21 18:23:252455 TestLoadTimingNotReused(load_timing_info1, CONNECT_TIMING_HAS_DNS_TIMES);
2456
sclittlefb249892015-09-10 21:33:222457 int64_t writes_size1 = CountWriteBytes(data_writes1, arraysize(data_writes1));
bnc691fda62016-08-12 00:43:162458 EXPECT_EQ(writes_size1, trans.GetTotalSentBytes());
sclittlefb249892015-09-10 21:33:222459 int64_t reads_size1 = CountReadBytes(data_reads1, arraysize(data_reads1));
bnc691fda62016-08-12 00:43:162460 EXPECT_EQ(reads_size1, trans.GetTotalReceivedBytes());
[email protected]b8015c42013-12-24 15:18:192461
bnc691fda62016-08-12 00:43:162462 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:522463 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:042464 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]038e9a32008-10-08 22:40:162465
[email protected]49639fa2011-12-20 23:22:412466 TestCompletionCallback callback2;
[email protected]038e9a32008-10-08 22:40:162467
bnc691fda62016-08-12 00:43:162468 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar), callback2.callback());
robpercival214763f2016-07-01 23:27:012469 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]038e9a32008-10-08 22:40:162470
2471 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:012472 EXPECT_THAT(rv, IsOk());
[email protected]038e9a32008-10-08 22:40:162473
[email protected]58e32bb2013-01-21 18:23:252474 LoadTimingInfo load_timing_info2;
bnc691fda62016-08-12 00:43:162475 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info2));
[email protected]58e32bb2013-01-21 18:23:252476 TestLoadTimingNotReused(load_timing_info2, CONNECT_TIMING_HAS_DNS_TIMES);
2477 // The load timing after restart should have a new socket ID, and times after
2478 // those of the first load timing.
2479 EXPECT_LE(load_timing_info1.receive_headers_end,
2480 load_timing_info2.connect_timing.connect_start);
2481 EXPECT_NE(load_timing_info1.socket_log_id, load_timing_info2.socket_log_id);
2482
sclittlefb249892015-09-10 21:33:222483 int64_t writes_size2 = CountWriteBytes(data_writes2, arraysize(data_writes2));
bnc691fda62016-08-12 00:43:162484 EXPECT_EQ(writes_size1 + writes_size2, trans.GetTotalSentBytes());
sclittlefb249892015-09-10 21:33:222485 int64_t reads_size2 = CountReadBytes(data_reads2, arraysize(data_reads2));
bnc691fda62016-08-12 00:43:162486 EXPECT_EQ(reads_size1 + reads_size2, trans.GetTotalReceivedBytes());
[email protected]b8015c42013-12-24 15:18:192487
bnc691fda62016-08-12 00:43:162488 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:522489 ASSERT_TRUE(response);
2490 EXPECT_FALSE(response->auth_challenge);
[email protected]038e9a32008-10-08 22:40:162491 EXPECT_EQ(100, response->headers->GetContentLength());
[email protected]038e9a32008-10-08 22:40:162492}
2493
ttuttled9dbc652015-09-29 20:00:592494// Test the request-challenge-retry sequence for basic auth.
2495// (basic auth is the easiest to mock, because it has no randomness).
bncd16676a2016-07-20 16:23:012496TEST_F(HttpNetworkTransactionTest, BasicAuthWithAddressChange) {
ttuttled9dbc652015-09-29 20:00:592497 HttpRequestInfo request;
2498 request.method = "GET";
2499 request.url = GURL("http://www.example.org/");
ttuttled9dbc652015-09-29 20:00:592500
2501 TestNetLog log;
2502 MockHostResolver* resolver = new MockHostResolver();
2503 session_deps_.net_log = &log;
2504 session_deps_.host_resolver.reset(resolver);
danakj1fd259a02016-04-16 03:17:092505 std::unique_ptr<HttpNetworkSession> session = CreateSession(&session_deps_);
bnc691fda62016-08-12 00:43:162506 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
ttuttled9dbc652015-09-29 20:00:592507
2508 resolver->rules()->ClearRules();
2509 resolver->rules()->AddRule("www.example.org", "127.0.0.1");
2510
2511 MockWrite data_writes1[] = {
2512 MockWrite("GET / HTTP/1.1\r\n"
2513 "Host: www.example.org\r\n"
2514 "Connection: keep-alive\r\n\r\n"),
2515 };
2516
2517 MockRead data_reads1[] = {
2518 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
2519 // Give a couple authenticate options (only the middle one is actually
2520 // supported).
2521 MockRead("WWW-Authenticate: Basic invalid\r\n"), // Malformed.
2522 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2523 MockRead("WWW-Authenticate: UNSUPPORTED realm=\"FOO\"\r\n"),
2524 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
2525 // Large content-length -- won't matter, as connection will be reset.
2526 MockRead("Content-Length: 10000\r\n\r\n"),
2527 MockRead(SYNCHRONOUS, ERR_FAILED),
2528 };
2529
2530 // After calling trans->RestartWithAuth(), this is the request we should
2531 // be issuing -- the final header line contains the credentials.
2532 MockWrite data_writes2[] = {
2533 MockWrite("GET / HTTP/1.1\r\n"
2534 "Host: www.example.org\r\n"
2535 "Connection: keep-alive\r\n"
2536 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
2537 };
2538
2539 // Lastly, the server responds with the actual content.
2540 MockRead data_reads2[] = {
2541 MockRead("HTTP/1.0 200 OK\r\n"),
2542 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
2543 MockRead("Content-Length: 100\r\n\r\n"), MockRead(SYNCHRONOUS, OK),
2544 };
2545
2546 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
2547 data_writes1, arraysize(data_writes1));
2548 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
2549 data_writes2, arraysize(data_writes2));
2550 session_deps_.socket_factory->AddSocketDataProvider(&data1);
2551 session_deps_.socket_factory->AddSocketDataProvider(&data2);
2552
2553 TestCompletionCallback callback1;
2554
bnc691fda62016-08-12 00:43:162555 EXPECT_EQ(OK, callback1.GetResult(trans.Start(&request, callback1.callback(),
tfarina42834112016-09-22 13:38:202556 NetLogWithSource())));
ttuttled9dbc652015-09-29 20:00:592557
2558 LoadTimingInfo load_timing_info1;
bnc691fda62016-08-12 00:43:162559 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info1));
ttuttled9dbc652015-09-29 20:00:592560 TestLoadTimingNotReused(load_timing_info1, CONNECT_TIMING_HAS_DNS_TIMES);
2561
2562 int64_t writes_size1 = CountWriteBytes(data_writes1, arraysize(data_writes1));
bnc691fda62016-08-12 00:43:162563 EXPECT_EQ(writes_size1, trans.GetTotalSentBytes());
ttuttled9dbc652015-09-29 20:00:592564 int64_t reads_size1 = CountReadBytes(data_reads1, arraysize(data_reads1));
bnc691fda62016-08-12 00:43:162565 EXPECT_EQ(reads_size1, trans.GetTotalReceivedBytes());
ttuttled9dbc652015-09-29 20:00:592566
bnc691fda62016-08-12 00:43:162567 const HttpResponseInfo* response = trans.GetResponseInfo();
ttuttled9dbc652015-09-29 20:00:592568 ASSERT_TRUE(response);
2569 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
2570
2571 IPEndPoint endpoint;
bnc691fda62016-08-12 00:43:162572 EXPECT_TRUE(trans.GetRemoteEndpoint(&endpoint));
ttuttled9dbc652015-09-29 20:00:592573 ASSERT_FALSE(endpoint.address().empty());
2574 EXPECT_EQ("127.0.0.1:80", endpoint.ToString());
2575
2576 resolver->rules()->ClearRules();
2577 resolver->rules()->AddRule("www.example.org", "127.0.0.2");
2578
2579 TestCompletionCallback callback2;
2580
bnc691fda62016-08-12 00:43:162581 EXPECT_EQ(OK, callback2.GetResult(trans.RestartWithAuth(
ttuttled9dbc652015-09-29 20:00:592582 AuthCredentials(kFoo, kBar), callback2.callback())));
2583
2584 LoadTimingInfo load_timing_info2;
bnc691fda62016-08-12 00:43:162585 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info2));
ttuttled9dbc652015-09-29 20:00:592586 TestLoadTimingNotReused(load_timing_info2, CONNECT_TIMING_HAS_DNS_TIMES);
2587 // The load timing after restart should have a new socket ID, and times after
2588 // those of the first load timing.
2589 EXPECT_LE(load_timing_info1.receive_headers_end,
2590 load_timing_info2.connect_timing.connect_start);
2591 EXPECT_NE(load_timing_info1.socket_log_id, load_timing_info2.socket_log_id);
2592
2593 int64_t writes_size2 = CountWriteBytes(data_writes2, arraysize(data_writes2));
bnc691fda62016-08-12 00:43:162594 EXPECT_EQ(writes_size1 + writes_size2, trans.GetTotalSentBytes());
ttuttled9dbc652015-09-29 20:00:592595 int64_t reads_size2 = CountReadBytes(data_reads2, arraysize(data_reads2));
bnc691fda62016-08-12 00:43:162596 EXPECT_EQ(reads_size1 + reads_size2, trans.GetTotalReceivedBytes());
ttuttled9dbc652015-09-29 20:00:592597
bnc691fda62016-08-12 00:43:162598 response = trans.GetResponseInfo();
ttuttled9dbc652015-09-29 20:00:592599 ASSERT_TRUE(response);
wezca1070932016-05-26 20:30:522600 EXPECT_FALSE(response->auth_challenge);
ttuttled9dbc652015-09-29 20:00:592601 EXPECT_EQ(100, response->headers->GetContentLength());
2602
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.2:80", endpoint.ToString());
2606}
2607
bncd16676a2016-07-20 16:23:012608TEST_F(HttpNetworkTransactionTest, DoNotSendAuth) {
[email protected]861fcd52009-08-26 02:33:462609 HttpRequestInfo request;
2610 request.method = "GET";
bncce36dca22015-04-21 22:11:232611 request.url = GURL("http://www.example.org/");
ttuttle859dc7a2015-04-23 19:42:292612 request.load_flags = LOAD_DO_NOT_SEND_AUTH_DATA;
[email protected]861fcd52009-08-26 02:33:462613
danakj1fd259a02016-04-16 03:17:092614 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:162615 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:272616
[email protected]861fcd52009-08-26 02:33:462617 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:232618 MockWrite(
2619 "GET / HTTP/1.1\r\n"
2620 "Host: www.example.org\r\n"
2621 "Connection: keep-alive\r\n\r\n"),
[email protected]861fcd52009-08-26 02:33:462622 };
2623
2624 MockRead data_reads[] = {
2625 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
2626 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2627 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
2628 // Large content-length -- won't matter, as connection will be reset.
2629 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:062630 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]861fcd52009-08-26 02:33:462631 };
2632
[email protected]31a2bfe2010-02-09 08:03:392633 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
2634 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:072635 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]49639fa2011-12-20 23:22:412636 TestCompletionCallback callback;
[email protected]861fcd52009-08-26 02:33:462637
tfarina42834112016-09-22 13:38:202638 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012639 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]861fcd52009-08-26 02:33:462640
2641 rv = callback.WaitForResult();
2642 EXPECT_EQ(0, rv);
2643
sclittlefb249892015-09-10 21:33:222644 int64_t writes_size = CountWriteBytes(data_writes, arraysize(data_writes));
bnc691fda62016-08-12 00:43:162645 EXPECT_EQ(writes_size, trans.GetTotalSentBytes());
sclittlefb249892015-09-10 21:33:222646 int64_t reads_size = CountReadBytes(data_reads, arraysize(data_reads));
bnc691fda62016-08-12 00:43:162647 EXPECT_EQ(reads_size, trans.GetTotalReceivedBytes());
[email protected]b8015c42013-12-24 15:18:192648
bnc691fda62016-08-12 00:43:162649 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:522650 ASSERT_TRUE(response);
2651 EXPECT_FALSE(response->auth_challenge);
[email protected]861fcd52009-08-26 02:33:462652}
2653
[email protected]2d2697f92009-02-18 21:00:322654// Test the request-challenge-retry sequence for basic auth, over a keep-alive
2655// connection.
bncd16676a2016-07-20 16:23:012656TEST_F(HttpNetworkTransactionTest, BasicAuthKeepAlive) {
mmenkecc2298e2015-12-07 18:20:182657 // On the second pass, the body read of the auth challenge is synchronous, so
2658 // IsConnectedAndIdle returns false. The socket should still be drained and
2659 // reused. See http://crbug.com/544255.
2660 for (int i = 0; i < 2; ++i) {
2661 HttpRequestInfo request;
2662 request.method = "GET";
2663 request.url = GURL("http://www.example.org/");
[email protected]2d2697f92009-02-18 21:00:322664
mmenkecc2298e2015-12-07 18:20:182665 TestNetLog log;
2666 session_deps_.net_log = &log;
danakj1fd259a02016-04-16 03:17:092667 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:272668
mmenkecc2298e2015-12-07 18:20:182669 MockWrite data_writes[] = {
2670 MockWrite(ASYNC, 0,
2671 "GET / HTTP/1.1\r\n"
2672 "Host: www.example.org\r\n"
2673 "Connection: keep-alive\r\n\r\n"),
[email protected]2d2697f92009-02-18 21:00:322674
bnc691fda62016-08-12 00:43:162675 // After calling trans.RestartWithAuth(), this is the request we should
mmenkecc2298e2015-12-07 18:20:182676 // be issuing -- the final header line contains the credentials.
2677 MockWrite(ASYNC, 6,
2678 "GET / HTTP/1.1\r\n"
2679 "Host: www.example.org\r\n"
2680 "Connection: keep-alive\r\n"
2681 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
2682 };
[email protected]2d2697f92009-02-18 21:00:322683
mmenkecc2298e2015-12-07 18:20:182684 MockRead data_reads[] = {
2685 MockRead(ASYNC, 1, "HTTP/1.1 401 Unauthorized\r\n"),
2686 MockRead(ASYNC, 2, "WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2687 MockRead(ASYNC, 3, "Content-Type: text/html; charset=iso-8859-1\r\n"),
2688 MockRead(ASYNC, 4, "Content-Length: 14\r\n\r\n"),
2689 MockRead(i == 0 ? ASYNC : SYNCHRONOUS, 5, "Unauthorized\r\n"),
[email protected]2d2697f92009-02-18 21:00:322690
mmenkecc2298e2015-12-07 18:20:182691 // Lastly, the server responds with the actual content.
2692 MockRead(ASYNC, 7, "HTTP/1.1 200 OK\r\n"),
2693 MockRead(ASYNC, 8, "Content-Type: text/html; charset=iso-8859-1\r\n"),
2694 MockRead(ASYNC, 9, "Content-Length: 5\r\n\r\n"),
2695 MockRead(ASYNC, 10, "Hello"),
2696 };
[email protected]2d2697f92009-02-18 21:00:322697
mmenkecc2298e2015-12-07 18:20:182698 SequencedSocketData data(data_reads, arraysize(data_reads), data_writes,
2699 arraysize(data_writes));
2700 data.set_busy_before_sync_reads(true);
2701 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]2d0a4f92011-05-05 16:38:462702
mmenkecc2298e2015-12-07 18:20:182703 TestCompletionCallback callback1;
[email protected]2d2697f92009-02-18 21:00:322704
bnc691fda62016-08-12 00:43:162705 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:202706 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012707 ASSERT_THAT(callback1.GetResult(rv), IsOk());
[email protected]2d2697f92009-02-18 21:00:322708
mmenkecc2298e2015-12-07 18:20:182709 LoadTimingInfo load_timing_info1;
bnc691fda62016-08-12 00:43:162710 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info1));
mmenkecc2298e2015-12-07 18:20:182711 TestLoadTimingNotReused(load_timing_info1, CONNECT_TIMING_HAS_DNS_TIMES);
[email protected]2d2697f92009-02-18 21:00:322712
bnc691fda62016-08-12 00:43:162713 const HttpResponseInfo* response = trans.GetResponseInfo();
mmenkecc2298e2015-12-07 18:20:182714 ASSERT_TRUE(response);
2715 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]2d2697f92009-02-18 21:00:322716
mmenkecc2298e2015-12-07 18:20:182717 TestCompletionCallback callback2;
[email protected]58e32bb2013-01-21 18:23:252718
bnc691fda62016-08-12 00:43:162719 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar),
2720 callback2.callback());
robpercival214763f2016-07-01 23:27:012721 ASSERT_THAT(callback2.GetResult(rv), IsOk());
[email protected]2d2697f92009-02-18 21:00:322722
mmenkecc2298e2015-12-07 18:20:182723 LoadTimingInfo load_timing_info2;
bnc691fda62016-08-12 00:43:162724 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info2));
mmenkecc2298e2015-12-07 18:20:182725 TestLoadTimingReused(load_timing_info2);
2726 // The load timing after restart should have the same socket ID, and times
2727 // those of the first load timing.
2728 EXPECT_LE(load_timing_info1.receive_headers_end,
2729 load_timing_info2.send_start);
2730 EXPECT_EQ(load_timing_info1.socket_log_id, load_timing_info2.socket_log_id);
[email protected]2d2697f92009-02-18 21:00:322731
bnc691fda62016-08-12 00:43:162732 response = trans.GetResponseInfo();
mmenkecc2298e2015-12-07 18:20:182733 ASSERT_TRUE(response);
2734 EXPECT_FALSE(response->auth_challenge);
2735 EXPECT_EQ(5, response->headers->GetContentLength());
[email protected]2d2697f92009-02-18 21:00:322736
mmenkecc2298e2015-12-07 18:20:182737 std::string response_data;
bnc691fda62016-08-12 00:43:162738 EXPECT_THAT(ReadTransaction(&trans, &response_data), IsOk());
[email protected]2d2697f92009-02-18 21:00:322739
mmenkecc2298e2015-12-07 18:20:182740 int64_t writes_size = CountWriteBytes(data_writes, arraysize(data_writes));
bnc691fda62016-08-12 00:43:162741 EXPECT_EQ(writes_size, trans.GetTotalSentBytes());
mmenkecc2298e2015-12-07 18:20:182742 int64_t reads_size = CountReadBytes(data_reads, arraysize(data_reads));
bnc691fda62016-08-12 00:43:162743 EXPECT_EQ(reads_size, trans.GetTotalReceivedBytes());
mmenkecc2298e2015-12-07 18:20:182744 }
[email protected]2d2697f92009-02-18 21:00:322745}
2746
2747// Test the request-challenge-retry sequence for basic auth, over a keep-alive
2748// connection and with no response body to drain.
bncd16676a2016-07-20 16:23:012749TEST_F(HttpNetworkTransactionTest, BasicAuthKeepAliveNoBody) {
[email protected]1c773ea12009-04-28 19:58:422750 HttpRequestInfo request;
[email protected]2d2697f92009-02-18 21:00:322751 request.method = "GET";
bncce36dca22015-04-21 22:11:232752 request.url = GURL("http://www.example.org/");
[email protected]2d2697f92009-02-18 21:00:322753
danakj1fd259a02016-04-16 03:17:092754 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:272755
[email protected]2d2697f92009-02-18 21:00:322756 MockWrite data_writes1[] = {
bnc691fda62016-08-12 00:43:162757 MockWrite("GET / HTTP/1.1\r\n"
2758 "Host: www.example.org\r\n"
2759 "Connection: keep-alive\r\n\r\n"),
[email protected]2d2697f92009-02-18 21:00:322760
bnc691fda62016-08-12 00:43:162761 // After calling trans.RestartWithAuth(), this is the request we should
bncce36dca22015-04-21 22:11:232762 // be issuing -- the final header line contains the credentials.
bnc691fda62016-08-12 00:43:162763 MockWrite("GET / HTTP/1.1\r\n"
2764 "Host: www.example.org\r\n"
2765 "Connection: keep-alive\r\n"
2766 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]2d2697f92009-02-18 21:00:322767 };
2768
[email protected]2d2697f92009-02-18 21:00:322769 MockRead data_reads1[] = {
2770 MockRead("HTTP/1.1 401 Unauthorized\r\n"),
2771 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
[email protected]11203f012009-11-12 23:02:312772 MockRead("Content-Length: 0\r\n\r\n"), // No response body.
[email protected]2d2697f92009-02-18 21:00:322773
2774 // Lastly, the server responds with the actual content.
2775 MockRead("HTTP/1.1 200 OK\r\n"),
2776 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
[email protected]0b0bf032010-09-21 18:08:502777 MockRead("Content-Length: 5\r\n\r\n"),
2778 MockRead("hello"),
[email protected]2d2697f92009-02-18 21:00:322779 };
2780
[email protected]2d0a4f92011-05-05 16:38:462781 // An incorrect reconnect would cause this to be read.
2782 MockRead data_reads2[] = {
[email protected]8ddf8322012-02-23 18:08:062783 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]2d0a4f92011-05-05 16:38:462784 };
2785
[email protected]31a2bfe2010-02-09 08:03:392786 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
2787 data_writes1, arraysize(data_writes1));
[email protected]2d0a4f92011-05-05 16:38:462788 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
2789 NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:072790 session_deps_.socket_factory->AddSocketDataProvider(&data1);
2791 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]2d2697f92009-02-18 21:00:322792
[email protected]49639fa2011-12-20 23:22:412793 TestCompletionCallback callback1;
[email protected]2d2697f92009-02-18 21:00:322794
bnc691fda62016-08-12 00:43:162795 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:202796 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012797 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2d2697f92009-02-18 21:00:322798
2799 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:012800 EXPECT_THAT(rv, IsOk());
[email protected]2d2697f92009-02-18 21:00:322801
bnc691fda62016-08-12 00:43:162802 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:522803 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:042804 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]2d2697f92009-02-18 21:00:322805
[email protected]49639fa2011-12-20 23:22:412806 TestCompletionCallback callback2;
[email protected]2d2697f92009-02-18 21:00:322807
bnc691fda62016-08-12 00:43:162808 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar), callback2.callback());
robpercival214763f2016-07-01 23:27:012809 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2d2697f92009-02-18 21:00:322810
2811 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:012812 EXPECT_THAT(rv, IsOk());
[email protected]2d2697f92009-02-18 21:00:322813
bnc691fda62016-08-12 00:43:162814 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:522815 ASSERT_TRUE(response);
2816 EXPECT_FALSE(response->auth_challenge);
[email protected]0b0bf032010-09-21 18:08:502817 EXPECT_EQ(5, response->headers->GetContentLength());
[email protected]2d2697f92009-02-18 21:00:322818}
2819
2820// Test the request-challenge-retry sequence for basic auth, over a keep-alive
2821// connection and with a large response body to drain.
bncd16676a2016-07-20 16:23:012822TEST_F(HttpNetworkTransactionTest, BasicAuthKeepAliveLargeBody) {
[email protected]1c773ea12009-04-28 19:58:422823 HttpRequestInfo request;
[email protected]2d2697f92009-02-18 21:00:322824 request.method = "GET";
bncce36dca22015-04-21 22:11:232825 request.url = GURL("http://www.example.org/");
[email protected]2d2697f92009-02-18 21:00:322826
danakj1fd259a02016-04-16 03:17:092827 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:272828
[email protected]2d2697f92009-02-18 21:00:322829 MockWrite data_writes1[] = {
bnc691fda62016-08-12 00:43:162830 MockWrite("GET / HTTP/1.1\r\n"
2831 "Host: www.example.org\r\n"
2832 "Connection: keep-alive\r\n\r\n"),
[email protected]2d2697f92009-02-18 21:00:322833
bnc691fda62016-08-12 00:43:162834 // After calling trans.RestartWithAuth(), this is the request we should
bncce36dca22015-04-21 22:11:232835 // be issuing -- the final header line contains the credentials.
bnc691fda62016-08-12 00:43:162836 MockWrite("GET / HTTP/1.1\r\n"
2837 "Host: www.example.org\r\n"
2838 "Connection: keep-alive\r\n"
2839 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]2d2697f92009-02-18 21:00:322840 };
2841
2842 // Respond with 5 kb of response body.
2843 std::string large_body_string("Unauthorized");
2844 large_body_string.append(5 * 1024, ' ');
2845 large_body_string.append("\r\n");
2846
2847 MockRead data_reads1[] = {
2848 MockRead("HTTP/1.1 401 Unauthorized\r\n"),
2849 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2850 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
2851 // 5134 = 12 + 5 * 1024 + 2
2852 MockRead("Content-Length: 5134\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:062853 MockRead(ASYNC, large_body_string.data(), large_body_string.size()),
[email protected]2d2697f92009-02-18 21:00:322854
2855 // Lastly, the server responds with the actual content.
2856 MockRead("HTTP/1.1 200 OK\r\n"),
2857 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
[email protected]0b0bf032010-09-21 18:08:502858 MockRead("Content-Length: 5\r\n\r\n"),
2859 MockRead("hello"),
[email protected]2d2697f92009-02-18 21:00:322860 };
2861
[email protected]2d0a4f92011-05-05 16:38:462862 // An incorrect reconnect would cause this to be read.
2863 MockRead data_reads2[] = {
[email protected]8ddf8322012-02-23 18:08:062864 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]2d0a4f92011-05-05 16:38:462865 };
2866
[email protected]31a2bfe2010-02-09 08:03:392867 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
2868 data_writes1, arraysize(data_writes1));
[email protected]2d0a4f92011-05-05 16:38:462869 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
2870 NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:072871 session_deps_.socket_factory->AddSocketDataProvider(&data1);
2872 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]2d2697f92009-02-18 21:00:322873
[email protected]49639fa2011-12-20 23:22:412874 TestCompletionCallback callback1;
[email protected]2d2697f92009-02-18 21:00:322875
bnc691fda62016-08-12 00:43:162876 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:202877 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012878 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2d2697f92009-02-18 21:00:322879
2880 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:012881 EXPECT_THAT(rv, IsOk());
[email protected]2d2697f92009-02-18 21:00:322882
bnc691fda62016-08-12 00:43:162883 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:522884 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:042885 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]2d2697f92009-02-18 21:00:322886
[email protected]49639fa2011-12-20 23:22:412887 TestCompletionCallback callback2;
[email protected]2d2697f92009-02-18 21:00:322888
bnc691fda62016-08-12 00:43:162889 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar), callback2.callback());
robpercival214763f2016-07-01 23:27:012890 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2d2697f92009-02-18 21:00:322891
2892 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:012893 EXPECT_THAT(rv, IsOk());
[email protected]2d2697f92009-02-18 21:00:322894
bnc691fda62016-08-12 00:43:162895 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:522896 ASSERT_TRUE(response);
2897 EXPECT_FALSE(response->auth_challenge);
[email protected]0b0bf032010-09-21 18:08:502898 EXPECT_EQ(5, response->headers->GetContentLength());
[email protected]2d2697f92009-02-18 21:00:322899}
2900
2901// Test the request-challenge-retry sequence for basic auth, over a keep-alive
[email protected]11203f012009-11-12 23:02:312902// connection, but the server gets impatient and closes the connection.
bncd16676a2016-07-20 16:23:012903TEST_F(HttpNetworkTransactionTest, BasicAuthKeepAliveImpatientServer) {
[email protected]11203f012009-11-12 23:02:312904 HttpRequestInfo request;
2905 request.method = "GET";
bncce36dca22015-04-21 22:11:232906 request.url = GURL("http://www.example.org/");
[email protected]11203f012009-11-12 23:02:312907
danakj1fd259a02016-04-16 03:17:092908 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:272909
[email protected]11203f012009-11-12 23:02:312910 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:232911 MockWrite(
2912 "GET / HTTP/1.1\r\n"
2913 "Host: www.example.org\r\n"
2914 "Connection: keep-alive\r\n\r\n"),
2915 // This simulates the seemingly successful write to a closed connection
2916 // if the bug is not fixed.
2917 MockWrite(
2918 "GET / HTTP/1.1\r\n"
2919 "Host: www.example.org\r\n"
2920 "Connection: keep-alive\r\n"
2921 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]11203f012009-11-12 23:02:312922 };
2923
2924 MockRead data_reads1[] = {
2925 MockRead("HTTP/1.1 401 Unauthorized\r\n"),
2926 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2927 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
2928 MockRead("Content-Length: 14\r\n\r\n"),
2929 // Tell MockTCPClientSocket to simulate the server closing the connection.
[email protected]8ddf8322012-02-23 18:08:062930 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
[email protected]11203f012009-11-12 23:02:312931 MockRead("Unauthorized\r\n"),
[email protected]8ddf8322012-02-23 18:08:062932 MockRead(SYNCHRONOUS, OK), // The server closes the connection.
[email protected]11203f012009-11-12 23:02:312933 };
2934
bnc691fda62016-08-12 00:43:162935 // After calling trans.RestartWithAuth(), this is the request we should
[email protected]11203f012009-11-12 23:02:312936 // be issuing -- the final header line contains the credentials.
2937 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:232938 MockWrite(
2939 "GET / HTTP/1.1\r\n"
2940 "Host: www.example.org\r\n"
2941 "Connection: keep-alive\r\n"
2942 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]11203f012009-11-12 23:02:312943 };
2944
2945 // Lastly, the server responds with the actual content.
2946 MockRead data_reads2[] = {
2947 MockRead("HTTP/1.1 200 OK\r\n"),
2948 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
[email protected]0b0bf032010-09-21 18:08:502949 MockRead("Content-Length: 5\r\n\r\n"),
2950 MockRead("hello"),
[email protected]11203f012009-11-12 23:02:312951 };
2952
[email protected]31a2bfe2010-02-09 08:03:392953 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
2954 data_writes1, arraysize(data_writes1));
2955 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
2956 data_writes2, arraysize(data_writes2));
[email protected]bb88e1d32013-05-03 23:11:072957 session_deps_.socket_factory->AddSocketDataProvider(&data1);
2958 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]11203f012009-11-12 23:02:312959
[email protected]49639fa2011-12-20 23:22:412960 TestCompletionCallback callback1;
[email protected]11203f012009-11-12 23:02:312961
bnc691fda62016-08-12 00:43:162962 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:202963 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012964 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]11203f012009-11-12 23:02:312965
2966 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:012967 EXPECT_THAT(rv, IsOk());
[email protected]11203f012009-11-12 23:02:312968
bnc691fda62016-08-12 00:43:162969 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:522970 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:042971 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]11203f012009-11-12 23:02:312972
[email protected]49639fa2011-12-20 23:22:412973 TestCompletionCallback callback2;
[email protected]11203f012009-11-12 23:02:312974
bnc691fda62016-08-12 00:43:162975 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar), callback2.callback());
robpercival214763f2016-07-01 23:27:012976 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]11203f012009-11-12 23:02:312977
2978 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:012979 EXPECT_THAT(rv, IsOk());
[email protected]11203f012009-11-12 23:02:312980
bnc691fda62016-08-12 00:43:162981 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:522982 ASSERT_TRUE(response);
2983 EXPECT_FALSE(response->auth_challenge);
[email protected]0b0bf032010-09-21 18:08:502984 EXPECT_EQ(5, response->headers->GetContentLength());
[email protected]11203f012009-11-12 23:02:312985}
2986
[email protected]394816e92010-08-03 07:38:592987// Test the request-challenge-retry sequence for basic auth, over a connection
2988// that requires a restart when setting up an SSL tunnel.
bncd16676a2016-07-20 16:23:012989TEST_F(HttpNetworkTransactionTest, BasicAuthProxyNoKeepAliveHttp10) {
ttuttle34f63b52015-03-05 04:33:012990 HttpRequestInfo request;
2991 request.method = "GET";
bncce36dca22015-04-21 22:11:232992 request.url = GURL("https://www.example.org/");
ttuttle34f63b52015-03-05 04:33:012993 // when the no authentication data flag is set.
ttuttle859dc7a2015-04-23 19:42:292994 request.load_flags = LOAD_DO_NOT_SEND_AUTH_DATA;
ttuttle34f63b52015-03-05 04:33:012995
2996 // Configure against proxy server "myproxy:70".
rdsmith82957ad2015-09-16 19:42:032997 session_deps_.proxy_service =
2998 ProxyService::CreateFixedFromPacResult("PROXY myproxy:70");
vishal.b62985ca92015-04-17 08:45:512999 BoundTestNetLog log;
ttuttle34f63b52015-03-05 04:33:013000 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:093001 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
ttuttle34f63b52015-03-05 04:33:013002
3003 // Since we have proxy, should try to establish tunnel.
3004 MockWrite data_writes1[] = {
mmenkee71e15332015-10-07 16:39:543005 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:173006 "Host: www.example.org:443\r\n"
mmenkee71e15332015-10-07 16:39:543007 "Proxy-Connection: keep-alive\r\n\r\n"),
ttuttle34f63b52015-03-05 04:33:013008 };
3009
mmenkee71e15332015-10-07 16:39:543010 // The proxy responds to the connect with a 407, using a non-persistent
ttuttle34f63b52015-03-05 04:33:013011 // connection.
3012 MockRead data_reads1[] = {
3013 // No credentials.
3014 MockRead("HTTP/1.0 407 Proxy Authentication Required\r\n"),
3015 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n\r\n"),
mmenkee71e15332015-10-07 16:39:543016 };
ttuttle34f63b52015-03-05 04:33:013017
mmenkee71e15332015-10-07 16:39:543018 // Since the first connection couldn't be reused, need to establish another
3019 // once given credentials.
3020 MockWrite data_writes2[] = {
3021 // After calling trans->RestartWithAuth(), this is the request we should
3022 // be issuing -- the final header line contains the credentials.
3023 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:173024 "Host: www.example.org:443\r\n"
mmenkee71e15332015-10-07 16:39:543025 "Proxy-Connection: keep-alive\r\n"
3026 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
3027
3028 MockWrite("GET / HTTP/1.1\r\n"
3029 "Host: www.example.org\r\n"
3030 "Connection: keep-alive\r\n\r\n"),
3031 };
3032
3033 MockRead data_reads2[] = {
ttuttle34f63b52015-03-05 04:33:013034 MockRead("HTTP/1.0 200 Connection Established\r\n\r\n"),
3035
3036 MockRead("HTTP/1.1 200 OK\r\n"),
3037 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
3038 MockRead("Content-Length: 5\r\n\r\n"),
3039 MockRead(SYNCHRONOUS, "hello"),
3040 };
3041
3042 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
3043 data_writes1, arraysize(data_writes1));
3044 session_deps_.socket_factory->AddSocketDataProvider(&data1);
mmenkee71e15332015-10-07 16:39:543045 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
3046 data_writes2, arraysize(data_writes2));
3047 session_deps_.socket_factory->AddSocketDataProvider(&data2);
ttuttle34f63b52015-03-05 04:33:013048 SSLSocketDataProvider ssl(ASYNC, OK);
3049 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
3050
3051 TestCompletionCallback callback1;
3052
bnc87dcefc2017-05-25 12:47:583053 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:193054 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
ttuttle34f63b52015-03-05 04:33:013055
3056 int rv = trans->Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:013057 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
ttuttle34f63b52015-03-05 04:33:013058
3059 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:013060 EXPECT_THAT(rv, IsOk());
mmenke43758e62015-05-04 21:09:463061 TestNetLogEntry::List entries;
ttuttle34f63b52015-03-05 04:33:013062 log.GetEntries(&entries);
3063 size_t pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:003064 entries, 0, NetLogEventType::HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
3065 NetLogEventPhase::NONE);
ttuttle34f63b52015-03-05 04:33:013066 ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:003067 entries, pos,
3068 NetLogEventType::HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
3069 NetLogEventPhase::NONE);
ttuttle34f63b52015-03-05 04:33:013070
3071 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:523072 ASSERT_TRUE(response);
ttuttle34f63b52015-03-05 04:33:013073 EXPECT_FALSE(response->headers->IsKeepAlive());
wezca1070932016-05-26 20:30:523074 ASSERT_TRUE(response->headers);
ttuttle34f63b52015-03-05 04:33:013075 EXPECT_EQ(407, response->headers->response_code());
3076 EXPECT_TRUE(HttpVersion(1, 0) == response->headers->GetHttpVersion());
3077 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
3078
3079 LoadTimingInfo load_timing_info;
3080 // CONNECT requests and responses are handled at the connect job level, so
3081 // the transaction does not yet have a connection.
3082 EXPECT_FALSE(trans->GetLoadTimingInfo(&load_timing_info));
3083
3084 TestCompletionCallback callback2;
3085
3086 rv =
3087 trans->RestartWithAuth(AuthCredentials(kFoo, kBar), callback2.callback());
robpercival214763f2016-07-01 23:27:013088 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
ttuttle34f63b52015-03-05 04:33:013089
3090 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:013091 EXPECT_THAT(rv, IsOk());
ttuttle34f63b52015-03-05 04:33:013092
3093 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:523094 ASSERT_TRUE(response);
ttuttle34f63b52015-03-05 04:33:013095
3096 EXPECT_TRUE(response->headers->IsKeepAlive());
3097 EXPECT_EQ(200, response->headers->response_code());
3098 EXPECT_EQ(5, response->headers->GetContentLength());
3099 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
3100
3101 // The password prompt info should not be set.
wezca1070932016-05-26 20:30:523102 EXPECT_FALSE(response->auth_challenge);
ttuttle34f63b52015-03-05 04:33:013103
3104 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
3105 TestLoadTimingNotReusedWithPac(load_timing_info,
3106 CONNECT_TIMING_HAS_SSL_TIMES);
3107
3108 trans.reset();
3109 session->CloseAllConnections();
3110}
3111
3112// Test the request-challenge-retry sequence for basic auth, over a connection
3113// that requires a restart when setting up an SSL tunnel.
bncd16676a2016-07-20 16:23:013114TEST_F(HttpNetworkTransactionTest, BasicAuthProxyNoKeepAliveHttp11) {
[email protected]394816e92010-08-03 07:38:593115 HttpRequestInfo request;
3116 request.method = "GET";
bncce36dca22015-04-21 22:11:233117 request.url = GURL("https://www.example.org/");
[email protected]394816e92010-08-03 07:38:593118 // when the no authentication data flag is set.
ttuttle859dc7a2015-04-23 19:42:293119 request.load_flags = LOAD_DO_NOT_SEND_AUTH_DATA;
[email protected]394816e92010-08-03 07:38:593120
[email protected]cb9bf6ca2011-01-28 13:15:273121 // Configure against proxy server "myproxy:70".
rdsmith82957ad2015-09-16 19:42:033122 session_deps_.proxy_service =
3123 ProxyService::CreateFixedFromPacResult("PROXY myproxy:70");
vishal.b62985ca92015-04-17 08:45:513124 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:073125 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:093126 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:273127
[email protected]394816e92010-08-03 07:38:593128 // Since we have proxy, should try to establish tunnel.
3129 MockWrite data_writes1[] = {
mmenkee71e15332015-10-07 16:39:543130 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:173131 "Host: www.example.org:443\r\n"
mmenkee71e15332015-10-07 16:39:543132 "Proxy-Connection: keep-alive\r\n\r\n"),
mmenkee0b5c882015-08-26 20:29:113133 };
3134
mmenkee71e15332015-10-07 16:39:543135 // The proxy responds to the connect with a 407, using a non-persistent
mmenke0fd148d2015-09-30 23:00:083136 // connection.
3137 MockRead data_reads1[] = {
mmenkee71e15332015-10-07 16:39:543138 // No credentials.
3139 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
3140 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
3141 MockRead("Proxy-Connection: close\r\n\r\n"),
3142 };
mmenkee0b5c882015-08-26 20:29:113143
mmenkee71e15332015-10-07 16:39:543144 MockWrite data_writes2[] = {
3145 // After calling trans->RestartWithAuth(), this is the request we should
3146 // be issuing -- the final header line contains the credentials.
3147 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:173148 "Host: www.example.org:443\r\n"
mmenkee71e15332015-10-07 16:39:543149 "Proxy-Connection: keep-alive\r\n"
3150 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
mmenke0fd148d2015-09-30 23:00:083151
mmenkee71e15332015-10-07 16:39:543152 MockWrite("GET / HTTP/1.1\r\n"
3153 "Host: www.example.org\r\n"
3154 "Connection: keep-alive\r\n\r\n"),
3155 };
3156
3157 MockRead data_reads2[] = {
3158 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
3159
3160 MockRead("HTTP/1.1 200 OK\r\n"),
3161 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
3162 MockRead("Content-Length: 5\r\n\r\n"),
3163 MockRead(SYNCHRONOUS, "hello"),
[email protected]394816e92010-08-03 07:38:593164 };
3165
3166 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
3167 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:073168 session_deps_.socket_factory->AddSocketDataProvider(&data1);
mmenkee71e15332015-10-07 16:39:543169 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
3170 data_writes2, arraysize(data_writes2));
3171 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]8ddf8322012-02-23 18:08:063172 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:073173 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]394816e92010-08-03 07:38:593174
[email protected]49639fa2011-12-20 23:22:413175 TestCompletionCallback callback1;
[email protected]394816e92010-08-03 07:38:593176
bnc87dcefc2017-05-25 12:47:583177 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:193178 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]0b0bf032010-09-21 18:08:503179
[email protected]49639fa2011-12-20 23:22:413180 int rv = trans->Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:013181 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]394816e92010-08-03 07:38:593182
3183 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:013184 EXPECT_THAT(rv, IsOk());
mmenke43758e62015-05-04 21:09:463185 TestNetLogEntry::List entries;
[email protected]b2fcd0e2010-12-01 15:19:403186 log.GetEntries(&entries);
[email protected]394816e92010-08-03 07:38:593187 size_t pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:003188 entries, 0, NetLogEventType::HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
3189 NetLogEventPhase::NONE);
[email protected]394816e92010-08-03 07:38:593190 ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:403191 entries, pos,
mikecirone8b85c432016-09-08 19:11:003192 NetLogEventType::HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
3193 NetLogEventPhase::NONE);
[email protected]394816e92010-08-03 07:38:593194
3195 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:523196 ASSERT_TRUE(response);
ttuttle34f63b52015-03-05 04:33:013197 EXPECT_FALSE(response->headers->IsKeepAlive());
wezca1070932016-05-26 20:30:523198 ASSERT_TRUE(response->headers);
[email protected]394816e92010-08-03 07:38:593199 EXPECT_EQ(407, response->headers->response_code());
3200 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
[email protected]79cb5c12011-09-12 13:12:043201 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
[email protected]394816e92010-08-03 07:38:593202
[email protected]029c83b62013-01-24 05:28:203203 LoadTimingInfo load_timing_info;
3204 // CONNECT requests and responses are handled at the connect job level, so
3205 // the transaction does not yet have a connection.
3206 EXPECT_FALSE(trans->GetLoadTimingInfo(&load_timing_info));
3207
[email protected]49639fa2011-12-20 23:22:413208 TestCompletionCallback callback2;
[email protected]394816e92010-08-03 07:38:593209
[email protected]49639fa2011-12-20 23:22:413210 rv = trans->RestartWithAuth(
3211 AuthCredentials(kFoo, kBar), callback2.callback());
robpercival214763f2016-07-01 23:27:013212 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]394816e92010-08-03 07:38:593213
3214 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:013215 EXPECT_THAT(rv, IsOk());
[email protected]394816e92010-08-03 07:38:593216
3217 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:523218 ASSERT_TRUE(response);
[email protected]394816e92010-08-03 07:38:593219
3220 EXPECT_TRUE(response->headers->IsKeepAlive());
3221 EXPECT_EQ(200, response->headers->response_code());
[email protected]0b0bf032010-09-21 18:08:503222 EXPECT_EQ(5, response->headers->GetContentLength());
[email protected]394816e92010-08-03 07:38:593223 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
3224
3225 // The password prompt info should not be set.
wezca1070932016-05-26 20:30:523226 EXPECT_FALSE(response->auth_challenge);
[email protected]0b0bf032010-09-21 18:08:503227
[email protected]029c83b62013-01-24 05:28:203228 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
3229 TestLoadTimingNotReusedWithPac(load_timing_info,
3230 CONNECT_TIMING_HAS_SSL_TIMES);
3231
[email protected]0b0bf032010-09-21 18:08:503232 trans.reset();
[email protected]102e27c2011-02-23 01:01:313233 session->CloseAllConnections();
[email protected]394816e92010-08-03 07:38:593234}
3235
[email protected]11203f012009-11-12 23:02:313236// Test the request-challenge-retry sequence for basic auth, over a keep-alive
ttuttle34f63b52015-03-05 04:33:013237// proxy connection with HTTP/1.0 responses, when setting up an SSL tunnel.
bncd16676a2016-07-20 16:23:013238TEST_F(HttpNetworkTransactionTest, BasicAuthProxyKeepAliveHttp10) {
mmenked39192ee2015-12-09 00:57:233239 // On the second pass, the body read of the auth challenge is synchronous, so
3240 // IsConnectedAndIdle returns false. The socket should still be drained and
3241 // reused. See http://crbug.com/544255.
3242 for (int i = 0; i < 2; ++i) {
3243 HttpRequestInfo request;
3244 request.method = "GET";
3245 request.url = GURL("https://www.example.org/");
3246 // Ensure that proxy authentication is attempted even
3247 // when the no authentication data flag is set.
3248 request.load_flags = LOAD_DO_NOT_SEND_AUTH_DATA;
ttuttle34f63b52015-03-05 04:33:013249
mmenked39192ee2015-12-09 00:57:233250 // Configure against proxy server "myproxy:70".
3251 session_deps_.proxy_service = ProxyService::CreateFixed("myproxy:70");
3252 BoundTestNetLog log;
3253 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:093254 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
ttuttle34f63b52015-03-05 04:33:013255
bnc691fda62016-08-12 00:43:163256 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
ttuttle34f63b52015-03-05 04:33:013257
mmenked39192ee2015-12-09 00:57:233258 // Since we have proxy, should try to establish tunnel.
3259 MockWrite data_writes1[] = {
3260 MockWrite(ASYNC, 0,
3261 "CONNECT www.example.org:443 HTTP/1.1\r\n"
3262 "Host: www.example.org:443\r\n"
3263 "Proxy-Connection: keep-alive\r\n\r\n"),
ttuttle34f63b52015-03-05 04:33:013264
bnc691fda62016-08-12 00:43:163265 // After calling trans.RestartWithAuth(), this is the request we should
mmenked39192ee2015-12-09 00:57:233266 // be issuing -- the final header line contains the credentials.
3267 MockWrite(ASYNC, 3,
3268 "CONNECT www.example.org:443 HTTP/1.1\r\n"
3269 "Host: www.example.org:443\r\n"
3270 "Proxy-Connection: keep-alive\r\n"
3271 "Proxy-Authorization: Basic Zm9vOmJheg==\r\n\r\n"),
3272 };
ttuttle34f63b52015-03-05 04:33:013273
mmenked39192ee2015-12-09 00:57:233274 // The proxy responds to the connect with a 407, using a persistent
3275 // connection. (Since it's HTTP/1.0, keep-alive has to be explicit.)
3276 MockRead data_reads1[] = {
3277 // No credentials.
3278 MockRead(ASYNC, 1,
3279 "HTTP/1.0 407 Proxy Authentication Required\r\n"
3280 "Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"
3281 "Proxy-Connection: keep-alive\r\n"
3282 "Content-Length: 10\r\n\r\n"),
3283 MockRead(i == 0 ? ASYNC : SYNCHRONOUS, 2, "0123456789"),
ttuttle34f63b52015-03-05 04:33:013284
mmenked39192ee2015-12-09 00:57:233285 // Wrong credentials (wrong password).
3286 MockRead(ASYNC, 4,
3287 "HTTP/1.0 407 Proxy Authentication Required\r\n"
3288 "Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"
3289 "Proxy-Connection: keep-alive\r\n"
3290 "Content-Length: 10\r\n\r\n"),
3291 // No response body because the test stops reading here.
3292 MockRead(SYNCHRONOUS, ERR_UNEXPECTED, 5),
3293 };
ttuttle34f63b52015-03-05 04:33:013294
mmenked39192ee2015-12-09 00:57:233295 SequencedSocketData data1(data_reads1, arraysize(data_reads1), data_writes1,
3296 arraysize(data_writes1));
3297 data1.set_busy_before_sync_reads(true);
3298 session_deps_.socket_factory->AddSocketDataProvider(&data1);
ttuttle34f63b52015-03-05 04:33:013299
mmenked39192ee2015-12-09 00:57:233300 TestCompletionCallback callback1;
ttuttle34f63b52015-03-05 04:33:013301
bnc691fda62016-08-12 00:43:163302 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:013303 EXPECT_THAT(callback1.GetResult(rv), IsOk());
ttuttle34f63b52015-03-05 04:33:013304
mmenked39192ee2015-12-09 00:57:233305 TestNetLogEntry::List entries;
3306 log.GetEntries(&entries);
3307 size_t pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:003308 entries, 0, NetLogEventType::HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
3309 NetLogEventPhase::NONE);
mmenked39192ee2015-12-09 00:57:233310 ExpectLogContainsSomewhere(
3311 entries, pos,
mikecirone8b85c432016-09-08 19:11:003312 NetLogEventType::HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
3313 NetLogEventPhase::NONE);
ttuttle34f63b52015-03-05 04:33:013314
bnc691fda62016-08-12 00:43:163315 const HttpResponseInfo* response = trans.GetResponseInfo();
mmenked39192ee2015-12-09 00:57:233316 ASSERT_TRUE(response);
3317 ASSERT_TRUE(response->headers);
3318 EXPECT_TRUE(response->headers->IsKeepAlive());
3319 EXPECT_EQ(407, response->headers->response_code());
3320 EXPECT_EQ(10, response->headers->GetContentLength());
3321 EXPECT_TRUE(HttpVersion(1, 0) == response->headers->GetHttpVersion());
3322 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
ttuttle34f63b52015-03-05 04:33:013323
mmenked39192ee2015-12-09 00:57:233324 TestCompletionCallback callback2;
ttuttle34f63b52015-03-05 04:33:013325
mmenked39192ee2015-12-09 00:57:233326 // Wrong password (should be "bar").
bnc691fda62016-08-12 00:43:163327 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBaz),
3328 callback2.callback());
robpercival214763f2016-07-01 23:27:013329 EXPECT_THAT(callback2.GetResult(rv), IsOk());
ttuttle34f63b52015-03-05 04:33:013330
bnc691fda62016-08-12 00:43:163331 response = trans.GetResponseInfo();
mmenked39192ee2015-12-09 00:57:233332 ASSERT_TRUE(response);
3333 ASSERT_TRUE(response->headers);
3334 EXPECT_TRUE(response->headers->IsKeepAlive());
3335 EXPECT_EQ(407, response->headers->response_code());
3336 EXPECT_EQ(10, response->headers->GetContentLength());
3337 EXPECT_TRUE(HttpVersion(1, 0) == response->headers->GetHttpVersion());
3338 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
ttuttle34f63b52015-03-05 04:33:013339
mmenked39192ee2015-12-09 00:57:233340 // Flush the idle socket before the NetLog and HttpNetworkTransaction go
3341 // out of scope.
3342 session->CloseAllConnections();
3343 }
ttuttle34f63b52015-03-05 04:33:013344}
3345
3346// Test the request-challenge-retry sequence for basic auth, over a keep-alive
3347// proxy connection with HTTP/1.1 responses, when setting up an SSL tunnel.
bncd16676a2016-07-20 16:23:013348TEST_F(HttpNetworkTransactionTest, BasicAuthProxyKeepAliveHttp11) {
mmenked39192ee2015-12-09 00:57:233349 // On the second pass, the body read of the auth challenge is synchronous, so
3350 // IsConnectedAndIdle returns false. The socket should still be drained and
3351 // reused. See http://crbug.com/544255.
3352 for (int i = 0; i < 2; ++i) {
3353 HttpRequestInfo request;
3354 request.method = "GET";
3355 request.url = GURL("https://www.example.org/");
3356 // Ensure that proxy authentication is attempted even
3357 // when the no authentication data flag is set.
3358 request.load_flags = LOAD_DO_NOT_SEND_AUTH_DATA;
3359
3360 // Configure against proxy server "myproxy:70".
3361 session_deps_.proxy_service = ProxyService::CreateFixed("myproxy:70");
3362 BoundTestNetLog log;
3363 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:093364 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
mmenked39192ee2015-12-09 00:57:233365
bnc691fda62016-08-12 00:43:163366 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
mmenked39192ee2015-12-09 00:57:233367
3368 // Since we have proxy, should try to establish tunnel.
3369 MockWrite data_writes1[] = {
3370 MockWrite(ASYNC, 0,
3371 "CONNECT www.example.org:443 HTTP/1.1\r\n"
3372 "Host: www.example.org:443\r\n"
3373 "Proxy-Connection: keep-alive\r\n\r\n"),
3374
bnc691fda62016-08-12 00:43:163375 // After calling trans.RestartWithAuth(), this is the request we should
mmenked39192ee2015-12-09 00:57:233376 // be issuing -- the final header line contains the credentials.
3377 MockWrite(ASYNC, 3,
3378 "CONNECT www.example.org:443 HTTP/1.1\r\n"
3379 "Host: www.example.org:443\r\n"
3380 "Proxy-Connection: keep-alive\r\n"
3381 "Proxy-Authorization: Basic Zm9vOmJheg==\r\n\r\n"),
3382 };
3383
3384 // The proxy responds to the connect with a 407, using a persistent
3385 // connection. (Since it's HTTP/1.0, keep-alive has to be explicit.)
3386 MockRead data_reads1[] = {
3387 // No credentials.
3388 MockRead(ASYNC, 1,
3389 "HTTP/1.1 407 Proxy Authentication Required\r\n"
3390 "Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"
3391 "Content-Length: 10\r\n\r\n"),
3392 MockRead(i == 0 ? ASYNC : SYNCHRONOUS, 2, "0123456789"),
3393
3394 // Wrong credentials (wrong password).
3395 MockRead(ASYNC, 4,
3396 "HTTP/1.1 407 Proxy Authentication Required\r\n"
3397 "Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"
3398 "Content-Length: 10\r\n\r\n"),
3399 // No response body because the test stops reading here.
3400 MockRead(SYNCHRONOUS, ERR_UNEXPECTED, 5),
3401 };
3402
3403 SequencedSocketData data1(data_reads1, arraysize(data_reads1), data_writes1,
3404 arraysize(data_writes1));
3405 data1.set_busy_before_sync_reads(true);
3406 session_deps_.socket_factory->AddSocketDataProvider(&data1);
3407
3408 TestCompletionCallback callback1;
3409
bnc691fda62016-08-12 00:43:163410 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:013411 EXPECT_THAT(callback1.GetResult(rv), IsOk());
mmenked39192ee2015-12-09 00:57:233412
3413 TestNetLogEntry::List entries;
3414 log.GetEntries(&entries);
3415 size_t pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:003416 entries, 0, NetLogEventType::HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
3417 NetLogEventPhase::NONE);
mmenked39192ee2015-12-09 00:57:233418 ExpectLogContainsSomewhere(
3419 entries, pos,
mikecirone8b85c432016-09-08 19:11:003420 NetLogEventType::HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
3421 NetLogEventPhase::NONE);
mmenked39192ee2015-12-09 00:57:233422
bnc691fda62016-08-12 00:43:163423 const HttpResponseInfo* response = trans.GetResponseInfo();
mmenked39192ee2015-12-09 00:57:233424 ASSERT_TRUE(response);
3425 ASSERT_TRUE(response->headers);
3426 EXPECT_TRUE(response->headers->IsKeepAlive());
3427 EXPECT_EQ(407, response->headers->response_code());
3428 EXPECT_EQ(10, response->headers->GetContentLength());
3429 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
3430 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
3431
3432 TestCompletionCallback callback2;
3433
3434 // Wrong password (should be "bar").
bnc691fda62016-08-12 00:43:163435 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBaz),
3436 callback2.callback());
robpercival214763f2016-07-01 23:27:013437 EXPECT_THAT(callback2.GetResult(rv), IsOk());
mmenked39192ee2015-12-09 00:57:233438
bnc691fda62016-08-12 00:43:163439 response = trans.GetResponseInfo();
mmenked39192ee2015-12-09 00:57:233440 ASSERT_TRUE(response);
3441 ASSERT_TRUE(response->headers);
3442 EXPECT_TRUE(response->headers->IsKeepAlive());
3443 EXPECT_EQ(407, response->headers->response_code());
3444 EXPECT_EQ(10, response->headers->GetContentLength());
3445 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
3446 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
3447
3448 // Flush the idle socket before the NetLog and HttpNetworkTransaction go
3449 // out of scope.
3450 session->CloseAllConnections();
3451 }
3452}
3453
3454// Test the request-challenge-retry sequence for basic auth, over a keep-alive
3455// proxy connection with HTTP/1.1 responses, when setting up an SSL tunnel, in
3456// the case the server sends extra data on the original socket, so it can't be
3457// reused.
bncd16676a2016-07-20 16:23:013458TEST_F(HttpNetworkTransactionTest, BasicAuthProxyKeepAliveExtraData) {
[email protected]cb9bf6ca2011-01-28 13:15:273459 HttpRequestInfo request;
3460 request.method = "GET";
bncce36dca22015-04-21 22:11:233461 request.url = GURL("https://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:273462 // when the no authentication data flag is set.
ttuttle859dc7a2015-04-23 19:42:293463 request.load_flags = LOAD_DO_NOT_SEND_AUTH_DATA;
[email protected]cb9bf6ca2011-01-28 13:15:273464
[email protected]2d2697f92009-02-18 21:00:323465 // Configure against proxy server "myproxy:70".
mmenked39192ee2015-12-09 00:57:233466 session_deps_.proxy_service =
3467 ProxyService::CreateFixedFromPacResult("PROXY myproxy:70");
vishal.b62985ca92015-04-17 08:45:513468 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:073469 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:093470 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]2d2697f92009-02-18 21:00:323471
[email protected]2d2697f92009-02-18 21:00:323472 // Since we have proxy, should try to establish tunnel.
3473 MockWrite data_writes1[] = {
mmenked39192ee2015-12-09 00:57:233474 MockWrite(ASYNC, 0,
3475 "CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:173476 "Host: www.example.org:443\r\n"
3477 "Proxy-Connection: keep-alive\r\n\r\n"),
mmenked39192ee2015-12-09 00:57:233478 };
[email protected]2d2697f92009-02-18 21:00:323479
mmenked39192ee2015-12-09 00:57:233480 // The proxy responds to the connect with a 407, using a persistent, but sends
3481 // extra data, so the socket cannot be reused.
3482 MockRead data_reads1[] = {
3483 // No credentials.
3484 MockRead(ASYNC, 1,
3485 "HTTP/1.1 407 Proxy Authentication Required\r\n"
3486 "Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"
3487 "Content-Length: 10\r\n\r\n"),
3488 MockRead(SYNCHRONOUS, 2, "0123456789"),
3489 MockRead(SYNCHRONOUS, 3, "I'm broken!"),
3490 };
3491
3492 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:233493 // After calling trans->RestartWithAuth(), this is the request we should
3494 // be issuing -- the final header line contains the credentials.
mmenked39192ee2015-12-09 00:57:233495 MockWrite(ASYNC, 0,
3496 "CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:173497 "Host: www.example.org:443\r\n"
3498 "Proxy-Connection: keep-alive\r\n"
mmenked39192ee2015-12-09 00:57:233499 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
3500
3501 MockWrite(ASYNC, 2,
3502 "GET / HTTP/1.1\r\n"
3503 "Host: www.example.org\r\n"
3504 "Connection: keep-alive\r\n\r\n"),
[email protected]2d2697f92009-02-18 21:00:323505 };
3506
mmenked39192ee2015-12-09 00:57:233507 MockRead data_reads2[] = {
3508 MockRead(ASYNC, 1, "HTTP/1.1 200 Connection Established\r\n\r\n"),
[email protected]2d2697f92009-02-18 21:00:323509
mmenked39192ee2015-12-09 00:57:233510 MockRead(ASYNC, 3,
3511 "HTTP/1.1 200 OK\r\n"
3512 "Content-Type: text/html; charset=iso-8859-1\r\n"
3513 "Content-Length: 5\r\n\r\n"),
3514 // No response body because the test stops reading here.
3515 MockRead(SYNCHRONOUS, ERR_UNEXPECTED, 4),
[email protected]2d2697f92009-02-18 21:00:323516 };
3517
mmenked39192ee2015-12-09 00:57:233518 SequencedSocketData data1(data_reads1, arraysize(data_reads1), data_writes1,
3519 arraysize(data_writes1));
3520 data1.set_busy_before_sync_reads(true);
[email protected]bb88e1d32013-05-03 23:11:073521 session_deps_.socket_factory->AddSocketDataProvider(&data1);
mmenked39192ee2015-12-09 00:57:233522 SequencedSocketData data2(data_reads2, arraysize(data_reads2), data_writes2,
3523 arraysize(data_writes2));
3524 session_deps_.socket_factory->AddSocketDataProvider(&data2);
3525 SSLSocketDataProvider ssl(ASYNC, OK);
3526 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]2d2697f92009-02-18 21:00:323527
[email protected]49639fa2011-12-20 23:22:413528 TestCompletionCallback callback1;
[email protected]2d2697f92009-02-18 21:00:323529
bnc87dcefc2017-05-25 12:47:583530 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:193531 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]2d2697f92009-02-18 21:00:323532
mmenked39192ee2015-12-09 00:57:233533 int rv = trans->Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:013534 EXPECT_THAT(callback1.GetResult(rv), IsOk());
mmenked39192ee2015-12-09 00:57:233535
mmenke43758e62015-05-04 21:09:463536 TestNetLogEntry::List entries;
[email protected]b2fcd0e2010-12-01 15:19:403537 log.GetEntries(&entries);
[email protected]dbb83db2010-05-11 18:13:393538 size_t pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:003539 entries, 0, NetLogEventType::HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
3540 NetLogEventPhase::NONE);
[email protected]dbb83db2010-05-11 18:13:393541 ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:403542 entries, pos,
mikecirone8b85c432016-09-08 19:11:003543 NetLogEventType::HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
3544 NetLogEventPhase::NONE);
[email protected]2d2697f92009-02-18 21:00:323545
[email protected]1c773ea12009-04-28 19:58:423546 const HttpResponseInfo* response = trans->GetResponseInfo();
ttuttle7933c112015-01-06 00:55:243547 ASSERT_TRUE(response);
3548 ASSERT_TRUE(response->headers);
[email protected]2d2697f92009-02-18 21:00:323549 EXPECT_TRUE(response->headers->IsKeepAlive());
3550 EXPECT_EQ(407, response->headers->response_code());
[email protected]1c773ea12009-04-28 19:58:423551 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
[email protected]79cb5c12011-09-12 13:12:043552 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
[email protected]2d2697f92009-02-18 21:00:323553
mmenked39192ee2015-12-09 00:57:233554 LoadTimingInfo load_timing_info;
3555 // CONNECT requests and responses are handled at the connect job level, so
3556 // the transaction does not yet have a connection.
3557 EXPECT_FALSE(trans->GetLoadTimingInfo(&load_timing_info));
3558
[email protected]49639fa2011-12-20 23:22:413559 TestCompletionCallback callback2;
[email protected]2d2697f92009-02-18 21:00:323560
mmenked39192ee2015-12-09 00:57:233561 rv =
3562 trans->RestartWithAuth(AuthCredentials(kFoo, kBar), callback2.callback());
robpercival214763f2016-07-01 23:27:013563 EXPECT_THAT(callback2.GetResult(rv), IsOk());
[email protected]2d2697f92009-02-18 21:00:323564
[email protected]2d2697f92009-02-18 21:00:323565 EXPECT_TRUE(response->headers->IsKeepAlive());
mmenked39192ee2015-12-09 00:57:233566 EXPECT_EQ(200, response->headers->response_code());
3567 EXPECT_EQ(5, response->headers->GetContentLength());
[email protected]1c773ea12009-04-28 19:58:423568 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
[email protected]e772db3f2010-07-12 18:11:133569
mmenked39192ee2015-12-09 00:57:233570 // The password prompt info should not be set.
3571 EXPECT_FALSE(response->auth_challenge);
3572
3573 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
3574 TestLoadTimingNotReusedWithPac(load_timing_info,
3575 CONNECT_TIMING_HAS_SSL_TIMES);
3576
3577 trans.reset();
[email protected]102e27c2011-02-23 01:01:313578 session->CloseAllConnections();
[email protected]2d2697f92009-02-18 21:00:323579}
3580
mmenkee71e15332015-10-07 16:39:543581// Test the case a proxy closes a socket while the challenge body is being
3582// drained.
bncd16676a2016-07-20 16:23:013583TEST_F(HttpNetworkTransactionTest, BasicAuthProxyKeepAliveHangupDuringBody) {
mmenkee71e15332015-10-07 16:39:543584 HttpRequestInfo request;
3585 request.method = "GET";
3586 request.url = GURL("https://www.example.org/");
3587 // Ensure that proxy authentication is attempted even
3588 // when the no authentication data flag is set.
3589 request.load_flags = LOAD_DO_NOT_SEND_AUTH_DATA;
3590
3591 // Configure against proxy server "myproxy:70".
3592 session_deps_.proxy_service = ProxyService::CreateFixed("myproxy:70");
danakj1fd259a02016-04-16 03:17:093593 std::unique_ptr<HttpNetworkSession> session = CreateSession(&session_deps_);
mmenkee71e15332015-10-07 16:39:543594
bnc691fda62016-08-12 00:43:163595 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
mmenkee71e15332015-10-07 16:39:543596
3597 // Since we have proxy, should try to establish tunnel.
3598 MockWrite data_writes1[] = {
3599 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:173600 "Host: www.example.org:443\r\n"
mmenkee71e15332015-10-07 16:39:543601 "Proxy-Connection: keep-alive\r\n\r\n"),
3602 };
3603
3604 // The proxy responds to the connect with a 407, using a persistent
3605 // connection.
3606 MockRead data_reads1[] = {
3607 // No credentials.
3608 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
3609 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
3610 MockRead("Content-Length: 10\r\n\r\n"), MockRead("spam!"),
3611 // Server hands up in the middle of the body.
3612 MockRead(ASYNC, ERR_CONNECTION_CLOSED),
3613 };
3614
3615 MockWrite data_writes2[] = {
bnc691fda62016-08-12 00:43:163616 // After calling trans.RestartWithAuth(), this is the request we should
mmenkee71e15332015-10-07 16:39:543617 // be issuing -- the final header line contains the credentials.
3618 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:173619 "Host: www.example.org:443\r\n"
mmenkee71e15332015-10-07 16:39:543620 "Proxy-Connection: keep-alive\r\n"
3621 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
3622
3623 MockWrite("GET / HTTP/1.1\r\n"
3624 "Host: www.example.org\r\n"
3625 "Connection: keep-alive\r\n\r\n"),
3626 };
3627
3628 MockRead data_reads2[] = {
3629 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
3630
3631 MockRead("HTTP/1.1 200 OK\r\n"),
3632 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
3633 MockRead("Content-Length: 5\r\n\r\n"),
3634 MockRead(SYNCHRONOUS, "hello"),
3635 };
3636
3637 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
3638 data_writes1, arraysize(data_writes1));
3639 session_deps_.socket_factory->AddSocketDataProvider(&data1);
3640 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
3641 data_writes2, arraysize(data_writes2));
3642 session_deps_.socket_factory->AddSocketDataProvider(&data2);
3643 SSLSocketDataProvider ssl(ASYNC, OK);
3644 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
3645
3646 TestCompletionCallback callback;
3647
tfarina42834112016-09-22 13:38:203648 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:013649 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenkee71e15332015-10-07 16:39:543650
bnc691fda62016-08-12 00:43:163651 const HttpResponseInfo* response = trans.GetResponseInfo();
mmenkee71e15332015-10-07 16:39:543652 ASSERT_TRUE(response);
3653 ASSERT_TRUE(response->headers);
3654 EXPECT_TRUE(response->headers->IsKeepAlive());
3655 EXPECT_EQ(407, response->headers->response_code());
3656 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
3657
bnc691fda62016-08-12 00:43:163658 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar), callback.callback());
robpercival214763f2016-07-01 23:27:013659 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenkee71e15332015-10-07 16:39:543660
bnc691fda62016-08-12 00:43:163661 response = trans.GetResponseInfo();
mmenkee71e15332015-10-07 16:39:543662 ASSERT_TRUE(response);
3663 ASSERT_TRUE(response->headers);
3664 EXPECT_TRUE(response->headers->IsKeepAlive());
3665 EXPECT_EQ(200, response->headers->response_code());
3666 std::string body;
bnc691fda62016-08-12 00:43:163667 EXPECT_THAT(ReadTransaction(&trans, &body), IsOk());
mmenkee71e15332015-10-07 16:39:543668 EXPECT_EQ("hello", body);
3669}
3670
[email protected]a8e9b162009-03-12 00:06:443671// Test that we don't read the response body when we fail to establish a tunnel,
3672// even if the user cancels the proxy's auth attempt.
bncd16676a2016-07-20 16:23:013673TEST_F(HttpNetworkTransactionTest, BasicAuthProxyCancelTunnel) {
[email protected]cb9bf6ca2011-01-28 13:15:273674 HttpRequestInfo request;
3675 request.method = "GET";
bncce36dca22015-04-21 22:11:233676 request.url = GURL("https://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:273677
[email protected]a8e9b162009-03-12 00:06:443678 // Configure against proxy server "myproxy:70".
rdsmith82957ad2015-09-16 19:42:033679 session_deps_.proxy_service = ProxyService::CreateFixed("myproxy:70");
[email protected]a8e9b162009-03-12 00:06:443680
danakj1fd259a02016-04-16 03:17:093681 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]a8e9b162009-03-12 00:06:443682
bnc691fda62016-08-12 00:43:163683 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]a8e9b162009-03-12 00:06:443684
[email protected]a8e9b162009-03-12 00:06:443685 // Since we have proxy, should try to establish tunnel.
3686 MockWrite data_writes[] = {
rsleevidb16bb02015-11-12 23:47:173687 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
3688 "Host: www.example.org:443\r\n"
3689 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]a8e9b162009-03-12 00:06:443690 };
3691
3692 // The proxy responds to the connect with a 407.
3693 MockRead data_reads[] = {
ttuttle7933c112015-01-06 00:55:243694 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
3695 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
3696 MockRead("Content-Length: 10\r\n\r\n"),
mmenked39192ee2015-12-09 00:57:233697 MockRead("0123456789"),
ttuttle7933c112015-01-06 00:55:243698 MockRead(SYNCHRONOUS, ERR_UNEXPECTED),
[email protected]a8e9b162009-03-12 00:06:443699 };
3700
[email protected]31a2bfe2010-02-09 08:03:393701 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
3702 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:073703 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]a8e9b162009-03-12 00:06:443704
[email protected]49639fa2011-12-20 23:22:413705 TestCompletionCallback callback;
[email protected]a8e9b162009-03-12 00:06:443706
tfarina42834112016-09-22 13:38:203707 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:013708 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]a8e9b162009-03-12 00:06:443709
3710 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:013711 EXPECT_THAT(rv, IsOk());
[email protected]a8e9b162009-03-12 00:06:443712
bnc691fda62016-08-12 00:43:163713 const HttpResponseInfo* response = trans.GetResponseInfo();
ttuttle7933c112015-01-06 00:55:243714 ASSERT_TRUE(response);
3715 ASSERT_TRUE(response->headers);
[email protected]a8e9b162009-03-12 00:06:443716 EXPECT_TRUE(response->headers->IsKeepAlive());
3717 EXPECT_EQ(407, response->headers->response_code());
[email protected]1c773ea12009-04-28 19:58:423718 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
[email protected]a8e9b162009-03-12 00:06:443719
3720 std::string response_data;
bnc691fda62016-08-12 00:43:163721 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:013722 EXPECT_THAT(rv, IsError(ERR_TUNNEL_CONNECTION_FAILED));
[email protected]e60e47a2010-07-14 03:37:183723
3724 // Flush the idle socket before the HttpNetworkTransaction goes out of scope.
[email protected]102e27c2011-02-23 01:01:313725 session->CloseAllConnections();
[email protected]a8e9b162009-03-12 00:06:443726}
3727
ttuttle7933c112015-01-06 00:55:243728// Test that we don't pass extraneous headers from the proxy's response to the
3729// caller when the proxy responds to CONNECT with 407.
bncd16676a2016-07-20 16:23:013730TEST_F(HttpNetworkTransactionTest, SanitizeProxyAuthHeaders) {
ttuttle7933c112015-01-06 00:55:243731 HttpRequestInfo request;
3732 request.method = "GET";
bncce36dca22015-04-21 22:11:233733 request.url = GURL("https://www.example.org/");
ttuttle7933c112015-01-06 00:55:243734
3735 // Configure against proxy server "myproxy:70".
rdsmith82957ad2015-09-16 19:42:033736 session_deps_.proxy_service = ProxyService::CreateFixed("myproxy:70");
ttuttle7933c112015-01-06 00:55:243737
danakj1fd259a02016-04-16 03:17:093738 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
ttuttle7933c112015-01-06 00:55:243739
bnc691fda62016-08-12 00:43:163740 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
ttuttle7933c112015-01-06 00:55:243741
3742 // Since we have proxy, should try to establish tunnel.
3743 MockWrite data_writes[] = {
rsleevidb16bb02015-11-12 23:47:173744 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
3745 "Host: www.example.org:443\r\n"
3746 "Proxy-Connection: keep-alive\r\n\r\n"),
ttuttle7933c112015-01-06 00:55:243747 };
3748
3749 // The proxy responds to the connect with a 407.
3750 MockRead data_reads[] = {
3751 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
3752 MockRead("X-Foo: bar\r\n"),
3753 MockRead("Set-Cookie: foo=bar\r\n"),
3754 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
3755 MockRead("Content-Length: 10\r\n\r\n"),
mmenked39192ee2015-12-09 00:57:233756 MockRead(SYNCHRONOUS, ERR_UNEXPECTED),
ttuttle7933c112015-01-06 00:55:243757 };
3758
3759 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
3760 arraysize(data_writes));
3761 session_deps_.socket_factory->AddSocketDataProvider(&data);
3762
3763 TestCompletionCallback callback;
3764
tfarina42834112016-09-22 13:38:203765 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:013766 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
ttuttle7933c112015-01-06 00:55:243767
3768 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:013769 EXPECT_THAT(rv, IsOk());
ttuttle7933c112015-01-06 00:55:243770
bnc691fda62016-08-12 00:43:163771 const HttpResponseInfo* response = trans.GetResponseInfo();
ttuttle7933c112015-01-06 00:55:243772 ASSERT_TRUE(response);
3773 ASSERT_TRUE(response->headers);
3774 EXPECT_TRUE(response->headers->IsKeepAlive());
3775 EXPECT_EQ(407, response->headers->response_code());
3776 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
3777 EXPECT_FALSE(response->headers->HasHeader("X-Foo"));
3778 EXPECT_FALSE(response->headers->HasHeader("Set-Cookie"));
3779
3780 std::string response_data;
bnc691fda62016-08-12 00:43:163781 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:013782 EXPECT_THAT(rv, IsError(ERR_TUNNEL_CONNECTION_FAILED));
ttuttle7933c112015-01-06 00:55:243783
3784 // Flush the idle socket before the HttpNetworkTransaction goes out of scope.
3785 session->CloseAllConnections();
3786}
3787
[email protected]8fdbcd22010-05-05 02:54:523788// Test when a server (non-proxy) returns a 407 (proxy-authenticate).
3789// The request should fail with ERR_UNEXPECTED_PROXY_AUTH.
bncd16676a2016-07-20 16:23:013790TEST_F(HttpNetworkTransactionTest, UnexpectedProxyAuth) {
[email protected]8fdbcd22010-05-05 02:54:523791 HttpRequestInfo request;
3792 request.method = "GET";
bncce36dca22015-04-21 22:11:233793 request.url = GURL("http://www.example.org/");
[email protected]8fdbcd22010-05-05 02:54:523794
[email protected]cb9bf6ca2011-01-28 13:15:273795 // We are using a DIRECT connection (i.e. no proxy) for this session.
danakj1fd259a02016-04-16 03:17:093796 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:163797 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:273798
[email protected]8fdbcd22010-05-05 02:54:523799 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:233800 MockWrite(
3801 "GET / HTTP/1.1\r\n"
3802 "Host: www.example.org\r\n"
3803 "Connection: keep-alive\r\n\r\n"),
[email protected]8fdbcd22010-05-05 02:54:523804 };
3805
3806 MockRead data_reads1[] = {
3807 MockRead("HTTP/1.0 407 Proxy Auth required\r\n"),
3808 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
3809 // Large content-length -- won't matter, as connection will be reset.
3810 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:063811 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]8fdbcd22010-05-05 02:54:523812 };
3813
3814 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
3815 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:073816 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8fdbcd22010-05-05 02:54:523817
[email protected]49639fa2011-12-20 23:22:413818 TestCompletionCallback callback;
[email protected]8fdbcd22010-05-05 02:54:523819
tfarina42834112016-09-22 13:38:203820 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:013821 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]8fdbcd22010-05-05 02:54:523822
3823 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:013824 EXPECT_THAT(rv, IsError(ERR_UNEXPECTED_PROXY_AUTH));
[email protected]8fdbcd22010-05-05 02:54:523825}
3826
[email protected]7a67a8152010-11-05 18:31:103827// Tests when an HTTPS server (non-proxy) returns a 407 (proxy-authentication)
3828// through a non-authenticating proxy. The request should fail with
3829// ERR_UNEXPECTED_PROXY_AUTH.
3830// Note that it is impossible to detect if an HTTP server returns a 407 through
3831// a non-authenticating proxy - there is nothing to indicate whether the
3832// response came from the proxy or the server, so it is treated as if the proxy
3833// issued the challenge.
bncd16676a2016-07-20 16:23:013834TEST_F(HttpNetworkTransactionTest, HttpsServerRequestsProxyAuthThroughProxy) {
[email protected]cb9bf6ca2011-01-28 13:15:273835 HttpRequestInfo request;
3836 request.method = "GET";
bncce36dca22015-04-21 22:11:233837 request.url = GURL("https://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:273838
rdsmith82957ad2015-09-16 19:42:033839 session_deps_.proxy_service = ProxyService::CreateFixed("myproxy:70");
vishal.b62985ca92015-04-17 08:45:513840 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:073841 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:093842 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]7a67a8152010-11-05 18:31:103843
[email protected]7a67a8152010-11-05 18:31:103844 // Since we have proxy, should try to establish tunnel.
3845 MockWrite data_writes1[] = {
rsleevidb16bb02015-11-12 23:47:173846 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
3847 "Host: www.example.org:443\r\n"
3848 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]7a67a8152010-11-05 18:31:103849
rsleevidb16bb02015-11-12 23:47:173850 MockWrite("GET / HTTP/1.1\r\n"
3851 "Host: www.example.org\r\n"
3852 "Connection: keep-alive\r\n\r\n"),
[email protected]7a67a8152010-11-05 18:31:103853 };
3854
3855 MockRead data_reads1[] = {
3856 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
3857
3858 MockRead("HTTP/1.1 407 Unauthorized\r\n"),
3859 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
3860 MockRead("\r\n"),
[email protected]8ddf8322012-02-23 18:08:063861 MockRead(SYNCHRONOUS, OK),
[email protected]7a67a8152010-11-05 18:31:103862 };
3863
3864 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
3865 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:073866 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8ddf8322012-02-23 18:08:063867 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:073868 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]7a67a8152010-11-05 18:31:103869
[email protected]49639fa2011-12-20 23:22:413870 TestCompletionCallback callback1;
[email protected]7a67a8152010-11-05 18:31:103871
bnc691fda62016-08-12 00:43:163872 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]7a67a8152010-11-05 18:31:103873
bnc691fda62016-08-12 00:43:163874 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:013875 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]7a67a8152010-11-05 18:31:103876
3877 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:013878 EXPECT_THAT(rv, IsError(ERR_UNEXPECTED_PROXY_AUTH));
mmenke43758e62015-05-04 21:09:463879 TestNetLogEntry::List entries;
[email protected]b2fcd0e2010-12-01 15:19:403880 log.GetEntries(&entries);
[email protected]7a67a8152010-11-05 18:31:103881 size_t pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:003882 entries, 0, NetLogEventType::HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
3883 NetLogEventPhase::NONE);
[email protected]7a67a8152010-11-05 18:31:103884 ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:403885 entries, pos,
mikecirone8b85c432016-09-08 19:11:003886 NetLogEventType::HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
3887 NetLogEventPhase::NONE);
[email protected]7a67a8152010-11-05 18:31:103888}
[email protected]2df19bb2010-08-25 20:13:463889
mmenke2a1781d2015-10-07 19:25:333890// Test a proxy auth scheme that allows default credentials and a proxy server
3891// that uses non-persistent connections.
bncd16676a2016-07-20 16:23:013892TEST_F(HttpNetworkTransactionTest,
mmenke2a1781d2015-10-07 19:25:333893 AuthAllowsDefaultCredentialsTunnelConnectionClose) {
3894 HttpRequestInfo request;
3895 request.method = "GET";
3896 request.url = GURL("https://www.example.org/");
3897
3898 // Configure against proxy server "myproxy:70".
3899 session_deps_.proxy_service =
3900 ProxyService::CreateFixedFromPacResult("PROXY myproxy:70");
3901
Jeremy Roman0579ed62017-08-29 15:56:193902 auto auth_handler_factory = std::make_unique<HttpAuthHandlerMock::Factory>();
mmenke2a1781d2015-10-07 19:25:333903 auth_handler_factory->set_do_init_from_challenge(true);
Jeremy Roman0579ed62017-08-29 15:56:193904 auto mock_handler = std::make_unique<HttpAuthHandlerMock>();
mmenke2a1781d2015-10-07 19:25:333905 mock_handler->set_allows_default_credentials(true);
3906 auth_handler_factory->AddMockHandler(mock_handler.release(),
3907 HttpAuth::AUTH_PROXY);
dchengc7eeda422015-12-26 03:56:483908 session_deps_.http_auth_handler_factory = std::move(auth_handler_factory);
mmenke2a1781d2015-10-07 19:25:333909
3910 // Add NetLog just so can verify load timing information gets a NetLog ID.
3911 NetLog net_log;
3912 session_deps_.net_log = &net_log;
danakj1fd259a02016-04-16 03:17:093913 std::unique_ptr<HttpNetworkSession> session = CreateSession(&session_deps_);
mmenke2a1781d2015-10-07 19:25:333914
3915 // Since we have proxy, should try to establish tunnel.
3916 MockWrite data_writes1[] = {
3917 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:173918 "Host: www.example.org:443\r\n"
mmenke2a1781d2015-10-07 19:25:333919 "Proxy-Connection: keep-alive\r\n\r\n"),
3920 };
3921
3922 // The proxy responds to the connect with a 407, using a non-persistent
3923 // connection.
3924 MockRead data_reads1[] = {
3925 // No credentials.
3926 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
3927 MockRead("Proxy-Authenticate: Mock\r\n"),
3928 MockRead("Proxy-Connection: close\r\n\r\n"),
3929 };
3930
3931 // Since the first connection couldn't be reused, need to establish another
3932 // once given credentials.
3933 MockWrite data_writes2[] = {
3934 // After calling trans->RestartWithAuth(), this is the request we should
3935 // be issuing -- the final header line contains the credentials.
3936 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:173937 "Host: www.example.org:443\r\n"
mmenke2a1781d2015-10-07 19:25:333938 "Proxy-Connection: keep-alive\r\n"
3939 "Proxy-Authorization: auth_token\r\n\r\n"),
3940
3941 MockWrite("GET / HTTP/1.1\r\n"
3942 "Host: www.example.org\r\n"
3943 "Connection: keep-alive\r\n\r\n"),
3944 };
3945
3946 MockRead data_reads2[] = {
3947 MockRead("HTTP/1.0 200 Connection Established\r\n\r\n"),
3948
3949 MockRead("HTTP/1.1 200 OK\r\n"),
3950 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
3951 MockRead("Content-Length: 5\r\n\r\n"),
3952 MockRead(SYNCHRONOUS, "hello"),
3953 };
3954
3955 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
3956 data_writes1, arraysize(data_writes1));
3957 session_deps_.socket_factory->AddSocketDataProvider(&data1);
3958 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
3959 data_writes2, arraysize(data_writes2));
3960 session_deps_.socket_factory->AddSocketDataProvider(&data2);
3961 SSLSocketDataProvider ssl(ASYNC, OK);
3962 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
3963
bnc87dcefc2017-05-25 12:47:583964 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:193965 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
mmenke2a1781d2015-10-07 19:25:333966
3967 TestCompletionCallback callback;
tfarina42834112016-09-22 13:38:203968 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:013969 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenke2a1781d2015-10-07 19:25:333970
3971 const HttpResponseInfo* response = trans->GetResponseInfo();
3972 ASSERT_TRUE(response);
3973 ASSERT_TRUE(response->headers);
3974 EXPECT_FALSE(response->headers->IsKeepAlive());
3975 EXPECT_EQ(407, response->headers->response_code());
3976 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
3977 EXPECT_TRUE(trans->IsReadyToRestartForAuth());
wezca1070932016-05-26 20:30:523978 EXPECT_FALSE(response->auth_challenge);
mmenke2a1781d2015-10-07 19:25:333979
3980 LoadTimingInfo load_timing_info;
3981 // CONNECT requests and responses are handled at the connect job level, so
3982 // the transaction does not yet have a connection.
3983 EXPECT_FALSE(trans->GetLoadTimingInfo(&load_timing_info));
3984
3985 rv = trans->RestartWithAuth(AuthCredentials(), callback.callback());
robpercival214763f2016-07-01 23:27:013986 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenke2a1781d2015-10-07 19:25:333987 response = trans->GetResponseInfo();
3988 ASSERT_TRUE(response);
3989 ASSERT_TRUE(response->headers);
3990 EXPECT_TRUE(response->headers->IsKeepAlive());
3991 EXPECT_EQ(200, response->headers->response_code());
3992 EXPECT_EQ(5, response->headers->GetContentLength());
3993 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
3994
3995 // The password prompt info should not be set.
3996 EXPECT_FALSE(response->auth_challenge);
3997
3998 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
3999 TestLoadTimingNotReusedWithPac(load_timing_info,
4000 CONNECT_TIMING_HAS_SSL_TIMES);
4001
4002 trans.reset();
4003 session->CloseAllConnections();
4004}
4005
4006// Test a proxy auth scheme that allows default credentials and a proxy server
4007// that hangs up when credentials are initially sent.
bncd16676a2016-07-20 16:23:014008TEST_F(HttpNetworkTransactionTest,
mmenke2a1781d2015-10-07 19:25:334009 AuthAllowsDefaultCredentialsTunnelServerClosesConnection) {
4010 HttpRequestInfo request;
4011 request.method = "GET";
4012 request.url = GURL("https://www.example.org/");
4013
4014 // Configure against proxy server "myproxy:70".
4015 session_deps_.proxy_service =
4016 ProxyService::CreateFixedFromPacResult("PROXY myproxy:70");
4017
Jeremy Roman0579ed62017-08-29 15:56:194018 auto auth_handler_factory = std::make_unique<HttpAuthHandlerMock::Factory>();
mmenke2a1781d2015-10-07 19:25:334019 auth_handler_factory->set_do_init_from_challenge(true);
Jeremy Roman0579ed62017-08-29 15:56:194020 auto mock_handler = std::make_unique<HttpAuthHandlerMock>();
mmenke2a1781d2015-10-07 19:25:334021 mock_handler->set_allows_default_credentials(true);
4022 auth_handler_factory->AddMockHandler(mock_handler.release(),
4023 HttpAuth::AUTH_PROXY);
dchengc7eeda422015-12-26 03:56:484024 session_deps_.http_auth_handler_factory = std::move(auth_handler_factory);
mmenke2a1781d2015-10-07 19:25:334025
4026 // Add NetLog just so can verify load timing information gets a NetLog ID.
4027 NetLog net_log;
4028 session_deps_.net_log = &net_log;
danakj1fd259a02016-04-16 03:17:094029 std::unique_ptr<HttpNetworkSession> session = CreateSession(&session_deps_);
mmenke2a1781d2015-10-07 19:25:334030
4031 // Should try to establish tunnel.
4032 MockWrite data_writes1[] = {
4033 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:174034 "Host: www.example.org:443\r\n"
mmenke2a1781d2015-10-07 19:25:334035 "Proxy-Connection: keep-alive\r\n\r\n"),
4036
4037 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:174038 "Host: www.example.org:443\r\n"
mmenke2a1781d2015-10-07 19:25:334039 "Proxy-Connection: keep-alive\r\n"
4040 "Proxy-Authorization: auth_token\r\n\r\n"),
4041 };
4042
4043 // The proxy responds to the connect with a 407, using a non-persistent
4044 // connection.
4045 MockRead data_reads1[] = {
4046 // No credentials.
4047 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
4048 MockRead("Proxy-Authenticate: Mock\r\n\r\n"),
4049 MockRead(SYNCHRONOUS, ERR_CONNECTION_CLOSED),
4050 };
4051
4052 // Since the first connection was closed, need to establish another once given
4053 // credentials.
4054 MockWrite data_writes2[] = {
4055 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:174056 "Host: www.example.org:443\r\n"
mmenke2a1781d2015-10-07 19:25:334057 "Proxy-Connection: keep-alive\r\n"
4058 "Proxy-Authorization: auth_token\r\n\r\n"),
4059
4060 MockWrite("GET / HTTP/1.1\r\n"
4061 "Host: www.example.org\r\n"
4062 "Connection: keep-alive\r\n\r\n"),
4063 };
4064
4065 MockRead data_reads2[] = {
4066 MockRead("HTTP/1.0 200 Connection Established\r\n\r\n"),
4067
4068 MockRead("HTTP/1.1 200 OK\r\n"),
4069 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
4070 MockRead("Content-Length: 5\r\n\r\n"),
4071 MockRead(SYNCHRONOUS, "hello"),
4072 };
4073
4074 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
4075 data_writes1, arraysize(data_writes1));
4076 session_deps_.socket_factory->AddSocketDataProvider(&data1);
4077 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
4078 data_writes2, arraysize(data_writes2));
4079 session_deps_.socket_factory->AddSocketDataProvider(&data2);
4080 SSLSocketDataProvider ssl(ASYNC, OK);
4081 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
4082
bnc87dcefc2017-05-25 12:47:584083 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:194084 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
mmenke2a1781d2015-10-07 19:25:334085
4086 TestCompletionCallback callback;
tfarina42834112016-09-22 13:38:204087 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:014088 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenke2a1781d2015-10-07 19:25:334089
4090 const HttpResponseInfo* response = trans->GetResponseInfo();
4091 ASSERT_TRUE(response);
4092 ASSERT_TRUE(response->headers);
4093 EXPECT_TRUE(response->headers->IsKeepAlive());
4094 EXPECT_EQ(407, response->headers->response_code());
4095 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
4096 EXPECT_TRUE(trans->IsReadyToRestartForAuth());
4097 EXPECT_FALSE(response->auth_challenge);
4098
4099 LoadTimingInfo load_timing_info;
4100 // CONNECT requests and responses are handled at the connect job level, so
4101 // the transaction does not yet have a connection.
4102 EXPECT_FALSE(trans->GetLoadTimingInfo(&load_timing_info));
4103
4104 rv = trans->RestartWithAuth(AuthCredentials(), callback.callback());
robpercival214763f2016-07-01 23:27:014105 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenke2a1781d2015-10-07 19:25:334106
4107 response = trans->GetResponseInfo();
4108 ASSERT_TRUE(response);
4109 ASSERT_TRUE(response->headers);
4110 EXPECT_TRUE(response->headers->IsKeepAlive());
4111 EXPECT_EQ(200, response->headers->response_code());
4112 EXPECT_EQ(5, response->headers->GetContentLength());
4113 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
4114
4115 // The password prompt info should not be set.
wezca1070932016-05-26 20:30:524116 EXPECT_FALSE(response->auth_challenge);
mmenke2a1781d2015-10-07 19:25:334117
4118 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
4119 TestLoadTimingNotReusedWithPac(load_timing_info,
4120 CONNECT_TIMING_HAS_SSL_TIMES);
4121
4122 trans.reset();
4123 session->CloseAllConnections();
4124}
4125
4126// Test a proxy auth scheme that allows default credentials and a proxy server
4127// that hangs up when credentials are initially sent, and hangs up again when
4128// they are retried.
bncd16676a2016-07-20 16:23:014129TEST_F(HttpNetworkTransactionTest,
mmenke2a1781d2015-10-07 19:25:334130 AuthAllowsDefaultCredentialsTunnelServerClosesConnectionTwice) {
4131 HttpRequestInfo request;
4132 request.method = "GET";
4133 request.url = GURL("https://www.example.org/");
4134
4135 // Configure against proxy server "myproxy:70".
4136 session_deps_.proxy_service =
4137 ProxyService::CreateFixedFromPacResult("PROXY myproxy:70");
4138
Jeremy Roman0579ed62017-08-29 15:56:194139 auto auth_handler_factory = std::make_unique<HttpAuthHandlerMock::Factory>();
mmenke2a1781d2015-10-07 19:25:334140 auth_handler_factory->set_do_init_from_challenge(true);
Jeremy Roman0579ed62017-08-29 15:56:194141 auto mock_handler = std::make_unique<HttpAuthHandlerMock>();
mmenke2a1781d2015-10-07 19:25:334142 mock_handler->set_allows_default_credentials(true);
4143 auth_handler_factory->AddMockHandler(mock_handler.release(),
4144 HttpAuth::AUTH_PROXY);
dchengc7eeda422015-12-26 03:56:484145 session_deps_.http_auth_handler_factory = std::move(auth_handler_factory);
mmenke2a1781d2015-10-07 19:25:334146
4147 // Add NetLog just so can verify load timing information gets a NetLog ID.
4148 NetLog net_log;
4149 session_deps_.net_log = &net_log;
danakj1fd259a02016-04-16 03:17:094150 std::unique_ptr<HttpNetworkSession> session = CreateSession(&session_deps_);
mmenke2a1781d2015-10-07 19:25:334151
4152 // Should try to establish tunnel.
4153 MockWrite data_writes1[] = {
4154 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:174155 "Host: www.example.org:443\r\n"
mmenke2a1781d2015-10-07 19:25:334156 "Proxy-Connection: keep-alive\r\n\r\n"),
4157
4158 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:174159 "Host: www.example.org:443\r\n"
mmenke2a1781d2015-10-07 19:25:334160 "Proxy-Connection: keep-alive\r\n"
4161 "Proxy-Authorization: auth_token\r\n\r\n"),
4162 };
4163
4164 // The proxy responds to the connect with a 407, and then hangs up after the
4165 // second request is sent.
4166 MockRead data_reads1[] = {
4167 // No credentials.
4168 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
4169 MockRead("Content-Length: 0\r\n"),
4170 MockRead("Proxy-Connection: keep-alive\r\n"),
4171 MockRead("Proxy-Authenticate: Mock\r\n\r\n"),
4172 MockRead(SYNCHRONOUS, ERR_CONNECTION_CLOSED),
4173 };
4174
4175 // HttpNetworkTransaction sees a reused connection that was closed with
4176 // ERR_CONNECTION_CLOSED, realized it might have been a race, so retries the
4177 // request.
4178 MockWrite data_writes2[] = {
4179 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:174180 "Host: www.example.org:443\r\n"
mmenke2a1781d2015-10-07 19:25:334181 "Proxy-Connection: keep-alive\r\n\r\n"),
4182 };
4183
4184 // The proxy, having had more than enough of us, just hangs up.
4185 MockRead data_reads2[] = {
4186 // No credentials.
4187 MockRead(SYNCHRONOUS, ERR_CONNECTION_CLOSED),
4188 };
4189
4190 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
4191 data_writes1, arraysize(data_writes1));
4192 session_deps_.socket_factory->AddSocketDataProvider(&data1);
4193 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
4194 data_writes2, arraysize(data_writes2));
4195 session_deps_.socket_factory->AddSocketDataProvider(&data2);
4196
bnc87dcefc2017-05-25 12:47:584197 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:194198 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
mmenke2a1781d2015-10-07 19:25:334199
4200 TestCompletionCallback callback;
tfarina42834112016-09-22 13:38:204201 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:014202 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenke2a1781d2015-10-07 19:25:334203
4204 const HttpResponseInfo* response = trans->GetResponseInfo();
4205 ASSERT_TRUE(response);
4206 ASSERT_TRUE(response->headers);
4207 EXPECT_TRUE(response->headers->IsKeepAlive());
4208 EXPECT_EQ(407, response->headers->response_code());
4209 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
4210 EXPECT_TRUE(trans->IsReadyToRestartForAuth());
4211 EXPECT_FALSE(response->auth_challenge);
4212
4213 LoadTimingInfo load_timing_info;
4214 EXPECT_FALSE(trans->GetLoadTimingInfo(&load_timing_info));
4215
4216 rv = trans->RestartWithAuth(AuthCredentials(), callback.callback());
robpercival214763f2016-07-01 23:27:014217 EXPECT_THAT(callback.GetResult(rv), IsError(ERR_EMPTY_RESPONSE));
mmenke2a1781d2015-10-07 19:25:334218
4219 trans.reset();
4220 session->CloseAllConnections();
4221}
4222
4223// Test a proxy auth scheme that allows default credentials and a proxy server
4224// that hangs up when credentials are initially sent, and sends a challenge
4225// again they are retried.
bncd16676a2016-07-20 16:23:014226TEST_F(HttpNetworkTransactionTest,
mmenke2a1781d2015-10-07 19:25:334227 AuthAllowsDefaultCredentialsTunnelServerChallengesTwice) {
4228 HttpRequestInfo request;
4229 request.method = "GET";
4230 request.url = GURL("https://www.example.org/");
4231
4232 // Configure against proxy server "myproxy:70".
4233 session_deps_.proxy_service =
4234 ProxyService::CreateFixedFromPacResult("PROXY myproxy:70");
4235
Jeremy Roman0579ed62017-08-29 15:56:194236 auto auth_handler_factory = std::make_unique<HttpAuthHandlerMock::Factory>();
mmenke2a1781d2015-10-07 19:25:334237 auth_handler_factory->set_do_init_from_challenge(true);
Jeremy Roman0579ed62017-08-29 15:56:194238 auto mock_handler = std::make_unique<HttpAuthHandlerMock>();
mmenke2a1781d2015-10-07 19:25:334239 mock_handler->set_allows_default_credentials(true);
4240 auth_handler_factory->AddMockHandler(mock_handler.release(),
4241 HttpAuth::AUTH_PROXY);
4242 // Add another handler for the second challenge. It supports default
4243 // credentials, but they shouldn't be used, since they were already tried.
Jeremy Roman0579ed62017-08-29 15:56:194244 mock_handler = std::make_unique<HttpAuthHandlerMock>();
mmenke2a1781d2015-10-07 19:25:334245 mock_handler->set_allows_default_credentials(true);
4246 auth_handler_factory->AddMockHandler(mock_handler.release(),
4247 HttpAuth::AUTH_PROXY);
dchengc7eeda422015-12-26 03:56:484248 session_deps_.http_auth_handler_factory = std::move(auth_handler_factory);
mmenke2a1781d2015-10-07 19:25:334249
4250 // Add NetLog just so can verify load timing information gets a NetLog ID.
4251 NetLog net_log;
4252 session_deps_.net_log = &net_log;
danakj1fd259a02016-04-16 03:17:094253 std::unique_ptr<HttpNetworkSession> session = CreateSession(&session_deps_);
mmenke2a1781d2015-10-07 19:25:334254
4255 // Should try to establish tunnel.
4256 MockWrite data_writes1[] = {
4257 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:174258 "Host: www.example.org:443\r\n"
mmenke2a1781d2015-10-07 19:25:334259 "Proxy-Connection: keep-alive\r\n\r\n"),
4260 };
4261
4262 // The proxy responds to the connect with a 407, using a non-persistent
4263 // connection.
4264 MockRead data_reads1[] = {
4265 // No credentials.
4266 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
4267 MockRead("Proxy-Authenticate: Mock\r\n"),
4268 MockRead("Proxy-Connection: close\r\n\r\n"),
4269 };
4270
4271 // Since the first connection was closed, need to establish another once given
4272 // credentials.
4273 MockWrite data_writes2[] = {
4274 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:174275 "Host: www.example.org:443\r\n"
mmenke2a1781d2015-10-07 19:25:334276 "Proxy-Connection: keep-alive\r\n"
4277 "Proxy-Authorization: auth_token\r\n\r\n"),
4278 };
4279
4280 MockRead data_reads2[] = {
4281 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
4282 MockRead("Proxy-Authenticate: Mock\r\n"),
4283 MockRead("Proxy-Connection: close\r\n\r\n"),
4284 };
4285
4286 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
4287 data_writes1, arraysize(data_writes1));
4288 session_deps_.socket_factory->AddSocketDataProvider(&data1);
4289 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
4290 data_writes2, arraysize(data_writes2));
4291 session_deps_.socket_factory->AddSocketDataProvider(&data2);
4292 SSLSocketDataProvider ssl(ASYNC, OK);
4293 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
4294
bnc87dcefc2017-05-25 12:47:584295 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:194296 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
mmenke2a1781d2015-10-07 19:25:334297
4298 TestCompletionCallback callback;
tfarina42834112016-09-22 13:38:204299 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:014300 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenke2a1781d2015-10-07 19:25:334301
4302 const HttpResponseInfo* response = trans->GetResponseInfo();
4303 ASSERT_TRUE(response);
4304 ASSERT_TRUE(response->headers);
4305 EXPECT_EQ(407, response->headers->response_code());
4306 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
4307 EXPECT_TRUE(trans->IsReadyToRestartForAuth());
4308 EXPECT_FALSE(response->auth_challenge);
4309
4310 LoadTimingInfo load_timing_info;
4311 EXPECT_FALSE(trans->GetLoadTimingInfo(&load_timing_info));
4312
4313 rv = trans->RestartWithAuth(AuthCredentials(), callback.callback());
robpercival214763f2016-07-01 23:27:014314 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenke2a1781d2015-10-07 19:25:334315 response = trans->GetResponseInfo();
4316 ASSERT_TRUE(response);
4317 ASSERT_TRUE(response->headers);
4318 EXPECT_EQ(407, response->headers->response_code());
4319 EXPECT_FALSE(trans->IsReadyToRestartForAuth());
4320 EXPECT_TRUE(response->auth_challenge);
4321
4322 trans.reset();
4323 session->CloseAllConnections();
4324}
4325
asankae2257db2016-10-11 22:03:164326// A more nuanced test than GenerateAuthToken test which asserts that
4327// ERR_INVALID_AUTH_CREDENTIALS does not cause the auth scheme to be
4328// unnecessarily invalidated, and that if the server co-operates, the
4329// authentication handshake can continue with the same scheme but with a
4330// different identity.
4331TEST_F(HttpNetworkTransactionTest, NonPermanentGenerateAuthTokenError) {
4332 HttpRequestInfo request;
4333 request.method = "GET";
4334 request.url = GURL("http://www.example.org/");
4335
Jeremy Roman0579ed62017-08-29 15:56:194336 auto auth_handler_factory = std::make_unique<HttpAuthHandlerMock::Factory>();
asankae2257db2016-10-11 22:03:164337 auth_handler_factory->set_do_init_from_challenge(true);
4338
4339 // First handler. Uses default credentials, but barfs at generate auth token.
Jeremy Roman0579ed62017-08-29 15:56:194340 auto mock_handler = std::make_unique<HttpAuthHandlerMock>();
asankae2257db2016-10-11 22:03:164341 mock_handler->set_allows_default_credentials(true);
4342 mock_handler->set_allows_explicit_credentials(true);
4343 mock_handler->set_connection_based(true);
4344 mock_handler->SetGenerateExpectation(true, ERR_INVALID_AUTH_CREDENTIALS);
4345 auth_handler_factory->AddMockHandler(mock_handler.release(),
4346 HttpAuth::AUTH_SERVER);
4347
4348 // Add another handler for the second challenge. It supports default
4349 // credentials, but they shouldn't be used, since they were already tried.
Jeremy Roman0579ed62017-08-29 15:56:194350 mock_handler = std::make_unique<HttpAuthHandlerMock>();
asankae2257db2016-10-11 22:03:164351 mock_handler->set_allows_default_credentials(true);
4352 mock_handler->set_allows_explicit_credentials(true);
4353 mock_handler->set_connection_based(true);
4354 auth_handler_factory->AddMockHandler(mock_handler.release(),
4355 HttpAuth::AUTH_SERVER);
4356 session_deps_.http_auth_handler_factory = std::move(auth_handler_factory);
4357
4358 std::unique_ptr<HttpNetworkSession> session = CreateSession(&session_deps_);
4359
4360 MockWrite data_writes1[] = {
4361 MockWrite("GET / HTTP/1.1\r\n"
4362 "Host: www.example.org\r\n"
4363 "Connection: keep-alive\r\n\r\n"),
4364 };
4365
4366 MockRead data_reads1[] = {
4367 MockRead("HTTP/1.1 401 Authentication Required\r\n"
4368 "WWW-Authenticate: Mock\r\n"
4369 "Connection: keep-alive\r\n\r\n"),
4370 };
4371
4372 // Identical to data_writes1[]. The AuthHandler encounters a
4373 // ERR_INVALID_AUTH_CREDENTIALS during the GenerateAuthToken stage, so the
4374 // transaction procceds without an authorization header.
4375 MockWrite data_writes2[] = {
4376 MockWrite("GET / HTTP/1.1\r\n"
4377 "Host: www.example.org\r\n"
4378 "Connection: keep-alive\r\n\r\n"),
4379 };
4380
4381 MockRead data_reads2[] = {
4382 MockRead("HTTP/1.1 401 Authentication Required\r\n"
4383 "WWW-Authenticate: Mock\r\n"
4384 "Connection: keep-alive\r\n\r\n"),
4385 };
4386
4387 MockWrite data_writes3[] = {
4388 MockWrite("GET / HTTP/1.1\r\n"
4389 "Host: www.example.org\r\n"
4390 "Connection: keep-alive\r\n"
4391 "Authorization: auth_token\r\n\r\n"),
4392 };
4393
4394 MockRead data_reads3[] = {
4395 MockRead("HTTP/1.1 200 OK\r\n"
4396 "Content-Length: 5\r\n"
4397 "Content-Type: text/plain\r\n"
4398 "Connection: keep-alive\r\n\r\n"
4399 "Hello"),
4400 };
4401
4402 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
4403 data_writes1, arraysize(data_writes1));
4404 session_deps_.socket_factory->AddSocketDataProvider(&data1);
4405
4406 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
4407 data_writes2, arraysize(data_writes2));
4408 session_deps_.socket_factory->AddSocketDataProvider(&data2);
4409
4410 StaticSocketDataProvider data3(data_reads3, arraysize(data_reads3),
4411 data_writes3, arraysize(data_writes3));
4412 session_deps_.socket_factory->AddSocketDataProvider(&data3);
4413
bnc87dcefc2017-05-25 12:47:584414 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:194415 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
asankae2257db2016-10-11 22:03:164416
4417 TestCompletionCallback callback;
4418 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
4419 EXPECT_THAT(callback.GetResult(rv), IsOk());
4420
4421 const HttpResponseInfo* response = trans->GetResponseInfo();
4422 ASSERT_TRUE(response);
4423 ASSERT_TRUE(response->headers);
4424 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
4425
4426 // The following three tests assert that an authentication challenge was
4427 // received and that the stack is ready to respond to the challenge using
4428 // ambient credentials.
4429 EXPECT_EQ(401, response->headers->response_code());
4430 EXPECT_TRUE(trans->IsReadyToRestartForAuth());
4431 EXPECT_FALSE(response->auth_challenge);
4432
4433 rv = trans->RestartWithAuth(AuthCredentials(), callback.callback());
4434 EXPECT_THAT(callback.GetResult(rv), IsOk());
4435 response = trans->GetResponseInfo();
4436 ASSERT_TRUE(response);
4437 ASSERT_TRUE(response->headers);
4438
4439 // The following three tests assert that an authentication challenge was
4440 // received and that the stack needs explicit credentials before it is ready
4441 // to respond to the challenge.
4442 EXPECT_EQ(401, response->headers->response_code());
4443 EXPECT_FALSE(trans->IsReadyToRestartForAuth());
4444 EXPECT_TRUE(response->auth_challenge);
4445
4446 rv = trans->RestartWithAuth(AuthCredentials(), callback.callback());
4447 EXPECT_THAT(callback.GetResult(rv), IsOk());
4448 response = trans->GetResponseInfo();
4449 ASSERT_TRUE(response);
4450 ASSERT_TRUE(response->headers);
4451 EXPECT_EQ(200, response->headers->response_code());
4452
4453 trans.reset();
4454 session->CloseAllConnections();
4455}
4456
[email protected]029c83b62013-01-24 05:28:204457// Test the load timing for HTTPS requests with an HTTP proxy.
bncd16676a2016-07-20 16:23:014458TEST_F(HttpNetworkTransactionTest, HttpProxyLoadTimingNoPacTwoRequests) {
[email protected]029c83b62013-01-24 05:28:204459 HttpRequestInfo request1;
4460 request1.method = "GET";
bncce36dca22015-04-21 22:11:234461 request1.url = GURL("https://www.example.org/1");
[email protected]029c83b62013-01-24 05:28:204462
4463 HttpRequestInfo request2;
4464 request2.method = "GET";
bncce36dca22015-04-21 22:11:234465 request2.url = GURL("https://www.example.org/2");
[email protected]029c83b62013-01-24 05:28:204466
4467 // Configure against proxy server "myproxy:70".
brettwc1213d92016-11-12 03:41:134468 session_deps_.proxy_service = ProxyService::CreateFixed("myproxy:70");
vishal.b62985ca92015-04-17 08:45:514469 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:074470 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:094471 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]029c83b62013-01-24 05:28:204472
4473 // Since we have proxy, should try to establish tunnel.
4474 MockWrite data_writes1[] = {
rsleevidb16bb02015-11-12 23:47:174475 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
4476 "Host: www.example.org:443\r\n"
4477 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]029c83b62013-01-24 05:28:204478
rsleevidb16bb02015-11-12 23:47:174479 MockWrite("GET /1 HTTP/1.1\r\n"
4480 "Host: www.example.org\r\n"
4481 "Connection: keep-alive\r\n\r\n"),
[email protected]029c83b62013-01-24 05:28:204482
rsleevidb16bb02015-11-12 23:47:174483 MockWrite("GET /2 HTTP/1.1\r\n"
4484 "Host: www.example.org\r\n"
4485 "Connection: keep-alive\r\n\r\n"),
[email protected]029c83b62013-01-24 05:28:204486 };
4487
4488 // The proxy responds to the connect with a 407, using a persistent
4489 // connection.
4490 MockRead data_reads1[] = {
4491 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
4492
4493 MockRead("HTTP/1.1 200 OK\r\n"),
4494 MockRead("Content-Length: 1\r\n\r\n"),
4495 MockRead(SYNCHRONOUS, "1"),
4496
4497 MockRead("HTTP/1.1 200 OK\r\n"),
4498 MockRead("Content-Length: 2\r\n\r\n"),
4499 MockRead(SYNCHRONOUS, "22"),
4500 };
4501
4502 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
4503 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:074504 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]029c83b62013-01-24 05:28:204505 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:074506 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]029c83b62013-01-24 05:28:204507
4508 TestCompletionCallback callback1;
bnc87dcefc2017-05-25 12:47:584509 auto trans1 =
Jeremy Roman0579ed62017-08-29 15:56:194510 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]029c83b62013-01-24 05:28:204511
4512 int rv = trans1->Start(&request1, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:014513 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]029c83b62013-01-24 05:28:204514
4515 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:014516 EXPECT_THAT(rv, IsOk());
[email protected]029c83b62013-01-24 05:28:204517
4518 const HttpResponseInfo* response1 = trans1->GetResponseInfo();
wezca1070932016-05-26 20:30:524519 ASSERT_TRUE(response1);
tbansal2ecbbc72016-10-06 17:15:474520 EXPECT_TRUE(response1->proxy_server.is_http());
wezca1070932016-05-26 20:30:524521 ASSERT_TRUE(response1->headers);
[email protected]029c83b62013-01-24 05:28:204522 EXPECT_EQ(1, response1->headers->GetContentLength());
4523
4524 LoadTimingInfo load_timing_info1;
4525 EXPECT_TRUE(trans1->GetLoadTimingInfo(&load_timing_info1));
4526 TestLoadTimingNotReused(load_timing_info1, CONNECT_TIMING_HAS_SSL_TIMES);
4527
4528 trans1.reset();
4529
4530 TestCompletionCallback callback2;
bnc87dcefc2017-05-25 12:47:584531 auto trans2 =
Jeremy Roman0579ed62017-08-29 15:56:194532 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]029c83b62013-01-24 05:28:204533
4534 rv = trans2->Start(&request2, callback2.callback(), log.bound());
robpercival214763f2016-07-01 23:27:014535 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]029c83b62013-01-24 05:28:204536
4537 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:014538 EXPECT_THAT(rv, IsOk());
[email protected]029c83b62013-01-24 05:28:204539
4540 const HttpResponseInfo* response2 = trans2->GetResponseInfo();
wezca1070932016-05-26 20:30:524541 ASSERT_TRUE(response2);
tbansal2ecbbc72016-10-06 17:15:474542 EXPECT_TRUE(response2->proxy_server.is_http());
wezca1070932016-05-26 20:30:524543 ASSERT_TRUE(response2->headers);
[email protected]029c83b62013-01-24 05:28:204544 EXPECT_EQ(2, response2->headers->GetContentLength());
4545
4546 LoadTimingInfo load_timing_info2;
4547 EXPECT_TRUE(trans2->GetLoadTimingInfo(&load_timing_info2));
4548 TestLoadTimingReused(load_timing_info2);
4549
4550 EXPECT_EQ(load_timing_info1.socket_log_id, load_timing_info2.socket_log_id);
4551
4552 trans2.reset();
4553 session->CloseAllConnections();
4554}
4555
4556// Test the load timing for HTTPS requests with an HTTP proxy and a PAC script.
bncd16676a2016-07-20 16:23:014557TEST_F(HttpNetworkTransactionTest, HttpProxyLoadTimingWithPacTwoRequests) {
[email protected]029c83b62013-01-24 05:28:204558 HttpRequestInfo request1;
4559 request1.method = "GET";
bncce36dca22015-04-21 22:11:234560 request1.url = GURL("https://www.example.org/1");
[email protected]029c83b62013-01-24 05:28:204561
4562 HttpRequestInfo request2;
4563 request2.method = "GET";
bncce36dca22015-04-21 22:11:234564 request2.url = GURL("https://www.example.org/2");
[email protected]029c83b62013-01-24 05:28:204565
4566 // Configure against proxy server "myproxy:70".
rdsmith82957ad2015-09-16 19:42:034567 session_deps_.proxy_service =
4568 ProxyService::CreateFixedFromPacResult("PROXY myproxy:70");
vishal.b62985ca92015-04-17 08:45:514569 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:074570 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:094571 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]029c83b62013-01-24 05:28:204572
4573 // Since we have proxy, should try to establish tunnel.
4574 MockWrite data_writes1[] = {
rsleevidb16bb02015-11-12 23:47:174575 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
4576 "Host: www.example.org:443\r\n"
4577 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]029c83b62013-01-24 05:28:204578
rsleevidb16bb02015-11-12 23:47:174579 MockWrite("GET /1 HTTP/1.1\r\n"
4580 "Host: www.example.org\r\n"
4581 "Connection: keep-alive\r\n\r\n"),
[email protected]029c83b62013-01-24 05:28:204582
rsleevidb16bb02015-11-12 23:47:174583 MockWrite("GET /2 HTTP/1.1\r\n"
4584 "Host: www.example.org\r\n"
4585 "Connection: keep-alive\r\n\r\n"),
[email protected]029c83b62013-01-24 05:28:204586 };
4587
4588 // The proxy responds to the connect with a 407, using a persistent
4589 // connection.
4590 MockRead data_reads1[] = {
4591 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
4592
4593 MockRead("HTTP/1.1 200 OK\r\n"),
4594 MockRead("Content-Length: 1\r\n\r\n"),
4595 MockRead(SYNCHRONOUS, "1"),
4596
4597 MockRead("HTTP/1.1 200 OK\r\n"),
4598 MockRead("Content-Length: 2\r\n\r\n"),
4599 MockRead(SYNCHRONOUS, "22"),
4600 };
4601
4602 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
4603 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:074604 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]029c83b62013-01-24 05:28:204605 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:074606 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]029c83b62013-01-24 05:28:204607
4608 TestCompletionCallback callback1;
bnc87dcefc2017-05-25 12:47:584609 auto trans1 =
Jeremy Roman0579ed62017-08-29 15:56:194610 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]029c83b62013-01-24 05:28:204611
4612 int rv = trans1->Start(&request1, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:014613 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]029c83b62013-01-24 05:28:204614
4615 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:014616 EXPECT_THAT(rv, IsOk());
[email protected]029c83b62013-01-24 05:28:204617
4618 const HttpResponseInfo* response1 = trans1->GetResponseInfo();
wezca1070932016-05-26 20:30:524619 ASSERT_TRUE(response1);
4620 ASSERT_TRUE(response1->headers);
[email protected]029c83b62013-01-24 05:28:204621 EXPECT_EQ(1, response1->headers->GetContentLength());
4622
4623 LoadTimingInfo load_timing_info1;
4624 EXPECT_TRUE(trans1->GetLoadTimingInfo(&load_timing_info1));
4625 TestLoadTimingNotReusedWithPac(load_timing_info1,
4626 CONNECT_TIMING_HAS_SSL_TIMES);
4627
4628 trans1.reset();
4629
4630 TestCompletionCallback callback2;
bnc87dcefc2017-05-25 12:47:584631 auto trans2 =
Jeremy Roman0579ed62017-08-29 15:56:194632 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]029c83b62013-01-24 05:28:204633
4634 rv = trans2->Start(&request2, callback2.callback(), log.bound());
robpercival214763f2016-07-01 23:27:014635 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]029c83b62013-01-24 05:28:204636
4637 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:014638 EXPECT_THAT(rv, IsOk());
[email protected]029c83b62013-01-24 05:28:204639
4640 const HttpResponseInfo* response2 = trans2->GetResponseInfo();
wezca1070932016-05-26 20:30:524641 ASSERT_TRUE(response2);
4642 ASSERT_TRUE(response2->headers);
[email protected]029c83b62013-01-24 05:28:204643 EXPECT_EQ(2, response2->headers->GetContentLength());
4644
4645 LoadTimingInfo load_timing_info2;
4646 EXPECT_TRUE(trans2->GetLoadTimingInfo(&load_timing_info2));
4647 TestLoadTimingReusedWithPac(load_timing_info2);
4648
4649 EXPECT_EQ(load_timing_info1.socket_log_id, load_timing_info2.socket_log_id);
4650
4651 trans2.reset();
4652 session->CloseAllConnections();
4653}
4654
[email protected]2df19bb2010-08-25 20:13:464655// Test a simple get through an HTTPS Proxy.
bncd16676a2016-07-20 16:23:014656TEST_F(HttpNetworkTransactionTest, HttpsProxyGet) {
[email protected]cb9bf6ca2011-01-28 13:15:274657 HttpRequestInfo request;
4658 request.method = "GET";
bncce36dca22015-04-21 22:11:234659 request.url = GURL("http://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:274660
[email protected]2df19bb2010-08-25 20:13:464661 // Configure against https proxy server "proxy:70".
rdsmith82957ad2015-09-16 19:42:034662 session_deps_.proxy_service = ProxyService::CreateFixed("https://proxy:70");
vishal.b62985ca92015-04-17 08:45:514663 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:074664 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:094665 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]2df19bb2010-08-25 20:13:464666
[email protected]2df19bb2010-08-25 20:13:464667 // Since we have proxy, should use full url
4668 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:234669 MockWrite(
4670 "GET http://www.example.org/ HTTP/1.1\r\n"
4671 "Host: www.example.org\r\n"
4672 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]2df19bb2010-08-25 20:13:464673 };
4674
4675 MockRead data_reads1[] = {
4676 MockRead("HTTP/1.1 200 OK\r\n"),
4677 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
4678 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:064679 MockRead(SYNCHRONOUS, OK),
[email protected]2df19bb2010-08-25 20:13:464680 };
4681
4682 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
4683 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:074684 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8ddf8322012-02-23 18:08:064685 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:074686 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]2df19bb2010-08-25 20:13:464687
[email protected]49639fa2011-12-20 23:22:414688 TestCompletionCallback callback1;
[email protected]2df19bb2010-08-25 20:13:464689
bnc691fda62016-08-12 00:43:164690 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]0b0bf032010-09-21 18:08:504691
bnc691fda62016-08-12 00:43:164692 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:014693 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2df19bb2010-08-25 20:13:464694
4695 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:014696 EXPECT_THAT(rv, IsOk());
[email protected]2df19bb2010-08-25 20:13:464697
[email protected]58e32bb2013-01-21 18:23:254698 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:164699 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]58e32bb2013-01-21 18:23:254700 TestLoadTimingNotReused(load_timing_info,
4701 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
4702
bnc691fda62016-08-12 00:43:164703 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:524704 ASSERT_TRUE(response);
[email protected]2df19bb2010-08-25 20:13:464705
tbansal2ecbbc72016-10-06 17:15:474706 EXPECT_TRUE(response->proxy_server.is_https());
[email protected]2df19bb2010-08-25 20:13:464707 EXPECT_TRUE(response->headers->IsKeepAlive());
4708 EXPECT_EQ(200, response->headers->response_code());
4709 EXPECT_EQ(100, response->headers->GetContentLength());
4710 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
4711
4712 // The password prompt info should not be set.
wezca1070932016-05-26 20:30:524713 EXPECT_FALSE(response->auth_challenge);
[email protected]2df19bb2010-08-25 20:13:464714}
4715
[email protected]7642b5ae2010-09-01 20:55:174716// Test a SPDY get through an HTTPS Proxy.
bncd16676a2016-07-20 16:23:014717TEST_F(HttpNetworkTransactionTest, HttpsProxySpdyGet) {
[email protected]cb9bf6ca2011-01-28 13:15:274718 HttpRequestInfo request;
4719 request.method = "GET";
bncce36dca22015-04-21 22:11:234720 request.url = GURL("http://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:274721
[email protected]7642b5ae2010-09-01 20:55:174722 // Configure against https proxy server "proxy:70".
rdsmith82957ad2015-09-16 19:42:034723 session_deps_.proxy_service = ProxyService::CreateFixed("https://proxy:70");
vishal.b62985ca92015-04-17 08:45:514724 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:074725 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:094726 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]7642b5ae2010-09-01 20:55:174727
bncce36dca22015-04-21 22:11:234728 // fetch http://www.example.org/ via SPDY
bncdf80d44fd2016-07-15 20:27:414729 SpdySerializedFrame req(
bncb26024382016-06-29 02:39:454730 spdy_util_.ConstructSpdyGet("http://www.example.org/", 1, LOWEST));
bncdf80d44fd2016-07-15 20:27:414731 MockWrite spdy_writes[] = {CreateMockWrite(req, 0)};
[email protected]7642b5ae2010-09-01 20:55:174732
bnc42331402016-07-25 13:36:154733 SpdySerializedFrame resp(spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
bncdf80d44fd2016-07-15 20:27:414734 SpdySerializedFrame data(spdy_util_.ConstructSpdyDataFrame(1, true));
[email protected]7642b5ae2010-09-01 20:55:174735 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:414736 CreateMockRead(resp, 1), CreateMockRead(data, 2), MockRead(ASYNC, 0, 3),
[email protected]7642b5ae2010-09-01 20:55:174737 };
4738
rch8e6c6c42015-05-01 14:05:134739 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
4740 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:074741 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]7642b5ae2010-09-01 20:55:174742
[email protected]8ddf8322012-02-23 18:08:064743 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:364744 ssl.next_proto = kProtoHTTP2;
[email protected]bb88e1d32013-05-03 23:11:074745 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]7642b5ae2010-09-01 20:55:174746
[email protected]49639fa2011-12-20 23:22:414747 TestCompletionCallback callback1;
[email protected]7642b5ae2010-09-01 20:55:174748
bnc691fda62016-08-12 00:43:164749 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]0b0bf032010-09-21 18:08:504750
bnc691fda62016-08-12 00:43:164751 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:014752 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]7642b5ae2010-09-01 20:55:174753
4754 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:014755 EXPECT_THAT(rv, IsOk());
[email protected]7642b5ae2010-09-01 20:55:174756
[email protected]58e32bb2013-01-21 18:23:254757 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:164758 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]58e32bb2013-01-21 18:23:254759 TestLoadTimingNotReused(load_timing_info,
4760 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
4761
bnc691fda62016-08-12 00:43:164762 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:524763 ASSERT_TRUE(response);
tbansal2ecbbc72016-10-06 17:15:474764 EXPECT_TRUE(response->proxy_server.is_https());
wezca1070932016-05-26 20:30:524765 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:024766 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]7642b5ae2010-09-01 20:55:174767
4768 std::string response_data;
bnc691fda62016-08-12 00:43:164769 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
[email protected]448d4ca52012-03-04 04:12:234770 EXPECT_EQ(kUploadData, response_data);
[email protected]7642b5ae2010-09-01 20:55:174771}
4772
[email protected]1c173852014-06-19 12:51:504773// Verifies that a session which races and wins against the owning transaction
4774// (completing prior to host resolution), doesn't fail the transaction.
4775// Regression test for crbug.com/334413.
bncd16676a2016-07-20 16:23:014776TEST_F(HttpNetworkTransactionTest, HttpsProxySpdyGetWithSessionRace) {
[email protected]1c173852014-06-19 12:51:504777 HttpRequestInfo request;
4778 request.method = "GET";
bncce36dca22015-04-21 22:11:234779 request.url = GURL("http://www.example.org/");
[email protected]1c173852014-06-19 12:51:504780
4781 // Configure SPDY proxy server "proxy:70".
rdsmith82957ad2015-09-16 19:42:034782 session_deps_.proxy_service = ProxyService::CreateFixed("https://proxy:70");
vishal.b62985ca92015-04-17 08:45:514783 BoundTestNetLog log;
[email protected]1c173852014-06-19 12:51:504784 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:094785 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]1c173852014-06-19 12:51:504786
bncce36dca22015-04-21 22:11:234787 // Fetch http://www.example.org/ through the SPDY proxy.
bncdf80d44fd2016-07-15 20:27:414788 SpdySerializedFrame req(
bncb26024382016-06-29 02:39:454789 spdy_util_.ConstructSpdyGet("http://www.example.org/", 1, LOWEST));
bncdf80d44fd2016-07-15 20:27:414790 MockWrite spdy_writes[] = {CreateMockWrite(req, 0)};
[email protected]1c173852014-06-19 12:51:504791
bnc42331402016-07-25 13:36:154792 SpdySerializedFrame resp(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
bncdf80d44fd2016-07-15 20:27:414793 SpdySerializedFrame data(spdy_util_.ConstructSpdyDataFrame(1, true));
[email protected]1c173852014-06-19 12:51:504794 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:414795 CreateMockRead(resp, 1), CreateMockRead(data, 2), MockRead(ASYNC, 0, 3),
[email protected]1c173852014-06-19 12:51:504796 };
4797
rch8e6c6c42015-05-01 14:05:134798 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
4799 arraysize(spdy_writes));
[email protected]1c173852014-06-19 12:51:504800 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
4801
4802 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:364803 ssl.next_proto = kProtoHTTP2;
[email protected]1c173852014-06-19 12:51:504804 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
4805
4806 TestCompletionCallback callback1;
4807
bnc691fda62016-08-12 00:43:164808 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]1c173852014-06-19 12:51:504809
4810 // Stall the hostname resolution begun by the transaction.
4811 session_deps_.host_resolver->set_synchronous_mode(false);
4812 session_deps_.host_resolver->set_ondemand_mode(true);
4813
bnc691fda62016-08-12 00:43:164814 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:014815 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]1c173852014-06-19 12:51:504816
4817 // Race a session to the proxy, which completes first.
4818 session_deps_.host_resolver->set_ondemand_mode(false);
4819 SpdySessionKey key(
4820 HostPortPair("proxy", 70), ProxyServer::Direct(), PRIVACY_MODE_DISABLED);
4821 base::WeakPtr<SpdySession> spdy_session =
Bence Béky0ef1556e2017-06-30 19:52:524822 CreateSpdySession(session.get(), key, log.bound());
[email protected]1c173852014-06-19 12:51:504823
4824 // Unstall the resolution begun by the transaction.
4825 session_deps_.host_resolver->set_ondemand_mode(true);
4826 session_deps_.host_resolver->ResolveAllPending();
4827
4828 EXPECT_FALSE(callback1.have_result());
4829 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:014830 EXPECT_THAT(rv, IsOk());
[email protected]1c173852014-06-19 12:51:504831
bnc691fda62016-08-12 00:43:164832 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:524833 ASSERT_TRUE(response);
4834 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:024835 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]1c173852014-06-19 12:51:504836
4837 std::string response_data;
bnc691fda62016-08-12 00:43:164838 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
[email protected]1c173852014-06-19 12:51:504839 EXPECT_EQ(kUploadData, response_data);
4840}
4841
[email protected]dc7bd1c52010-11-12 00:01:134842// Test a SPDY get through an HTTPS Proxy.
bncd16676a2016-07-20 16:23:014843TEST_F(HttpNetworkTransactionTest, HttpsProxySpdyGetWithProxyAuth) {
[email protected]cb9bf6ca2011-01-28 13:15:274844 HttpRequestInfo request;
4845 request.method = "GET";
bncce36dca22015-04-21 22:11:234846 request.url = GURL("http://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:274847
[email protected]79cb5c12011-09-12 13:12:044848 // Configure against https proxy server "myproxy:70".
rdsmith82957ad2015-09-16 19:42:034849 session_deps_.proxy_service = ProxyService::CreateFixed("https://myproxy:70");
vishal.b62985ca92015-04-17 08:45:514850 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:074851 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:094852 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]dc7bd1c52010-11-12 00:01:134853
[email protected]dc7bd1c52010-11-12 00:01:134854 // The first request will be a bare GET, the second request will be a
4855 // GET with a Proxy-Authorization header.
bncb26024382016-06-29 02:39:454856 spdy_util_.set_default_url(request.url);
bncdf80d44fd2016-07-15 20:27:414857 SpdySerializedFrame req_get(
bnc38dcd392016-02-09 23:19:494858 spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST, false));
rdsmithebb50aa2015-11-12 03:44:384859 spdy_util_.UpdateWithStreamDestruction(1);
[email protected]dc7bd1c52010-11-12 00:01:134860 const char* const kExtraAuthorizationHeaders[] = {
[email protected]cdf8f7e72013-05-23 10:56:464861 "proxy-authorization", "Basic Zm9vOmJhcg=="
[email protected]dc7bd1c52010-11-12 00:01:134862 };
bncdf80d44fd2016-07-15 20:27:414863 SpdySerializedFrame req_get_authorization(spdy_util_.ConstructSpdyGet(
4864 kExtraAuthorizationHeaders, arraysize(kExtraAuthorizationHeaders) / 2, 3,
4865 LOWEST, false));
[email protected]dc7bd1c52010-11-12 00:01:134866 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:414867 CreateMockWrite(req_get, 0), CreateMockWrite(req_get_authorization, 3),
[email protected]dc7bd1c52010-11-12 00:01:134868 };
4869
4870 // The first response is a 407 proxy authentication challenge, and the second
4871 // response will be a 200 response since the second request includes a valid
4872 // Authorization header.
4873 const char* const kExtraAuthenticationHeaders[] = {
[email protected]cdf8f7e72013-05-23 10:56:464874 "proxy-authenticate", "Basic realm=\"MyRealm1\""
[email protected]dc7bd1c52010-11-12 00:01:134875 };
bnc42331402016-07-25 13:36:154876 SpdySerializedFrame resp_authentication(spdy_util_.ConstructSpdyReplyError(
bncc9f762a2016-12-06 20:38:234877 "407", kExtraAuthenticationHeaders,
bncdf80d44fd2016-07-15 20:27:414878 arraysize(kExtraAuthenticationHeaders) / 2, 1));
4879 SpdySerializedFrame body_authentication(
4880 spdy_util_.ConstructSpdyDataFrame(1, true));
bnc42331402016-07-25 13:36:154881 SpdySerializedFrame resp_data(spdy_util_.ConstructSpdyGetReply(NULL, 0, 3));
bncdf80d44fd2016-07-15 20:27:414882 SpdySerializedFrame body_data(spdy_util_.ConstructSpdyDataFrame(3, true));
[email protected]dc7bd1c52010-11-12 00:01:134883 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:414884 CreateMockRead(resp_authentication, 1),
bnceb9aa7112017-01-05 01:03:464885 CreateMockRead(body_authentication, 2, SYNCHRONOUS),
bncdf80d44fd2016-07-15 20:27:414886 CreateMockRead(resp_data, 4),
4887 CreateMockRead(body_data, 5),
rch8e6c6c42015-05-01 14:05:134888 MockRead(ASYNC, 0, 6),
[email protected]dc7bd1c52010-11-12 00:01:134889 };
4890
rch8e6c6c42015-05-01 14:05:134891 SequencedSocketData data(spdy_reads, arraysize(spdy_reads), spdy_writes,
4892 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:074893 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]dc7bd1c52010-11-12 00:01:134894
[email protected]8ddf8322012-02-23 18:08:064895 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:364896 ssl.next_proto = kProtoHTTP2;
[email protected]bb88e1d32013-05-03 23:11:074897 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]dc7bd1c52010-11-12 00:01:134898
[email protected]49639fa2011-12-20 23:22:414899 TestCompletionCallback callback1;
[email protected]dc7bd1c52010-11-12 00:01:134900
bnc691fda62016-08-12 00:43:164901 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]dc7bd1c52010-11-12 00:01:134902
bnc691fda62016-08-12 00:43:164903 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:014904 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]dc7bd1c52010-11-12 00:01:134905
4906 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:014907 EXPECT_THAT(rv, IsOk());
[email protected]dc7bd1c52010-11-12 00:01:134908
bnc691fda62016-08-12 00:43:164909 const HttpResponseInfo* const response = trans.GetResponseInfo();
[email protected]dc7bd1c52010-11-12 00:01:134910
wezca1070932016-05-26 20:30:524911 ASSERT_TRUE(response);
4912 ASSERT_TRUE(response->headers);
[email protected]dc7bd1c52010-11-12 00:01:134913 EXPECT_EQ(407, response->headers->response_code());
4914 EXPECT_TRUE(response->was_fetched_via_spdy);
asanka098c0092016-06-16 20:18:434915 EXPECT_TRUE(CheckBasicSecureProxyAuth(response->auth_challenge.get()));
[email protected]dc7bd1c52010-11-12 00:01:134916
[email protected]49639fa2011-12-20 23:22:414917 TestCompletionCallback callback2;
[email protected]dc7bd1c52010-11-12 00:01:134918
bnc691fda62016-08-12 00:43:164919 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar), callback2.callback());
robpercival214763f2016-07-01 23:27:014920 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]dc7bd1c52010-11-12 00:01:134921
4922 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:014923 EXPECT_THAT(rv, IsOk());
[email protected]dc7bd1c52010-11-12 00:01:134924
bnc691fda62016-08-12 00:43:164925 const HttpResponseInfo* const response_restart = trans.GetResponseInfo();
[email protected]dc7bd1c52010-11-12 00:01:134926
wezca1070932016-05-26 20:30:524927 ASSERT_TRUE(response_restart);
4928 ASSERT_TRUE(response_restart->headers);
[email protected]dc7bd1c52010-11-12 00:01:134929 EXPECT_EQ(200, response_restart->headers->response_code());
4930 // The password prompt info should not be set.
wezca1070932016-05-26 20:30:524931 EXPECT_FALSE(response_restart->auth_challenge);
[email protected]dc7bd1c52010-11-12 00:01:134932}
4933
[email protected]d9da5fe2010-10-13 22:37:164934// Test a SPDY CONNECT through an HTTPS Proxy to an HTTPS (non-SPDY) Server.
bncd16676a2016-07-20 16:23:014935TEST_F(HttpNetworkTransactionTest, HttpsProxySpdyConnectHttps) {
[email protected]cb9bf6ca2011-01-28 13:15:274936 HttpRequestInfo request;
4937 request.method = "GET";
bncce36dca22015-04-21 22:11:234938 request.url = GURL("https://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:274939
[email protected]d9da5fe2010-10-13 22:37:164940 // Configure against https proxy server "proxy:70".
rdsmith82957ad2015-09-16 19:42:034941 session_deps_.proxy_service = ProxyService::CreateFixed("https://proxy:70");
vishal.b62985ca92015-04-17 08:45:514942 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:074943 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:094944 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]d9da5fe2010-10-13 22:37:164945
bnc691fda62016-08-12 00:43:164946 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]d9da5fe2010-10-13 22:37:164947
bncce36dca22015-04-21 22:11:234948 // CONNECT to www.example.org:443 via SPDY
bncdf80d44fd2016-07-15 20:27:414949 SpdySerializedFrame connect(spdy_util_.ConstructSpdyConnect(
bncce36dca22015-04-21 22:11:234950 NULL, 0, 1, LOWEST, HostPortPair("www.example.org", 443)));
4951 // fetch https://www.example.org/ via HTTP
[email protected]d9da5fe2010-10-13 22:37:164952
bncce36dca22015-04-21 22:11:234953 const char get[] =
4954 "GET / HTTP/1.1\r\n"
4955 "Host: www.example.org\r\n"
4956 "Connection: keep-alive\r\n\r\n";
bncdf80d44fd2016-07-15 20:27:414957 SpdySerializedFrame wrapped_get(
4958 spdy_util_.ConstructSpdyDataFrame(1, get, strlen(get), false));
bnc42331402016-07-25 13:36:154959 SpdySerializedFrame conn_resp(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
[email protected]d9da5fe2010-10-13 22:37:164960 const char resp[] = "HTTP/1.1 200 OK\r\n"
4961 "Content-Length: 10\r\n\r\n";
bncdf80d44fd2016-07-15 20:27:414962 SpdySerializedFrame wrapped_get_resp(
4963 spdy_util_.ConstructSpdyDataFrame(1, resp, strlen(resp), false));
4964 SpdySerializedFrame wrapped_body(
4965 spdy_util_.ConstructSpdyDataFrame(1, "1234567890", 10, false));
4966 SpdySerializedFrame window_update(
4967 spdy_util_.ConstructSpdyWindowUpdate(1, wrapped_get_resp.size()));
[email protected]8d2f7012012-02-16 00:08:044968
4969 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:414970 CreateMockWrite(connect, 0), CreateMockWrite(wrapped_get, 2),
4971 CreateMockWrite(window_update, 6),
[email protected]8d2f7012012-02-16 00:08:044972 };
4973
[email protected]d9da5fe2010-10-13 22:37:164974 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:414975 CreateMockRead(conn_resp, 1, ASYNC),
4976 CreateMockRead(wrapped_get_resp, 3, ASYNC),
4977 CreateMockRead(wrapped_body, 4, ASYNC),
4978 CreateMockRead(wrapped_body, 5, ASYNC),
rch8e6c6c42015-05-01 14:05:134979 MockRead(ASYNC, 0, 7),
[email protected]d9da5fe2010-10-13 22:37:164980 };
4981
rch8e6c6c42015-05-01 14:05:134982 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
4983 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:074984 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]d9da5fe2010-10-13 22:37:164985
[email protected]8ddf8322012-02-23 18:08:064986 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:364987 ssl.next_proto = kProtoHTTP2;
[email protected]bb88e1d32013-05-03 23:11:074988 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]8ddf8322012-02-23 18:08:064989 SSLSocketDataProvider ssl2(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:074990 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
[email protected]d9da5fe2010-10-13 22:37:164991
[email protected]49639fa2011-12-20 23:22:414992 TestCompletionCallback callback1;
[email protected]d9da5fe2010-10-13 22:37:164993
bnc691fda62016-08-12 00:43:164994 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:014995 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]d9da5fe2010-10-13 22:37:164996
4997 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:014998 ASSERT_THAT(rv, IsOk());
[email protected]d9da5fe2010-10-13 22:37:164999
[email protected]58e32bb2013-01-21 18:23:255000 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:165001 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]58e32bb2013-01-21 18:23:255002 TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_SSL_TIMES);
5003
bnc691fda62016-08-12 00:43:165004 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:525005 ASSERT_TRUE(response);
5006 ASSERT_TRUE(response->headers);
[email protected]d9da5fe2010-10-13 22:37:165007 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
5008
5009 std::string response_data;
bnc691fda62016-08-12 00:43:165010 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
[email protected]d9da5fe2010-10-13 22:37:165011 EXPECT_EQ("1234567890", response_data);
5012}
5013
5014// Test a SPDY CONNECT through an HTTPS Proxy to a SPDY server.
bncd16676a2016-07-20 16:23:015015TEST_F(HttpNetworkTransactionTest, HttpsProxySpdyConnectSpdy) {
5016 SpdyTestUtil spdy_util_wrapped;
rdsmithebb50aa2015-11-12 03:44:385017
[email protected]cb9bf6ca2011-01-28 13:15:275018 HttpRequestInfo request;
5019 request.method = "GET";
bncce36dca22015-04-21 22:11:235020 request.url = GURL("https://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:275021
[email protected]d9da5fe2010-10-13 22:37:165022 // Configure against https proxy server "proxy:70".
rdsmith82957ad2015-09-16 19:42:035023 session_deps_.proxy_service = ProxyService::CreateFixed("https://proxy:70");
vishal.b62985ca92015-04-17 08:45:515024 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:075025 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:095026 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]d9da5fe2010-10-13 22:37:165027
bnc691fda62016-08-12 00:43:165028 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]d9da5fe2010-10-13 22:37:165029
bncce36dca22015-04-21 22:11:235030 // CONNECT to www.example.org:443 via SPDY
bncdf80d44fd2016-07-15 20:27:415031 SpdySerializedFrame connect(spdy_util_.ConstructSpdyConnect(
bncce36dca22015-04-21 22:11:235032 NULL, 0, 1, LOWEST, HostPortPair("www.example.org", 443)));
5033 // fetch https://www.example.org/ via SPDY
5034 const char kMyUrl[] = "https://www.example.org/";
bncdf80d44fd2016-07-15 20:27:415035 SpdySerializedFrame get(
bnc38dcd392016-02-09 23:19:495036 spdy_util_wrapped.ConstructSpdyGet(kMyUrl, 1, LOWEST));
bncdf80d44fd2016-07-15 20:27:415037 SpdySerializedFrame wrapped_get(spdy_util_.ConstructWrappedSpdyFrame(get, 1));
bnc42331402016-07-25 13:36:155038 SpdySerializedFrame conn_resp(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
bncdf80d44fd2016-07-15 20:27:415039 SpdySerializedFrame get_resp(
bnc42331402016-07-25 13:36:155040 spdy_util_wrapped.ConstructSpdyGetReply(NULL, 0, 1));
bncdf80d44fd2016-07-15 20:27:415041 SpdySerializedFrame wrapped_get_resp(
[email protected]23e482282013-06-14 16:08:025042 spdy_util_.ConstructWrappedSpdyFrame(get_resp, 1));
bncdf80d44fd2016-07-15 20:27:415043 SpdySerializedFrame body(spdy_util_wrapped.ConstructSpdyDataFrame(1, true));
5044 SpdySerializedFrame wrapped_body(
[email protected]23e482282013-06-14 16:08:025045 spdy_util_.ConstructWrappedSpdyFrame(body, 1));
bncdf80d44fd2016-07-15 20:27:415046 SpdySerializedFrame window_update_get_resp(
5047 spdy_util_.ConstructSpdyWindowUpdate(1, wrapped_get_resp.size()));
5048 SpdySerializedFrame window_update_body(
5049 spdy_util_.ConstructSpdyWindowUpdate(1, wrapped_body.size()));
[email protected]8d2f7012012-02-16 00:08:045050
5051 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:415052 CreateMockWrite(connect, 0), CreateMockWrite(wrapped_get, 2),
5053 CreateMockWrite(window_update_get_resp, 6),
5054 CreateMockWrite(window_update_body, 7),
[email protected]8d2f7012012-02-16 00:08:045055 };
5056
[email protected]d9da5fe2010-10-13 22:37:165057 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:415058 CreateMockRead(conn_resp, 1, ASYNC),
rch32320842015-05-16 15:57:095059 MockRead(ASYNC, ERR_IO_PENDING, 3),
bncdf80d44fd2016-07-15 20:27:415060 CreateMockRead(wrapped_get_resp, 4, ASYNC),
5061 CreateMockRead(wrapped_body, 5, ASYNC),
rch8e6c6c42015-05-01 14:05:135062 MockRead(ASYNC, 0, 8),
[email protected]d9da5fe2010-10-13 22:37:165063 };
5064
rch32320842015-05-16 15:57:095065 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
5066 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:075067 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]d9da5fe2010-10-13 22:37:165068
[email protected]8ddf8322012-02-23 18:08:065069 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:365070 ssl.next_proto = kProtoHTTP2;
[email protected]bb88e1d32013-05-03 23:11:075071 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]8ddf8322012-02-23 18:08:065072 SSLSocketDataProvider ssl2(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:365073 ssl2.next_proto = kProtoHTTP2;
[email protected]bb88e1d32013-05-03 23:11:075074 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
[email protected]d9da5fe2010-10-13 22:37:165075
[email protected]49639fa2011-12-20 23:22:415076 TestCompletionCallback callback1;
[email protected]d9da5fe2010-10-13 22:37:165077
bnc691fda62016-08-12 00:43:165078 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:015079 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]d9da5fe2010-10-13 22:37:165080
rch32320842015-05-16 15:57:095081 // Allow the SpdyProxyClientSocket's write callback to complete.
fdoray92e35a72016-06-10 15:54:555082 base::RunLoop().RunUntilIdle();
rch32320842015-05-16 15:57:095083 // Now allow the read of the response to complete.
mmenkee24011922015-12-17 22:12:595084 spdy_data.Resume();
[email protected]d9da5fe2010-10-13 22:37:165085 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:015086 EXPECT_THAT(rv, IsOk());
[email protected]d9da5fe2010-10-13 22:37:165087
[email protected]58e32bb2013-01-21 18:23:255088 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:165089 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]58e32bb2013-01-21 18:23:255090 TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_SSL_TIMES);
5091
bnc691fda62016-08-12 00:43:165092 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:525093 ASSERT_TRUE(response);
5094 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:025095 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]d9da5fe2010-10-13 22:37:165096
5097 std::string response_data;
bnc691fda62016-08-12 00:43:165098 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
[email protected]448d4ca52012-03-04 04:12:235099 EXPECT_EQ(kUploadData, response_data);
[email protected]d9da5fe2010-10-13 22:37:165100}
5101
5102// Test a SPDY CONNECT failure through an HTTPS Proxy.
bncd16676a2016-07-20 16:23:015103TEST_F(HttpNetworkTransactionTest, HttpsProxySpdyConnectFailure) {
[email protected]cb9bf6ca2011-01-28 13:15:275104 HttpRequestInfo request;
5105 request.method = "GET";
bncce36dca22015-04-21 22:11:235106 request.url = GURL("https://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:275107
[email protected]d9da5fe2010-10-13 22:37:165108 // Configure against https proxy server "proxy:70".
rdsmith82957ad2015-09-16 19:42:035109 session_deps_.proxy_service = ProxyService::CreateFixed("https://proxy:70");
vishal.b62985ca92015-04-17 08:45:515110 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:075111 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:095112 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]d9da5fe2010-10-13 22:37:165113
bnc691fda62016-08-12 00:43:165114 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]d9da5fe2010-10-13 22:37:165115
bncce36dca22015-04-21 22:11:235116 // CONNECT to www.example.org:443 via SPDY
bncdf80d44fd2016-07-15 20:27:415117 SpdySerializedFrame connect(spdy_util_.ConstructSpdyConnect(
bncce36dca22015-04-21 22:11:235118 NULL, 0, 1, LOWEST, HostPortPair("www.example.org", 443)));
bncdf80d44fd2016-07-15 20:27:415119 SpdySerializedFrame get(
diannahu9904e272017-02-03 14:40:085120 spdy_util_.ConstructSpdyRstStream(1, ERROR_CODE_CANCEL));
[email protected]d9da5fe2010-10-13 22:37:165121
5122 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:415123 CreateMockWrite(connect, 0), CreateMockWrite(get, 2),
[email protected]d9da5fe2010-10-13 22:37:165124 };
5125
bnc42331402016-07-25 13:36:155126 SpdySerializedFrame resp(spdy_util_.ConstructSpdyReplyError(1));
bncdf80d44fd2016-07-15 20:27:415127 SpdySerializedFrame data(spdy_util_.ConstructSpdyDataFrame(1, true));
[email protected]d9da5fe2010-10-13 22:37:165128 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:415129 CreateMockRead(resp, 1, ASYNC), MockRead(ASYNC, 0, 3),
[email protected]d9da5fe2010-10-13 22:37:165130 };
5131
rch8e6c6c42015-05-01 14:05:135132 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
5133 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:075134 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]d9da5fe2010-10-13 22:37:165135
[email protected]8ddf8322012-02-23 18:08:065136 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:365137 ssl.next_proto = kProtoHTTP2;
[email protected]bb88e1d32013-05-03 23:11:075138 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]8ddf8322012-02-23 18:08:065139 SSLSocketDataProvider ssl2(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:365140 ssl2.next_proto = kProtoHTTP2;
[email protected]bb88e1d32013-05-03 23:11:075141 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
[email protected]d9da5fe2010-10-13 22:37:165142
[email protected]49639fa2011-12-20 23:22:415143 TestCompletionCallback callback1;
[email protected]d9da5fe2010-10-13 22:37:165144
bnc691fda62016-08-12 00:43:165145 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:015146 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]d9da5fe2010-10-13 22:37:165147
5148 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:015149 EXPECT_THAT(rv, IsError(ERR_TUNNEL_CONNECTION_FAILED));
[email protected]d9da5fe2010-10-13 22:37:165150
ttuttle960fcbf2016-04-19 13:26:325151 // TODO(juliatuttle): Anything else to check here?
[email protected]d9da5fe2010-10-13 22:37:165152}
5153
[email protected]f6c63db52013-02-02 00:35:225154// Test load timing in the case of two HTTPS (non-SPDY) requests through a SPDY
5155// HTTPS Proxy to different servers.
bncd16676a2016-07-20 16:23:015156TEST_F(HttpNetworkTransactionTest,
[email protected]f6c63db52013-02-02 00:35:225157 HttpsProxySpdyConnectHttpsLoadTimingTwoRequestsTwoServers) {
5158 // Configure against https proxy server "proxy:70".
rdsmith82957ad2015-09-16 19:42:035159 session_deps_.proxy_service = ProxyService::CreateFixed("https://proxy:70");
vishal.b62985ca92015-04-17 08:45:515160 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:075161 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:095162 std::unique_ptr<HttpNetworkSession> session(
mmenke11eb5152015-06-09 14:50:505163 SpdySessionDependencies::SpdyCreateSession(&session_deps_));
[email protected]f6c63db52013-02-02 00:35:225164
5165 HttpRequestInfo request1;
5166 request1.method = "GET";
bncce36dca22015-04-21 22:11:235167 request1.url = GURL("https://www.example.org/");
[email protected]f6c63db52013-02-02 00:35:225168 request1.load_flags = 0;
5169
5170 HttpRequestInfo request2;
5171 request2.method = "GET";
bncce36dca22015-04-21 22:11:235172 request2.url = GURL("https://mail.example.org/");
[email protected]f6c63db52013-02-02 00:35:225173 request2.load_flags = 0;
5174
bncce36dca22015-04-21 22:11:235175 // CONNECT to www.example.org:443 via SPDY.
bncdf80d44fd2016-07-15 20:27:415176 SpdySerializedFrame connect1(spdy_util_.ConstructSpdyConnect(
bncce36dca22015-04-21 22:11:235177 NULL, 0, 1, LOWEST, HostPortPair("www.example.org", 443)));
bnc42331402016-07-25 13:36:155178 SpdySerializedFrame conn_resp1(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
[email protected]f6c63db52013-02-02 00:35:225179
bncce36dca22015-04-21 22:11:235180 // Fetch https://www.example.org/ via HTTP.
5181 const char get1[] =
5182 "GET / HTTP/1.1\r\n"
5183 "Host: www.example.org\r\n"
[email protected]f6c63db52013-02-02 00:35:225184 "Connection: keep-alive\r\n\r\n";
bncdf80d44fd2016-07-15 20:27:415185 SpdySerializedFrame wrapped_get1(
5186 spdy_util_.ConstructSpdyDataFrame(1, get1, strlen(get1), false));
[email protected]f6c63db52013-02-02 00:35:225187 const char resp1[] = "HTTP/1.1 200 OK\r\n"
5188 "Content-Length: 1\r\n\r\n";
bncdf80d44fd2016-07-15 20:27:415189 SpdySerializedFrame wrapped_get_resp1(
5190 spdy_util_.ConstructSpdyDataFrame(1, resp1, strlen(resp1), false));
5191 SpdySerializedFrame wrapped_body1(
5192 spdy_util_.ConstructSpdyDataFrame(1, "1", 1, false));
5193 SpdySerializedFrame window_update(
5194 spdy_util_.ConstructSpdyWindowUpdate(1, wrapped_get_resp1.size()));
[email protected]f6c63db52013-02-02 00:35:225195
bncce36dca22015-04-21 22:11:235196 // CONNECT to mail.example.org:443 via SPDY.
[email protected]745aa9c2014-06-27 02:21:295197 SpdyHeaderBlock connect2_block;
Bence Békybda82952017-10-02 17:35:275198 connect2_block[kHttp2MethodHeader] = "CONNECT";
5199 connect2_block[kHttp2AuthorityHeader] = "mail.example.org:443";
bnc42331402016-07-25 13:36:155200 SpdySerializedFrame connect2(spdy_util_.ConstructSpdyHeaders(
5201 3, std::move(connect2_block), LOWEST, false));
[email protected]601e03f12014-04-06 16:26:395202
bnc42331402016-07-25 13:36:155203 SpdySerializedFrame conn_resp2(spdy_util_.ConstructSpdyGetReply(NULL, 0, 3));
[email protected]f6c63db52013-02-02 00:35:225204
bncce36dca22015-04-21 22:11:235205 // Fetch https://mail.example.org/ via HTTP.
5206 const char get2[] =
5207 "GET / HTTP/1.1\r\n"
5208 "Host: mail.example.org\r\n"
[email protected]f6c63db52013-02-02 00:35:225209 "Connection: keep-alive\r\n\r\n";
bncdf80d44fd2016-07-15 20:27:415210 SpdySerializedFrame wrapped_get2(
5211 spdy_util_.ConstructSpdyDataFrame(3, get2, strlen(get2), false));
[email protected]f6c63db52013-02-02 00:35:225212 const char resp2[] = "HTTP/1.1 200 OK\r\n"
5213 "Content-Length: 2\r\n\r\n";
bncdf80d44fd2016-07-15 20:27:415214 SpdySerializedFrame wrapped_get_resp2(
5215 spdy_util_.ConstructSpdyDataFrame(3, resp2, strlen(resp2), false));
5216 SpdySerializedFrame wrapped_body2(
5217 spdy_util_.ConstructSpdyDataFrame(3, "22", 2, false));
[email protected]f6c63db52013-02-02 00:35:225218
5219 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:415220 CreateMockWrite(connect1, 0), CreateMockWrite(wrapped_get1, 2),
5221 CreateMockWrite(connect2, 5), CreateMockWrite(wrapped_get2, 7),
[email protected]f6c63db52013-02-02 00:35:225222 };
5223
5224 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:415225 CreateMockRead(conn_resp1, 1, ASYNC),
5226 CreateMockRead(wrapped_get_resp1, 3, ASYNC),
5227 CreateMockRead(wrapped_body1, 4, ASYNC),
5228 CreateMockRead(conn_resp2, 6, ASYNC),
5229 CreateMockRead(wrapped_get_resp2, 8, ASYNC),
5230 CreateMockRead(wrapped_body2, 9, ASYNC),
5231 MockRead(ASYNC, 0, 10),
[email protected]f6c63db52013-02-02 00:35:225232 };
5233
mmenke11eb5152015-06-09 14:50:505234 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
5235 arraysize(spdy_writes));
5236 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]f6c63db52013-02-02 00:35:225237
5238 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:365239 ssl.next_proto = kProtoHTTP2;
mmenke11eb5152015-06-09 14:50:505240 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]f6c63db52013-02-02 00:35:225241 SSLSocketDataProvider ssl2(ASYNC, OK);
mmenke11eb5152015-06-09 14:50:505242 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
[email protected]f6c63db52013-02-02 00:35:225243 SSLSocketDataProvider ssl3(ASYNC, OK);
mmenke11eb5152015-06-09 14:50:505244 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl3);
[email protected]f6c63db52013-02-02 00:35:225245
5246 TestCompletionCallback callback;
5247
bnc691fda62016-08-12 00:43:165248 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:205249 int rv = trans.Start(&request1, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:015250 EXPECT_THAT(callback.GetResult(rv), IsOk());
[email protected]f6c63db52013-02-02 00:35:225251
5252 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:165253 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]f6c63db52013-02-02 00:35:225254 TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_SSL_TIMES);
5255
bnc691fda62016-08-12 00:43:165256 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:525257 ASSERT_TRUE(response);
5258 ASSERT_TRUE(response->headers);
[email protected]f6c63db52013-02-02 00:35:225259 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
5260
5261 std::string response_data;
ttuttle859dc7a2015-04-23 19:42:295262 scoped_refptr<IOBuffer> buf(new IOBuffer(256));
bnc691fda62016-08-12 00:43:165263 rv = trans.Read(buf.get(), 256, callback.callback());
mmenke11eb5152015-06-09 14:50:505264 EXPECT_EQ(1, callback.GetResult(rv));
[email protected]f6c63db52013-02-02 00:35:225265
bnc691fda62016-08-12 00:43:165266 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:205267 rv = trans2.Start(&request2, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:015268 EXPECT_THAT(callback.GetResult(rv), IsOk());
[email protected]f6c63db52013-02-02 00:35:225269
5270 LoadTimingInfo load_timing_info2;
bnc691fda62016-08-12 00:43:165271 EXPECT_TRUE(trans2.GetLoadTimingInfo(&load_timing_info2));
[email protected]f6c63db52013-02-02 00:35:225272 // Even though the SPDY connection is reused, a new tunnelled connection has
5273 // to be created, so the socket's load timing looks like a fresh connection.
5274 TestLoadTimingNotReused(load_timing_info2, CONNECT_TIMING_HAS_SSL_TIMES);
5275
5276 // The requests should have different IDs, since they each are using their own
5277 // separate stream.
5278 EXPECT_NE(load_timing_info.socket_log_id, load_timing_info2.socket_log_id);
5279
bnc691fda62016-08-12 00:43:165280 rv = trans2.Read(buf.get(), 256, callback.callback());
mmenke11eb5152015-06-09 14:50:505281 EXPECT_EQ(2, callback.GetResult(rv));
[email protected]f6c63db52013-02-02 00:35:225282}
5283
5284// Test load timing in the case of two HTTPS (non-SPDY) requests through a SPDY
5285// HTTPS Proxy to the same server.
bncd16676a2016-07-20 16:23:015286TEST_F(HttpNetworkTransactionTest,
[email protected]f6c63db52013-02-02 00:35:225287 HttpsProxySpdyConnectHttpsLoadTimingTwoRequestsSameServer) {
5288 // Configure against https proxy server "proxy:70".
rdsmith82957ad2015-09-16 19:42:035289 session_deps_.proxy_service = ProxyService::CreateFixed("https://proxy:70");
vishal.b62985ca92015-04-17 08:45:515290 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:075291 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:095292 std::unique_ptr<HttpNetworkSession> session(
mmenke11eb5152015-06-09 14:50:505293 SpdySessionDependencies::SpdyCreateSession(&session_deps_));
[email protected]f6c63db52013-02-02 00:35:225294
5295 HttpRequestInfo request1;
5296 request1.method = "GET";
bncce36dca22015-04-21 22:11:235297 request1.url = GURL("https://www.example.org/");
[email protected]f6c63db52013-02-02 00:35:225298 request1.load_flags = 0;
5299
5300 HttpRequestInfo request2;
5301 request2.method = "GET";
bncce36dca22015-04-21 22:11:235302 request2.url = GURL("https://www.example.org/2");
[email protected]f6c63db52013-02-02 00:35:225303 request2.load_flags = 0;
5304
bncce36dca22015-04-21 22:11:235305 // CONNECT to www.example.org:443 via SPDY.
bncdf80d44fd2016-07-15 20:27:415306 SpdySerializedFrame connect1(spdy_util_.ConstructSpdyConnect(
bncce36dca22015-04-21 22:11:235307 NULL, 0, 1, LOWEST, HostPortPair("www.example.org", 443)));
bnc42331402016-07-25 13:36:155308 SpdySerializedFrame conn_resp1(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
[email protected]f6c63db52013-02-02 00:35:225309
bncce36dca22015-04-21 22:11:235310 // Fetch https://www.example.org/ via HTTP.
5311 const char get1[] =
5312 "GET / HTTP/1.1\r\n"
5313 "Host: www.example.org\r\n"
[email protected]f6c63db52013-02-02 00:35:225314 "Connection: keep-alive\r\n\r\n";
bncdf80d44fd2016-07-15 20:27:415315 SpdySerializedFrame wrapped_get1(
5316 spdy_util_.ConstructSpdyDataFrame(1, get1, strlen(get1), false));
[email protected]f6c63db52013-02-02 00:35:225317 const char resp1[] = "HTTP/1.1 200 OK\r\n"
5318 "Content-Length: 1\r\n\r\n";
bncdf80d44fd2016-07-15 20:27:415319 SpdySerializedFrame wrapped_get_resp1(
5320 spdy_util_.ConstructSpdyDataFrame(1, resp1, strlen(resp1), false));
5321 SpdySerializedFrame wrapped_body1(
5322 spdy_util_.ConstructSpdyDataFrame(1, "1", 1, false));
5323 SpdySerializedFrame window_update(
5324 spdy_util_.ConstructSpdyWindowUpdate(1, wrapped_get_resp1.size()));
[email protected]f6c63db52013-02-02 00:35:225325
bncce36dca22015-04-21 22:11:235326 // Fetch https://www.example.org/2 via HTTP.
5327 const char get2[] =
5328 "GET /2 HTTP/1.1\r\n"
5329 "Host: www.example.org\r\n"
[email protected]f6c63db52013-02-02 00:35:225330 "Connection: keep-alive\r\n\r\n";
bncdf80d44fd2016-07-15 20:27:415331 SpdySerializedFrame wrapped_get2(
5332 spdy_util_.ConstructSpdyDataFrame(1, get2, strlen(get2), false));
[email protected]f6c63db52013-02-02 00:35:225333 const char resp2[] = "HTTP/1.1 200 OK\r\n"
5334 "Content-Length: 2\r\n\r\n";
bncdf80d44fd2016-07-15 20:27:415335 SpdySerializedFrame wrapped_get_resp2(
5336 spdy_util_.ConstructSpdyDataFrame(1, resp2, strlen(resp2), false));
5337 SpdySerializedFrame wrapped_body2(
5338 spdy_util_.ConstructSpdyDataFrame(1, "22", 2, false));
[email protected]f6c63db52013-02-02 00:35:225339
5340 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:415341 CreateMockWrite(connect1, 0), CreateMockWrite(wrapped_get1, 2),
5342 CreateMockWrite(wrapped_get2, 5),
[email protected]f6c63db52013-02-02 00:35:225343 };
5344
5345 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:415346 CreateMockRead(conn_resp1, 1, ASYNC),
5347 CreateMockRead(wrapped_get_resp1, 3, ASYNC),
bnceb9aa7112017-01-05 01:03:465348 CreateMockRead(wrapped_body1, 4, SYNCHRONOUS),
bncdf80d44fd2016-07-15 20:27:415349 CreateMockRead(wrapped_get_resp2, 6, ASYNC),
bnceb9aa7112017-01-05 01:03:465350 CreateMockRead(wrapped_body2, 7, SYNCHRONOUS),
bncdf80d44fd2016-07-15 20:27:415351 MockRead(ASYNC, 0, 8),
[email protected]f6c63db52013-02-02 00:35:225352 };
5353
mmenke11eb5152015-06-09 14:50:505354 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
5355 arraysize(spdy_writes));
5356 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]f6c63db52013-02-02 00:35:225357
5358 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:365359 ssl.next_proto = kProtoHTTP2;
mmenke11eb5152015-06-09 14:50:505360 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]f6c63db52013-02-02 00:35:225361 SSLSocketDataProvider ssl2(ASYNC, OK);
mmenke11eb5152015-06-09 14:50:505362 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
[email protected]f6c63db52013-02-02 00:35:225363
5364 TestCompletionCallback callback;
5365
bnc87dcefc2017-05-25 12:47:585366 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:195367 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:205368 int rv = trans->Start(&request1, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:015369 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]f6c63db52013-02-02 00:35:225370
5371 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:015372 EXPECT_THAT(rv, IsOk());
[email protected]f6c63db52013-02-02 00:35:225373
5374 LoadTimingInfo load_timing_info;
5375 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
5376 TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_SSL_TIMES);
5377
5378 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:525379 ASSERT_TRUE(response);
5380 ASSERT_TRUE(response->headers);
[email protected]f6c63db52013-02-02 00:35:225381 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
5382
5383 std::string response_data;
ttuttle859dc7a2015-04-23 19:42:295384 scoped_refptr<IOBuffer> buf(new IOBuffer(256));
[email protected]90499482013-06-01 00:39:505385 EXPECT_EQ(1, trans->Read(buf.get(), 256, callback.callback()));
[email protected]f6c63db52013-02-02 00:35:225386 trans.reset();
5387
bnc87dcefc2017-05-25 12:47:585388 auto trans2 =
Jeremy Roman0579ed62017-08-29 15:56:195389 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:205390 rv = trans2->Start(&request2, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:015391 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]f6c63db52013-02-02 00:35:225392
[email protected]f6c63db52013-02-02 00:35:225393 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:015394 EXPECT_THAT(rv, IsOk());
[email protected]f6c63db52013-02-02 00:35:225395
5396 LoadTimingInfo load_timing_info2;
5397 EXPECT_TRUE(trans2->GetLoadTimingInfo(&load_timing_info2));
5398 TestLoadTimingReused(load_timing_info2);
5399
5400 // The requests should have the same ID.
5401 EXPECT_EQ(load_timing_info.socket_log_id, load_timing_info2.socket_log_id);
5402
[email protected]90499482013-06-01 00:39:505403 EXPECT_EQ(2, trans2->Read(buf.get(), 256, callback.callback()));
[email protected]f6c63db52013-02-02 00:35:225404}
5405
5406// Test load timing in the case of of two HTTP requests through a SPDY HTTPS
5407// Proxy to different servers.
bncd16676a2016-07-20 16:23:015408TEST_F(HttpNetworkTransactionTest, HttpsProxySpdyLoadTimingTwoHttpRequests) {
[email protected]f6c63db52013-02-02 00:35:225409 // Configure against https proxy server "proxy:70".
rdsmith82957ad2015-09-16 19:42:035410 session_deps_.proxy_service = ProxyService::CreateFixed("https://proxy:70");
vishal.b62985ca92015-04-17 08:45:515411 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:075412 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:095413 std::unique_ptr<HttpNetworkSession> session(
mmenke11eb5152015-06-09 14:50:505414 SpdySessionDependencies::SpdyCreateSession(&session_deps_));
[email protected]f6c63db52013-02-02 00:35:225415
5416 HttpRequestInfo request1;
5417 request1.method = "GET";
bncce36dca22015-04-21 22:11:235418 request1.url = GURL("http://www.example.org/");
[email protected]f6c63db52013-02-02 00:35:225419 request1.load_flags = 0;
5420
5421 HttpRequestInfo request2;
5422 request2.method = "GET";
bncce36dca22015-04-21 22:11:235423 request2.url = GURL("http://mail.example.org/");
[email protected]f6c63db52013-02-02 00:35:225424 request2.load_flags = 0;
5425
bncce36dca22015-04-21 22:11:235426 // http://www.example.org/
bnc086b39e12016-06-24 13:05:265427 SpdyHeaderBlock headers(
bncce36dca22015-04-21 22:11:235428 spdy_util_.ConstructGetHeaderBlockForProxy("http://www.example.org/"));
bncdf80d44fd2016-07-15 20:27:415429 SpdySerializedFrame get1(
bnc42331402016-07-25 13:36:155430 spdy_util_.ConstructSpdyHeaders(1, std::move(headers), LOWEST, true));
5431 SpdySerializedFrame get_resp1(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
bncdf80d44fd2016-07-15 20:27:415432 SpdySerializedFrame body1(spdy_util_.ConstructSpdyDataFrame(1, "1", 1, true));
rdsmithebb50aa2015-11-12 03:44:385433 spdy_util_.UpdateWithStreamDestruction(1);
[email protected]f6c63db52013-02-02 00:35:225434
bncce36dca22015-04-21 22:11:235435 // http://mail.example.org/
bnc086b39e12016-06-24 13:05:265436 SpdyHeaderBlock headers2(
bncce36dca22015-04-21 22:11:235437 spdy_util_.ConstructGetHeaderBlockForProxy("http://mail.example.org/"));
bncdf80d44fd2016-07-15 20:27:415438 SpdySerializedFrame get2(
bnc42331402016-07-25 13:36:155439 spdy_util_.ConstructSpdyHeaders(3, std::move(headers2), LOWEST, true));
5440 SpdySerializedFrame get_resp2(spdy_util_.ConstructSpdyGetReply(NULL, 0, 3));
bncdf80d44fd2016-07-15 20:27:415441 SpdySerializedFrame body2(
5442 spdy_util_.ConstructSpdyDataFrame(3, "22", 2, true));
[email protected]f6c63db52013-02-02 00:35:225443
5444 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:415445 CreateMockWrite(get1, 0), CreateMockWrite(get2, 3),
[email protected]f6c63db52013-02-02 00:35:225446 };
5447
5448 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:415449 CreateMockRead(get_resp1, 1, ASYNC),
5450 CreateMockRead(body1, 2, ASYNC),
5451 CreateMockRead(get_resp2, 4, ASYNC),
5452 CreateMockRead(body2, 5, ASYNC),
5453 MockRead(ASYNC, 0, 6),
[email protected]f6c63db52013-02-02 00:35:225454 };
5455
mmenke11eb5152015-06-09 14:50:505456 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
5457 arraysize(spdy_writes));
5458 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]f6c63db52013-02-02 00:35:225459
5460 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:365461 ssl.next_proto = kProtoHTTP2;
mmenke11eb5152015-06-09 14:50:505462 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]f6c63db52013-02-02 00:35:225463
5464 TestCompletionCallback callback;
5465
bnc87dcefc2017-05-25 12:47:585466 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:195467 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:205468 int rv = trans->Start(&request1, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:015469 EXPECT_THAT(callback.GetResult(rv), IsOk());
[email protected]f6c63db52013-02-02 00:35:225470
5471 LoadTimingInfo load_timing_info;
5472 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
5473 TestLoadTimingNotReused(load_timing_info,
5474 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
5475
5476 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:525477 ASSERT_TRUE(response);
5478 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:025479 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]f6c63db52013-02-02 00:35:225480
5481 std::string response_data;
ttuttle859dc7a2015-04-23 19:42:295482 scoped_refptr<IOBuffer> buf(new IOBuffer(256));
mmenke11eb5152015-06-09 14:50:505483 rv = trans->Read(buf.get(), 256, callback.callback());
5484 EXPECT_EQ(1, callback.GetResult(rv));
[email protected]f6c63db52013-02-02 00:35:225485 // Delete the first request, so the second one can reuse the socket.
5486 trans.reset();
5487
bnc691fda62016-08-12 00:43:165488 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:205489 rv = trans2.Start(&request2, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:015490 EXPECT_THAT(callback.GetResult(rv), IsOk());
[email protected]f6c63db52013-02-02 00:35:225491
5492 LoadTimingInfo load_timing_info2;
bnc691fda62016-08-12 00:43:165493 EXPECT_TRUE(trans2.GetLoadTimingInfo(&load_timing_info2));
[email protected]f6c63db52013-02-02 00:35:225494 TestLoadTimingReused(load_timing_info2);
5495
5496 // The requests should have the same ID.
5497 EXPECT_EQ(load_timing_info.socket_log_id, load_timing_info2.socket_log_id);
5498
bnc691fda62016-08-12 00:43:165499 rv = trans2.Read(buf.get(), 256, callback.callback());
mmenke11eb5152015-06-09 14:50:505500 EXPECT_EQ(2, callback.GetResult(rv));
[email protected]f6c63db52013-02-02 00:35:225501}
5502
[email protected]2df19bb2010-08-25 20:13:465503// Test the challenge-response-retry sequence through an HTTPS Proxy
bncd16676a2016-07-20 16:23:015504TEST_F(HttpNetworkTransactionTest, HttpsProxyAuthRetry) {
[email protected]2df19bb2010-08-25 20:13:465505 HttpRequestInfo request;
5506 request.method = "GET";
bncce36dca22015-04-21 22:11:235507 request.url = GURL("http://www.example.org/");
[email protected]2df19bb2010-08-25 20:13:465508 // when the no authentication data flag is set.
ttuttle859dc7a2015-04-23 19:42:295509 request.load_flags = LOAD_DO_NOT_SEND_AUTH_DATA;
[email protected]2df19bb2010-08-25 20:13:465510
[email protected]79cb5c12011-09-12 13:12:045511 // Configure against https proxy server "myproxy:70".
rdsmith82957ad2015-09-16 19:42:035512 session_deps_.proxy_service = ProxyService::CreateFixed("https://myproxy:70");
vishal.b62985ca92015-04-17 08:45:515513 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:075514 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:095515 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:275516
[email protected]2df19bb2010-08-25 20:13:465517 // Since we have proxy, should use full url
5518 MockWrite data_writes1[] = {
bnc691fda62016-08-12 00:43:165519 MockWrite("GET http://www.example.org/ HTTP/1.1\r\n"
5520 "Host: www.example.org\r\n"
5521 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]2df19bb2010-08-25 20:13:465522
bnc691fda62016-08-12 00:43:165523 // After calling trans.RestartWithAuth(), this is the request we should
bncce36dca22015-04-21 22:11:235524 // be issuing -- the final header line contains the credentials.
bnc691fda62016-08-12 00:43:165525 MockWrite("GET http://www.example.org/ HTTP/1.1\r\n"
5526 "Host: www.example.org\r\n"
5527 "Proxy-Connection: keep-alive\r\n"
5528 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]2df19bb2010-08-25 20:13:465529 };
5530
5531 // The proxy responds to the GET with a 407, using a persistent
5532 // connection.
5533 MockRead data_reads1[] = {
5534 // No credentials.
5535 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
5536 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
5537 MockRead("Proxy-Connection: keep-alive\r\n"),
5538 MockRead("Content-Length: 0\r\n\r\n"),
5539
5540 MockRead("HTTP/1.1 200 OK\r\n"),
5541 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
5542 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:065543 MockRead(SYNCHRONOUS, OK),
[email protected]2df19bb2010-08-25 20:13:465544 };
5545
5546 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
5547 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:075548 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8ddf8322012-02-23 18:08:065549 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:075550 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]2df19bb2010-08-25 20:13:465551
[email protected]49639fa2011-12-20 23:22:415552 TestCompletionCallback callback1;
[email protected]2df19bb2010-08-25 20:13:465553
bnc691fda62016-08-12 00:43:165554 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]0b0bf032010-09-21 18:08:505555
bnc691fda62016-08-12 00:43:165556 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:015557 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2df19bb2010-08-25 20:13:465558
5559 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:015560 EXPECT_THAT(rv, IsOk());
[email protected]2df19bb2010-08-25 20:13:465561
[email protected]58e32bb2013-01-21 18:23:255562 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:165563 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]58e32bb2013-01-21 18:23:255564 TestLoadTimingNotReused(load_timing_info,
5565 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
5566
bnc691fda62016-08-12 00:43:165567 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:525568 ASSERT_TRUE(response);
5569 ASSERT_TRUE(response->headers);
[email protected]2df19bb2010-08-25 20:13:465570 EXPECT_EQ(407, response->headers->response_code());
5571 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
asanka098c0092016-06-16 20:18:435572 EXPECT_TRUE(CheckBasicSecureProxyAuth(response->auth_challenge.get()));
[email protected]2df19bb2010-08-25 20:13:465573
[email protected]49639fa2011-12-20 23:22:415574 TestCompletionCallback callback2;
[email protected]2df19bb2010-08-25 20:13:465575
bnc691fda62016-08-12 00:43:165576 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar), callback2.callback());
robpercival214763f2016-07-01 23:27:015577 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2df19bb2010-08-25 20:13:465578
5579 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:015580 EXPECT_THAT(rv, IsOk());
[email protected]2df19bb2010-08-25 20:13:465581
[email protected]58e32bb2013-01-21 18:23:255582 load_timing_info = LoadTimingInfo();
bnc691fda62016-08-12 00:43:165583 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]58e32bb2013-01-21 18:23:255584 // Retrying with HTTP AUTH is considered to be reusing a socket.
5585 TestLoadTimingReused(load_timing_info);
5586
bnc691fda62016-08-12 00:43:165587 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:525588 ASSERT_TRUE(response);
[email protected]2df19bb2010-08-25 20:13:465589
5590 EXPECT_TRUE(response->headers->IsKeepAlive());
5591 EXPECT_EQ(200, response->headers->response_code());
5592 EXPECT_EQ(100, response->headers->GetContentLength());
5593 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
5594
5595 // The password prompt info should not be set.
wezca1070932016-05-26 20:30:525596 EXPECT_FALSE(response->auth_challenge);
[email protected]2df19bb2010-08-25 20:13:465597}
5598
[email protected]23e482282013-06-14 16:08:025599void HttpNetworkTransactionTest::ConnectStatusHelperWithExpectedStatus(
[email protected]c744cf22009-02-27 07:28:085600 const MockRead& status, int expected_status) {
[email protected]1c773ea12009-04-28 19:58:425601 HttpRequestInfo request;
[email protected]c744cf22009-02-27 07:28:085602 request.method = "GET";
bncce36dca22015-04-21 22:11:235603 request.url = GURL("https://www.example.org/");
[email protected]c744cf22009-02-27 07:28:085604
[email protected]cb9bf6ca2011-01-28 13:15:275605 // Configure against proxy server "myproxy:70".
rdsmith82957ad2015-09-16 19:42:035606 session_deps_.proxy_service = ProxyService::CreateFixed("myproxy:70");
danakj1fd259a02016-04-16 03:17:095607 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:275608
[email protected]c744cf22009-02-27 07:28:085609 // Since we have proxy, should try to establish tunnel.
5610 MockWrite data_writes[] = {
rsleevidb16bb02015-11-12 23:47:175611 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
5612 "Host: www.example.org:443\r\n"
5613 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]c744cf22009-02-27 07:28:085614 };
5615
5616 MockRead data_reads[] = {
mmenked39192ee2015-12-09 00:57:235617 status, MockRead("Content-Length: 10\r\n\r\n"),
5618 // No response body because the test stops reading here.
5619 MockRead(SYNCHRONOUS, ERR_UNEXPECTED),
[email protected]c744cf22009-02-27 07:28:085620 };
5621
[email protected]31a2bfe2010-02-09 08:03:395622 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
5623 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:075624 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]c744cf22009-02-27 07:28:085625
[email protected]49639fa2011-12-20 23:22:415626 TestCompletionCallback callback;
[email protected]c744cf22009-02-27 07:28:085627
bnc691fda62016-08-12 00:43:165628 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]0b0bf032010-09-21 18:08:505629
tfarina42834112016-09-22 13:38:205630 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:015631 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]c744cf22009-02-27 07:28:085632
5633 rv = callback.WaitForResult();
5634 EXPECT_EQ(expected_status, rv);
5635}
5636
[email protected]23e482282013-06-14 16:08:025637void HttpNetworkTransactionTest::ConnectStatusHelper(
[email protected]448d4ca52012-03-04 04:12:235638 const MockRead& status) {
[email protected]c744cf22009-02-27 07:28:085639 ConnectStatusHelperWithExpectedStatus(
[email protected]1c773ea12009-04-28 19:58:425640 status, ERR_TUNNEL_CONNECTION_FAILED);
[email protected]c744cf22009-02-27 07:28:085641}
5642
bncd16676a2016-07-20 16:23:015643TEST_F(HttpNetworkTransactionTest, ConnectStatus100) {
[email protected]c744cf22009-02-27 07:28:085644 ConnectStatusHelper(MockRead("HTTP/1.1 100 Continue\r\n"));
5645}
5646
bncd16676a2016-07-20 16:23:015647TEST_F(HttpNetworkTransactionTest, ConnectStatus101) {
[email protected]c744cf22009-02-27 07:28:085648 ConnectStatusHelper(MockRead("HTTP/1.1 101 Switching Protocols\r\n"));
5649}
5650
bncd16676a2016-07-20 16:23:015651TEST_F(HttpNetworkTransactionTest, ConnectStatus201) {
[email protected]c744cf22009-02-27 07:28:085652 ConnectStatusHelper(MockRead("HTTP/1.1 201 Created\r\n"));
5653}
5654
bncd16676a2016-07-20 16:23:015655TEST_F(HttpNetworkTransactionTest, ConnectStatus202) {
[email protected]c744cf22009-02-27 07:28:085656 ConnectStatusHelper(MockRead("HTTP/1.1 202 Accepted\r\n"));
5657}
5658
bncd16676a2016-07-20 16:23:015659TEST_F(HttpNetworkTransactionTest, ConnectStatus203) {
[email protected]c744cf22009-02-27 07:28:085660 ConnectStatusHelper(
5661 MockRead("HTTP/1.1 203 Non-Authoritative Information\r\n"));
5662}
5663
bncd16676a2016-07-20 16:23:015664TEST_F(HttpNetworkTransactionTest, ConnectStatus204) {
[email protected]c744cf22009-02-27 07:28:085665 ConnectStatusHelper(MockRead("HTTP/1.1 204 No Content\r\n"));
5666}
5667
bncd16676a2016-07-20 16:23:015668TEST_F(HttpNetworkTransactionTest, ConnectStatus205) {
[email protected]c744cf22009-02-27 07:28:085669 ConnectStatusHelper(MockRead("HTTP/1.1 205 Reset Content\r\n"));
5670}
5671
bncd16676a2016-07-20 16:23:015672TEST_F(HttpNetworkTransactionTest, ConnectStatus206) {
[email protected]c744cf22009-02-27 07:28:085673 ConnectStatusHelper(MockRead("HTTP/1.1 206 Partial Content\r\n"));
5674}
5675
bncd16676a2016-07-20 16:23:015676TEST_F(HttpNetworkTransactionTest, ConnectStatus300) {
[email protected]c744cf22009-02-27 07:28:085677 ConnectStatusHelper(MockRead("HTTP/1.1 300 Multiple Choices\r\n"));
5678}
5679
bncd16676a2016-07-20 16:23:015680TEST_F(HttpNetworkTransactionTest, ConnectStatus301) {
[email protected]c744cf22009-02-27 07:28:085681 ConnectStatusHelper(MockRead("HTTP/1.1 301 Moved Permanently\r\n"));
5682}
5683
bncd16676a2016-07-20 16:23:015684TEST_F(HttpNetworkTransactionTest, ConnectStatus302) {
[email protected]c744cf22009-02-27 07:28:085685 ConnectStatusHelper(MockRead("HTTP/1.1 302 Found\r\n"));
5686}
5687
bncd16676a2016-07-20 16:23:015688TEST_F(HttpNetworkTransactionTest, ConnectStatus303) {
[email protected]c744cf22009-02-27 07:28:085689 ConnectStatusHelper(MockRead("HTTP/1.1 303 See Other\r\n"));
5690}
5691
bncd16676a2016-07-20 16:23:015692TEST_F(HttpNetworkTransactionTest, ConnectStatus304) {
[email protected]c744cf22009-02-27 07:28:085693 ConnectStatusHelper(MockRead("HTTP/1.1 304 Not Modified\r\n"));
5694}
5695
bncd16676a2016-07-20 16:23:015696TEST_F(HttpNetworkTransactionTest, ConnectStatus305) {
[email protected]c744cf22009-02-27 07:28:085697 ConnectStatusHelper(MockRead("HTTP/1.1 305 Use Proxy\r\n"));
5698}
5699
bncd16676a2016-07-20 16:23:015700TEST_F(HttpNetworkTransactionTest, ConnectStatus306) {
[email protected]c744cf22009-02-27 07:28:085701 ConnectStatusHelper(MockRead("HTTP/1.1 306\r\n"));
5702}
5703
bncd16676a2016-07-20 16:23:015704TEST_F(HttpNetworkTransactionTest, ConnectStatus307) {
[email protected]c744cf22009-02-27 07:28:085705 ConnectStatusHelper(MockRead("HTTP/1.1 307 Temporary Redirect\r\n"));
5706}
5707
bncd16676a2016-07-20 16:23:015708TEST_F(HttpNetworkTransactionTest, ConnectStatus308) {
[email protected]0a17aab32014-04-24 03:32:375709 ConnectStatusHelper(MockRead("HTTP/1.1 308 Permanent Redirect\r\n"));
5710}
5711
bncd16676a2016-07-20 16:23:015712TEST_F(HttpNetworkTransactionTest, ConnectStatus400) {
[email protected]c744cf22009-02-27 07:28:085713 ConnectStatusHelper(MockRead("HTTP/1.1 400 Bad Request\r\n"));
5714}
5715
bncd16676a2016-07-20 16:23:015716TEST_F(HttpNetworkTransactionTest, ConnectStatus401) {
[email protected]c744cf22009-02-27 07:28:085717 ConnectStatusHelper(MockRead("HTTP/1.1 401 Unauthorized\r\n"));
5718}
5719
bncd16676a2016-07-20 16:23:015720TEST_F(HttpNetworkTransactionTest, ConnectStatus402) {
[email protected]c744cf22009-02-27 07:28:085721 ConnectStatusHelper(MockRead("HTTP/1.1 402 Payment Required\r\n"));
5722}
5723
bncd16676a2016-07-20 16:23:015724TEST_F(HttpNetworkTransactionTest, ConnectStatus403) {
[email protected]c744cf22009-02-27 07:28:085725 ConnectStatusHelper(MockRead("HTTP/1.1 403 Forbidden\r\n"));
5726}
5727
bncd16676a2016-07-20 16:23:015728TEST_F(HttpNetworkTransactionTest, ConnectStatus404) {
[email protected]c744cf22009-02-27 07:28:085729 ConnectStatusHelper(MockRead("HTTP/1.1 404 Not Found\r\n"));
5730}
5731
bncd16676a2016-07-20 16:23:015732TEST_F(HttpNetworkTransactionTest, ConnectStatus405) {
[email protected]c744cf22009-02-27 07:28:085733 ConnectStatusHelper(MockRead("HTTP/1.1 405 Method Not Allowed\r\n"));
5734}
5735
bncd16676a2016-07-20 16:23:015736TEST_F(HttpNetworkTransactionTest, ConnectStatus406) {
[email protected]c744cf22009-02-27 07:28:085737 ConnectStatusHelper(MockRead("HTTP/1.1 406 Not Acceptable\r\n"));
5738}
5739
bncd16676a2016-07-20 16:23:015740TEST_F(HttpNetworkTransactionTest, ConnectStatus407) {
[email protected]c744cf22009-02-27 07:28:085741 ConnectStatusHelperWithExpectedStatus(
5742 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
[email protected]a7ea8832010-07-12 17:54:545743 ERR_PROXY_AUTH_UNSUPPORTED);
[email protected]c744cf22009-02-27 07:28:085744}
5745
bncd16676a2016-07-20 16:23:015746TEST_F(HttpNetworkTransactionTest, ConnectStatus408) {
[email protected]c744cf22009-02-27 07:28:085747 ConnectStatusHelper(MockRead("HTTP/1.1 408 Request Timeout\r\n"));
5748}
5749
bncd16676a2016-07-20 16:23:015750TEST_F(HttpNetworkTransactionTest, ConnectStatus409) {
[email protected]c744cf22009-02-27 07:28:085751 ConnectStatusHelper(MockRead("HTTP/1.1 409 Conflict\r\n"));
5752}
5753
bncd16676a2016-07-20 16:23:015754TEST_F(HttpNetworkTransactionTest, ConnectStatus410) {
[email protected]c744cf22009-02-27 07:28:085755 ConnectStatusHelper(MockRead("HTTP/1.1 410 Gone\r\n"));
5756}
5757
bncd16676a2016-07-20 16:23:015758TEST_F(HttpNetworkTransactionTest, ConnectStatus411) {
[email protected]c744cf22009-02-27 07:28:085759 ConnectStatusHelper(MockRead("HTTP/1.1 411 Length Required\r\n"));
5760}
5761
bncd16676a2016-07-20 16:23:015762TEST_F(HttpNetworkTransactionTest, ConnectStatus412) {
[email protected]c744cf22009-02-27 07:28:085763 ConnectStatusHelper(MockRead("HTTP/1.1 412 Precondition Failed\r\n"));
5764}
5765
bncd16676a2016-07-20 16:23:015766TEST_F(HttpNetworkTransactionTest, ConnectStatus413) {
[email protected]c744cf22009-02-27 07:28:085767 ConnectStatusHelper(MockRead("HTTP/1.1 413 Request Entity Too Large\r\n"));
5768}
5769
bncd16676a2016-07-20 16:23:015770TEST_F(HttpNetworkTransactionTest, ConnectStatus414) {
[email protected]c744cf22009-02-27 07:28:085771 ConnectStatusHelper(MockRead("HTTP/1.1 414 Request-URI Too Long\r\n"));
5772}
5773
bncd16676a2016-07-20 16:23:015774TEST_F(HttpNetworkTransactionTest, ConnectStatus415) {
[email protected]c744cf22009-02-27 07:28:085775 ConnectStatusHelper(MockRead("HTTP/1.1 415 Unsupported Media Type\r\n"));
5776}
5777
bncd16676a2016-07-20 16:23:015778TEST_F(HttpNetworkTransactionTest, ConnectStatus416) {
[email protected]c744cf22009-02-27 07:28:085779 ConnectStatusHelper(
5780 MockRead("HTTP/1.1 416 Requested Range Not Satisfiable\r\n"));
5781}
5782
bncd16676a2016-07-20 16:23:015783TEST_F(HttpNetworkTransactionTest, ConnectStatus417) {
[email protected]c744cf22009-02-27 07:28:085784 ConnectStatusHelper(MockRead("HTTP/1.1 417 Expectation Failed\r\n"));
5785}
5786
bncd16676a2016-07-20 16:23:015787TEST_F(HttpNetworkTransactionTest, ConnectStatus500) {
[email protected]c744cf22009-02-27 07:28:085788 ConnectStatusHelper(MockRead("HTTP/1.1 500 Internal Server Error\r\n"));
5789}
5790
bncd16676a2016-07-20 16:23:015791TEST_F(HttpNetworkTransactionTest, ConnectStatus501) {
[email protected]c744cf22009-02-27 07:28:085792 ConnectStatusHelper(MockRead("HTTP/1.1 501 Not Implemented\r\n"));
5793}
5794
bncd16676a2016-07-20 16:23:015795TEST_F(HttpNetworkTransactionTest, ConnectStatus502) {
[email protected]c744cf22009-02-27 07:28:085796 ConnectStatusHelper(MockRead("HTTP/1.1 502 Bad Gateway\r\n"));
5797}
5798
bncd16676a2016-07-20 16:23:015799TEST_F(HttpNetworkTransactionTest, ConnectStatus503) {
[email protected]c744cf22009-02-27 07:28:085800 ConnectStatusHelper(MockRead("HTTP/1.1 503 Service Unavailable\r\n"));
5801}
5802
bncd16676a2016-07-20 16:23:015803TEST_F(HttpNetworkTransactionTest, ConnectStatus504) {
[email protected]c744cf22009-02-27 07:28:085804 ConnectStatusHelper(MockRead("HTTP/1.1 504 Gateway Timeout\r\n"));
5805}
5806
bncd16676a2016-07-20 16:23:015807TEST_F(HttpNetworkTransactionTest, ConnectStatus505) {
[email protected]c744cf22009-02-27 07:28:085808 ConnectStatusHelper(MockRead("HTTP/1.1 505 HTTP Version Not Supported\r\n"));
5809}
5810
[email protected]038e9a32008-10-08 22:40:165811// Test the flow when both the proxy server AND origin server require
5812// authentication. Again, this uses basic auth for both since that is
5813// the simplest to mock.
bncd16676a2016-07-20 16:23:015814TEST_F(HttpNetworkTransactionTest, BasicAuthProxyThenServer) {
[email protected]cb9bf6ca2011-01-28 13:15:275815 HttpRequestInfo request;
5816 request.method = "GET";
bncce36dca22015-04-21 22:11:235817 request.url = GURL("http://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:275818
[email protected]038e9a32008-10-08 22:40:165819 // Configure against proxy server "myproxy:70".
rdsmith82957ad2015-09-16 19:42:035820 session_deps_.proxy_service = ProxyService::CreateFixed("myproxy:70");
danakj1fd259a02016-04-16 03:17:095821 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]3fe8d2f82013-10-17 08:56:075822
bnc691fda62016-08-12 00:43:165823 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]038e9a32008-10-08 22:40:165824
[email protected]f9ee6b52008-11-08 06:46:235825 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:235826 MockWrite(
5827 "GET http://www.example.org/ HTTP/1.1\r\n"
5828 "Host: www.example.org\r\n"
5829 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:235830 };
5831
[email protected]038e9a32008-10-08 22:40:165832 MockRead data_reads1[] = {
5833 MockRead("HTTP/1.0 407 Unauthorized\r\n"),
5834 // Give a couple authenticate options (only the middle one is actually
5835 // supported).
[email protected]22927ad2009-09-21 19:56:195836 MockRead("Proxy-Authenticate: Basic invalid\r\n"), // Malformed.
[email protected]038e9a32008-10-08 22:40:165837 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
5838 MockRead("Proxy-Authenticate: UNSUPPORTED realm=\"FOO\"\r\n"),
5839 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
5840 // Large content-length -- won't matter, as connection will be reset.
5841 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:065842 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]038e9a32008-10-08 22:40:165843 };
5844
bnc691fda62016-08-12 00:43:165845 // After calling trans.RestartWithAuth() the first time, this is the
[email protected]038e9a32008-10-08 22:40:165846 // request we should be issuing -- the final header line contains the
5847 // proxy's credentials.
5848 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:235849 MockWrite(
5850 "GET http://www.example.org/ HTTP/1.1\r\n"
5851 "Host: www.example.org\r\n"
5852 "Proxy-Connection: keep-alive\r\n"
5853 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]038e9a32008-10-08 22:40:165854 };
5855
5856 // Now the proxy server lets the request pass through to origin server.
5857 // The origin server responds with a 401.
5858 MockRead data_reads2[] = {
5859 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
5860 // Note: We are using the same realm-name as the proxy server. This is
5861 // completely valid, as realms are unique across hosts.
5862 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
5863 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
5864 MockRead("Content-Length: 2000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:065865 MockRead(SYNCHRONOUS, ERR_FAILED), // Won't be reached.
[email protected]038e9a32008-10-08 22:40:165866 };
5867
bnc691fda62016-08-12 00:43:165868 // After calling trans.RestartWithAuth() the second time, we should send
[email protected]038e9a32008-10-08 22:40:165869 // the credentials for both the proxy and origin server.
5870 MockWrite data_writes3[] = {
bncce36dca22015-04-21 22:11:235871 MockWrite(
5872 "GET http://www.example.org/ HTTP/1.1\r\n"
5873 "Host: www.example.org\r\n"
5874 "Proxy-Connection: keep-alive\r\n"
5875 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n"
5876 "Authorization: Basic Zm9vMjpiYXIy\r\n\r\n"),
[email protected]038e9a32008-10-08 22:40:165877 };
5878
5879 // Lastly we get the desired content.
5880 MockRead data_reads3[] = {
5881 MockRead("HTTP/1.0 200 OK\r\n"),
5882 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
5883 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:065884 MockRead(SYNCHRONOUS, OK),
[email protected]038e9a32008-10-08 22:40:165885 };
5886
[email protected]31a2bfe2010-02-09 08:03:395887 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
5888 data_writes1, arraysize(data_writes1));
5889 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
5890 data_writes2, arraysize(data_writes2));
5891 StaticSocketDataProvider data3(data_reads3, arraysize(data_reads3),
5892 data_writes3, arraysize(data_writes3));
[email protected]bb88e1d32013-05-03 23:11:075893 session_deps_.socket_factory->AddSocketDataProvider(&data1);
5894 session_deps_.socket_factory->AddSocketDataProvider(&data2);
5895 session_deps_.socket_factory->AddSocketDataProvider(&data3);
[email protected]038e9a32008-10-08 22:40:165896
[email protected]49639fa2011-12-20 23:22:415897 TestCompletionCallback callback1;
[email protected]038e9a32008-10-08 22:40:165898
tfarina42834112016-09-22 13:38:205899 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:015900 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]038e9a32008-10-08 22:40:165901
5902 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:015903 EXPECT_THAT(rv, IsOk());
[email protected]038e9a32008-10-08 22:40:165904
bnc691fda62016-08-12 00:43:165905 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:525906 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:045907 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
[email protected]038e9a32008-10-08 22:40:165908
[email protected]49639fa2011-12-20 23:22:415909 TestCompletionCallback callback2;
[email protected]038e9a32008-10-08 22:40:165910
bnc691fda62016-08-12 00:43:165911 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar), callback2.callback());
robpercival214763f2016-07-01 23:27:015912 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]038e9a32008-10-08 22:40:165913
5914 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:015915 EXPECT_THAT(rv, IsOk());
[email protected]038e9a32008-10-08 22:40:165916
bnc691fda62016-08-12 00:43:165917 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:525918 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:045919 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]038e9a32008-10-08 22:40:165920
[email protected]49639fa2011-12-20 23:22:415921 TestCompletionCallback callback3;
[email protected]038e9a32008-10-08 22:40:165922
bnc691fda62016-08-12 00:43:165923 rv = trans.RestartWithAuth(AuthCredentials(kFoo2, kBar2),
5924 callback3.callback());
robpercival214763f2016-07-01 23:27:015925 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]038e9a32008-10-08 22:40:165926
5927 rv = callback3.WaitForResult();
robpercival214763f2016-07-01 23:27:015928 EXPECT_THAT(rv, IsOk());
[email protected]038e9a32008-10-08 22:40:165929
bnc691fda62016-08-12 00:43:165930 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:525931 EXPECT_FALSE(response->auth_challenge);
[email protected]038e9a32008-10-08 22:40:165932 EXPECT_EQ(100, response->headers->GetContentLength());
[email protected]038e9a32008-10-08 22:40:165933}
[email protected]4ddaf2502008-10-23 18:26:195934
[email protected]ea9dc9a2009-09-05 00:43:325935// For the NTLM implementation using SSPI, we skip the NTLM tests since we
5936// can't hook into its internals to cause it to generate predictable NTLM
5937// authorization headers.
5938#if defined(NTLM_PORTABLE)
Zentaro Kavanagh5b27a6e22017-09-25 23:00:375939// The NTLM authentication unit tests are based on known test data from the
5940// [MS-NLMP] Specification [1]. These tests are primarily of the authentication
5941// flow rather than the implementation of the NTLM protocol. See net/ntlm
5942// for the implementation and testing of the protocol.
5943//
5944// [1] https://msdn.microsoft.com/en-us/library/cc236621.aspx
[email protected]385a4672009-03-11 22:21:295945
5946// Enter the correct password and authenticate successfully.
Zentaro Kavanagh5b27a6e22017-09-25 23:00:375947TEST_F(HttpNetworkTransactionTest, NTLMAuthV1) {
[email protected]1c773ea12009-04-28 19:58:425948 HttpRequestInfo request;
[email protected]3f918782009-02-28 01:29:245949 request.method = "GET";
Bence Béky83eb3512017-09-05 12:56:095950 request.url = GURL("https://172.22.68.17/kids/login.aspx");
[email protected]2217aa22013-10-11 03:03:545951
5952 // Ensure load is not disrupted by flags which suppress behaviour specific
5953 // to other auth schemes.
5954 request.load_flags = LOAD_DO_NOT_USE_EMBEDDED_IDENTITY;
[email protected]3f918782009-02-28 01:29:245955
Zentaro Kavanagh6ccee512017-09-28 18:34:095956 HttpAuthHandlerNTLM::ScopedProcSetter proc_setter(
5957 MockGetMSTime, MockGenerateRandom, MockGetHostName);
danakj1fd259a02016-04-16 03:17:095958 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:275959
Zentaro Kavanagh5b27a6e22017-09-25 23:00:375960 // Generate the NTLM messages based on known test data.
5961 std::string negotiate_msg;
5962 std::string challenge_msg;
5963 std::string authenticate_msg;
5964 base::Base64Encode(
5965 base::StringPiece(
5966 reinterpret_cast<const char*>(ntlm::test::kExpectedNegotiateMsg),
5967 arraysize(ntlm::test::kExpectedNegotiateMsg)),
5968 &negotiate_msg);
5969 base::Base64Encode(base::StringPiece(reinterpret_cast<const char*>(
5970 ntlm::test::kChallengeMsgV1),
5971 arraysize(ntlm::test::kChallengeMsgV1)),
5972 &challenge_msg);
5973 base::Base64Encode(
5974 base::StringPiece(
Zentaro Kavanagh6ccee512017-09-28 18:34:095975 reinterpret_cast<const char*>(
5976 ntlm::test::kExpectedAuthenticateMsgSpecResponseV1),
5977 arraysize(ntlm::test::kExpectedAuthenticateMsgSpecResponseV1)),
Zentaro Kavanagh5b27a6e22017-09-25 23:00:375978 &authenticate_msg);
5979
[email protected]3f918782009-02-28 01:29:245980 MockWrite data_writes1[] = {
5981 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
5982 "Host: 172.22.68.17\r\n"
5983 "Connection: keep-alive\r\n\r\n"),
5984 };
5985
5986 MockRead data_reads1[] = {
5987 MockRead("HTTP/1.1 401 Access Denied\r\n"),
[email protected]aef04272010-06-28 18:03:045988 // Negotiate and NTLM are often requested together. However, we only want
5989 // to test NTLM. Since Negotiate is preferred over NTLM, we have to skip
5990 // the header that requests Negotiate for this test.
[email protected]3f918782009-02-28 01:29:245991 MockRead("WWW-Authenticate: NTLM\r\n"),
5992 MockRead("Connection: close\r\n"),
5993 MockRead("Content-Length: 42\r\n"),
[email protected]076c85082009-04-10 23:21:365994 MockRead("Content-Type: text/html\r\n\r\n"),
[email protected]3f918782009-02-28 01:29:245995 // Missing content -- won't matter, as connection will be reset.
[email protected]3f918782009-02-28 01:29:245996 };
5997
5998 MockWrite data_writes2[] = {
bnc691fda62016-08-12 00:43:165999 // After restarting with a null identity, this is the
6000 // request we should be issuing -- the final header line contains a Type
6001 // 1 message.
6002 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
6003 "Host: 172.22.68.17\r\n"
6004 "Connection: keep-alive\r\n"
Zentaro Kavanagh5b27a6e22017-09-25 23:00:376005 "Authorization: NTLM "),
6006 MockWrite(negotiate_msg.c_str()), MockWrite("\r\n\r\n"),
[email protected]3f918782009-02-28 01:29:246007
bnc691fda62016-08-12 00:43:166008 // After calling trans.RestartWithAuth(), we should send a Type 3 message
Zentaro Kavanagh5b27a6e22017-09-25 23:00:376009 // (using correct credentials). The second request continues on the
6010 // same connection.
bnc691fda62016-08-12 00:43:166011 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
6012 "Host: 172.22.68.17\r\n"
6013 "Connection: keep-alive\r\n"
Zentaro Kavanagh5b27a6e22017-09-25 23:00:376014 "Authorization: NTLM "),
6015 MockWrite(authenticate_msg.c_str()), MockWrite("\r\n\r\n"),
[email protected]3f918782009-02-28 01:29:246016 };
6017
6018 MockRead data_reads2[] = {
Bence Béky1e4ef192017-09-18 19:58:026019 // The origin server responds with a Type 2 message.
6020 MockRead("HTTP/1.1 401 Access Denied\r\n"),
Zentaro Kavanagh5b27a6e22017-09-25 23:00:376021 MockRead("WWW-Authenticate: NTLM "), MockRead(challenge_msg.c_str()),
6022 MockRead("\r\n"), MockRead("Content-Length: 42\r\n"),
Bence Béky1e4ef192017-09-18 19:58:026023 MockRead("Content-Type: text/html\r\n\r\n"),
6024 MockRead("You are not authorized to view this page\r\n"),
[email protected]3f918782009-02-28 01:29:246025
Bence Béky1e4ef192017-09-18 19:58:026026 // Lastly we get the desired content.
6027 MockRead("HTTP/1.1 200 OK\r\n"),
6028 MockRead("Content-Type: text/html; charset=utf-8\r\n"),
6029 MockRead("Content-Length: 14\r\n\r\n"), MockRead("Please Login\r\n"),
[email protected]3f918782009-02-28 01:29:246030 };
6031
[email protected]31a2bfe2010-02-09 08:03:396032 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
6033 data_writes1, arraysize(data_writes1));
6034 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
6035 data_writes2, arraysize(data_writes2));
[email protected]bb88e1d32013-05-03 23:11:076036 session_deps_.socket_factory->AddSocketDataProvider(&data1);
6037 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]3f918782009-02-28 01:29:246038
Bence Béky83eb3512017-09-05 12:56:096039 SSLSocketDataProvider ssl1(ASYNC, OK);
6040 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl1);
6041 SSLSocketDataProvider ssl2(ASYNC, OK);
6042 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
6043
[email protected]49639fa2011-12-20 23:22:416044 TestCompletionCallback callback1;
[email protected]3f918782009-02-28 01:29:246045
bnc691fda62016-08-12 00:43:166046 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]0b0bf032010-09-21 18:08:506047
tfarina42834112016-09-22 13:38:206048 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:016049 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]3f918782009-02-28 01:29:246050
6051 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:016052 EXPECT_THAT(rv, IsOk());
[email protected]3f918782009-02-28 01:29:246053
bnc691fda62016-08-12 00:43:166054 EXPECT_FALSE(trans.IsReadyToRestartForAuth());
[email protected]0757e7702009-03-27 04:00:226055
bnc691fda62016-08-12 00:43:166056 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:526057 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:046058 EXPECT_TRUE(CheckNTLMServerAuth(response->auth_challenge.get()));
[email protected]3f918782009-02-28 01:29:246059
[email protected]49639fa2011-12-20 23:22:416060 TestCompletionCallback callback2;
[email protected]10af5fe72011-01-31 16:17:256061
Zentaro Kavanagh5b27a6e22017-09-25 23:00:376062 rv = trans.RestartWithAuth(
6063 AuthCredentials(ntlm::test::kDomainUserCombined, ntlm::test::kPassword),
6064 callback2.callback());
robpercival214763f2016-07-01 23:27:016065 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]10af5fe72011-01-31 16:17:256066
6067 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:016068 EXPECT_THAT(rv, IsOk());
[email protected]10af5fe72011-01-31 16:17:256069
bnc691fda62016-08-12 00:43:166070 EXPECT_TRUE(trans.IsReadyToRestartForAuth());
[email protected]10af5fe72011-01-31 16:17:256071
bnc691fda62016-08-12 00:43:166072 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:526073 ASSERT_TRUE(response);
6074 EXPECT_FALSE(response->auth_challenge);
[email protected]10af5fe72011-01-31 16:17:256075
[email protected]49639fa2011-12-20 23:22:416076 TestCompletionCallback callback3;
[email protected]3f918782009-02-28 01:29:246077
bnc691fda62016-08-12 00:43:166078 rv = trans.RestartWithAuth(AuthCredentials(), callback3.callback());
robpercival214763f2016-07-01 23:27:016079 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]3f918782009-02-28 01:29:246080
[email protected]0757e7702009-03-27 04:00:226081 rv = callback3.WaitForResult();
robpercival214763f2016-07-01 23:27:016082 EXPECT_THAT(rv, IsOk());
[email protected]3f918782009-02-28 01:29:246083
bnc691fda62016-08-12 00:43:166084 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:526085 ASSERT_TRUE(response);
6086 EXPECT_FALSE(response->auth_challenge);
Bence Béky1e4ef192017-09-18 19:58:026087 EXPECT_EQ(14, response->headers->GetContentLength());
6088
6089 std::string response_data;
6090 rv = ReadTransaction(&trans, &response_data);
6091 EXPECT_THAT(rv, IsOk());
6092 EXPECT_EQ("Please Login\r\n", response_data);
6093
6094 EXPECT_TRUE(data1.AllReadDataConsumed());
6095 EXPECT_TRUE(data1.AllWriteDataConsumed());
6096 EXPECT_TRUE(data2.AllReadDataConsumed());
6097 EXPECT_TRUE(data2.AllWriteDataConsumed());
[email protected]3f918782009-02-28 01:29:246098}
6099
[email protected]385a4672009-03-11 22:21:296100// Enter a wrong password, and then the correct one.
Zentaro Kavanagh5b27a6e22017-09-25 23:00:376101TEST_F(HttpNetworkTransactionTest, NTLMAuthV1WrongThenRightPassword) {
[email protected]1c773ea12009-04-28 19:58:426102 HttpRequestInfo request;
[email protected]385a4672009-03-11 22:21:296103 request.method = "GET";
Bence Béky83eb3512017-09-05 12:56:096104 request.url = GURL("https://172.22.68.17/kids/login.aspx");
[email protected]385a4672009-03-11 22:21:296105
Zentaro Kavanagh6ccee512017-09-28 18:34:096106 HttpAuthHandlerNTLM::ScopedProcSetter proc_setter(
6107 MockGetMSTime, MockGenerateRandom, MockGetHostName);
danakj1fd259a02016-04-16 03:17:096108 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:276109
Zentaro Kavanagh5b27a6e22017-09-25 23:00:376110 // Generate the NTLM messages based on known test data.
6111 std::string negotiate_msg;
6112 std::string challenge_msg;
6113 std::string authenticate_msg;
6114 base::Base64Encode(
6115 base::StringPiece(
6116 reinterpret_cast<const char*>(ntlm::test::kExpectedNegotiateMsg),
6117 arraysize(ntlm::test::kExpectedNegotiateMsg)),
6118 &negotiate_msg);
6119 base::Base64Encode(base::StringPiece(reinterpret_cast<const char*>(
6120 ntlm::test::kChallengeMsgV1),
6121 arraysize(ntlm::test::kChallengeMsgV1)),
6122 &challenge_msg);
6123 base::Base64Encode(
6124 base::StringPiece(
Zentaro Kavanagh6ccee512017-09-28 18:34:096125 reinterpret_cast<const char*>(
6126 ntlm::test::kExpectedAuthenticateMsgSpecResponseV1),
6127 arraysize(ntlm::test::kExpectedAuthenticateMsgSpecResponseV1)),
Zentaro Kavanagh5b27a6e22017-09-25 23:00:376128 &authenticate_msg);
6129
6130 // The authenticate message when |kWrongPassword| is sent.
6131 std::string wrong_password_authenticate_msg(
6132 "TlRMTVNTUAADAAAAGAAYAEAAAAAYABgAWAAAAAwADABwAAAACAAIAHwAAAAQABAAhAAAAAAA"
6133 "AABAAAAAA4IIAKqqqqqqqqqqAAAAAAAAAAAAAAAAAAAAAF2npafgDxlql9qxEIhLlsuuJIEd"
6134 "NQHk7kQAbwBtAGEAaQBuAFUAcwBlAHIAQwBPAE0AUABVAFQARQBSAA==");
6135
6136 // Sanity check that this is the same as |authenticate_msg| except for the
6137 // 24 bytes (32 encoded chars) of the NTLM Response.
6138 ASSERT_EQ(authenticate_msg.length(),
6139 wrong_password_authenticate_msg.length());
Zentaro Kavanagh6ccee512017-09-28 18:34:096140 ASSERT_EQ(authenticate_msg.length(), 200u);
Zentaro Kavanagh5b27a6e22017-09-25 23:00:376141 ASSERT_EQ(base::StringPiece(authenticate_msg.data(), 117),
6142 base::StringPiece(wrong_password_authenticate_msg.data(), 117));
6143 ASSERT_EQ(
6144 base::StringPiece(authenticate_msg.data() + 149, 51),
6145 base::StringPiece(wrong_password_authenticate_msg.data() + 149, 51));
6146
[email protected]385a4672009-03-11 22:21:296147 MockWrite data_writes1[] = {
6148 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
6149 "Host: 172.22.68.17\r\n"
6150 "Connection: keep-alive\r\n\r\n"),
6151 };
6152
6153 MockRead data_reads1[] = {
6154 MockRead("HTTP/1.1 401 Access Denied\r\n"),
[email protected]aef04272010-06-28 18:03:046155 // Negotiate and NTLM are often requested together. However, we only want
6156 // to test NTLM. Since Negotiate is preferred over NTLM, we have to skip
6157 // the header that requests Negotiate for this test.
[email protected]385a4672009-03-11 22:21:296158 MockRead("WWW-Authenticate: NTLM\r\n"),
6159 MockRead("Connection: close\r\n"),
6160 MockRead("Content-Length: 42\r\n"),
[email protected]076c85082009-04-10 23:21:366161 MockRead("Content-Type: text/html\r\n\r\n"),
[email protected]385a4672009-03-11 22:21:296162 // Missing content -- won't matter, as connection will be reset.
[email protected]385a4672009-03-11 22:21:296163 };
6164
6165 MockWrite data_writes2[] = {
bnc691fda62016-08-12 00:43:166166 // After restarting with a null identity, this is the
6167 // request we should be issuing -- the final header line contains a Type
6168 // 1 message.
6169 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
6170 "Host: 172.22.68.17\r\n"
6171 "Connection: keep-alive\r\n"
Zentaro Kavanagh5b27a6e22017-09-25 23:00:376172 "Authorization: NTLM "),
6173 MockWrite(negotiate_msg.c_str()), MockWrite("\r\n\r\n"),
[email protected]385a4672009-03-11 22:21:296174
bnc691fda62016-08-12 00:43:166175 // After calling trans.RestartWithAuth(), we should send a Type 3 message
Zentaro Kavanagh5b27a6e22017-09-25 23:00:376176 // (using incorrect credentials). The second request continues on the
6177 // same connection.
bnc691fda62016-08-12 00:43:166178 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
6179 "Host: 172.22.68.17\r\n"
6180 "Connection: keep-alive\r\n"
Zentaro Kavanagh5b27a6e22017-09-25 23:00:376181 "Authorization: NTLM "),
6182 MockWrite(wrong_password_authenticate_msg.c_str()), MockWrite("\r\n\r\n"),
[email protected]385a4672009-03-11 22:21:296183 };
6184
6185 MockRead data_reads2[] = {
Zentaro Kavanagh5b27a6e22017-09-25 23:00:376186 // The origin server responds with a Type 2 message.
6187 MockRead("HTTP/1.1 401 Access Denied\r\n"),
6188 MockRead("WWW-Authenticate: NTLM "), MockRead(challenge_msg.c_str()),
6189 MockRead("\r\n"), MockRead("Content-Length: 42\r\n"),
6190 MockRead("Content-Type: text/html\r\n\r\n"),
6191 MockRead("You are not authorized to view this page\r\n"),
[email protected]385a4672009-03-11 22:21:296192
Zentaro Kavanagh5b27a6e22017-09-25 23:00:376193 // Wrong password.
6194 MockRead("HTTP/1.1 401 Access Denied\r\n"),
6195 MockRead("WWW-Authenticate: NTLM\r\n"), MockRead("Connection: close\r\n"),
6196 MockRead("Content-Length: 42\r\n"),
6197 MockRead("Content-Type: text/html\r\n\r\n"),
6198 // Missing content -- won't matter, as connection will be reset.
[email protected]385a4672009-03-11 22:21:296199 };
6200
6201 MockWrite data_writes3[] = {
bnc691fda62016-08-12 00:43:166202 // After restarting with a null identity, this is the
6203 // request we should be issuing -- the final header line contains a Type
6204 // 1 message.
6205 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
6206 "Host: 172.22.68.17\r\n"
6207 "Connection: keep-alive\r\n"
Zentaro Kavanagh5b27a6e22017-09-25 23:00:376208 "Authorization: NTLM "),
6209 MockWrite(negotiate_msg.c_str()), MockWrite("\r\n\r\n"),
[email protected]385a4672009-03-11 22:21:296210
bnc691fda62016-08-12 00:43:166211 // After calling trans.RestartWithAuth(), we should send a Type 3 message
6212 // (the credentials for the origin server). The second request continues
6213 // on the same connection.
6214 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
6215 "Host: 172.22.68.17\r\n"
6216 "Connection: keep-alive\r\n"
Zentaro Kavanagh5b27a6e22017-09-25 23:00:376217 "Authorization: NTLM "),
6218 MockWrite(authenticate_msg.c_str()), MockWrite("\r\n\r\n"),
[email protected]385a4672009-03-11 22:21:296219 };
6220
6221 MockRead data_reads3[] = {
Bence Béky1e4ef192017-09-18 19:58:026222 // The origin server responds with a Type 2 message.
6223 MockRead("HTTP/1.1 401 Access Denied\r\n"),
Zentaro Kavanagh5b27a6e22017-09-25 23:00:376224 MockRead("WWW-Authenticate: NTLM "), MockRead(challenge_msg.c_str()),
6225 MockRead("\r\n"), MockRead("Content-Length: 42\r\n"),
Bence Béky1e4ef192017-09-18 19:58:026226 MockRead("Content-Type: text/html\r\n\r\n"),
6227 MockRead("You are not authorized to view this page\r\n"),
[email protected]385a4672009-03-11 22:21:296228
Bence Béky1e4ef192017-09-18 19:58:026229 // Lastly we get the desired content.
6230 MockRead("HTTP/1.1 200 OK\r\n"),
6231 MockRead("Content-Type: text/html; charset=utf-8\r\n"),
6232 MockRead("Content-Length: 14\r\n\r\n"), MockRead("Please Login\r\n"),
[email protected]385a4672009-03-11 22:21:296233 };
6234
[email protected]31a2bfe2010-02-09 08:03:396235 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
6236 data_writes1, arraysize(data_writes1));
6237 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
6238 data_writes2, arraysize(data_writes2));
6239 StaticSocketDataProvider data3(data_reads3, arraysize(data_reads3),
6240 data_writes3, arraysize(data_writes3));
[email protected]bb88e1d32013-05-03 23:11:076241 session_deps_.socket_factory->AddSocketDataProvider(&data1);
6242 session_deps_.socket_factory->AddSocketDataProvider(&data2);
6243 session_deps_.socket_factory->AddSocketDataProvider(&data3);
[email protected]385a4672009-03-11 22:21:296244
Bence Béky83eb3512017-09-05 12:56:096245 SSLSocketDataProvider ssl1(ASYNC, OK);
6246 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl1);
6247 SSLSocketDataProvider ssl2(ASYNC, OK);
6248 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
6249 SSLSocketDataProvider ssl3(ASYNC, OK);
6250 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl3);
6251
[email protected]49639fa2011-12-20 23:22:416252 TestCompletionCallback callback1;
[email protected]385a4672009-03-11 22:21:296253
bnc691fda62016-08-12 00:43:166254 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]0b0bf032010-09-21 18:08:506255
tfarina42834112016-09-22 13:38:206256 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:016257 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]385a4672009-03-11 22:21:296258
6259 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:016260 EXPECT_THAT(rv, IsOk());
[email protected]385a4672009-03-11 22:21:296261
bnc691fda62016-08-12 00:43:166262 EXPECT_FALSE(trans.IsReadyToRestartForAuth());
[email protected]385a4672009-03-11 22:21:296263
bnc691fda62016-08-12 00:43:166264 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:526265 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:046266 EXPECT_TRUE(CheckNTLMServerAuth(response->auth_challenge.get()));
[email protected]385a4672009-03-11 22:21:296267
[email protected]49639fa2011-12-20 23:22:416268 TestCompletionCallback callback2;
[email protected]385a4672009-03-11 22:21:296269
[email protected]0757e7702009-03-27 04:00:226270 // Enter the wrong password.
Zentaro Kavanagh5b27a6e22017-09-25 23:00:376271 rv = trans.RestartWithAuth(
6272 AuthCredentials(ntlm::test::kDomainUserCombined, kWrongPassword),
6273 callback2.callback());
robpercival214763f2016-07-01 23:27:016274 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]385a4672009-03-11 22:21:296275
[email protected]10af5fe72011-01-31 16:17:256276 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:016277 EXPECT_THAT(rv, IsOk());
[email protected]385a4672009-03-11 22:21:296278
bnc691fda62016-08-12 00:43:166279 EXPECT_TRUE(trans.IsReadyToRestartForAuth());
[email protected]49639fa2011-12-20 23:22:416280 TestCompletionCallback callback3;
bnc691fda62016-08-12 00:43:166281 rv = trans.RestartWithAuth(AuthCredentials(), callback3.callback());
robpercival214763f2016-07-01 23:27:016282 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]10af5fe72011-01-31 16:17:256283 rv = callback3.WaitForResult();
robpercival214763f2016-07-01 23:27:016284 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:166285 EXPECT_FALSE(trans.IsReadyToRestartForAuth());
[email protected]0757e7702009-03-27 04:00:226286
bnc691fda62016-08-12 00:43:166287 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:526288 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:046289 EXPECT_TRUE(CheckNTLMServerAuth(response->auth_challenge.get()));
[email protected]0757e7702009-03-27 04:00:226290
[email protected]49639fa2011-12-20 23:22:416291 TestCompletionCallback callback4;
[email protected]0757e7702009-03-27 04:00:226292
6293 // Now enter the right password.
Zentaro Kavanagh5b27a6e22017-09-25 23:00:376294 rv = trans.RestartWithAuth(
6295 AuthCredentials(ntlm::test::kDomainUserCombined, ntlm::test::kPassword),
6296 callback4.callback());
robpercival214763f2016-07-01 23:27:016297 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]10af5fe72011-01-31 16:17:256298
6299 rv = callback4.WaitForResult();
robpercival214763f2016-07-01 23:27:016300 EXPECT_THAT(rv, IsOk());
[email protected]10af5fe72011-01-31 16:17:256301
bnc691fda62016-08-12 00:43:166302 EXPECT_TRUE(trans.IsReadyToRestartForAuth());
[email protected]10af5fe72011-01-31 16:17:256303
[email protected]49639fa2011-12-20 23:22:416304 TestCompletionCallback callback5;
[email protected]10af5fe72011-01-31 16:17:256305
6306 // One more roundtrip
bnc691fda62016-08-12 00:43:166307 rv = trans.RestartWithAuth(AuthCredentials(), callback5.callback());
robpercival214763f2016-07-01 23:27:016308 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]0757e7702009-03-27 04:00:226309
6310 rv = callback5.WaitForResult();
robpercival214763f2016-07-01 23:27:016311 EXPECT_THAT(rv, IsOk());
[email protected]0757e7702009-03-27 04:00:226312
bnc691fda62016-08-12 00:43:166313 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:526314 EXPECT_FALSE(response->auth_challenge);
Bence Béky1e4ef192017-09-18 19:58:026315 EXPECT_EQ(14, response->headers->GetContentLength());
6316
6317 std::string response_data;
6318 rv = ReadTransaction(&trans, &response_data);
6319 EXPECT_THAT(rv, IsOk());
6320 EXPECT_EQ("Please Login\r\n", response_data);
6321
6322 EXPECT_TRUE(data1.AllReadDataConsumed());
6323 EXPECT_TRUE(data1.AllWriteDataConsumed());
6324 EXPECT_TRUE(data2.AllReadDataConsumed());
6325 EXPECT_TRUE(data2.AllWriteDataConsumed());
6326 EXPECT_TRUE(data3.AllReadDataConsumed());
6327 EXPECT_TRUE(data3.AllWriteDataConsumed());
[email protected]385a4672009-03-11 22:21:296328}
Bence Béky83eb3512017-09-05 12:56:096329
Bence Béky3238f2e12017-09-22 22:44:496330// Server requests NTLM authentication, which is not supported over HTTP/2.
6331// Subsequent request with authorization header should be sent over HTTP/1.1.
Bence Béky83eb3512017-09-05 12:56:096332TEST_F(HttpNetworkTransactionTest, NTLMOverHttp2) {
Zentaro Kavanagh6ccee512017-09-28 18:34:096333 HttpAuthHandlerNTLM::ScopedProcSetter proc_setter(
6334 MockGetMSTime, MockGenerateRandom, MockGetHostName);
Bence Béky83eb3512017-09-05 12:56:096335
6336 const char* kUrl = "https://172.22.68.17/kids/login.aspx";
6337
6338 HttpRequestInfo request;
6339 request.method = "GET";
6340 request.url = GURL(kUrl);
6341
6342 // First request without credentials.
6343 SpdyHeaderBlock request_headers0(spdy_util_.ConstructGetHeaderBlock(kUrl));
6344 SpdySerializedFrame request0(spdy_util_.ConstructSpdyHeaders(
6345 1, std::move(request_headers0), LOWEST, true));
6346
6347 SpdyHeaderBlock response_headers0;
Bence Békybda82952017-10-02 17:35:276348 response_headers0[kHttp2StatusHeader] = "401";
Bence Béky83eb3512017-09-05 12:56:096349 response_headers0["www-authenticate"] = "NTLM";
6350 SpdySerializedFrame resp(spdy_util_.ConstructSpdyResponseHeaders(
6351 1, std::move(response_headers0), true));
6352
Zentaro Kavanagh5b27a6e22017-09-25 23:00:376353 // Stream 1 is closed.
6354 spdy_util_.UpdateWithStreamDestruction(1);
6355
6356 // Generate the NTLM messages based on known test data.
6357 std::string negotiate_msg;
6358 std::string challenge_msg;
6359 std::string authenticate_msg;
6360 base::Base64Encode(
6361 base::StringPiece(
6362 reinterpret_cast<const char*>(ntlm::test::kExpectedNegotiateMsg),
6363 arraysize(ntlm::test::kExpectedNegotiateMsg)),
6364 &negotiate_msg);
6365 base::Base64Encode(base::StringPiece(reinterpret_cast<const char*>(
6366 ntlm::test::kChallengeMsgV1),
6367 arraysize(ntlm::test::kChallengeMsgV1)),
6368 &challenge_msg);
6369 base::Base64Encode(
6370 base::StringPiece(
Zentaro Kavanagh6ccee512017-09-28 18:34:096371 reinterpret_cast<const char*>(
6372 ntlm::test::kExpectedAuthenticateMsgSpecResponseV1),
6373 arraysize(ntlm::test::kExpectedAuthenticateMsgSpecResponseV1)),
Zentaro Kavanagh5b27a6e22017-09-25 23:00:376374 &authenticate_msg);
6375
6376 // Retry with authorization header.
6377 SpdyHeaderBlock request_headers1(spdy_util_.ConstructGetHeaderBlock(kUrl));
6378 request_headers1["authorization"] = std::string("NTLM ") + negotiate_msg;
6379 SpdySerializedFrame request1(spdy_util_.ConstructSpdyHeaders(
6380 3, std::move(request_headers1), LOWEST, true));
6381
6382 SpdySerializedFrame rst(
6383 spdy_util_.ConstructSpdyRstStream(3, ERROR_CODE_HTTP_1_1_REQUIRED));
6384
Bence Béky3238f2e12017-09-22 22:44:496385 MockWrite writes0[] = {CreateMockWrite(request0, 0)};
6386 MockRead reads0[] = {CreateMockRead(resp, 1), MockRead(ASYNC, 0, 2)};
Bence Béky83eb3512017-09-05 12:56:096387
6388 // Retry yet again using HTTP/1.1.
6389 MockWrite writes1[] = {
6390 // After restarting with a null identity, this is the
6391 // request we should be issuing -- the final header line contains a Type
6392 // 1 message.
6393 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
6394 "Host: 172.22.68.17\r\n"
6395 "Connection: keep-alive\r\n"
Zentaro Kavanagh5b27a6e22017-09-25 23:00:376396 "Authorization: NTLM "),
6397 MockWrite(negotiate_msg.c_str()), MockWrite("\r\n\r\n"),
Bence Béky83eb3512017-09-05 12:56:096398
6399 // After calling trans.RestartWithAuth(), we should send a Type 3 message
6400 // (the credentials for the origin server). The second request continues
6401 // on the same connection.
6402 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
6403 "Host: 172.22.68.17\r\n"
6404 "Connection: keep-alive\r\n"
Zentaro Kavanagh5b27a6e22017-09-25 23:00:376405 "Authorization: NTLM "),
6406 MockWrite(authenticate_msg.c_str()), MockWrite("\r\n\r\n"),
Bence Béky83eb3512017-09-05 12:56:096407 };
6408
6409 MockRead reads1[] = {
6410 // The origin server responds with a Type 2 message.
6411 MockRead("HTTP/1.1 401 Access Denied\r\n"),
Zentaro Kavanagh5b27a6e22017-09-25 23:00:376412 MockRead("WWW-Authenticate: NTLM "), MockRead(challenge_msg.c_str()),
6413 MockRead("\r\n"), MockRead("Content-Length: 42\r\n"),
Bence Béky83eb3512017-09-05 12:56:096414 MockRead("Content-Type: text/html\r\n\r\n"),
6415 MockRead("You are not authorized to view this page\r\n"),
6416
6417 // Lastly we get the desired content.
6418 MockRead("HTTP/1.1 200 OK\r\n"),
6419 MockRead("Content-Type: text/html; charset=utf-8\r\n"),
Bence Béky1e4ef192017-09-18 19:58:026420 MockRead("Content-Length: 14\r\n\r\n"), MockRead("Please Login\r\n"),
Bence Béky83eb3512017-09-05 12:56:096421 };
6422 SequencedSocketData data0(reads0, arraysize(reads0), writes0,
6423 arraysize(writes0));
6424 StaticSocketDataProvider data1(reads1, arraysize(reads1), writes1,
6425 arraysize(writes1));
6426 session_deps_.socket_factory->AddSocketDataProvider(&data0);
6427 session_deps_.socket_factory->AddSocketDataProvider(&data1);
6428
6429 SSLSocketDataProvider ssl0(ASYNC, OK);
6430 ssl0.next_proto = kProtoHTTP2;
6431 SSLSocketDataProvider ssl1(ASYNC, OK);
6432 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl0);
6433 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl1);
6434
6435 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
6436 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
6437
6438 TestCompletionCallback callback1;
6439 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
6440 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
6441
6442 rv = callback1.WaitForResult();
6443 EXPECT_THAT(rv, IsOk());
6444
6445 EXPECT_FALSE(trans.IsReadyToRestartForAuth());
6446
6447 const HttpResponseInfo* response = trans.GetResponseInfo();
6448 ASSERT_TRUE(response);
6449 EXPECT_TRUE(CheckNTLMServerAuth(response->auth_challenge.get()));
6450
6451 TestCompletionCallback callback2;
6452
Zentaro Kavanagh5b27a6e22017-09-25 23:00:376453 rv = trans.RestartWithAuth(
6454 AuthCredentials(ntlm::test::kDomainUserCombined, ntlm::test::kPassword),
6455 callback2.callback());
Bence Béky83eb3512017-09-05 12:56:096456 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
6457
6458 rv = callback2.WaitForResult();
6459 EXPECT_THAT(rv, IsOk());
6460
6461 EXPECT_TRUE(trans.IsReadyToRestartForAuth());
6462
6463 response = trans.GetResponseInfo();
6464 ASSERT_TRUE(response);
6465 EXPECT_FALSE(response->auth_challenge);
6466
6467 TestCompletionCallback callback3;
6468
6469 rv = trans.RestartWithAuth(AuthCredentials(), callback3.callback());
6470 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
6471
6472 rv = callback3.WaitForResult();
6473 EXPECT_THAT(rv, IsOk());
6474
6475 response = trans.GetResponseInfo();
6476 ASSERT_TRUE(response);
6477 EXPECT_FALSE(response->auth_challenge);
Bence Béky1e4ef192017-09-18 19:58:026478 EXPECT_EQ(14, response->headers->GetContentLength());
6479
6480 std::string response_data;
6481 rv = ReadTransaction(&trans, &response_data);
6482 EXPECT_THAT(rv, IsOk());
6483 EXPECT_EQ("Please Login\r\n", response_data);
6484
6485 EXPECT_TRUE(data0.AllReadDataConsumed());
6486 EXPECT_TRUE(data0.AllWriteDataConsumed());
6487 EXPECT_TRUE(data1.AllReadDataConsumed());
6488 EXPECT_TRUE(data1.AllWriteDataConsumed());
Bence Béky83eb3512017-09-05 12:56:096489}
[email protected]ea9dc9a2009-09-05 00:43:326490#endif // NTLM_PORTABLE
[email protected]385a4672009-03-11 22:21:296491
[email protected]4ddaf2502008-10-23 18:26:196492// Test reading a server response which has only headers, and no body.
6493// After some maximum number of bytes is consumed, the transaction should
6494// fail with ERR_RESPONSE_HEADERS_TOO_BIG.
bncd16676a2016-07-20 16:23:016495TEST_F(HttpNetworkTransactionTest, LargeHeadersNoBody) {
[email protected]1c773ea12009-04-28 19:58:426496 HttpRequestInfo request;
[email protected]4ddaf2502008-10-23 18:26:196497 request.method = "GET";
bncce36dca22015-04-21 22:11:236498 request.url = GURL("http://www.example.org/");
[email protected]4ddaf2502008-10-23 18:26:196499
danakj1fd259a02016-04-16 03:17:096500 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:166501 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:276502
[email protected]b75b7b2f2009-10-06 00:54:536503 // Respond with 300 kb of headers (we should fail after 256 kb).
[email protected]15a5ccf82008-10-23 19:57:436504 std::string large_headers_string;
[email protected]b75b7b2f2009-10-06 00:54:536505 FillLargeHeadersString(&large_headers_string, 300 * 1024);
[email protected]4ddaf2502008-10-23 18:26:196506
6507 MockRead data_reads[] = {
6508 MockRead("HTTP/1.0 200 OK\r\n"),
[email protected]8ddf8322012-02-23 18:08:066509 MockRead(ASYNC, large_headers_string.data(), large_headers_string.size()),
[email protected]4ddaf2502008-10-23 18:26:196510 MockRead("\r\nBODY"),
[email protected]8ddf8322012-02-23 18:08:066511 MockRead(SYNCHRONOUS, OK),
[email protected]4ddaf2502008-10-23 18:26:196512 };
[email protected]31a2bfe2010-02-09 08:03:396513 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:076514 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]4ddaf2502008-10-23 18:26:196515
[email protected]49639fa2011-12-20 23:22:416516 TestCompletionCallback callback;
[email protected]4ddaf2502008-10-23 18:26:196517
tfarina42834112016-09-22 13:38:206518 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:016519 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]4ddaf2502008-10-23 18:26:196520
6521 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:016522 EXPECT_THAT(rv, IsError(ERR_RESPONSE_HEADERS_TOO_BIG));
[email protected]4ddaf2502008-10-23 18:26:196523}
[email protected]f4e426b2008-11-05 00:24:496524
6525// Make sure that we don't try to reuse a TCPClientSocket when failing to
6526// establish tunnel.
6527// http://code.google.com/p/chromium/issues/detail?id=3772
bncd16676a2016-07-20 16:23:016528TEST_F(HttpNetworkTransactionTest, DontRecycleTransportSocketForSSLTunnel) {
[email protected]cb9bf6ca2011-01-28 13:15:276529 HttpRequestInfo request;
6530 request.method = "GET";
bncce36dca22015-04-21 22:11:236531 request.url = GURL("https://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:276532
[email protected]f4e426b2008-11-05 00:24:496533 // Configure against proxy server "myproxy:70".
rdsmith82957ad2015-09-16 19:42:036534 session_deps_.proxy_service = ProxyService::CreateFixed("myproxy:70");
[email protected]db8f44c2008-12-13 04:52:016535
danakj1fd259a02016-04-16 03:17:096536 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]f4e426b2008-11-05 00:24:496537
bnc87dcefc2017-05-25 12:47:586538 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:196539 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]f4e426b2008-11-05 00:24:496540
[email protected]f4e426b2008-11-05 00:24:496541 // Since we have proxy, should try to establish tunnel.
6542 MockWrite data_writes1[] = {
rsleevidb16bb02015-11-12 23:47:176543 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
6544 "Host: www.example.org:443\r\n"
6545 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]f4e426b2008-11-05 00:24:496546 };
6547
[email protected]77848d12008-11-14 00:00:226548 // The proxy responds to the connect with a 404, using a persistent
[email protected]f4e426b2008-11-05 00:24:496549 // connection. Usually a proxy would return 501 (not implemented),
6550 // or 200 (tunnel established).
6551 MockRead data_reads1[] = {
mmenked39192ee2015-12-09 00:57:236552 MockRead("HTTP/1.1 404 Not Found\r\n"),
6553 MockRead("Content-Length: 10\r\n\r\n"),
6554 MockRead(SYNCHRONOUS, ERR_UNEXPECTED),
[email protected]f4e426b2008-11-05 00:24:496555 };
6556
[email protected]31a2bfe2010-02-09 08:03:396557 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
6558 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:076559 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]f4e426b2008-11-05 00:24:496560
[email protected]49639fa2011-12-20 23:22:416561 TestCompletionCallback callback1;
[email protected]f4e426b2008-11-05 00:24:496562
tfarina42834112016-09-22 13:38:206563 int rv = trans->Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:016564 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]f4e426b2008-11-05 00:24:496565
6566 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:016567 EXPECT_THAT(rv, IsError(ERR_TUNNEL_CONNECTION_FAILED));
[email protected]f4e426b2008-11-05 00:24:496568
[email protected]b4404c02009-04-10 16:38:526569 // Empty the current queue. This is necessary because idle sockets are
6570 // added to the connection pool asynchronously with a PostTask.
fdoray92e35a72016-06-10 15:54:556571 base::RunLoop().RunUntilIdle();
[email protected]b4404c02009-04-10 16:38:526572
[email protected]f4e426b2008-11-05 00:24:496573 // We now check to make sure the TCPClientSocket was not added back to
6574 // the pool.
[email protected]90499482013-06-01 00:39:506575 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]f4e426b2008-11-05 00:24:496576 trans.reset();
fdoray92e35a72016-06-10 15:54:556577 base::RunLoop().RunUntilIdle();
[email protected]f4e426b2008-11-05 00:24:496578 // Make sure that the socket didn't get recycled after calling the destructor.
[email protected]90499482013-06-01 00:39:506579 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]f4e426b2008-11-05 00:24:496580}
[email protected]372d34a2008-11-05 21:30:516581
[email protected]1b157c02009-04-21 01:55:406582// Make sure that we recycle a socket after reading all of the response body.
bncd16676a2016-07-20 16:23:016583TEST_F(HttpNetworkTransactionTest, RecycleSocket) {
[email protected]1c773ea12009-04-28 19:58:426584 HttpRequestInfo request;
[email protected]1b157c02009-04-21 01:55:406585 request.method = "GET";
bncce36dca22015-04-21 22:11:236586 request.url = GURL("http://www.example.org/");
[email protected]1b157c02009-04-21 01:55:406587
danakj1fd259a02016-04-16 03:17:096588 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:276589
bnc691fda62016-08-12 00:43:166590 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:276591
[email protected]1b157c02009-04-21 01:55:406592 MockRead data_reads[] = {
6593 // A part of the response body is received with the response headers.
6594 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 11\r\n\r\nhel"),
6595 // The rest of the response body is received in two parts.
6596 MockRead("lo"),
6597 MockRead(" world"),
6598 MockRead("junk"), // Should not be read!!
[email protected]8ddf8322012-02-23 18:08:066599 MockRead(SYNCHRONOUS, OK),
[email protected]1b157c02009-04-21 01:55:406600 };
6601
[email protected]31a2bfe2010-02-09 08:03:396602 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:076603 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1b157c02009-04-21 01:55:406604
[email protected]49639fa2011-12-20 23:22:416605 TestCompletionCallback callback;
[email protected]1b157c02009-04-21 01:55:406606
tfarina42834112016-09-22 13:38:206607 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:016608 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]1b157c02009-04-21 01:55:406609
6610 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:016611 EXPECT_THAT(rv, IsOk());
[email protected]1b157c02009-04-21 01:55:406612
bnc691fda62016-08-12 00:43:166613 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:526614 ASSERT_TRUE(response);
[email protected]1b157c02009-04-21 01:55:406615
wezca1070932016-05-26 20:30:526616 EXPECT_TRUE(response->headers);
[email protected]1b157c02009-04-21 01:55:406617 std::string status_line = response->headers->GetStatusLine();
6618 EXPECT_EQ("HTTP/1.1 200 OK", status_line);
6619
[email protected]90499482013-06-01 00:39:506620 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]1b157c02009-04-21 01:55:406621
6622 std::string response_data;
bnc691fda62016-08-12 00:43:166623 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:016624 EXPECT_THAT(rv, IsOk());
[email protected]1b157c02009-04-21 01:55:406625 EXPECT_EQ("hello world", response_data);
6626
6627 // Empty the current queue. This is necessary because idle sockets are
6628 // added to the connection pool asynchronously with a PostTask.
fdoray92e35a72016-06-10 15:54:556629 base::RunLoop().RunUntilIdle();
[email protected]1b157c02009-04-21 01:55:406630
6631 // We now check to make sure the socket was added back to the pool.
[email protected]90499482013-06-01 00:39:506632 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]1b157c02009-04-21 01:55:406633}
6634
[email protected]76a505b2010-08-25 06:23:006635// Make sure that we recycle a SSL socket after reading all of the response
6636// body.
bncd16676a2016-07-20 16:23:016637TEST_F(HttpNetworkTransactionTest, RecycleSSLSocket) {
[email protected]76a505b2010-08-25 06:23:006638 HttpRequestInfo request;
6639 request.method = "GET";
bncce36dca22015-04-21 22:11:236640 request.url = GURL("https://www.example.org/");
[email protected]76a505b2010-08-25 06:23:006641
6642 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:236643 MockWrite(
6644 "GET / HTTP/1.1\r\n"
6645 "Host: www.example.org\r\n"
6646 "Connection: keep-alive\r\n\r\n"),
[email protected]76a505b2010-08-25 06:23:006647 };
6648
6649 MockRead data_reads[] = {
6650 MockRead("HTTP/1.1 200 OK\r\n"),
6651 MockRead("Content-Length: 11\r\n\r\n"),
6652 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:066653 MockRead(SYNCHRONOUS, OK),
[email protected]76a505b2010-08-25 06:23:006654 };
6655
[email protected]8ddf8322012-02-23 18:08:066656 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:076657 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]76a505b2010-08-25 06:23:006658
6659 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
6660 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:076661 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]76a505b2010-08-25 06:23:006662
[email protected]49639fa2011-12-20 23:22:416663 TestCompletionCallback callback;
[email protected]76a505b2010-08-25 06:23:006664
danakj1fd259a02016-04-16 03:17:096665 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:166666 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]76a505b2010-08-25 06:23:006667
tfarina42834112016-09-22 13:38:206668 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
[email protected]76a505b2010-08-25 06:23:006669
robpercival214763f2016-07-01 23:27:016670 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
6671 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]76a505b2010-08-25 06:23:006672
bnc691fda62016-08-12 00:43:166673 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:526674 ASSERT_TRUE(response);
6675 ASSERT_TRUE(response->headers);
[email protected]76a505b2010-08-25 06:23:006676 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
6677
[email protected]90499482013-06-01 00:39:506678 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]76a505b2010-08-25 06:23:006679
6680 std::string response_data;
bnc691fda62016-08-12 00:43:166681 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:016682 EXPECT_THAT(rv, IsOk());
[email protected]76a505b2010-08-25 06:23:006683 EXPECT_EQ("hello world", response_data);
6684
6685 // Empty the current queue. This is necessary because idle sockets are
6686 // added to the connection pool asynchronously with a PostTask.
fdoray92e35a72016-06-10 15:54:556687 base::RunLoop().RunUntilIdle();
[email protected]76a505b2010-08-25 06:23:006688
6689 // We now check to make sure the socket was added back to the pool.
[email protected]90499482013-06-01 00:39:506690 EXPECT_EQ(1, GetIdleSocketCountInSSLSocketPool(session.get()));
[email protected]76a505b2010-08-25 06:23:006691}
6692
6693// Grab a SSL socket, use it, and put it back into the pool. Then, reuse it
6694// from the pool and make sure that we recover okay.
bncd16676a2016-07-20 16:23:016695TEST_F(HttpNetworkTransactionTest, RecycleDeadSSLSocket) {
[email protected]76a505b2010-08-25 06:23:006696 HttpRequestInfo request;
6697 request.method = "GET";
bncce36dca22015-04-21 22:11:236698 request.url = GURL("https://www.example.org/");
[email protected]76a505b2010-08-25 06:23:006699
6700 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:236701 MockWrite(
6702 "GET / HTTP/1.1\r\n"
6703 "Host: www.example.org\r\n"
6704 "Connection: keep-alive\r\n\r\n"),
6705 MockWrite(
6706 "GET / HTTP/1.1\r\n"
6707 "Host: www.example.org\r\n"
6708 "Connection: keep-alive\r\n\r\n"),
[email protected]76a505b2010-08-25 06:23:006709 };
6710
6711 MockRead data_reads[] = {
mmenke911ee0222015-12-04 03:58:426712 MockRead("HTTP/1.1 200 OK\r\n"), MockRead("Content-Length: 11\r\n\r\n"),
6713 MockRead("hello world"), MockRead(ASYNC, ERR_CONNECTION_CLOSED)};
[email protected]76a505b2010-08-25 06:23:006714
[email protected]8ddf8322012-02-23 18:08:066715 SSLSocketDataProvider ssl(ASYNC, OK);
6716 SSLSocketDataProvider ssl2(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:076717 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
6718 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
[email protected]76a505b2010-08-25 06:23:006719
6720 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
6721 data_writes, arraysize(data_writes));
6722 StaticSocketDataProvider data2(data_reads, arraysize(data_reads),
6723 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:076724 session_deps_.socket_factory->AddSocketDataProvider(&data);
6725 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]76a505b2010-08-25 06:23:006726
[email protected]49639fa2011-12-20 23:22:416727 TestCompletionCallback callback;
[email protected]76a505b2010-08-25 06:23:006728
danakj1fd259a02016-04-16 03:17:096729 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc87dcefc2017-05-25 12:47:586730 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:196731 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]76a505b2010-08-25 06:23:006732
tfarina42834112016-09-22 13:38:206733 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
[email protected]76a505b2010-08-25 06:23:006734
robpercival214763f2016-07-01 23:27:016735 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
6736 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]76a505b2010-08-25 06:23:006737
6738 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:526739 ASSERT_TRUE(response);
6740 ASSERT_TRUE(response->headers);
[email protected]76a505b2010-08-25 06:23:006741 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
6742
[email protected]90499482013-06-01 00:39:506743 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]76a505b2010-08-25 06:23:006744
6745 std::string response_data;
6746 rv = ReadTransaction(trans.get(), &response_data);
robpercival214763f2016-07-01 23:27:016747 EXPECT_THAT(rv, IsOk());
[email protected]76a505b2010-08-25 06:23:006748 EXPECT_EQ("hello world", response_data);
6749
6750 // Empty the current queue. This is necessary because idle sockets are
6751 // added to the connection pool asynchronously with a PostTask.
fdoray92e35a72016-06-10 15:54:556752 base::RunLoop().RunUntilIdle();
[email protected]76a505b2010-08-25 06:23:006753
6754 // We now check to make sure the socket was added back to the pool.
[email protected]90499482013-06-01 00:39:506755 EXPECT_EQ(1, GetIdleSocketCountInSSLSocketPool(session.get()));
[email protected]76a505b2010-08-25 06:23:006756
6757 // Now start the second transaction, which should reuse the previous socket.
6758
bnc87dcefc2017-05-25 12:47:586759 trans =
Jeremy Roman0579ed62017-08-29 15:56:196760 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]76a505b2010-08-25 06:23:006761
tfarina42834112016-09-22 13:38:206762 rv = trans->Start(&request, callback.callback(), NetLogWithSource());
[email protected]76a505b2010-08-25 06:23:006763
robpercival214763f2016-07-01 23:27:016764 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
6765 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]76a505b2010-08-25 06:23:006766
6767 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:526768 ASSERT_TRUE(response);
6769 ASSERT_TRUE(response->headers);
[email protected]76a505b2010-08-25 06:23:006770 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
6771
[email protected]90499482013-06-01 00:39:506772 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]76a505b2010-08-25 06:23:006773
6774 rv = ReadTransaction(trans.get(), &response_data);
robpercival214763f2016-07-01 23:27:016775 EXPECT_THAT(rv, IsOk());
[email protected]76a505b2010-08-25 06:23:006776 EXPECT_EQ("hello world", response_data);
6777
6778 // Empty the current queue. This is necessary because idle sockets are
6779 // added to the connection pool asynchronously with a PostTask.
fdoray92e35a72016-06-10 15:54:556780 base::RunLoop().RunUntilIdle();
[email protected]76a505b2010-08-25 06:23:006781
6782 // We now check to make sure the socket was added back to the pool.
[email protected]90499482013-06-01 00:39:506783 EXPECT_EQ(1, GetIdleSocketCountInSSLSocketPool(session.get()));
[email protected]76a505b2010-08-25 06:23:006784}
6785
maksim.sisov0adf8592016-07-15 06:25:566786// Grab a socket, use it, and put it back into the pool. Then, make
6787// low memory notification and ensure the socket pool is flushed.
bncd16676a2016-07-20 16:23:016788TEST_F(HttpNetworkTransactionTest, FlushSocketPoolOnLowMemoryNotifications) {
maksim.sisov0adf8592016-07-15 06:25:566789 HttpRequestInfo request;
6790 request.method = "GET";
6791 request.url = GURL("http://www.example.org/");
6792 request.load_flags = 0;
6793
6794 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
6795
bnc691fda62016-08-12 00:43:166796 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
maksim.sisov0adf8592016-07-15 06:25:566797
6798 MockRead data_reads[] = {
6799 // A part of the response body is received with the response headers.
6800 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 11\r\n\r\nhel"),
6801 // The rest of the response body is received in two parts.
6802 MockRead("lo"), MockRead(" world"),
6803 MockRead("junk"), // Should not be read!!
6804 MockRead(SYNCHRONOUS, OK),
6805 };
6806
6807 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
6808 session_deps_.socket_factory->AddSocketDataProvider(&data);
6809
6810 TestCompletionCallback callback;
6811
tfarina42834112016-09-22 13:38:206812 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
maksim.sisov0adf8592016-07-15 06:25:566813 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
6814
6815 EXPECT_THAT(callback.GetResult(rv), IsOk());
6816
bnc691fda62016-08-12 00:43:166817 const HttpResponseInfo* response = trans.GetResponseInfo();
maksim.sisov0adf8592016-07-15 06:25:566818 ASSERT_TRUE(response);
6819 EXPECT_TRUE(response->headers);
6820 std::string status_line = response->headers->GetStatusLine();
6821 EXPECT_EQ("HTTP/1.1 200 OK", status_line);
6822
6823 // Make memory critical notification and ensure the transaction still has been
6824 // operating right.
6825 base::MemoryPressureListener::NotifyMemoryPressure(
6826 base::MemoryPressureListener::MEMORY_PRESSURE_LEVEL_CRITICAL);
6827 base::RunLoop().RunUntilIdle();
6828
6829 // Socket should not be flushed as long as it is not idle.
6830 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
6831
6832 std::string response_data;
bnc691fda62016-08-12 00:43:166833 rv = ReadTransaction(&trans, &response_data);
maksim.sisov0adf8592016-07-15 06:25:566834 EXPECT_THAT(rv, IsOk());
6835 EXPECT_EQ("hello world", response_data);
6836
6837 // Empty the current queue. This is necessary because idle sockets are
6838 // added to the connection pool asynchronously with a PostTask.
6839 base::RunLoop().RunUntilIdle();
6840
6841 // We now check to make sure the socket was added back to the pool.
6842 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
6843
6844 // Idle sockets should be flushed now.
6845 base::MemoryPressureListener::NotifyMemoryPressure(
6846 base::MemoryPressureListener::MEMORY_PRESSURE_LEVEL_CRITICAL);
6847 base::RunLoop().RunUntilIdle();
6848
6849 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
6850}
6851
6852// Grab an SSL socket, use it, and put it back into the pool. Then, make
6853// low memory notification and ensure the socket pool is flushed.
bncd16676a2016-07-20 16:23:016854TEST_F(HttpNetworkTransactionTest, FlushSSLSocketPoolOnLowMemoryNotifications) {
maksim.sisov0adf8592016-07-15 06:25:566855 HttpRequestInfo request;
6856 request.method = "GET";
6857 request.url = GURL("https://www.example.org/");
6858 request.load_flags = 0;
6859
6860 MockWrite data_writes[] = {
6861 MockWrite("GET / HTTP/1.1\r\n"
6862 "Host: www.example.org\r\n"
6863 "Connection: keep-alive\r\n\r\n"),
6864 };
6865
6866 MockRead data_reads[] = {
6867 MockRead("HTTP/1.1 200 OK\r\n"), MockRead("Content-Length: 11\r\n\r\n"),
6868 MockRead("hello world"), MockRead(ASYNC, ERR_CONNECTION_CLOSED)};
6869
6870 SSLSocketDataProvider ssl(ASYNC, OK);
6871 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
6872
6873 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
6874 arraysize(data_writes));
6875 session_deps_.socket_factory->AddSocketDataProvider(&data);
6876
6877 TestCompletionCallback callback;
6878
6879 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:166880 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
maksim.sisov0adf8592016-07-15 06:25:566881
6882 EXPECT_EQ(0, GetIdleSocketCountInSSLSocketPool(session.get()));
tfarina42834112016-09-22 13:38:206883 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
maksim.sisov0adf8592016-07-15 06:25:566884
6885 EXPECT_THAT(callback.GetResult(rv), IsOk());
6886
bnc691fda62016-08-12 00:43:166887 const HttpResponseInfo* response = trans.GetResponseInfo();
maksim.sisov0adf8592016-07-15 06:25:566888 ASSERT_TRUE(response);
6889 ASSERT_TRUE(response->headers);
6890 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
6891
6892 // Make memory critical notification and ensure the transaction still has been
6893 // operating right.
6894 base::MemoryPressureListener::NotifyMemoryPressure(
6895 base::MemoryPressureListener::MEMORY_PRESSURE_LEVEL_CRITICAL);
6896 base::RunLoop().RunUntilIdle();
6897
6898 EXPECT_EQ(0, GetIdleSocketCountInSSLSocketPool(session.get()));
6899
6900 std::string response_data;
bnc691fda62016-08-12 00:43:166901 rv = ReadTransaction(&trans, &response_data);
maksim.sisov0adf8592016-07-15 06:25:566902 EXPECT_THAT(rv, IsOk());
6903 EXPECT_EQ("hello world", response_data);
6904
6905 // Empty the current queue. This is necessary because idle sockets are
6906 // added to the connection pool asynchronously with a PostTask.
6907 base::RunLoop().RunUntilIdle();
6908
6909 // We now check to make sure the socket was added back to the pool.
6910 EXPECT_EQ(1, GetIdleSocketCountInSSLSocketPool(session.get()));
6911
6912 // Make memory notification once again and ensure idle socket is closed.
6913 base::MemoryPressureListener::NotifyMemoryPressure(
6914 base::MemoryPressureListener::MEMORY_PRESSURE_LEVEL_CRITICAL);
6915 base::RunLoop().RunUntilIdle();
6916
6917 EXPECT_EQ(0, GetIdleSocketCountInSSLSocketPool(session.get()));
6918}
6919
[email protected]b4404c02009-04-10 16:38:526920// Make sure that we recycle a socket after a zero-length response.
6921// http://crbug.com/9880
bncd16676a2016-07-20 16:23:016922TEST_F(HttpNetworkTransactionTest, RecycleSocketAfterZeroContentLength) {
[email protected]1c773ea12009-04-28 19:58:426923 HttpRequestInfo request;
[email protected]b4404c02009-04-10 16:38:526924 request.method = "GET";
bncce36dca22015-04-21 22:11:236925 request.url = GURL(
6926 "http://www.example.org/csi?v=3&s=web&action=&"
6927 "tran=undefined&ei=mAXcSeegAo-SMurloeUN&"
6928 "e=17259,18167,19592,19773,19981,20133,20173,20233&"
6929 "rt=prt.2642,ol.2649,xjs.2951");
[email protected]b4404c02009-04-10 16:38:526930
danakj1fd259a02016-04-16 03:17:096931 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:276932
[email protected]b4404c02009-04-10 16:38:526933 MockRead data_reads[] = {
6934 MockRead("HTTP/1.1 204 No Content\r\n"
6935 "Content-Length: 0\r\n"
6936 "Content-Type: text/html\r\n\r\n"),
6937 MockRead("junk"), // Should not be read!!
[email protected]8ddf8322012-02-23 18:08:066938 MockRead(SYNCHRONOUS, OK),
[email protected]b4404c02009-04-10 16:38:526939 };
6940
[email protected]31a2bfe2010-02-09 08:03:396941 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:076942 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]b4404c02009-04-10 16:38:526943
mmenkecc2298e2015-12-07 18:20:186944 // Transaction must be created after the MockReads, so it's destroyed before
6945 // them.
bnc691fda62016-08-12 00:43:166946 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
mmenkecc2298e2015-12-07 18:20:186947
[email protected]49639fa2011-12-20 23:22:416948 TestCompletionCallback callback;
[email protected]b4404c02009-04-10 16:38:526949
tfarina42834112016-09-22 13:38:206950 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:016951 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]b4404c02009-04-10 16:38:526952
6953 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:016954 EXPECT_THAT(rv, IsOk());
[email protected]b4404c02009-04-10 16:38:526955
bnc691fda62016-08-12 00:43:166956 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:526957 ASSERT_TRUE(response);
[email protected]b4404c02009-04-10 16:38:526958
wezca1070932016-05-26 20:30:526959 EXPECT_TRUE(response->headers);
[email protected]b4404c02009-04-10 16:38:526960 std::string status_line = response->headers->GetStatusLine();
6961 EXPECT_EQ("HTTP/1.1 204 No Content", status_line);
6962
[email protected]90499482013-06-01 00:39:506963 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]b4404c02009-04-10 16:38:526964
6965 std::string response_data;
bnc691fda62016-08-12 00:43:166966 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:016967 EXPECT_THAT(rv, IsOk());
[email protected]b4404c02009-04-10 16:38:526968 EXPECT_EQ("", response_data);
6969
6970 // Empty the current queue. This is necessary because idle sockets are
6971 // added to the connection pool asynchronously with a PostTask.
fdoray92e35a72016-06-10 15:54:556972 base::RunLoop().RunUntilIdle();
[email protected]b4404c02009-04-10 16:38:526973
6974 // We now check to make sure the socket was added back to the pool.
[email protected]90499482013-06-01 00:39:506975 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]b4404c02009-04-10 16:38:526976}
6977
bncd16676a2016-07-20 16:23:016978TEST_F(HttpNetworkTransactionTest, ResendRequestOnWriteBodyError) {
danakj1fd259a02016-04-16 03:17:096979 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:226980 element_readers.push_back(
Jeremy Roman0579ed62017-08-29 15:56:196981 std::make_unique<UploadBytesElementReader>("foo", 3));
olli.raula6df48b2a2015-11-26 07:40:226982 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]329b68b2012-11-14 17:54:276983
[email protected]1c773ea12009-04-28 19:58:426984 HttpRequestInfo request[2];
[email protected]372d34a2008-11-05 21:30:516985 // Transaction 1: a GET request that succeeds. The socket is recycled
6986 // after use.
6987 request[0].method = "GET";
6988 request[0].url = GURL("http://www.google.com/");
6989 request[0].load_flags = 0;
6990 // Transaction 2: a POST request. Reuses the socket kept alive from
6991 // transaction 1. The first attempts fails when writing the POST data.
6992 // This causes the transaction to retry with a new socket. The second
6993 // attempt succeeds.
6994 request[1].method = "POST";
6995 request[1].url = GURL("http://www.google.com/login.cgi");
[email protected]329b68b2012-11-14 17:54:276996 request[1].upload_data_stream = &upload_data_stream;
[email protected]372d34a2008-11-05 21:30:516997 request[1].load_flags = 0;
6998
danakj1fd259a02016-04-16 03:17:096999 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]372d34a2008-11-05 21:30:517000
7001 // The first socket is used for transaction 1 and the first attempt of
7002 // transaction 2.
7003
7004 // The response of transaction 1.
7005 MockRead data_reads1[] = {
7006 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 11\r\n\r\n"),
7007 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:067008 MockRead(SYNCHRONOUS, OK),
[email protected]372d34a2008-11-05 21:30:517009 };
7010 // The mock write results of transaction 1 and the first attempt of
7011 // transaction 2.
7012 MockWrite data_writes1[] = {
[email protected]8ddf8322012-02-23 18:08:067013 MockWrite(SYNCHRONOUS, 64), // GET
7014 MockWrite(SYNCHRONOUS, 93), // POST
7015 MockWrite(SYNCHRONOUS, ERR_CONNECTION_ABORTED), // POST data
[email protected]372d34a2008-11-05 21:30:517016 };
[email protected]31a2bfe2010-02-09 08:03:397017 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
7018 data_writes1, arraysize(data_writes1));
[email protected]372d34a2008-11-05 21:30:517019
7020 // The second socket is used for the second attempt of transaction 2.
7021
7022 // The response of transaction 2.
7023 MockRead data_reads2[] = {
7024 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 7\r\n\r\n"),
7025 MockRead("welcome"),
[email protected]8ddf8322012-02-23 18:08:067026 MockRead(SYNCHRONOUS, OK),
[email protected]372d34a2008-11-05 21:30:517027 };
7028 // The mock write results of the second attempt of transaction 2.
7029 MockWrite data_writes2[] = {
[email protected]8ddf8322012-02-23 18:08:067030 MockWrite(SYNCHRONOUS, 93), // POST
7031 MockWrite(SYNCHRONOUS, 3), // POST data
[email protected]372d34a2008-11-05 21:30:517032 };
[email protected]31a2bfe2010-02-09 08:03:397033 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
7034 data_writes2, arraysize(data_writes2));
[email protected]372d34a2008-11-05 21:30:517035
[email protected]bb88e1d32013-05-03 23:11:077036 session_deps_.socket_factory->AddSocketDataProvider(&data1);
7037 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]372d34a2008-11-05 21:30:517038
thestig9d3bb0c2015-01-24 00:49:517039 const char* const kExpectedResponseData[] = {
[email protected]372d34a2008-11-05 21:30:517040 "hello world", "welcome"
7041 };
7042
7043 for (int i = 0; i < 2; ++i) {
bnc691fda62016-08-12 00:43:167044 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]372d34a2008-11-05 21:30:517045
[email protected]49639fa2011-12-20 23:22:417046 TestCompletionCallback callback;
[email protected]372d34a2008-11-05 21:30:517047
tfarina42834112016-09-22 13:38:207048 int rv = trans.Start(&request[i], callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:017049 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]372d34a2008-11-05 21:30:517050
7051 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:017052 EXPECT_THAT(rv, IsOk());
[email protected]372d34a2008-11-05 21:30:517053
bnc691fda62016-08-12 00:43:167054 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:527055 ASSERT_TRUE(response);
[email protected]372d34a2008-11-05 21:30:517056
wezca1070932016-05-26 20:30:527057 EXPECT_TRUE(response->headers);
[email protected]372d34a2008-11-05 21:30:517058 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
7059
7060 std::string response_data;
bnc691fda62016-08-12 00:43:167061 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:017062 EXPECT_THAT(rv, IsOk());
[email protected]372d34a2008-11-05 21:30:517063 EXPECT_EQ(kExpectedResponseData[i], response_data);
7064 }
7065}
[email protected]f9ee6b52008-11-08 06:46:237066
7067// Test the request-challenge-retry sequence for basic auth when there is
7068// an identity in the URL. The request should be sent as normal, but when
[email protected]2262e3a2012-05-22 16:08:167069// it fails the identity from the URL is used to answer the challenge.
bncd16676a2016-07-20 16:23:017070TEST_F(HttpNetworkTransactionTest, AuthIdentityInURL) {
[email protected]1c773ea12009-04-28 19:58:427071 HttpRequestInfo request;
[email protected]f9ee6b52008-11-08 06:46:237072 request.method = "GET";
bncce36dca22015-04-21 22:11:237073 request.url = GURL("http://foo:b@[email protected]/");
[email protected]7b08ba62012-02-10 20:19:417074 request.load_flags = LOAD_NORMAL;
[email protected]a97cca42009-08-14 01:00:297075
danakj1fd259a02016-04-16 03:17:097076 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:167077 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:277078
[email protected]a97cca42009-08-14 01:00:297079 // The password contains an escaped character -- for this test to pass it
7080 // will need to be unescaped by HttpNetworkTransaction.
7081 EXPECT_EQ("b%40r", request.url.password());
7082
[email protected]f9ee6b52008-11-08 06:46:237083 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:237084 MockWrite(
7085 "GET / HTTP/1.1\r\n"
7086 "Host: www.example.org\r\n"
7087 "Connection: keep-alive\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:237088 };
7089
7090 MockRead data_reads1[] = {
7091 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
7092 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
7093 MockRead("Content-Length: 10\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067094 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]f9ee6b52008-11-08 06:46:237095 };
7096
[email protected]2262e3a2012-05-22 16:08:167097 // After the challenge above, the transaction will be restarted using the
7098 // identity from the url (foo, b@r) to answer the challenge.
7099 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:237100 MockWrite(
7101 "GET / HTTP/1.1\r\n"
7102 "Host: www.example.org\r\n"
7103 "Connection: keep-alive\r\n"
7104 "Authorization: Basic Zm9vOmJAcg==\r\n\r\n"),
[email protected]2262e3a2012-05-22 16:08:167105 };
7106
7107 MockRead data_reads2[] = {
7108 MockRead("HTTP/1.0 200 OK\r\n"),
7109 MockRead("Content-Length: 100\r\n\r\n"),
7110 MockRead(SYNCHRONOUS, OK),
7111 };
7112
[email protected]31a2bfe2010-02-09 08:03:397113 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
7114 data_writes1, arraysize(data_writes1));
[email protected]2262e3a2012-05-22 16:08:167115 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
7116 data_writes2, arraysize(data_writes2));
[email protected]bb88e1d32013-05-03 23:11:077117 session_deps_.socket_factory->AddSocketDataProvider(&data1);
7118 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]f9ee6b52008-11-08 06:46:237119
[email protected]49639fa2011-12-20 23:22:417120 TestCompletionCallback callback1;
tfarina42834112016-09-22 13:38:207121 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:017122 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]f9ee6b52008-11-08 06:46:237123 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:017124 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:167125 EXPECT_TRUE(trans.IsReadyToRestartForAuth());
[email protected]2262e3a2012-05-22 16:08:167126
7127 TestCompletionCallback callback2;
bnc691fda62016-08-12 00:43:167128 rv = trans.RestartWithAuth(AuthCredentials(), callback2.callback());
robpercival214763f2016-07-01 23:27:017129 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2262e3a2012-05-22 16:08:167130 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:017131 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:167132 EXPECT_FALSE(trans.IsReadyToRestartForAuth());
[email protected]0757e7702009-03-27 04:00:227133
bnc691fda62016-08-12 00:43:167134 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:527135 ASSERT_TRUE(response);
[email protected]2262e3a2012-05-22 16:08:167136
7137 // There is no challenge info, since the identity in URL worked.
wezca1070932016-05-26 20:30:527138 EXPECT_FALSE(response->auth_challenge);
[email protected]2262e3a2012-05-22 16:08:167139
7140 EXPECT_EQ(100, response->headers->GetContentLength());
7141
7142 // Empty the current queue.
fdoray92e35a72016-06-10 15:54:557143 base::RunLoop().RunUntilIdle();
[email protected]2262e3a2012-05-22 16:08:167144}
7145
7146// Test the request-challenge-retry sequence for basic auth when there is an
7147// incorrect identity in the URL. The identity from the URL should be used only
7148// once.
bncd16676a2016-07-20 16:23:017149TEST_F(HttpNetworkTransactionTest, WrongAuthIdentityInURL) {
[email protected]2262e3a2012-05-22 16:08:167150 HttpRequestInfo request;
7151 request.method = "GET";
7152 // Note: the URL has a username:password in it. The password "baz" is
7153 // wrong (should be "bar").
bncce36dca22015-04-21 22:11:237154 request.url = GURL("http://foo:[email protected]/");
[email protected]2262e3a2012-05-22 16:08:167155
7156 request.load_flags = LOAD_NORMAL;
7157
danakj1fd259a02016-04-16 03:17:097158 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:167159 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]2262e3a2012-05-22 16:08:167160
7161 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:237162 MockWrite(
7163 "GET / HTTP/1.1\r\n"
7164 "Host: www.example.org\r\n"
7165 "Connection: keep-alive\r\n\r\n"),
[email protected]2262e3a2012-05-22 16:08:167166 };
7167
7168 MockRead data_reads1[] = {
7169 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
7170 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
7171 MockRead("Content-Length: 10\r\n\r\n"),
7172 MockRead(SYNCHRONOUS, ERR_FAILED),
7173 };
7174
7175 // After the challenge above, the transaction will be restarted using the
7176 // identity from the url (foo, baz) to answer the challenge.
7177 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:237178 MockWrite(
7179 "GET / HTTP/1.1\r\n"
7180 "Host: www.example.org\r\n"
7181 "Connection: keep-alive\r\n"
7182 "Authorization: Basic Zm9vOmJheg==\r\n\r\n"),
[email protected]2262e3a2012-05-22 16:08:167183 };
7184
7185 MockRead data_reads2[] = {
7186 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
7187 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
7188 MockRead("Content-Length: 10\r\n\r\n"),
7189 MockRead(SYNCHRONOUS, ERR_FAILED),
7190 };
7191
7192 // After the challenge above, the transaction will be restarted using the
7193 // identity supplied by the user (foo, bar) to answer the challenge.
7194 MockWrite data_writes3[] = {
bncce36dca22015-04-21 22:11:237195 MockWrite(
7196 "GET / HTTP/1.1\r\n"
7197 "Host: www.example.org\r\n"
7198 "Connection: keep-alive\r\n"
7199 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]2262e3a2012-05-22 16:08:167200 };
7201
7202 MockRead data_reads3[] = {
7203 MockRead("HTTP/1.0 200 OK\r\n"),
7204 MockRead("Content-Length: 100\r\n\r\n"),
7205 MockRead(SYNCHRONOUS, OK),
7206 };
7207
7208 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
7209 data_writes1, arraysize(data_writes1));
7210 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
7211 data_writes2, arraysize(data_writes2));
7212 StaticSocketDataProvider data3(data_reads3, arraysize(data_reads3),
7213 data_writes3, arraysize(data_writes3));
[email protected]bb88e1d32013-05-03 23:11:077214 session_deps_.socket_factory->AddSocketDataProvider(&data1);
7215 session_deps_.socket_factory->AddSocketDataProvider(&data2);
7216 session_deps_.socket_factory->AddSocketDataProvider(&data3);
[email protected]2262e3a2012-05-22 16:08:167217
7218 TestCompletionCallback callback1;
7219
tfarina42834112016-09-22 13:38:207220 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:017221 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2262e3a2012-05-22 16:08:167222
7223 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:017224 EXPECT_THAT(rv, IsOk());
[email protected]2262e3a2012-05-22 16:08:167225
bnc691fda62016-08-12 00:43:167226 EXPECT_TRUE(trans.IsReadyToRestartForAuth());
[email protected]2262e3a2012-05-22 16:08:167227 TestCompletionCallback callback2;
bnc691fda62016-08-12 00:43:167228 rv = trans.RestartWithAuth(AuthCredentials(), callback2.callback());
robpercival214763f2016-07-01 23:27:017229 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2262e3a2012-05-22 16:08:167230 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:017231 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:167232 EXPECT_FALSE(trans.IsReadyToRestartForAuth());
[email protected]2262e3a2012-05-22 16:08:167233
bnc691fda62016-08-12 00:43:167234 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:527235 ASSERT_TRUE(response);
[email protected]2262e3a2012-05-22 16:08:167236 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
7237
7238 TestCompletionCallback callback3;
bnc691fda62016-08-12 00:43:167239 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar), callback3.callback());
robpercival214763f2016-07-01 23:27:017240 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2262e3a2012-05-22 16:08:167241 rv = callback3.WaitForResult();
robpercival214763f2016-07-01 23:27:017242 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:167243 EXPECT_FALSE(trans.IsReadyToRestartForAuth());
[email protected]2262e3a2012-05-22 16:08:167244
bnc691fda62016-08-12 00:43:167245 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:527246 ASSERT_TRUE(response);
[email protected]2262e3a2012-05-22 16:08:167247
7248 // There is no challenge info, since the identity worked.
wezca1070932016-05-26 20:30:527249 EXPECT_FALSE(response->auth_challenge);
[email protected]2262e3a2012-05-22 16:08:167250
7251 EXPECT_EQ(100, response->headers->GetContentLength());
7252
[email protected]ea9dc9a2009-09-05 00:43:327253 // Empty the current queue.
fdoray92e35a72016-06-10 15:54:557254 base::RunLoop().RunUntilIdle();
[email protected]ea9dc9a2009-09-05 00:43:327255}
7256
[email protected]2217aa22013-10-11 03:03:547257
7258// Test the request-challenge-retry sequence for basic auth when there is a
7259// correct identity in the URL, but its use is being suppressed. The identity
7260// from the URL should never be used.
bncd16676a2016-07-20 16:23:017261TEST_F(HttpNetworkTransactionTest, AuthIdentityInURLSuppressed) {
[email protected]2217aa22013-10-11 03:03:547262 HttpRequestInfo request;
7263 request.method = "GET";
bncce36dca22015-04-21 22:11:237264 request.url = GURL("http://foo:[email protected]/");
[email protected]2217aa22013-10-11 03:03:547265 request.load_flags = LOAD_DO_NOT_USE_EMBEDDED_IDENTITY;
7266
danakj1fd259a02016-04-16 03:17:097267 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:167268 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]2217aa22013-10-11 03:03:547269
7270 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:237271 MockWrite(
7272 "GET / HTTP/1.1\r\n"
7273 "Host: www.example.org\r\n"
7274 "Connection: keep-alive\r\n\r\n"),
[email protected]2217aa22013-10-11 03:03:547275 };
7276
7277 MockRead data_reads1[] = {
7278 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
7279 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
7280 MockRead("Content-Length: 10\r\n\r\n"),
7281 MockRead(SYNCHRONOUS, ERR_FAILED),
7282 };
7283
7284 // After the challenge above, the transaction will be restarted using the
7285 // identity supplied by the user, not the one in the URL, to answer the
7286 // challenge.
7287 MockWrite data_writes3[] = {
bncce36dca22015-04-21 22:11:237288 MockWrite(
7289 "GET / HTTP/1.1\r\n"
7290 "Host: www.example.org\r\n"
7291 "Connection: keep-alive\r\n"
7292 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]2217aa22013-10-11 03:03:547293 };
7294
7295 MockRead data_reads3[] = {
7296 MockRead("HTTP/1.0 200 OK\r\n"),
7297 MockRead("Content-Length: 100\r\n\r\n"),
7298 MockRead(SYNCHRONOUS, OK),
7299 };
7300
7301 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
7302 data_writes1, arraysize(data_writes1));
7303 StaticSocketDataProvider data3(data_reads3, arraysize(data_reads3),
7304 data_writes3, arraysize(data_writes3));
7305 session_deps_.socket_factory->AddSocketDataProvider(&data1);
7306 session_deps_.socket_factory->AddSocketDataProvider(&data3);
7307
7308 TestCompletionCallback callback1;
tfarina42834112016-09-22 13:38:207309 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:017310 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2217aa22013-10-11 03:03:547311 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:017312 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:167313 EXPECT_FALSE(trans.IsReadyToRestartForAuth());
[email protected]2217aa22013-10-11 03:03:547314
bnc691fda62016-08-12 00:43:167315 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:527316 ASSERT_TRUE(response);
[email protected]2217aa22013-10-11 03:03:547317 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
7318
7319 TestCompletionCallback callback3;
bnc691fda62016-08-12 00:43:167320 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar), callback3.callback());
robpercival214763f2016-07-01 23:27:017321 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2217aa22013-10-11 03:03:547322 rv = callback3.WaitForResult();
robpercival214763f2016-07-01 23:27:017323 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:167324 EXPECT_FALSE(trans.IsReadyToRestartForAuth());
[email protected]2217aa22013-10-11 03:03:547325
bnc691fda62016-08-12 00:43:167326 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:527327 ASSERT_TRUE(response);
[email protected]2217aa22013-10-11 03:03:547328
7329 // There is no challenge info, since the identity worked.
wezca1070932016-05-26 20:30:527330 EXPECT_FALSE(response->auth_challenge);
[email protected]2217aa22013-10-11 03:03:547331 EXPECT_EQ(100, response->headers->GetContentLength());
7332
7333 // Empty the current queue.
fdoray92e35a72016-06-10 15:54:557334 base::RunLoop().RunUntilIdle();
[email protected]2217aa22013-10-11 03:03:547335}
7336
[email protected]f9ee6b52008-11-08 06:46:237337// Test that previously tried username/passwords for a realm get re-used.
bncd16676a2016-07-20 16:23:017338TEST_F(HttpNetworkTransactionTest, BasicAuthCacheAndPreauth) {
danakj1fd259a02016-04-16 03:17:097339 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]f9ee6b52008-11-08 06:46:237340
7341 // Transaction 1: authenticate (foo, bar) on MyRealm1
7342 {
[email protected]1c773ea12009-04-28 19:58:427343 HttpRequestInfo request;
[email protected]f9ee6b52008-11-08 06:46:237344 request.method = "GET";
bncce36dca22015-04-21 22:11:237345 request.url = GURL("http://www.example.org/x/y/z");
[email protected]f9ee6b52008-11-08 06:46:237346
bnc691fda62016-08-12 00:43:167347 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:277348
[email protected]f9ee6b52008-11-08 06:46:237349 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:237350 MockWrite(
7351 "GET /x/y/z HTTP/1.1\r\n"
7352 "Host: www.example.org\r\n"
7353 "Connection: keep-alive\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:237354 };
7355
7356 MockRead data_reads1[] = {
7357 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
7358 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
7359 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067360 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]f9ee6b52008-11-08 06:46:237361 };
7362
7363 // Resend with authorization (username=foo, password=bar)
7364 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:237365 MockWrite(
7366 "GET /x/y/z HTTP/1.1\r\n"
7367 "Host: www.example.org\r\n"
7368 "Connection: keep-alive\r\n"
7369 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:237370 };
7371
7372 // Sever accepts the authorization.
7373 MockRead data_reads2[] = {
7374 MockRead("HTTP/1.0 200 OK\r\n"),
7375 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067376 MockRead(SYNCHRONOUS, OK),
[email protected]f9ee6b52008-11-08 06:46:237377 };
7378
[email protected]31a2bfe2010-02-09 08:03:397379 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
7380 data_writes1, arraysize(data_writes1));
7381 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
7382 data_writes2, arraysize(data_writes2));
[email protected]bb88e1d32013-05-03 23:11:077383 session_deps_.socket_factory->AddSocketDataProvider(&data1);
7384 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]f9ee6b52008-11-08 06:46:237385
[email protected]49639fa2011-12-20 23:22:417386 TestCompletionCallback callback1;
[email protected]f9ee6b52008-11-08 06:46:237387
tfarina42834112016-09-22 13:38:207388 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:017389 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]f9ee6b52008-11-08 06:46:237390
7391 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:017392 EXPECT_THAT(rv, IsOk());
[email protected]f9ee6b52008-11-08 06:46:237393
bnc691fda62016-08-12 00:43:167394 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:527395 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:047396 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]f9ee6b52008-11-08 06:46:237397
[email protected]49639fa2011-12-20 23:22:417398 TestCompletionCallback callback2;
[email protected]f9ee6b52008-11-08 06:46:237399
bnc691fda62016-08-12 00:43:167400 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar),
7401 callback2.callback());
robpercival214763f2016-07-01 23:27:017402 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]f9ee6b52008-11-08 06:46:237403
7404 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:017405 EXPECT_THAT(rv, IsOk());
[email protected]f9ee6b52008-11-08 06:46:237406
bnc691fda62016-08-12 00:43:167407 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:527408 ASSERT_TRUE(response);
7409 EXPECT_FALSE(response->auth_challenge);
[email protected]f9ee6b52008-11-08 06:46:237410 EXPECT_EQ(100, response->headers->GetContentLength());
7411 }
7412
7413 // ------------------------------------------------------------------------
7414
7415 // Transaction 2: authenticate (foo2, bar2) on MyRealm2
7416 {
[email protected]1c773ea12009-04-28 19:58:427417 HttpRequestInfo request;
[email protected]f9ee6b52008-11-08 06:46:237418 request.method = "GET";
7419 // Note that Transaction 1 was at /x/y/z, so this is in the same
7420 // protection space as MyRealm1.
bncce36dca22015-04-21 22:11:237421 request.url = GURL("http://www.example.org/x/y/a/b");
[email protected]f9ee6b52008-11-08 06:46:237422
bnc691fda62016-08-12 00:43:167423 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:277424
[email protected]f9ee6b52008-11-08 06:46:237425 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:237426 MockWrite(
7427 "GET /x/y/a/b HTTP/1.1\r\n"
7428 "Host: www.example.org\r\n"
7429 "Connection: keep-alive\r\n"
7430 // Send preemptive authorization for MyRealm1
7431 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:237432 };
7433
7434 // The server didn't like the preemptive authorization, and
7435 // challenges us for a different realm (MyRealm2).
7436 MockRead data_reads1[] = {
7437 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
7438 MockRead("WWW-Authenticate: Basic realm=\"MyRealm2\"\r\n"),
7439 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067440 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]f9ee6b52008-11-08 06:46:237441 };
7442
7443 // Resend with authorization for MyRealm2 (username=foo2, password=bar2)
7444 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:237445 MockWrite(
7446 "GET /x/y/a/b HTTP/1.1\r\n"
7447 "Host: www.example.org\r\n"
7448 "Connection: keep-alive\r\n"
7449 "Authorization: Basic Zm9vMjpiYXIy\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:237450 };
7451
7452 // Sever accepts the authorization.
7453 MockRead data_reads2[] = {
7454 MockRead("HTTP/1.0 200 OK\r\n"),
7455 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067456 MockRead(SYNCHRONOUS, OK),
[email protected]f9ee6b52008-11-08 06:46:237457 };
7458
[email protected]31a2bfe2010-02-09 08:03:397459 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
7460 data_writes1, arraysize(data_writes1));
7461 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
7462 data_writes2, arraysize(data_writes2));
[email protected]bb88e1d32013-05-03 23:11:077463 session_deps_.socket_factory->AddSocketDataProvider(&data1);
7464 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]f9ee6b52008-11-08 06:46:237465
[email protected]49639fa2011-12-20 23:22:417466 TestCompletionCallback callback1;
[email protected]f9ee6b52008-11-08 06:46:237467
tfarina42834112016-09-22 13:38:207468 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:017469 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]f9ee6b52008-11-08 06:46:237470
7471 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:017472 EXPECT_THAT(rv, IsOk());
[email protected]f9ee6b52008-11-08 06:46:237473
bnc691fda62016-08-12 00:43:167474 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:527475 ASSERT_TRUE(response);
7476 ASSERT_TRUE(response->auth_challenge);
[email protected]79cb5c12011-09-12 13:12:047477 EXPECT_FALSE(response->auth_challenge->is_proxy);
asanka098c0092016-06-16 20:18:437478 EXPECT_EQ("http://www.example.org",
7479 response->auth_challenge->challenger.Serialize());
[email protected]79cb5c12011-09-12 13:12:047480 EXPECT_EQ("MyRealm2", response->auth_challenge->realm);
aberentbba302d2015-12-03 10:20:197481 EXPECT_EQ(kBasicAuthScheme, response->auth_challenge->scheme);
[email protected]f9ee6b52008-11-08 06:46:237482
[email protected]49639fa2011-12-20 23:22:417483 TestCompletionCallback callback2;
[email protected]f9ee6b52008-11-08 06:46:237484
bnc691fda62016-08-12 00:43:167485 rv = trans.RestartWithAuth(AuthCredentials(kFoo2, kBar2),
7486 callback2.callback());
robpercival214763f2016-07-01 23:27:017487 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]f9ee6b52008-11-08 06:46:237488
7489 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:017490 EXPECT_THAT(rv, IsOk());
[email protected]f9ee6b52008-11-08 06:46:237491
bnc691fda62016-08-12 00:43:167492 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:527493 ASSERT_TRUE(response);
7494 EXPECT_FALSE(response->auth_challenge);
[email protected]f9ee6b52008-11-08 06:46:237495 EXPECT_EQ(100, response->headers->GetContentLength());
7496 }
7497
7498 // ------------------------------------------------------------------------
7499
7500 // Transaction 3: Resend a request in MyRealm's protection space --
7501 // succeed with preemptive authorization.
7502 {
[email protected]1c773ea12009-04-28 19:58:427503 HttpRequestInfo request;
[email protected]f9ee6b52008-11-08 06:46:237504 request.method = "GET";
bncce36dca22015-04-21 22:11:237505 request.url = GURL("http://www.example.org/x/y/z2");
[email protected]f9ee6b52008-11-08 06:46:237506
bnc691fda62016-08-12 00:43:167507 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:277508
[email protected]f9ee6b52008-11-08 06:46:237509 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:237510 MockWrite(
7511 "GET /x/y/z2 HTTP/1.1\r\n"
7512 "Host: www.example.org\r\n"
7513 "Connection: keep-alive\r\n"
7514 // The authorization for MyRealm1 gets sent preemptively
7515 // (since the url is in the same protection space)
7516 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:237517 };
7518
7519 // Sever accepts the preemptive authorization
7520 MockRead data_reads1[] = {
7521 MockRead("HTTP/1.0 200 OK\r\n"),
7522 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067523 MockRead(SYNCHRONOUS, OK),
[email protected]f9ee6b52008-11-08 06:46:237524 };
7525
[email protected]31a2bfe2010-02-09 08:03:397526 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
7527 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:077528 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]f9ee6b52008-11-08 06:46:237529
[email protected]49639fa2011-12-20 23:22:417530 TestCompletionCallback callback1;
[email protected]f9ee6b52008-11-08 06:46:237531
tfarina42834112016-09-22 13:38:207532 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:017533 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]f9ee6b52008-11-08 06:46:237534
7535 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:017536 EXPECT_THAT(rv, IsOk());
[email protected]f9ee6b52008-11-08 06:46:237537
bnc691fda62016-08-12 00:43:167538 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:527539 ASSERT_TRUE(response);
[email protected]f9ee6b52008-11-08 06:46:237540
wezca1070932016-05-26 20:30:527541 EXPECT_FALSE(response->auth_challenge);
[email protected]f9ee6b52008-11-08 06:46:237542 EXPECT_EQ(100, response->headers->GetContentLength());
7543 }
7544
7545 // ------------------------------------------------------------------------
7546
7547 // Transaction 4: request another URL in MyRealm (however the
7548 // url is not known to belong to the protection space, so no pre-auth).
7549 {
[email protected]1c773ea12009-04-28 19:58:427550 HttpRequestInfo request;
[email protected]f9ee6b52008-11-08 06:46:237551 request.method = "GET";
bncce36dca22015-04-21 22:11:237552 request.url = GURL("http://www.example.org/x/1");
[email protected]f9ee6b52008-11-08 06:46:237553
bnc691fda62016-08-12 00:43:167554 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:277555
[email protected]f9ee6b52008-11-08 06:46:237556 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:237557 MockWrite(
7558 "GET /x/1 HTTP/1.1\r\n"
7559 "Host: www.example.org\r\n"
7560 "Connection: keep-alive\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:237561 };
7562
7563 MockRead data_reads1[] = {
7564 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
7565 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
7566 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067567 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]f9ee6b52008-11-08 06:46:237568 };
7569
7570 // Resend with authorization from MyRealm's cache.
7571 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:237572 MockWrite(
7573 "GET /x/1 HTTP/1.1\r\n"
7574 "Host: www.example.org\r\n"
7575 "Connection: keep-alive\r\n"
7576 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:237577 };
7578
7579 // Sever accepts the authorization.
7580 MockRead data_reads2[] = {
7581 MockRead("HTTP/1.0 200 OK\r\n"),
7582 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067583 MockRead(SYNCHRONOUS, OK),
[email protected]f9ee6b52008-11-08 06:46:237584 };
7585
[email protected]31a2bfe2010-02-09 08:03:397586 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
7587 data_writes1, arraysize(data_writes1));
7588 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
7589 data_writes2, arraysize(data_writes2));
[email protected]bb88e1d32013-05-03 23:11:077590 session_deps_.socket_factory->AddSocketDataProvider(&data1);
7591 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]f9ee6b52008-11-08 06:46:237592
[email protected]49639fa2011-12-20 23:22:417593 TestCompletionCallback callback1;
[email protected]f9ee6b52008-11-08 06:46:237594
tfarina42834112016-09-22 13:38:207595 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:017596 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]f9ee6b52008-11-08 06:46:237597
7598 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:017599 EXPECT_THAT(rv, IsOk());
[email protected]f9ee6b52008-11-08 06:46:237600
bnc691fda62016-08-12 00:43:167601 EXPECT_TRUE(trans.IsReadyToRestartForAuth());
[email protected]49639fa2011-12-20 23:22:417602 TestCompletionCallback callback2;
bnc691fda62016-08-12 00:43:167603 rv = trans.RestartWithAuth(AuthCredentials(), callback2.callback());
robpercival214763f2016-07-01 23:27:017604 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]0757e7702009-03-27 04:00:227605 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:017606 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:167607 EXPECT_FALSE(trans.IsReadyToRestartForAuth());
[email protected]0757e7702009-03-27 04:00:227608
bnc691fda62016-08-12 00:43:167609 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:527610 ASSERT_TRUE(response);
7611 EXPECT_FALSE(response->auth_challenge);
[email protected]f9ee6b52008-11-08 06:46:237612 EXPECT_EQ(100, response->headers->GetContentLength());
7613 }
7614
7615 // ------------------------------------------------------------------------
7616
7617 // Transaction 5: request a URL in MyRealm, but the server rejects the
7618 // cached identity. Should invalidate and re-prompt.
7619 {
[email protected]1c773ea12009-04-28 19:58:427620 HttpRequestInfo request;
[email protected]f9ee6b52008-11-08 06:46:237621 request.method = "GET";
bncce36dca22015-04-21 22:11:237622 request.url = GURL("http://www.example.org/p/q/t");
[email protected]f9ee6b52008-11-08 06:46:237623
bnc691fda62016-08-12 00:43:167624 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:277625
[email protected]f9ee6b52008-11-08 06:46:237626 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:237627 MockWrite(
7628 "GET /p/q/t HTTP/1.1\r\n"
7629 "Host: www.example.org\r\n"
7630 "Connection: keep-alive\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:237631 };
7632
7633 MockRead data_reads1[] = {
7634 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
7635 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
7636 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067637 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]f9ee6b52008-11-08 06:46:237638 };
7639
7640 // Resend with authorization from cache for MyRealm.
7641 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:237642 MockWrite(
7643 "GET /p/q/t HTTP/1.1\r\n"
7644 "Host: www.example.org\r\n"
7645 "Connection: keep-alive\r\n"
7646 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:237647 };
7648
7649 // Sever rejects the authorization.
7650 MockRead data_reads2[] = {
7651 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
7652 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
7653 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067654 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]f9ee6b52008-11-08 06:46:237655 };
7656
7657 // At this point we should prompt for new credentials for MyRealm.
7658 // Restart with username=foo3, password=foo4.
7659 MockWrite data_writes3[] = {
bncce36dca22015-04-21 22:11:237660 MockWrite(
7661 "GET /p/q/t HTTP/1.1\r\n"
7662 "Host: www.example.org\r\n"
7663 "Connection: keep-alive\r\n"
7664 "Authorization: Basic Zm9vMzpiYXIz\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:237665 };
7666
7667 // Sever accepts the authorization.
7668 MockRead data_reads3[] = {
7669 MockRead("HTTP/1.0 200 OK\r\n"),
7670 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067671 MockRead(SYNCHRONOUS, OK),
[email protected]f9ee6b52008-11-08 06:46:237672 };
7673
[email protected]31a2bfe2010-02-09 08:03:397674 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
7675 data_writes1, arraysize(data_writes1));
7676 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
7677 data_writes2, arraysize(data_writes2));
7678 StaticSocketDataProvider data3(data_reads3, arraysize(data_reads3),
7679 data_writes3, arraysize(data_writes3));
[email protected]bb88e1d32013-05-03 23:11:077680 session_deps_.socket_factory->AddSocketDataProvider(&data1);
7681 session_deps_.socket_factory->AddSocketDataProvider(&data2);
7682 session_deps_.socket_factory->AddSocketDataProvider(&data3);
[email protected]f9ee6b52008-11-08 06:46:237683
[email protected]49639fa2011-12-20 23:22:417684 TestCompletionCallback callback1;
[email protected]f9ee6b52008-11-08 06:46:237685
tfarina42834112016-09-22 13:38:207686 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:017687 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]f9ee6b52008-11-08 06:46:237688
7689 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:017690 EXPECT_THAT(rv, IsOk());
[email protected]f9ee6b52008-11-08 06:46:237691
bnc691fda62016-08-12 00:43:167692 EXPECT_TRUE(trans.IsReadyToRestartForAuth());
[email protected]49639fa2011-12-20 23:22:417693 TestCompletionCallback callback2;
bnc691fda62016-08-12 00:43:167694 rv = trans.RestartWithAuth(AuthCredentials(), callback2.callback());
robpercival214763f2016-07-01 23:27:017695 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]0757e7702009-03-27 04:00:227696 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:017697 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:167698 EXPECT_FALSE(trans.IsReadyToRestartForAuth());
[email protected]0757e7702009-03-27 04:00:227699
bnc691fda62016-08-12 00:43:167700 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:527701 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:047702 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]f9ee6b52008-11-08 06:46:237703
[email protected]49639fa2011-12-20 23:22:417704 TestCompletionCallback callback3;
[email protected]f9ee6b52008-11-08 06:46:237705
bnc691fda62016-08-12 00:43:167706 rv = trans.RestartWithAuth(AuthCredentials(kFoo3, kBar3),
7707 callback3.callback());
robpercival214763f2016-07-01 23:27:017708 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]f9ee6b52008-11-08 06:46:237709
[email protected]0757e7702009-03-27 04:00:227710 rv = callback3.WaitForResult();
robpercival214763f2016-07-01 23:27:017711 EXPECT_THAT(rv, IsOk());
[email protected]f9ee6b52008-11-08 06:46:237712
bnc691fda62016-08-12 00:43:167713 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:527714 ASSERT_TRUE(response);
7715 EXPECT_FALSE(response->auth_challenge);
[email protected]f9ee6b52008-11-08 06:46:237716 EXPECT_EQ(100, response->headers->GetContentLength());
7717 }
7718}
[email protected]89ceba9a2009-03-21 03:46:067719
[email protected]3c32c5f2010-05-18 15:18:127720// Tests that nonce count increments when multiple auth attempts
7721// are started with the same nonce.
bncd16676a2016-07-20 16:23:017722TEST_F(HttpNetworkTransactionTest, DigestPreAuthNonceCount) {
[email protected]54fea2562010-11-17 14:40:447723 HttpAuthHandlerDigest::Factory* digest_factory =
7724 new HttpAuthHandlerDigest::Factory();
7725 HttpAuthHandlerDigest::FixedNonceGenerator* nonce_generator =
7726 new HttpAuthHandlerDigest::FixedNonceGenerator("0123456789abcdef");
7727 digest_factory->set_nonce_generator(nonce_generator);
[email protected]bb88e1d32013-05-03 23:11:077728 session_deps_.http_auth_handler_factory.reset(digest_factory);
danakj1fd259a02016-04-16 03:17:097729 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]3c32c5f2010-05-18 15:18:127730
7731 // Transaction 1: authenticate (foo, bar) on MyRealm1
7732 {
[email protected]3c32c5f2010-05-18 15:18:127733 HttpRequestInfo request;
7734 request.method = "GET";
bncce36dca22015-04-21 22:11:237735 request.url = GURL("http://www.example.org/x/y/z");
[email protected]3c32c5f2010-05-18 15:18:127736
bnc691fda62016-08-12 00:43:167737 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:277738
[email protected]3c32c5f2010-05-18 15:18:127739 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:237740 MockWrite(
7741 "GET /x/y/z HTTP/1.1\r\n"
7742 "Host: www.example.org\r\n"
7743 "Connection: keep-alive\r\n\r\n"),
[email protected]3c32c5f2010-05-18 15:18:127744 };
7745
7746 MockRead data_reads1[] = {
7747 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
7748 MockRead("WWW-Authenticate: Digest realm=\"digestive\", nonce=\"OU812\", "
7749 "algorithm=MD5, qop=\"auth\"\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067750 MockRead(SYNCHRONOUS, OK),
[email protected]3c32c5f2010-05-18 15:18:127751 };
7752
7753 // Resend with authorization (username=foo, password=bar)
7754 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:237755 MockWrite(
7756 "GET /x/y/z HTTP/1.1\r\n"
7757 "Host: www.example.org\r\n"
7758 "Connection: keep-alive\r\n"
7759 "Authorization: Digest username=\"foo\", realm=\"digestive\", "
7760 "nonce=\"OU812\", uri=\"/x/y/z\", algorithm=MD5, "
7761 "response=\"03ffbcd30add722589c1de345d7a927f\", qop=auth, "
7762 "nc=00000001, cnonce=\"0123456789abcdef\"\r\n\r\n"),
[email protected]3c32c5f2010-05-18 15:18:127763 };
7764
7765 // Sever accepts the authorization.
7766 MockRead data_reads2[] = {
zmo9528c9f42015-08-04 22:12:087767 MockRead("HTTP/1.0 200 OK\r\n"),
7768 MockRead(SYNCHRONOUS, OK),
[email protected]3c32c5f2010-05-18 15:18:127769 };
7770
7771 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
7772 data_writes1, arraysize(data_writes1));
7773 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
7774 data_writes2, arraysize(data_writes2));
[email protected]bb88e1d32013-05-03 23:11:077775 session_deps_.socket_factory->AddSocketDataProvider(&data1);
7776 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]3c32c5f2010-05-18 15:18:127777
[email protected]49639fa2011-12-20 23:22:417778 TestCompletionCallback callback1;
[email protected]3c32c5f2010-05-18 15:18:127779
tfarina42834112016-09-22 13:38:207780 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:017781 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]3c32c5f2010-05-18 15:18:127782
7783 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:017784 EXPECT_THAT(rv, IsOk());
[email protected]3c32c5f2010-05-18 15:18:127785
bnc691fda62016-08-12 00:43:167786 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:527787 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:047788 EXPECT_TRUE(CheckDigestServerAuth(response->auth_challenge.get()));
[email protected]3c32c5f2010-05-18 15:18:127789
[email protected]49639fa2011-12-20 23:22:417790 TestCompletionCallback callback2;
[email protected]3c32c5f2010-05-18 15:18:127791
bnc691fda62016-08-12 00:43:167792 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar),
7793 callback2.callback());
robpercival214763f2016-07-01 23:27:017794 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]3c32c5f2010-05-18 15:18:127795
7796 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:017797 EXPECT_THAT(rv, IsOk());
[email protected]3c32c5f2010-05-18 15:18:127798
bnc691fda62016-08-12 00:43:167799 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:527800 ASSERT_TRUE(response);
7801 EXPECT_FALSE(response->auth_challenge);
[email protected]3c32c5f2010-05-18 15:18:127802 }
7803
7804 // ------------------------------------------------------------------------
7805
7806 // Transaction 2: Request another resource in digestive's protection space.
7807 // This will preemptively add an Authorization header which should have an
7808 // "nc" value of 2 (as compared to 1 in the first use.
7809 {
[email protected]3c32c5f2010-05-18 15:18:127810 HttpRequestInfo request;
7811 request.method = "GET";
7812 // Note that Transaction 1 was at /x/y/z, so this is in the same
7813 // protection space as digest.
bncce36dca22015-04-21 22:11:237814 request.url = GURL("http://www.example.org/x/y/a/b");
[email protected]3c32c5f2010-05-18 15:18:127815
bnc691fda62016-08-12 00:43:167816 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:277817
[email protected]3c32c5f2010-05-18 15:18:127818 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:237819 MockWrite(
7820 "GET /x/y/a/b HTTP/1.1\r\n"
7821 "Host: www.example.org\r\n"
7822 "Connection: keep-alive\r\n"
7823 "Authorization: Digest username=\"foo\", realm=\"digestive\", "
7824 "nonce=\"OU812\", uri=\"/x/y/a/b\", algorithm=MD5, "
7825 "response=\"d6f9a2c07d1c5df7b89379dca1269b35\", qop=auth, "
7826 "nc=00000002, cnonce=\"0123456789abcdef\"\r\n\r\n"),
[email protected]3c32c5f2010-05-18 15:18:127827 };
7828
7829 // Sever accepts the authorization.
7830 MockRead data_reads1[] = {
7831 MockRead("HTTP/1.0 200 OK\r\n"),
7832 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067833 MockRead(SYNCHRONOUS, OK),
[email protected]3c32c5f2010-05-18 15:18:127834 };
7835
7836 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
7837 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:077838 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]3c32c5f2010-05-18 15:18:127839
[email protected]49639fa2011-12-20 23:22:417840 TestCompletionCallback callback1;
[email protected]3c32c5f2010-05-18 15:18:127841
tfarina42834112016-09-22 13:38:207842 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:017843 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]3c32c5f2010-05-18 15:18:127844
7845 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:017846 EXPECT_THAT(rv, IsOk());
[email protected]3c32c5f2010-05-18 15:18:127847
bnc691fda62016-08-12 00:43:167848 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:527849 ASSERT_TRUE(response);
7850 EXPECT_FALSE(response->auth_challenge);
[email protected]3c32c5f2010-05-18 15:18:127851 }
7852}
7853
[email protected]89ceba9a2009-03-21 03:46:067854// Test the ResetStateForRestart() private method.
bncd16676a2016-07-20 16:23:017855TEST_F(HttpNetworkTransactionTest, ResetStateForRestart) {
[email protected]89ceba9a2009-03-21 03:46:067856 // Create a transaction (the dependencies aren't important).
danakj1fd259a02016-04-16 03:17:097857 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:167858 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]89ceba9a2009-03-21 03:46:067859
7860 // Setup some state (which we expect ResetStateForRestart() will clear).
bnc691fda62016-08-12 00:43:167861 trans.read_buf_ = new IOBuffer(15);
7862 trans.read_buf_len_ = 15;
7863 trans.request_headers_.SetHeader("Authorization", "NTLM");
[email protected]89ceba9a2009-03-21 03:46:067864
7865 // Setup state in response_
bnc691fda62016-08-12 00:43:167866 HttpResponseInfo* response = &trans.response_;
[email protected]0877e3d2009-10-17 22:29:577867 response->auth_challenge = new AuthChallengeInfo();
[email protected]70d66502011-09-23 00:55:087868 response->ssl_info.cert_status = static_cast<CertStatus>(-1); // Nonsensical.
[email protected]0877e3d2009-10-17 22:29:577869 response->response_time = base::Time::Now();
7870 response->was_cached = true; // (Wouldn't ever actually be true...)
[email protected]89ceba9a2009-03-21 03:46:067871
7872 { // Setup state for response_.vary_data
7873 HttpRequestInfo request;
7874 std::string temp("HTTP/1.1 200 OK\nVary: foo, bar\n\n");
7875 std::replace(temp.begin(), temp.end(), '\n', '\0');
[email protected]ad8e04a2010-11-01 04:16:277876 scoped_refptr<HttpResponseHeaders> headers(new HttpResponseHeaders(temp));
[email protected]8c76ae22010-04-20 22:15:437877 request.extra_headers.SetHeader("Foo", "1");
7878 request.extra_headers.SetHeader("bar", "23");
[email protected]90499482013-06-01 00:39:507879 EXPECT_TRUE(response->vary_data.Init(request, *headers.get()));
[email protected]89ceba9a2009-03-21 03:46:067880 }
7881
7882 // Cause the above state to be reset.
bnc691fda62016-08-12 00:43:167883 trans.ResetStateForRestart();
[email protected]89ceba9a2009-03-21 03:46:067884
7885 // Verify that the state that needed to be reset, has been reset.
bnc691fda62016-08-12 00:43:167886 EXPECT_FALSE(trans.read_buf_);
7887 EXPECT_EQ(0, trans.read_buf_len_);
7888 EXPECT_TRUE(trans.request_headers_.IsEmpty());
wezca1070932016-05-26 20:30:527889 EXPECT_FALSE(response->auth_challenge);
7890 EXPECT_FALSE(response->headers);
[email protected]34f40942010-10-04 00:34:047891 EXPECT_FALSE(response->was_cached);
[email protected]70d66502011-09-23 00:55:087892 EXPECT_EQ(0U, response->ssl_info.cert_status);
[email protected]0877e3d2009-10-17 22:29:577893 EXPECT_FALSE(response->vary_data.is_valid());
[email protected]89ceba9a2009-03-21 03:46:067894}
7895
[email protected]bacff652009-03-31 17:50:337896// Test HTTPS connections to a site with a bad certificate
bncd16676a2016-07-20 16:23:017897TEST_F(HttpNetworkTransactionTest, HTTPSBadCertificate) {
[email protected]bacff652009-03-31 17:50:337898 HttpRequestInfo request;
7899 request.method = "GET";
bncce36dca22015-04-21 22:11:237900 request.url = GURL("https://www.example.org/");
[email protected]bacff652009-03-31 17:50:337901
danakj1fd259a02016-04-16 03:17:097902 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:167903 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:277904
[email protected]bacff652009-03-31 17:50:337905 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:237906 MockWrite(
7907 "GET / HTTP/1.1\r\n"
7908 "Host: www.example.org\r\n"
7909 "Connection: keep-alive\r\n\r\n"),
[email protected]bacff652009-03-31 17:50:337910 };
7911
7912 MockRead data_reads[] = {
7913 MockRead("HTTP/1.0 200 OK\r\n"),
7914 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
7915 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067916 MockRead(SYNCHRONOUS, OK),
[email protected]bacff652009-03-31 17:50:337917 };
7918
[email protected]5ecc992a42009-11-11 01:41:597919 StaticSocketDataProvider ssl_bad_certificate;
[email protected]31a2bfe2010-02-09 08:03:397920 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
7921 data_writes, arraysize(data_writes));
[email protected]8ddf8322012-02-23 18:08:067922 SSLSocketDataProvider ssl_bad(ASYNC, ERR_CERT_AUTHORITY_INVALID);
7923 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bacff652009-03-31 17:50:337924
[email protected]bb88e1d32013-05-03 23:11:077925 session_deps_.socket_factory->AddSocketDataProvider(&ssl_bad_certificate);
7926 session_deps_.socket_factory->AddSocketDataProvider(&data);
7927 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_bad);
7928 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]bacff652009-03-31 17:50:337929
[email protected]49639fa2011-12-20 23:22:417930 TestCompletionCallback callback;
[email protected]bacff652009-03-31 17:50:337931
tfarina42834112016-09-22 13:38:207932 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:017933 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]bacff652009-03-31 17:50:337934
7935 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:017936 EXPECT_THAT(rv, IsError(ERR_CERT_AUTHORITY_INVALID));
[email protected]bacff652009-03-31 17:50:337937
bnc691fda62016-08-12 00:43:167938 rv = trans.RestartIgnoringLastError(callback.callback());
robpercival214763f2016-07-01 23:27:017939 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]bacff652009-03-31 17:50:337940
7941 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:017942 EXPECT_THAT(rv, IsOk());
[email protected]bacff652009-03-31 17:50:337943
bnc691fda62016-08-12 00:43:167944 const HttpResponseInfo* response = trans.GetResponseInfo();
[email protected]bacff652009-03-31 17:50:337945
wezca1070932016-05-26 20:30:527946 ASSERT_TRUE(response);
[email protected]bacff652009-03-31 17:50:337947 EXPECT_EQ(100, response->headers->GetContentLength());
7948}
7949
7950// Test HTTPS connections to a site with a bad certificate, going through a
7951// proxy
bncd16676a2016-07-20 16:23:017952TEST_F(HttpNetworkTransactionTest, HTTPSBadCertificateViaProxy) {
rdsmith82957ad2015-09-16 19:42:037953 session_deps_.proxy_service = ProxyService::CreateFixed("myproxy:70");
[email protected]bacff652009-03-31 17:50:337954
7955 HttpRequestInfo request;
7956 request.method = "GET";
bncce36dca22015-04-21 22:11:237957 request.url = GURL("https://www.example.org/");
[email protected]bacff652009-03-31 17:50:337958
7959 MockWrite proxy_writes[] = {
rsleevidb16bb02015-11-12 23:47:177960 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
7961 "Host: www.example.org:443\r\n"
7962 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]bacff652009-03-31 17:50:337963 };
7964
7965 MockRead proxy_reads[] = {
7966 MockRead("HTTP/1.0 200 Connected\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067967 MockRead(SYNCHRONOUS, OK)
[email protected]bacff652009-03-31 17:50:337968 };
7969
7970 MockWrite data_writes[] = {
rsleevidb16bb02015-11-12 23:47:177971 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
7972 "Host: www.example.org:443\r\n"
7973 "Proxy-Connection: keep-alive\r\n\r\n"),
7974 MockWrite("GET / HTTP/1.1\r\n"
7975 "Host: www.example.org\r\n"
7976 "Connection: keep-alive\r\n\r\n"),
[email protected]bacff652009-03-31 17:50:337977 };
7978
7979 MockRead data_reads[] = {
7980 MockRead("HTTP/1.0 200 Connected\r\n\r\n"),
7981 MockRead("HTTP/1.0 200 OK\r\n"),
7982 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
7983 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067984 MockRead(SYNCHRONOUS, OK),
[email protected]bacff652009-03-31 17:50:337985 };
7986
[email protected]31a2bfe2010-02-09 08:03:397987 StaticSocketDataProvider ssl_bad_certificate(
7988 proxy_reads, arraysize(proxy_reads),
7989 proxy_writes, arraysize(proxy_writes));
7990 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
7991 data_writes, arraysize(data_writes));
[email protected]8ddf8322012-02-23 18:08:067992 SSLSocketDataProvider ssl_bad(ASYNC, ERR_CERT_AUTHORITY_INVALID);
7993 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bacff652009-03-31 17:50:337994
[email protected]bb88e1d32013-05-03 23:11:077995 session_deps_.socket_factory->AddSocketDataProvider(&ssl_bad_certificate);
7996 session_deps_.socket_factory->AddSocketDataProvider(&data);
7997 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_bad);
7998 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]bacff652009-03-31 17:50:337999
[email protected]49639fa2011-12-20 23:22:418000 TestCompletionCallback callback;
[email protected]bacff652009-03-31 17:50:338001
8002 for (int i = 0; i < 2; i++) {
[email protected]bb88e1d32013-05-03 23:11:078003 session_deps_.socket_factory->ResetNextMockIndexes();
[email protected]bacff652009-03-31 17:50:338004
danakj1fd259a02016-04-16 03:17:098005 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:168006 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]bacff652009-03-31 17:50:338007
tfarina42834112016-09-22 13:38:208008 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:018009 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]bacff652009-03-31 17:50:338010
8011 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:018012 EXPECT_THAT(rv, IsError(ERR_CERT_AUTHORITY_INVALID));
[email protected]bacff652009-03-31 17:50:338013
bnc691fda62016-08-12 00:43:168014 rv = trans.RestartIgnoringLastError(callback.callback());
robpercival214763f2016-07-01 23:27:018015 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]bacff652009-03-31 17:50:338016
8017 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:018018 EXPECT_THAT(rv, IsOk());
[email protected]bacff652009-03-31 17:50:338019
bnc691fda62016-08-12 00:43:168020 const HttpResponseInfo* response = trans.GetResponseInfo();
[email protected]bacff652009-03-31 17:50:338021
wezca1070932016-05-26 20:30:528022 ASSERT_TRUE(response);
[email protected]bacff652009-03-31 17:50:338023 EXPECT_EQ(100, response->headers->GetContentLength());
8024 }
8025}
8026
[email protected]2df19bb2010-08-25 20:13:468027
8028// Test HTTPS connections to a site, going through an HTTPS proxy
bncd16676a2016-07-20 16:23:018029TEST_F(HttpNetworkTransactionTest, HTTPSViaHttpsProxy) {
rdsmith82957ad2015-09-16 19:42:038030 session_deps_.proxy_service =
8031 ProxyService::CreateFixedFromPacResult("HTTPS proxy:70");
vishal.b62985ca92015-04-17 08:45:518032 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:078033 session_deps_.net_log = &net_log;
[email protected]2df19bb2010-08-25 20:13:468034
8035 HttpRequestInfo request;
8036 request.method = "GET";
bncce36dca22015-04-21 22:11:238037 request.url = GURL("https://www.example.org/");
[email protected]2df19bb2010-08-25 20:13:468038
8039 MockWrite data_writes[] = {
rsleevidb16bb02015-11-12 23:47:178040 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
8041 "Host: www.example.org:443\r\n"
8042 "Proxy-Connection: keep-alive\r\n\r\n"),
8043 MockWrite("GET / HTTP/1.1\r\n"
8044 "Host: www.example.org\r\n"
8045 "Connection: keep-alive\r\n\r\n"),
[email protected]2df19bb2010-08-25 20:13:468046 };
8047
8048 MockRead data_reads[] = {
8049 MockRead("HTTP/1.0 200 Connected\r\n\r\n"),
8050 MockRead("HTTP/1.1 200 OK\r\n"),
8051 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
8052 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:068053 MockRead(SYNCHRONOUS, OK),
[email protected]2df19bb2010-08-25 20:13:468054 };
8055
8056 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
8057 data_writes, arraysize(data_writes));
[email protected]8ddf8322012-02-23 18:08:068058 SSLSocketDataProvider proxy_ssl(ASYNC, OK); // SSL to the proxy
8059 SSLSocketDataProvider tunnel_ssl(ASYNC, OK); // SSL through the tunnel
[email protected]2df19bb2010-08-25 20:13:468060
[email protected]bb88e1d32013-05-03 23:11:078061 session_deps_.socket_factory->AddSocketDataProvider(&data);
8062 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy_ssl);
8063 session_deps_.socket_factory->AddSSLSocketDataProvider(&tunnel_ssl);
[email protected]2df19bb2010-08-25 20:13:468064
[email protected]49639fa2011-12-20 23:22:418065 TestCompletionCallback callback;
[email protected]2df19bb2010-08-25 20:13:468066
danakj1fd259a02016-04-16 03:17:098067 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:168068 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]2df19bb2010-08-25 20:13:468069
tfarina42834112016-09-22 13:38:208070 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:018071 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2df19bb2010-08-25 20:13:468072
8073 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:018074 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:168075 const HttpResponseInfo* response = trans.GetResponseInfo();
[email protected]2df19bb2010-08-25 20:13:468076
wezca1070932016-05-26 20:30:528077 ASSERT_TRUE(response);
[email protected]2df19bb2010-08-25 20:13:468078
tbansal2ecbbc72016-10-06 17:15:478079 EXPECT_TRUE(response->proxy_server.is_https());
[email protected]2df19bb2010-08-25 20:13:468080 EXPECT_TRUE(response->headers->IsKeepAlive());
8081 EXPECT_EQ(200, response->headers->response_code());
8082 EXPECT_EQ(100, response->headers->GetContentLength());
8083 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
[email protected]029c83b62013-01-24 05:28:208084
8085 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:168086 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]029c83b62013-01-24 05:28:208087 TestLoadTimingNotReusedWithPac(load_timing_info,
8088 CONNECT_TIMING_HAS_SSL_TIMES);
[email protected]2df19bb2010-08-25 20:13:468089}
8090
[email protected]511f6f52010-12-17 03:58:298091// Test an HTTPS Proxy's ability to redirect a CONNECT request
bncd16676a2016-07-20 16:23:018092TEST_F(HttpNetworkTransactionTest, RedirectOfHttpsConnectViaHttpsProxy) {
rdsmith82957ad2015-09-16 19:42:038093 session_deps_.proxy_service =
8094 ProxyService::CreateFixedFromPacResult("HTTPS proxy:70");
vishal.b62985ca92015-04-17 08:45:518095 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:078096 session_deps_.net_log = &net_log;
[email protected]511f6f52010-12-17 03:58:298097
8098 HttpRequestInfo request;
8099 request.method = "GET";
bncce36dca22015-04-21 22:11:238100 request.url = GURL("https://www.example.org/");
[email protected]511f6f52010-12-17 03:58:298101
8102 MockWrite data_writes[] = {
rsleevidb16bb02015-11-12 23:47:178103 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
8104 "Host: www.example.org:443\r\n"
8105 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]511f6f52010-12-17 03:58:298106 };
8107
8108 MockRead data_reads[] = {
8109 MockRead("HTTP/1.1 302 Redirect\r\n"),
8110 MockRead("Location: http://login.example.com/\r\n"),
8111 MockRead("Content-Length: 0\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:068112 MockRead(SYNCHRONOUS, OK),
[email protected]511f6f52010-12-17 03:58:298113 };
8114
8115 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
8116 data_writes, arraysize(data_writes));
[email protected]8ddf8322012-02-23 18:08:068117 SSLSocketDataProvider proxy_ssl(ASYNC, OK); // SSL to the proxy
[email protected]511f6f52010-12-17 03:58:298118
[email protected]bb88e1d32013-05-03 23:11:078119 session_deps_.socket_factory->AddSocketDataProvider(&data);
8120 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy_ssl);
[email protected]511f6f52010-12-17 03:58:298121
[email protected]49639fa2011-12-20 23:22:418122 TestCompletionCallback callback;
[email protected]511f6f52010-12-17 03:58:298123
danakj1fd259a02016-04-16 03:17:098124 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:168125 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]511f6f52010-12-17 03:58:298126
tfarina42834112016-09-22 13:38:208127 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:018128 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]511f6f52010-12-17 03:58:298129
8130 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:018131 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:168132 const HttpResponseInfo* response = trans.GetResponseInfo();
[email protected]511f6f52010-12-17 03:58:298133
wezca1070932016-05-26 20:30:528134 ASSERT_TRUE(response);
[email protected]511f6f52010-12-17 03:58:298135
8136 EXPECT_EQ(302, response->headers->response_code());
8137 std::string url;
8138 EXPECT_TRUE(response->headers->IsRedirect(&url));
8139 EXPECT_EQ("http://login.example.com/", url);
[email protected]029c83b62013-01-24 05:28:208140
8141 // In the case of redirects from proxies, HttpNetworkTransaction returns
8142 // timing for the proxy connection instead of the connection to the host,
8143 // and no send / receive times.
8144 // See HttpNetworkTransaction::OnHttpsProxyTunnelResponse.
8145 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:168146 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]029c83b62013-01-24 05:28:208147
8148 EXPECT_FALSE(load_timing_info.socket_reused);
mikecironef22f9812016-10-04 03:40:198149 EXPECT_NE(NetLogSource::kInvalidId, load_timing_info.socket_log_id);
[email protected]029c83b62013-01-24 05:28:208150
8151 EXPECT_FALSE(load_timing_info.proxy_resolve_start.is_null());
8152 EXPECT_LE(load_timing_info.proxy_resolve_start,
8153 load_timing_info.proxy_resolve_end);
8154 EXPECT_LE(load_timing_info.proxy_resolve_end,
8155 load_timing_info.connect_timing.connect_start);
8156 ExpectConnectTimingHasTimes(
8157 load_timing_info.connect_timing,
8158 CONNECT_TIMING_HAS_DNS_TIMES | CONNECT_TIMING_HAS_SSL_TIMES);
8159
8160 EXPECT_TRUE(load_timing_info.send_start.is_null());
8161 EXPECT_TRUE(load_timing_info.send_end.is_null());
8162 EXPECT_TRUE(load_timing_info.receive_headers_end.is_null());
[email protected]511f6f52010-12-17 03:58:298163}
8164
8165// Test an HTTPS (SPDY) Proxy's ability to redirect a CONNECT request
bncd16676a2016-07-20 16:23:018166TEST_F(HttpNetworkTransactionTest, RedirectOfHttpsConnectViaSpdyProxy) {
rdsmith82957ad2015-09-16 19:42:038167 session_deps_.proxy_service = ProxyService::CreateFixed("https://proxy:70");
[email protected]511f6f52010-12-17 03:58:298168
8169 HttpRequestInfo request;
8170 request.method = "GET";
bncce36dca22015-04-21 22:11:238171 request.url = GURL("https://www.example.org/");
[email protected]511f6f52010-12-17 03:58:298172
bncdf80d44fd2016-07-15 20:27:418173 SpdySerializedFrame conn(spdy_util_.ConstructSpdyConnect(
bncce36dca22015-04-21 22:11:238174 NULL, 0, 1, LOWEST, HostPortPair("www.example.org", 443)));
bncdf80d44fd2016-07-15 20:27:418175 SpdySerializedFrame goaway(
diannahu9904e272017-02-03 14:40:088176 spdy_util_.ConstructSpdyRstStream(1, ERROR_CODE_CANCEL));
[email protected]511f6f52010-12-17 03:58:298177 MockWrite data_writes[] = {
bncdf80d44fd2016-07-15 20:27:418178 CreateMockWrite(conn, 0, SYNCHRONOUS),
8179 CreateMockWrite(goaway, 2, SYNCHRONOUS),
[email protected]511f6f52010-12-17 03:58:298180 };
8181
8182 static const char* const kExtraHeaders[] = {
8183 "location",
8184 "http://login.example.com/",
8185 };
bnc42331402016-07-25 13:36:158186 SpdySerializedFrame resp(spdy_util_.ConstructSpdyReplyError(
bncc9f762a2016-12-06 20:38:238187 "302", kExtraHeaders, arraysize(kExtraHeaders) / 2, 1));
[email protected]511f6f52010-12-17 03:58:298188 MockRead data_reads[] = {
bncdf80d44fd2016-07-15 20:27:418189 CreateMockRead(resp, 1), MockRead(ASYNC, 0, 3), // EOF
[email protected]511f6f52010-12-17 03:58:298190 };
8191
rch8e6c6c42015-05-01 14:05:138192 SequencedSocketData data(data_reads, arraysize(data_reads), data_writes,
8193 arraysize(data_writes));
[email protected]8ddf8322012-02-23 18:08:068194 SSLSocketDataProvider proxy_ssl(ASYNC, OK); // SSL to the proxy
bnc3cf2a592016-08-11 14:48:368195 proxy_ssl.next_proto = kProtoHTTP2;
[email protected]511f6f52010-12-17 03:58:298196
[email protected]bb88e1d32013-05-03 23:11:078197 session_deps_.socket_factory->AddSocketDataProvider(&data);
8198 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy_ssl);
[email protected]511f6f52010-12-17 03:58:298199
[email protected]49639fa2011-12-20 23:22:418200 TestCompletionCallback callback;
[email protected]511f6f52010-12-17 03:58:298201
danakj1fd259a02016-04-16 03:17:098202 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:168203 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]511f6f52010-12-17 03:58:298204
tfarina42834112016-09-22 13:38:208205 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:018206 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]511f6f52010-12-17 03:58:298207
8208 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:018209 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:168210 const HttpResponseInfo* response = trans.GetResponseInfo();
[email protected]511f6f52010-12-17 03:58:298211
wezca1070932016-05-26 20:30:528212 ASSERT_TRUE(response);
[email protected]511f6f52010-12-17 03:58:298213
8214 EXPECT_EQ(302, response->headers->response_code());
8215 std::string url;
8216 EXPECT_TRUE(response->headers->IsRedirect(&url));
8217 EXPECT_EQ("http://login.example.com/", url);
8218}
8219
[email protected]4eddbc732012-08-09 05:40:178220// Test that an HTTPS proxy's response to a CONNECT request is filtered.
bncd16676a2016-07-20 16:23:018221TEST_F(HttpNetworkTransactionTest, ErrorResponseToHttpsConnectViaHttpsProxy) {
rdsmith82957ad2015-09-16 19:42:038222 session_deps_.proxy_service = ProxyService::CreateFixed("https://proxy:70");
[email protected]511f6f52010-12-17 03:58:298223
8224 HttpRequestInfo request;
8225 request.method = "GET";
bncce36dca22015-04-21 22:11:238226 request.url = GURL("https://www.example.org/");
[email protected]511f6f52010-12-17 03:58:298227
8228 MockWrite data_writes[] = {
rsleevidb16bb02015-11-12 23:47:178229 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
8230 "Host: www.example.org:443\r\n"
8231 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]511f6f52010-12-17 03:58:298232 };
8233
8234 MockRead data_reads[] = {
8235 MockRead("HTTP/1.1 404 Not Found\r\n"),
8236 MockRead("Content-Length: 23\r\n\r\n"),
8237 MockRead("The host does not exist"),
[email protected]8ddf8322012-02-23 18:08:068238 MockRead(SYNCHRONOUS, OK),
[email protected]511f6f52010-12-17 03:58:298239 };
8240
8241 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
8242 data_writes, arraysize(data_writes));
[email protected]8ddf8322012-02-23 18:08:068243 SSLSocketDataProvider proxy_ssl(ASYNC, OK); // SSL to the proxy
[email protected]511f6f52010-12-17 03:58:298244
[email protected]bb88e1d32013-05-03 23:11:078245 session_deps_.socket_factory->AddSocketDataProvider(&data);
8246 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy_ssl);
[email protected]511f6f52010-12-17 03:58:298247
[email protected]49639fa2011-12-20 23:22:418248 TestCompletionCallback callback;
[email protected]511f6f52010-12-17 03:58:298249
danakj1fd259a02016-04-16 03:17:098250 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:168251 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]511f6f52010-12-17 03:58:298252
tfarina42834112016-09-22 13:38:208253 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:018254 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]511f6f52010-12-17 03:58:298255
8256 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:018257 EXPECT_THAT(rv, IsError(ERR_TUNNEL_CONNECTION_FAILED));
[email protected]511f6f52010-12-17 03:58:298258
ttuttle960fcbf2016-04-19 13:26:328259 // TODO(juliatuttle): Anything else to check here?
[email protected]511f6f52010-12-17 03:58:298260}
8261
[email protected]4eddbc732012-08-09 05:40:178262// Test that a SPDY proxy's response to a CONNECT request is filtered.
bncd16676a2016-07-20 16:23:018263TEST_F(HttpNetworkTransactionTest, ErrorResponseToHttpsConnectViaSpdyProxy) {
rdsmith82957ad2015-09-16 19:42:038264 session_deps_.proxy_service = ProxyService::CreateFixed("https://proxy:70");
[email protected]511f6f52010-12-17 03:58:298265
8266 HttpRequestInfo request;
8267 request.method = "GET";
bncce36dca22015-04-21 22:11:238268 request.url = GURL("https://www.example.org/");
[email protected]511f6f52010-12-17 03:58:298269
bncdf80d44fd2016-07-15 20:27:418270 SpdySerializedFrame conn(spdy_util_.ConstructSpdyConnect(
bncce36dca22015-04-21 22:11:238271 NULL, 0, 1, LOWEST, HostPortPair("www.example.org", 443)));
bncdf80d44fd2016-07-15 20:27:418272 SpdySerializedFrame rst(
diannahu9904e272017-02-03 14:40:088273 spdy_util_.ConstructSpdyRstStream(1, ERROR_CODE_CANCEL));
[email protected]511f6f52010-12-17 03:58:298274 MockWrite data_writes[] = {
bncdf80d44fd2016-07-15 20:27:418275 CreateMockWrite(conn, 0), CreateMockWrite(rst, 3),
[email protected]511f6f52010-12-17 03:58:298276 };
8277
8278 static const char* const kExtraHeaders[] = {
8279 "location",
8280 "http://login.example.com/",
8281 };
bnc42331402016-07-25 13:36:158282 SpdySerializedFrame resp(spdy_util_.ConstructSpdyReplyError(
bncc9f762a2016-12-06 20:38:238283 "404", kExtraHeaders, arraysize(kExtraHeaders) / 2, 1));
bncdf80d44fd2016-07-15 20:27:418284 SpdySerializedFrame body(spdy_util_.ConstructSpdyDataFrame(
bncb03b1092016-04-06 11:19:558285 1, "The host does not exist", 23, true));
[email protected]511f6f52010-12-17 03:58:298286 MockRead data_reads[] = {
bncdf80d44fd2016-07-15 20:27:418287 CreateMockRead(resp, 1), CreateMockRead(body, 2),
rch8e6c6c42015-05-01 14:05:138288 MockRead(ASYNC, 0, 4), // EOF
[email protected]511f6f52010-12-17 03:58:298289 };
8290
rch8e6c6c42015-05-01 14:05:138291 SequencedSocketData data(data_reads, arraysize(data_reads), data_writes,
8292 arraysize(data_writes));
[email protected]8ddf8322012-02-23 18:08:068293 SSLSocketDataProvider proxy_ssl(ASYNC, OK); // SSL to the proxy
bnc3cf2a592016-08-11 14:48:368294 proxy_ssl.next_proto = kProtoHTTP2;
[email protected]511f6f52010-12-17 03:58:298295
[email protected]bb88e1d32013-05-03 23:11:078296 session_deps_.socket_factory->AddSocketDataProvider(&data);
8297 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy_ssl);
[email protected]511f6f52010-12-17 03:58:298298
[email protected]49639fa2011-12-20 23:22:418299 TestCompletionCallback callback;
[email protected]511f6f52010-12-17 03:58:298300
danakj1fd259a02016-04-16 03:17:098301 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:168302 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]511f6f52010-12-17 03:58:298303
tfarina42834112016-09-22 13:38:208304 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:018305 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]511f6f52010-12-17 03:58:298306
8307 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:018308 EXPECT_THAT(rv, IsError(ERR_TUNNEL_CONNECTION_FAILED));
[email protected]511f6f52010-12-17 03:58:298309
ttuttle960fcbf2016-04-19 13:26:328310 // TODO(juliatuttle): Anything else to check here?
[email protected]511f6f52010-12-17 03:58:298311}
8312
[email protected]0c5fb722012-02-28 11:50:358313// Test the request-challenge-retry sequence for basic auth, through
8314// a SPDY proxy over a single SPDY session.
bncd16676a2016-07-20 16:23:018315TEST_F(HttpNetworkTransactionTest, BasicAuthSpdyProxy) {
[email protected]0c5fb722012-02-28 11:50:358316 HttpRequestInfo request;
8317 request.method = "GET";
bncce36dca22015-04-21 22:11:238318 request.url = GURL("https://www.example.org/");
[email protected]0c5fb722012-02-28 11:50:358319 // when the no authentication data flag is set.
ttuttle859dc7a2015-04-23 19:42:298320 request.load_flags = LOAD_DO_NOT_SEND_AUTH_DATA;
[email protected]0c5fb722012-02-28 11:50:358321
8322 // Configure against https proxy server "myproxy:70".
rdsmith82957ad2015-09-16 19:42:038323 session_deps_.proxy_service =
8324 ProxyService::CreateFixedFromPacResult("HTTPS myproxy:70");
vishal.b62985ca92015-04-17 08:45:518325 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:078326 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:098327 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]0c5fb722012-02-28 11:50:358328
8329 // Since we have proxy, should try to establish tunnel.
bncdf80d44fd2016-07-15 20:27:418330 SpdySerializedFrame req(spdy_util_.ConstructSpdyConnect(
bncce36dca22015-04-21 22:11:238331 NULL, 0, 1, LOWEST, HostPortPair("www.example.org", 443)));
bncdf80d44fd2016-07-15 20:27:418332 SpdySerializedFrame rst(
diannahu9904e272017-02-03 14:40:088333 spdy_util_.ConstructSpdyRstStream(1, ERROR_CODE_CANCEL));
rdsmithebb50aa2015-11-12 03:44:388334 spdy_util_.UpdateWithStreamDestruction(1);
[email protected]0c5fb722012-02-28 11:50:358335
bnc691fda62016-08-12 00:43:168336 // After calling trans.RestartWithAuth(), this is the request we should
[email protected]0c5fb722012-02-28 11:50:358337 // be issuing -- the final header line contains the credentials.
8338 const char* const kAuthCredentials[] = {
8339 "proxy-authorization", "Basic Zm9vOmJhcg==",
8340 };
bncdf80d44fd2016-07-15 20:27:418341 SpdySerializedFrame connect2(spdy_util_.ConstructSpdyConnect(
lgarrona91df87f2014-12-05 00:51:348342 kAuthCredentials, arraysize(kAuthCredentials) / 2, 3, LOWEST,
bncce36dca22015-04-21 22:11:238343 HostPortPair("www.example.org", 443)));
8344 // fetch https://www.example.org/ via HTTP
8345 const char get[] =
8346 "GET / HTTP/1.1\r\n"
8347 "Host: www.example.org\r\n"
8348 "Connection: keep-alive\r\n\r\n";
bncdf80d44fd2016-07-15 20:27:418349 SpdySerializedFrame wrapped_get(
8350 spdy_util_.ConstructSpdyDataFrame(3, get, strlen(get), false));
[email protected]0c5fb722012-02-28 11:50:358351
8352 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:418353 CreateMockWrite(req, 0, ASYNC), CreateMockWrite(rst, 2, ASYNC),
8354 CreateMockWrite(connect2, 3), CreateMockWrite(wrapped_get, 5),
[email protected]0c5fb722012-02-28 11:50:358355 };
8356
8357 // The proxy responds to the connect with a 407, using a persistent
8358 // connection.
thestig9d3bb0c2015-01-24 00:49:518359 const char kAuthStatus[] = "407";
[email protected]0c5fb722012-02-28 11:50:358360 const char* const kAuthChallenge[] = {
[email protected]0c5fb722012-02-28 11:50:358361 "proxy-authenticate", "Basic realm=\"MyRealm1\"",
8362 };
bnc42331402016-07-25 13:36:158363 SpdySerializedFrame conn_auth_resp(spdy_util_.ConstructSpdyReplyError(
bncdf80d44fd2016-07-15 20:27:418364 kAuthStatus, kAuthChallenge, arraysize(kAuthChallenge) / 2, 1));
[email protected]0c5fb722012-02-28 11:50:358365
bnc42331402016-07-25 13:36:158366 SpdySerializedFrame conn_resp(spdy_util_.ConstructSpdyGetReply(NULL, 0, 3));
[email protected]0c5fb722012-02-28 11:50:358367 const char resp[] = "HTTP/1.1 200 OK\r\n"
8368 "Content-Length: 5\r\n\r\n";
8369
bncdf80d44fd2016-07-15 20:27:418370 SpdySerializedFrame wrapped_get_resp(
8371 spdy_util_.ConstructSpdyDataFrame(3, resp, strlen(resp), false));
8372 SpdySerializedFrame wrapped_body(
8373 spdy_util_.ConstructSpdyDataFrame(3, "hello", 5, false));
[email protected]0c5fb722012-02-28 11:50:358374 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:418375 CreateMockRead(conn_auth_resp, 1, ASYNC),
8376 CreateMockRead(conn_resp, 4, ASYNC),
8377 CreateMockRead(wrapped_get_resp, 6, ASYNC),
8378 CreateMockRead(wrapped_body, 7, ASYNC),
rch8e6c6c42015-05-01 14:05:138379 MockRead(ASYNC, OK, 8), // EOF. May or may not be read.
[email protected]0c5fb722012-02-28 11:50:358380 };
8381
rch8e6c6c42015-05-01 14:05:138382 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
8383 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:078384 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]0c5fb722012-02-28 11:50:358385 // Negotiate SPDY to the proxy
8386 SSLSocketDataProvider proxy(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:368387 proxy.next_proto = kProtoHTTP2;
[email protected]bb88e1d32013-05-03 23:11:078388 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy);
[email protected]0c5fb722012-02-28 11:50:358389 // Vanilla SSL to the server
8390 SSLSocketDataProvider server(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:078391 session_deps_.socket_factory->AddSSLSocketDataProvider(&server);
[email protected]0c5fb722012-02-28 11:50:358392
8393 TestCompletionCallback callback1;
8394
bnc87dcefc2017-05-25 12:47:588395 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:198396 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]0c5fb722012-02-28 11:50:358397
8398 int rv = trans->Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:018399 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]0c5fb722012-02-28 11:50:358400
8401 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:018402 EXPECT_THAT(rv, IsOk());
mmenke43758e62015-05-04 21:09:468403 TestNetLogEntry::List entries;
[email protected]0c5fb722012-02-28 11:50:358404 log.GetEntries(&entries);
8405 size_t pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:008406 entries, 0, NetLogEventType::HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
8407 NetLogEventPhase::NONE);
[email protected]0c5fb722012-02-28 11:50:358408 ExpectLogContainsSomewhere(
8409 entries, pos,
mikecirone8b85c432016-09-08 19:11:008410 NetLogEventType::HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
8411 NetLogEventPhase::NONE);
[email protected]0c5fb722012-02-28 11:50:358412
8413 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:528414 ASSERT_TRUE(response);
8415 ASSERT_TRUE(response->headers);
[email protected]0c5fb722012-02-28 11:50:358416 EXPECT_EQ(407, response->headers->response_code());
8417 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
wezca1070932016-05-26 20:30:528418 EXPECT_TRUE(response->auth_challenge);
asanka098c0092016-06-16 20:18:438419 EXPECT_TRUE(CheckBasicSecureProxyAuth(response->auth_challenge.get()));
[email protected]0c5fb722012-02-28 11:50:358420
8421 TestCompletionCallback callback2;
8422
8423 rv = trans->RestartWithAuth(AuthCredentials(kFoo, kBar),
8424 callback2.callback());
robpercival214763f2016-07-01 23:27:018425 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]0c5fb722012-02-28 11:50:358426
8427 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:018428 EXPECT_THAT(rv, IsOk());
[email protected]0c5fb722012-02-28 11:50:358429
8430 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:528431 ASSERT_TRUE(response);
[email protected]0c5fb722012-02-28 11:50:358432
8433 EXPECT_TRUE(response->headers->IsKeepAlive());
8434 EXPECT_EQ(200, response->headers->response_code());
8435 EXPECT_EQ(5, response->headers->GetContentLength());
8436 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
8437
8438 // The password prompt info should not be set.
wezca1070932016-05-26 20:30:528439 EXPECT_FALSE(response->auth_challenge);
[email protected]0c5fb722012-02-28 11:50:358440
[email protected]029c83b62013-01-24 05:28:208441 LoadTimingInfo load_timing_info;
8442 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
8443 TestLoadTimingNotReusedWithPac(load_timing_info,
8444 CONNECT_TIMING_HAS_SSL_TIMES);
8445
[email protected]0c5fb722012-02-28 11:50:358446 trans.reset();
8447 session->CloseAllConnections();
8448}
8449
[email protected]7c6f7ba2012-04-03 04:09:298450// Test that an explicitly trusted SPDY proxy can push a resource from an
8451// origin that is different from that of its associated resource.
bncd16676a2016-07-20 16:23:018452TEST_F(HttpNetworkTransactionTest, CrossOriginSPDYProxyPush) {
tbansal28e68f82016-02-04 02:56:158453 // Configure the proxy delegate to allow cross-origin SPDY pushes.
Jeremy Roman0579ed62017-08-29 15:56:198454 auto proxy_delegate = std::make_unique<TestProxyDelegate>();
tbansal28e68f82016-02-04 02:56:158455 proxy_delegate->set_trusted_spdy_proxy(net::ProxyServer::FromURI(
8456 "https://myproxy:443", net::ProxyServer::SCHEME_HTTP));
[email protected]7c6f7ba2012-04-03 04:09:298457 HttpRequestInfo request;
8458 HttpRequestInfo push_request;
8459
[email protected]7c6f7ba2012-04-03 04:09:298460 request.method = "GET";
bncce36dca22015-04-21 22:11:238461 request.url = GURL("http://www.example.org/");
[email protected]7c6f7ba2012-04-03 04:09:298462 push_request.method = "GET";
8463 push_request.url = GURL("http://www.another-origin.com/foo.dat");
8464
tbansal28e68f82016-02-04 02:56:158465 // Configure against https proxy server "myproxy:443".
rdsmith82957ad2015-09-16 19:42:038466 session_deps_.proxy_service =
tbansal28e68f82016-02-04 02:56:158467 ProxyService::CreateFixedFromPacResult("HTTPS myproxy:443");
vishal.b62985ca92015-04-17 08:45:518468 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:078469 session_deps_.net_log = log.bound().net_log();
[email protected]61b4efc2012-04-27 18:12:508470
inlinechan894515af2016-12-09 02:40:108471 session_deps_.proxy_delegate = std::move(proxy_delegate);
[email protected]61b4efc2012-04-27 18:12:508472
danakj1fd259a02016-04-16 03:17:098473 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]7c6f7ba2012-04-03 04:09:298474
bncdf80d44fd2016-07-15 20:27:418475 SpdySerializedFrame stream1_syn(
bncb26024382016-06-29 02:39:458476 spdy_util_.ConstructSpdyGet("http://www.example.org/", 1, LOWEST));
tombergan5d22c182017-01-11 02:05:358477 SpdySerializedFrame stream2_priority(
8478 spdy_util_.ConstructSpdyPriority(2, 1, IDLE, true));
[email protected]7c6f7ba2012-04-03 04:09:298479
8480 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:418481 CreateMockWrite(stream1_syn, 0, ASYNC),
tombergan5d22c182017-01-11 02:05:358482 CreateMockWrite(stream2_priority, 3, ASYNC),
[email protected]7c6f7ba2012-04-03 04:09:298483 };
8484
bncdf80d44fd2016-07-15 20:27:418485 SpdySerializedFrame stream1_reply(
bnc42331402016-07-25 13:36:158486 spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
[email protected]7c6f7ba2012-04-03 04:09:298487
bncdf80d44fd2016-07-15 20:27:418488 SpdySerializedFrame stream1_body(spdy_util_.ConstructSpdyDataFrame(1, true));
[email protected]7c6f7ba2012-04-03 04:09:298489
bncdf80d44fd2016-07-15 20:27:418490 SpdySerializedFrame stream2_syn(spdy_util_.ConstructSpdyPush(
bncb03b1092016-04-06 11:19:558491 NULL, 0, 2, 1, "http://www.another-origin.com/foo.dat"));
[email protected]8a0fc822013-06-27 20:52:438492 const char kPushedData[] = "pushed";
bncdf80d44fd2016-07-15 20:27:418493 SpdySerializedFrame stream2_body(spdy_util_.ConstructSpdyDataFrame(
8494 2, kPushedData, strlen(kPushedData), true));
[email protected]7c6f7ba2012-04-03 04:09:298495
8496 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:418497 CreateMockRead(stream1_reply, 1, ASYNC),
8498 CreateMockRead(stream2_syn, 2, ASYNC),
tombergan5d22c182017-01-11 02:05:358499 CreateMockRead(stream1_body, 4, ASYNC),
8500 CreateMockRead(stream2_body, 5, ASYNC),
8501 MockRead(SYNCHRONOUS, ERR_IO_PENDING, 6), // Force a hang
[email protected]7c6f7ba2012-04-03 04:09:298502 };
8503
rch8e6c6c42015-05-01 14:05:138504 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
8505 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:078506 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]7c6f7ba2012-04-03 04:09:298507 // Negotiate SPDY to the proxy
8508 SSLSocketDataProvider proxy(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:368509 proxy.next_proto = kProtoHTTP2;
[email protected]bb88e1d32013-05-03 23:11:078510 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy);
[email protected]7c6f7ba2012-04-03 04:09:298511
bnc87dcefc2017-05-25 12:47:588512 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:198513 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]7c6f7ba2012-04-03 04:09:298514 TestCompletionCallback callback;
8515 int rv = trans->Start(&request, callback.callback(), log.bound());
robpercival214763f2016-07-01 23:27:018516 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]7c6f7ba2012-04-03 04:09:298517
8518 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:018519 EXPECT_THAT(rv, IsOk());
[email protected]7c6f7ba2012-04-03 04:09:298520 const HttpResponseInfo* response = trans->GetResponseInfo();
8521
bnc87dcefc2017-05-25 12:47:588522 auto push_trans =
Jeremy Roman0579ed62017-08-29 15:56:198523 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]90499482013-06-01 00:39:508524 rv = push_trans->Start(&push_request, callback.callback(), log.bound());
robpercival214763f2016-07-01 23:27:018525 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]7c6f7ba2012-04-03 04:09:298526
8527 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:018528 EXPECT_THAT(rv, IsOk());
[email protected]7c6f7ba2012-04-03 04:09:298529 const HttpResponseInfo* push_response = push_trans->GetResponseInfo();
8530
wezca1070932016-05-26 20:30:528531 ASSERT_TRUE(response);
[email protected]7c6f7ba2012-04-03 04:09:298532 EXPECT_TRUE(response->headers->IsKeepAlive());
8533
8534 EXPECT_EQ(200, response->headers->response_code());
8535 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
8536
8537 std::string response_data;
8538 rv = ReadTransaction(trans.get(), &response_data);
robpercival214763f2016-07-01 23:27:018539 EXPECT_THAT(rv, IsOk());
[email protected]7c6f7ba2012-04-03 04:09:298540 EXPECT_EQ("hello!", response_data);
8541
[email protected]029c83b62013-01-24 05:28:208542 LoadTimingInfo load_timing_info;
8543 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
8544 TestLoadTimingNotReusedWithPac(load_timing_info,
8545 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
8546
[email protected]7c6f7ba2012-04-03 04:09:298547 // Verify the pushed stream.
wezca1070932016-05-26 20:30:528548 EXPECT_TRUE(push_response->headers);
[email protected]7c6f7ba2012-04-03 04:09:298549 EXPECT_EQ(200, push_response->headers->response_code());
8550
8551 rv = ReadTransaction(push_trans.get(), &response_data);
robpercival214763f2016-07-01 23:27:018552 EXPECT_THAT(rv, IsOk());
[email protected]7c6f7ba2012-04-03 04:09:298553 EXPECT_EQ("pushed", response_data);
8554
[email protected]029c83b62013-01-24 05:28:208555 LoadTimingInfo push_load_timing_info;
8556 EXPECT_TRUE(push_trans->GetLoadTimingInfo(&push_load_timing_info));
8557 TestLoadTimingReusedWithPac(push_load_timing_info);
8558 // The transactions should share a socket ID, despite being for different
8559 // origins.
8560 EXPECT_EQ(load_timing_info.socket_log_id,
8561 push_load_timing_info.socket_log_id);
8562
[email protected]7c6f7ba2012-04-03 04:09:298563 trans.reset();
8564 push_trans.reset();
8565 session->CloseAllConnections();
8566}
8567
[email protected]8c843192012-04-05 07:15:008568// Test that an explicitly trusted SPDY proxy cannot push HTTPS content.
bncd16676a2016-07-20 16:23:018569TEST_F(HttpNetworkTransactionTest, CrossOriginProxyPushCorrectness) {
tbansal28e68f82016-02-04 02:56:158570 // Configure the proxy delegate to allow cross-origin SPDY pushes.
Jeremy Roman0579ed62017-08-29 15:56:198571 auto proxy_delegate = std::make_unique<TestProxyDelegate>();
tbansal28e68f82016-02-04 02:56:158572 proxy_delegate->set_trusted_spdy_proxy(net::ProxyServer::FromURI(
8573 "https://myproxy:443", net::ProxyServer::SCHEME_HTTP));
[email protected]8c843192012-04-05 07:15:008574 HttpRequestInfo request;
8575
8576 request.method = "GET";
bncce36dca22015-04-21 22:11:238577 request.url = GURL("http://www.example.org/");
[email protected]8c843192012-04-05 07:15:008578
tbansal28e68f82016-02-04 02:56:158579 session_deps_.proxy_service =
8580 ProxyService::CreateFixed("https://myproxy:443");
vishal.b62985ca92015-04-17 08:45:518581 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:078582 session_deps_.net_log = log.bound().net_log();
[email protected]61b4efc2012-04-27 18:12:508583
8584 // Enable cross-origin push.
inlinechan894515af2016-12-09 02:40:108585 session_deps_.proxy_delegate = std::move(proxy_delegate);
[email protected]61b4efc2012-04-27 18:12:508586
danakj1fd259a02016-04-16 03:17:098587 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]8c843192012-04-05 07:15:008588
bncdf80d44fd2016-07-15 20:27:418589 SpdySerializedFrame stream1_syn(
bncb26024382016-06-29 02:39:458590 spdy_util_.ConstructSpdyGet("http://www.example.org/", 1, LOWEST));
[email protected]8c843192012-04-05 07:15:008591
bncdf80d44fd2016-07-15 20:27:418592 SpdySerializedFrame push_rst(
diannahu9904e272017-02-03 14:40:088593 spdy_util_.ConstructSpdyRstStream(2, ERROR_CODE_REFUSED_STREAM));
[email protected]8c843192012-04-05 07:15:008594
8595 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:418596 CreateMockWrite(stream1_syn, 0, ASYNC), CreateMockWrite(push_rst, 3),
[email protected]8c843192012-04-05 07:15:008597 };
8598
bncdf80d44fd2016-07-15 20:27:418599 SpdySerializedFrame stream1_reply(
bnc42331402016-07-25 13:36:158600 spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
[email protected]8c843192012-04-05 07:15:008601
bncdf80d44fd2016-07-15 20:27:418602 SpdySerializedFrame stream1_body(spdy_util_.ConstructSpdyDataFrame(1, true));
[email protected]8c843192012-04-05 07:15:008603
bncdf80d44fd2016-07-15 20:27:418604 SpdySerializedFrame stream2_syn(spdy_util_.ConstructSpdyPush(
bncb03b1092016-04-06 11:19:558605 NULL, 0, 2, 1, "https://www.another-origin.com/foo.dat"));
[email protected]8c843192012-04-05 07:15:008606
8607 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:418608 CreateMockRead(stream1_reply, 1, ASYNC),
8609 CreateMockRead(stream2_syn, 2, ASYNC),
8610 CreateMockRead(stream1_body, 4, ASYNC),
mmenkee24011922015-12-17 22:12:598611 MockRead(SYNCHRONOUS, ERR_IO_PENDING, 5), // Force a hang
[email protected]8c843192012-04-05 07:15:008612 };
8613
rch8e6c6c42015-05-01 14:05:138614 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
8615 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:078616 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]8c843192012-04-05 07:15:008617 // Negotiate SPDY to the proxy
8618 SSLSocketDataProvider proxy(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:368619 proxy.next_proto = kProtoHTTP2;
[email protected]bb88e1d32013-05-03 23:11:078620 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy);
[email protected]8c843192012-04-05 07:15:008621
bnc87dcefc2017-05-25 12:47:588622 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:198623 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]8c843192012-04-05 07:15:008624 TestCompletionCallback callback;
8625 int rv = trans->Start(&request, callback.callback(), log.bound());
robpercival214763f2016-07-01 23:27:018626 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]8c843192012-04-05 07:15:008627
8628 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:018629 EXPECT_THAT(rv, IsOk());
[email protected]8c843192012-04-05 07:15:008630 const HttpResponseInfo* response = trans->GetResponseInfo();
8631
wezca1070932016-05-26 20:30:528632 ASSERT_TRUE(response);
[email protected]8c843192012-04-05 07:15:008633 EXPECT_TRUE(response->headers->IsKeepAlive());
8634
8635 EXPECT_EQ(200, response->headers->response_code());
8636 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
8637
8638 std::string response_data;
8639 rv = ReadTransaction(trans.get(), &response_data);
robpercival214763f2016-07-01 23:27:018640 EXPECT_THAT(rv, IsOk());
[email protected]8c843192012-04-05 07:15:008641 EXPECT_EQ("hello!", response_data);
8642
8643 trans.reset();
8644 session->CloseAllConnections();
8645}
8646
tbansal8ef1d3e2016-02-03 04:05:428647// Test that an explicitly trusted SPDY proxy can push same-origin HTTPS
8648// resources.
bncd16676a2016-07-20 16:23:018649TEST_F(HttpNetworkTransactionTest, SameOriginProxyPushCorrectness) {
tbansal28e68f82016-02-04 02:56:158650 // Configure the proxy delegate to allow cross-origin SPDY pushes.
Jeremy Roman0579ed62017-08-29 15:56:198651 auto proxy_delegate = std::make_unique<TestProxyDelegate>();
tbansal28e68f82016-02-04 02:56:158652 proxy_delegate->set_trusted_spdy_proxy(
8653 net::ProxyServer::FromURI("myproxy:70", net::ProxyServer::SCHEME_HTTP));
8654
tbansal8ef1d3e2016-02-03 04:05:428655 HttpRequestInfo request;
8656
8657 request.method = "GET";
8658 request.url = GURL("http://www.example.org/");
8659
8660 // Configure against https proxy server "myproxy:70".
8661 session_deps_.proxy_service = ProxyService::CreateFixed("https://myproxy:70");
8662 BoundTestNetLog log;
8663 session_deps_.net_log = log.bound().net_log();
8664
8665 // Enable cross-origin push.
inlinechan894515af2016-12-09 02:40:108666 session_deps_.proxy_delegate = std::move(proxy_delegate);
tbansal8ef1d3e2016-02-03 04:05:428667
danakj1fd259a02016-04-16 03:17:098668 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
tbansal8ef1d3e2016-02-03 04:05:428669
bncdf80d44fd2016-07-15 20:27:418670 SpdySerializedFrame stream1_syn(
bncb26024382016-06-29 02:39:458671 spdy_util_.ConstructSpdyGet("http://www.example.org/", 1, LOWEST));
tombergan5d22c182017-01-11 02:05:358672 SpdySerializedFrame stream2_priority(
8673 spdy_util_.ConstructSpdyPriority(2, 1, IDLE, true));
tbansal8ef1d3e2016-02-03 04:05:428674
8675 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:418676 CreateMockWrite(stream1_syn, 0, ASYNC),
tombergan5d22c182017-01-11 02:05:358677 CreateMockWrite(stream2_priority, 3, ASYNC),
tbansal8ef1d3e2016-02-03 04:05:428678 };
8679
bncdf80d44fd2016-07-15 20:27:418680 SpdySerializedFrame stream1_reply(
bnc42331402016-07-25 13:36:158681 spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
tbansal8ef1d3e2016-02-03 04:05:428682
bncdf80d44fd2016-07-15 20:27:418683 SpdySerializedFrame stream2_syn(spdy_util_.ConstructSpdyPush(
Bence Béky096cf052017-08-08 23:55:338684 nullptr, 0, 2, 1, "http://www.example.org/foo.dat"));
bnc38dcd392016-02-09 23:19:498685
bncdf80d44fd2016-07-15 20:27:418686 SpdySerializedFrame stream1_body(spdy_util_.ConstructSpdyDataFrame(1, true));
tbansal8ef1d3e2016-02-03 04:05:428687
bncdf80d44fd2016-07-15 20:27:418688 SpdySerializedFrame stream2_reply(
bnc42331402016-07-25 13:36:158689 spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
tbansal8ef1d3e2016-02-03 04:05:428690
bncdf80d44fd2016-07-15 20:27:418691 SpdySerializedFrame stream2_body(spdy_util_.ConstructSpdyDataFrame(1, true));
tbansal8ef1d3e2016-02-03 04:05:428692
8693 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:418694 CreateMockRead(stream1_reply, 1, ASYNC),
8695 CreateMockRead(stream2_syn, 2, ASYNC),
tombergan5d22c182017-01-11 02:05:358696 CreateMockRead(stream1_body, 4, ASYNC),
8697 CreateMockRead(stream2_body, 5, ASYNC),
8698 MockRead(SYNCHRONOUS, ERR_IO_PENDING, 6), // Force a hang
tbansal8ef1d3e2016-02-03 04:05:428699 };
8700
8701 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
8702 arraysize(spdy_writes));
8703 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
8704 // Negotiate SPDY to the proxy
8705 SSLSocketDataProvider proxy(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:368706 proxy.next_proto = kProtoHTTP2;
tbansal8ef1d3e2016-02-03 04:05:428707 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy);
8708
bnc87dcefc2017-05-25 12:47:588709 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:198710 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
tbansal8ef1d3e2016-02-03 04:05:428711 TestCompletionCallback callback;
8712 int rv = trans->Start(&request, callback.callback(), log.bound());
robpercival214763f2016-07-01 23:27:018713 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
tbansal8ef1d3e2016-02-03 04:05:428714
8715 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:018716 EXPECT_THAT(rv, IsOk());
tbansal8ef1d3e2016-02-03 04:05:428717 const HttpResponseInfo* response = trans->GetResponseInfo();
8718
wezca1070932016-05-26 20:30:528719 ASSERT_TRUE(response);
tbansal8ef1d3e2016-02-03 04:05:428720 EXPECT_TRUE(response->headers->IsKeepAlive());
8721
8722 EXPECT_EQ(200, response->headers->response_code());
8723 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
8724
8725 std::string response_data;
8726 rv = ReadTransaction(trans.get(), &response_data);
robpercival214763f2016-07-01 23:27:018727 EXPECT_THAT(rv, IsOk());
tbansal8ef1d3e2016-02-03 04:05:428728 EXPECT_EQ("hello!", response_data);
8729
8730 trans.reset();
8731 session->CloseAllConnections();
8732}
8733
[email protected]2df19bb2010-08-25 20:13:468734// Test HTTPS connections to a site with a bad certificate, going through an
8735// HTTPS proxy
bncd16676a2016-07-20 16:23:018736TEST_F(HttpNetworkTransactionTest, HTTPSBadCertificateViaHttpsProxy) {
rdsmith82957ad2015-09-16 19:42:038737 session_deps_.proxy_service = ProxyService::CreateFixed("https://proxy:70");
[email protected]2df19bb2010-08-25 20:13:468738
8739 HttpRequestInfo request;
8740 request.method = "GET";
bncce36dca22015-04-21 22:11:238741 request.url = GURL("https://www.example.org/");
[email protected]2df19bb2010-08-25 20:13:468742
8743 // Attempt to fetch the URL from a server with a bad cert
8744 MockWrite bad_cert_writes[] = {
rsleevidb16bb02015-11-12 23:47:178745 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
8746 "Host: www.example.org:443\r\n"
8747 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]2df19bb2010-08-25 20:13:468748 };
8749
8750 MockRead bad_cert_reads[] = {
8751 MockRead("HTTP/1.0 200 Connected\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:068752 MockRead(SYNCHRONOUS, OK)
[email protected]2df19bb2010-08-25 20:13:468753 };
8754
8755 // Attempt to fetch the URL with a good cert
8756 MockWrite good_data_writes[] = {
rsleevidb16bb02015-11-12 23:47:178757 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
8758 "Host: www.example.org:443\r\n"
8759 "Proxy-Connection: keep-alive\r\n\r\n"),
8760 MockWrite("GET / HTTP/1.1\r\n"
8761 "Host: www.example.org\r\n"
8762 "Connection: keep-alive\r\n\r\n"),
[email protected]2df19bb2010-08-25 20:13:468763 };
8764
8765 MockRead good_cert_reads[] = {
8766 MockRead("HTTP/1.0 200 Connected\r\n\r\n"),
8767 MockRead("HTTP/1.0 200 OK\r\n"),
8768 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
8769 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:068770 MockRead(SYNCHRONOUS, OK),
[email protected]2df19bb2010-08-25 20:13:468771 };
8772
8773 StaticSocketDataProvider ssl_bad_certificate(
8774 bad_cert_reads, arraysize(bad_cert_reads),
8775 bad_cert_writes, arraysize(bad_cert_writes));
8776 StaticSocketDataProvider data(good_cert_reads, arraysize(good_cert_reads),
8777 good_data_writes, arraysize(good_data_writes));
[email protected]8ddf8322012-02-23 18:08:068778 SSLSocketDataProvider ssl_bad(ASYNC, ERR_CERT_AUTHORITY_INVALID);
8779 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]2df19bb2010-08-25 20:13:468780
8781 // SSL to the proxy, then CONNECT request, then SSL with bad certificate
[email protected]bb88e1d32013-05-03 23:11:078782 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
8783 session_deps_.socket_factory->AddSocketDataProvider(&ssl_bad_certificate);
8784 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_bad);
[email protected]2df19bb2010-08-25 20:13:468785
8786 // SSL to the proxy, then CONNECT request, then valid SSL certificate
[email protected]bb88e1d32013-05-03 23:11:078787 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
8788 session_deps_.socket_factory->AddSocketDataProvider(&data);
8789 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]2df19bb2010-08-25 20:13:468790
[email protected]49639fa2011-12-20 23:22:418791 TestCompletionCallback callback;
[email protected]2df19bb2010-08-25 20:13:468792
danakj1fd259a02016-04-16 03:17:098793 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:168794 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]2df19bb2010-08-25 20:13:468795
tfarina42834112016-09-22 13:38:208796 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:018797 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2df19bb2010-08-25 20:13:468798
8799 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:018800 EXPECT_THAT(rv, IsError(ERR_CERT_AUTHORITY_INVALID));
[email protected]2df19bb2010-08-25 20:13:468801
bnc691fda62016-08-12 00:43:168802 rv = trans.RestartIgnoringLastError(callback.callback());
robpercival214763f2016-07-01 23:27:018803 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2df19bb2010-08-25 20:13:468804
8805 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:018806 EXPECT_THAT(rv, IsOk());
[email protected]2df19bb2010-08-25 20:13:468807
bnc691fda62016-08-12 00:43:168808 const HttpResponseInfo* response = trans.GetResponseInfo();
[email protected]2df19bb2010-08-25 20:13:468809
wezca1070932016-05-26 20:30:528810 ASSERT_TRUE(response);
[email protected]2df19bb2010-08-25 20:13:468811 EXPECT_EQ(100, response->headers->GetContentLength());
8812}
8813
bncd16676a2016-07-20 16:23:018814TEST_F(HttpNetworkTransactionTest, BuildRequest_UserAgent) {
[email protected]1c773ea12009-04-28 19:58:428815 HttpRequestInfo request;
8816 request.method = "GET";
bncce36dca22015-04-21 22:11:238817 request.url = GURL("http://www.example.org/");
[email protected]8c76ae22010-04-20 22:15:438818 request.extra_headers.SetHeader(HttpRequestHeaders::kUserAgent,
8819 "Chromium Ultra Awesome X Edition");
[email protected]1c773ea12009-04-28 19:58:428820
danakj1fd259a02016-04-16 03:17:098821 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:168822 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:278823
[email protected]1c773ea12009-04-28 19:58:428824 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:238825 MockWrite(
8826 "GET / HTTP/1.1\r\n"
8827 "Host: www.example.org\r\n"
8828 "Connection: keep-alive\r\n"
8829 "User-Agent: Chromium Ultra Awesome X Edition\r\n\r\n"),
[email protected]1c773ea12009-04-28 19:58:428830 };
8831
8832 // Lastly, the server responds with the actual content.
8833 MockRead data_reads[] = {
8834 MockRead("HTTP/1.0 200 OK\r\n"),
8835 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
8836 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:068837 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:428838 };
8839
[email protected]31a2bfe2010-02-09 08:03:398840 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
8841 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:078842 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:428843
[email protected]49639fa2011-12-20 23:22:418844 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:428845
tfarina42834112016-09-22 13:38:208846 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:018847 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]1c773ea12009-04-28 19:58:428848
8849 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:018850 EXPECT_THAT(rv, IsOk());
[email protected]1c773ea12009-04-28 19:58:428851}
8852
bncd16676a2016-07-20 16:23:018853TEST_F(HttpNetworkTransactionTest, BuildRequest_UserAgentOverTunnel) {
[email protected]da81f132010-08-18 23:39:298854 HttpRequestInfo request;
8855 request.method = "GET";
bncce36dca22015-04-21 22:11:238856 request.url = GURL("https://www.example.org/");
[email protected]da81f132010-08-18 23:39:298857 request.extra_headers.SetHeader(HttpRequestHeaders::kUserAgent,
8858 "Chromium Ultra Awesome X Edition");
8859
rdsmith82957ad2015-09-16 19:42:038860 session_deps_.proxy_service = ProxyService::CreateFixed("myproxy:70");
danakj1fd259a02016-04-16 03:17:098861 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:168862 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:278863
[email protected]da81f132010-08-18 23:39:298864 MockWrite data_writes[] = {
rsleevidb16bb02015-11-12 23:47:178865 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
8866 "Host: www.example.org:443\r\n"
8867 "Proxy-Connection: keep-alive\r\n"
8868 "User-Agent: Chromium Ultra Awesome X Edition\r\n\r\n"),
[email protected]da81f132010-08-18 23:39:298869 };
8870 MockRead data_reads[] = {
8871 // Return an error, so the transaction stops here (this test isn't
8872 // interested in the rest).
8873 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
8874 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
8875 MockRead("Proxy-Connection: close\r\n\r\n"),
8876 };
8877
8878 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
8879 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:078880 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]da81f132010-08-18 23:39:298881
[email protected]49639fa2011-12-20 23:22:418882 TestCompletionCallback callback;
[email protected]da81f132010-08-18 23:39:298883
tfarina42834112016-09-22 13:38:208884 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:018885 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]da81f132010-08-18 23:39:298886
8887 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:018888 EXPECT_THAT(rv, IsOk());
[email protected]da81f132010-08-18 23:39:298889}
8890
bncd16676a2016-07-20 16:23:018891TEST_F(HttpNetworkTransactionTest, BuildRequest_Referer) {
[email protected]1c773ea12009-04-28 19:58:428892 HttpRequestInfo request;
8893 request.method = "GET";
bncce36dca22015-04-21 22:11:238894 request.url = GURL("http://www.example.org/");
[email protected]c10450102011-06-27 09:06:168895 request.extra_headers.SetHeader(HttpRequestHeaders::kReferer,
8896 "http://the.previous.site.com/");
[email protected]1c773ea12009-04-28 19:58:428897
danakj1fd259a02016-04-16 03:17:098898 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:168899 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:278900
[email protected]1c773ea12009-04-28 19:58:428901 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:238902 MockWrite(
8903 "GET / HTTP/1.1\r\n"
8904 "Host: www.example.org\r\n"
8905 "Connection: keep-alive\r\n"
8906 "Referer: http://the.previous.site.com/\r\n\r\n"),
[email protected]1c773ea12009-04-28 19:58:428907 };
8908
8909 // Lastly, the server responds with the actual content.
8910 MockRead data_reads[] = {
8911 MockRead("HTTP/1.0 200 OK\r\n"),
8912 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
8913 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:068914 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:428915 };
8916
[email protected]31a2bfe2010-02-09 08:03:398917 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
8918 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:078919 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:428920
[email protected]49639fa2011-12-20 23:22:418921 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:428922
tfarina42834112016-09-22 13:38:208923 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:018924 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]1c773ea12009-04-28 19:58:428925
8926 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:018927 EXPECT_THAT(rv, IsOk());
[email protected]1c773ea12009-04-28 19:58:428928}
8929
bncd16676a2016-07-20 16:23:018930TEST_F(HttpNetworkTransactionTest, BuildRequest_PostContentLengthZero) {
[email protected]1c773ea12009-04-28 19:58:428931 HttpRequestInfo request;
8932 request.method = "POST";
bncce36dca22015-04-21 22:11:238933 request.url = GURL("http://www.example.org/");
[email protected]1c773ea12009-04-28 19:58:428934
danakj1fd259a02016-04-16 03:17:098935 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:168936 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:278937
[email protected]1c773ea12009-04-28 19:58:428938 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:238939 MockWrite(
8940 "POST / HTTP/1.1\r\n"
8941 "Host: www.example.org\r\n"
8942 "Connection: keep-alive\r\n"
8943 "Content-Length: 0\r\n\r\n"),
[email protected]1c773ea12009-04-28 19:58:428944 };
8945
8946 // Lastly, the server responds with the actual content.
8947 MockRead data_reads[] = {
8948 MockRead("HTTP/1.0 200 OK\r\n"),
8949 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
8950 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:068951 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:428952 };
8953
[email protected]31a2bfe2010-02-09 08:03:398954 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
8955 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:078956 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:428957
[email protected]49639fa2011-12-20 23:22:418958 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:428959
tfarina42834112016-09-22 13:38:208960 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:018961 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]1c773ea12009-04-28 19:58:428962
8963 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:018964 EXPECT_THAT(rv, IsOk());
[email protected]1c773ea12009-04-28 19:58:428965}
8966
bncd16676a2016-07-20 16:23:018967TEST_F(HttpNetworkTransactionTest, BuildRequest_PutContentLengthZero) {
[email protected]1c773ea12009-04-28 19:58:428968 HttpRequestInfo request;
8969 request.method = "PUT";
bncce36dca22015-04-21 22:11:238970 request.url = GURL("http://www.example.org/");
[email protected]1c773ea12009-04-28 19:58:428971
danakj1fd259a02016-04-16 03:17:098972 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:168973 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:278974
[email protected]1c773ea12009-04-28 19:58:428975 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:238976 MockWrite(
8977 "PUT / HTTP/1.1\r\n"
8978 "Host: www.example.org\r\n"
8979 "Connection: keep-alive\r\n"
8980 "Content-Length: 0\r\n\r\n"),
[email protected]1c773ea12009-04-28 19:58:428981 };
8982
8983 // Lastly, the server responds with the actual content.
8984 MockRead data_reads[] = {
8985 MockRead("HTTP/1.0 200 OK\r\n"),
8986 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
8987 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:068988 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:428989 };
8990
[email protected]31a2bfe2010-02-09 08:03:398991 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
8992 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:078993 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:428994
[email protected]49639fa2011-12-20 23:22:418995 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:428996
tfarina42834112016-09-22 13:38:208997 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:018998 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]1c773ea12009-04-28 19:58:428999
9000 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:019001 EXPECT_THAT(rv, IsOk());
[email protected]1c773ea12009-04-28 19:58:429002}
9003
bncd16676a2016-07-20 16:23:019004TEST_F(HttpNetworkTransactionTest, BuildRequest_HeadContentLengthZero) {
[email protected]1c773ea12009-04-28 19:58:429005 HttpRequestInfo request;
9006 request.method = "HEAD";
bncce36dca22015-04-21 22:11:239007 request.url = GURL("http://www.example.org/");
[email protected]1c773ea12009-04-28 19:58:429008
danakj1fd259a02016-04-16 03:17:099009 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:169010 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:279011
[email protected]1c773ea12009-04-28 19:58:429012 MockWrite data_writes[] = {
csharrisonf473dd192015-08-18 13:54:139013 MockWrite("HEAD / HTTP/1.1\r\n"
9014 "Host: www.example.org\r\n"
9015 "Connection: keep-alive\r\n\r\n"),
[email protected]1c773ea12009-04-28 19:58:429016 };
9017
9018 // Lastly, the server responds with the actual content.
9019 MockRead data_reads[] = {
9020 MockRead("HTTP/1.0 200 OK\r\n"),
9021 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
9022 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:069023 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:429024 };
9025
[email protected]31a2bfe2010-02-09 08:03:399026 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
9027 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:079028 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:429029
[email protected]49639fa2011-12-20 23:22:419030 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:429031
tfarina42834112016-09-22 13:38:209032 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:019033 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]1c773ea12009-04-28 19:58:429034
9035 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:019036 EXPECT_THAT(rv, IsOk());
[email protected]1c773ea12009-04-28 19:58:429037}
9038
bncd16676a2016-07-20 16:23:019039TEST_F(HttpNetworkTransactionTest, BuildRequest_CacheControlNoCache) {
[email protected]1c773ea12009-04-28 19:58:429040 HttpRequestInfo request;
9041 request.method = "GET";
bncce36dca22015-04-21 22:11:239042 request.url = GURL("http://www.example.org/");
[email protected]1c773ea12009-04-28 19:58:429043 request.load_flags = LOAD_BYPASS_CACHE;
9044
danakj1fd259a02016-04-16 03:17:099045 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:169046 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:279047
[email protected]1c773ea12009-04-28 19:58:429048 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:239049 MockWrite(
9050 "GET / HTTP/1.1\r\n"
9051 "Host: www.example.org\r\n"
9052 "Connection: keep-alive\r\n"
9053 "Pragma: no-cache\r\n"
9054 "Cache-Control: no-cache\r\n\r\n"),
[email protected]1c773ea12009-04-28 19:58:429055 };
9056
9057 // Lastly, the server responds with the actual content.
9058 MockRead data_reads[] = {
9059 MockRead("HTTP/1.0 200 OK\r\n"),
9060 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
9061 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:069062 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:429063 };
9064
[email protected]31a2bfe2010-02-09 08:03:399065 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
9066 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:079067 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:429068
[email protected]49639fa2011-12-20 23:22:419069 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:429070
tfarina42834112016-09-22 13:38:209071 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:019072 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]1c773ea12009-04-28 19:58:429073
9074 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:019075 EXPECT_THAT(rv, IsOk());
[email protected]1c773ea12009-04-28 19:58:429076}
9077
bncd16676a2016-07-20 16:23:019078TEST_F(HttpNetworkTransactionTest, BuildRequest_CacheControlValidateCache) {
[email protected]1c773ea12009-04-28 19:58:429079 HttpRequestInfo request;
9080 request.method = "GET";
bncce36dca22015-04-21 22:11:239081 request.url = GURL("http://www.example.org/");
[email protected]1c773ea12009-04-28 19:58:429082 request.load_flags = LOAD_VALIDATE_CACHE;
9083
danakj1fd259a02016-04-16 03:17:099084 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:169085 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:279086
[email protected]1c773ea12009-04-28 19:58:429087 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:239088 MockWrite(
9089 "GET / HTTP/1.1\r\n"
9090 "Host: www.example.org\r\n"
9091 "Connection: keep-alive\r\n"
9092 "Cache-Control: max-age=0\r\n\r\n"),
[email protected]1c773ea12009-04-28 19:58:429093 };
9094
9095 // Lastly, the server responds with the actual content.
9096 MockRead data_reads[] = {
9097 MockRead("HTTP/1.0 200 OK\r\n"),
9098 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
9099 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:069100 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:429101 };
9102
[email protected]31a2bfe2010-02-09 08:03:399103 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
9104 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:079105 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:429106
[email protected]49639fa2011-12-20 23:22:419107 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:429108
tfarina42834112016-09-22 13:38:209109 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:019110 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]1c773ea12009-04-28 19:58:429111
9112 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:019113 EXPECT_THAT(rv, IsOk());
[email protected]1c773ea12009-04-28 19:58:429114}
9115
bncd16676a2016-07-20 16:23:019116TEST_F(HttpNetworkTransactionTest, BuildRequest_ExtraHeaders) {
[email protected]1c773ea12009-04-28 19:58:429117 HttpRequestInfo request;
9118 request.method = "GET";
bncce36dca22015-04-21 22:11:239119 request.url = GURL("http://www.example.org/");
[email protected]8c76ae22010-04-20 22:15:439120 request.extra_headers.SetHeader("FooHeader", "Bar");
[email protected]1c773ea12009-04-28 19:58:429121
danakj1fd259a02016-04-16 03:17:099122 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:169123 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:279124
[email protected]1c773ea12009-04-28 19:58:429125 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:239126 MockWrite(
9127 "GET / HTTP/1.1\r\n"
9128 "Host: www.example.org\r\n"
9129 "Connection: keep-alive\r\n"
9130 "FooHeader: Bar\r\n\r\n"),
[email protected]1c773ea12009-04-28 19:58:429131 };
9132
9133 // Lastly, the server responds with the actual content.
9134 MockRead data_reads[] = {
9135 MockRead("HTTP/1.0 200 OK\r\n"),
9136 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
9137 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:069138 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:429139 };
9140
[email protected]31a2bfe2010-02-09 08:03:399141 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
9142 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:079143 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:429144
[email protected]49639fa2011-12-20 23:22:419145 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:429146
tfarina42834112016-09-22 13:38:209147 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:019148 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]1c773ea12009-04-28 19:58:429149
9150 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:019151 EXPECT_THAT(rv, IsOk());
[email protected]1c773ea12009-04-28 19:58:429152}
9153
bncd16676a2016-07-20 16:23:019154TEST_F(HttpNetworkTransactionTest, BuildRequest_ExtraHeadersStripped) {
[email protected]270c6412010-03-29 22:02:479155 HttpRequestInfo request;
9156 request.method = "GET";
bncce36dca22015-04-21 22:11:239157 request.url = GURL("http://www.example.org/");
[email protected]8c76ae22010-04-20 22:15:439158 request.extra_headers.SetHeader("referer", "www.foo.com");
9159 request.extra_headers.SetHeader("hEllo", "Kitty");
9160 request.extra_headers.SetHeader("FoO", "bar");
[email protected]270c6412010-03-29 22:02:479161
danakj1fd259a02016-04-16 03:17:099162 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:169163 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:279164
[email protected]270c6412010-03-29 22:02:479165 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:239166 MockWrite(
9167 "GET / HTTP/1.1\r\n"
9168 "Host: www.example.org\r\n"
9169 "Connection: keep-alive\r\n"
9170 "referer: www.foo.com\r\n"
9171 "hEllo: Kitty\r\n"
9172 "FoO: bar\r\n\r\n"),
[email protected]270c6412010-03-29 22:02:479173 };
9174
9175 // Lastly, the server responds with the actual content.
9176 MockRead data_reads[] = {
9177 MockRead("HTTP/1.0 200 OK\r\n"),
9178 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
9179 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:069180 MockRead(SYNCHRONOUS, OK),
[email protected]270c6412010-03-29 22:02:479181 };
9182
9183 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
9184 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:079185 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]270c6412010-03-29 22:02:479186
[email protected]49639fa2011-12-20 23:22:419187 TestCompletionCallback callback;
[email protected]270c6412010-03-29 22:02:479188
tfarina42834112016-09-22 13:38:209189 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:019190 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]270c6412010-03-29 22:02:479191
9192 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:019193 EXPECT_THAT(rv, IsOk());
[email protected]270c6412010-03-29 22:02:479194}
9195
bncd16676a2016-07-20 16:23:019196TEST_F(HttpNetworkTransactionTest, SOCKS4_HTTP_GET) {
[email protected]cb9bf6ca2011-01-28 13:15:279197 HttpRequestInfo request;
9198 request.method = "GET";
bncce36dca22015-04-21 22:11:239199 request.url = GURL("http://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:279200
rdsmith82957ad2015-09-16 19:42:039201 session_deps_.proxy_service =
9202 ProxyService::CreateFixedFromPacResult("SOCKS myproxy:1080");
vishal.b62985ca92015-04-17 08:45:519203 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:079204 session_deps_.net_log = &net_log;
[email protected]3cd17242009-06-23 02:59:029205
danakj1fd259a02016-04-16 03:17:099206 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:169207 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]3cd17242009-06-23 02:59:029208
[email protected]3cd17242009-06-23 02:59:029209 char write_buffer[] = { 0x04, 0x01, 0x00, 0x50, 127, 0, 0, 1, 0 };
9210 char read_buffer[] = { 0x00, 0x5A, 0x00, 0x00, 0, 0, 0, 0 };
9211
9212 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:239213 MockWrite(ASYNC, write_buffer, arraysize(write_buffer)),
9214 MockWrite(
9215 "GET / HTTP/1.1\r\n"
9216 "Host: www.example.org\r\n"
9217 "Connection: keep-alive\r\n\r\n")};
[email protected]3cd17242009-06-23 02:59:029218
9219 MockRead data_reads[] = {
[email protected]8ddf8322012-02-23 18:08:069220 MockRead(ASYNC, read_buffer, arraysize(read_buffer)),
[email protected]3cd17242009-06-23 02:59:029221 MockRead("HTTP/1.0 200 OK\r\n"),
9222 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n\r\n"),
9223 MockRead("Payload"),
[email protected]8ddf8322012-02-23 18:08:069224 MockRead(SYNCHRONOUS, OK)
[email protected]3cd17242009-06-23 02:59:029225 };
9226
[email protected]31a2bfe2010-02-09 08:03:399227 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
9228 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:079229 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]3cd17242009-06-23 02:59:029230
[email protected]49639fa2011-12-20 23:22:419231 TestCompletionCallback callback;
[email protected]3cd17242009-06-23 02:59:029232
tfarina42834112016-09-22 13:38:209233 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:019234 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]3cd17242009-06-23 02:59:029235
9236 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:019237 EXPECT_THAT(rv, IsOk());
[email protected]3cd17242009-06-23 02:59:029238
bnc691fda62016-08-12 00:43:169239 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:529240 ASSERT_TRUE(response);
[email protected]3cd17242009-06-23 02:59:029241
tbansal2ecbbc72016-10-06 17:15:479242 EXPECT_EQ(ProxyServer::SCHEME_SOCKS4, response->proxy_server.scheme());
[email protected]029c83b62013-01-24 05:28:209243 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:169244 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]029c83b62013-01-24 05:28:209245 TestLoadTimingNotReusedWithPac(load_timing_info,
9246 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
9247
[email protected]3cd17242009-06-23 02:59:029248 std::string response_text;
bnc691fda62016-08-12 00:43:169249 rv = ReadTransaction(&trans, &response_text);
robpercival214763f2016-07-01 23:27:019250 EXPECT_THAT(rv, IsOk());
[email protected]3cd17242009-06-23 02:59:029251 EXPECT_EQ("Payload", response_text);
9252}
9253
bncd16676a2016-07-20 16:23:019254TEST_F(HttpNetworkTransactionTest, SOCKS4_SSL_GET) {
[email protected]cb9bf6ca2011-01-28 13:15:279255 HttpRequestInfo request;
9256 request.method = "GET";
bncce36dca22015-04-21 22:11:239257 request.url = GURL("https://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:279258
rdsmith82957ad2015-09-16 19:42:039259 session_deps_.proxy_service =
9260 ProxyService::CreateFixedFromPacResult("SOCKS myproxy:1080");
vishal.b62985ca92015-04-17 08:45:519261 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:079262 session_deps_.net_log = &net_log;
[email protected]3cd17242009-06-23 02:59:029263
danakj1fd259a02016-04-16 03:17:099264 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:169265 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]3cd17242009-06-23 02:59:029266
[email protected]3cd17242009-06-23 02:59:029267 unsigned char write_buffer[] = { 0x04, 0x01, 0x01, 0xBB, 127, 0, 0, 1, 0 };
9268 unsigned char read_buffer[] = { 0x00, 0x5A, 0x00, 0x00, 0, 0, 0, 0 };
9269
9270 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:239271 MockWrite(ASYNC, reinterpret_cast<char*>(write_buffer),
9272 arraysize(write_buffer)),
9273 MockWrite(
9274 "GET / HTTP/1.1\r\n"
9275 "Host: www.example.org\r\n"
9276 "Connection: keep-alive\r\n\r\n")};
[email protected]3cd17242009-06-23 02:59:029277
9278 MockRead data_reads[] = {
[email protected]f871ee152012-07-27 19:02:019279 MockRead(ASYNC, reinterpret_cast<char*>(read_buffer),
9280 arraysize(read_buffer)),
[email protected]e0c27be2009-07-15 13:09:359281 MockRead("HTTP/1.0 200 OK\r\n"),
9282 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n\r\n"),
9283 MockRead("Payload"),
[email protected]8ddf8322012-02-23 18:08:069284 MockRead(SYNCHRONOUS, OK)
[email protected]e0c27be2009-07-15 13:09:359285 };
9286
[email protected]31a2bfe2010-02-09 08:03:399287 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
9288 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:079289 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]e0c27be2009-07-15 13:09:359290
[email protected]8ddf8322012-02-23 18:08:069291 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:079292 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]e0c27be2009-07-15 13:09:359293
[email protected]49639fa2011-12-20 23:22:419294 TestCompletionCallback callback;
[email protected]e0c27be2009-07-15 13:09:359295
tfarina42834112016-09-22 13:38:209296 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:019297 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]e0c27be2009-07-15 13:09:359298
9299 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:019300 EXPECT_THAT(rv, IsOk());
[email protected]e0c27be2009-07-15 13:09:359301
[email protected]029c83b62013-01-24 05:28:209302 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:169303 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]029c83b62013-01-24 05:28:209304 TestLoadTimingNotReusedWithPac(load_timing_info,
9305 CONNECT_TIMING_HAS_SSL_TIMES);
9306
bnc691fda62016-08-12 00:43:169307 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:529308 ASSERT_TRUE(response);
tbansal2ecbbc72016-10-06 17:15:479309 EXPECT_EQ(ProxyServer::SCHEME_SOCKS4, response->proxy_server.scheme());
[email protected]e0c27be2009-07-15 13:09:359310
9311 std::string response_text;
bnc691fda62016-08-12 00:43:169312 rv = ReadTransaction(&trans, &response_text);
robpercival214763f2016-07-01 23:27:019313 EXPECT_THAT(rv, IsOk());
[email protected]e0c27be2009-07-15 13:09:359314 EXPECT_EQ("Payload", response_text);
9315}
9316
bncd16676a2016-07-20 16:23:019317TEST_F(HttpNetworkTransactionTest, SOCKS4_HTTP_GET_no_PAC) {
[email protected]029c83b62013-01-24 05:28:209318 HttpRequestInfo request;
9319 request.method = "GET";
bncce36dca22015-04-21 22:11:239320 request.url = GURL("http://www.example.org/");
[email protected]029c83b62013-01-24 05:28:209321
rdsmith82957ad2015-09-16 19:42:039322 session_deps_.proxy_service =
9323 ProxyService::CreateFixed("socks4://myproxy:1080");
vishal.b62985ca92015-04-17 08:45:519324 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:079325 session_deps_.net_log = &net_log;
[email protected]029c83b62013-01-24 05:28:209326
danakj1fd259a02016-04-16 03:17:099327 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:169328 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]029c83b62013-01-24 05:28:209329
9330 char write_buffer[] = { 0x04, 0x01, 0x00, 0x50, 127, 0, 0, 1, 0 };
9331 char read_buffer[] = { 0x00, 0x5A, 0x00, 0x00, 0, 0, 0, 0 };
9332
9333 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:239334 MockWrite(ASYNC, write_buffer, arraysize(write_buffer)),
9335 MockWrite(
9336 "GET / HTTP/1.1\r\n"
9337 "Host: www.example.org\r\n"
9338 "Connection: keep-alive\r\n\r\n")};
[email protected]029c83b62013-01-24 05:28:209339
9340 MockRead data_reads[] = {
9341 MockRead(ASYNC, read_buffer, arraysize(read_buffer)),
9342 MockRead("HTTP/1.0 200 OK\r\n"),
9343 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n\r\n"),
9344 MockRead("Payload"),
9345 MockRead(SYNCHRONOUS, OK)
9346 };
9347
9348 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
9349 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:079350 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]029c83b62013-01-24 05:28:209351
9352 TestCompletionCallback callback;
9353
tfarina42834112016-09-22 13:38:209354 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:019355 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]029c83b62013-01-24 05:28:209356
9357 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:019358 EXPECT_THAT(rv, IsOk());
[email protected]029c83b62013-01-24 05:28:209359
bnc691fda62016-08-12 00:43:169360 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:529361 ASSERT_TRUE(response);
[email protected]029c83b62013-01-24 05:28:209362
9363 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:169364 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]029c83b62013-01-24 05:28:209365 TestLoadTimingNotReused(load_timing_info,
9366 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
9367
9368 std::string response_text;
bnc691fda62016-08-12 00:43:169369 rv = ReadTransaction(&trans, &response_text);
robpercival214763f2016-07-01 23:27:019370 EXPECT_THAT(rv, IsOk());
[email protected]029c83b62013-01-24 05:28:209371 EXPECT_EQ("Payload", response_text);
9372}
9373
bncd16676a2016-07-20 16:23:019374TEST_F(HttpNetworkTransactionTest, SOCKS5_HTTP_GET) {
[email protected]cb9bf6ca2011-01-28 13:15:279375 HttpRequestInfo request;
9376 request.method = "GET";
bncce36dca22015-04-21 22:11:239377 request.url = GURL("http://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:279378
rdsmith82957ad2015-09-16 19:42:039379 session_deps_.proxy_service =
9380 ProxyService::CreateFixedFromPacResult("SOCKS5 myproxy:1080");
vishal.b62985ca92015-04-17 08:45:519381 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:079382 session_deps_.net_log = &net_log;
[email protected]e0c27be2009-07-15 13:09:359383
danakj1fd259a02016-04-16 03:17:099384 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:169385 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]e0c27be2009-07-15 13:09:359386
[email protected]e0c27be2009-07-15 13:09:359387 const char kSOCKS5GreetRequest[] = { 0x05, 0x01, 0x00 };
9388 const char kSOCKS5GreetResponse[] = { 0x05, 0x00 };
[email protected]f209dba2009-12-18 00:24:379389 const char kSOCKS5OkRequest[] = {
bncce36dca22015-04-21 22:11:239390 0x05, // Version
9391 0x01, // Command (CONNECT)
9392 0x00, // Reserved.
9393 0x03, // Address type (DOMAINNAME).
9394 0x0F, // Length of domain (15)
9395 'w', 'w', 'w', '.', 'e', 'x', 'a', 'm', 'p', 'l', 'e', // Domain string
9396 '.', 'o', 'r', 'g', 0x00, 0x50, // 16-bit port (80)
[email protected]f209dba2009-12-18 00:24:379397 };
[email protected]e0c27be2009-07-15 13:09:359398 const char kSOCKS5OkResponse[] =
9399 { 0x05, 0x00, 0x00, 0x01, 127, 0, 0, 1, 0x00, 0x50 };
9400
9401 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:239402 MockWrite(ASYNC, kSOCKS5GreetRequest, arraysize(kSOCKS5GreetRequest)),
9403 MockWrite(ASYNC, kSOCKS5OkRequest, arraysize(kSOCKS5OkRequest)),
9404 MockWrite(
9405 "GET / HTTP/1.1\r\n"
9406 "Host: www.example.org\r\n"
9407 "Connection: keep-alive\r\n\r\n")};
[email protected]e0c27be2009-07-15 13:09:359408
9409 MockRead data_reads[] = {
[email protected]f871ee152012-07-27 19:02:019410 MockRead(ASYNC, kSOCKS5GreetResponse, arraysize(kSOCKS5GreetResponse)),
9411 MockRead(ASYNC, kSOCKS5OkResponse, arraysize(kSOCKS5OkResponse)),
[email protected]e0c27be2009-07-15 13:09:359412 MockRead("HTTP/1.0 200 OK\r\n"),
9413 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n\r\n"),
9414 MockRead("Payload"),
[email protected]8ddf8322012-02-23 18:08:069415 MockRead(SYNCHRONOUS, OK)
[email protected]e0c27be2009-07-15 13:09:359416 };
9417
[email protected]31a2bfe2010-02-09 08:03:399418 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
9419 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:079420 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]e0c27be2009-07-15 13:09:359421
[email protected]49639fa2011-12-20 23:22:419422 TestCompletionCallback callback;
[email protected]e0c27be2009-07-15 13:09:359423
tfarina42834112016-09-22 13:38:209424 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:019425 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]e0c27be2009-07-15 13:09:359426
9427 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:019428 EXPECT_THAT(rv, IsOk());
[email protected]e0c27be2009-07-15 13:09:359429
bnc691fda62016-08-12 00:43:169430 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:529431 ASSERT_TRUE(response);
tbansal2ecbbc72016-10-06 17:15:479432 EXPECT_EQ(ProxyServer::SCHEME_SOCKS5, response->proxy_server.scheme());
[email protected]e0c27be2009-07-15 13:09:359433
[email protected]029c83b62013-01-24 05:28:209434 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:169435 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]029c83b62013-01-24 05:28:209436 TestLoadTimingNotReusedWithPac(load_timing_info,
9437 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
9438
[email protected]e0c27be2009-07-15 13:09:359439 std::string response_text;
bnc691fda62016-08-12 00:43:169440 rv = ReadTransaction(&trans, &response_text);
robpercival214763f2016-07-01 23:27:019441 EXPECT_THAT(rv, IsOk());
[email protected]e0c27be2009-07-15 13:09:359442 EXPECT_EQ("Payload", response_text);
9443}
9444
bncd16676a2016-07-20 16:23:019445TEST_F(HttpNetworkTransactionTest, SOCKS5_SSL_GET) {
[email protected]cb9bf6ca2011-01-28 13:15:279446 HttpRequestInfo request;
9447 request.method = "GET";
bncce36dca22015-04-21 22:11:239448 request.url = GURL("https://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:279449
rdsmith82957ad2015-09-16 19:42:039450 session_deps_.proxy_service =
9451 ProxyService::CreateFixedFromPacResult("SOCKS5 myproxy:1080");
vishal.b62985ca92015-04-17 08:45:519452 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:079453 session_deps_.net_log = &net_log;
[email protected]e0c27be2009-07-15 13:09:359454
danakj1fd259a02016-04-16 03:17:099455 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:169456 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]e0c27be2009-07-15 13:09:359457
[email protected]e0c27be2009-07-15 13:09:359458 const char kSOCKS5GreetRequest[] = { 0x05, 0x01, 0x00 };
9459 const char kSOCKS5GreetResponse[] = { 0x05, 0x00 };
[email protected]f209dba2009-12-18 00:24:379460 const unsigned char kSOCKS5OkRequest[] = {
bncce36dca22015-04-21 22:11:239461 0x05, // Version
9462 0x01, // Command (CONNECT)
9463 0x00, // Reserved.
9464 0x03, // Address type (DOMAINNAME).
9465 0x0F, // Length of domain (15)
9466 'w', 'w', 'w', '.', 'e', 'x', 'a', 'm', 'p', 'l', 'e', // Domain string
9467 '.', 'o', 'r', 'g', 0x01, 0xBB, // 16-bit port (443)
[email protected]f209dba2009-12-18 00:24:379468 };
9469
[email protected]e0c27be2009-07-15 13:09:359470 const char kSOCKS5OkResponse[] =
9471 { 0x05, 0x00, 0x00, 0x01, 0, 0, 0, 0, 0x00, 0x00 };
9472
9473 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:239474 MockWrite(ASYNC, kSOCKS5GreetRequest, arraysize(kSOCKS5GreetRequest)),
9475 MockWrite(ASYNC, reinterpret_cast<const char*>(kSOCKS5OkRequest),
9476 arraysize(kSOCKS5OkRequest)),
9477 MockWrite(
9478 "GET / HTTP/1.1\r\n"
9479 "Host: www.example.org\r\n"
9480 "Connection: keep-alive\r\n\r\n")};
[email protected]e0c27be2009-07-15 13:09:359481
9482 MockRead data_reads[] = {
[email protected]f871ee152012-07-27 19:02:019483 MockRead(ASYNC, kSOCKS5GreetResponse, arraysize(kSOCKS5GreetResponse)),
9484 MockRead(ASYNC, kSOCKS5OkResponse, arraysize(kSOCKS5OkResponse)),
[email protected]3cd17242009-06-23 02:59:029485 MockRead("HTTP/1.0 200 OK\r\n"),
9486 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n\r\n"),
9487 MockRead("Payload"),
[email protected]8ddf8322012-02-23 18:08:069488 MockRead(SYNCHRONOUS, OK)
[email protected]3cd17242009-06-23 02:59:029489 };
9490
[email protected]31a2bfe2010-02-09 08:03:399491 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
9492 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:079493 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]3cd17242009-06-23 02:59:029494
[email protected]8ddf8322012-02-23 18:08:069495 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:079496 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]3cd17242009-06-23 02:59:029497
[email protected]49639fa2011-12-20 23:22:419498 TestCompletionCallback callback;
[email protected]3cd17242009-06-23 02:59:029499
tfarina42834112016-09-22 13:38:209500 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:019501 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]3cd17242009-06-23 02:59:029502
9503 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:019504 EXPECT_THAT(rv, IsOk());
[email protected]3cd17242009-06-23 02:59:029505
bnc691fda62016-08-12 00:43:169506 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:529507 ASSERT_TRUE(response);
tbansal2ecbbc72016-10-06 17:15:479508 EXPECT_EQ(ProxyServer::SCHEME_SOCKS5, response->proxy_server.scheme());
[email protected]3cd17242009-06-23 02:59:029509
[email protected]029c83b62013-01-24 05:28:209510 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:169511 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]029c83b62013-01-24 05:28:209512 TestLoadTimingNotReusedWithPac(load_timing_info,
9513 CONNECT_TIMING_HAS_SSL_TIMES);
9514
[email protected]3cd17242009-06-23 02:59:029515 std::string response_text;
bnc691fda62016-08-12 00:43:169516 rv = ReadTransaction(&trans, &response_text);
robpercival214763f2016-07-01 23:27:019517 EXPECT_THAT(rv, IsOk());
[email protected]3cd17242009-06-23 02:59:029518 EXPECT_EQ("Payload", response_text);
9519}
9520
[email protected]448d4ca52012-03-04 04:12:239521namespace {
9522
[email protected]04e5be32009-06-26 20:00:319523// Tests that for connection endpoints the group names are correctly set.
[email protected]2d731a32010-04-29 01:04:069524
9525struct GroupNameTest {
9526 std::string proxy_server;
9527 std::string url;
9528 std::string expected_group_name;
[email protected]e60e47a2010-07-14 03:37:189529 bool ssl;
[email protected]2d731a32010-04-29 01:04:069530};
9531
danakj1fd259a02016-04-16 03:17:099532std::unique_ptr<HttpNetworkSession> SetupSessionForGroupNameTests(
[email protected]bb88e1d32013-05-03 23:11:079533 SpdySessionDependencies* session_deps_) {
danakj1fd259a02016-04-16 03:17:099534 std::unique_ptr<HttpNetworkSession> session(CreateSession(session_deps_));
[email protected]2d731a32010-04-29 01:04:069535
bnc525e175a2016-06-20 12:36:409536 HttpServerProperties* http_server_properties =
[email protected]17291a022011-10-10 07:32:539537 session->http_server_properties();
bnc3472afd2016-11-17 15:27:219538 AlternativeService alternative_service(kProtoHTTP2, "", 444);
bnc7dc7e1b42015-07-28 14:43:129539 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:219540 http_server_properties->SetHttp2AlternativeService(
bncaa60ff402016-06-22 19:12:429541 url::SchemeHostPort("https", "host.with.alternate", 443),
zhongyi3d4a55e72016-04-22 20:36:469542 alternative_service, expiration);
[email protected]2d731a32010-04-29 01:04:069543
9544 return session;
9545}
9546
mmenkee65e7af2015-10-13 17:16:429547int GroupNameTransactionHelper(const std::string& url,
9548 HttpNetworkSession* session) {
[email protected]2d731a32010-04-29 01:04:069549 HttpRequestInfo request;
9550 request.method = "GET";
9551 request.url = GURL(url);
[email protected]2d731a32010-04-29 01:04:069552
bnc691fda62016-08-12 00:43:169553 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session);
[email protected]cb9bf6ca2011-01-28 13:15:279554
[email protected]49639fa2011-12-20 23:22:419555 TestCompletionCallback callback;
[email protected]2d731a32010-04-29 01:04:069556
9557 // We do not complete this request, the dtor will clean the transaction up.
tfarina42834112016-09-22 13:38:209558 return trans.Start(&request, callback.callback(), NetLogWithSource());
[email protected]2d731a32010-04-29 01:04:069559}
9560
[email protected]448d4ca52012-03-04 04:12:239561} // namespace
9562
bncd16676a2016-07-20 16:23:019563TEST_F(HttpNetworkTransactionTest, GroupNameForDirectConnections) {
[email protected]2d731a32010-04-29 01:04:069564 const GroupNameTest tests[] = {
bncce36dca22015-04-21 22:11:239565 {
9566 "", // unused
9567 "http://www.example.org/direct",
9568 "www.example.org:80",
9569 false,
9570 },
9571 {
9572 "", // unused
9573 "http://[2001:1418:13:1::25]/direct",
9574 "[2001:1418:13:1::25]:80",
9575 false,
9576 },
[email protected]04e5be32009-06-26 20:00:319577
bncce36dca22015-04-21 22:11:239578 // SSL Tests
9579 {
9580 "", // unused
9581 "https://www.example.org/direct_ssl",
9582 "ssl/www.example.org:443",
9583 true,
9584 },
9585 {
9586 "", // unused
9587 "https://[2001:1418:13:1::25]/direct",
9588 "ssl/[2001:1418:13:1::25]:443",
9589 true,
9590 },
9591 {
9592 "", // unused
bncaa60ff402016-06-22 19:12:429593 "https://host.with.alternate/direct",
bncce36dca22015-04-21 22:11:239594 "ssl/host.with.alternate:443",
9595 true,
9596 },
[email protected]2d731a32010-04-29 01:04:069597 };
[email protected]2ff8b312010-04-26 22:20:549598
viettrungluue4a8b882014-10-16 06:17:389599 for (size_t i = 0; i < arraysize(tests); ++i) {
rdsmith82957ad2015-09-16 19:42:039600 session_deps_.proxy_service =
9601 ProxyService::CreateFixed(tests[i].proxy_server);
danakj1fd259a02016-04-16 03:17:099602 std::unique_ptr<HttpNetworkSession> session(
bnca9b9e222016-07-11 20:10:409603 SetupSessionForGroupNameTests(&session_deps_));
[email protected]2d731a32010-04-29 01:04:069604
mmenkee65e7af2015-10-13 17:16:429605 HttpNetworkSessionPeer peer(session.get());
[email protected]ab739042011-04-07 15:22:289606 CaptureGroupNameTransportSocketPool* transport_conn_pool =
bnc87dcefc2017-05-25 12:47:589607 new CaptureGroupNameTransportSocketPool(nullptr, nullptr);
[email protected]2431756e2010-09-29 20:26:139608 CaptureGroupNameSSLSocketPool* ssl_conn_pool =
bnc87dcefc2017-05-25 12:47:589609 new CaptureGroupNameSSLSocketPool(nullptr, nullptr);
Jeremy Roman0579ed62017-08-29 15:56:199610 auto mock_pool_manager = std::make_unique<MockClientSocketPoolManager>();
[email protected]a42dbd142011-11-17 16:42:029611 mock_pool_manager->SetTransportSocketPool(transport_conn_pool);
9612 mock_pool_manager->SetSSLSocketPool(ssl_conn_pool);
dchengc7eeda422015-12-26 03:56:489613 peer.SetClientSocketPoolManager(std::move(mock_pool_manager));
[email protected]2d731a32010-04-29 01:04:069614
9615 EXPECT_EQ(ERR_IO_PENDING,
mmenkee65e7af2015-10-13 17:16:429616 GroupNameTransactionHelper(tests[i].url, session.get()));
[email protected]e60e47a2010-07-14 03:37:189617 if (tests[i].ssl)
9618 EXPECT_EQ(tests[i].expected_group_name,
9619 ssl_conn_pool->last_group_name_received());
9620 else
9621 EXPECT_EQ(tests[i].expected_group_name,
[email protected]ab739042011-04-07 15:22:289622 transport_conn_pool->last_group_name_received());
[email protected]2d731a32010-04-29 01:04:069623 }
[email protected]2d731a32010-04-29 01:04:069624}
9625
bncd16676a2016-07-20 16:23:019626TEST_F(HttpNetworkTransactionTest, GroupNameForHTTPProxyConnections) {
[email protected]2d731a32010-04-29 01:04:069627 const GroupNameTest tests[] = {
bncce36dca22015-04-21 22:11:239628 {
9629 "http_proxy",
9630 "http://www.example.org/http_proxy_normal",
9631 "www.example.org:80",
9632 false,
9633 },
[email protected]2d731a32010-04-29 01:04:069634
bncce36dca22015-04-21 22:11:239635 // SSL Tests
9636 {
9637 "http_proxy",
9638 "https://www.example.org/http_connect_ssl",
9639 "ssl/www.example.org:443",
9640 true,
9641 },
[email protected]af3490e2010-10-16 21:02:299642
bncce36dca22015-04-21 22:11:239643 {
9644 "http_proxy",
bncaa60ff402016-06-22 19:12:429645 "https://host.with.alternate/direct",
bncce36dca22015-04-21 22:11:239646 "ssl/host.with.alternate:443",
9647 true,
9648 },
[email protected]45499252013-01-23 17:12:569649
bncce36dca22015-04-21 22:11:239650 {
9651 "http_proxy",
9652 "ftp://ftp.google.com/http_proxy_normal",
9653 "ftp/ftp.google.com:21",
9654 false,
9655 },
[email protected]2d731a32010-04-29 01:04:069656 };
9657
viettrungluue4a8b882014-10-16 06:17:389658 for (size_t i = 0; i < arraysize(tests); ++i) {
rdsmith82957ad2015-09-16 19:42:039659 session_deps_.proxy_service =
9660 ProxyService::CreateFixed(tests[i].proxy_server);
danakj1fd259a02016-04-16 03:17:099661 std::unique_ptr<HttpNetworkSession> session(
bnca9b9e222016-07-11 20:10:409662 SetupSessionForGroupNameTests(&session_deps_));
[email protected]2d731a32010-04-29 01:04:069663
mmenkee65e7af2015-10-13 17:16:429664 HttpNetworkSessionPeer peer(session.get());
[email protected]2d731a32010-04-29 01:04:069665
[email protected]e60e47a2010-07-14 03:37:189666 HostPortPair proxy_host("http_proxy", 80);
[email protected]2431756e2010-09-29 20:26:139667 CaptureGroupNameHttpProxySocketPool* http_proxy_pool =
[email protected]9e1bdd32011-02-03 21:48:349668 new CaptureGroupNameHttpProxySocketPool(NULL, NULL);
[email protected]2431756e2010-09-29 20:26:139669 CaptureGroupNameSSLSocketPool* ssl_conn_pool =
[email protected]9e1bdd32011-02-03 21:48:349670 new CaptureGroupNameSSLSocketPool(NULL, NULL);
Jeremy Roman0579ed62017-08-29 15:56:199671 auto mock_pool_manager = std::make_unique<MockClientSocketPoolManager>();
aviadef3442016-10-03 18:50:399672 mock_pool_manager->SetSocketPoolForHTTPProxy(
9673 proxy_host, base::WrapUnique(http_proxy_pool));
9674 mock_pool_manager->SetSocketPoolForSSLWithProxy(
9675 proxy_host, base::WrapUnique(ssl_conn_pool));
dchengc7eeda422015-12-26 03:56:489676 peer.SetClientSocketPoolManager(std::move(mock_pool_manager));
[email protected]2d731a32010-04-29 01:04:069677
9678 EXPECT_EQ(ERR_IO_PENDING,
mmenkee65e7af2015-10-13 17:16:429679 GroupNameTransactionHelper(tests[i].url, session.get()));
[email protected]e60e47a2010-07-14 03:37:189680 if (tests[i].ssl)
9681 EXPECT_EQ(tests[i].expected_group_name,
9682 ssl_conn_pool->last_group_name_received());
9683 else
9684 EXPECT_EQ(tests[i].expected_group_name,
9685 http_proxy_pool->last_group_name_received());
[email protected]2d731a32010-04-29 01:04:069686 }
[email protected]2d731a32010-04-29 01:04:069687}
9688
bncd16676a2016-07-20 16:23:019689TEST_F(HttpNetworkTransactionTest, GroupNameForSOCKSConnections) {
[email protected]2d731a32010-04-29 01:04:069690 const GroupNameTest tests[] = {
bncce36dca22015-04-21 22:11:239691 {
9692 "socks4://socks_proxy:1080",
9693 "http://www.example.org/socks4_direct",
9694 "socks4/www.example.org:80",
9695 false,
9696 },
9697 {
9698 "socks5://socks_proxy:1080",
9699 "http://www.example.org/socks5_direct",
9700 "socks5/www.example.org:80",
9701 false,
9702 },
[email protected]2d731a32010-04-29 01:04:069703
bncce36dca22015-04-21 22:11:239704 // SSL Tests
9705 {
9706 "socks4://socks_proxy:1080",
9707 "https://www.example.org/socks4_ssl",
9708 "socks4/ssl/www.example.org:443",
9709 true,
9710 },
9711 {
9712 "socks5://socks_proxy:1080",
9713 "https://www.example.org/socks5_ssl",
9714 "socks5/ssl/www.example.org:443",
9715 true,
9716 },
[email protected]af3490e2010-10-16 21:02:299717
bncce36dca22015-04-21 22:11:239718 {
9719 "socks4://socks_proxy:1080",
bncaa60ff402016-06-22 19:12:429720 "https://host.with.alternate/direct",
bncce36dca22015-04-21 22:11:239721 "socks4/ssl/host.with.alternate:443",
9722 true,
9723 },
[email protected]04e5be32009-06-26 20:00:319724 };
9725
viettrungluue4a8b882014-10-16 06:17:389726 for (size_t i = 0; i < arraysize(tests); ++i) {
rdsmith82957ad2015-09-16 19:42:039727 session_deps_.proxy_service =
9728 ProxyService::CreateFixed(tests[i].proxy_server);
danakj1fd259a02016-04-16 03:17:099729 std::unique_ptr<HttpNetworkSession> session(
bnca9b9e222016-07-11 20:10:409730 SetupSessionForGroupNameTests(&session_deps_));
[email protected]8b114dd72011-03-25 05:33:029731
mmenkee65e7af2015-10-13 17:16:429732 HttpNetworkSessionPeer peer(session.get());
[email protected]04e5be32009-06-26 20:00:319733
[email protected]e60e47a2010-07-14 03:37:189734 HostPortPair proxy_host("socks_proxy", 1080);
[email protected]2431756e2010-09-29 20:26:139735 CaptureGroupNameSOCKSSocketPool* socks_conn_pool =
[email protected]9e1bdd32011-02-03 21:48:349736 new CaptureGroupNameSOCKSSocketPool(NULL, NULL);
[email protected]2431756e2010-09-29 20:26:139737 CaptureGroupNameSSLSocketPool* ssl_conn_pool =
[email protected]9e1bdd32011-02-03 21:48:349738 new CaptureGroupNameSSLSocketPool(NULL, NULL);
Jeremy Roman0579ed62017-08-29 15:56:199739 auto mock_pool_manager = std::make_unique<MockClientSocketPoolManager>();
aviadef3442016-10-03 18:50:399740 mock_pool_manager->SetSocketPoolForSOCKSProxy(
9741 proxy_host, base::WrapUnique(socks_conn_pool));
9742 mock_pool_manager->SetSocketPoolForSSLWithProxy(
9743 proxy_host, base::WrapUnique(ssl_conn_pool));
dchengc7eeda422015-12-26 03:56:489744 peer.SetClientSocketPoolManager(std::move(mock_pool_manager));
[email protected]04e5be32009-06-26 20:00:319745
bnc691fda62016-08-12 00:43:169746 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]04e5be32009-06-26 20:00:319747
[email protected]2d731a32010-04-29 01:04:069748 EXPECT_EQ(ERR_IO_PENDING,
mmenkee65e7af2015-10-13 17:16:429749 GroupNameTransactionHelper(tests[i].url, session.get()));
[email protected]e60e47a2010-07-14 03:37:189750 if (tests[i].ssl)
9751 EXPECT_EQ(tests[i].expected_group_name,
9752 ssl_conn_pool->last_group_name_received());
9753 else
9754 EXPECT_EQ(tests[i].expected_group_name,
9755 socks_conn_pool->last_group_name_received());
[email protected]04e5be32009-06-26 20:00:319756 }
9757}
9758
bncd16676a2016-07-20 16:23:019759TEST_F(HttpNetworkTransactionTest, ReconsiderProxyAfterFailedConnection) {
[email protected]cb9bf6ca2011-01-28 13:15:279760 HttpRequestInfo request;
9761 request.method = "GET";
bncce36dca22015-04-21 22:11:239762 request.url = GURL("http://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:279763
rdsmith82957ad2015-09-16 19:42:039764 session_deps_.proxy_service =
9765 ProxyService::CreateFixed("myproxy:70;foobar:80");
[email protected]b59ff372009-07-15 22:04:329766
[email protected]69719062010-01-05 20:09:219767 // This simulates failure resolving all hostnames; that means we will fail
9768 // connecting to both proxies (myproxy:70 and foobar:80).
[email protected]bb88e1d32013-05-03 23:11:079769 session_deps_.host_resolver->rules()->AddSimulatedFailure("*");
[email protected]b59ff372009-07-15 22:04:329770
danakj1fd259a02016-04-16 03:17:099771 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:169772 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]9172a982009-06-06 00:30:259773
[email protected]49639fa2011-12-20 23:22:419774 TestCompletionCallback callback;
[email protected]9172a982009-06-06 00:30:259775
tfarina42834112016-09-22 13:38:209776 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:019777 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]9172a982009-06-06 00:30:259778
[email protected]9172a982009-06-06 00:30:259779 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:019780 EXPECT_THAT(rv, IsError(ERR_PROXY_CONNECTION_FAILED));
[email protected]9172a982009-06-06 00:30:259781}
9782
[email protected]685af592010-05-11 19:31:249783// Base test to make sure that when the load flags for a request specify to
9784// bypass the cache, the DNS cache is not used.
[email protected]23e482282013-06-14 16:08:029785void HttpNetworkTransactionTest::BypassHostCacheOnRefreshHelper(
[email protected]bb88e1d32013-05-03 23:11:079786 int load_flags) {
[email protected]cb9bf6ca2011-01-28 13:15:279787 // Issue a request, asking to bypass the cache(s).
maksim.sisov31452af2016-07-27 06:38:109788 HttpRequestInfo request_info;
9789 request_info.method = "GET";
9790 request_info.load_flags = load_flags;
9791 request_info.url = GURL("http://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:279792
[email protected]a2c2fb92009-07-18 07:31:049793 // Select a host resolver that does caching.
Jeremy Roman0579ed62017-08-29 15:56:199794 session_deps_.host_resolver = std::make_unique<MockCachingHostResolver>();
[email protected]b59ff372009-07-15 22:04:329795
danakj1fd259a02016-04-16 03:17:099796 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:169797 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]3b9cca42009-06-16 01:08:289798
bncce36dca22015-04-21 22:11:239799 // Warm up the host cache so it has an entry for "www.example.org".
[email protected]3b9cca42009-06-16 01:08:289800 AddressList addrlist;
[email protected]aa22b242011-11-16 18:58:299801 TestCompletionCallback callback;
maksim.sisov31452af2016-07-27 06:38:109802 std::unique_ptr<HostResolver::Request> request1;
[email protected]bb88e1d32013-05-03 23:11:079803 int rv = session_deps_.host_resolver->Resolve(
bncce36dca22015-04-21 22:11:239804 HostResolver::RequestInfo(HostPortPair("www.example.org", 80)),
maksim.sisov31452af2016-07-27 06:38:109805 DEFAULT_PRIORITY, &addrlist, callback.callback(), &request1,
tfarina42834112016-09-22 13:38:209806 NetLogWithSource());
robpercival214763f2016-07-01 23:27:019807 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]6e78dfb2011-07-28 21:34:479808 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:019809 EXPECT_THAT(rv, IsOk());
[email protected]3b9cca42009-06-16 01:08:289810
9811 // Verify that it was added to host cache, by doing a subsequent async lookup
9812 // and confirming it completes synchronously.
maksim.sisov31452af2016-07-27 06:38:109813 std::unique_ptr<HostResolver::Request> request2;
[email protected]bb88e1d32013-05-03 23:11:079814 rv = session_deps_.host_resolver->Resolve(
bncce36dca22015-04-21 22:11:239815 HostResolver::RequestInfo(HostPortPair("www.example.org", 80)),
maksim.sisov31452af2016-07-27 06:38:109816 DEFAULT_PRIORITY, &addrlist, callback.callback(), &request2,
tfarina42834112016-09-22 13:38:209817 NetLogWithSource());
robpercival214763f2016-07-01 23:27:019818 ASSERT_THAT(rv, IsOk());
[email protected]3b9cca42009-06-16 01:08:289819
bncce36dca22015-04-21 22:11:239820 // Inject a failure the next time that "www.example.org" is resolved. This way
[email protected]3b9cca42009-06-16 01:08:289821 // we can tell if the next lookup hit the cache, or the "network".
9822 // (cache --> success, "network" --> failure).
bncce36dca22015-04-21 22:11:239823 session_deps_.host_resolver->rules()->AddSimulatedFailure("www.example.org");
[email protected]3b9cca42009-06-16 01:08:289824
9825 // Connect up a mock socket which will fail with ERR_UNEXPECTED during the
9826 // first read -- this won't be reached as the host resolution will fail first.
[email protected]8ddf8322012-02-23 18:08:069827 MockRead data_reads[] = { MockRead(SYNCHRONOUS, ERR_UNEXPECTED) };
[email protected]31a2bfe2010-02-09 08:03:399828 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:079829 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]3b9cca42009-06-16 01:08:289830
[email protected]3b9cca42009-06-16 01:08:289831 // Run the request.
tfarina42834112016-09-22 13:38:209832 rv = trans.Start(&request_info, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:019833 ASSERT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]49639fa2011-12-20 23:22:419834 rv = callback.WaitForResult();
[email protected]3b9cca42009-06-16 01:08:289835
9836 // If we bypassed the cache, we would have gotten a failure while resolving
bncce36dca22015-04-21 22:11:239837 // "www.example.org".
robpercival214763f2016-07-01 23:27:019838 EXPECT_THAT(rv, IsError(ERR_NAME_NOT_RESOLVED));
[email protected]3b9cca42009-06-16 01:08:289839}
9840
[email protected]685af592010-05-11 19:31:249841// There are multiple load flags that should trigger the host cache bypass.
9842// Test each in isolation:
bncd16676a2016-07-20 16:23:019843TEST_F(HttpNetworkTransactionTest, BypassHostCacheOnRefresh1) {
[email protected]685af592010-05-11 19:31:249844 BypassHostCacheOnRefreshHelper(LOAD_BYPASS_CACHE);
9845}
9846
bncd16676a2016-07-20 16:23:019847TEST_F(HttpNetworkTransactionTest, BypassHostCacheOnRefresh2) {
[email protected]685af592010-05-11 19:31:249848 BypassHostCacheOnRefreshHelper(LOAD_VALIDATE_CACHE);
9849}
9850
bncd16676a2016-07-20 16:23:019851TEST_F(HttpNetworkTransactionTest, BypassHostCacheOnRefresh3) {
[email protected]685af592010-05-11 19:31:249852 BypassHostCacheOnRefreshHelper(LOAD_DISABLE_CACHE);
9853}
9854
[email protected]0877e3d2009-10-17 22:29:579855// Make sure we can handle an error when writing the request.
bncd16676a2016-07-20 16:23:019856TEST_F(HttpNetworkTransactionTest, RequestWriteError) {
[email protected]0877e3d2009-10-17 22:29:579857 HttpRequestInfo request;
9858 request.method = "GET";
9859 request.url = GURL("http://www.foo.com/");
[email protected]0877e3d2009-10-17 22:29:579860
9861 MockWrite write_failure[] = {
[email protected]8ddf8322012-02-23 18:08:069862 MockWrite(ASYNC, ERR_CONNECTION_RESET),
[email protected]0877e3d2009-10-17 22:29:579863 };
[email protected]31a2bfe2010-02-09 08:03:399864 StaticSocketDataProvider data(NULL, 0,
9865 write_failure, arraysize(write_failure));
[email protected]bb88e1d32013-05-03 23:11:079866 session_deps_.socket_factory->AddSocketDataProvider(&data);
danakj1fd259a02016-04-16 03:17:099867 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]0877e3d2009-10-17 22:29:579868
[email protected]49639fa2011-12-20 23:22:419869 TestCompletionCallback callback;
[email protected]0877e3d2009-10-17 22:29:579870
bnc691fda62016-08-12 00:43:169871 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]0877e3d2009-10-17 22:29:579872
tfarina42834112016-09-22 13:38:209873 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:019874 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]0877e3d2009-10-17 22:29:579875
9876 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:019877 EXPECT_THAT(rv, IsError(ERR_CONNECTION_RESET));
ttuttled9dbc652015-09-29 20:00:599878
9879 IPEndPoint endpoint;
bnc691fda62016-08-12 00:43:169880 EXPECT_TRUE(trans.GetRemoteEndpoint(&endpoint));
ttuttled9dbc652015-09-29 20:00:599881 EXPECT_LT(0u, endpoint.address().size());
[email protected]0877e3d2009-10-17 22:29:579882}
9883
zmo9528c9f42015-08-04 22:12:089884// Check that a connection closed after the start of the headers finishes ok.
bncd16676a2016-07-20 16:23:019885TEST_F(HttpNetworkTransactionTest, ConnectionClosedAfterStartOfHeaders) {
[email protected]0877e3d2009-10-17 22:29:579886 HttpRequestInfo request;
9887 request.method = "GET";
9888 request.url = GURL("http://www.foo.com/");
[email protected]0877e3d2009-10-17 22:29:579889
9890 MockRead data_reads[] = {
9891 MockRead("HTTP/1."),
[email protected]8ddf8322012-02-23 18:08:069892 MockRead(SYNCHRONOUS, OK),
[email protected]0877e3d2009-10-17 22:29:579893 };
9894
[email protected]31a2bfe2010-02-09 08:03:399895 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:079896 session_deps_.socket_factory->AddSocketDataProvider(&data);
danakj1fd259a02016-04-16 03:17:099897 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]0877e3d2009-10-17 22:29:579898
[email protected]49639fa2011-12-20 23:22:419899 TestCompletionCallback callback;
[email protected]0877e3d2009-10-17 22:29:579900
bnc691fda62016-08-12 00:43:169901 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]0877e3d2009-10-17 22:29:579902
tfarina42834112016-09-22 13:38:209903 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:019904 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]0877e3d2009-10-17 22:29:579905
9906 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:019907 EXPECT_THAT(rv, IsOk());
zmo9528c9f42015-08-04 22:12:089908
bnc691fda62016-08-12 00:43:169909 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:529910 ASSERT_TRUE(response);
zmo9528c9f42015-08-04 22:12:089911
wezca1070932016-05-26 20:30:529912 EXPECT_TRUE(response->headers);
zmo9528c9f42015-08-04 22:12:089913 EXPECT_EQ("HTTP/1.0 200 OK", response->headers->GetStatusLine());
9914
9915 std::string response_data;
bnc691fda62016-08-12 00:43:169916 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:019917 EXPECT_THAT(rv, IsOk());
zmo9528c9f42015-08-04 22:12:089918 EXPECT_EQ("", response_data);
ttuttled9dbc652015-09-29 20:00:599919
9920 IPEndPoint endpoint;
bnc691fda62016-08-12 00:43:169921 EXPECT_TRUE(trans.GetRemoteEndpoint(&endpoint));
ttuttled9dbc652015-09-29 20:00:599922 EXPECT_LT(0u, endpoint.address().size());
[email protected]0877e3d2009-10-17 22:29:579923}
9924
9925// Make sure that a dropped connection while draining the body for auth
9926// restart does the right thing.
bncd16676a2016-07-20 16:23:019927TEST_F(HttpNetworkTransactionTest, DrainResetOK) {
[email protected]0877e3d2009-10-17 22:29:579928 HttpRequestInfo request;
9929 request.method = "GET";
bncce36dca22015-04-21 22:11:239930 request.url = GURL("http://www.example.org/");
[email protected]0877e3d2009-10-17 22:29:579931
9932 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:239933 MockWrite(
9934 "GET / HTTP/1.1\r\n"
9935 "Host: www.example.org\r\n"
9936 "Connection: keep-alive\r\n\r\n"),
[email protected]0877e3d2009-10-17 22:29:579937 };
9938
9939 MockRead data_reads1[] = {
9940 MockRead("HTTP/1.1 401 Unauthorized\r\n"),
9941 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
9942 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
9943 MockRead("Content-Length: 14\r\n\r\n"),
9944 MockRead("Unauth"),
[email protected]8ddf8322012-02-23 18:08:069945 MockRead(ASYNC, ERR_CONNECTION_RESET),
[email protected]0877e3d2009-10-17 22:29:579946 };
9947
[email protected]31a2bfe2010-02-09 08:03:399948 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
9949 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:079950 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]0877e3d2009-10-17 22:29:579951
bnc691fda62016-08-12 00:43:169952 // After calling trans.RestartWithAuth(), this is the request we should
[email protected]0877e3d2009-10-17 22:29:579953 // be issuing -- the final header line contains the credentials.
9954 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:239955 MockWrite(
9956 "GET / HTTP/1.1\r\n"
9957 "Host: www.example.org\r\n"
9958 "Connection: keep-alive\r\n"
9959 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]0877e3d2009-10-17 22:29:579960 };
9961
9962 // Lastly, the server responds with the actual content.
9963 MockRead data_reads2[] = {
9964 MockRead("HTTP/1.1 200 OK\r\n"),
9965 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
9966 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:069967 MockRead(SYNCHRONOUS, OK),
[email protected]0877e3d2009-10-17 22:29:579968 };
9969
[email protected]31a2bfe2010-02-09 08:03:399970 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
9971 data_writes2, arraysize(data_writes2));
[email protected]bb88e1d32013-05-03 23:11:079972 session_deps_.socket_factory->AddSocketDataProvider(&data2);
danakj1fd259a02016-04-16 03:17:099973 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]0877e3d2009-10-17 22:29:579974
[email protected]49639fa2011-12-20 23:22:419975 TestCompletionCallback callback1;
[email protected]0877e3d2009-10-17 22:29:579976
bnc691fda62016-08-12 00:43:169977 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]0b0bf032010-09-21 18:08:509978
tfarina42834112016-09-22 13:38:209979 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:019980 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]0877e3d2009-10-17 22:29:579981
9982 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:019983 EXPECT_THAT(rv, IsOk());
[email protected]0877e3d2009-10-17 22:29:579984
bnc691fda62016-08-12 00:43:169985 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:529986 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:049987 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]0877e3d2009-10-17 22:29:579988
[email protected]49639fa2011-12-20 23:22:419989 TestCompletionCallback callback2;
[email protected]0877e3d2009-10-17 22:29:579990
bnc691fda62016-08-12 00:43:169991 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar), callback2.callback());
robpercival214763f2016-07-01 23:27:019992 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]0877e3d2009-10-17 22:29:579993
9994 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:019995 EXPECT_THAT(rv, IsOk());
[email protected]0877e3d2009-10-17 22:29:579996
bnc691fda62016-08-12 00:43:169997 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:529998 ASSERT_TRUE(response);
9999 EXPECT_FALSE(response->auth_challenge);
[email protected]0877e3d2009-10-17 22:29:5710000 EXPECT_EQ(100, response->headers->GetContentLength());
10001}
10002
10003// Test HTTPS connections going through a proxy that sends extra data.
bncd16676a2016-07-20 16:23:0110004TEST_F(HttpNetworkTransactionTest, HTTPSViaProxyWithExtraData) {
rdsmith82957ad2015-09-16 19:42:0310005 session_deps_.proxy_service = ProxyService::CreateFixed("myproxy:70");
[email protected]0877e3d2009-10-17 22:29:5710006
10007 HttpRequestInfo request;
10008 request.method = "GET";
bncce36dca22015-04-21 22:11:2310009 request.url = GURL("https://www.example.org/");
[email protected]0877e3d2009-10-17 22:29:5710010
10011 MockRead proxy_reads[] = {
10012 MockRead("HTTP/1.0 200 Connected\r\n\r\nExtra data"),
[email protected]8ddf8322012-02-23 18:08:0610013 MockRead(SYNCHRONOUS, OK)
[email protected]0877e3d2009-10-17 22:29:5710014 };
10015
[email protected]31a2bfe2010-02-09 08:03:3910016 StaticSocketDataProvider data(proxy_reads, arraysize(proxy_reads), NULL, 0);
[email protected]8ddf8322012-02-23 18:08:0610017 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]0877e3d2009-10-17 22:29:5710018
[email protected]bb88e1d32013-05-03 23:11:0710019 session_deps_.socket_factory->AddSocketDataProvider(&data);
10020 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]0877e3d2009-10-17 22:29:5710021
[email protected]49639fa2011-12-20 23:22:4110022 TestCompletionCallback callback;
[email protected]0877e3d2009-10-17 22:29:5710023
[email protected]bb88e1d32013-05-03 23:11:0710024 session_deps_.socket_factory->ResetNextMockIndexes();
[email protected]0877e3d2009-10-17 22:29:5710025
danakj1fd259a02016-04-16 03:17:0910026 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1610027 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]0877e3d2009-10-17 22:29:5710028
tfarina42834112016-09-22 13:38:2010029 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110030 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]0877e3d2009-10-17 22:29:5710031
10032 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0110033 EXPECT_THAT(rv, IsError(ERR_TUNNEL_CONNECTION_FAILED));
[email protected]0877e3d2009-10-17 22:29:5710034}
10035
bncd16676a2016-07-20 16:23:0110036TEST_F(HttpNetworkTransactionTest, LargeContentLengthThenClose) {
[email protected]9492e4a2010-02-24 00:58:4610037 HttpRequestInfo request;
10038 request.method = "GET";
bncce36dca22015-04-21 22:11:2310039 request.url = GURL("http://www.example.org/");
[email protected]9492e4a2010-02-24 00:58:4610040
danakj1fd259a02016-04-16 03:17:0910041 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1610042 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:2710043
[email protected]e22e1362009-11-23 21:31:1210044 MockRead data_reads[] = {
10045 MockRead("HTTP/1.0 200 OK\r\nContent-Length:6719476739\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:0610046 MockRead(SYNCHRONOUS, OK),
[email protected]e22e1362009-11-23 21:31:1210047 };
[email protected]9492e4a2010-02-24 00:58:4610048
10049 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0710050 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]9492e4a2010-02-24 00:58:4610051
[email protected]49639fa2011-12-20 23:22:4110052 TestCompletionCallback callback;
[email protected]9492e4a2010-02-24 00:58:4610053
tfarina42834112016-09-22 13:38:2010054 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110055 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]9492e4a2010-02-24 00:58:4610056
robpercival214763f2016-07-01 23:27:0110057 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]9492e4a2010-02-24 00:58:4610058
bnc691fda62016-08-12 00:43:1610059 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5210060 ASSERT_TRUE(response);
[email protected]9492e4a2010-02-24 00:58:4610061
wezca1070932016-05-26 20:30:5210062 EXPECT_TRUE(response->headers);
[email protected]9492e4a2010-02-24 00:58:4610063 EXPECT_EQ("HTTP/1.0 200 OK", response->headers->GetStatusLine());
10064
10065 std::string response_data;
bnc691fda62016-08-12 00:43:1610066 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:0110067 EXPECT_THAT(rv, IsError(ERR_CONTENT_LENGTH_MISMATCH));
[email protected]e22e1362009-11-23 21:31:1210068}
10069
bncd16676a2016-07-20 16:23:0110070TEST_F(HttpNetworkTransactionTest, UploadFileSmallerThanLength) {
[email protected]6cdfd7f2013-02-08 20:40:1510071 base::FilePath temp_file_path;
[email protected]03d9afc02013-12-03 17:55:5210072 ASSERT_TRUE(base::CreateTemporaryFile(&temp_file_path));
avibf0746c2015-12-09 19:53:1410073 const uint64_t kFakeSize = 100000; // file is actually blank
[email protected]d98961652012-09-11 20:27:2110074 UploadFileElementReader::ScopedOverridingContentLengthForTests
10075 overriding_content_length(kFakeSize);
[email protected]95d88ffe2010-02-04 21:25:3310076
danakj1fd259a02016-04-16 03:17:0910077 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
Jeremy Roman0579ed62017-08-29 15:56:1910078 element_readers.push_back(std::make_unique<UploadFileElementReader>(
avibf0746c2015-12-09 19:53:1410079 base::ThreadTaskRunnerHandle::Get().get(), temp_file_path, 0,
ricea2deef682016-09-09 08:04:0710080 std::numeric_limits<uint64_t>::max(), base::Time()));
olli.raula6df48b2a2015-11-26 07:40:2210081 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]329b68b2012-11-14 17:54:2710082
10083 HttpRequestInfo request;
10084 request.method = "POST";
bncce36dca22015-04-21 22:11:2310085 request.url = GURL("http://www.example.org/upload");
[email protected]329b68b2012-11-14 17:54:2710086 request.upload_data_stream = &upload_data_stream;
[email protected]329b68b2012-11-14 17:54:2710087
danakj1fd259a02016-04-16 03:17:0910088 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1610089 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]95d88ffe2010-02-04 21:25:3310090
10091 MockRead data_reads[] = {
10092 MockRead("HTTP/1.0 200 OK\r\n\r\n"),
10093 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:0610094 MockRead(SYNCHRONOUS, OK),
[email protected]95d88ffe2010-02-04 21:25:3310095 };
[email protected]31a2bfe2010-02-09 08:03:3910096 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0710097 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]95d88ffe2010-02-04 21:25:3310098
[email protected]49639fa2011-12-20 23:22:4110099 TestCompletionCallback callback;
[email protected]95d88ffe2010-02-04 21:25:3310100
tfarina42834112016-09-22 13:38:2010101 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110102 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]95d88ffe2010-02-04 21:25:3310103
10104 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0110105 EXPECT_THAT(rv, IsError(ERR_UPLOAD_FILE_CHANGED));
[email protected]95d88ffe2010-02-04 21:25:3310106
bnc691fda62016-08-12 00:43:1610107 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5210108 ASSERT_TRUE(response);
[email protected]95d88ffe2010-02-04 21:25:3310109
maksim.sisove869bf52016-06-23 17:11:5210110 EXPECT_FALSE(response->headers);
[email protected]95d88ffe2010-02-04 21:25:3310111
[email protected]dd3aa792013-07-16 19:10:2310112 base::DeleteFile(temp_file_path, false);
[email protected]95d88ffe2010-02-04 21:25:3310113}
10114
bncd16676a2016-07-20 16:23:0110115TEST_F(HttpNetworkTransactionTest, UploadUnreadableFile) {
[email protected]6cdfd7f2013-02-08 20:40:1510116 base::FilePath temp_file;
[email protected]03d9afc02013-12-03 17:55:5210117 ASSERT_TRUE(base::CreateTemporaryFile(&temp_file));
[email protected]6624b4622010-03-29 19:58:3610118 std::string temp_file_content("Unreadable file.");
lazyboy8df84fc2017-04-12 02:12:4810119 ASSERT_EQ(static_cast<int>(temp_file_content.length()),
10120 base::WriteFile(temp_file, temp_file_content.c_str(),
10121 temp_file_content.length()));
[email protected]92be8eb2014-08-07 22:57:1110122 ASSERT_TRUE(base::MakeFileUnreadable(temp_file));
[email protected]6624b4622010-03-29 19:58:3610123
danakj1fd259a02016-04-16 03:17:0910124 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
Jeremy Roman0579ed62017-08-29 15:56:1910125 element_readers.push_back(std::make_unique<UploadFileElementReader>(
avibf0746c2015-12-09 19:53:1410126 base::ThreadTaskRunnerHandle::Get().get(), temp_file, 0,
ricea2deef682016-09-09 08:04:0710127 std::numeric_limits<uint64_t>::max(), base::Time()));
olli.raula6df48b2a2015-11-26 07:40:2210128 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]329b68b2012-11-14 17:54:2710129
10130 HttpRequestInfo request;
10131 request.method = "POST";
bncce36dca22015-04-21 22:11:2310132 request.url = GURL("http://www.example.org/upload");
[email protected]329b68b2012-11-14 17:54:2710133 request.upload_data_stream = &upload_data_stream;
[email protected]329b68b2012-11-14 17:54:2710134
[email protected]999dd8c2013-11-12 06:45:5410135 // If we try to upload an unreadable file, the transaction should fail.
danakj1fd259a02016-04-16 03:17:0910136 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1610137 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]6624b4622010-03-29 19:58:3610138
[email protected]999dd8c2013-11-12 06:45:5410139 StaticSocketDataProvider data(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0710140 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]6624b4622010-03-29 19:58:3610141
[email protected]49639fa2011-12-20 23:22:4110142 TestCompletionCallback callback;
[email protected]6624b4622010-03-29 19:58:3610143
tfarina42834112016-09-22 13:38:2010144 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110145 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]6624b4622010-03-29 19:58:3610146
10147 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0110148 EXPECT_THAT(rv, IsError(ERR_ACCESS_DENIED));
[email protected]6624b4622010-03-29 19:58:3610149
[email protected]dd3aa792013-07-16 19:10:2310150 base::DeleteFile(temp_file, false);
[email protected]6624b4622010-03-29 19:58:3610151}
10152
bncd16676a2016-07-20 16:23:0110153TEST_F(HttpNetworkTransactionTest, CancelDuringInitRequestBody) {
[email protected]02cad5d2013-10-02 08:14:0310154 class FakeUploadElementReader : public UploadElementReader {
10155 public:
10156 FakeUploadElementReader() {}
dchengb03027d2014-10-21 12:00:2010157 ~FakeUploadElementReader() override {}
[email protected]02cad5d2013-10-02 08:14:0310158
10159 const CompletionCallback& callback() const { return callback_; }
10160
10161 // UploadElementReader overrides:
dchengb03027d2014-10-21 12:00:2010162 int Init(const CompletionCallback& callback) override {
[email protected]02cad5d2013-10-02 08:14:0310163 callback_ = callback;
10164 return ERR_IO_PENDING;
10165 }
avibf0746c2015-12-09 19:53:1410166 uint64_t GetContentLength() const override { return 0; }
10167 uint64_t BytesRemaining() const override { return 0; }
dchengb03027d2014-10-21 12:00:2010168 int Read(IOBuffer* buf,
10169 int buf_length,
10170 const CompletionCallback& callback) override {
[email protected]02cad5d2013-10-02 08:14:0310171 return ERR_FAILED;
10172 }
10173
10174 private:
10175 CompletionCallback callback_;
10176 };
10177
10178 FakeUploadElementReader* fake_reader = new FakeUploadElementReader;
danakj1fd259a02016-04-16 03:17:0910179 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
10180 element_readers.push_back(base::WrapUnique(fake_reader));
olli.raula6df48b2a2015-11-26 07:40:2210181 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]02cad5d2013-10-02 08:14:0310182
10183 HttpRequestInfo request;
10184 request.method = "POST";
bncce36dca22015-04-21 22:11:2310185 request.url = GURL("http://www.example.org/upload");
[email protected]02cad5d2013-10-02 08:14:0310186 request.upload_data_stream = &upload_data_stream;
[email protected]02cad5d2013-10-02 08:14:0310187
danakj1fd259a02016-04-16 03:17:0910188 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc87dcefc2017-05-25 12:47:5810189 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:1910190 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]02cad5d2013-10-02 08:14:0310191
10192 StaticSocketDataProvider data;
10193 session_deps_.socket_factory->AddSocketDataProvider(&data);
10194
10195 TestCompletionCallback callback;
tfarina42834112016-09-22 13:38:2010196 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110197 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
fdoray92e35a72016-06-10 15:54:5510198 base::RunLoop().RunUntilIdle();
[email protected]02cad5d2013-10-02 08:14:0310199
10200 // Transaction is pending on request body initialization.
10201 ASSERT_FALSE(fake_reader->callback().is_null());
10202
10203 // Return Init()'s result after the transaction gets destroyed.
10204 trans.reset();
10205 fake_reader->callback().Run(OK); // Should not crash.
10206}
10207
[email protected]aeefc9e82010-02-19 16:18:2710208// Tests that changes to Auth realms are treated like auth rejections.
bncd16676a2016-07-20 16:23:0110209TEST_F(HttpNetworkTransactionTest, ChangeAuthRealms) {
[email protected]aeefc9e82010-02-19 16:18:2710210 HttpRequestInfo request;
10211 request.method = "GET";
bncce36dca22015-04-21 22:11:2310212 request.url = GURL("http://www.example.org/");
[email protected]aeefc9e82010-02-19 16:18:2710213
10214 // First transaction will request a resource and receive a Basic challenge
10215 // with realm="first_realm".
10216 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:2310217 MockWrite(
10218 "GET / HTTP/1.1\r\n"
10219 "Host: www.example.org\r\n"
10220 "Connection: keep-alive\r\n"
10221 "\r\n"),
[email protected]aeefc9e82010-02-19 16:18:2710222 };
10223 MockRead data_reads1[] = {
10224 MockRead("HTTP/1.1 401 Unauthorized\r\n"
10225 "WWW-Authenticate: Basic realm=\"first_realm\"\r\n"
10226 "\r\n"),
10227 };
10228
bnc691fda62016-08-12 00:43:1610229 // After calling trans.RestartWithAuth(), provide an Authentication header
[email protected]aeefc9e82010-02-19 16:18:2710230 // for first_realm. The server will reject and provide a challenge with
10231 // second_realm.
10232 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:2310233 MockWrite(
10234 "GET / HTTP/1.1\r\n"
10235 "Host: www.example.org\r\n"
10236 "Connection: keep-alive\r\n"
10237 "Authorization: Basic Zmlyc3Q6YmF6\r\n"
10238 "\r\n"),
[email protected]aeefc9e82010-02-19 16:18:2710239 };
10240 MockRead data_reads2[] = {
10241 MockRead("HTTP/1.1 401 Unauthorized\r\n"
10242 "WWW-Authenticate: Basic realm=\"second_realm\"\r\n"
10243 "\r\n"),
10244 };
10245
10246 // This again fails, and goes back to first_realm. Make sure that the
10247 // entry is removed from cache.
10248 MockWrite data_writes3[] = {
bncce36dca22015-04-21 22:11:2310249 MockWrite(
10250 "GET / HTTP/1.1\r\n"
10251 "Host: www.example.org\r\n"
10252 "Connection: keep-alive\r\n"
10253 "Authorization: Basic c2Vjb25kOmZvdQ==\r\n"
10254 "\r\n"),
[email protected]aeefc9e82010-02-19 16:18:2710255 };
10256 MockRead data_reads3[] = {
10257 MockRead("HTTP/1.1 401 Unauthorized\r\n"
10258 "WWW-Authenticate: Basic realm=\"first_realm\"\r\n"
10259 "\r\n"),
10260 };
10261
10262 // Try one last time (with the correct password) and get the resource.
10263 MockWrite data_writes4[] = {
bncce36dca22015-04-21 22:11:2310264 MockWrite(
10265 "GET / HTTP/1.1\r\n"
10266 "Host: www.example.org\r\n"
10267 "Connection: keep-alive\r\n"
10268 "Authorization: Basic Zmlyc3Q6YmFy\r\n"
10269 "\r\n"),
[email protected]aeefc9e82010-02-19 16:18:2710270 };
10271 MockRead data_reads4[] = {
10272 MockRead("HTTP/1.1 200 OK\r\n"
10273 "Content-Type: text/html; charset=iso-8859-1\r\n"
[email protected]0b0bf032010-09-21 18:08:5010274 "Content-Length: 5\r\n"
10275 "\r\n"
10276 "hello"),
[email protected]aeefc9e82010-02-19 16:18:2710277 };
10278
10279 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
10280 data_writes1, arraysize(data_writes1));
10281 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
10282 data_writes2, arraysize(data_writes2));
10283 StaticSocketDataProvider data3(data_reads3, arraysize(data_reads3),
10284 data_writes3, arraysize(data_writes3));
10285 StaticSocketDataProvider data4(data_reads4, arraysize(data_reads4),
10286 data_writes4, arraysize(data_writes4));
[email protected]bb88e1d32013-05-03 23:11:0710287 session_deps_.socket_factory->AddSocketDataProvider(&data1);
10288 session_deps_.socket_factory->AddSocketDataProvider(&data2);
10289 session_deps_.socket_factory->AddSocketDataProvider(&data3);
10290 session_deps_.socket_factory->AddSocketDataProvider(&data4);
[email protected]aeefc9e82010-02-19 16:18:2710291
[email protected]49639fa2011-12-20 23:22:4110292 TestCompletionCallback callback1;
[email protected]aeefc9e82010-02-19 16:18:2710293
danakj1fd259a02016-04-16 03:17:0910294 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1610295 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]0b0bf032010-09-21 18:08:5010296
[email protected]aeefc9e82010-02-19 16:18:2710297 // Issue the first request with Authorize headers. There should be a
10298 // password prompt for first_realm waiting to be filled in after the
10299 // transaction completes.
tfarina42834112016-09-22 13:38:2010300 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110301 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]aeefc9e82010-02-19 16:18:2710302 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:0110303 EXPECT_THAT(rv, IsOk());
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 const AuthChallengeInfo* challenge = response->auth_challenge.get();
wezca1070932016-05-26 20:30:5210307 ASSERT_TRUE(challenge);
[email protected]79cb5c12011-09-12 13:12:0410308 EXPECT_FALSE(challenge->is_proxy);
asanka098c0092016-06-16 20:18:4310309 EXPECT_EQ("http://www.example.org", challenge->challenger.Serialize());
[email protected]79cb5c12011-09-12 13:12:0410310 EXPECT_EQ("first_realm", challenge->realm);
aberentbba302d2015-12-03 10:20:1910311 EXPECT_EQ(kBasicAuthScheme, challenge->scheme);
[email protected]aeefc9e82010-02-19 16:18:2710312
10313 // Issue the second request with an incorrect password. There should be a
10314 // password prompt for second_realm waiting to be filled in after the
10315 // transaction completes.
[email protected]49639fa2011-12-20 23:22:4110316 TestCompletionCallback callback2;
bnc691fda62016-08-12 00:43:1610317 rv = trans.RestartWithAuth(AuthCredentials(kFirst, kBaz),
10318 callback2.callback());
robpercival214763f2016-07-01 23:27:0110319 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]aeefc9e82010-02-19 16:18:2710320 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:0110321 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:1610322 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5210323 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:0410324 challenge = response->auth_challenge.get();
wezca1070932016-05-26 20:30:5210325 ASSERT_TRUE(challenge);
[email protected]79cb5c12011-09-12 13:12:0410326 EXPECT_FALSE(challenge->is_proxy);
asanka098c0092016-06-16 20:18:4310327 EXPECT_EQ("http://www.example.org", challenge->challenger.Serialize());
[email protected]79cb5c12011-09-12 13:12:0410328 EXPECT_EQ("second_realm", challenge->realm);
aberentbba302d2015-12-03 10:20:1910329 EXPECT_EQ(kBasicAuthScheme, challenge->scheme);
[email protected]aeefc9e82010-02-19 16:18:2710330
10331 // Issue the third request with another incorrect password. There should be
10332 // a password prompt for first_realm waiting to be filled in. If the password
10333 // prompt is not present, it indicates that the HttpAuthCacheEntry for
10334 // first_realm was not correctly removed.
[email protected]49639fa2011-12-20 23:22:4110335 TestCompletionCallback callback3;
bnc691fda62016-08-12 00:43:1610336 rv = trans.RestartWithAuth(AuthCredentials(kSecond, kFou),
10337 callback3.callback());
robpercival214763f2016-07-01 23:27:0110338 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]aeefc9e82010-02-19 16:18:2710339 rv = callback3.WaitForResult();
robpercival214763f2016-07-01 23:27:0110340 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:1610341 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5210342 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:0410343 challenge = response->auth_challenge.get();
wezca1070932016-05-26 20:30:5210344 ASSERT_TRUE(challenge);
[email protected]79cb5c12011-09-12 13:12:0410345 EXPECT_FALSE(challenge->is_proxy);
asanka098c0092016-06-16 20:18:4310346 EXPECT_EQ("http://www.example.org", challenge->challenger.Serialize());
[email protected]79cb5c12011-09-12 13:12:0410347 EXPECT_EQ("first_realm", challenge->realm);
aberentbba302d2015-12-03 10:20:1910348 EXPECT_EQ(kBasicAuthScheme, challenge->scheme);
[email protected]aeefc9e82010-02-19 16:18:2710349
10350 // Issue the fourth request with the correct password and username.
[email protected]49639fa2011-12-20 23:22:4110351 TestCompletionCallback callback4;
bnc691fda62016-08-12 00:43:1610352 rv = trans.RestartWithAuth(AuthCredentials(kFirst, kBar),
10353 callback4.callback());
robpercival214763f2016-07-01 23:27:0110354 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]aeefc9e82010-02-19 16:18:2710355 rv = callback4.WaitForResult();
robpercival214763f2016-07-01 23:27:0110356 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:1610357 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5210358 ASSERT_TRUE(response);
10359 EXPECT_FALSE(response->auth_challenge);
[email protected]aeefc9e82010-02-19 16:18:2710360}
10361
Bence Béky230ac612017-08-30 19:17:0810362// Regression test for https://crbug.com/754395.
10363TEST_F(HttpNetworkTransactionTest, IgnoreAltSvcWithInvalidCert) {
10364 MockRead data_reads[] = {
10365 MockRead("HTTP/1.1 200 OK\r\n"),
10366 MockRead(kAlternativeServiceHttpHeader),
10367 MockRead("\r\n"),
10368 MockRead("hello world"),
10369 MockRead(SYNCHRONOUS, OK),
10370 };
10371
10372 HttpRequestInfo request;
10373 request.method = "GET";
10374 request.url = GURL("https://www.example.org/");
10375
10376 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
10377 session_deps_.socket_factory->AddSocketDataProvider(&data);
10378
10379 SSLSocketDataProvider ssl(ASYNC, OK);
10380 ssl.cert = ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem");
10381 ASSERT_TRUE(ssl.cert);
10382 ssl.cert_status = CERT_STATUS_COMMON_NAME_INVALID;
10383 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
10384
10385 TestCompletionCallback callback;
10386
10387 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
10388 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
10389
10390 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
10391 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
10392
10393 url::SchemeHostPort test_server(request.url);
10394 HttpServerProperties* http_server_properties =
10395 session->http_server_properties();
10396 EXPECT_TRUE(
10397 http_server_properties->GetAlternativeServiceInfos(test_server).empty());
10398
10399 EXPECT_THAT(callback.WaitForResult(), IsOk());
10400
10401 const HttpResponseInfo* response = trans.GetResponseInfo();
10402 ASSERT_TRUE(response);
10403 ASSERT_TRUE(response->headers);
10404 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
10405 EXPECT_FALSE(response->was_fetched_via_spdy);
10406 EXPECT_FALSE(response->was_alpn_negotiated);
10407
10408 std::string response_data;
10409 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
10410 EXPECT_EQ("hello world", response_data);
10411
10412 EXPECT_TRUE(
10413 http_server_properties->GetAlternativeServiceInfos(test_server).empty());
10414}
10415
bncd16676a2016-07-20 16:23:0110416TEST_F(HttpNetworkTransactionTest, HonorAlternativeServiceHeader) {
bncc958faa2015-07-31 18:14:5210417 MockRead data_reads[] = {
10418 MockRead("HTTP/1.1 200 OK\r\n"),
bnc2df4b522016-07-08 18:17:4310419 MockRead(kAlternativeServiceHttpHeader),
bncc958faa2015-07-31 18:14:5210420 MockRead("\r\n"),
10421 MockRead("hello world"),
10422 MockRead(SYNCHRONOUS, OK),
10423 };
10424
10425 HttpRequestInfo request;
10426 request.method = "GET";
bncb26024382016-06-29 02:39:4510427 request.url = GURL("https://www.example.org/");
bncc958faa2015-07-31 18:14:5210428
10429 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
bncc958faa2015-07-31 18:14:5210430 session_deps_.socket_factory->AddSocketDataProvider(&data);
10431
bncb26024382016-06-29 02:39:4510432 SSLSocketDataProvider ssl(ASYNC, OK);
Bence Béky230ac612017-08-30 19:17:0810433 ssl.cert = ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem");
10434 ASSERT_TRUE(ssl.cert);
bncb26024382016-06-29 02:39:4510435 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
10436
bncc958faa2015-07-31 18:14:5210437 TestCompletionCallback callback;
10438
danakj1fd259a02016-04-16 03:17:0910439 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1610440 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
bncc958faa2015-07-31 18:14:5210441
tfarina42834112016-09-22 13:38:2010442 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110443 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
bncc958faa2015-07-31 18:14:5210444
bncb26024382016-06-29 02:39:4510445 url::SchemeHostPort test_server(request.url);
bnc525e175a2016-06-20 12:36:4010446 HttpServerProperties* http_server_properties =
10447 session->http_server_properties();
zhongyic4de03032017-05-19 04:07:3410448 EXPECT_TRUE(
10449 http_server_properties->GetAlternativeServiceInfos(test_server).empty());
bncc958faa2015-07-31 18:14:5210450
robpercival214763f2016-07-01 23:27:0110451 EXPECT_THAT(callback.WaitForResult(), IsOk());
bncc958faa2015-07-31 18:14:5210452
bnc691fda62016-08-12 00:43:1610453 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5210454 ASSERT_TRUE(response);
10455 ASSERT_TRUE(response->headers);
bncc958faa2015-07-31 18:14:5210456 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
10457 EXPECT_FALSE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5210458 EXPECT_FALSE(response->was_alpn_negotiated);
bncc958faa2015-07-31 18:14:5210459
10460 std::string response_data;
bnc691fda62016-08-12 00:43:1610461 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
bncc958faa2015-07-31 18:14:5210462 EXPECT_EQ("hello world", response_data);
10463
zhongyic4de03032017-05-19 04:07:3410464 AlternativeServiceInfoVector alternative_service_info_vector =
10465 http_server_properties->GetAlternativeServiceInfos(test_server);
10466 ASSERT_EQ(1u, alternative_service_info_vector.size());
10467 AlternativeService alternative_service(kProtoHTTP2, "mail.example.org", 443);
10468 EXPECT_EQ(alternative_service,
zhongyi422ce352017-06-09 23:28:5410469 alternative_service_info_vector[0].alternative_service());
bncc958faa2015-07-31 18:14:5210470}
10471
bnce3dd56f2016-06-01 10:37:1110472// Regression test for https://crbug.com/615497.
bncd16676a2016-07-20 16:23:0110473TEST_F(HttpNetworkTransactionTest,
bnce3dd56f2016-06-01 10:37:1110474 DoNotParseAlternativeServiceHeaderOnInsecureRequest) {
bnce3dd56f2016-06-01 10:37:1110475 MockRead data_reads[] = {
10476 MockRead("HTTP/1.1 200 OK\r\n"),
bnc2df4b522016-07-08 18:17:4310477 MockRead(kAlternativeServiceHttpHeader),
bnce3dd56f2016-06-01 10:37:1110478 MockRead("\r\n"),
10479 MockRead("hello world"),
10480 MockRead(SYNCHRONOUS, OK),
10481 };
10482
10483 HttpRequestInfo request;
10484 request.method = "GET";
10485 request.url = GURL("http://www.example.org/");
10486 request.load_flags = 0;
10487
10488 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
10489 session_deps_.socket_factory->AddSocketDataProvider(&data);
10490
10491 TestCompletionCallback callback;
10492
10493 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1610494 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
bnce3dd56f2016-06-01 10:37:1110495
10496 url::SchemeHostPort test_server(request.url);
bnc525e175a2016-06-20 12:36:4010497 HttpServerProperties* http_server_properties =
10498 session->http_server_properties();
zhongyic4de03032017-05-19 04:07:3410499 EXPECT_TRUE(
10500 http_server_properties->GetAlternativeServiceInfos(test_server).empty());
bnce3dd56f2016-06-01 10:37:1110501
tfarina42834112016-09-22 13:38:2010502 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110503 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
10504 EXPECT_THAT(callback.WaitForResult(), IsOk());
bnce3dd56f2016-06-01 10:37:1110505
bnc691fda62016-08-12 00:43:1610506 const HttpResponseInfo* response = trans.GetResponseInfo();
bnce3dd56f2016-06-01 10:37:1110507 ASSERT_TRUE(response);
10508 ASSERT_TRUE(response->headers);
10509 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
10510 EXPECT_FALSE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5210511 EXPECT_FALSE(response->was_alpn_negotiated);
bnce3dd56f2016-06-01 10:37:1110512
10513 std::string response_data;
bnc691fda62016-08-12 00:43:1610514 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
bnce3dd56f2016-06-01 10:37:1110515 EXPECT_EQ("hello world", response_data);
10516
zhongyic4de03032017-05-19 04:07:3410517 EXPECT_TRUE(
10518 http_server_properties->GetAlternativeServiceInfos(test_server).empty());
bnce3dd56f2016-06-01 10:37:1110519}
10520
bnca86731e2017-04-17 12:31:2810521// HTTP/2 Alternative Services should be disabled by default.
bnc8bef8da22016-05-30 01:28:2510522// TODO(bnc): Remove when https://crbug.com/615413 is fixed.
bncd16676a2016-07-20 16:23:0110523TEST_F(HttpNetworkTransactionTest,
bnc8bef8da22016-05-30 01:28:2510524 DisableHTTP2AlternativeServicesWithDifferentHost) {
bnca86731e2017-04-17 12:31:2810525 session_deps_.enable_http2_alternative_service = false;
bncb26024382016-06-29 02:39:4510526
bnc8bef8da22016-05-30 01:28:2510527 HttpRequestInfo request;
10528 request.method = "GET";
bncb26024382016-06-29 02:39:4510529 request.url = GURL("https://www.example.org/");
bnc8bef8da22016-05-30 01:28:2510530 request.load_flags = 0;
10531
10532 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
10533 StaticSocketDataProvider first_data;
10534 first_data.set_connect_data(mock_connect);
10535 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
bncb26024382016-06-29 02:39:4510536 SSLSocketDataProvider ssl_http11(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3610537 ssl_http11.next_proto = kProtoHTTP11;
bncb26024382016-06-29 02:39:4510538 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_http11);
bnc8bef8da22016-05-30 01:28:2510539
10540 MockRead data_reads[] = {
10541 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello world"),
10542 MockRead(ASYNC, OK),
10543 };
10544 StaticSocketDataProvider second_data(data_reads, arraysize(data_reads), NULL,
10545 0);
10546 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
10547
10548 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
10549
bnc525e175a2016-06-20 12:36:4010550 HttpServerProperties* http_server_properties =
bnc8bef8da22016-05-30 01:28:2510551 session->http_server_properties();
bnc3472afd2016-11-17 15:27:2110552 AlternativeService alternative_service(kProtoHTTP2, "different.example.org",
10553 444);
bnc8bef8da22016-05-30 01:28:2510554 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:2110555 http_server_properties->SetHttp2AlternativeService(
bnc8bef8da22016-05-30 01:28:2510556 url::SchemeHostPort(request.url), alternative_service, expiration);
10557
bnc691fda62016-08-12 00:43:1610558 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
bnc8bef8da22016-05-30 01:28:2510559 TestCompletionCallback callback;
10560
tfarina42834112016-09-22 13:38:2010561 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
bnc8bef8da22016-05-30 01:28:2510562 // Alternative service is not used, request fails.
robpercival214763f2016-07-01 23:27:0110563 EXPECT_THAT(callback.GetResult(rv), IsError(ERR_CONNECTION_REFUSED));
bnc8bef8da22016-05-30 01:28:2510564}
10565
bnce3dd56f2016-06-01 10:37:1110566// Regression test for https://crbug.com/615497:
10567// Alternative Services should be disabled for http origin.
bncd16676a2016-07-20 16:23:0110568TEST_F(HttpNetworkTransactionTest,
bnce3dd56f2016-06-01 10:37:1110569 DisableAlternativeServicesForInsecureOrigin) {
bnce3dd56f2016-06-01 10:37:1110570 HttpRequestInfo request;
10571 request.method = "GET";
10572 request.url = GURL("http://www.example.org/");
10573 request.load_flags = 0;
10574
10575 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
10576 StaticSocketDataProvider first_data;
10577 first_data.set_connect_data(mock_connect);
10578 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
10579
10580 MockRead data_reads[] = {
10581 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello world"),
10582 MockRead(ASYNC, OK),
10583 };
10584 StaticSocketDataProvider second_data(data_reads, arraysize(data_reads), NULL,
10585 0);
10586 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
10587
10588 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
10589
bnc525e175a2016-06-20 12:36:4010590 HttpServerProperties* http_server_properties =
bnce3dd56f2016-06-01 10:37:1110591 session->http_server_properties();
bnc3472afd2016-11-17 15:27:2110592 AlternativeService alternative_service(kProtoHTTP2, "", 444);
bnce3dd56f2016-06-01 10:37:1110593 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:2110594 http_server_properties->SetHttp2AlternativeService(
bnce3dd56f2016-06-01 10:37:1110595 url::SchemeHostPort(request.url), alternative_service, expiration);
10596
bnc691fda62016-08-12 00:43:1610597 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
bnce3dd56f2016-06-01 10:37:1110598 TestCompletionCallback callback;
10599
tfarina42834112016-09-22 13:38:2010600 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
bnce3dd56f2016-06-01 10:37:1110601 // Alternative service is not used, request fails.
robpercival214763f2016-07-01 23:27:0110602 EXPECT_THAT(callback.GetResult(rv), IsError(ERR_CONNECTION_REFUSED));
bnce3dd56f2016-06-01 10:37:1110603}
10604
bncd16676a2016-07-20 16:23:0110605TEST_F(HttpNetworkTransactionTest, ClearAlternativeServices) {
bnc4f575852015-10-14 18:35:0810606 // Set an alternative service for origin.
danakj1fd259a02016-04-16 03:17:0910607 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc525e175a2016-06-20 12:36:4010608 HttpServerProperties* http_server_properties =
10609 session->http_server_properties();
bncb26024382016-06-29 02:39:4510610 url::SchemeHostPort test_server("https", "www.example.org", 443);
bnc3472afd2016-11-17 15:27:2110611 AlternativeService alternative_service(kProtoQUIC, "", 80);
bnc4f575852015-10-14 18:35:0810612 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:2110613 http_server_properties->SetQuicAlternativeService(
10614 test_server, alternative_service, expiration,
10615 session->params().quic_supported_versions);
zhongyic4de03032017-05-19 04:07:3410616 EXPECT_EQ(
10617 1u,
10618 http_server_properties->GetAlternativeServiceInfos(test_server).size());
bnc4f575852015-10-14 18:35:0810619
10620 // Send a clear header.
10621 MockRead data_reads[] = {
10622 MockRead("HTTP/1.1 200 OK\r\n"),
10623 MockRead("Alt-Svc: clear\r\n"),
10624 MockRead("\r\n"),
10625 MockRead("hello world"),
10626 MockRead(SYNCHRONOUS, OK),
10627 };
10628 StaticSocketDataProvider data(data_reads, arraysize(data_reads), nullptr, 0);
10629 session_deps_.socket_factory->AddSocketDataProvider(&data);
10630
bncb26024382016-06-29 02:39:4510631 SSLSocketDataProvider ssl(ASYNC, OK);
Bence Béky230ac612017-08-30 19:17:0810632 ssl.cert = ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem");
10633 ASSERT_TRUE(ssl.cert);
bncb26024382016-06-29 02:39:4510634 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
10635
bnc4f575852015-10-14 18:35:0810636 HttpRequestInfo request;
10637 request.method = "GET";
bncb26024382016-06-29 02:39:4510638 request.url = GURL("https://www.example.org/");
bnc4f575852015-10-14 18:35:0810639
10640 TestCompletionCallback callback;
10641
bnc691fda62016-08-12 00:43:1610642 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
bnc4f575852015-10-14 18:35:0810643
tfarina42834112016-09-22 13:38:2010644 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110645 EXPECT_THAT(callback.GetResult(rv), IsOk());
bnc4f575852015-10-14 18:35:0810646
bnc691fda62016-08-12 00:43:1610647 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5210648 ASSERT_TRUE(response);
10649 ASSERT_TRUE(response->headers);
bnc4f575852015-10-14 18:35:0810650 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
10651 EXPECT_FALSE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5210652 EXPECT_FALSE(response->was_alpn_negotiated);
bnc4f575852015-10-14 18:35:0810653
10654 std::string response_data;
bnc691fda62016-08-12 00:43:1610655 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
bnc4f575852015-10-14 18:35:0810656 EXPECT_EQ("hello world", response_data);
10657
zhongyic4de03032017-05-19 04:07:3410658 EXPECT_TRUE(
10659 http_server_properties->GetAlternativeServiceInfos(test_server).empty());
bnc4f575852015-10-14 18:35:0810660}
10661
bncd16676a2016-07-20 16:23:0110662TEST_F(HttpNetworkTransactionTest, HonorMultipleAlternativeServiceHeaders) {
bncc958faa2015-07-31 18:14:5210663 MockRead data_reads[] = {
10664 MockRead("HTTP/1.1 200 OK\r\n"),
bnc2df4b522016-07-08 18:17:4310665 MockRead("Alt-Svc: h2=\"www.example.com:443\","),
10666 MockRead("h2=\":1234\"\r\n\r\n"),
bncc958faa2015-07-31 18:14:5210667 MockRead("hello world"),
10668 MockRead(SYNCHRONOUS, OK),
10669 };
10670
10671 HttpRequestInfo request;
10672 request.method = "GET";
bncb26024382016-06-29 02:39:4510673 request.url = GURL("https://www.example.org/");
bncc958faa2015-07-31 18:14:5210674
10675 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
bncc958faa2015-07-31 18:14:5210676 session_deps_.socket_factory->AddSocketDataProvider(&data);
10677
bncb26024382016-06-29 02:39:4510678 SSLSocketDataProvider ssl(ASYNC, OK);
Bence Béky230ac612017-08-30 19:17:0810679 ssl.cert = ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem");
10680 ASSERT_TRUE(ssl.cert);
bncb26024382016-06-29 02:39:4510681 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
10682
bncc958faa2015-07-31 18:14:5210683 TestCompletionCallback callback;
10684
danakj1fd259a02016-04-16 03:17:0910685 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1610686 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
bncc958faa2015-07-31 18:14:5210687
tfarina42834112016-09-22 13:38:2010688 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110689 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
bncc958faa2015-07-31 18:14:5210690
bncb26024382016-06-29 02:39:4510691 url::SchemeHostPort test_server("https", "www.example.org", 443);
bnc525e175a2016-06-20 12:36:4010692 HttpServerProperties* http_server_properties =
10693 session->http_server_properties();
zhongyic4de03032017-05-19 04:07:3410694 EXPECT_TRUE(
10695 http_server_properties->GetAlternativeServiceInfos(test_server).empty());
bncc958faa2015-07-31 18:14:5210696
robpercival214763f2016-07-01 23:27:0110697 EXPECT_THAT(callback.WaitForResult(), IsOk());
bncc958faa2015-07-31 18:14:5210698
bnc691fda62016-08-12 00:43:1610699 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5210700 ASSERT_TRUE(response);
10701 ASSERT_TRUE(response->headers);
bncc958faa2015-07-31 18:14:5210702 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
10703 EXPECT_FALSE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5210704 EXPECT_FALSE(response->was_alpn_negotiated);
bncc958faa2015-07-31 18:14:5210705
10706 std::string response_data;
bnc691fda62016-08-12 00:43:1610707 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
bncc958faa2015-07-31 18:14:5210708 EXPECT_EQ("hello world", response_data);
10709
zhongyic4de03032017-05-19 04:07:3410710 AlternativeServiceInfoVector alternative_service_info_vector =
10711 http_server_properties->GetAlternativeServiceInfos(test_server);
10712 ASSERT_EQ(2u, alternative_service_info_vector.size());
10713
10714 AlternativeService alternative_service(kProtoHTTP2, "www.example.com", 443);
10715 EXPECT_EQ(alternative_service,
zhongyi422ce352017-06-09 23:28:5410716 alternative_service_info_vector[0].alternative_service());
zhongyic4de03032017-05-19 04:07:3410717 AlternativeService alternative_service_2(kProtoHTTP2, "www.example.org",
10718 1234);
10719 EXPECT_EQ(alternative_service_2,
zhongyi422ce352017-06-09 23:28:5410720 alternative_service_info_vector[1].alternative_service());
bncc958faa2015-07-31 18:14:5210721}
10722
bncd16676a2016-07-20 16:23:0110723TEST_F(HttpNetworkTransactionTest, IdentifyQuicBroken) {
zhongyi3d4a55e72016-04-22 20:36:4610724 url::SchemeHostPort server("https", "origin.example.org", 443);
zhongyi48704c182015-12-07 07:52:0210725 HostPortPair alternative("alternative.example.org", 443);
10726 std::string origin_url = "https://origin.example.org:443";
10727 std::string alternative_url = "https://alternative.example.org:443";
10728
10729 // Negotiate HTTP/1.1 with alternative.example.org.
10730 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3610731 ssl.next_proto = kProtoHTTP11;
zhongyi48704c182015-12-07 07:52:0210732 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
10733
10734 // HTTP/1.1 data for request.
10735 MockWrite http_writes[] = {
10736 MockWrite("GET / HTTP/1.1\r\n"
10737 "Host: alternative.example.org\r\n"
10738 "Connection: keep-alive\r\n\r\n"),
10739 };
10740
10741 MockRead http_reads[] = {
10742 MockRead("HTTP/1.1 200 OK\r\n"
10743 "Content-Type: text/html; charset=iso-8859-1\r\n"
10744 "Content-Length: 40\r\n\r\n"
10745 "first HTTP/1.1 response from alternative"),
10746 };
10747 StaticSocketDataProvider http_data(http_reads, arraysize(http_reads),
10748 http_writes, arraysize(http_writes));
10749 session_deps_.socket_factory->AddSocketDataProvider(&http_data);
10750
10751 StaticSocketDataProvider data_refused;
10752 data_refused.set_connect_data(MockConnect(ASYNC, ERR_CONNECTION_REFUSED));
10753 session_deps_.socket_factory->AddSocketDataProvider(&data_refused);
10754
zhongyi3d4a55e72016-04-22 20:36:4610755 // Set up a QUIC alternative service for server.
danakj1fd259a02016-04-16 03:17:0910756 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc525e175a2016-06-20 12:36:4010757 HttpServerProperties* http_server_properties =
zhongyi48704c182015-12-07 07:52:0210758 session->http_server_properties();
bnc3472afd2016-11-17 15:27:2110759 AlternativeService alternative_service(kProtoQUIC, alternative);
zhongyi48704c182015-12-07 07:52:0210760 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:2110761 http_server_properties->SetQuicAlternativeService(
10762 server, alternative_service, expiration,
10763 HttpNetworkSession::Params().quic_supported_versions);
zhongyi48704c182015-12-07 07:52:0210764 // Mark the QUIC alternative service as broken.
10765 http_server_properties->MarkAlternativeServiceBroken(alternative_service);
10766
zhongyi48704c182015-12-07 07:52:0210767 HttpRequestInfo request;
krasinc06a72a2016-12-21 03:42:4610768 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
zhongyi48704c182015-12-07 07:52:0210769 request.method = "GET";
10770 request.url = GURL(origin_url);
zhongyi48704c182015-12-07 07:52:0210771 TestCompletionCallback callback;
10772 NetErrorDetails details;
10773 EXPECT_FALSE(details.quic_broken);
10774
tfarina42834112016-09-22 13:38:2010775 trans.Start(&request, callback.callback(), NetLogWithSource());
bnc691fda62016-08-12 00:43:1610776 trans.PopulateNetErrorDetails(&details);
zhongyi48704c182015-12-07 07:52:0210777 EXPECT_TRUE(details.quic_broken);
10778}
10779
bncd16676a2016-07-20 16:23:0110780TEST_F(HttpNetworkTransactionTest, IdentifyQuicNotBroken) {
zhongyi3d4a55e72016-04-22 20:36:4610781 url::SchemeHostPort server("https", "origin.example.org", 443);
zhongyi48704c182015-12-07 07:52:0210782 HostPortPair alternative1("alternative1.example.org", 443);
10783 HostPortPair alternative2("alternative2.example.org", 443);
10784 std::string origin_url = "https://origin.example.org:443";
10785 std::string alternative_url1 = "https://alternative1.example.org:443";
10786 std::string alternative_url2 = "https://alternative2.example.org:443";
10787
10788 // Negotiate HTTP/1.1 with alternative1.example.org.
10789 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3610790 ssl.next_proto = kProtoHTTP11;
zhongyi48704c182015-12-07 07:52:0210791 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
10792
10793 // HTTP/1.1 data for request.
10794 MockWrite http_writes[] = {
10795 MockWrite("GET / HTTP/1.1\r\n"
10796 "Host: alternative1.example.org\r\n"
10797 "Connection: keep-alive\r\n\r\n"),
10798 };
10799
10800 MockRead http_reads[] = {
10801 MockRead("HTTP/1.1 200 OK\r\n"
10802 "Content-Type: text/html; charset=iso-8859-1\r\n"
10803 "Content-Length: 40\r\n\r\n"
10804 "first HTTP/1.1 response from alternative1"),
10805 };
10806 StaticSocketDataProvider http_data(http_reads, arraysize(http_reads),
10807 http_writes, arraysize(http_writes));
10808 session_deps_.socket_factory->AddSocketDataProvider(&http_data);
10809
10810 StaticSocketDataProvider data_refused;
10811 data_refused.set_connect_data(MockConnect(ASYNC, ERR_CONNECTION_REFUSED));
10812 session_deps_.socket_factory->AddSocketDataProvider(&data_refused);
10813
danakj1fd259a02016-04-16 03:17:0910814 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc525e175a2016-06-20 12:36:4010815 HttpServerProperties* http_server_properties =
zhongyi48704c182015-12-07 07:52:0210816 session->http_server_properties();
10817
zhongyi3d4a55e72016-04-22 20:36:4610818 // Set up two QUIC alternative services for server.
zhongyi48704c182015-12-07 07:52:0210819 AlternativeServiceInfoVector alternative_service_info_vector;
10820 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
10821
bnc3472afd2016-11-17 15:27:2110822 AlternativeService alternative_service1(kProtoQUIC, alternative1);
zhongyie537a002017-06-27 16:48:2110823 alternative_service_info_vector.push_back(
10824 AlternativeServiceInfo::CreateQuicAlternativeServiceInfo(
10825 alternative_service1, expiration,
10826 session->params().quic_supported_versions));
bnc3472afd2016-11-17 15:27:2110827 AlternativeService alternative_service2(kProtoQUIC, alternative2);
zhongyie537a002017-06-27 16:48:2110828 alternative_service_info_vector.push_back(
10829 AlternativeServiceInfo::CreateQuicAlternativeServiceInfo(
10830 alternative_service2, expiration,
10831 session->params().quic_supported_versions));
zhongyi48704c182015-12-07 07:52:0210832
10833 http_server_properties->SetAlternativeServices(
zhongyi3d4a55e72016-04-22 20:36:4610834 server, alternative_service_info_vector);
zhongyi48704c182015-12-07 07:52:0210835
10836 // Mark one of the QUIC alternative service as broken.
10837 http_server_properties->MarkAlternativeServiceBroken(alternative_service1);
zhongyic4de03032017-05-19 04:07:3410838 EXPECT_EQ(2u,
10839 http_server_properties->GetAlternativeServiceInfos(server).size());
zhongyi48704c182015-12-07 07:52:0210840
zhongyi48704c182015-12-07 07:52:0210841 HttpRequestInfo request;
krasinc06a72a2016-12-21 03:42:4610842 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
zhongyi48704c182015-12-07 07:52:0210843 request.method = "GET";
10844 request.url = GURL(origin_url);
zhongyi48704c182015-12-07 07:52:0210845 TestCompletionCallback callback;
10846 NetErrorDetails details;
10847 EXPECT_FALSE(details.quic_broken);
10848
tfarina42834112016-09-22 13:38:2010849 trans.Start(&request, callback.callback(), NetLogWithSource());
bnc691fda62016-08-12 00:43:1610850 trans.PopulateNetErrorDetails(&details);
zhongyi48704c182015-12-07 07:52:0210851 EXPECT_FALSE(details.quic_broken);
10852}
10853
bncd16676a2016-07-20 16:23:0110854TEST_F(HttpNetworkTransactionTest, MarkBrokenAlternateProtocolAndFallback) {
[email protected]564b4912010-03-09 16:30:4210855 HttpRequestInfo request;
10856 request.method = "GET";
bncb26024382016-06-29 02:39:4510857 request.url = GURL("https://www.example.org/");
[email protected]564b4912010-03-09 16:30:4210858
[email protected]d973e99a2012-02-17 21:02:3610859 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
[email protected]564b4912010-03-09 16:30:4210860 StaticSocketDataProvider first_data;
10861 first_data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:0710862 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
bncb26024382016-06-29 02:39:4510863 SSLSocketDataProvider ssl_http11(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3610864 ssl_http11.next_proto = kProtoHTTP11;
bncb26024382016-06-29 02:39:4510865 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_http11);
[email protected]564b4912010-03-09 16:30:4210866
10867 MockRead data_reads[] = {
10868 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
10869 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:0610870 MockRead(ASYNC, OK),
[email protected]564b4912010-03-09 16:30:4210871 };
10872 StaticSocketDataProvider second_data(
10873 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0710874 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
[email protected]564b4912010-03-09 16:30:4210875
danakj1fd259a02016-04-16 03:17:0910876 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]564b4912010-03-09 16:30:4210877
bnc525e175a2016-06-20 12:36:4010878 HttpServerProperties* http_server_properties =
[email protected]17291a022011-10-10 07:32:5310879 session->http_server_properties();
zhongyi3d4a55e72016-04-22 20:36:4610880 const url::SchemeHostPort server(request.url);
[email protected]3912662a32011-10-04 00:51:1110881 // Port must be < 1024, or the header will be ignored (since initial port was
10882 // port 80 (another restricted port).
zhongyie537a002017-06-27 16:48:2110883 // Port is ignored by MockConnect anyway.
10884 const AlternativeService alternative_service(kProtoHTTP2, "www.example.org",
10885 666);
bnc7dc7e1b42015-07-28 14:43:1210886 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:2110887 http_server_properties->SetHttp2AlternativeService(
10888 server, alternative_service, expiration);
[email protected]564b4912010-03-09 16:30:4210889
bnc691fda62016-08-12 00:43:1610890 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]49639fa2011-12-20 23:22:4110891 TestCompletionCallback callback;
[email protected]564b4912010-03-09 16:30:4210892
tfarina42834112016-09-22 13:38:2010893 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110894 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
10895 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]564b4912010-03-09 16:30:4210896
bnc691fda62016-08-12 00:43:1610897 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5210898 ASSERT_TRUE(response);
10899 ASSERT_TRUE(response->headers);
[email protected]564b4912010-03-09 16:30:4210900 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
10901
10902 std::string response_data;
bnc691fda62016-08-12 00:43:1610903 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
[email protected]564b4912010-03-09 16:30:4210904 EXPECT_EQ("hello world", response_data);
10905
zhongyic4de03032017-05-19 04:07:3410906 const AlternativeServiceInfoVector alternative_service_info_vector =
10907 http_server_properties->GetAlternativeServiceInfos(server);
10908 ASSERT_EQ(1u, alternative_service_info_vector.size());
10909 EXPECT_EQ(alternative_service,
zhongyi422ce352017-06-09 23:28:5410910 alternative_service_info_vector[0].alternative_service());
zhongyic4de03032017-05-19 04:07:3410911 EXPECT_TRUE(
10912 http_server_properties->IsAlternativeServiceBroken(alternative_service));
[email protected]564b4912010-03-09 16:30:4210913}
10914
bnc55ff9da2015-08-19 18:42:3510915// Ensure that we are not allowed to redirect traffic via an alternate protocol
10916// to an unrestricted (port >= 1024) when the original traffic was on a
10917// restricted port (port < 1024). Ensure that we can redirect in all other
10918// cases.
bncd16676a2016-07-20 16:23:0110919TEST_F(HttpNetworkTransactionTest, AlternateProtocolPortRestrictedBlocked) {
[email protected]3912662a32011-10-04 00:51:1110920 HttpRequestInfo restricted_port_request;
10921 restricted_port_request.method = "GET";
bncb26024382016-06-29 02:39:4510922 restricted_port_request.url = GURL("https://www.example.org:1023/");
[email protected]3912662a32011-10-04 00:51:1110923 restricted_port_request.load_flags = 0;
10924
[email protected]d973e99a2012-02-17 21:02:3610925 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
[email protected]3912662a32011-10-04 00:51:1110926 StaticSocketDataProvider first_data;
10927 first_data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:0710928 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
[email protected]3912662a32011-10-04 00:51:1110929
10930 MockRead data_reads[] = {
10931 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
10932 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:0610933 MockRead(ASYNC, OK),
[email protected]3912662a32011-10-04 00:51:1110934 };
10935 StaticSocketDataProvider second_data(
10936 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0710937 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
bncb26024382016-06-29 02:39:4510938 SSLSocketDataProvider ssl_http11(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3610939 ssl_http11.next_proto = kProtoHTTP11;
bncb26024382016-06-29 02:39:4510940 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_http11);
[email protected]3912662a32011-10-04 00:51:1110941
danakj1fd259a02016-04-16 03:17:0910942 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]3912662a32011-10-04 00:51:1110943
bnc525e175a2016-06-20 12:36:4010944 HttpServerProperties* http_server_properties =
[email protected]17291a022011-10-10 07:32:5310945 session->http_server_properties();
[email protected]3912662a32011-10-04 00:51:1110946 const int kUnrestrictedAlternatePort = 1024;
bnc3472afd2016-11-17 15:27:2110947 AlternativeService alternative_service(kProtoHTTP2, "www.example.org",
10948 kUnrestrictedAlternatePort);
bnc7dc7e1b42015-07-28 14:43:1210949 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:2110950 http_server_properties->SetHttp2AlternativeService(
zhongyi3d4a55e72016-04-22 20:36:4610951 url::SchemeHostPort(restricted_port_request.url), alternative_service,
rchdc7b9052016-03-17 20:51:5010952 expiration);
[email protected]3912662a32011-10-04 00:51:1110953
bnc691fda62016-08-12 00:43:1610954 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]49639fa2011-12-20 23:22:4110955 TestCompletionCallback callback;
[email protected]3912662a32011-10-04 00:51:1110956
tfarina42834112016-09-22 13:38:2010957 int rv = trans.Start(&restricted_port_request, callback.callback(),
10958 NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110959 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]3912662a32011-10-04 00:51:1110960 // Invalid change to unrestricted port should fail.
robpercival214763f2016-07-01 23:27:0110961 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_CONNECTION_REFUSED));
[email protected]c54c6962013-02-01 04:53:1910962}
[email protected]3912662a32011-10-04 00:51:1110963
bnc55ff9da2015-08-19 18:42:3510964// Ensure that we are allowed to redirect traffic via an alternate protocol to
10965// an unrestricted (port >= 1024) when the original traffic was on a restricted
10966// port (port < 1024) if we set |enable_user_alternate_protocol_ports|.
bncd16676a2016-07-20 16:23:0110967TEST_F(HttpNetworkTransactionTest, AlternateProtocolPortRestrictedPermitted) {
[email protected]bb88e1d32013-05-03 23:11:0710968 session_deps_.enable_user_alternate_protocol_ports = true;
[email protected]c54c6962013-02-01 04:53:1910969
10970 HttpRequestInfo restricted_port_request;
10971 restricted_port_request.method = "GET";
bncb26024382016-06-29 02:39:4510972 restricted_port_request.url = GURL("https://www.example.org:1023/");
[email protected]c54c6962013-02-01 04:53:1910973 restricted_port_request.load_flags = 0;
10974
10975 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
10976 StaticSocketDataProvider first_data;
10977 first_data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:0710978 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
[email protected]c54c6962013-02-01 04:53:1910979
10980 MockRead data_reads[] = {
10981 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
10982 MockRead("hello world"),
10983 MockRead(ASYNC, OK),
10984 };
10985 StaticSocketDataProvider second_data(
10986 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0710987 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
bncb26024382016-06-29 02:39:4510988 SSLSocketDataProvider ssl_http11(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3610989 ssl_http11.next_proto = kProtoHTTP11;
bncb26024382016-06-29 02:39:4510990 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_http11);
[email protected]c54c6962013-02-01 04:53:1910991
danakj1fd259a02016-04-16 03:17:0910992 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]c54c6962013-02-01 04:53:1910993
bnc525e175a2016-06-20 12:36:4010994 HttpServerProperties* http_server_properties =
[email protected]c54c6962013-02-01 04:53:1910995 session->http_server_properties();
10996 const int kUnrestrictedAlternatePort = 1024;
bnc3472afd2016-11-17 15:27:2110997 AlternativeService alternative_service(kProtoHTTP2, "www.example.org",
10998 kUnrestrictedAlternatePort);
bnc7dc7e1b42015-07-28 14:43:1210999 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:2111000 http_server_properties->SetHttp2AlternativeService(
zhongyi3d4a55e72016-04-22 20:36:4611001 url::SchemeHostPort(restricted_port_request.url), alternative_service,
rchdc7b9052016-03-17 20:51:5011002 expiration);
[email protected]c54c6962013-02-01 04:53:1911003
bnc691fda62016-08-12 00:43:1611004 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]c54c6962013-02-01 04:53:1911005 TestCompletionCallback callback;
11006
tfarina42834112016-09-22 13:38:2011007 EXPECT_EQ(ERR_IO_PENDING,
11008 trans.Start(&restricted_port_request, callback.callback(),
11009 NetLogWithSource()));
[email protected]c54c6962013-02-01 04:53:1911010 // Change to unrestricted port should succeed.
robpercival214763f2016-07-01 23:27:0111011 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]3912662a32011-10-04 00:51:1111012}
11013
bnc55ff9da2015-08-19 18:42:3511014// Ensure that we are not allowed to redirect traffic via an alternate protocol
11015// to an unrestricted (port >= 1024) when the original traffic was on a
11016// restricted port (port < 1024). Ensure that we can redirect in all other
11017// cases.
bncd16676a2016-07-20 16:23:0111018TEST_F(HttpNetworkTransactionTest, AlternateProtocolPortRestrictedAllowed) {
[email protected]3912662a32011-10-04 00:51:1111019 HttpRequestInfo restricted_port_request;
11020 restricted_port_request.method = "GET";
bncb26024382016-06-29 02:39:4511021 restricted_port_request.url = GURL("https://www.example.org:1023/");
[email protected]3912662a32011-10-04 00:51:1111022 restricted_port_request.load_flags = 0;
11023
[email protected]d973e99a2012-02-17 21:02:3611024 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
[email protected]3912662a32011-10-04 00:51:1111025 StaticSocketDataProvider first_data;
11026 first_data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:0711027 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
[email protected]3912662a32011-10-04 00:51:1111028
11029 MockRead data_reads[] = {
11030 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
11031 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:0611032 MockRead(ASYNC, OK),
[email protected]3912662a32011-10-04 00:51:1111033 };
11034 StaticSocketDataProvider second_data(
11035 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0711036 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
[email protected]3912662a32011-10-04 00:51:1111037
bncb26024382016-06-29 02:39:4511038 SSLSocketDataProvider ssl(ASYNC, OK);
11039 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
11040
danakj1fd259a02016-04-16 03:17:0911041 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]3912662a32011-10-04 00:51:1111042
bnc525e175a2016-06-20 12:36:4011043 HttpServerProperties* http_server_properties =
[email protected]17291a022011-10-10 07:32:5311044 session->http_server_properties();
[email protected]3912662a32011-10-04 00:51:1111045 const int kRestrictedAlternatePort = 80;
bnc3472afd2016-11-17 15:27:2111046 AlternativeService alternative_service(kProtoHTTP2, "www.example.org",
11047 kRestrictedAlternatePort);
bnc7dc7e1b42015-07-28 14:43:1211048 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:2111049 http_server_properties->SetHttp2AlternativeService(
zhongyi3d4a55e72016-04-22 20:36:4611050 url::SchemeHostPort(restricted_port_request.url), alternative_service,
rchdc7b9052016-03-17 20:51:5011051 expiration);
[email protected]3912662a32011-10-04 00:51:1111052
bnc691fda62016-08-12 00:43:1611053 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]49639fa2011-12-20 23:22:4111054 TestCompletionCallback callback;
[email protected]3912662a32011-10-04 00:51:1111055
tfarina42834112016-09-22 13:38:2011056 int rv = trans.Start(&restricted_port_request, callback.callback(),
11057 NetLogWithSource());
robpercival214763f2016-07-01 23:27:0111058 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]3912662a32011-10-04 00:51:1111059 // Valid change to restricted port should pass.
robpercival214763f2016-07-01 23:27:0111060 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]3912662a32011-10-04 00:51:1111061}
11062
bnc55ff9da2015-08-19 18:42:3511063// Ensure that we are not allowed to redirect traffic via an alternate protocol
11064// to an unrestricted (port >= 1024) when the original traffic was on a
11065// restricted port (port < 1024). Ensure that we can redirect in all other
11066// cases.
bncd16676a2016-07-20 16:23:0111067TEST_F(HttpNetworkTransactionTest, AlternateProtocolPortUnrestrictedAllowed1) {
[email protected]3912662a32011-10-04 00:51:1111068 HttpRequestInfo unrestricted_port_request;
11069 unrestricted_port_request.method = "GET";
bncb26024382016-06-29 02:39:4511070 unrestricted_port_request.url = GURL("https://www.example.org:1024/");
[email protected]3912662a32011-10-04 00:51:1111071 unrestricted_port_request.load_flags = 0;
11072
[email protected]d973e99a2012-02-17 21:02:3611073 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
[email protected]3912662a32011-10-04 00:51:1111074 StaticSocketDataProvider first_data;
11075 first_data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:0711076 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
[email protected]3912662a32011-10-04 00:51:1111077
11078 MockRead data_reads[] = {
11079 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
11080 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:0611081 MockRead(ASYNC, OK),
[email protected]3912662a32011-10-04 00:51:1111082 };
11083 StaticSocketDataProvider second_data(
11084 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0711085 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
bncb26024382016-06-29 02:39:4511086 SSLSocketDataProvider ssl_http11(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3611087 ssl_http11.next_proto = kProtoHTTP11;
bncb26024382016-06-29 02:39:4511088 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_http11);
[email protected]3912662a32011-10-04 00:51:1111089
danakj1fd259a02016-04-16 03:17:0911090 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]3912662a32011-10-04 00:51:1111091
bnc525e175a2016-06-20 12:36:4011092 HttpServerProperties* http_server_properties =
[email protected]17291a022011-10-10 07:32:5311093 session->http_server_properties();
[email protected]3912662a32011-10-04 00:51:1111094 const int kRestrictedAlternatePort = 80;
bnc3472afd2016-11-17 15:27:2111095 AlternativeService alternative_service(kProtoHTTP2, "www.example.org",
11096 kRestrictedAlternatePort);
bnc7dc7e1b42015-07-28 14:43:1211097 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:2111098 http_server_properties->SetHttp2AlternativeService(
zhongyi3d4a55e72016-04-22 20:36:4611099 url::SchemeHostPort(unrestricted_port_request.url), alternative_service,
rchdc7b9052016-03-17 20:51:5011100 expiration);
[email protected]3912662a32011-10-04 00:51:1111101
bnc691fda62016-08-12 00:43:1611102 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]49639fa2011-12-20 23:22:4111103 TestCompletionCallback callback;
[email protected]3912662a32011-10-04 00:51:1111104
bnc691fda62016-08-12 00:43:1611105 int rv = trans.Start(&unrestricted_port_request, callback.callback(),
tfarina42834112016-09-22 13:38:2011106 NetLogWithSource());
robpercival214763f2016-07-01 23:27:0111107 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]3912662a32011-10-04 00:51:1111108 // Valid change to restricted port should pass.
robpercival214763f2016-07-01 23:27:0111109 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]3912662a32011-10-04 00:51:1111110}
11111
bnc55ff9da2015-08-19 18:42:3511112// Ensure that we are not allowed to redirect traffic via an alternate protocol
11113// to an unrestricted (port >= 1024) when the original traffic was on a
11114// restricted port (port < 1024). Ensure that we can redirect in all other
11115// cases.
bncd16676a2016-07-20 16:23:0111116TEST_F(HttpNetworkTransactionTest, AlternateProtocolPortUnrestrictedAllowed2) {
[email protected]3912662a32011-10-04 00:51:1111117 HttpRequestInfo unrestricted_port_request;
11118 unrestricted_port_request.method = "GET";
bncb26024382016-06-29 02:39:4511119 unrestricted_port_request.url = GURL("https://www.example.org:1024/");
[email protected]3912662a32011-10-04 00:51:1111120 unrestricted_port_request.load_flags = 0;
11121
[email protected]d973e99a2012-02-17 21:02:3611122 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
[email protected]3912662a32011-10-04 00:51:1111123 StaticSocketDataProvider first_data;
11124 first_data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:0711125 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
[email protected]3912662a32011-10-04 00:51:1111126
11127 MockRead data_reads[] = {
11128 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
11129 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:0611130 MockRead(ASYNC, OK),
[email protected]3912662a32011-10-04 00:51:1111131 };
11132 StaticSocketDataProvider second_data(
11133 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0711134 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
[email protected]3912662a32011-10-04 00:51:1111135
bncb26024382016-06-29 02:39:4511136 SSLSocketDataProvider ssl(ASYNC, OK);
11137 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
11138
danakj1fd259a02016-04-16 03:17:0911139 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]3912662a32011-10-04 00:51:1111140
bnc525e175a2016-06-20 12:36:4011141 HttpServerProperties* http_server_properties =
[email protected]17291a022011-10-10 07:32:5311142 session->http_server_properties();
bnc0bbb02622015-07-23 10:06:2211143 const int kUnrestrictedAlternatePort = 1025;
bnc3472afd2016-11-17 15:27:2111144 AlternativeService alternative_service(kProtoHTTP2, "www.example.org",
11145 kUnrestrictedAlternatePort);
bnc7dc7e1b42015-07-28 14:43:1211146 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:2111147 http_server_properties->SetHttp2AlternativeService(
zhongyi3d4a55e72016-04-22 20:36:4611148 url::SchemeHostPort(unrestricted_port_request.url), alternative_service,
rchdc7b9052016-03-17 20:51:5011149 expiration);
[email protected]3912662a32011-10-04 00:51:1111150
bnc691fda62016-08-12 00:43:1611151 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]49639fa2011-12-20 23:22:4111152 TestCompletionCallback callback;
[email protected]3912662a32011-10-04 00:51:1111153
bnc691fda62016-08-12 00:43:1611154 int rv = trans.Start(&unrestricted_port_request, callback.callback(),
tfarina42834112016-09-22 13:38:2011155 NetLogWithSource());
robpercival214763f2016-07-01 23:27:0111156 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]3912662a32011-10-04 00:51:1111157 // Valid change to an unrestricted port should pass.
robpercival214763f2016-07-01 23:27:0111158 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]3912662a32011-10-04 00:51:1111159}
11160
bnc55ff9da2015-08-19 18:42:3511161// Ensure that we are not allowed to redirect traffic via an alternate protocol
11162// to an unsafe port, and that we resume the second HttpStreamFactoryImpl::Job
11163// once the alternate protocol request fails.
bncd16676a2016-07-20 16:23:0111164TEST_F(HttpNetworkTransactionTest, AlternateProtocolUnsafeBlocked) {
[email protected]eb6234e2012-01-19 01:50:0211165 HttpRequestInfo request;
11166 request.method = "GET";
bncce36dca22015-04-21 22:11:2311167 request.url = GURL("http://www.example.org/");
[email protected]eb6234e2012-01-19 01:50:0211168
11169 // The alternate protocol request will error out before we attempt to connect,
11170 // so only the standard HTTP request will try to connect.
11171 MockRead data_reads[] = {
11172 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
11173 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:0611174 MockRead(ASYNC, OK),
[email protected]eb6234e2012-01-19 01:50:0211175 };
11176 StaticSocketDataProvider data(
11177 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0711178 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]eb6234e2012-01-19 01:50:0211179
danakj1fd259a02016-04-16 03:17:0911180 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]eb6234e2012-01-19 01:50:0211181
bnc525e175a2016-06-20 12:36:4011182 HttpServerProperties* http_server_properties =
[email protected]eb6234e2012-01-19 01:50:0211183 session->http_server_properties();
11184 const int kUnsafePort = 7;
bnc3472afd2016-11-17 15:27:2111185 AlternativeService alternative_service(kProtoHTTP2, "www.example.org",
11186 kUnsafePort);
bnc7dc7e1b42015-07-28 14:43:1211187 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:2111188 http_server_properties->SetHttp2AlternativeService(
zhongyi3d4a55e72016-04-22 20:36:4611189 url::SchemeHostPort(request.url), alternative_service, expiration);
[email protected]eb6234e2012-01-19 01:50:0211190
bnc691fda62016-08-12 00:43:1611191 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]eb6234e2012-01-19 01:50:0211192 TestCompletionCallback callback;
11193
tfarina42834112016-09-22 13:38:2011194 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0111195 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]eb6234e2012-01-19 01:50:0211196 // The HTTP request should succeed.
robpercival214763f2016-07-01 23:27:0111197 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]eb6234e2012-01-19 01:50:0211198
bnc691fda62016-08-12 00:43:1611199 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5211200 ASSERT_TRUE(response);
11201 ASSERT_TRUE(response->headers);
[email protected]eb6234e2012-01-19 01:50:0211202 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
11203
11204 std::string response_data;
bnc691fda62016-08-12 00:43:1611205 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
[email protected]eb6234e2012-01-19 01:50:0211206 EXPECT_EQ("hello world", response_data);
11207}
11208
bncd16676a2016-07-20 16:23:0111209TEST_F(HttpNetworkTransactionTest, UseAlternateProtocolForNpnSpdy) {
[email protected]2ff8b312010-04-26 22:20:5411210 HttpRequestInfo request;
11211 request.method = "GET";
bncb26024382016-06-29 02:39:4511212 request.url = GURL("https://www.example.org/");
[email protected]2ff8b312010-04-26 22:20:5411213
11214 MockRead data_reads[] = {
bncc958faa2015-07-31 18:14:5211215 MockRead("HTTP/1.1 200 OK\r\n"),
bnc2df4b522016-07-08 18:17:4311216 MockRead(kAlternativeServiceHttpHeader),
bncc958faa2015-07-31 18:14:5211217 MockRead("\r\n"),
11218 MockRead("hello world"),
11219 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
11220 MockRead(ASYNC, OK)};
[email protected]2ff8b312010-04-26 22:20:5411221
11222 StaticSocketDataProvider first_transaction(
11223 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0711224 session_deps_.socket_factory->AddSocketDataProvider(&first_transaction);
bncb26024382016-06-29 02:39:4511225 SSLSocketDataProvider ssl_http11(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3611226 ssl_http11.next_proto = kProtoHTTP11;
bncb26024382016-06-29 02:39:4511227 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_http11);
[email protected]2ff8b312010-04-26 22:20:5411228
bnc032658ba2016-09-26 18:17:1511229 AddSSLSocketData();
[email protected]2ff8b312010-04-26 22:20:5411230
bncdf80d44fd2016-07-15 20:27:4111231 SpdySerializedFrame req(
bncb26024382016-06-29 02:39:4511232 spdy_util_.ConstructSpdyGet("https://www.example.org/", 1, LOWEST));
bncdf80d44fd2016-07-15 20:27:4111233 MockWrite spdy_writes[] = {CreateMockWrite(req, 0)};
[email protected]2ff8b312010-04-26 22:20:5411234
bnc42331402016-07-25 13:36:1511235 SpdySerializedFrame resp(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
bncdf80d44fd2016-07-15 20:27:4111236 SpdySerializedFrame data(spdy_util_.ConstructSpdyDataFrame(1, true));
[email protected]2ff8b312010-04-26 22:20:5411237 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:4111238 CreateMockRead(resp, 1), CreateMockRead(data, 2), MockRead(ASYNC, 0, 3),
[email protected]2ff8b312010-04-26 22:20:5411239 };
11240
rch8e6c6c42015-05-01 14:05:1311241 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
11242 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:0711243 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]2ff8b312010-04-26 22:20:5411244
[email protected]d973e99a2012-02-17 21:02:3611245 MockConnect never_finishing_connect(SYNCHRONOUS, ERR_IO_PENDING);
[email protected]2d6728692011-03-12 01:39:5511246 StaticSocketDataProvider hanging_non_alternate_protocol_socket(
11247 NULL, 0, NULL, 0);
11248 hanging_non_alternate_protocol_socket.set_connect_data(
11249 never_finishing_connect);
[email protected]bb88e1d32013-05-03 23:11:0711250 session_deps_.socket_factory->AddSocketDataProvider(
[email protected]2d6728692011-03-12 01:39:5511251 &hanging_non_alternate_protocol_socket);
11252
[email protected]49639fa2011-12-20 23:22:4111253 TestCompletionCallback callback;
[email protected]2ff8b312010-04-26 22:20:5411254
danakj1fd259a02016-04-16 03:17:0911255 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc87dcefc2017-05-25 12:47:5811256 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:1911257 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]2ff8b312010-04-26 22:20:5411258
tfarina42834112016-09-22 13:38:2011259 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0111260 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
11261 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]2ff8b312010-04-26 22:20:5411262
11263 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5211264 ASSERT_TRUE(response);
11265 ASSERT_TRUE(response->headers);
[email protected]2ff8b312010-04-26 22:20:5411266 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
11267
11268 std::string response_data;
robpercival214763f2016-07-01 23:27:0111269 ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
[email protected]2ff8b312010-04-26 22:20:5411270 EXPECT_EQ("hello world", response_data);
11271
bnc87dcefc2017-05-25 12:47:5811272 trans =
Jeremy Roman0579ed62017-08-29 15:56:1911273 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]2ff8b312010-04-26 22:20:5411274
tfarina42834112016-09-22 13:38:2011275 rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0111276 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
11277 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]2ff8b312010-04-26 22:20:5411278
11279 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5211280 ASSERT_TRUE(response);
11281 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0211282 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]65041fa2010-05-21 06:56:5311283 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5211284 EXPECT_TRUE(response->was_alpn_negotiated);
[email protected]2ff8b312010-04-26 22:20:5411285
robpercival214763f2016-07-01 23:27:0111286 ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
[email protected]2ff8b312010-04-26 22:20:5411287 EXPECT_EQ("hello!", response_data);
[email protected]2ff8b312010-04-26 22:20:5411288}
11289
bncd16676a2016-07-20 16:23:0111290TEST_F(HttpNetworkTransactionTest, AlternateProtocolWithSpdyLateBinding) {
[email protected]2d6728692011-03-12 01:39:5511291 HttpRequestInfo request;
11292 request.method = "GET";
bncb26024382016-06-29 02:39:4511293 request.url = GURL("https://www.example.org/");
[email protected]2d6728692011-03-12 01:39:5511294
bncb26024382016-06-29 02:39:4511295 // First transaction receives Alt-Svc header over HTTP/1.1.
[email protected]2d6728692011-03-12 01:39:5511296 MockRead data_reads[] = {
bncc958faa2015-07-31 18:14:5211297 MockRead("HTTP/1.1 200 OK\r\n"),
bnc2df4b522016-07-08 18:17:4311298 MockRead(kAlternativeServiceHttpHeader),
bncc958faa2015-07-31 18:14:5211299 MockRead("\r\n"),
11300 MockRead("hello world"),
11301 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
11302 MockRead(ASYNC, OK),
[email protected]2d6728692011-03-12 01:39:5511303 };
11304
bncb26024382016-06-29 02:39:4511305 StaticSocketDataProvider http11_data(data_reads, arraysize(data_reads), NULL,
11306 0);
11307 session_deps_.socket_factory->AddSocketDataProvider(&http11_data);
[email protected]2d6728692011-03-12 01:39:5511308
bncb26024382016-06-29 02:39:4511309 SSLSocketDataProvider ssl_http11(ASYNC, OK);
Bence Béky230ac612017-08-30 19:17:0811310 ssl_http11.cert = ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem");
11311 ASSERT_TRUE(ssl_http11.cert);
bncb26024382016-06-29 02:39:4511312 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_http11);
11313
11314 // Second transaction starts an alternative and a non-alternative Job.
11315 // Both sockets hang.
[email protected]d973e99a2012-02-17 21:02:3611316 MockConnect never_finishing_connect(SYNCHRONOUS, ERR_IO_PENDING);
mmenkecc2298e2015-12-07 18:20:1811317 StaticSocketDataProvider hanging_socket1(NULL, 0, NULL, 0);
11318 hanging_socket1.set_connect_data(never_finishing_connect);
mmenkecc2298e2015-12-07 18:20:1811319 session_deps_.socket_factory->AddSocketDataProvider(&hanging_socket1);
11320
11321 StaticSocketDataProvider hanging_socket2(NULL, 0, NULL, 0);
11322 hanging_socket2.set_connect_data(never_finishing_connect);
11323 session_deps_.socket_factory->AddSocketDataProvider(&hanging_socket2);
[email protected]2d6728692011-03-12 01:39:5511324
bncb26024382016-06-29 02:39:4511325 // Third transaction starts an alternative and a non-alternative job.
11326 // The non-alternative job hangs, but the alternative one succeeds.
11327 // The second transaction, still pending, binds to this socket.
bncdf80d44fd2016-07-15 20:27:4111328 SpdySerializedFrame req1(
bncb26024382016-06-29 02:39:4511329 spdy_util_.ConstructSpdyGet("https://www.example.org/", 1, LOWEST));
bncdf80d44fd2016-07-15 20:27:4111330 SpdySerializedFrame req2(
bncb26024382016-06-29 02:39:4511331 spdy_util_.ConstructSpdyGet("https://www.example.org/", 3, LOWEST));
[email protected]2d6728692011-03-12 01:39:5511332 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:4111333 CreateMockWrite(req1, 0), CreateMockWrite(req2, 1),
[email protected]2d6728692011-03-12 01:39:5511334 };
bnc42331402016-07-25 13:36:1511335 SpdySerializedFrame resp1(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
bncdf80d44fd2016-07-15 20:27:4111336 SpdySerializedFrame data1(spdy_util_.ConstructSpdyDataFrame(1, true));
bnc42331402016-07-25 13:36:1511337 SpdySerializedFrame resp2(spdy_util_.ConstructSpdyGetReply(NULL, 0, 3));
bncdf80d44fd2016-07-15 20:27:4111338 SpdySerializedFrame data2(spdy_util_.ConstructSpdyDataFrame(3, true));
[email protected]2d6728692011-03-12 01:39:5511339 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:4111340 CreateMockRead(resp1, 2), CreateMockRead(data1, 3),
11341 CreateMockRead(resp2, 4), CreateMockRead(data2, 5),
rch8e6c6c42015-05-01 14:05:1311342 MockRead(ASYNC, 0, 6),
[email protected]2d6728692011-03-12 01:39:5511343 };
11344
rch8e6c6c42015-05-01 14:05:1311345 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
11346 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:0711347 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]2d6728692011-03-12 01:39:5511348
bnc032658ba2016-09-26 18:17:1511349 AddSSLSocketData();
bncb26024382016-06-29 02:39:4511350
mmenkecc2298e2015-12-07 18:20:1811351 StaticSocketDataProvider hanging_socket3(NULL, 0, NULL, 0);
11352 hanging_socket3.set_connect_data(never_finishing_connect);
11353 session_deps_.socket_factory->AddSocketDataProvider(&hanging_socket3);
[email protected]2d6728692011-03-12 01:39:5511354
danakj1fd259a02016-04-16 03:17:0911355 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]49639fa2011-12-20 23:22:4111356 TestCompletionCallback callback1;
[email protected]90499482013-06-01 00:39:5011357 HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
[email protected]2d6728692011-03-12 01:39:5511358
tfarina42834112016-09-22 13:38:2011359 int rv = trans1.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0111360 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
11361 EXPECT_THAT(callback1.WaitForResult(), IsOk());
[email protected]2d6728692011-03-12 01:39:5511362
11363 const HttpResponseInfo* response = trans1.GetResponseInfo();
wezca1070932016-05-26 20:30:5211364 ASSERT_TRUE(response);
11365 ASSERT_TRUE(response->headers);
[email protected]2d6728692011-03-12 01:39:5511366 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
11367
11368 std::string response_data;
robpercival214763f2016-07-01 23:27:0111369 ASSERT_THAT(ReadTransaction(&trans1, &response_data), IsOk());
[email protected]2d6728692011-03-12 01:39:5511370 EXPECT_EQ("hello world", response_data);
11371
[email protected]49639fa2011-12-20 23:22:4111372 TestCompletionCallback callback2;
[email protected]90499482013-06-01 00:39:5011373 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:2011374 rv = trans2.Start(&request, callback2.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0111375 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2d6728692011-03-12 01:39:5511376
[email protected]49639fa2011-12-20 23:22:4111377 TestCompletionCallback callback3;
[email protected]90499482013-06-01 00:39:5011378 HttpNetworkTransaction trans3(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:2011379 rv = trans3.Start(&request, callback3.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0111380 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2d6728692011-03-12 01:39:5511381
robpercival214763f2016-07-01 23:27:0111382 EXPECT_THAT(callback2.WaitForResult(), IsOk());
11383 EXPECT_THAT(callback3.WaitForResult(), IsOk());
[email protected]2d6728692011-03-12 01:39:5511384
11385 response = trans2.GetResponseInfo();
wezca1070932016-05-26 20:30:5211386 ASSERT_TRUE(response);
11387 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0211388 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]2d6728692011-03-12 01:39:5511389 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5211390 EXPECT_TRUE(response->was_alpn_negotiated);
robpercival214763f2016-07-01 23:27:0111391 ASSERT_THAT(ReadTransaction(&trans2, &response_data), IsOk());
[email protected]2d6728692011-03-12 01:39:5511392 EXPECT_EQ("hello!", response_data);
11393
11394 response = trans3.GetResponseInfo();
wezca1070932016-05-26 20:30:5211395 ASSERT_TRUE(response);
11396 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0211397 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]2d6728692011-03-12 01:39:5511398 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5211399 EXPECT_TRUE(response->was_alpn_negotiated);
robpercival214763f2016-07-01 23:27:0111400 ASSERT_THAT(ReadTransaction(&trans3, &response_data), IsOk());
[email protected]2d6728692011-03-12 01:39:5511401 EXPECT_EQ("hello!", response_data);
[email protected]2d6728692011-03-12 01:39:5511402}
11403
bncd16676a2016-07-20 16:23:0111404TEST_F(HttpNetworkTransactionTest, StallAlternativeServiceForNpnSpdy) {
[email protected]2d6728692011-03-12 01:39:5511405 HttpRequestInfo request;
11406 request.method = "GET";
bncb26024382016-06-29 02:39:4511407 request.url = GURL("https://www.example.org/");
[email protected]2d6728692011-03-12 01:39:5511408
11409 MockRead data_reads[] = {
bncc958faa2015-07-31 18:14:5211410 MockRead("HTTP/1.1 200 OK\r\n"),
bnc2df4b522016-07-08 18:17:4311411 MockRead(kAlternativeServiceHttpHeader),
bncc958faa2015-07-31 18:14:5211412 MockRead("\r\n"),
11413 MockRead("hello world"),
11414 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
11415 MockRead(ASYNC, OK),
[email protected]2d6728692011-03-12 01:39:5511416 };
11417
11418 StaticSocketDataProvider first_transaction(
11419 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0711420 session_deps_.socket_factory->AddSocketDataProvider(&first_transaction);
[email protected]2d6728692011-03-12 01:39:5511421
[email protected]8ddf8322012-02-23 18:08:0611422 SSLSocketDataProvider ssl(ASYNC, OK);
Bence Béky230ac612017-08-30 19:17:0811423 ssl.cert = ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem");
11424 ASSERT_TRUE(ssl.cert);
[email protected]bb88e1d32013-05-03 23:11:0711425 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]2d6728692011-03-12 01:39:5511426
[email protected]d973e99a2012-02-17 21:02:3611427 MockConnect never_finishing_connect(SYNCHRONOUS, ERR_IO_PENDING);
[email protected]2d6728692011-03-12 01:39:5511428 StaticSocketDataProvider hanging_alternate_protocol_socket(
11429 NULL, 0, NULL, 0);
11430 hanging_alternate_protocol_socket.set_connect_data(
11431 never_finishing_connect);
[email protected]bb88e1d32013-05-03 23:11:0711432 session_deps_.socket_factory->AddSocketDataProvider(
[email protected]2d6728692011-03-12 01:39:5511433 &hanging_alternate_protocol_socket);
11434
bncb26024382016-06-29 02:39:4511435 // 2nd request is just a copy of the first one, over HTTP/1.1 again.
mmenkecc2298e2015-12-07 18:20:1811436 StaticSocketDataProvider second_transaction(data_reads, arraysize(data_reads),
11437 NULL, 0);
11438 session_deps_.socket_factory->AddSocketDataProvider(&second_transaction);
bncb26024382016-06-29 02:39:4511439 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]2d6728692011-03-12 01:39:5511440
[email protected]49639fa2011-12-20 23:22:4111441 TestCompletionCallback callback;
[email protected]2d6728692011-03-12 01:39:5511442
danakj1fd259a02016-04-16 03:17:0911443 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc87dcefc2017-05-25 12:47:5811444 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:1911445 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]2d6728692011-03-12 01:39:5511446
tfarina42834112016-09-22 13:38:2011447 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0111448 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
11449 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]2d6728692011-03-12 01:39:5511450
11451 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5211452 ASSERT_TRUE(response);
11453 ASSERT_TRUE(response->headers);
[email protected]2d6728692011-03-12 01:39:5511454 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
11455
11456 std::string response_data;
robpercival214763f2016-07-01 23:27:0111457 ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
[email protected]2d6728692011-03-12 01:39:5511458 EXPECT_EQ("hello world", response_data);
11459
bnc87dcefc2017-05-25 12:47:5811460 trans =
Jeremy Roman0579ed62017-08-29 15:56:1911461 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]2d6728692011-03-12 01:39:5511462
tfarina42834112016-09-22 13:38:2011463 rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0111464 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
11465 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]2d6728692011-03-12 01:39:5511466
11467 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5211468 ASSERT_TRUE(response);
11469 ASSERT_TRUE(response->headers);
[email protected]2d6728692011-03-12 01:39:5511470 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
11471 EXPECT_FALSE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5211472 EXPECT_FALSE(response->was_alpn_negotiated);
[email protected]2d6728692011-03-12 01:39:5511473
robpercival214763f2016-07-01 23:27:0111474 ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
[email protected]2d6728692011-03-12 01:39:5511475 EXPECT_EQ("hello world", response_data);
[email protected]2d6728692011-03-12 01:39:5511476}
11477
[email protected]631f1322010-04-30 17:59:1111478class CapturingProxyResolver : public ProxyResolver {
11479 public:
sammce90c9212015-05-27 23:43:3511480 CapturingProxyResolver() {}
dchengb03027d2014-10-21 12:00:2011481 ~CapturingProxyResolver() override {}
[email protected]631f1322010-04-30 17:59:1111482
dchengb03027d2014-10-21 12:00:2011483 int GetProxyForURL(const GURL& url,
11484 ProxyInfo* results,
11485 const CompletionCallback& callback,
maksim.sisov7e157262016-10-20 11:19:5511486 std::unique_ptr<Request>* request,
tfarina42834112016-09-22 13:38:2011487 const NetLogWithSource& net_log) override {
[email protected]fae7669f2010-08-02 21:49:4011488 ProxyServer proxy_server(ProxyServer::SCHEME_HTTP,
11489 HostPortPair("myproxy", 80));
[email protected]d911f1b2010-05-05 22:39:4211490 results->UseProxyServer(proxy_server);
[email protected]631f1322010-04-30 17:59:1111491 resolved_.push_back(url);
[email protected]d911f1b2010-05-05 22:39:4211492 return OK;
[email protected]631f1322010-04-30 17:59:1111493 }
11494
[email protected]24476402010-07-20 20:55:1711495 const std::vector<GURL>& resolved() const { return resolved_; }
11496
11497 private:
[email protected]631f1322010-04-30 17:59:1111498 std::vector<GURL> resolved_;
11499
11500 DISALLOW_COPY_AND_ASSIGN(CapturingProxyResolver);
11501};
11502
sammce64b2362015-04-29 03:50:2311503class CapturingProxyResolverFactory : public ProxyResolverFactory {
11504 public:
11505 explicit CapturingProxyResolverFactory(CapturingProxyResolver* resolver)
11506 : ProxyResolverFactory(false), resolver_(resolver) {}
11507
11508 int CreateProxyResolver(
11509 const scoped_refptr<ProxyResolverScriptData>& pac_script,
danakj1fd259a02016-04-16 03:17:0911510 std::unique_ptr<ProxyResolver>* resolver,
sammce64b2362015-04-29 03:50:2311511 const net::CompletionCallback& callback,
danakj1fd259a02016-04-16 03:17:0911512 std::unique_ptr<Request>* request) override {
Jeremy Roman0579ed62017-08-29 15:56:1911513 *resolver = std::make_unique<ForwardingProxyResolver>(resolver_);
sammce64b2362015-04-29 03:50:2311514 return OK;
11515 }
11516
11517 private:
11518 ProxyResolver* resolver_;
11519};
11520
bnc2e884782016-08-11 19:45:1911521// Test that proxy is resolved using the origin url,
11522// regardless of the alternative server.
11523TEST_F(HttpNetworkTransactionTest, UseOriginNotAlternativeForProxy) {
11524 // Configure proxy to bypass www.example.org, which is the origin URL.
11525 ProxyConfig proxy_config;
11526 proxy_config.proxy_rules().ParseFromString("myproxy:70");
11527 proxy_config.proxy_rules().bypass_rules.AddRuleFromString("www.example.org");
11528 auto proxy_config_service =
Jeremy Roman0579ed62017-08-29 15:56:1911529 std::make_unique<ProxyConfigServiceFixed>(proxy_config);
bnc2e884782016-08-11 19:45:1911530
11531 CapturingProxyResolver capturing_proxy_resolver;
Jeremy Roman0579ed62017-08-29 15:56:1911532 auto proxy_resolver_factory = std::make_unique<CapturingProxyResolverFactory>(
bnc2e884782016-08-11 19:45:1911533 &capturing_proxy_resolver);
11534
11535 TestNetLog net_log;
11536
Jeremy Roman0579ed62017-08-29 15:56:1911537 session_deps_.proxy_service = std::make_unique<ProxyService>(
bnc2e884782016-08-11 19:45:1911538 std::move(proxy_config_service), std::move(proxy_resolver_factory),
11539 &net_log);
11540
11541 session_deps_.net_log = &net_log;
11542
11543 // Configure alternative service with a hostname that is not bypassed by the
11544 // proxy.
11545 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
11546 HttpServerProperties* http_server_properties =
11547 session->http_server_properties();
11548 url::SchemeHostPort server("https", "www.example.org", 443);
11549 HostPortPair alternative("www.example.com", 443);
bnc3472afd2016-11-17 15:27:2111550 AlternativeService alternative_service(kProtoHTTP2, alternative);
bnc2e884782016-08-11 19:45:1911551 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:2111552 http_server_properties->SetHttp2AlternativeService(
11553 server, alternative_service, expiration);
bnc2e884782016-08-11 19:45:1911554
11555 // Non-alternative job should hang.
11556 MockConnect never_finishing_connect(SYNCHRONOUS, ERR_IO_PENDING);
11557 StaticSocketDataProvider hanging_alternate_protocol_socket(nullptr, 0,
11558 nullptr, 0);
11559 hanging_alternate_protocol_socket.set_connect_data(never_finishing_connect);
11560 session_deps_.socket_factory->AddSocketDataProvider(
11561 &hanging_alternate_protocol_socket);
11562
bnc032658ba2016-09-26 18:17:1511563 AddSSLSocketData();
bnc2e884782016-08-11 19:45:1911564
11565 HttpRequestInfo request;
11566 request.method = "GET";
11567 request.url = GURL("https://www.example.org/");
11568 request.load_flags = 0;
11569
11570 SpdySerializedFrame req(
11571 spdy_util_.ConstructSpdyGet("https://www.example.org/", 1, LOWEST));
11572
11573 MockWrite spdy_writes[] = {CreateMockWrite(req, 0)};
11574
11575 SpdySerializedFrame resp(spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
11576 SpdySerializedFrame data(spdy_util_.ConstructSpdyDataFrame(1, true));
11577 MockRead spdy_reads[] = {
11578 CreateMockRead(resp, 1), CreateMockRead(data, 2), MockRead(ASYNC, 0, 3),
11579 };
11580
11581 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
11582 arraysize(spdy_writes));
11583 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
11584
11585 TestCompletionCallback callback;
11586
11587 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
11588
tfarina42834112016-09-22 13:38:2011589 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
bnc2e884782016-08-11 19:45:1911590 EXPECT_THAT(callback.GetResult(rv), IsOk());
11591
11592 const HttpResponseInfo* response = trans.GetResponseInfo();
11593 ASSERT_TRUE(response);
11594 ASSERT_TRUE(response->headers);
11595 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
11596 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5211597 EXPECT_TRUE(response->was_alpn_negotiated);
bnc2e884782016-08-11 19:45:1911598
11599 std::string response_data;
11600 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
11601 EXPECT_EQ("hello!", response_data);
11602
11603 // Origin host bypasses proxy, no resolution should have happened.
11604 ASSERT_TRUE(capturing_proxy_resolver.resolved().empty());
11605}
11606
bncd16676a2016-07-20 16:23:0111607TEST_F(HttpNetworkTransactionTest, UseAlternativeServiceForTunneledNpnSpdy) {
[email protected]631f1322010-04-30 17:59:1111608 ProxyConfig proxy_config;
[email protected]d911f1b2010-05-05 22:39:4211609 proxy_config.set_auto_detect(true);
11610 proxy_config.set_pac_url(GURL("http://fooproxyurl"));
[email protected]2227c692010-05-04 15:36:1111611
sammc5dd160c2015-04-02 02:43:1311612 CapturingProxyResolver capturing_proxy_resolver;
Jeremy Roman0579ed62017-08-29 15:56:1911613 session_deps_.proxy_service = std::make_unique<ProxyService>(
11614 std::make_unique<ProxyConfigServiceFixed>(proxy_config),
11615 std::make_unique<CapturingProxyResolverFactory>(
bnc87dcefc2017-05-25 12:47:5811616 &capturing_proxy_resolver),
11617 nullptr);
vishal.b62985ca92015-04-17 08:45:5111618 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:0711619 session_deps_.net_log = &net_log;
[email protected]631f1322010-04-30 17:59:1111620
11621 HttpRequestInfo request;
11622 request.method = "GET";
bncb26024382016-06-29 02:39:4511623 request.url = GURL("https://www.example.org/");
[email protected]631f1322010-04-30 17:59:1111624
11625 MockRead data_reads[] = {
bncc958faa2015-07-31 18:14:5211626 MockRead("HTTP/1.1 200 OK\r\n"),
bnc2df4b522016-07-08 18:17:4311627 MockRead(kAlternativeServiceHttpHeader),
bncc958faa2015-07-31 18:14:5211628 MockRead("\r\n"),
11629 MockRead("hello world"),
11630 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
11631 MockRead(ASYNC, OK),
[email protected]631f1322010-04-30 17:59:1111632 };
11633
11634 StaticSocketDataProvider first_transaction(
11635 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0711636 session_deps_.socket_factory->AddSocketDataProvider(&first_transaction);
bncb26024382016-06-29 02:39:4511637 SSLSocketDataProvider ssl_http11(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3611638 ssl_http11.next_proto = kProtoHTTP11;
bncb26024382016-06-29 02:39:4511639 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_http11);
[email protected]631f1322010-04-30 17:59:1111640
bnc032658ba2016-09-26 18:17:1511641 AddSSLSocketData();
[email protected]631f1322010-04-30 17:59:1111642
bncdf80d44fd2016-07-15 20:27:4111643 SpdySerializedFrame req(
bncb26024382016-06-29 02:39:4511644 spdy_util_.ConstructSpdyGet("https://www.example.org/", 1, LOWEST));
[email protected]631f1322010-04-30 17:59:1111645 MockWrite spdy_writes[] = {
rch8e6c6c42015-05-01 14:05:1311646 MockWrite(ASYNC, 0,
bnc8bef8da22016-05-30 01:28:2511647 "CONNECT www.example.org:443 HTTP/1.1\r\n"
11648 "Host: www.example.org:443\r\n"
rch8e6c6c42015-05-01 14:05:1311649 "Proxy-Connection: keep-alive\r\n\r\n"),
bncdf80d44fd2016-07-15 20:27:4111650 CreateMockWrite(req, 2),
[email protected]631f1322010-04-30 17:59:1111651 };
11652
[email protected]d911f1b2010-05-05 22:39:4211653 const char kCONNECTResponse[] = "HTTP/1.1 200 Connected\r\n\r\n";
11654
bnc42331402016-07-25 13:36:1511655 SpdySerializedFrame resp(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
bncdf80d44fd2016-07-15 20:27:4111656 SpdySerializedFrame data(spdy_util_.ConstructSpdyDataFrame(1, true));
[email protected]631f1322010-04-30 17:59:1111657 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:4111658 MockRead(ASYNC, 1, kCONNECTResponse), CreateMockRead(resp, 3),
11659 CreateMockRead(data, 4), MockRead(SYNCHRONOUS, ERR_IO_PENDING, 5),
[email protected]631f1322010-04-30 17:59:1111660 };
11661
rch8e6c6c42015-05-01 14:05:1311662 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
11663 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:0711664 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]631f1322010-04-30 17:59:1111665
[email protected]d973e99a2012-02-17 21:02:3611666 MockConnect never_finishing_connect(SYNCHRONOUS, ERR_IO_PENDING);
[email protected]2d6728692011-03-12 01:39:5511667 StaticSocketDataProvider hanging_non_alternate_protocol_socket(
11668 NULL, 0, NULL, 0);
11669 hanging_non_alternate_protocol_socket.set_connect_data(
11670 never_finishing_connect);
[email protected]bb88e1d32013-05-03 23:11:0711671 session_deps_.socket_factory->AddSocketDataProvider(
[email protected]2d6728692011-03-12 01:39:5511672 &hanging_non_alternate_protocol_socket);
11673
[email protected]49639fa2011-12-20 23:22:4111674 TestCompletionCallback callback;
[email protected]631f1322010-04-30 17:59:1111675
danakj1fd259a02016-04-16 03:17:0911676 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc87dcefc2017-05-25 12:47:5811677 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:1911678 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]631f1322010-04-30 17:59:1111679
tfarina42834112016-09-22 13:38:2011680 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
mmenkea2dcd3bf2016-08-16 21:49:4111681 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
11682 EXPECT_THAT(callback.WaitForResult(), IsOk());
11683
11684 const HttpResponseInfo* response = trans->GetResponseInfo();
11685 ASSERT_TRUE(response);
11686 ASSERT_TRUE(response->headers);
11687 EXPECT_EQ("HTTP/0.9 200 OK", response->headers->GetStatusLine());
11688 EXPECT_FALSE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5211689 EXPECT_TRUE(response->was_alpn_negotiated);
mmenkea2dcd3bf2016-08-16 21:49:4111690
11691 std::string response_data;
11692 ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
11693 EXPECT_EQ("hello world", response_data);
[email protected]631f1322010-04-30 17:59:1111694
bnc87dcefc2017-05-25 12:47:5811695 trans =
Jeremy Roman0579ed62017-08-29 15:56:1911696 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]631f1322010-04-30 17:59:1111697
tfarina42834112016-09-22 13:38:2011698 rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0111699 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
11700 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]631f1322010-04-30 17:59:1111701
mmenkea2dcd3bf2016-08-16 21:49:4111702 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5211703 ASSERT_TRUE(response);
11704 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0211705 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]65041fa2010-05-21 06:56:5311706 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5211707 EXPECT_TRUE(response->was_alpn_negotiated);
[email protected]631f1322010-04-30 17:59:1111708
robpercival214763f2016-07-01 23:27:0111709 ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
[email protected]631f1322010-04-30 17:59:1111710 EXPECT_EQ("hello!", response_data);
bncb26024382016-06-29 02:39:4511711 ASSERT_EQ(2u, capturing_proxy_resolver.resolved().size());
11712 EXPECT_EQ("https://www.example.org/",
sammc5dd160c2015-04-02 02:43:1311713 capturing_proxy_resolver.resolved()[0].spec());
bncce36dca22015-04-21 22:11:2311714 EXPECT_EQ("https://www.example.org/",
sammc5dd160c2015-04-02 02:43:1311715 capturing_proxy_resolver.resolved()[1].spec());
[email protected]631f1322010-04-30 17:59:1111716
[email protected]029c83b62013-01-24 05:28:2011717 LoadTimingInfo load_timing_info;
11718 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
11719 TestLoadTimingNotReusedWithPac(load_timing_info,
11720 CONNECT_TIMING_HAS_SSL_TIMES);
[email protected]631f1322010-04-30 17:59:1111721}
[email protected]631f1322010-04-30 17:59:1111722
bncd16676a2016-07-20 16:23:0111723TEST_F(HttpNetworkTransactionTest,
bnc1c196c6e2016-05-28 13:51:4811724 UseAlternativeServiceForNpnSpdyWithExistingSpdySession) {
[email protected]2ff8b312010-04-26 22:20:5411725 HttpRequestInfo request;
11726 request.method = "GET";
bncb26024382016-06-29 02:39:4511727 request.url = GURL("https://www.example.org/");
[email protected]2ff8b312010-04-26 22:20:5411728
11729 MockRead data_reads[] = {
bncc958faa2015-07-31 18:14:5211730 MockRead("HTTP/1.1 200 OK\r\n"),
bnc2df4b522016-07-08 18:17:4311731 MockRead(kAlternativeServiceHttpHeader),
bncc958faa2015-07-31 18:14:5211732 MockRead("\r\n"),
11733 MockRead("hello world"),
11734 MockRead(ASYNC, OK),
[email protected]2ff8b312010-04-26 22:20:5411735 };
11736
11737 StaticSocketDataProvider first_transaction(
11738 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0711739 session_deps_.socket_factory->AddSocketDataProvider(&first_transaction);
bncb26024382016-06-29 02:39:4511740 SSLSocketDataProvider ssl_http11(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3611741 ssl_http11.next_proto = kProtoHTTP11;
bncb26024382016-06-29 02:39:4511742 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_http11);
[email protected]2ff8b312010-04-26 22:20:5411743
bnc032658ba2016-09-26 18:17:1511744 AddSSLSocketData();
[email protected]2ff8b312010-04-26 22:20:5411745
bncdf80d44fd2016-07-15 20:27:4111746 SpdySerializedFrame req(
bncb26024382016-06-29 02:39:4511747 spdy_util_.ConstructSpdyGet("https://www.example.org/", 1, LOWEST));
bncdf80d44fd2016-07-15 20:27:4111748 MockWrite spdy_writes[] = {CreateMockWrite(req, 0)};
[email protected]2ff8b312010-04-26 22:20:5411749
bnc42331402016-07-25 13:36:1511750 SpdySerializedFrame resp(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
bncdf80d44fd2016-07-15 20:27:4111751 SpdySerializedFrame data(spdy_util_.ConstructSpdyDataFrame(1, true));
[email protected]2ff8b312010-04-26 22:20:5411752 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:4111753 CreateMockRead(resp, 1), CreateMockRead(data, 2), MockRead(ASYNC, 0, 3),
[email protected]2ff8b312010-04-26 22:20:5411754 };
11755
rch8e6c6c42015-05-01 14:05:1311756 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
11757 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:0711758 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]2ff8b312010-04-26 22:20:5411759
[email protected]83039bb2011-12-09 18:43:5511760 TestCompletionCallback callback;
[email protected]2ff8b312010-04-26 22:20:5411761
danakj1fd259a02016-04-16 03:17:0911762 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]2ff8b312010-04-26 22:20:5411763
bnc87dcefc2017-05-25 12:47:5811764 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:1911765 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]2ff8b312010-04-26 22:20:5411766
tfarina42834112016-09-22 13:38:2011767 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0111768 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
11769 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]2ff8b312010-04-26 22:20:5411770
11771 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5211772 ASSERT_TRUE(response);
11773 ASSERT_TRUE(response->headers);
[email protected]2ff8b312010-04-26 22:20:5411774 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
11775
11776 std::string response_data;
robpercival214763f2016-07-01 23:27:0111777 ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
[email protected]2ff8b312010-04-26 22:20:5411778 EXPECT_EQ("hello world", response_data);
11779
11780 // Set up an initial SpdySession in the pool to reuse.
bnc8bef8da22016-05-30 01:28:2511781 HostPortPair host_port_pair("www.example.org", 443);
[email protected]e6d017652013-05-17 18:01:4011782 SpdySessionKey key(host_port_pair, ProxyServer::Direct(),
[email protected]314b03992014-04-01 01:28:5311783 PRIVACY_MODE_DISABLED);
[email protected]795cbf82013-07-22 09:37:2711784 base::WeakPtr<SpdySession> spdy_session =
Bence Béky0ef1556e2017-06-30 19:52:5211785 CreateSpdySession(session.get(), key, NetLogWithSource());
[email protected]02b0c342010-09-25 21:09:3811786
bnc87dcefc2017-05-25 12:47:5811787 trans =
Jeremy Roman0579ed62017-08-29 15:56:1911788 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]2ff8b312010-04-26 22:20:5411789
tfarina42834112016-09-22 13:38:2011790 rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0111791 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
11792 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]2ff8b312010-04-26 22:20:5411793
11794 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5211795 ASSERT_TRUE(response);
11796 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0211797 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]65041fa2010-05-21 06:56:5311798 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5211799 EXPECT_TRUE(response->was_alpn_negotiated);
[email protected]2ff8b312010-04-26 22:20:5411800
robpercival214763f2016-07-01 23:27:0111801 ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
[email protected]2ff8b312010-04-26 22:20:5411802 EXPECT_EQ("hello!", response_data);
[email protected]564b4912010-03-09 16:30:4211803}
11804
[email protected]044de0642010-06-17 10:42:1511805// GenerateAuthToken is a mighty big test.
11806// It tests all permutation of GenerateAuthToken behavior:
11807// - Synchronous and Asynchronous completion.
11808// - OK or error on completion.
11809// - Direct connection, non-authenticating proxy, and authenticating proxy.
11810// - HTTP or HTTPS backend (to include proxy tunneling).
11811// - Non-authenticating and authenticating backend.
11812//
[email protected]fe3b7dc2012-02-03 19:52:0911813// In all, there are 44 reasonable permuations (for example, if there are
[email protected]044de0642010-06-17 10:42:1511814// problems generating an auth token for an authenticating proxy, we don't
11815// need to test all permutations of the backend server).
11816//
11817// The test proceeds by going over each of the configuration cases, and
11818// potentially running up to three rounds in each of the tests. The TestConfig
11819// specifies both the configuration for the test as well as the expectations
11820// for the results.
bncd16676a2016-07-20 16:23:0111821TEST_F(HttpNetworkTransactionTest, GenerateAuthToken) {
[email protected]0b0bf032010-09-21 18:08:5011822 static const char kServer[] = "http://www.example.com";
11823 static const char kSecureServer[] = "https://www.example.com";
11824 static const char kProxy[] = "myproxy:70";
[email protected]044de0642010-06-17 10:42:1511825
11826 enum AuthTiming {
11827 AUTH_NONE,
11828 AUTH_SYNC,
11829 AUTH_ASYNC,
11830 };
11831
11832 const MockWrite kGet(
11833 "GET / HTTP/1.1\r\n"
11834 "Host: www.example.com\r\n"
11835 "Connection: keep-alive\r\n\r\n");
11836 const MockWrite kGetProxy(
11837 "GET http://www.example.com/ HTTP/1.1\r\n"
11838 "Host: www.example.com\r\n"
11839 "Proxy-Connection: keep-alive\r\n\r\n");
11840 const MockWrite kGetAuth(
11841 "GET / HTTP/1.1\r\n"
11842 "Host: www.example.com\r\n"
11843 "Connection: keep-alive\r\n"
11844 "Authorization: auth_token\r\n\r\n");
11845 const MockWrite kGetProxyAuth(
11846 "GET http://www.example.com/ HTTP/1.1\r\n"
11847 "Host: www.example.com\r\n"
11848 "Proxy-Connection: keep-alive\r\n"
11849 "Proxy-Authorization: auth_token\r\n\r\n");
11850 const MockWrite kGetAuthThroughProxy(
11851 "GET http://www.example.com/ HTTP/1.1\r\n"
11852 "Host: www.example.com\r\n"
11853 "Proxy-Connection: keep-alive\r\n"
11854 "Authorization: auth_token\r\n\r\n");
11855 const MockWrite kGetAuthWithProxyAuth(
11856 "GET http://www.example.com/ HTTP/1.1\r\n"
11857 "Host: www.example.com\r\n"
11858 "Proxy-Connection: keep-alive\r\n"
11859 "Proxy-Authorization: auth_token\r\n"
11860 "Authorization: auth_token\r\n\r\n");
11861 const MockWrite kConnect(
11862 "CONNECT www.example.com:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:1711863 "Host: www.example.com:443\r\n"
[email protected]044de0642010-06-17 10:42:1511864 "Proxy-Connection: keep-alive\r\n\r\n");
11865 const MockWrite kConnectProxyAuth(
11866 "CONNECT www.example.com:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:1711867 "Host: www.example.com:443\r\n"
[email protected]044de0642010-06-17 10:42:1511868 "Proxy-Connection: keep-alive\r\n"
11869 "Proxy-Authorization: auth_token\r\n\r\n");
11870
11871 const MockRead kSuccess(
11872 "HTTP/1.1 200 OK\r\n"
11873 "Content-Type: text/html; charset=iso-8859-1\r\n"
11874 "Content-Length: 3\r\n\r\n"
11875 "Yes");
11876 const MockRead kFailure(
11877 "Should not be called.");
11878 const MockRead kServerChallenge(
11879 "HTTP/1.1 401 Unauthorized\r\n"
11880 "WWW-Authenticate: Mock realm=server\r\n"
11881 "Content-Type: text/html; charset=iso-8859-1\r\n"
11882 "Content-Length: 14\r\n\r\n"
11883 "Unauthorized\r\n");
11884 const MockRead kProxyChallenge(
11885 "HTTP/1.1 407 Unauthorized\r\n"
11886 "Proxy-Authenticate: Mock realm=proxy\r\n"
11887 "Proxy-Connection: close\r\n"
11888 "Content-Type: text/html; charset=iso-8859-1\r\n"
11889 "Content-Length: 14\r\n\r\n"
11890 "Unauthorized\r\n");
11891 const MockRead kProxyConnected(
11892 "HTTP/1.1 200 Connection Established\r\n\r\n");
11893
11894 // NOTE(cbentzel): I wanted TestReadWriteRound to be a simple struct with
11895 // no constructors, but the C++ compiler on Windows warns about
11896 // unspecified data in compound literals. So, moved to using constructors,
11897 // and TestRound's created with the default constructor should not be used.
11898 struct TestRound {
11899 TestRound()
11900 : expected_rv(ERR_UNEXPECTED),
11901 extra_write(NULL),
11902 extra_read(NULL) {
11903 }
11904 TestRound(const MockWrite& write_arg, const MockRead& read_arg,
11905 int expected_rv_arg)
11906 : write(write_arg),
11907 read(read_arg),
11908 expected_rv(expected_rv_arg),
11909 extra_write(NULL),
11910 extra_read(NULL) {
11911 }
11912 TestRound(const MockWrite& write_arg, const MockRead& read_arg,
11913 int expected_rv_arg, const MockWrite* extra_write_arg,
[email protected]f871ee152012-07-27 19:02:0111914 const MockRead* extra_read_arg)
[email protected]044de0642010-06-17 10:42:1511915 : write(write_arg),
11916 read(read_arg),
11917 expected_rv(expected_rv_arg),
11918 extra_write(extra_write_arg),
11919 extra_read(extra_read_arg) {
11920 }
11921 MockWrite write;
11922 MockRead read;
11923 int expected_rv;
11924 const MockWrite* extra_write;
11925 const MockRead* extra_read;
11926 };
11927
11928 static const int kNoSSL = 500;
11929
11930 struct TestConfig {
asanka463ca4262016-11-16 02:34:3111931 int line_number;
thestig9d3bb0c2015-01-24 00:49:5111932 const char* const proxy_url;
[email protected]044de0642010-06-17 10:42:1511933 AuthTiming proxy_auth_timing;
asanka463ca4262016-11-16 02:34:3111934 int first_generate_proxy_token_rv;
thestig9d3bb0c2015-01-24 00:49:5111935 const char* const server_url;
[email protected]044de0642010-06-17 10:42:1511936 AuthTiming server_auth_timing;
asanka463ca4262016-11-16 02:34:3111937 int first_generate_server_token_rv;
[email protected]044de0642010-06-17 10:42:1511938 int num_auth_rounds;
11939 int first_ssl_round;
asankae2257db2016-10-11 22:03:1611940 TestRound rounds[4];
[email protected]044de0642010-06-17 10:42:1511941 } test_configs[] = {
asankac93076192016-10-03 15:46:0211942 // Non-authenticating HTTP server with a direct connection.
asanka463ca4262016-11-16 02:34:3111943 {__LINE__,
11944 nullptr,
asankac93076192016-10-03 15:46:0211945 AUTH_NONE,
11946 OK,
11947 kServer,
11948 AUTH_NONE,
11949 OK,
11950 1,
11951 kNoSSL,
11952 {TestRound(kGet, kSuccess, OK)}},
11953 // Authenticating HTTP server with a direct connection.
asanka463ca4262016-11-16 02:34:3111954 {__LINE__,
11955 nullptr,
asankac93076192016-10-03 15:46:0211956 AUTH_NONE,
11957 OK,
11958 kServer,
11959 AUTH_SYNC,
11960 OK,
11961 2,
11962 kNoSSL,
11963 {TestRound(kGet, kServerChallenge, OK),
[email protected]044de0642010-06-17 10:42:1511964 TestRound(kGetAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3111965 {__LINE__,
11966 nullptr,
asankac93076192016-10-03 15:46:0211967 AUTH_NONE,
11968 OK,
11969 kServer,
11970 AUTH_SYNC,
11971 ERR_INVALID_AUTH_CREDENTIALS,
asankae2257db2016-10-11 22:03:1611972 3,
11973 kNoSSL,
11974 {TestRound(kGet, kServerChallenge, OK),
11975 TestRound(kGet, kServerChallenge, OK),
11976 TestRound(kGetAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3111977 {__LINE__,
11978 nullptr,
asankae2257db2016-10-11 22:03:1611979 AUTH_NONE,
11980 OK,
11981 kServer,
11982 AUTH_SYNC,
11983 ERR_UNSUPPORTED_AUTH_SCHEME,
11984 2,
11985 kNoSSL,
11986 {TestRound(kGet, kServerChallenge, OK), TestRound(kGet, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3111987 {__LINE__,
11988 nullptr,
asankae2257db2016-10-11 22:03:1611989 AUTH_NONE,
11990 OK,
11991 kServer,
11992 AUTH_SYNC,
11993 ERR_UNDOCUMENTED_SECURITY_LIBRARY_STATUS,
11994 2,
11995 kNoSSL,
11996 {TestRound(kGet, kServerChallenge, OK), TestRound(kGet, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3111997 {__LINE__,
11998 kProxy,
asankae2257db2016-10-11 22:03:1611999 AUTH_SYNC,
12000 ERR_FAILED,
12001 kServer,
12002 AUTH_NONE,
12003 OK,
12004 2,
12005 kNoSSL,
12006 {TestRound(kGetProxy, kProxyChallenge, OK),
12007 TestRound(kGetProxy, kFailure, ERR_FAILED)}},
asanka463ca4262016-11-16 02:34:3112008 {__LINE__,
12009 kProxy,
asankae2257db2016-10-11 22:03:1612010 AUTH_ASYNC,
12011 ERR_FAILED,
12012 kServer,
12013 AUTH_NONE,
12014 OK,
12015 2,
12016 kNoSSL,
12017 {TestRound(kGetProxy, kProxyChallenge, OK),
12018 TestRound(kGetProxy, kFailure, ERR_FAILED)}},
asanka463ca4262016-11-16 02:34:3112019 {__LINE__,
12020 nullptr,
asankae2257db2016-10-11 22:03:1612021 AUTH_NONE,
12022 OK,
12023 kServer,
12024 AUTH_SYNC,
12025 ERR_FAILED,
asankac93076192016-10-03 15:46:0212026 2,
12027 kNoSSL,
12028 {TestRound(kGet, kServerChallenge, OK),
asankae2257db2016-10-11 22:03:1612029 TestRound(kGet, kFailure, ERR_FAILED)}},
asanka463ca4262016-11-16 02:34:3112030 {__LINE__,
12031 nullptr,
asankae2257db2016-10-11 22:03:1612032 AUTH_NONE,
12033 OK,
12034 kServer,
12035 AUTH_ASYNC,
12036 ERR_FAILED,
12037 2,
12038 kNoSSL,
12039 {TestRound(kGet, kServerChallenge, OK),
12040 TestRound(kGet, kFailure, ERR_FAILED)}},
asanka463ca4262016-11-16 02:34:3112041 {__LINE__,
12042 nullptr,
asankac93076192016-10-03 15:46:0212043 AUTH_NONE,
12044 OK,
12045 kServer,
12046 AUTH_ASYNC,
12047 OK,
12048 2,
12049 kNoSSL,
12050 {TestRound(kGet, kServerChallenge, OK),
[email protected]044de0642010-06-17 10:42:1512051 TestRound(kGetAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112052 {__LINE__,
12053 nullptr,
asankac93076192016-10-03 15:46:0212054 AUTH_NONE,
12055 OK,
12056 kServer,
12057 AUTH_ASYNC,
12058 ERR_INVALID_AUTH_CREDENTIALS,
asankae2257db2016-10-11 22:03:1612059 3,
asankac93076192016-10-03 15:46:0212060 kNoSSL,
12061 {TestRound(kGet, kServerChallenge, OK),
asankae2257db2016-10-11 22:03:1612062 // The second round uses a HttpAuthHandlerMock that always succeeds.
12063 TestRound(kGet, kServerChallenge, OK),
12064 TestRound(kGetAuth, kSuccess, OK)}},
asankac93076192016-10-03 15:46:0212065 // Non-authenticating HTTP server through a non-authenticating proxy.
asanka463ca4262016-11-16 02:34:3112066 {__LINE__,
12067 kProxy,
asankac93076192016-10-03 15:46:0212068 AUTH_NONE,
12069 OK,
12070 kServer,
12071 AUTH_NONE,
12072 OK,
12073 1,
12074 kNoSSL,
12075 {TestRound(kGetProxy, kSuccess, OK)}},
12076 // Authenticating HTTP server through a non-authenticating proxy.
asanka463ca4262016-11-16 02:34:3112077 {__LINE__,
12078 kProxy,
asankac93076192016-10-03 15:46:0212079 AUTH_NONE,
12080 OK,
12081 kServer,
12082 AUTH_SYNC,
12083 OK,
12084 2,
12085 kNoSSL,
12086 {TestRound(kGetProxy, kServerChallenge, OK),
[email protected]044de0642010-06-17 10:42:1512087 TestRound(kGetAuthThroughProxy, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112088 {__LINE__,
12089 kProxy,
asankac93076192016-10-03 15:46:0212090 AUTH_NONE,
12091 OK,
12092 kServer,
12093 AUTH_SYNC,
12094 ERR_INVALID_AUTH_CREDENTIALS,
asankae2257db2016-10-11 22:03:1612095 3,
asankac93076192016-10-03 15:46:0212096 kNoSSL,
12097 {TestRound(kGetProxy, kServerChallenge, OK),
asankae2257db2016-10-11 22:03:1612098 TestRound(kGetProxy, kServerChallenge, OK),
12099 TestRound(kGetAuthThroughProxy, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112100 {__LINE__,
12101 kProxy,
asankac93076192016-10-03 15:46:0212102 AUTH_NONE,
12103 OK,
12104 kServer,
12105 AUTH_ASYNC,
12106 OK,
12107 2,
12108 kNoSSL,
12109 {TestRound(kGetProxy, kServerChallenge, OK),
[email protected]044de0642010-06-17 10:42:1512110 TestRound(kGetAuthThroughProxy, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112111 {__LINE__,
12112 kProxy,
asankac93076192016-10-03 15:46:0212113 AUTH_NONE,
12114 OK,
12115 kServer,
12116 AUTH_ASYNC,
12117 ERR_INVALID_AUTH_CREDENTIALS,
12118 2,
12119 kNoSSL,
12120 {TestRound(kGetProxy, kServerChallenge, OK),
asankae2257db2016-10-11 22:03:1612121 TestRound(kGetProxy, kSuccess, OK)}},
asankac93076192016-10-03 15:46:0212122 // Non-authenticating HTTP server through an authenticating proxy.
asanka463ca4262016-11-16 02:34:3112123 {__LINE__,
12124 kProxy,
asankac93076192016-10-03 15:46:0212125 AUTH_SYNC,
12126 OK,
12127 kServer,
12128 AUTH_NONE,
12129 OK,
12130 2,
12131 kNoSSL,
12132 {TestRound(kGetProxy, kProxyChallenge, OK),
[email protected]044de0642010-06-17 10:42:1512133 TestRound(kGetProxyAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112134 {__LINE__,
12135 kProxy,
asankac93076192016-10-03 15:46:0212136 AUTH_SYNC,
12137 ERR_INVALID_AUTH_CREDENTIALS,
12138 kServer,
12139 AUTH_NONE,
12140 OK,
12141 2,
12142 kNoSSL,
12143 {TestRound(kGetProxy, kProxyChallenge, OK),
asankae2257db2016-10-11 22:03:1612144 TestRound(kGetProxy, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112145 {__LINE__,
12146 kProxy,
asankac93076192016-10-03 15:46:0212147 AUTH_ASYNC,
12148 OK,
12149 kServer,
12150 AUTH_NONE,
12151 OK,
12152 2,
12153 kNoSSL,
12154 {TestRound(kGetProxy, kProxyChallenge, OK),
[email protected]044de0642010-06-17 10:42:1512155 TestRound(kGetProxyAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112156 {__LINE__,
12157 kProxy,
asankac93076192016-10-03 15:46:0212158 AUTH_ASYNC,
12159 ERR_INVALID_AUTH_CREDENTIALS,
12160 kServer,
12161 AUTH_NONE,
12162 OK,
12163 2,
12164 kNoSSL,
12165 {TestRound(kGetProxy, kProxyChallenge, OK),
asankae2257db2016-10-11 22:03:1612166 TestRound(kGetProxy, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112167 {__LINE__,
12168 kProxy,
12169 AUTH_ASYNC,
12170 ERR_INVALID_AUTH_CREDENTIALS,
12171 kServer,
12172 AUTH_NONE,
12173 OK,
12174 3,
12175 kNoSSL,
12176 {TestRound(kGetProxy, kProxyChallenge, OK),
12177 TestRound(kGetProxy, kProxyChallenge, OK),
12178 TestRound(kGetProxyAuth, kSuccess, OK)}},
asankac93076192016-10-03 15:46:0212179 // Authenticating HTTP server through an authenticating proxy.
asanka463ca4262016-11-16 02:34:3112180 {__LINE__,
12181 kProxy,
asankac93076192016-10-03 15:46:0212182 AUTH_SYNC,
12183 OK,
12184 kServer,
12185 AUTH_SYNC,
12186 OK,
12187 3,
12188 kNoSSL,
12189 {TestRound(kGetProxy, kProxyChallenge, OK),
[email protected]044de0642010-06-17 10:42:1512190 TestRound(kGetProxyAuth, kServerChallenge, OK),
12191 TestRound(kGetAuthWithProxyAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112192 {__LINE__,
12193 kProxy,
asankac93076192016-10-03 15:46:0212194 AUTH_SYNC,
12195 OK,
12196 kServer,
12197 AUTH_SYNC,
12198 ERR_INVALID_AUTH_CREDENTIALS,
12199 3,
12200 kNoSSL,
12201 {TestRound(kGetProxy, kProxyChallenge, OK),
[email protected]044de0642010-06-17 10:42:1512202 TestRound(kGetProxyAuth, kServerChallenge, OK),
asankae2257db2016-10-11 22:03:1612203 TestRound(kGetProxyAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112204 {__LINE__,
12205 kProxy,
asankac93076192016-10-03 15:46:0212206 AUTH_ASYNC,
12207 OK,
12208 kServer,
12209 AUTH_SYNC,
12210 OK,
12211 3,
12212 kNoSSL,
12213 {TestRound(kGetProxy, kProxyChallenge, OK),
[email protected]044de0642010-06-17 10:42:1512214 TestRound(kGetProxyAuth, kServerChallenge, OK),
12215 TestRound(kGetAuthWithProxyAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112216 {__LINE__,
12217 kProxy,
asankac93076192016-10-03 15:46:0212218 AUTH_ASYNC,
12219 OK,
12220 kServer,
12221 AUTH_SYNC,
12222 ERR_INVALID_AUTH_CREDENTIALS,
12223 3,
12224 kNoSSL,
12225 {TestRound(kGetProxy, kProxyChallenge, OK),
[email protected]044de0642010-06-17 10:42:1512226 TestRound(kGetProxyAuth, kServerChallenge, OK),
asankae2257db2016-10-11 22:03:1612227 TestRound(kGetProxyAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112228 {__LINE__,
12229 kProxy,
asankac93076192016-10-03 15:46:0212230 AUTH_SYNC,
12231 OK,
12232 kServer,
12233 AUTH_ASYNC,
12234 OK,
12235 3,
12236 kNoSSL,
12237 {TestRound(kGetProxy, kProxyChallenge, OK),
[email protected]044de0642010-06-17 10:42:1512238 TestRound(kGetProxyAuth, kServerChallenge, OK),
12239 TestRound(kGetAuthWithProxyAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112240 {__LINE__,
12241 kProxy,
12242 AUTH_SYNC,
12243 ERR_INVALID_AUTH_CREDENTIALS,
12244 kServer,
12245 AUTH_ASYNC,
12246 OK,
12247 4,
12248 kNoSSL,
12249 {TestRound(kGetProxy, kProxyChallenge, OK),
12250 TestRound(kGetProxy, kProxyChallenge, OK),
12251 TestRound(kGetProxyAuth, kServerChallenge, OK),
12252 TestRound(kGetAuthWithProxyAuth, kSuccess, OK)}},
12253 {__LINE__,
12254 kProxy,
asankac93076192016-10-03 15:46:0212255 AUTH_SYNC,
12256 OK,
12257 kServer,
12258 AUTH_ASYNC,
12259 ERR_INVALID_AUTH_CREDENTIALS,
12260 3,
12261 kNoSSL,
12262 {TestRound(kGetProxy, kProxyChallenge, OK),
[email protected]044de0642010-06-17 10:42:1512263 TestRound(kGetProxyAuth, kServerChallenge, OK),
asankae2257db2016-10-11 22:03:1612264 TestRound(kGetProxyAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112265 {__LINE__,
12266 kProxy,
asankac93076192016-10-03 15:46:0212267 AUTH_ASYNC,
12268 OK,
12269 kServer,
12270 AUTH_ASYNC,
12271 OK,
12272 3,
12273 kNoSSL,
12274 {TestRound(kGetProxy, kProxyChallenge, OK),
[email protected]044de0642010-06-17 10:42:1512275 TestRound(kGetProxyAuth, kServerChallenge, OK),
12276 TestRound(kGetAuthWithProxyAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112277 {__LINE__,
12278 kProxy,
asankac93076192016-10-03 15:46:0212279 AUTH_ASYNC,
12280 OK,
12281 kServer,
12282 AUTH_ASYNC,
12283 ERR_INVALID_AUTH_CREDENTIALS,
12284 3,
12285 kNoSSL,
12286 {TestRound(kGetProxy, kProxyChallenge, OK),
[email protected]044de0642010-06-17 10:42:1512287 TestRound(kGetProxyAuth, kServerChallenge, OK),
asankae2257db2016-10-11 22:03:1612288 TestRound(kGetProxyAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112289 {__LINE__,
12290 kProxy,
12291 AUTH_ASYNC,
12292 ERR_INVALID_AUTH_CREDENTIALS,
12293 kServer,
12294 AUTH_ASYNC,
12295 ERR_INVALID_AUTH_CREDENTIALS,
12296 4,
12297 kNoSSL,
12298 {TestRound(kGetProxy, kProxyChallenge, OK),
12299 TestRound(kGetProxy, kProxyChallenge, OK),
12300 TestRound(kGetProxyAuth, kServerChallenge, OK),
12301 TestRound(kGetProxyAuth, kSuccess, OK)}},
asankac93076192016-10-03 15:46:0212302 // Non-authenticating HTTPS server with a direct connection.
asanka463ca4262016-11-16 02:34:3112303 {__LINE__,
12304 nullptr,
asankac93076192016-10-03 15:46:0212305 AUTH_NONE,
12306 OK,
12307 kSecureServer,
12308 AUTH_NONE,
12309 OK,
12310 1,
12311 0,
12312 {TestRound(kGet, kSuccess, OK)}},
12313 // Authenticating HTTPS server with a direct connection.
asanka463ca4262016-11-16 02:34:3112314 {__LINE__,
12315 nullptr,
asankac93076192016-10-03 15:46:0212316 AUTH_NONE,
12317 OK,
12318 kSecureServer,
12319 AUTH_SYNC,
12320 OK,
12321 2,
12322 0,
12323 {TestRound(kGet, kServerChallenge, OK),
[email protected]044de0642010-06-17 10:42:1512324 TestRound(kGetAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112325 {__LINE__,
12326 nullptr,
asankac93076192016-10-03 15:46:0212327 AUTH_NONE,
12328 OK,
12329 kSecureServer,
12330 AUTH_SYNC,
12331 ERR_INVALID_AUTH_CREDENTIALS,
12332 2,
12333 0,
asankae2257db2016-10-11 22:03:1612334 {TestRound(kGet, kServerChallenge, OK), TestRound(kGet, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112335 {__LINE__,
12336 nullptr,
asankac93076192016-10-03 15:46:0212337 AUTH_NONE,
12338 OK,
12339 kSecureServer,
12340 AUTH_ASYNC,
12341 OK,
12342 2,
12343 0,
12344 {TestRound(kGet, kServerChallenge, OK),
[email protected]044de0642010-06-17 10:42:1512345 TestRound(kGetAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112346 {__LINE__,
12347 nullptr,
asankac93076192016-10-03 15:46:0212348 AUTH_NONE,
12349 OK,
12350 kSecureServer,
12351 AUTH_ASYNC,
12352 ERR_INVALID_AUTH_CREDENTIALS,
12353 2,
12354 0,
asankae2257db2016-10-11 22:03:1612355 {TestRound(kGet, kServerChallenge, OK), TestRound(kGet, kSuccess, OK)}},
asankac93076192016-10-03 15:46:0212356 // Non-authenticating HTTPS server with a non-authenticating proxy.
asanka463ca4262016-11-16 02:34:3112357 {__LINE__,
12358 kProxy,
asankac93076192016-10-03 15:46:0212359 AUTH_NONE,
12360 OK,
12361 kSecureServer,
12362 AUTH_NONE,
12363 OK,
12364 1,
12365 0,
12366 {TestRound(kConnect, kProxyConnected, OK, &kGet, &kSuccess)}},
12367 // Authenticating HTTPS server through a non-authenticating proxy.
asanka463ca4262016-11-16 02:34:3112368 {__LINE__,
12369 kProxy,
asankac93076192016-10-03 15:46:0212370 AUTH_NONE,
12371 OK,
12372 kSecureServer,
12373 AUTH_SYNC,
12374 OK,
12375 2,
12376 0,
12377 {TestRound(kConnect, kProxyConnected, OK, &kGet, &kServerChallenge),
[email protected]044de0642010-06-17 10:42:1512378 TestRound(kGetAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112379 {__LINE__,
12380 kProxy,
asankac93076192016-10-03 15:46:0212381 AUTH_NONE,
12382 OK,
12383 kSecureServer,
12384 AUTH_SYNC,
12385 ERR_INVALID_AUTH_CREDENTIALS,
12386 2,
12387 0,
12388 {TestRound(kConnect, kProxyConnected, OK, &kGet, &kServerChallenge),
asankae2257db2016-10-11 22:03:1612389 TestRound(kGet, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112390 {__LINE__,
12391 kProxy,
asankac93076192016-10-03 15:46:0212392 AUTH_NONE,
12393 OK,
12394 kSecureServer,
12395 AUTH_ASYNC,
12396 OK,
12397 2,
12398 0,
12399 {TestRound(kConnect, kProxyConnected, OK, &kGet, &kServerChallenge),
[email protected]044de0642010-06-17 10:42:1512400 TestRound(kGetAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112401 {__LINE__,
12402 kProxy,
asankac93076192016-10-03 15:46:0212403 AUTH_NONE,
12404 OK,
12405 kSecureServer,
12406 AUTH_ASYNC,
12407 ERR_INVALID_AUTH_CREDENTIALS,
12408 2,
12409 0,
12410 {TestRound(kConnect, kProxyConnected, OK, &kGet, &kServerChallenge),
asankae2257db2016-10-11 22:03:1612411 TestRound(kGet, kSuccess, OK)}},
asankac93076192016-10-03 15:46:0212412 // Non-Authenticating HTTPS server through an authenticating proxy.
asanka463ca4262016-11-16 02:34:3112413 {__LINE__,
12414 kProxy,
asankac93076192016-10-03 15:46:0212415 AUTH_SYNC,
12416 OK,
12417 kSecureServer,
12418 AUTH_NONE,
12419 OK,
12420 2,
12421 1,
12422 {TestRound(kConnect, kProxyChallenge, OK),
[email protected]044de0642010-06-17 10:42:1512423 TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet, &kSuccess)}},
asanka463ca4262016-11-16 02:34:3112424 {__LINE__,
12425 kProxy,
asankac93076192016-10-03 15:46:0212426 AUTH_SYNC,
12427 ERR_INVALID_AUTH_CREDENTIALS,
12428 kSecureServer,
12429 AUTH_NONE,
12430 OK,
12431 2,
12432 kNoSSL,
12433 {TestRound(kConnect, kProxyChallenge, OK),
asankae2257db2016-10-11 22:03:1612434 TestRound(kConnect, kProxyConnected, OK, &kGet, &kSuccess)}},
asanka463ca4262016-11-16 02:34:3112435 {__LINE__,
12436 kProxy,
asankae2257db2016-10-11 22:03:1612437 AUTH_SYNC,
12438 ERR_UNSUPPORTED_AUTH_SCHEME,
12439 kSecureServer,
12440 AUTH_NONE,
12441 OK,
12442 2,
12443 kNoSSL,
12444 {TestRound(kConnect, kProxyChallenge, OK),
12445 TestRound(kConnect, kProxyConnected, OK, &kGet, &kSuccess)}},
asanka463ca4262016-11-16 02:34:3112446 {__LINE__,
12447 kProxy,
asankae2257db2016-10-11 22:03:1612448 AUTH_SYNC,
12449 ERR_UNEXPECTED,
12450 kSecureServer,
12451 AUTH_NONE,
12452 OK,
12453 2,
12454 kNoSSL,
12455 {TestRound(kConnect, kProxyChallenge, OK),
12456 TestRound(kConnect, kProxyConnected, ERR_UNEXPECTED)}},
asanka463ca4262016-11-16 02:34:3112457 {__LINE__,
12458 kProxy,
asankac93076192016-10-03 15:46:0212459 AUTH_ASYNC,
12460 OK,
12461 kSecureServer,
12462 AUTH_NONE,
12463 OK,
12464 2,
12465 1,
12466 {TestRound(kConnect, kProxyChallenge, OK),
[email protected]044de0642010-06-17 10:42:1512467 TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet, &kSuccess)}},
asanka463ca4262016-11-16 02:34:3112468 {__LINE__,
12469 kProxy,
asankac93076192016-10-03 15:46:0212470 AUTH_ASYNC,
12471 ERR_INVALID_AUTH_CREDENTIALS,
12472 kSecureServer,
12473 AUTH_NONE,
12474 OK,
12475 2,
12476 kNoSSL,
12477 {TestRound(kConnect, kProxyChallenge, OK),
asankae2257db2016-10-11 22:03:1612478 TestRound(kConnect, kProxyConnected, OK, &kGet, &kSuccess)}},
asankac93076192016-10-03 15:46:0212479 // Authenticating HTTPS server through an authenticating proxy.
asanka463ca4262016-11-16 02:34:3112480 {__LINE__,
12481 kProxy,
asankac93076192016-10-03 15:46:0212482 AUTH_SYNC,
12483 OK,
12484 kSecureServer,
12485 AUTH_SYNC,
12486 OK,
12487 3,
12488 1,
12489 {TestRound(kConnect, kProxyChallenge, OK),
12490 TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet,
12491 &kServerChallenge),
[email protected]044de0642010-06-17 10:42:1512492 TestRound(kGetAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112493 {__LINE__,
12494 kProxy,
asankac93076192016-10-03 15:46:0212495 AUTH_SYNC,
12496 OK,
12497 kSecureServer,
12498 AUTH_SYNC,
12499 ERR_INVALID_AUTH_CREDENTIALS,
12500 3,
12501 1,
12502 {TestRound(kConnect, kProxyChallenge, OK),
12503 TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet,
12504 &kServerChallenge),
asankae2257db2016-10-11 22:03:1612505 TestRound(kGet, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112506 {__LINE__,
12507 kProxy,
asankac93076192016-10-03 15:46:0212508 AUTH_ASYNC,
12509 OK,
12510 kSecureServer,
12511 AUTH_SYNC,
12512 OK,
12513 3,
12514 1,
12515 {TestRound(kConnect, kProxyChallenge, OK),
12516 TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet,
12517 &kServerChallenge),
[email protected]044de0642010-06-17 10:42:1512518 TestRound(kGetAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112519 {__LINE__,
12520 kProxy,
asankac93076192016-10-03 15:46:0212521 AUTH_ASYNC,
12522 OK,
12523 kSecureServer,
12524 AUTH_SYNC,
12525 ERR_INVALID_AUTH_CREDENTIALS,
12526 3,
12527 1,
12528 {TestRound(kConnect, kProxyChallenge, OK),
12529 TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet,
12530 &kServerChallenge),
asankae2257db2016-10-11 22:03:1612531 TestRound(kGet, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112532 {__LINE__,
12533 kProxy,
asankac93076192016-10-03 15:46:0212534 AUTH_SYNC,
12535 OK,
12536 kSecureServer,
12537 AUTH_ASYNC,
12538 OK,
12539 3,
12540 1,
12541 {TestRound(kConnect, kProxyChallenge, OK),
12542 TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet,
12543 &kServerChallenge),
[email protected]044de0642010-06-17 10:42:1512544 TestRound(kGetAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112545 {__LINE__,
12546 kProxy,
asankac93076192016-10-03 15:46:0212547 AUTH_SYNC,
12548 OK,
12549 kSecureServer,
12550 AUTH_ASYNC,
12551 ERR_INVALID_AUTH_CREDENTIALS,
12552 3,
12553 1,
12554 {TestRound(kConnect, kProxyChallenge, OK),
12555 TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet,
12556 &kServerChallenge),
asankae2257db2016-10-11 22:03:1612557 TestRound(kGet, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112558 {__LINE__,
12559 kProxy,
asankac93076192016-10-03 15:46:0212560 AUTH_ASYNC,
12561 OK,
12562 kSecureServer,
12563 AUTH_ASYNC,
12564 OK,
12565 3,
12566 1,
12567 {TestRound(kConnect, kProxyChallenge, OK),
12568 TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet,
12569 &kServerChallenge),
[email protected]044de0642010-06-17 10:42:1512570 TestRound(kGetAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112571 {__LINE__,
12572 kProxy,
asankac93076192016-10-03 15:46:0212573 AUTH_ASYNC,
12574 OK,
12575 kSecureServer,
12576 AUTH_ASYNC,
12577 ERR_INVALID_AUTH_CREDENTIALS,
12578 3,
12579 1,
12580 {TestRound(kConnect, kProxyChallenge, OK),
12581 TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet,
12582 &kServerChallenge),
asankae2257db2016-10-11 22:03:1612583 TestRound(kGet, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112584 {__LINE__,
12585 kProxy,
12586 AUTH_ASYNC,
12587 ERR_INVALID_AUTH_CREDENTIALS,
12588 kSecureServer,
12589 AUTH_ASYNC,
12590 ERR_INVALID_AUTH_CREDENTIALS,
12591 4,
12592 2,
12593 {TestRound(kConnect, kProxyChallenge, OK),
12594 TestRound(kConnect, kProxyChallenge, OK),
12595 TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet,
12596 &kServerChallenge),
12597 TestRound(kGet, kSuccess, OK)}},
[email protected]044de0642010-06-17 10:42:1512598 };
12599
asanka463ca4262016-11-16 02:34:3112600 for (const auto& test_config : test_configs) {
12601 SCOPED_TRACE(::testing::Message() << "Test config at "
12602 << test_config.line_number);
[email protected]2d01c262011-08-11 23:07:0812603 HttpAuthHandlerMock::Factory* auth_factory(
12604 new HttpAuthHandlerMock::Factory());
[email protected]bb88e1d32013-05-03 23:11:0712605 session_deps_.http_auth_handler_factory.reset(auth_factory);
asanka5ffd5d72016-03-23 16:20:4912606 SSLInfo empty_ssl_info;
[email protected]65d34382010-07-01 18:12:2612607
12608 // Set up authentication handlers as necessary.
[email protected]044de0642010-06-17 10:42:1512609 if (test_config.proxy_auth_timing != AUTH_NONE) {
asanka463ca4262016-11-16 02:34:3112610 for (int n = 0; n < 3; n++) {
[email protected]2d01c262011-08-11 23:07:0812611 HttpAuthHandlerMock* auth_handler(new HttpAuthHandlerMock());
12612 std::string auth_challenge = "Mock realm=proxy";
12613 GURL origin(test_config.proxy_url);
[email protected]df41d0d82014-03-13 00:43:2412614 HttpAuthChallengeTokenizer tokenizer(auth_challenge.begin(),
12615 auth_challenge.end());
[email protected]2d01c262011-08-11 23:07:0812616 auth_handler->InitFromChallenge(&tokenizer, HttpAuth::AUTH_PROXY,
tfarina42834112016-09-22 13:38:2012617 empty_ssl_info, origin,
12618 NetLogWithSource());
[email protected]2d01c262011-08-11 23:07:0812619 auth_handler->SetGenerateExpectation(
12620 test_config.proxy_auth_timing == AUTH_ASYNC,
asanka463ca4262016-11-16 02:34:3112621 n == 0 ? test_config.first_generate_proxy_token_rv : OK);
[email protected]2d01c262011-08-11 23:07:0812622 auth_factory->AddMockHandler(auth_handler, HttpAuth::AUTH_PROXY);
12623 }
[email protected]044de0642010-06-17 10:42:1512624 }
12625 if (test_config.server_auth_timing != AUTH_NONE) {
[email protected]3fd9dae2010-06-21 11:39:0012626 HttpAuthHandlerMock* auth_handler(new HttpAuthHandlerMock());
[email protected]044de0642010-06-17 10:42:1512627 std::string auth_challenge = "Mock realm=server";
12628 GURL origin(test_config.server_url);
[email protected]df41d0d82014-03-13 00:43:2412629 HttpAuthChallengeTokenizer tokenizer(auth_challenge.begin(),
12630 auth_challenge.end());
[email protected]044de0642010-06-17 10:42:1512631 auth_handler->InitFromChallenge(&tokenizer, HttpAuth::AUTH_SERVER,
tfarina42834112016-09-22 13:38:2012632 empty_ssl_info, origin,
12633 NetLogWithSource());
[email protected]044de0642010-06-17 10:42:1512634 auth_handler->SetGenerateExpectation(
12635 test_config.server_auth_timing == AUTH_ASYNC,
asanka463ca4262016-11-16 02:34:3112636 test_config.first_generate_server_token_rv);
[email protected]2d01c262011-08-11 23:07:0812637 auth_factory->AddMockHandler(auth_handler, HttpAuth::AUTH_SERVER);
asankae2257db2016-10-11 22:03:1612638
12639 // The second handler always succeeds. It should only be used where there
12640 // are multiple auth sessions for server auth in the same network
12641 // transaction using the same auth scheme.
12642 std::unique_ptr<HttpAuthHandlerMock> second_handler =
Jeremy Roman0579ed62017-08-29 15:56:1912643 std::make_unique<HttpAuthHandlerMock>();
asankae2257db2016-10-11 22:03:1612644 second_handler->InitFromChallenge(&tokenizer, HttpAuth::AUTH_SERVER,
12645 empty_ssl_info, origin,
12646 NetLogWithSource());
12647 second_handler->SetGenerateExpectation(true, OK);
12648 auth_factory->AddMockHandler(second_handler.release(),
12649 HttpAuth::AUTH_SERVER);
[email protected]044de0642010-06-17 10:42:1512650 }
12651 if (test_config.proxy_url) {
rdsmith82957ad2015-09-16 19:42:0312652 session_deps_.proxy_service =
12653 ProxyService::CreateFixed(test_config.proxy_url);
[email protected]044de0642010-06-17 10:42:1512654 } else {
rdsmith82957ad2015-09-16 19:42:0312655 session_deps_.proxy_service = ProxyService::CreateDirect();
[email protected]044de0642010-06-17 10:42:1512656 }
12657
12658 HttpRequestInfo request;
12659 request.method = "GET";
12660 request.url = GURL(test_config.server_url);
[email protected]044de0642010-06-17 10:42:1512661
danakj1fd259a02016-04-16 03:17:0912662 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]044de0642010-06-17 10:42:1512663
rchcb68dc62015-05-21 04:45:3612664 SSLSocketDataProvider ssl_socket_data_provider(SYNCHRONOUS, OK);
12665
12666 std::vector<std::vector<MockRead>> mock_reads(1);
12667 std::vector<std::vector<MockWrite>> mock_writes(1);
[email protected]044de0642010-06-17 10:42:1512668 for (int round = 0; round < test_config.num_auth_rounds; ++round) {
davidben8c7089a2017-04-17 20:38:2212669 SCOPED_TRACE(round);
[email protected]044de0642010-06-17 10:42:1512670 const TestRound& read_write_round = test_config.rounds[round];
12671
12672 // Set up expected reads and writes.
rchcb68dc62015-05-21 04:45:3612673 mock_reads.back().push_back(read_write_round.read);
12674 mock_writes.back().push_back(read_write_round.write);
12675
12676 // kProxyChallenge uses Proxy-Connection: close which means that the
12677 // socket is closed and a new one will be created for the next request.
mmenkee71e15332015-10-07 16:39:5412678 if (read_write_round.read.data == kProxyChallenge.data) {
rchcb68dc62015-05-21 04:45:3612679 mock_reads.push_back(std::vector<MockRead>());
12680 mock_writes.push_back(std::vector<MockWrite>());
[email protected]044de0642010-06-17 10:42:1512681 }
12682
rchcb68dc62015-05-21 04:45:3612683 if (read_write_round.extra_read) {
12684 mock_reads.back().push_back(*read_write_round.extra_read);
[email protected]044de0642010-06-17 10:42:1512685 }
rchcb68dc62015-05-21 04:45:3612686 if (read_write_round.extra_write) {
12687 mock_writes.back().push_back(*read_write_round.extra_write);
12688 }
[email protected]044de0642010-06-17 10:42:1512689
12690 // Add an SSL sequence if necessary.
[email protected]044de0642010-06-17 10:42:1512691 if (round >= test_config.first_ssl_round)
[email protected]bb88e1d32013-05-03 23:11:0712692 session_deps_.socket_factory->AddSSLSocketDataProvider(
[email protected]044de0642010-06-17 10:42:1512693 &ssl_socket_data_provider);
rchcb68dc62015-05-21 04:45:3612694 }
[email protected]044de0642010-06-17 10:42:1512695
danakj1fd259a02016-04-16 03:17:0912696 std::vector<std::unique_ptr<StaticSocketDataProvider>> data_providers;
rchcb68dc62015-05-21 04:45:3612697 for (size_t i = 0; i < mock_reads.size(); ++i) {
Jeremy Roman0579ed62017-08-29 15:56:1912698 data_providers.push_back(std::make_unique<StaticSocketDataProvider>(
davidben5f8b6bc2015-11-25 03:19:5412699 mock_reads[i].data(), mock_reads[i].size(), mock_writes[i].data(),
bnc87dcefc2017-05-25 12:47:5812700 mock_writes[i].size()));
rchcb68dc62015-05-21 04:45:3612701 session_deps_.socket_factory->AddSocketDataProvider(
olli.raula525048c2015-12-10 07:38:3212702 data_providers.back().get());
rchcb68dc62015-05-21 04:45:3612703 }
12704
mmenkecc2298e2015-12-07 18:20:1812705 // Transaction must be created after DataProviders, so it's destroyed before
12706 // they are as well.
12707 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
12708
rchcb68dc62015-05-21 04:45:3612709 for (int round = 0; round < test_config.num_auth_rounds; ++round) {
davidben8c7089a2017-04-17 20:38:2212710 SCOPED_TRACE(round);
rchcb68dc62015-05-21 04:45:3612711 const TestRound& read_write_round = test_config.rounds[round];
[email protected]044de0642010-06-17 10:42:1512712 // Start or restart the transaction.
[email protected]49639fa2011-12-20 23:22:4112713 TestCompletionCallback callback;
[email protected]044de0642010-06-17 10:42:1512714 int rv;
12715 if (round == 0) {
tfarina42834112016-09-22 13:38:2012716 rv = trans.Start(&request, callback.callback(), NetLogWithSource());
[email protected]044de0642010-06-17 10:42:1512717 } else {
[email protected]49639fa2011-12-20 23:22:4112718 rv = trans.RestartWithAuth(
12719 AuthCredentials(kFoo, kBar), callback.callback());
[email protected]044de0642010-06-17 10:42:1512720 }
12721 if (rv == ERR_IO_PENDING)
12722 rv = callback.WaitForResult();
12723
12724 // Compare results with expected data.
asankae2257db2016-10-11 22:03:1612725 EXPECT_THAT(rv, IsError(read_write_round.expected_rv));
[email protected]0b0bf032010-09-21 18:08:5012726 const HttpResponseInfo* response = trans.GetResponseInfo();
ttuttlec0c828492015-05-15 01:25:5512727 if (read_write_round.expected_rv != OK) {
[email protected]044de0642010-06-17 10:42:1512728 EXPECT_EQ(round + 1, test_config.num_auth_rounds);
12729 continue;
12730 }
12731 if (round + 1 < test_config.num_auth_rounds) {
wezca1070932016-05-26 20:30:5212732 EXPECT_TRUE(response->auth_challenge);
[email protected]044de0642010-06-17 10:42:1512733 } else {
wezca1070932016-05-26 20:30:5212734 EXPECT_FALSE(response->auth_challenge);
asankae2257db2016-10-11 22:03:1612735 EXPECT_FALSE(trans.IsReadyToRestartForAuth());
[email protected]044de0642010-06-17 10:42:1512736 }
12737 }
[email protected]e5ae96a2010-04-14 20:12:4512738 }
12739}
12740
bncd16676a2016-07-20 16:23:0112741TEST_F(HttpNetworkTransactionTest, MultiRoundAuth) {
[email protected]c871bce92010-07-15 21:51:1412742 // Do multi-round authentication and make sure it works correctly.
[email protected]c871bce92010-07-15 21:51:1412743 HttpAuthHandlerMock::Factory* auth_factory(
12744 new HttpAuthHandlerMock::Factory());
[email protected]bb88e1d32013-05-03 23:11:0712745 session_deps_.http_auth_handler_factory.reset(auth_factory);
rdsmith82957ad2015-09-16 19:42:0312746 session_deps_.proxy_service = ProxyService::CreateDirect();
[email protected]bb88e1d32013-05-03 23:11:0712747 session_deps_.host_resolver->rules()->AddRule("www.example.com", "10.0.0.1");
12748 session_deps_.host_resolver->set_synchronous_mode(true);
[email protected]c871bce92010-07-15 21:51:1412749
12750 HttpAuthHandlerMock* auth_handler(new HttpAuthHandlerMock());
12751 auth_handler->set_connection_based(true);
12752 std::string auth_challenge = "Mock realm=server";
12753 GURL origin("http://www.example.com");
[email protected]df41d0d82014-03-13 00:43:2412754 HttpAuthChallengeTokenizer tokenizer(auth_challenge.begin(),
12755 auth_challenge.end());
asanka5ffd5d72016-03-23 16:20:4912756 SSLInfo empty_ssl_info;
[email protected]c871bce92010-07-15 21:51:1412757 auth_handler->InitFromChallenge(&tokenizer, HttpAuth::AUTH_SERVER,
tfarina42834112016-09-22 13:38:2012758 empty_ssl_info, origin, NetLogWithSource());
[email protected]2d01c262011-08-11 23:07:0812759 auth_factory->AddMockHandler(auth_handler, HttpAuth::AUTH_SERVER);
[email protected]c871bce92010-07-15 21:51:1412760
[email protected]c871bce92010-07-15 21:51:1412761 int rv = OK;
12762 const HttpResponseInfo* response = NULL;
12763 HttpRequestInfo request;
12764 request.method = "GET";
12765 request.url = origin;
[email protected]cb9bf6ca2011-01-28 13:15:2712766
danakj1fd259a02016-04-16 03:17:0912767 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]7ef4cbbb2011-02-06 11:19:1012768
12769 // Use a TCP Socket Pool with only one connection per group. This is used
12770 // to validate that the TCP socket is not released to the pool between
12771 // each round of multi-round authentication.
mmenkee65e7af2015-10-13 17:16:4212772 HttpNetworkSessionPeer session_peer(session.get());
[email protected]ab739042011-04-07 15:22:2812773 TransportClientSocketPool* transport_pool = new TransportClientSocketPool(
[email protected]7ef4cbbb2011-02-06 11:19:1012774 50, // Max sockets for pool
12775 1, // Max sockets per group
tbansal7b403bcc2016-04-13 22:33:2112776 session_deps_.host_resolver.get(), session_deps_.socket_factory.get(),
12777 NULL, session_deps_.net_log);
Jeremy Roman0579ed62017-08-29 15:56:1912778 auto mock_pool_manager = std::make_unique<MockClientSocketPoolManager>();
[email protected]a42dbd142011-11-17 16:42:0212779 mock_pool_manager->SetTransportSocketPool(transport_pool);
dchengc7eeda422015-12-26 03:56:4812780 session_peer.SetClientSocketPoolManager(std::move(mock_pool_manager));
[email protected]7ef4cbbb2011-02-06 11:19:1012781
bnc691fda62016-08-12 00:43:1612782 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]49639fa2011-12-20 23:22:4112783 TestCompletionCallback callback;
[email protected]c871bce92010-07-15 21:51:1412784
12785 const MockWrite kGet(
12786 "GET / HTTP/1.1\r\n"
12787 "Host: www.example.com\r\n"
12788 "Connection: keep-alive\r\n\r\n");
12789 const MockWrite kGetAuth(
12790 "GET / HTTP/1.1\r\n"
12791 "Host: www.example.com\r\n"
12792 "Connection: keep-alive\r\n"
12793 "Authorization: auth_token\r\n\r\n");
12794
12795 const MockRead kServerChallenge(
12796 "HTTP/1.1 401 Unauthorized\r\n"
12797 "WWW-Authenticate: Mock realm=server\r\n"
12798 "Content-Type: text/html; charset=iso-8859-1\r\n"
12799 "Content-Length: 14\r\n\r\n"
12800 "Unauthorized\r\n");
12801 const MockRead kSuccess(
12802 "HTTP/1.1 200 OK\r\n"
12803 "Content-Type: text/html; charset=iso-8859-1\r\n"
12804 "Content-Length: 3\r\n\r\n"
12805 "Yes");
12806
12807 MockWrite writes[] = {
12808 // First round
12809 kGet,
12810 // Second round
12811 kGetAuth,
12812 // Third round
12813 kGetAuth,
[email protected]eca50e122010-09-11 14:03:3012814 // Fourth round
[email protected]7ef4cbbb2011-02-06 11:19:1012815 kGetAuth,
12816 // Competing request
12817 kGet,
[email protected]c871bce92010-07-15 21:51:1412818 };
12819 MockRead reads[] = {
12820 // First round
12821 kServerChallenge,
12822 // Second round
12823 kServerChallenge,
12824 // Third round
[email protected]eca50e122010-09-11 14:03:3012825 kServerChallenge,
12826 // Fourth round
[email protected]c871bce92010-07-15 21:51:1412827 kSuccess,
[email protected]7ef4cbbb2011-02-06 11:19:1012828 // Competing response
12829 kSuccess,
[email protected]c871bce92010-07-15 21:51:1412830 };
12831 StaticSocketDataProvider data_provider(reads, arraysize(reads),
12832 writes, arraysize(writes));
[email protected]bb88e1d32013-05-03 23:11:0712833 session_deps_.socket_factory->AddSocketDataProvider(&data_provider);
[email protected]c871bce92010-07-15 21:51:1412834
thestig9d3bb0c2015-01-24 00:49:5112835 const char kSocketGroup[] = "www.example.com:80";
[email protected]7ef4cbbb2011-02-06 11:19:1012836
12837 // First round of authentication.
[email protected]c871bce92010-07-15 21:51:1412838 auth_handler->SetGenerateExpectation(false, OK);
tfarina42834112016-09-22 13:38:2012839 rv = trans.Start(&request, callback.callback(), NetLogWithSource());
[email protected]c871bce92010-07-15 21:51:1412840 if (rv == ERR_IO_PENDING)
12841 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0112842 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:1612843 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5212844 ASSERT_TRUE(response);
12845 EXPECT_TRUE(response->auth_challenge);
[email protected]ab739042011-04-07 15:22:2812846 EXPECT_EQ(0, transport_pool->IdleSocketCountInGroup(kSocketGroup));
asanka463ca4262016-11-16 02:34:3112847 EXPECT_EQ(HttpAuthHandlerMock::State::WAIT_FOR_GENERATE_AUTH_TOKEN,
12848 auth_handler->state());
[email protected]c871bce92010-07-15 21:51:1412849
[email protected]7ef4cbbb2011-02-06 11:19:1012850 // In between rounds, another request comes in for the same domain.
12851 // It should not be able to grab the TCP socket that trans has already
12852 // claimed.
bnc691fda62016-08-12 00:43:1612853 HttpNetworkTransaction trans_compete(DEFAULT_PRIORITY, session.get());
[email protected]49639fa2011-12-20 23:22:4112854 TestCompletionCallback callback_compete;
tfarina42834112016-09-22 13:38:2012855 rv = trans_compete.Start(&request, callback_compete.callback(),
12856 NetLogWithSource());
robpercival214763f2016-07-01 23:27:0112857 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]7ef4cbbb2011-02-06 11:19:1012858 // callback_compete.WaitForResult at this point would stall forever,
12859 // since the HttpNetworkTransaction does not release the request back to
12860 // the pool until after authentication completes.
12861
12862 // Second round of authentication.
[email protected]c871bce92010-07-15 21:51:1412863 auth_handler->SetGenerateExpectation(false, OK);
bnc691fda62016-08-12 00:43:1612864 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar), callback.callback());
[email protected]c871bce92010-07-15 21:51:1412865 if (rv == ERR_IO_PENDING)
12866 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0112867 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:1612868 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5212869 ASSERT_TRUE(response);
12870 EXPECT_FALSE(response->auth_challenge);
[email protected]ab739042011-04-07 15:22:2812871 EXPECT_EQ(0, transport_pool->IdleSocketCountInGroup(kSocketGroup));
asanka463ca4262016-11-16 02:34:3112872 EXPECT_EQ(HttpAuthHandlerMock::State::WAIT_FOR_GENERATE_AUTH_TOKEN,
12873 auth_handler->state());
[email protected]c871bce92010-07-15 21:51:1412874
[email protected]7ef4cbbb2011-02-06 11:19:1012875 // Third round of authentication.
[email protected]c871bce92010-07-15 21:51:1412876 auth_handler->SetGenerateExpectation(false, OK);
bnc691fda62016-08-12 00:43:1612877 rv = trans.RestartWithAuth(AuthCredentials(), callback.callback());
[email protected]c871bce92010-07-15 21:51:1412878 if (rv == ERR_IO_PENDING)
12879 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0112880 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:1612881 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5212882 ASSERT_TRUE(response);
12883 EXPECT_FALSE(response->auth_challenge);
[email protected]ab739042011-04-07 15:22:2812884 EXPECT_EQ(0, transport_pool->IdleSocketCountInGroup(kSocketGroup));
asanka463ca4262016-11-16 02:34:3112885 EXPECT_EQ(HttpAuthHandlerMock::State::WAIT_FOR_GENERATE_AUTH_TOKEN,
12886 auth_handler->state());
[email protected]eca50e122010-09-11 14:03:3012887
[email protected]7ef4cbbb2011-02-06 11:19:1012888 // Fourth round of authentication, which completes successfully.
[email protected]eca50e122010-09-11 14:03:3012889 auth_handler->SetGenerateExpectation(false, OK);
bnc691fda62016-08-12 00:43:1612890 rv = trans.RestartWithAuth(AuthCredentials(), callback.callback());
[email protected]eca50e122010-09-11 14:03:3012891 if (rv == ERR_IO_PENDING)
12892 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0112893 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:1612894 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5212895 ASSERT_TRUE(response);
12896 EXPECT_FALSE(response->auth_challenge);
[email protected]ab739042011-04-07 15:22:2812897 EXPECT_EQ(0, transport_pool->IdleSocketCountInGroup(kSocketGroup));
[email protected]7ef4cbbb2011-02-06 11:19:1012898
asanka463ca4262016-11-16 02:34:3112899 // In WAIT_FOR_CHALLENGE, although in reality the auth handler is done. A real
12900 // auth handler should transition to a DONE state in concert with the remote
12901 // server. But that's not something we can test here with a mock handler.
12902 EXPECT_EQ(HttpAuthHandlerMock::State::WAIT_FOR_CHALLENGE,
12903 auth_handler->state());
12904
[email protected]7ef4cbbb2011-02-06 11:19:1012905 // Read the body since the fourth round was successful. This will also
12906 // release the socket back to the pool.
12907 scoped_refptr<IOBufferWithSize> io_buf(new IOBufferWithSize(50));
bnc691fda62016-08-12 00:43:1612908 rv = trans.Read(io_buf.get(), io_buf->size(), callback.callback());
[email protected]7ef4cbbb2011-02-06 11:19:1012909 if (rv == ERR_IO_PENDING)
12910 rv = callback.WaitForResult();
12911 EXPECT_EQ(3, rv);
bnc691fda62016-08-12 00:43:1612912 rv = trans.Read(io_buf.get(), io_buf->size(), callback.callback());
[email protected]7ef4cbbb2011-02-06 11:19:1012913 EXPECT_EQ(0, rv);
12914 // There are still 0 idle sockets, since the trans_compete transaction
12915 // will be handed it immediately after trans releases it to the group.
[email protected]ab739042011-04-07 15:22:2812916 EXPECT_EQ(0, transport_pool->IdleSocketCountInGroup(kSocketGroup));
[email protected]7ef4cbbb2011-02-06 11:19:1012917
12918 // The competing request can now finish. Wait for the headers and then
12919 // read the body.
12920 rv = callback_compete.WaitForResult();
robpercival214763f2016-07-01 23:27:0112921 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:1612922 rv = trans_compete.Read(io_buf.get(), io_buf->size(), callback.callback());
[email protected]7ef4cbbb2011-02-06 11:19:1012923 if (rv == ERR_IO_PENDING)
12924 rv = callback.WaitForResult();
12925 EXPECT_EQ(3, rv);
bnc691fda62016-08-12 00:43:1612926 rv = trans_compete.Read(io_buf.get(), io_buf->size(), callback.callback());
[email protected]7ef4cbbb2011-02-06 11:19:1012927 EXPECT_EQ(0, rv);
12928
12929 // Finally, the socket is released to the group.
[email protected]ab739042011-04-07 15:22:2812930 EXPECT_EQ(1, transport_pool->IdleSocketCountInGroup(kSocketGroup));
[email protected]c871bce92010-07-15 21:51:1412931}
12932
[email protected]65041fa2010-05-21 06:56:5312933// This tests the case that a request is issued via http instead of spdy after
12934// npn is negotiated.
bncd16676a2016-07-20 16:23:0112935TEST_F(HttpNetworkTransactionTest, NpnWithHttpOverSSL) {
[email protected]65041fa2010-05-21 06:56:5312936 HttpRequestInfo request;
12937 request.method = "GET";
bncce36dca22015-04-21 22:11:2312938 request.url = GURL("https://www.example.org/");
[email protected]65041fa2010-05-21 06:56:5312939
12940 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:2312941 MockWrite(
12942 "GET / HTTP/1.1\r\n"
12943 "Host: www.example.org\r\n"
12944 "Connection: keep-alive\r\n\r\n"),
[email protected]65041fa2010-05-21 06:56:5312945 };
12946
12947 MockRead data_reads[] = {
bncc958faa2015-07-31 18:14:5212948 MockRead("HTTP/1.1 200 OK\r\n"),
bnc2df4b522016-07-08 18:17:4312949 MockRead(kAlternativeServiceHttpHeader),
bncc958faa2015-07-31 18:14:5212950 MockRead("\r\n"),
12951 MockRead("hello world"),
12952 MockRead(SYNCHRONOUS, OK),
[email protected]65041fa2010-05-21 06:56:5312953 };
12954
[email protected]8ddf8322012-02-23 18:08:0612955 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3612956 ssl.next_proto = kProtoHTTP11;
[email protected]65041fa2010-05-21 06:56:5312957
[email protected]bb88e1d32013-05-03 23:11:0712958 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]65041fa2010-05-21 06:56:5312959
12960 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
12961 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:0712962 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]65041fa2010-05-21 06:56:5312963
[email protected]49639fa2011-12-20 23:22:4112964 TestCompletionCallback callback;
[email protected]65041fa2010-05-21 06:56:5312965
danakj1fd259a02016-04-16 03:17:0912966 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1612967 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]65041fa2010-05-21 06:56:5312968
tfarina42834112016-09-22 13:38:2012969 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
[email protected]65041fa2010-05-21 06:56:5312970
robpercival214763f2016-07-01 23:27:0112971 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
12972 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]65041fa2010-05-21 06:56:5312973
bnc691fda62016-08-12 00:43:1612974 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5212975 ASSERT_TRUE(response);
12976 ASSERT_TRUE(response->headers);
[email protected]65041fa2010-05-21 06:56:5312977 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
12978
12979 std::string response_data;
bnc691fda62016-08-12 00:43:1612980 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
[email protected]65041fa2010-05-21 06:56:5312981 EXPECT_EQ("hello world", response_data);
12982
12983 EXPECT_FALSE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5212984 EXPECT_TRUE(response->was_alpn_negotiated);
[email protected]65041fa2010-05-21 06:56:5312985}
[email protected]26ef6582010-06-24 02:30:4712986
bnc55ff9da2015-08-19 18:42:3512987// Simulate the SSL handshake completing with an NPN negotiation followed by an
12988// immediate server closing of the socket.
12989// Regression test for https://crbug.com/46369.
bncd16676a2016-07-20 16:23:0112990TEST_F(HttpNetworkTransactionTest, SpdyPostNPNServerHangup) {
[email protected]26ef6582010-06-24 02:30:4712991 HttpRequestInfo request;
12992 request.method = "GET";
bncce36dca22015-04-21 22:11:2312993 request.url = GURL("https://www.example.org/");
[email protected]26ef6582010-06-24 02:30:4712994
[email protected]8ddf8322012-02-23 18:08:0612995 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3612996 ssl.next_proto = kProtoHTTP2;
[email protected]bb88e1d32013-05-03 23:11:0712997 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]26ef6582010-06-24 02:30:4712998
bncdf80d44fd2016-07-15 20:27:4112999 SpdySerializedFrame req(
bnc38dcd392016-02-09 23:19:4913000 spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST, true));
bncdf80d44fd2016-07-15 20:27:4113001 MockWrite spdy_writes[] = {CreateMockWrite(req, 1)};
[email protected]26ef6582010-06-24 02:30:4713002
13003 MockRead spdy_reads[] = {
[email protected]8ddf8322012-02-23 18:08:0613004 MockRead(SYNCHRONOUS, 0, 0) // Not async - return 0 immediately.
[email protected]26ef6582010-06-24 02:30:4713005 };
13006
rch8e6c6c42015-05-01 14:05:1313007 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
13008 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:0713009 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]26ef6582010-06-24 02:30:4713010
[email protected]49639fa2011-12-20 23:22:4113011 TestCompletionCallback callback;
[email protected]26ef6582010-06-24 02:30:4713012
danakj1fd259a02016-04-16 03:17:0913013 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1613014 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]26ef6582010-06-24 02:30:4713015
tfarina42834112016-09-22 13:38:2013016 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0113017 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
13018 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_CONNECTION_CLOSED));
[email protected]26ef6582010-06-24 02:30:4713019}
[email protected]65d34382010-07-01 18:12:2613020
[email protected]795cbf82013-07-22 09:37:2713021// A subclass of HttpAuthHandlerMock that records the request URL when
13022// it gets it. This is needed since the auth handler may get destroyed
13023// before we get a chance to query it.
13024class UrlRecordingHttpAuthHandlerMock : public HttpAuthHandlerMock {
13025 public:
13026 explicit UrlRecordingHttpAuthHandlerMock(GURL* url) : url_(url) {}
13027
dchengb03027d2014-10-21 12:00:2013028 ~UrlRecordingHttpAuthHandlerMock() override {}
[email protected]795cbf82013-07-22 09:37:2713029
13030 protected:
dchengb03027d2014-10-21 12:00:2013031 int GenerateAuthTokenImpl(const AuthCredentials* credentials,
13032 const HttpRequestInfo* request,
13033 const CompletionCallback& callback,
13034 std::string* auth_token) override {
[email protected]795cbf82013-07-22 09:37:2713035 *url_ = request->url;
13036 return HttpAuthHandlerMock::GenerateAuthTokenImpl(
13037 credentials, request, callback, auth_token);
13038 }
13039
13040 private:
13041 GURL* url_;
13042};
13043
[email protected]8e6441ca2010-08-19 05:56:3813044// Test that if we cancel the transaction as the connection is completing, that
13045// everything tears down correctly.
bncd16676a2016-07-20 16:23:0113046TEST_F(HttpNetworkTransactionTest, SimpleCancel) {
[email protected]8e6441ca2010-08-19 05:56:3813047 // Setup everything about the connection to complete synchronously, so that
13048 // after calling HttpNetworkTransaction::Start, the only thing we're waiting
13049 // for is the callback from the HttpStreamRequest.
13050 // Then cancel the transaction.
13051 // Verify that we don't crash.
[email protected]d973e99a2012-02-17 21:02:3613052 MockConnect mock_connect(SYNCHRONOUS, OK);
[email protected]8e6441ca2010-08-19 05:56:3813053 MockRead data_reads[] = {
[email protected]8ddf8322012-02-23 18:08:0613054 MockRead(SYNCHRONOUS, "HTTP/1.0 200 OK\r\n\r\n"),
13055 MockRead(SYNCHRONOUS, "hello world"),
13056 MockRead(SYNCHRONOUS, OK),
[email protected]8e6441ca2010-08-19 05:56:3813057 };
13058
[email protected]8e6441ca2010-08-19 05:56:3813059 HttpRequestInfo request;
13060 request.method = "GET";
bncce36dca22015-04-21 22:11:2313061 request.url = GURL("http://www.example.org/");
[email protected]8e6441ca2010-08-19 05:56:3813062
[email protected]bb88e1d32013-05-03 23:11:0713063 session_deps_.host_resolver->set_synchronous_mode(true);
danakj1fd259a02016-04-16 03:17:0913064 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc87dcefc2017-05-25 12:47:5813065 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:1913066 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:2713067
[email protected]8e6441ca2010-08-19 05:56:3813068 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
13069 data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:0713070 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]8e6441ca2010-08-19 05:56:3813071
[email protected]49639fa2011-12-20 23:22:4113072 TestCompletionCallback callback;
[email protected]8e6441ca2010-08-19 05:56:3813073
vishal.b62985ca92015-04-17 08:45:5113074 BoundTestNetLog log;
[email protected]49639fa2011-12-20 23:22:4113075 int rv = trans->Start(&request, callback.callback(), log.bound());
robpercival214763f2016-07-01 23:27:0113076 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]8e6441ca2010-08-19 05:56:3813077 trans.reset(); // Cancel the transaction here.
13078
fdoray92e35a72016-06-10 15:54:5513079 base::RunLoop().RunUntilIdle();
[email protected]f45c1ee2010-08-03 00:54:3013080}
13081
[email protected]ecab6e052014-05-16 14:58:1213082// Test that if a transaction is cancelled after receiving the headers, the
13083// stream is drained properly and added back to the socket pool. The main
13084// purpose of this test is to make sure that an HttpStreamParser can be read
13085// from after the HttpNetworkTransaction and the objects it owns have been
13086// deleted.
13087// See http://crbug.com/368418
bncd16676a2016-07-20 16:23:0113088TEST_F(HttpNetworkTransactionTest, CancelAfterHeaders) {
[email protected]ecab6e052014-05-16 14:58:1213089 MockRead data_reads[] = {
13090 MockRead(ASYNC, "HTTP/1.1 200 OK\r\n"),
13091 MockRead(ASYNC, "Content-Length: 2\r\n"),
13092 MockRead(ASYNC, "Connection: Keep-Alive\r\n\r\n"),
13093 MockRead(ASYNC, "1"),
13094 // 2 async reads are necessary to trigger a ReadResponseBody call after the
13095 // HttpNetworkTransaction has been deleted.
13096 MockRead(ASYNC, "2"),
13097 MockRead(SYNCHRONOUS, ERR_IO_PENDING), // Should never read this.
13098 };
13099 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
13100 session_deps_.socket_factory->AddSocketDataProvider(&data);
13101
danakj1fd259a02016-04-16 03:17:0913102 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]ecab6e052014-05-16 14:58:1213103
13104 {
13105 HttpRequestInfo request;
13106 request.method = "GET";
bncce36dca22015-04-21 22:11:2313107 request.url = GURL("http://www.example.org/");
[email protected]ecab6e052014-05-16 14:58:1213108
dcheng48459ac22014-08-26 00:46:4113109 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]ecab6e052014-05-16 14:58:1213110 TestCompletionCallback callback;
13111
tfarina42834112016-09-22 13:38:2013112 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0113113 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]ecab6e052014-05-16 14:58:1213114 callback.WaitForResult();
13115
13116 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5213117 ASSERT_TRUE(response);
13118 EXPECT_TRUE(response->headers);
[email protected]ecab6e052014-05-16 14:58:1213119 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
13120
13121 // The transaction and HttpRequestInfo are deleted.
13122 }
13123
13124 // Let the HttpResponseBodyDrainer drain the socket.
fdoray92e35a72016-06-10 15:54:5513125 base::RunLoop().RunUntilIdle();
[email protected]ecab6e052014-05-16 14:58:1213126
13127 // Socket should now be idle, waiting to be reused.
dcheng48459ac22014-08-26 00:46:4113128 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]ecab6e052014-05-16 14:58:1213129}
13130
[email protected]76a505b2010-08-25 06:23:0013131// Test a basic GET request through a proxy.
bncd16676a2016-07-20 16:23:0113132TEST_F(HttpNetworkTransactionTest, ProxyGet) {
rdsmith82957ad2015-09-16 19:42:0313133 session_deps_.proxy_service =
13134 ProxyService::CreateFixedFromPacResult("PROXY myproxy:70");
vishal.b62985ca92015-04-17 08:45:5113135 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:0713136 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:0913137 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]76a505b2010-08-25 06:23:0013138
[email protected]76a505b2010-08-25 06:23:0013139 HttpRequestInfo request;
13140 request.method = "GET";
bncce36dca22015-04-21 22:11:2313141 request.url = GURL("http://www.example.org/");
[email protected]76a505b2010-08-25 06:23:0013142
13143 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:2313144 MockWrite(
13145 "GET http://www.example.org/ HTTP/1.1\r\n"
13146 "Host: www.example.org\r\n"
13147 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]76a505b2010-08-25 06:23:0013148 };
13149
13150 MockRead data_reads1[] = {
13151 MockRead("HTTP/1.1 200 OK\r\n"),
13152 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
13153 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:0613154 MockRead(SYNCHRONOUS, OK),
[email protected]76a505b2010-08-25 06:23:0013155 };
13156
13157 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
13158 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:0713159 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]76a505b2010-08-25 06:23:0013160
[email protected]49639fa2011-12-20 23:22:4113161 TestCompletionCallback callback1;
[email protected]76a505b2010-08-25 06:23:0013162
bnc691fda62016-08-12 00:43:1613163 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
ryansturm49a8cb12016-06-15 16:51:0913164 BeforeHeadersSentHandler headers_handler;
bnc691fda62016-08-12 00:43:1613165 trans.SetBeforeHeadersSentCallback(
ryansturm49a8cb12016-06-15 16:51:0913166 base::Bind(&BeforeHeadersSentHandler::OnBeforeHeadersSent,
13167 base::Unretained(&headers_handler)));
[email protected]0b0bf032010-09-21 18:08:5013168
bnc691fda62016-08-12 00:43:1613169 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:0113170 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]76a505b2010-08-25 06:23:0013171
13172 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:0113173 EXPECT_THAT(rv, IsOk());
[email protected]76a505b2010-08-25 06:23:0013174
bnc691fda62016-08-12 00:43:1613175 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5213176 ASSERT_TRUE(response);
[email protected]76a505b2010-08-25 06:23:0013177
13178 EXPECT_TRUE(response->headers->IsKeepAlive());
13179 EXPECT_EQ(200, response->headers->response_code());
13180 EXPECT_EQ(100, response->headers->GetContentLength());
13181 EXPECT_TRUE(response->was_fetched_via_proxy);
tbansal2ecbbc72016-10-06 17:15:4713182 EXPECT_EQ(ProxyServer(ProxyServer::SCHEME_HTTP,
13183 HostPortPair::FromString("myproxy:70")),
13184 response->proxy_server);
ryansturm49a8cb12016-06-15 16:51:0913185 EXPECT_TRUE(headers_handler.observed_before_headers_sent());
13186 EXPECT_TRUE(headers_handler.observed_before_headers_sent_with_proxy());
13187 EXPECT_EQ("myproxy:70", headers_handler.observed_proxy_server_uri());
[email protected]76a505b2010-08-25 06:23:0013188 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
[email protected]029c83b62013-01-24 05:28:2013189
13190 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:1613191 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]029c83b62013-01-24 05:28:2013192 TestLoadTimingNotReusedWithPac(load_timing_info,
13193 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
[email protected]76a505b2010-08-25 06:23:0013194}
13195
13196// Test a basic HTTPS GET request through a proxy.
bncd16676a2016-07-20 16:23:0113197TEST_F(HttpNetworkTransactionTest, ProxyTunnelGet) {
rdsmith82957ad2015-09-16 19:42:0313198 session_deps_.proxy_service =
13199 ProxyService::CreateFixedFromPacResult("PROXY myproxy:70");
vishal.b62985ca92015-04-17 08:45:5113200 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:0713201 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:0913202 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]76a505b2010-08-25 06:23:0013203
[email protected]76a505b2010-08-25 06:23:0013204 HttpRequestInfo request;
13205 request.method = "GET";
bncce36dca22015-04-21 22:11:2313206 request.url = GURL("https://www.example.org/");
[email protected]76a505b2010-08-25 06:23:0013207
13208 // Since we have proxy, should try to establish tunnel.
13209 MockWrite data_writes1[] = {
rsleevidb16bb02015-11-12 23:47:1713210 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
13211 "Host: www.example.org:443\r\n"
13212 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]76a505b2010-08-25 06:23:0013213
rsleevidb16bb02015-11-12 23:47:1713214 MockWrite("GET / HTTP/1.1\r\n"
13215 "Host: www.example.org\r\n"
13216 "Connection: keep-alive\r\n\r\n"),
[email protected]76a505b2010-08-25 06:23:0013217 };
13218
13219 MockRead data_reads1[] = {
13220 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
13221
13222 MockRead("HTTP/1.1 200 OK\r\n"),
13223 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
13224 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:0613225 MockRead(SYNCHRONOUS, OK),
[email protected]76a505b2010-08-25 06:23:0013226 };
13227
13228 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
13229 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:0713230 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8ddf8322012-02-23 18:08:0613231 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:0713232 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]76a505b2010-08-25 06:23:0013233
[email protected]49639fa2011-12-20 23:22:4113234 TestCompletionCallback callback1;
[email protected]76a505b2010-08-25 06:23:0013235
bnc691fda62016-08-12 00:43:1613236 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
ryansturm49a8cb12016-06-15 16:51:0913237 BeforeHeadersSentHandler headers_handler;
bnc691fda62016-08-12 00:43:1613238 trans.SetBeforeHeadersSentCallback(
ryansturm49a8cb12016-06-15 16:51:0913239 base::Bind(&BeforeHeadersSentHandler::OnBeforeHeadersSent,
13240 base::Unretained(&headers_handler)));
[email protected]0b0bf032010-09-21 18:08:5013241
bnc691fda62016-08-12 00:43:1613242 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:0113243 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]76a505b2010-08-25 06:23:0013244
13245 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:0113246 EXPECT_THAT(rv, IsOk());
mmenke43758e62015-05-04 21:09:4613247 TestNetLogEntry::List entries;
[email protected]b2fcd0e2010-12-01 15:19:4013248 log.GetEntries(&entries);
[email protected]76a505b2010-08-25 06:23:0013249 size_t pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:0013250 entries, 0, NetLogEventType::HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
13251 NetLogEventPhase::NONE);
[email protected]76a505b2010-08-25 06:23:0013252 ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:4013253 entries, pos,
mikecirone8b85c432016-09-08 19:11:0013254 NetLogEventType::HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
13255 NetLogEventPhase::NONE);
[email protected]76a505b2010-08-25 06:23:0013256
bnc691fda62016-08-12 00:43:1613257 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5213258 ASSERT_TRUE(response);
[email protected]76a505b2010-08-25 06:23:0013259
13260 EXPECT_TRUE(response->headers->IsKeepAlive());
13261 EXPECT_EQ(200, response->headers->response_code());
13262 EXPECT_EQ(100, response->headers->GetContentLength());
13263 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
13264 EXPECT_TRUE(response->was_fetched_via_proxy);
tbansal2ecbbc72016-10-06 17:15:4713265 EXPECT_EQ(ProxyServer(ProxyServer::SCHEME_HTTP,
13266 HostPortPair::FromString("myproxy:70")),
13267 response->proxy_server);
ryansturm49a8cb12016-06-15 16:51:0913268 EXPECT_TRUE(headers_handler.observed_before_headers_sent());
13269 EXPECT_TRUE(headers_handler.observed_before_headers_sent_with_proxy());
13270 EXPECT_EQ("myproxy:70", headers_handler.observed_proxy_server_uri());
[email protected]029c83b62013-01-24 05:28:2013271
13272 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:1613273 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]029c83b62013-01-24 05:28:2013274 TestLoadTimingNotReusedWithPac(load_timing_info,
13275 CONNECT_TIMING_HAS_SSL_TIMES);
[email protected]76a505b2010-08-25 06:23:0013276}
13277
rsleevidb16bb02015-11-12 23:47:1713278// Test a basic HTTPS GET request through a proxy, connecting to an IPv6
13279// literal host.
bncd16676a2016-07-20 16:23:0113280TEST_F(HttpNetworkTransactionTest, ProxyTunnelGetIPv6) {
rsleevidb16bb02015-11-12 23:47:1713281 session_deps_.proxy_service =
13282 ProxyService::CreateFixedFromPacResult("PROXY myproxy:70");
13283 BoundTestNetLog log;
13284 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:0913285 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
rsleevidb16bb02015-11-12 23:47:1713286
13287 HttpRequestInfo request;
13288 request.method = "GET";
13289 request.url = GURL("https://[::1]:443/");
13290
13291 // Since we have proxy, should try to establish tunnel.
13292 MockWrite data_writes1[] = {
13293 MockWrite("CONNECT [::1]:443 HTTP/1.1\r\n"
13294 "Host: [::1]:443\r\n"
13295 "Proxy-Connection: keep-alive\r\n\r\n"),
13296
13297 MockWrite("GET / HTTP/1.1\r\n"
13298 "Host: [::1]\r\n"
13299 "Connection: keep-alive\r\n\r\n"),
13300 };
13301
13302 MockRead data_reads1[] = {
13303 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
13304
13305 MockRead("HTTP/1.1 200 OK\r\n"),
13306 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
13307 MockRead("Content-Length: 100\r\n\r\n"),
13308 MockRead(SYNCHRONOUS, OK),
13309 };
13310
13311 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
13312 data_writes1, arraysize(data_writes1));
13313 session_deps_.socket_factory->AddSocketDataProvider(&data1);
13314 SSLSocketDataProvider ssl(ASYNC, OK);
13315 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
13316
13317 TestCompletionCallback callback1;
13318
bnc691fda62016-08-12 00:43:1613319 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
rsleevidb16bb02015-11-12 23:47:1713320
bnc691fda62016-08-12 00:43:1613321 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:0113322 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
rsleevidb16bb02015-11-12 23:47:1713323
13324 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:0113325 EXPECT_THAT(rv, IsOk());
rsleevidb16bb02015-11-12 23:47:1713326 TestNetLogEntry::List entries;
13327 log.GetEntries(&entries);
13328 size_t pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:0013329 entries, 0, NetLogEventType::HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
13330 NetLogEventPhase::NONE);
rsleevidb16bb02015-11-12 23:47:1713331 ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:0013332 entries, pos,
13333 NetLogEventType::HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
13334 NetLogEventPhase::NONE);
rsleevidb16bb02015-11-12 23:47:1713335
bnc691fda62016-08-12 00:43:1613336 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5213337 ASSERT_TRUE(response);
rsleevidb16bb02015-11-12 23:47:1713338
13339 EXPECT_TRUE(response->headers->IsKeepAlive());
13340 EXPECT_EQ(200, response->headers->response_code());
13341 EXPECT_EQ(100, response->headers->GetContentLength());
13342 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
13343 EXPECT_TRUE(response->was_fetched_via_proxy);
tbansal2ecbbc72016-10-06 17:15:4713344 EXPECT_EQ(ProxyServer(ProxyServer::SCHEME_HTTP,
13345 HostPortPair::FromString("myproxy:70")),
13346 response->proxy_server);
rsleevidb16bb02015-11-12 23:47:1713347
13348 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:1613349 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
rsleevidb16bb02015-11-12 23:47:1713350 TestLoadTimingNotReusedWithPac(load_timing_info,
13351 CONNECT_TIMING_HAS_SSL_TIMES);
13352}
13353
[email protected]76a505b2010-08-25 06:23:0013354// Test a basic HTTPS GET request through a proxy, but the server hangs up
13355// while establishing the tunnel.
bncd16676a2016-07-20 16:23:0113356TEST_F(HttpNetworkTransactionTest, ProxyTunnelGetHangup) {
rdsmith82957ad2015-09-16 19:42:0313357 session_deps_.proxy_service = ProxyService::CreateFixed("myproxy:70");
vishal.b62985ca92015-04-17 08:45:5113358 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:0713359 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:0913360 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]76a505b2010-08-25 06:23:0013361
[email protected]76a505b2010-08-25 06:23:0013362 HttpRequestInfo request;
13363 request.method = "GET";
bncce36dca22015-04-21 22:11:2313364 request.url = GURL("https://www.example.org/");
[email protected]76a505b2010-08-25 06:23:0013365
13366 // Since we have proxy, should try to establish tunnel.
13367 MockWrite data_writes1[] = {
rsleevidb16bb02015-11-12 23:47:1713368 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
13369 "Host: www.example.org:443\r\n"
13370 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]76a505b2010-08-25 06:23:0013371
rsleevidb16bb02015-11-12 23:47:1713372 MockWrite("GET / HTTP/1.1\r\n"
13373 "Host: www.example.org\r\n"
13374 "Connection: keep-alive\r\n\r\n"),
[email protected]76a505b2010-08-25 06:23:0013375 };
13376
13377 MockRead data_reads1[] = {
[email protected]8ddf8322012-02-23 18:08:0613378 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
[email protected]76a505b2010-08-25 06:23:0013379 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:0613380 MockRead(ASYNC, 0, 0), // EOF
[email protected]76a505b2010-08-25 06:23:0013381 };
13382
13383 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
13384 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:0713385 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8ddf8322012-02-23 18:08:0613386 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:0713387 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]76a505b2010-08-25 06:23:0013388
[email protected]49639fa2011-12-20 23:22:4113389 TestCompletionCallback callback1;
[email protected]76a505b2010-08-25 06:23:0013390
bnc691fda62016-08-12 00:43:1613391 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]0b0bf032010-09-21 18:08:5013392
bnc691fda62016-08-12 00:43:1613393 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:0113394 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]76a505b2010-08-25 06:23:0013395
13396 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:0113397 EXPECT_THAT(rv, IsError(ERR_EMPTY_RESPONSE));
mmenke43758e62015-05-04 21:09:4613398 TestNetLogEntry::List entries;
[email protected]b2fcd0e2010-12-01 15:19:4013399 log.GetEntries(&entries);
[email protected]76a505b2010-08-25 06:23:0013400 size_t pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:0013401 entries, 0, NetLogEventType::HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
13402 NetLogEventPhase::NONE);
[email protected]76a505b2010-08-25 06:23:0013403 ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:4013404 entries, pos,
mikecirone8b85c432016-09-08 19:11:0013405 NetLogEventType::HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
13406 NetLogEventPhase::NONE);
[email protected]76a505b2010-08-25 06:23:0013407}
13408
[email protected]749eefa82010-09-13 22:14:0313409// Test for crbug.com/55424.
bncd16676a2016-07-20 16:23:0113410TEST_F(HttpNetworkTransactionTest, PreconnectWithExistingSpdySession) {
bncdf80d44fd2016-07-15 20:27:4113411 SpdySerializedFrame req(
bnc38dcd392016-02-09 23:19:4913412 spdy_util_.ConstructSpdyGet("https://www.example.org", 1, LOWEST));
bncdf80d44fd2016-07-15 20:27:4113413 MockWrite spdy_writes[] = {CreateMockWrite(req, 0)};
[email protected]749eefa82010-09-13 22:14:0313414
bnc42331402016-07-25 13:36:1513415 SpdySerializedFrame resp(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
bncdf80d44fd2016-07-15 20:27:4113416 SpdySerializedFrame data(spdy_util_.ConstructSpdyDataFrame(1, true));
[email protected]749eefa82010-09-13 22:14:0313417 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:4113418 CreateMockRead(resp, 1), CreateMockRead(data, 2), MockRead(ASYNC, 0, 3),
[email protected]749eefa82010-09-13 22:14:0313419 };
13420
rch8e6c6c42015-05-01 14:05:1313421 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
13422 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:0713423 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]749eefa82010-09-13 22:14:0313424
[email protected]8ddf8322012-02-23 18:08:0613425 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3613426 ssl.next_proto = kProtoHTTP2;
[email protected]bb88e1d32013-05-03 23:11:0713427 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]749eefa82010-09-13 22:14:0313428
danakj1fd259a02016-04-16 03:17:0913429 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]749eefa82010-09-13 22:14:0313430
13431 // Set up an initial SpdySession in the pool to reuse.
bncce36dca22015-04-21 22:11:2313432 HostPortPair host_port_pair("www.example.org", 443);
[email protected]e6d017652013-05-17 18:01:4013433 SpdySessionKey key(host_port_pair, ProxyServer::Direct(),
[email protected]314b03992014-04-01 01:28:5313434 PRIVACY_MODE_DISABLED);
[email protected]795cbf82013-07-22 09:37:2713435 base::WeakPtr<SpdySession> spdy_session =
Bence Béky0ef1556e2017-06-30 19:52:5213436 CreateSpdySession(session.get(), key, NetLogWithSource());
[email protected]749eefa82010-09-13 22:14:0313437
13438 HttpRequestInfo request;
13439 request.method = "GET";
bncce36dca22015-04-21 22:11:2313440 request.url = GURL("https://www.example.org/");
[email protected]749eefa82010-09-13 22:14:0313441
13442 // This is the important line that marks this as a preconnect.
13443 request.motivation = HttpRequestInfo::PRECONNECT_MOTIVATED;
13444
bnc691fda62016-08-12 00:43:1613445 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]749eefa82010-09-13 22:14:0313446
[email protected]41d64e82013-07-03 22:44:2613447 TestCompletionCallback callback;
tfarina42834112016-09-22 13:38:2013448 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0113449 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
13450 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]749eefa82010-09-13 22:14:0313451}
13452
[email protected]73b8dd222010-11-11 19:55:2413453// Given a net error, cause that error to be returned from the first Write()
bnc691fda62016-08-12 00:43:1613454// call and verify that the HttpNetworkTransaction fails with that error.
[email protected]23e482282013-06-14 16:08:0213455void HttpNetworkTransactionTest::CheckErrorIsPassedBack(
[email protected]bb88e1d32013-05-03 23:11:0713456 int error, IoMode mode) {
ttuttle859dc7a2015-04-23 19:42:2913457 HttpRequestInfo request_info;
[email protected]cb9bf6ca2011-01-28 13:15:2713458 request_info.url = GURL("https://www.example.com/");
13459 request_info.method = "GET";
ttuttle859dc7a2015-04-23 19:42:2913460 request_info.load_flags = LOAD_NORMAL;
[email protected]cb9bf6ca2011-01-28 13:15:2713461
[email protected]8ddf8322012-02-23 18:08:0613462 SSLSocketDataProvider ssl_data(mode, OK);
ttuttle859dc7a2015-04-23 19:42:2913463 MockWrite data_writes[] = {
13464 MockWrite(mode, error),
[email protected]73b8dd222010-11-11 19:55:2413465 };
ttuttle859dc7a2015-04-23 19:42:2913466 StaticSocketDataProvider data(NULL, 0, data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:0713467 session_deps_.socket_factory->AddSocketDataProvider(&data);
13468 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data);
[email protected]73b8dd222010-11-11 19:55:2413469
danakj1fd259a02016-04-16 03:17:0913470 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1613471 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]73b8dd222010-11-11 19:55:2413472
[email protected]49639fa2011-12-20 23:22:4113473 TestCompletionCallback callback;
tfarina42834112016-09-22 13:38:2013474 int rv = trans.Start(&request_info, callback.callback(), NetLogWithSource());
ttuttle859dc7a2015-04-23 19:42:2913475 if (rv == ERR_IO_PENDING)
[email protected]73b8dd222010-11-11 19:55:2413476 rv = callback.WaitForResult();
13477 ASSERT_EQ(error, rv);
13478}
13479
bncd16676a2016-07-20 16:23:0113480TEST_F(HttpNetworkTransactionTest, SSLWriteCertError) {
[email protected]73b8dd222010-11-11 19:55:2413481 // Just check a grab bag of cert errors.
13482 static const int kErrors[] = {
13483 ERR_CERT_COMMON_NAME_INVALID,
13484 ERR_CERT_AUTHORITY_INVALID,
13485 ERR_CERT_DATE_INVALID,
13486 };
13487 for (size_t i = 0; i < arraysize(kErrors); i++) {
[email protected]8ddf8322012-02-23 18:08:0613488 CheckErrorIsPassedBack(kErrors[i], ASYNC);
13489 CheckErrorIsPassedBack(kErrors[i], SYNCHRONOUS);
[email protected]73b8dd222010-11-11 19:55:2413490 }
13491}
13492
[email protected]bd0b6772011-01-11 19:59:3013493// Ensure that a client certificate is removed from the SSL client auth
13494// cache when:
13495// 1) No proxy is involved.
13496// 2) TLS False Start is disabled.
13497// 3) The initial TLS handshake requests a client certificate.
13498// 4) The client supplies an invalid/unacceptable certificate.
bncd16676a2016-07-20 16:23:0113499TEST_F(HttpNetworkTransactionTest, ClientAuthCertCache_Direct_NoFalseStart) {
ttuttle859dc7a2015-04-23 19:42:2913500 HttpRequestInfo request_info;
[email protected]cb9bf6ca2011-01-28 13:15:2713501 request_info.url = GURL("https://www.example.com/");
13502 request_info.method = "GET";
ttuttle859dc7a2015-04-23 19:42:2913503 request_info.load_flags = LOAD_NORMAL;
[email protected]cb9bf6ca2011-01-28 13:15:2713504
[email protected]bd0b6772011-01-11 19:59:3013505 scoped_refptr<SSLCertRequestInfo> cert_request(new SSLCertRequestInfo());
[email protected]791879c2013-12-17 07:22:4113506 cert_request->host_and_port = HostPortPair("www.example.com", 443);
[email protected]bd0b6772011-01-11 19:59:3013507
13508 // [ssl_]data1 contains the data for the first SSL handshake. When a
13509 // CertificateRequest is received for the first time, the handshake will
13510 // be aborted to allow the caller to provide a certificate.
ttuttle859dc7a2015-04-23 19:42:2913511 SSLSocketDataProvider ssl_data1(ASYNC, ERR_SSL_CLIENT_AUTH_CERT_NEEDED);
[email protected]bd0b6772011-01-11 19:59:3013512 ssl_data1.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0713513 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data1);
ttuttle859dc7a2015-04-23 19:42:2913514 StaticSocketDataProvider data1(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0713515 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]bd0b6772011-01-11 19:59:3013516
13517 // [ssl_]data2 contains the data for the second SSL handshake. When TLS
13518 // False Start is not being used, the result of the SSL handshake will be
13519 // returned as part of the SSLClientSocket::Connect() call. This test
13520 // matches the result of a server sending a handshake_failure alert,
13521 // rather than a Finished message, because it requires a client
13522 // certificate and none was supplied.
ttuttle859dc7a2015-04-23 19:42:2913523 SSLSocketDataProvider ssl_data2(ASYNC, ERR_SSL_PROTOCOL_ERROR);
[email protected]bd0b6772011-01-11 19:59:3013524 ssl_data2.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0713525 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data2);
ttuttle859dc7a2015-04-23 19:42:2913526 StaticSocketDataProvider data2(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0713527 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]bd0b6772011-01-11 19:59:3013528
13529 // [ssl_]data3 contains the data for the third SSL handshake. When a
13530 // connection to a server fails during an SSL handshake,
davidbenb937d6c2015-05-14 04:53:4213531 // HttpNetworkTransaction will attempt to fallback to TLSv1.1 if the previous
13532 // connection was attempted with TLSv1.2. This is transparent to the caller
[email protected]bd0b6772011-01-11 19:59:3013533 // of the HttpNetworkTransaction. Because this test failure is due to
13534 // requiring a client certificate, this fallback handshake should also
13535 // fail.
ttuttle859dc7a2015-04-23 19:42:2913536 SSLSocketDataProvider ssl_data3(ASYNC, ERR_SSL_PROTOCOL_ERROR);
[email protected]bd0b6772011-01-11 19:59:3013537 ssl_data3.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0713538 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data3);
ttuttle859dc7a2015-04-23 19:42:2913539 StaticSocketDataProvider data3(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0713540 session_deps_.socket_factory->AddSocketDataProvider(&data3);
[email protected]bd0b6772011-01-11 19:59:3013541
[email protected]80c75f682012-05-26 16:22:1713542 // [ssl_]data4 contains the data for the fourth SSL handshake. When a
13543 // connection to a server fails during an SSL handshake,
davidbenb937d6c2015-05-14 04:53:4213544 // HttpNetworkTransaction will attempt to fallback to TLSv1 if the previous
13545 // connection was attempted with TLSv1.1. This is transparent to the caller
[email protected]80c75f682012-05-26 16:22:1713546 // of the HttpNetworkTransaction. Because this test failure is due to
13547 // requiring a client certificate, this fallback handshake should also
13548 // fail.
ttuttle859dc7a2015-04-23 19:42:2913549 SSLSocketDataProvider ssl_data4(ASYNC, ERR_SSL_PROTOCOL_ERROR);
[email protected]80c75f682012-05-26 16:22:1713550 ssl_data4.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0713551 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data4);
ttuttle859dc7a2015-04-23 19:42:2913552 StaticSocketDataProvider data4(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0713553 session_deps_.socket_factory->AddSocketDataProvider(&data4);
[email protected]80c75f682012-05-26 16:22:1713554
danakj1fd259a02016-04-16 03:17:0913555 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1613556 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]bd0b6772011-01-11 19:59:3013557
[email protected]bd0b6772011-01-11 19:59:3013558 // Begin the SSL handshake with the peer. This consumes ssl_data1.
[email protected]49639fa2011-12-20 23:22:4113559 TestCompletionCallback callback;
tfarina42834112016-09-22 13:38:2013560 int rv = trans.Start(&request_info, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0113561 ASSERT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]bd0b6772011-01-11 19:59:3013562
13563 // Complete the SSL handshake, which should abort due to requiring a
13564 // client certificate.
13565 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0113566 ASSERT_THAT(rv, IsError(ERR_SSL_CLIENT_AUTH_CERT_NEEDED));
[email protected]bd0b6772011-01-11 19:59:3013567
13568 // Indicate that no certificate should be supplied. From the perspective
13569 // of SSLClientCertCache, NULL is just as meaningful as a real
13570 // certificate, so this is the same as supply a
13571 // legitimate-but-unacceptable certificate.
bnc691fda62016-08-12 00:43:1613572 rv = trans.RestartWithCertificate(NULL, NULL, callback.callback());
robpercival214763f2016-07-01 23:27:0113573 ASSERT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]bd0b6772011-01-11 19:59:3013574
13575 // Ensure the certificate was added to the client auth cache before
13576 // allowing the connection to continue restarting.
13577 scoped_refptr<X509Certificate> client_cert;
svaldez7872fd02015-11-19 21:10:5413578 scoped_refptr<SSLPrivateKey> client_private_key;
[email protected]791879c2013-12-17 07:22:4113579 ASSERT_TRUE(session->ssl_client_auth_cache()->Lookup(
svaldez7872fd02015-11-19 21:10:5413580 HostPortPair("www.example.com", 443), &client_cert, &client_private_key));
wezca1070932016-05-26 20:30:5213581 ASSERT_FALSE(client_cert);
[email protected]bd0b6772011-01-11 19:59:3013582
13583 // Restart the handshake. This will consume ssl_data2, which fails, and
[email protected]80c75f682012-05-26 16:22:1713584 // then consume ssl_data3 and ssl_data4, both of which should also fail.
13585 // The result code is checked against what ssl_data4 should return.
[email protected]bd0b6772011-01-11 19:59:3013586 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0113587 ASSERT_THAT(rv, IsError(ERR_SSL_PROTOCOL_ERROR));
[email protected]bd0b6772011-01-11 19:59:3013588
13589 // Ensure that the client certificate is removed from the cache on a
13590 // handshake failure.
[email protected]791879c2013-12-17 07:22:4113591 ASSERT_FALSE(session->ssl_client_auth_cache()->Lookup(
svaldez7872fd02015-11-19 21:10:5413592 HostPortPair("www.example.com", 443), &client_cert, &client_private_key));
[email protected]bd0b6772011-01-11 19:59:3013593}
13594
13595// Ensure that a client certificate is removed from the SSL client auth
13596// cache when:
13597// 1) No proxy is involved.
13598// 2) TLS False Start is enabled.
13599// 3) The initial TLS handshake requests a client certificate.
13600// 4) The client supplies an invalid/unacceptable certificate.
bncd16676a2016-07-20 16:23:0113601TEST_F(HttpNetworkTransactionTest, ClientAuthCertCache_Direct_FalseStart) {
ttuttle859dc7a2015-04-23 19:42:2913602 HttpRequestInfo request_info;
[email protected]cb9bf6ca2011-01-28 13:15:2713603 request_info.url = GURL("https://www.example.com/");
13604 request_info.method = "GET";
ttuttle859dc7a2015-04-23 19:42:2913605 request_info.load_flags = LOAD_NORMAL;
[email protected]cb9bf6ca2011-01-28 13:15:2713606
[email protected]bd0b6772011-01-11 19:59:3013607 scoped_refptr<SSLCertRequestInfo> cert_request(new SSLCertRequestInfo());
[email protected]791879c2013-12-17 07:22:4113608 cert_request->host_and_port = HostPortPair("www.example.com", 443);
[email protected]bd0b6772011-01-11 19:59:3013609
13610 // When TLS False Start is used, SSLClientSocket::Connect() calls will
13611 // return successfully after reading up to the peer's Certificate message.
13612 // This is to allow the caller to call SSLClientSocket::Write(), which can
13613 // enqueue application data to be sent in the same packet as the
13614 // ChangeCipherSpec and Finished messages.
13615 // The actual handshake will be finished when SSLClientSocket::Read() is
13616 // called, which expects to process the peer's ChangeCipherSpec and
13617 // Finished messages. If there was an error negotiating with the peer,
13618 // such as due to the peer requiring a client certificate when none was
13619 // supplied, the alert sent by the peer won't be processed until Read() is
13620 // called.
13621
13622 // Like the non-False Start case, when a client certificate is requested by
13623 // the peer, the handshake is aborted during the Connect() call.
13624 // [ssl_]data1 represents the initial SSL handshake with the peer.
ttuttle859dc7a2015-04-23 19:42:2913625 SSLSocketDataProvider ssl_data1(ASYNC, ERR_SSL_CLIENT_AUTH_CERT_NEEDED);
[email protected]bd0b6772011-01-11 19:59:3013626 ssl_data1.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0713627 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data1);
ttuttle859dc7a2015-04-23 19:42:2913628 StaticSocketDataProvider data1(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0713629 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]bd0b6772011-01-11 19:59:3013630
13631 // When a client certificate is supplied, Connect() will not be aborted
13632 // when the peer requests the certificate. Instead, the handshake will
13633 // artificially succeed, allowing the caller to write the HTTP request to
13634 // the socket. The handshake messages are not processed until Read() is
13635 // called, which then detects that the handshake was aborted, due to the
13636 // peer sending a handshake_failure because it requires a client
13637 // certificate.
ttuttle859dc7a2015-04-23 19:42:2913638 SSLSocketDataProvider ssl_data2(ASYNC, OK);
[email protected]bd0b6772011-01-11 19:59:3013639 ssl_data2.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0713640 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data2);
ttuttle859dc7a2015-04-23 19:42:2913641 MockRead data2_reads[] = {
13642 MockRead(ASYNC /* async */, ERR_SSL_PROTOCOL_ERROR),
[email protected]bd0b6772011-01-11 19:59:3013643 };
ttuttle859dc7a2015-04-23 19:42:2913644 StaticSocketDataProvider data2(data2_reads, arraysize(data2_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0713645 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]bd0b6772011-01-11 19:59:3013646
13647 // As described in ClientAuthCertCache_Direct_NoFalseStart, [ssl_]data3 is
[email protected]80c75f682012-05-26 16:22:1713648 // the data for the SSL handshake once the TLSv1.1 connection falls back to
13649 // TLSv1. It has the same behaviour as [ssl_]data2.
ttuttle859dc7a2015-04-23 19:42:2913650 SSLSocketDataProvider ssl_data3(ASYNC, OK);
[email protected]bd0b6772011-01-11 19:59:3013651 ssl_data3.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0713652 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data3);
ttuttle859dc7a2015-04-23 19:42:2913653 StaticSocketDataProvider data3(data2_reads, arraysize(data2_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0713654 session_deps_.socket_factory->AddSocketDataProvider(&data3);
[email protected]bd0b6772011-01-11 19:59:3013655
[email protected]80c75f682012-05-26 16:22:1713656 // [ssl_]data4 is the data for the SSL handshake once the TLSv1 connection
13657 // falls back to SSLv3. It has the same behaviour as [ssl_]data2.
ttuttle859dc7a2015-04-23 19:42:2913658 SSLSocketDataProvider ssl_data4(ASYNC, OK);
[email protected]80c75f682012-05-26 16:22:1713659 ssl_data4.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0713660 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data4);
ttuttle859dc7a2015-04-23 19:42:2913661 StaticSocketDataProvider data4(data2_reads, arraysize(data2_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0713662 session_deps_.socket_factory->AddSocketDataProvider(&data4);
[email protected]80c75f682012-05-26 16:22:1713663
[email protected]7799de12013-05-30 05:52:5113664 // Need one more if TLSv1.2 is enabled.
ttuttle859dc7a2015-04-23 19:42:2913665 SSLSocketDataProvider ssl_data5(ASYNC, OK);
[email protected]7799de12013-05-30 05:52:5113666 ssl_data5.cert_request_info = cert_request.get();
13667 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data5);
ttuttle859dc7a2015-04-23 19:42:2913668 StaticSocketDataProvider data5(data2_reads, arraysize(data2_reads), NULL, 0);
[email protected]7799de12013-05-30 05:52:5113669 session_deps_.socket_factory->AddSocketDataProvider(&data5);
13670
danakj1fd259a02016-04-16 03:17:0913671 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1613672 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]bd0b6772011-01-11 19:59:3013673
[email protected]bd0b6772011-01-11 19:59:3013674 // Begin the initial SSL handshake.
[email protected]49639fa2011-12-20 23:22:4113675 TestCompletionCallback callback;
tfarina42834112016-09-22 13:38:2013676 int rv = trans.Start(&request_info, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0113677 ASSERT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]bd0b6772011-01-11 19:59:3013678
13679 // Complete the SSL handshake, which should abort due to requiring a
13680 // client certificate.
13681 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0113682 ASSERT_THAT(rv, IsError(ERR_SSL_CLIENT_AUTH_CERT_NEEDED));
[email protected]bd0b6772011-01-11 19:59:3013683
13684 // Indicate that no certificate should be supplied. From the perspective
13685 // of SSLClientCertCache, NULL is just as meaningful as a real
13686 // certificate, so this is the same as supply a
13687 // legitimate-but-unacceptable certificate.
bnc691fda62016-08-12 00:43:1613688 rv = trans.RestartWithCertificate(NULL, NULL, callback.callback());
robpercival214763f2016-07-01 23:27:0113689 ASSERT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]bd0b6772011-01-11 19:59:3013690
13691 // Ensure the certificate was added to the client auth cache before
13692 // allowing the connection to continue restarting.
13693 scoped_refptr<X509Certificate> client_cert;
svaldez7872fd02015-11-19 21:10:5413694 scoped_refptr<SSLPrivateKey> client_private_key;
[email protected]791879c2013-12-17 07:22:4113695 ASSERT_TRUE(session->ssl_client_auth_cache()->Lookup(
svaldez7872fd02015-11-19 21:10:5413696 HostPortPair("www.example.com", 443), &client_cert, &client_private_key));
wezca1070932016-05-26 20:30:5213697 ASSERT_FALSE(client_cert);
[email protected]bd0b6772011-01-11 19:59:3013698
[email protected]bd0b6772011-01-11 19:59:3013699 // Restart the handshake. This will consume ssl_data2, which fails, and
[email protected]80c75f682012-05-26 16:22:1713700 // then consume ssl_data3 and ssl_data4, both of which should also fail.
13701 // The result code is checked against what ssl_data4 should return.
[email protected]bd0b6772011-01-11 19:59:3013702 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0113703 ASSERT_THAT(rv, IsError(ERR_SSL_PROTOCOL_ERROR));
[email protected]bd0b6772011-01-11 19:59:3013704
13705 // Ensure that the client certificate is removed from the cache on a
13706 // handshake failure.
[email protected]791879c2013-12-17 07:22:4113707 ASSERT_FALSE(session->ssl_client_auth_cache()->Lookup(
svaldez7872fd02015-11-19 21:10:5413708 HostPortPair("www.example.com", 443), &client_cert, &client_private_key));
[email protected]bd0b6772011-01-11 19:59:3013709}
13710
[email protected]8c405132011-01-11 22:03:1813711// Ensure that a client certificate is removed from the SSL client auth
13712// cache when:
13713// 1) An HTTPS proxy is involved.
13714// 3) The HTTPS proxy requests a client certificate.
13715// 4) The client supplies an invalid/unacceptable certificate for the
13716// proxy.
13717// The test is repeated twice, first for connecting to an HTTPS endpoint,
13718// then for connecting to an HTTP endpoint.
bncd16676a2016-07-20 16:23:0113719TEST_F(HttpNetworkTransactionTest, ClientAuthCertCache_Proxy_Fail) {
rdsmith82957ad2015-09-16 19:42:0313720 session_deps_.proxy_service = ProxyService::CreateFixed("https://proxy:70");
vishal.b62985ca92015-04-17 08:45:5113721 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:0713722 session_deps_.net_log = log.bound().net_log();
[email protected]8c405132011-01-11 22:03:1813723
13724 scoped_refptr<SSLCertRequestInfo> cert_request(new SSLCertRequestInfo());
[email protected]791879c2013-12-17 07:22:4113725 cert_request->host_and_port = HostPortPair("proxy", 70);
[email protected]8c405132011-01-11 22:03:1813726
13727 // See ClientAuthCertCache_Direct_NoFalseStart for the explanation of
13728 // [ssl_]data[1-3]. Rather than represending the endpoint
13729 // (www.example.com:443), they represent failures with the HTTPS proxy
13730 // (proxy:70).
ttuttle859dc7a2015-04-23 19:42:2913731 SSLSocketDataProvider ssl_data1(ASYNC, ERR_SSL_CLIENT_AUTH_CERT_NEEDED);
[email protected]8c405132011-01-11 22:03:1813732 ssl_data1.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0713733 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data1);
ttuttle859dc7a2015-04-23 19:42:2913734 StaticSocketDataProvider data1(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0713735 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8c405132011-01-11 22:03:1813736
ttuttle859dc7a2015-04-23 19:42:2913737 SSLSocketDataProvider ssl_data2(ASYNC, ERR_SSL_PROTOCOL_ERROR);
[email protected]8c405132011-01-11 22:03:1813738 ssl_data2.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0713739 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data2);
ttuttle859dc7a2015-04-23 19:42:2913740 StaticSocketDataProvider data2(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0713741 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]8c405132011-01-11 22:03:1813742
[email protected]80c75f682012-05-26 16:22:1713743 // TODO(wtc): find out why this unit test doesn't need [ssl_]data3.
13744#if 0
ttuttle859dc7a2015-04-23 19:42:2913745 SSLSocketDataProvider ssl_data3(ASYNC, ERR_SSL_PROTOCOL_ERROR);
[email protected]8c405132011-01-11 22:03:1813746 ssl_data3.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0713747 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data3);
ttuttle859dc7a2015-04-23 19:42:2913748 StaticSocketDataProvider data3(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0713749 session_deps_.socket_factory->AddSocketDataProvider(&data3);
[email protected]80c75f682012-05-26 16:22:1713750#endif
[email protected]8c405132011-01-11 22:03:1813751
ttuttle859dc7a2015-04-23 19:42:2913752 HttpRequestInfo requests[2];
[email protected]8c405132011-01-11 22:03:1813753 requests[0].url = GURL("https://www.example.com/");
13754 requests[0].method = "GET";
ttuttle859dc7a2015-04-23 19:42:2913755 requests[0].load_flags = LOAD_NORMAL;
[email protected]8c405132011-01-11 22:03:1813756
13757 requests[1].url = GURL("http://www.example.com/");
13758 requests[1].method = "GET";
ttuttle859dc7a2015-04-23 19:42:2913759 requests[1].load_flags = LOAD_NORMAL;
[email protected]8c405132011-01-11 22:03:1813760
13761 for (size_t i = 0; i < arraysize(requests); ++i) {
[email protected]bb88e1d32013-05-03 23:11:0713762 session_deps_.socket_factory->ResetNextMockIndexes();
danakj1fd259a02016-04-16 03:17:0913763 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1613764 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]8c405132011-01-11 22:03:1813765
13766 // Begin the SSL handshake with the proxy.
[email protected]49639fa2011-12-20 23:22:4113767 TestCompletionCallback callback;
tfarina42834112016-09-22 13:38:2013768 int rv = trans.Start(&requests[i], callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0113769 ASSERT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]8c405132011-01-11 22:03:1813770
13771 // Complete the SSL handshake, which should abort due to requiring a
13772 // client certificate.
13773 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0113774 ASSERT_THAT(rv, IsError(ERR_SSL_CLIENT_AUTH_CERT_NEEDED));
[email protected]8c405132011-01-11 22:03:1813775
13776 // Indicate that no certificate should be supplied. From the perspective
13777 // of SSLClientCertCache, NULL is just as meaningful as a real
13778 // certificate, so this is the same as supply a
13779 // legitimate-but-unacceptable certificate.
bnc691fda62016-08-12 00:43:1613780 rv = trans.RestartWithCertificate(NULL, NULL, callback.callback());
robpercival214763f2016-07-01 23:27:0113781 ASSERT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]8c405132011-01-11 22:03:1813782
13783 // Ensure the certificate was added to the client auth cache before
13784 // allowing the connection to continue restarting.
13785 scoped_refptr<X509Certificate> client_cert;
svaldez7872fd02015-11-19 21:10:5413786 scoped_refptr<SSLPrivateKey> client_private_key;
[email protected]791879c2013-12-17 07:22:4113787 ASSERT_TRUE(session->ssl_client_auth_cache()->Lookup(
svaldez7872fd02015-11-19 21:10:5413788 HostPortPair("proxy", 70), &client_cert, &client_private_key));
wezca1070932016-05-26 20:30:5213789 ASSERT_FALSE(client_cert);
[email protected]8c405132011-01-11 22:03:1813790 // Ensure the certificate was NOT cached for the endpoint. This only
13791 // applies to HTTPS requests, but is fine to check for HTTP requests.
[email protected]791879c2013-12-17 07:22:4113792 ASSERT_FALSE(session->ssl_client_auth_cache()->Lookup(
svaldez7872fd02015-11-19 21:10:5413793 HostPortPair("www.example.com", 443), &client_cert,
13794 &client_private_key));
[email protected]8c405132011-01-11 22:03:1813795
13796 // Restart the handshake. This will consume ssl_data2, which fails, and
13797 // then consume ssl_data3, which should also fail. The result code is
13798 // checked against what ssl_data3 should return.
13799 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0113800 ASSERT_THAT(rv, IsError(ERR_PROXY_CONNECTION_FAILED));
[email protected]8c405132011-01-11 22:03:1813801
13802 // Now that the new handshake has failed, ensure that the client
13803 // certificate was removed from the client auth cache.
[email protected]791879c2013-12-17 07:22:4113804 ASSERT_FALSE(session->ssl_client_auth_cache()->Lookup(
svaldez7872fd02015-11-19 21:10:5413805 HostPortPair("proxy", 70), &client_cert, &client_private_key));
[email protected]791879c2013-12-17 07:22:4113806 ASSERT_FALSE(session->ssl_client_auth_cache()->Lookup(
svaldez7872fd02015-11-19 21:10:5413807 HostPortPair("www.example.com", 443), &client_cert,
13808 &client_private_key));
[email protected]8c405132011-01-11 22:03:1813809 }
13810}
13811
bncd16676a2016-07-20 16:23:0113812TEST_F(HttpNetworkTransactionTest, UseIPConnectionPooling) {
[email protected]e3ceb682011-06-28 23:55:4613813 // Set up a special HttpNetworkSession with a MockCachingHostResolver.
Jeremy Roman0579ed62017-08-29 15:56:1913814 session_deps_.host_resolver = std::make_unique<MockCachingHostResolver>();
danakj1fd259a02016-04-16 03:17:0913815 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]e3ceb682011-06-28 23:55:4613816
bnc032658ba2016-09-26 18:17:1513817 AddSSLSocketData();
[email protected]e3ceb682011-06-28 23:55:4613818
bncdf80d44fd2016-07-15 20:27:4113819 SpdySerializedFrame host1_req(
bnc38dcd392016-02-09 23:19:4913820 spdy_util_.ConstructSpdyGet("https://www.example.org", 1, LOWEST));
rdsmithebb50aa2015-11-12 03:44:3813821 spdy_util_.UpdateWithStreamDestruction(1);
bncdf80d44fd2016-07-15 20:27:4113822 SpdySerializedFrame host2_req(
bnca4d611d2016-09-22 19:55:3713823 spdy_util_.ConstructSpdyGet("https://mail.example.com", 3, LOWEST));
[email protected]e3ceb682011-06-28 23:55:4613824 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:4113825 CreateMockWrite(host1_req, 0), CreateMockWrite(host2_req, 3),
[email protected]e3ceb682011-06-28 23:55:4613826 };
bnc42331402016-07-25 13:36:1513827 SpdySerializedFrame host1_resp(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
bncdf80d44fd2016-07-15 20:27:4113828 SpdySerializedFrame host1_resp_body(
13829 spdy_util_.ConstructSpdyDataFrame(1, true));
bnc42331402016-07-25 13:36:1513830 SpdySerializedFrame host2_resp(spdy_util_.ConstructSpdyGetReply(NULL, 0, 3));
bncdf80d44fd2016-07-15 20:27:4113831 SpdySerializedFrame host2_resp_body(
13832 spdy_util_.ConstructSpdyDataFrame(3, true));
[email protected]e3ceb682011-06-28 23:55:4613833 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:4113834 CreateMockRead(host1_resp, 1), CreateMockRead(host1_resp_body, 2),
13835 CreateMockRead(host2_resp, 4), CreateMockRead(host2_resp_body, 5),
rch8e6c6c42015-05-01 14:05:1313836 MockRead(ASYNC, 0, 6),
[email protected]e3ceb682011-06-28 23:55:4613837 };
13838
eroman36d84e54432016-03-17 03:23:0213839 IPEndPoint peer_addr(IPAddress::IPv4Localhost(), 443);
[email protected]d2b5f092012-06-08 23:55:0213840 MockConnect connect(ASYNC, OK, peer_addr);
rch8e6c6c42015-05-01 14:05:1313841 SequencedSocketData spdy_data(connect, spdy_reads, arraysize(spdy_reads),
13842 spdy_writes, arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:0713843 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]e3ceb682011-06-28 23:55:4613844
[email protected]aa22b242011-11-16 18:58:2913845 TestCompletionCallback callback;
[email protected]e3ceb682011-06-28 23:55:4613846 HttpRequestInfo request1;
13847 request1.method = "GET";
bncce36dca22015-04-21 22:11:2313848 request1.url = GURL("https://www.example.org/");
[email protected]e3ceb682011-06-28 23:55:4613849 request1.load_flags = 0;
[email protected]90499482013-06-01 00:39:5013850 HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
[email protected]e3ceb682011-06-28 23:55:4613851
tfarina42834112016-09-22 13:38:2013852 int rv = trans1.Start(&request1, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0113853 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
13854 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]e3ceb682011-06-28 23:55:4613855
13856 const HttpResponseInfo* response = trans1.GetResponseInfo();
wezca1070932016-05-26 20:30:5213857 ASSERT_TRUE(response);
13858 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0213859 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]e3ceb682011-06-28 23:55:4613860
13861 std::string response_data;
robpercival214763f2016-07-01 23:27:0113862 ASSERT_THAT(ReadTransaction(&trans1, &response_data), IsOk());
[email protected]e3ceb682011-06-28 23:55:4613863 EXPECT_EQ("hello!", response_data);
13864
bnca4d611d2016-09-22 19:55:3713865 // Preload mail.example.com into HostCache.
13866 HostPortPair host_port("mail.example.com", 443);
[email protected]5109c1952013-08-20 18:44:1013867 HostResolver::RequestInfo resolve_info(host_port);
[email protected]e3ceb682011-06-28 23:55:4613868 AddressList ignored;
maksim.sisov31452af2016-07-27 06:38:1013869 std::unique_ptr<HostResolver::Request> request;
13870 rv = session_deps_.host_resolver->Resolve(resolve_info, DEFAULT_PRIORITY,
13871 &ignored, callback.callback(),
tfarina42834112016-09-22 13:38:2013872 &request, NetLogWithSource());
robpercival214763f2016-07-01 23:27:0113873 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]6e78dfb2011-07-28 21:34:4713874 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0113875 EXPECT_THAT(rv, IsOk());
[email protected]e3ceb682011-06-28 23:55:4613876
13877 HttpRequestInfo request2;
13878 request2.method = "GET";
bnca4d611d2016-09-22 19:55:3713879 request2.url = GURL("https://mail.example.com/");
[email protected]e3ceb682011-06-28 23:55:4613880 request2.load_flags = 0;
[email protected]90499482013-06-01 00:39:5013881 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
[email protected]e3ceb682011-06-28 23:55:4613882
tfarina42834112016-09-22 13:38:2013883 rv = trans2.Start(&request2, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0113884 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
13885 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]e3ceb682011-06-28 23:55:4613886
13887 response = trans2.GetResponseInfo();
wezca1070932016-05-26 20:30:5213888 ASSERT_TRUE(response);
13889 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0213890 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]e3ceb682011-06-28 23:55:4613891 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5213892 EXPECT_TRUE(response->was_alpn_negotiated);
robpercival214763f2016-07-01 23:27:0113893 ASSERT_THAT(ReadTransaction(&trans2, &response_data), IsOk());
[email protected]e3ceb682011-06-28 23:55:4613894 EXPECT_EQ("hello!", response_data);
[email protected]e3ceb682011-06-28 23:55:4613895}
13896
bncd16676a2016-07-20 16:23:0113897TEST_F(HttpNetworkTransactionTest, UseIPConnectionPoolingAfterResolution) {
[email protected]d2b5f092012-06-08 23:55:0213898 // Set up a special HttpNetworkSession with a MockCachingHostResolver.
Jeremy Roman0579ed62017-08-29 15:56:1913899 session_deps_.host_resolver = std::make_unique<MockCachingHostResolver>();
danakj1fd259a02016-04-16 03:17:0913900 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]d2b5f092012-06-08 23:55:0213901
bnc032658ba2016-09-26 18:17:1513902 AddSSLSocketData();
[email protected]d2b5f092012-06-08 23:55:0213903
bncdf80d44fd2016-07-15 20:27:4113904 SpdySerializedFrame host1_req(
bnc38dcd392016-02-09 23:19:4913905 spdy_util_.ConstructSpdyGet("https://www.example.org", 1, LOWEST));
rdsmithebb50aa2015-11-12 03:44:3813906 spdy_util_.UpdateWithStreamDestruction(1);
bncdf80d44fd2016-07-15 20:27:4113907 SpdySerializedFrame host2_req(
bnca4d611d2016-09-22 19:55:3713908 spdy_util_.ConstructSpdyGet("https://mail.example.com", 3, LOWEST));
[email protected]d2b5f092012-06-08 23:55:0213909 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:4113910 CreateMockWrite(host1_req, 0), CreateMockWrite(host2_req, 3),
[email protected]d2b5f092012-06-08 23:55:0213911 };
bnc42331402016-07-25 13:36:1513912 SpdySerializedFrame host1_resp(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
bncdf80d44fd2016-07-15 20:27:4113913 SpdySerializedFrame host1_resp_body(
13914 spdy_util_.ConstructSpdyDataFrame(1, true));
bnc42331402016-07-25 13:36:1513915 SpdySerializedFrame host2_resp(spdy_util_.ConstructSpdyGetReply(NULL, 0, 3));
bncdf80d44fd2016-07-15 20:27:4113916 SpdySerializedFrame host2_resp_body(
13917 spdy_util_.ConstructSpdyDataFrame(3, true));
[email protected]d2b5f092012-06-08 23:55:0213918 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:4113919 CreateMockRead(host1_resp, 1), CreateMockRead(host1_resp_body, 2),
13920 CreateMockRead(host2_resp, 4), CreateMockRead(host2_resp_body, 5),
rch8e6c6c42015-05-01 14:05:1313921 MockRead(ASYNC, 0, 6),
[email protected]d2b5f092012-06-08 23:55:0213922 };
13923
eroman36d84e54432016-03-17 03:23:0213924 IPEndPoint peer_addr(IPAddress::IPv4Localhost(), 443);
[email protected]d2b5f092012-06-08 23:55:0213925 MockConnect connect(ASYNC, OK, peer_addr);
rch8e6c6c42015-05-01 14:05:1313926 SequencedSocketData spdy_data(connect, spdy_reads, arraysize(spdy_reads),
13927 spdy_writes, arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:0713928 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]d2b5f092012-06-08 23:55:0213929
13930 TestCompletionCallback callback;
13931 HttpRequestInfo request1;
13932 request1.method = "GET";
bncce36dca22015-04-21 22:11:2313933 request1.url = GURL("https://www.example.org/");
[email protected]d2b5f092012-06-08 23:55:0213934 request1.load_flags = 0;
[email protected]90499482013-06-01 00:39:5013935 HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
[email protected]d2b5f092012-06-08 23:55:0213936
tfarina42834112016-09-22 13:38:2013937 int rv = trans1.Start(&request1, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0113938 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
13939 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]d2b5f092012-06-08 23:55:0213940
13941 const HttpResponseInfo* response = trans1.GetResponseInfo();
wezca1070932016-05-26 20:30:5213942 ASSERT_TRUE(response);
13943 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0213944 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]d2b5f092012-06-08 23:55:0213945
13946 std::string response_data;
robpercival214763f2016-07-01 23:27:0113947 ASSERT_THAT(ReadTransaction(&trans1, &response_data), IsOk());
[email protected]d2b5f092012-06-08 23:55:0213948 EXPECT_EQ("hello!", response_data);
13949
13950 HttpRequestInfo request2;
13951 request2.method = "GET";
bnca4d611d2016-09-22 19:55:3713952 request2.url = GURL("https://mail.example.com/");
[email protected]d2b5f092012-06-08 23:55:0213953 request2.load_flags = 0;
[email protected]90499482013-06-01 00:39:5013954 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
[email protected]d2b5f092012-06-08 23:55:0213955
tfarina42834112016-09-22 13:38:2013956 rv = trans2.Start(&request2, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0113957 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
13958 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]d2b5f092012-06-08 23:55:0213959
13960 response = trans2.GetResponseInfo();
wezca1070932016-05-26 20:30:5213961 ASSERT_TRUE(response);
13962 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0213963 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]d2b5f092012-06-08 23:55:0213964 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5213965 EXPECT_TRUE(response->was_alpn_negotiated);
robpercival214763f2016-07-01 23:27:0113966 ASSERT_THAT(ReadTransaction(&trans2, &response_data), IsOk());
[email protected]d2b5f092012-06-08 23:55:0213967 EXPECT_EQ("hello!", response_data);
[email protected]d2b5f092012-06-08 23:55:0213968}
13969
bnc8016c1f2017-03-31 02:11:2913970// Regression test for https://crbug.com/546991.
13971// The server might not be able to serve an IP pooled request, and might send a
13972// 421 Misdirected Request response status to indicate this.
13973// HttpNetworkTransaction should reset the request and retry without IP pooling.
13974TEST_F(HttpNetworkTransactionTest, RetryWithoutConnectionPooling) {
13975 // Two hosts resolve to the same IP address.
13976 const std::string ip_addr = "1.2.3.4";
13977 IPAddress ip;
13978 ASSERT_TRUE(ip.AssignFromIPLiteral(ip_addr));
13979 IPEndPoint peer_addr = IPEndPoint(ip, 443);
13980
Jeremy Roman0579ed62017-08-29 15:56:1913981 session_deps_.host_resolver = std::make_unique<MockCachingHostResolver>();
bnc8016c1f2017-03-31 02:11:2913982 session_deps_.host_resolver->rules()->AddRule("www.example.org", ip_addr);
13983 session_deps_.host_resolver->rules()->AddRule("mail.example.org", ip_addr);
13984
13985 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
13986
13987 // Two requests on the first connection.
13988 SpdySerializedFrame req1(
13989 spdy_util_.ConstructSpdyGet("https://www.example.org", 1, LOWEST));
13990 spdy_util_.UpdateWithStreamDestruction(1);
13991 SpdySerializedFrame req2(
13992 spdy_util_.ConstructSpdyGet("https://mail.example.org", 3, LOWEST));
13993 SpdySerializedFrame rst(
13994 spdy_util_.ConstructSpdyRstStream(3, ERROR_CODE_CANCEL));
13995 MockWrite writes1[] = {
13996 CreateMockWrite(req1, 0), CreateMockWrite(req2, 3),
13997 CreateMockWrite(rst, 6),
13998 };
13999
14000 // The first one succeeds, the second gets error 421 Misdirected Request.
14001 SpdySerializedFrame resp1(spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
14002 SpdySerializedFrame body1(spdy_util_.ConstructSpdyDataFrame(1, true));
14003 SpdyHeaderBlock response_headers;
Bence Békybda82952017-10-02 17:35:2714004 response_headers[kHttp2StatusHeader] = "421";
bnc8016c1f2017-03-31 02:11:2914005 SpdySerializedFrame resp2(
14006 spdy_util_.ConstructSpdyReply(3, std::move(response_headers)));
14007 MockRead reads1[] = {CreateMockRead(resp1, 1), CreateMockRead(body1, 2),
14008 CreateMockRead(resp2, 4), MockRead(ASYNC, 0, 5)};
14009
14010 MockConnect connect1(ASYNC, OK, peer_addr);
14011 SequencedSocketData data1(connect1, reads1, arraysize(reads1), writes1,
14012 arraysize(writes1));
14013 session_deps_.socket_factory->AddSocketDataProvider(&data1);
14014
14015 AddSSLSocketData();
14016
14017 // Retry the second request on a second connection.
14018 SpdyTestUtil spdy_util2;
14019 SpdySerializedFrame req3(
14020 spdy_util2.ConstructSpdyGet("https://mail.example.org", 1, LOWEST));
14021 MockWrite writes2[] = {
14022 CreateMockWrite(req3, 0),
14023 };
14024
14025 SpdySerializedFrame resp3(spdy_util2.ConstructSpdyGetReply(nullptr, 0, 1));
14026 SpdySerializedFrame body3(spdy_util2.ConstructSpdyDataFrame(1, true));
14027 MockRead reads2[] = {CreateMockRead(resp3, 1), CreateMockRead(body3, 2),
14028 MockRead(ASYNC, 0, 3)};
14029
14030 MockConnect connect2(ASYNC, OK, peer_addr);
14031 SequencedSocketData data2(connect2, reads2, arraysize(reads2), writes2,
14032 arraysize(writes2));
14033 session_deps_.socket_factory->AddSocketDataProvider(&data2);
14034
14035 AddSSLSocketData();
14036
14037 // Preload mail.example.org into HostCache.
14038 HostPortPair host_port("mail.example.org", 443);
14039 HostResolver::RequestInfo resolve_info(host_port);
14040 AddressList ignored;
14041 std::unique_ptr<HostResolver::Request> request;
14042 TestCompletionCallback callback;
14043 int rv = session_deps_.host_resolver->Resolve(resolve_info, DEFAULT_PRIORITY,
14044 &ignored, callback.callback(),
14045 &request, NetLogWithSource());
14046 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
14047 rv = callback.WaitForResult();
14048 EXPECT_THAT(rv, IsOk());
14049
14050 HttpRequestInfo request1;
14051 request1.method = "GET";
14052 request1.url = GURL("https://www.example.org/");
14053 request1.load_flags = 0;
14054 HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
14055
14056 rv = trans1.Start(&request1, callback.callback(), NetLogWithSource());
14057 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
14058 rv = callback.WaitForResult();
14059 EXPECT_THAT(rv, IsOk());
14060
14061 const HttpResponseInfo* response = trans1.GetResponseInfo();
14062 ASSERT_TRUE(response);
14063 ASSERT_TRUE(response->headers);
14064 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
14065 EXPECT_TRUE(response->was_fetched_via_spdy);
14066 EXPECT_TRUE(response->was_alpn_negotiated);
14067 std::string response_data;
14068 ASSERT_THAT(ReadTransaction(&trans1, &response_data), IsOk());
14069 EXPECT_EQ("hello!", response_data);
14070
14071 HttpRequestInfo request2;
14072 request2.method = "GET";
14073 request2.url = GURL("https://mail.example.org/");
14074 request2.load_flags = 0;
14075 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
14076
14077 BoundTestNetLog log;
14078 rv = trans2.Start(&request2, callback.callback(), log.bound());
14079 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
14080 rv = callback.WaitForResult();
14081 EXPECT_THAT(rv, IsOk());
14082
14083 response = trans2.GetResponseInfo();
14084 ASSERT_TRUE(response);
14085 ASSERT_TRUE(response->headers);
14086 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
14087 EXPECT_TRUE(response->was_fetched_via_spdy);
14088 EXPECT_TRUE(response->was_alpn_negotiated);
14089 ASSERT_THAT(ReadTransaction(&trans2, &response_data), IsOk());
14090 EXPECT_EQ("hello!", response_data);
14091
14092 TestNetLogEntry::List entries;
14093 log.GetEntries(&entries);
davidbence688ae2017-05-04 15:12:5914094 ExpectLogContainsSomewhere(
14095 entries, 0, NetLogEventType::HTTP_TRANSACTION_RESTART_MISDIRECTED_REQUEST,
bnc8016c1f2017-03-31 02:11:2914096 NetLogEventPhase::NONE);
davidbence688ae2017-05-04 15:12:5914097}
14098
14099// Test that HTTP 421 responses are properly returned to the caller if received
14100// on the retry as well. HttpNetworkTransaction should not infinite loop or lose
14101// portions of the response.
14102TEST_F(HttpNetworkTransactionTest, ReturnHTTP421OnRetry) {
14103 // Two hosts resolve to the same IP address.
14104 const std::string ip_addr = "1.2.3.4";
14105 IPAddress ip;
14106 ASSERT_TRUE(ip.AssignFromIPLiteral(ip_addr));
14107 IPEndPoint peer_addr = IPEndPoint(ip, 443);
14108
Jeremy Roman0579ed62017-08-29 15:56:1914109 session_deps_.host_resolver = std::make_unique<MockCachingHostResolver>();
davidbence688ae2017-05-04 15:12:5914110 session_deps_.host_resolver->rules()->AddRule("www.example.org", ip_addr);
14111 session_deps_.host_resolver->rules()->AddRule("mail.example.org", ip_addr);
14112
14113 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
14114
14115 // Two requests on the first connection.
14116 SpdySerializedFrame req1(
14117 spdy_util_.ConstructSpdyGet("https://www.example.org", 1, LOWEST));
14118 spdy_util_.UpdateWithStreamDestruction(1);
14119 SpdySerializedFrame req2(
14120 spdy_util_.ConstructSpdyGet("https://mail.example.org", 3, LOWEST));
14121 SpdySerializedFrame rst(
14122 spdy_util_.ConstructSpdyRstStream(3, ERROR_CODE_CANCEL));
14123 MockWrite writes1[] = {
14124 CreateMockWrite(req1, 0), CreateMockWrite(req2, 3),
14125 CreateMockWrite(rst, 6),
14126 };
14127
14128 // The first one succeeds, the second gets error 421 Misdirected Request.
14129 SpdySerializedFrame resp1(spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
14130 SpdySerializedFrame body1(spdy_util_.ConstructSpdyDataFrame(1, true));
14131 SpdyHeaderBlock response_headers;
Bence Békybda82952017-10-02 17:35:2714132 response_headers[kHttp2StatusHeader] = "421";
davidbence688ae2017-05-04 15:12:5914133 SpdySerializedFrame resp2(
14134 spdy_util_.ConstructSpdyReply(3, response_headers.Clone()));
14135 MockRead reads1[] = {CreateMockRead(resp1, 1), CreateMockRead(body1, 2),
14136 CreateMockRead(resp2, 4), MockRead(ASYNC, 0, 5)};
14137
14138 MockConnect connect1(ASYNC, OK, peer_addr);
14139 SequencedSocketData data1(connect1, reads1, arraysize(reads1), writes1,
14140 arraysize(writes1));
14141 session_deps_.socket_factory->AddSocketDataProvider(&data1);
14142
14143 AddSSLSocketData();
14144
14145 // Retry the second request on a second connection. It returns 421 Misdirected
14146 // Retry again.
14147 SpdyTestUtil spdy_util2;
14148 SpdySerializedFrame req3(
14149 spdy_util2.ConstructSpdyGet("https://mail.example.org", 1, LOWEST));
14150 MockWrite writes2[] = {
14151 CreateMockWrite(req3, 0),
14152 };
14153
14154 SpdySerializedFrame resp3(
14155 spdy_util2.ConstructSpdyReply(1, std::move(response_headers)));
14156 SpdySerializedFrame body3(spdy_util2.ConstructSpdyDataFrame(1, true));
14157 MockRead reads2[] = {CreateMockRead(resp3, 1), CreateMockRead(body3, 2),
14158 MockRead(ASYNC, 0, 3)};
14159
14160 MockConnect connect2(ASYNC, OK, peer_addr);
14161 SequencedSocketData data2(connect2, reads2, arraysize(reads2), writes2,
14162 arraysize(writes2));
14163 session_deps_.socket_factory->AddSocketDataProvider(&data2);
14164
14165 AddSSLSocketData();
14166
14167 // Preload mail.example.org into HostCache.
14168 HostPortPair host_port("mail.example.org", 443);
14169 HostResolver::RequestInfo resolve_info(host_port);
14170 AddressList ignored;
14171 std::unique_ptr<HostResolver::Request> request;
14172 TestCompletionCallback callback;
14173 int rv = session_deps_.host_resolver->Resolve(resolve_info, DEFAULT_PRIORITY,
14174 &ignored, callback.callback(),
14175 &request, NetLogWithSource());
14176 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
14177 rv = callback.WaitForResult();
14178 EXPECT_THAT(rv, IsOk());
14179
14180 HttpRequestInfo request1;
14181 request1.method = "GET";
14182 request1.url = GURL("https://www.example.org/");
14183 request1.load_flags = 0;
14184 HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
14185
14186 rv = trans1.Start(&request1, callback.callback(), NetLogWithSource());
14187 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
14188 rv = callback.WaitForResult();
14189 EXPECT_THAT(rv, IsOk());
14190
14191 const HttpResponseInfo* response = trans1.GetResponseInfo();
14192 ASSERT_TRUE(response);
14193 ASSERT_TRUE(response->headers);
14194 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
14195 EXPECT_TRUE(response->was_fetched_via_spdy);
14196 EXPECT_TRUE(response->was_alpn_negotiated);
14197 std::string response_data;
14198 ASSERT_THAT(ReadTransaction(&trans1, &response_data), IsOk());
14199 EXPECT_EQ("hello!", response_data);
14200
14201 HttpRequestInfo request2;
14202 request2.method = "GET";
14203 request2.url = GURL("https://mail.example.org/");
14204 request2.load_flags = 0;
14205 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
14206
14207 BoundTestNetLog log;
14208 rv = trans2.Start(&request2, callback.callback(), log.bound());
14209 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
14210 rv = callback.WaitForResult();
14211 EXPECT_THAT(rv, IsOk());
14212
14213 // After a retry, the 421 Misdirected Request is reported back up to the
14214 // caller.
14215 response = trans2.GetResponseInfo();
14216 ASSERT_TRUE(response);
14217 ASSERT_TRUE(response->headers);
14218 EXPECT_EQ("HTTP/1.1 421", response->headers->GetStatusLine());
14219 EXPECT_TRUE(response->was_fetched_via_spdy);
14220 EXPECT_TRUE(response->was_alpn_negotiated);
14221 EXPECT_TRUE(response->ssl_info.cert);
14222 ASSERT_THAT(ReadTransaction(&trans2, &response_data), IsOk());
14223 EXPECT_EQ("hello!", response_data);
bnc8016c1f2017-03-31 02:11:2914224}
14225
bnc6dcd8192017-05-25 20:11:5014226class OneTimeCachingHostResolver : public MockHostResolverBase {
[email protected]e3ceb682011-06-28 23:55:4614227 public:
14228 explicit OneTimeCachingHostResolver(const HostPortPair& host_port)
bnc6dcd8192017-05-25 20:11:5014229 : MockHostResolverBase(/* use_caching = */ true), host_port_(host_port) {}
dchengb03027d2014-10-21 12:00:2014230 ~OneTimeCachingHostResolver() override {}
[email protected]e3ceb682011-06-28 23:55:4614231
dchengb03027d2014-10-21 12:00:2014232 int ResolveFromCache(const RequestInfo& info,
14233 AddressList* addresses,
tfarina42834112016-09-22 13:38:2014234 const NetLogWithSource& net_log) override {
bnc6dcd8192017-05-25 20:11:5014235 int rv = MockHostResolverBase::ResolveFromCache(info, addresses, net_log);
[email protected]95a214c2011-08-04 21:50:4014236 if (rv == OK && info.host_port_pair().Equals(host_port_))
bnc6dcd8192017-05-25 20:11:5014237 GetHostCache()->clear();
[email protected]e3ceb682011-06-28 23:55:4614238 return rv;
14239 }
14240
[email protected]e3ceb682011-06-28 23:55:4614241 private:
[email protected]e3ceb682011-06-28 23:55:4614242 const HostPortPair host_port_;
14243};
14244
bncd16676a2016-07-20 16:23:0114245TEST_F(HttpNetworkTransactionTest,
mmenke5c642132015-06-02 16:05:1314246 UseIPConnectionPoolingWithHostCacheExpiration) {
[email protected]e3ceb682011-06-28 23:55:4614247 // Set up a special HttpNetworkSession with a OneTimeCachingHostResolver.
Jeremy Roman0579ed62017-08-29 15:56:1914248 session_deps_.host_resolver = std::make_unique<OneTimeCachingHostResolver>(
bnca4d611d2016-09-22 19:55:3714249 HostPortPair("mail.example.com", 443));
danakj1fd259a02016-04-16 03:17:0914250 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]e3ceb682011-06-28 23:55:4614251
bnc032658ba2016-09-26 18:17:1514252 AddSSLSocketData();
[email protected]e3ceb682011-06-28 23:55:4614253
bncdf80d44fd2016-07-15 20:27:4114254 SpdySerializedFrame host1_req(
bnc38dcd392016-02-09 23:19:4914255 spdy_util_.ConstructSpdyGet("https://www.example.org", 1, LOWEST));
rdsmithebb50aa2015-11-12 03:44:3814256 spdy_util_.UpdateWithStreamDestruction(1);
bncdf80d44fd2016-07-15 20:27:4114257 SpdySerializedFrame host2_req(
bnca4d611d2016-09-22 19:55:3714258 spdy_util_.ConstructSpdyGet("https://mail.example.com", 3, LOWEST));
[email protected]e3ceb682011-06-28 23:55:4614259 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:4114260 CreateMockWrite(host1_req, 0), CreateMockWrite(host2_req, 3),
[email protected]e3ceb682011-06-28 23:55:4614261 };
bnc42331402016-07-25 13:36:1514262 SpdySerializedFrame host1_resp(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
bncdf80d44fd2016-07-15 20:27:4114263 SpdySerializedFrame host1_resp_body(
14264 spdy_util_.ConstructSpdyDataFrame(1, true));
bnc42331402016-07-25 13:36:1514265 SpdySerializedFrame host2_resp(spdy_util_.ConstructSpdyGetReply(NULL, 0, 3));
bncdf80d44fd2016-07-15 20:27:4114266 SpdySerializedFrame host2_resp_body(
14267 spdy_util_.ConstructSpdyDataFrame(3, true));
[email protected]e3ceb682011-06-28 23:55:4614268 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:4114269 CreateMockRead(host1_resp, 1), CreateMockRead(host1_resp_body, 2),
14270 CreateMockRead(host2_resp, 4), CreateMockRead(host2_resp_body, 5),
rch8e6c6c42015-05-01 14:05:1314271 MockRead(ASYNC, 0, 6),
[email protected]e3ceb682011-06-28 23:55:4614272 };
14273
eroman36d84e54432016-03-17 03:23:0214274 IPEndPoint peer_addr(IPAddress::IPv4Localhost(), 443);
[email protected]d2b5f092012-06-08 23:55:0214275 MockConnect connect(ASYNC, OK, peer_addr);
rch8e6c6c42015-05-01 14:05:1314276 SequencedSocketData spdy_data(connect, spdy_reads, arraysize(spdy_reads),
14277 spdy_writes, arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:0714278 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]e3ceb682011-06-28 23:55:4614279
[email protected]aa22b242011-11-16 18:58:2914280 TestCompletionCallback callback;
[email protected]e3ceb682011-06-28 23:55:4614281 HttpRequestInfo request1;
14282 request1.method = "GET";
bncce36dca22015-04-21 22:11:2314283 request1.url = GURL("https://www.example.org/");
[email protected]e3ceb682011-06-28 23:55:4614284 request1.load_flags = 0;
[email protected]90499482013-06-01 00:39:5014285 HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
[email protected]e3ceb682011-06-28 23:55:4614286
tfarina42834112016-09-22 13:38:2014287 int rv = trans1.Start(&request1, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0114288 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
14289 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]e3ceb682011-06-28 23:55:4614290
14291 const HttpResponseInfo* response = trans1.GetResponseInfo();
wezca1070932016-05-26 20:30:5214292 ASSERT_TRUE(response);
14293 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0214294 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]e3ceb682011-06-28 23:55:4614295
14296 std::string response_data;
robpercival214763f2016-07-01 23:27:0114297 ASSERT_THAT(ReadTransaction(&trans1, &response_data), IsOk());
[email protected]e3ceb682011-06-28 23:55:4614298 EXPECT_EQ("hello!", response_data);
14299
14300 // Preload cache entries into HostCache.
bnca4d611d2016-09-22 19:55:3714301 HostResolver::RequestInfo resolve_info(HostPortPair("mail.example.com", 443));
[email protected]e3ceb682011-06-28 23:55:4614302 AddressList ignored;
maksim.sisov31452af2016-07-27 06:38:1014303 std::unique_ptr<HostResolver::Request> request;
bnc6dcd8192017-05-25 20:11:5014304 rv = session_deps_.host_resolver->Resolve(resolve_info, DEFAULT_PRIORITY,
14305 &ignored, callback.callback(),
14306 &request, NetLogWithSource());
robpercival214763f2016-07-01 23:27:0114307 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]6e78dfb2011-07-28 21:34:4714308 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0114309 EXPECT_THAT(rv, IsOk());
[email protected]e3ceb682011-06-28 23:55:4614310
14311 HttpRequestInfo request2;
14312 request2.method = "GET";
bnca4d611d2016-09-22 19:55:3714313 request2.url = GURL("https://mail.example.com/");
[email protected]e3ceb682011-06-28 23:55:4614314 request2.load_flags = 0;
[email protected]90499482013-06-01 00:39:5014315 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
[email protected]e3ceb682011-06-28 23:55:4614316
tfarina42834112016-09-22 13:38:2014317 rv = trans2.Start(&request2, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0114318 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
14319 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]e3ceb682011-06-28 23:55:4614320
14321 response = trans2.GetResponseInfo();
wezca1070932016-05-26 20:30:5214322 ASSERT_TRUE(response);
14323 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0214324 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]e3ceb682011-06-28 23:55:4614325 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5214326 EXPECT_TRUE(response->was_alpn_negotiated);
robpercival214763f2016-07-01 23:27:0114327 ASSERT_THAT(ReadTransaction(&trans2, &response_data), IsOk());
[email protected]e3ceb682011-06-28 23:55:4614328 EXPECT_EQ("hello!", response_data);
[email protected]e3ceb682011-06-28 23:55:4614329}
14330
bncd16676a2016-07-20 16:23:0114331TEST_F(HttpNetworkTransactionTest, DoNotUseSpdySessionForHttp) {
bncce36dca22015-04-21 22:11:2314332 const std::string https_url = "https://www.example.org:8080/";
14333 const std::string http_url = "http://www.example.org:8080/";
[email protected]8450d722012-07-02 19:14:0414334
14335 // SPDY GET for HTTPS URL
bncdf80d44fd2016-07-15 20:27:4114336 SpdySerializedFrame req1(
bnc38dcd392016-02-09 23:19:4914337 spdy_util_.ConstructSpdyGet(https_url.c_str(), 1, LOWEST));
[email protected]8450d722012-07-02 19:14:0414338
14339 MockWrite writes1[] = {
bncdf80d44fd2016-07-15 20:27:4114340 CreateMockWrite(req1, 0),
[email protected]8450d722012-07-02 19:14:0414341 };
14342
bnc42331402016-07-25 13:36:1514343 SpdySerializedFrame resp1(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
bncdf80d44fd2016-07-15 20:27:4114344 SpdySerializedFrame body1(spdy_util_.ConstructSpdyDataFrame(1, true));
14345 MockRead reads1[] = {CreateMockRead(resp1, 1), CreateMockRead(body1, 2),
mmenkee24011922015-12-17 22:12:5914346 MockRead(SYNCHRONOUS, ERR_IO_PENDING, 3)};
[email protected]8450d722012-07-02 19:14:0414347
rch8e6c6c42015-05-01 14:05:1314348 SequencedSocketData data1(reads1, arraysize(reads1), writes1,
14349 arraysize(writes1));
[email protected]8450d722012-07-02 19:14:0414350 MockConnect connect_data1(ASYNC, OK);
[email protected]dd54bd82012-07-19 23:44:5714351 data1.set_connect_data(connect_data1);
[email protected]8450d722012-07-02 19:14:0414352
14353 // HTTP GET for the HTTP URL
14354 MockWrite writes2[] = {
rch8e6c6c42015-05-01 14:05:1314355 MockWrite(ASYNC, 0,
lgarrona91df87f2014-12-05 00:51:3414356 "GET / HTTP/1.1\r\n"
bncce36dca22015-04-21 22:11:2314357 "Host: www.example.org:8080\r\n"
lgarrona91df87f2014-12-05 00:51:3414358 "Connection: keep-alive\r\n\r\n"),
[email protected]8450d722012-07-02 19:14:0414359 };
14360
14361 MockRead reads2[] = {
rch8e6c6c42015-05-01 14:05:1314362 MockRead(ASYNC, 1, "HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
14363 MockRead(ASYNC, 2, "hello"),
14364 MockRead(ASYNC, OK, 3),
[email protected]8450d722012-07-02 19:14:0414365 };
14366
rch8e6c6c42015-05-01 14:05:1314367 SequencedSocketData data2(reads2, arraysize(reads2), writes2,
14368 arraysize(writes2));
[email protected]8450d722012-07-02 19:14:0414369
[email protected]8450d722012-07-02 19:14:0414370 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3614371 ssl.next_proto = kProtoHTTP2;
[email protected]bb88e1d32013-05-03 23:11:0714372 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
14373 session_deps_.socket_factory->AddSocketDataProvider(&data1);
14374 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]8450d722012-07-02 19:14:0414375
danakj1fd259a02016-04-16 03:17:0914376 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]8450d722012-07-02 19:14:0414377
14378 // Start the first transaction to set up the SpdySession
14379 HttpRequestInfo request1;
14380 request1.method = "GET";
14381 request1.url = GURL(https_url);
[email protected]8450d722012-07-02 19:14:0414382 request1.load_flags = 0;
[email protected]90499482013-06-01 00:39:5014383 HttpNetworkTransaction trans1(LOWEST, session.get());
[email protected]8450d722012-07-02 19:14:0414384 TestCompletionCallback callback1;
14385 EXPECT_EQ(ERR_IO_PENDING,
tfarina42834112016-09-22 13:38:2014386 trans1.Start(&request1, callback1.callback(), NetLogWithSource()));
fdoray92e35a72016-06-10 15:54:5514387 base::RunLoop().RunUntilIdle();
[email protected]8450d722012-07-02 19:14:0414388
robpercival214763f2016-07-01 23:27:0114389 EXPECT_THAT(callback1.WaitForResult(), IsOk());
[email protected]8450d722012-07-02 19:14:0414390 EXPECT_TRUE(trans1.GetResponseInfo()->was_fetched_via_spdy);
14391
14392 // Now, start the HTTP request
14393 HttpRequestInfo request2;
14394 request2.method = "GET";
14395 request2.url = GURL(http_url);
[email protected]8450d722012-07-02 19:14:0414396 request2.load_flags = 0;
[email protected]90499482013-06-01 00:39:5014397 HttpNetworkTransaction trans2(MEDIUM, session.get());
[email protected]8450d722012-07-02 19:14:0414398 TestCompletionCallback callback2;
14399 EXPECT_EQ(ERR_IO_PENDING,
tfarina42834112016-09-22 13:38:2014400 trans2.Start(&request2, callback2.callback(), NetLogWithSource()));
fdoray92e35a72016-06-10 15:54:5514401 base::RunLoop().RunUntilIdle();
[email protected]8450d722012-07-02 19:14:0414402
robpercival214763f2016-07-01 23:27:0114403 EXPECT_THAT(callback2.WaitForResult(), IsOk());
[email protected]8450d722012-07-02 19:14:0414404 EXPECT_FALSE(trans2.GetResponseInfo()->was_fetched_via_spdy);
14405}
14406
bnc5452e2a2015-05-08 16:27:4214407// Alternative service requires HTTP/2 (or SPDY), but HTTP/1.1 is negotiated
14408// with the alternative server. That connection should not be used.
bncd16676a2016-07-20 16:23:0114409TEST_F(HttpNetworkTransactionTest, AlternativeServiceNotOnHttp11) {
bnc8bef8da22016-05-30 01:28:2514410 url::SchemeHostPort server("https", "www.example.org", 443);
14411 HostPortPair alternative("www.example.org", 444);
bnc5452e2a2015-05-08 16:27:4214412
bnc8bef8da22016-05-30 01:28:2514413 // Negotiate HTTP/1.1 with alternative.
bnc5452e2a2015-05-08 16:27:4214414 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3614415 ssl.next_proto = kProtoHTTP11;
bnc5452e2a2015-05-08 16:27:4214416 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
14417
14418 // No data should be read from the alternative, because HTTP/1.1 is
14419 // negotiated.
14420 StaticSocketDataProvider data;
14421 session_deps_.socket_factory->AddSocketDataProvider(&data);
14422
14423 // This test documents that an alternate Job should not be used if HTTP/1.1 is
zhongyi3d4a55e72016-04-22 20:36:4614424 // negotiated. In order to test this, a failed connection to the server is
bnc5452e2a2015-05-08 16:27:4214425 // mocked. This way the request relies on the alternate Job.
14426 StaticSocketDataProvider data_refused;
14427 data_refused.set_connect_data(MockConnect(ASYNC, ERR_CONNECTION_REFUSED));
14428 session_deps_.socket_factory->AddSocketDataProvider(&data_refused);
14429
zhongyi3d4a55e72016-04-22 20:36:4614430 // Set up alternative service for server.
danakj1fd259a02016-04-16 03:17:0914431 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc525e175a2016-06-20 12:36:4014432 HttpServerProperties* http_server_properties =
bnc5452e2a2015-05-08 16:27:4214433 session->http_server_properties();
bnc3472afd2016-11-17 15:27:2114434 AlternativeService alternative_service(kProtoHTTP2, alternative);
bnc7dc7e1b42015-07-28 14:43:1214435 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:2114436 http_server_properties->SetHttp2AlternativeService(
14437 server, alternative_service, expiration);
bnc5452e2a2015-05-08 16:27:4214438
bnc5452e2a2015-05-08 16:27:4214439 HttpRequestInfo request;
krasinc06a72a2016-12-21 03:42:4614440 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
bnc5452e2a2015-05-08 16:27:4214441 request.method = "GET";
bnc8bef8da22016-05-30 01:28:2514442 request.url = GURL("https://www.example.org:443");
bnc5452e2a2015-05-08 16:27:4214443 TestCompletionCallback callback;
14444
14445 // HTTP/2 (or SPDY) is required for alternative service, if HTTP/1.1 is
bnc94c92842016-09-21 15:22:5214446 // negotiated, the alternate Job should fail with ERR_ALPN_NEGOTIATION_FAILED.
tfarina42834112016-09-22 13:38:2014447 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
bnc94c92842016-09-21 15:22:5214448 EXPECT_THAT(callback.GetResult(rv), IsError(ERR_ALPN_NEGOTIATION_FAILED));
bnc5452e2a2015-05-08 16:27:4214449}
14450
bnc40448a532015-05-11 19:13:1414451// A request to a server with an alternative service fires two Jobs: one to the
zhongyi3d4a55e72016-04-22 20:36:4614452// server, and an alternate one to the alternative server. If the former
bnc40448a532015-05-11 19:13:1414453// succeeds, the request should succeed, even if the latter fails because
14454// HTTP/1.1 is negotiated which is insufficient for alternative service.
bncd16676a2016-07-20 16:23:0114455TEST_F(HttpNetworkTransactionTest, FailedAlternativeServiceIsNotUserVisible) {
bnc8bef8da22016-05-30 01:28:2514456 url::SchemeHostPort server("https", "www.example.org", 443);
14457 HostPortPair alternative("www.example.org", 444);
bnc40448a532015-05-11 19:13:1414458
14459 // Negotiate HTTP/1.1 with alternative.
14460 SSLSocketDataProvider alternative_ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3614461 alternative_ssl.next_proto = kProtoHTTP11;
bnc40448a532015-05-11 19:13:1414462 session_deps_.socket_factory->AddSSLSocketDataProvider(&alternative_ssl);
14463
14464 // No data should be read from the alternative, because HTTP/1.1 is
14465 // negotiated.
14466 StaticSocketDataProvider data;
14467 session_deps_.socket_factory->AddSocketDataProvider(&data);
14468
zhongyi3d4a55e72016-04-22 20:36:4614469 // Negotiate HTTP/1.1 with server.
bnc40448a532015-05-11 19:13:1414470 SSLSocketDataProvider origin_ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3614471 origin_ssl.next_proto = kProtoHTTP11;
bnc40448a532015-05-11 19:13:1414472 session_deps_.socket_factory->AddSSLSocketDataProvider(&origin_ssl);
14473
14474 MockWrite http_writes[] = {
bnc8bef8da22016-05-30 01:28:2514475 MockWrite("GET / HTTP/1.1\r\n"
14476 "Host: www.example.org\r\n"
14477 "Connection: keep-alive\r\n\r\n"),
14478 MockWrite("GET /second HTTP/1.1\r\n"
14479 "Host: www.example.org\r\n"
14480 "Connection: keep-alive\r\n\r\n"),
bnc40448a532015-05-11 19:13:1414481 };
14482
14483 MockRead http_reads[] = {
14484 MockRead("HTTP/1.1 200 OK\r\n"),
14485 MockRead("Content-Type: text/html\r\n"),
14486 MockRead("Content-Length: 6\r\n\r\n"),
14487 MockRead("foobar"),
14488 MockRead("HTTP/1.1 200 OK\r\n"),
14489 MockRead("Content-Type: text/html\r\n"),
14490 MockRead("Content-Length: 7\r\n\r\n"),
14491 MockRead("another"),
14492 };
14493 StaticSocketDataProvider http_data(http_reads, arraysize(http_reads),
14494 http_writes, arraysize(http_writes));
14495 session_deps_.socket_factory->AddSocketDataProvider(&http_data);
14496
zhongyi3d4a55e72016-04-22 20:36:4614497 // Set up alternative service for server.
danakj1fd259a02016-04-16 03:17:0914498 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc525e175a2016-06-20 12:36:4014499 HttpServerProperties* http_server_properties =
bnc40448a532015-05-11 19:13:1414500 session->http_server_properties();
bnc3472afd2016-11-17 15:27:2114501 AlternativeService alternative_service(kProtoHTTP2, alternative);
bnc7dc7e1b42015-07-28 14:43:1214502 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:2114503 http_server_properties->SetHttp2AlternativeService(
14504 server, alternative_service, expiration);
bnc40448a532015-05-11 19:13:1414505
14506 HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
14507 HttpRequestInfo request1;
14508 request1.method = "GET";
bnc8bef8da22016-05-30 01:28:2514509 request1.url = GURL("https://www.example.org:443");
bnc40448a532015-05-11 19:13:1414510 request1.load_flags = 0;
14511 TestCompletionCallback callback1;
14512
tfarina42834112016-09-22 13:38:2014513 int rv = trans1.Start(&request1, callback1.callback(), NetLogWithSource());
bnc40448a532015-05-11 19:13:1414514 rv = callback1.GetResult(rv);
robpercival214763f2016-07-01 23:27:0114515 EXPECT_THAT(rv, IsOk());
bnc40448a532015-05-11 19:13:1414516
14517 const HttpResponseInfo* response1 = trans1.GetResponseInfo();
wezca1070932016-05-26 20:30:5214518 ASSERT_TRUE(response1);
14519 ASSERT_TRUE(response1->headers);
bnc40448a532015-05-11 19:13:1414520 EXPECT_EQ("HTTP/1.1 200 OK", response1->headers->GetStatusLine());
14521
14522 std::string response_data1;
robpercival214763f2016-07-01 23:27:0114523 ASSERT_THAT(ReadTransaction(&trans1, &response_data1), IsOk());
bnc40448a532015-05-11 19:13:1414524 EXPECT_EQ("foobar", response_data1);
14525
14526 // Alternative should be marked as broken, because HTTP/1.1 is not sufficient
14527 // for alternative service.
14528 EXPECT_TRUE(
14529 http_server_properties->IsAlternativeServiceBroken(alternative_service));
14530
zhongyi3d4a55e72016-04-22 20:36:4614531 // Since |alternative_service| is broken, a second transaction to server
bnc40448a532015-05-11 19:13:1414532 // should not start an alternate Job. It should pool to existing connection
zhongyi3d4a55e72016-04-22 20:36:4614533 // to server.
bnc40448a532015-05-11 19:13:1414534 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
14535 HttpRequestInfo request2;
14536 request2.method = "GET";
bnc8bef8da22016-05-30 01:28:2514537 request2.url = GURL("https://www.example.org:443/second");
bnc40448a532015-05-11 19:13:1414538 request2.load_flags = 0;
14539 TestCompletionCallback callback2;
14540
tfarina42834112016-09-22 13:38:2014541 rv = trans2.Start(&request2, callback2.callback(), NetLogWithSource());
bnc40448a532015-05-11 19:13:1414542 rv = callback2.GetResult(rv);
robpercival214763f2016-07-01 23:27:0114543 EXPECT_THAT(rv, IsOk());
bnc40448a532015-05-11 19:13:1414544
14545 const HttpResponseInfo* response2 = trans2.GetResponseInfo();
wezca1070932016-05-26 20:30:5214546 ASSERT_TRUE(response2);
14547 ASSERT_TRUE(response2->headers);
bnc40448a532015-05-11 19:13:1414548 EXPECT_EQ("HTTP/1.1 200 OK", response2->headers->GetStatusLine());
14549
14550 std::string response_data2;
robpercival214763f2016-07-01 23:27:0114551 ASSERT_THAT(ReadTransaction(&trans2, &response_data2), IsOk());
bnc40448a532015-05-11 19:13:1414552 EXPECT_EQ("another", response_data2);
14553}
14554
bnc5452e2a2015-05-08 16:27:4214555// Alternative service requires HTTP/2 (or SPDY), but there is already a
14556// HTTP/1.1 socket open to the alternative server. That socket should not be
14557// used.
bncd16676a2016-07-20 16:23:0114558TEST_F(HttpNetworkTransactionTest, AlternativeServiceShouldNotPoolToHttp11) {
zhongyi3d4a55e72016-04-22 20:36:4614559 url::SchemeHostPort server("https", "origin.example.org", 443);
bnc5452e2a2015-05-08 16:27:4214560 HostPortPair alternative("alternative.example.org", 443);
14561 std::string origin_url = "https://origin.example.org:443";
14562 std::string alternative_url = "https://alternative.example.org:443";
14563
14564 // Negotiate HTTP/1.1 with alternative.example.org.
14565 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3614566 ssl.next_proto = kProtoHTTP11;
bnc5452e2a2015-05-08 16:27:4214567 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
14568
14569 // HTTP/1.1 data for |request1| and |request2|.
14570 MockWrite http_writes[] = {
14571 MockWrite(
14572 "GET / HTTP/1.1\r\n"
14573 "Host: alternative.example.org\r\n"
14574 "Connection: keep-alive\r\n\r\n"),
14575 MockWrite(
14576 "GET / HTTP/1.1\r\n"
14577 "Host: alternative.example.org\r\n"
14578 "Connection: keep-alive\r\n\r\n"),
14579 };
14580
14581 MockRead http_reads[] = {
14582 MockRead(
14583 "HTTP/1.1 200 OK\r\n"
14584 "Content-Type: text/html; charset=iso-8859-1\r\n"
14585 "Content-Length: 40\r\n\r\n"
14586 "first HTTP/1.1 response from alternative"),
14587 MockRead(
14588 "HTTP/1.1 200 OK\r\n"
14589 "Content-Type: text/html; charset=iso-8859-1\r\n"
14590 "Content-Length: 41\r\n\r\n"
14591 "second HTTP/1.1 response from alternative"),
14592 };
14593 StaticSocketDataProvider http_data(http_reads, arraysize(http_reads),
14594 http_writes, arraysize(http_writes));
14595 session_deps_.socket_factory->AddSocketDataProvider(&http_data);
14596
14597 // This test documents that an alternate Job should not pool to an already
14598 // existing HTTP/1.1 connection. In order to test this, a failed connection
zhongyi3d4a55e72016-04-22 20:36:4614599 // to the server is mocked. This way |request2| relies on the alternate Job.
bnc5452e2a2015-05-08 16:27:4214600 StaticSocketDataProvider data_refused;
14601 data_refused.set_connect_data(MockConnect(ASYNC, ERR_CONNECTION_REFUSED));
14602 session_deps_.socket_factory->AddSocketDataProvider(&data_refused);
14603
zhongyi3d4a55e72016-04-22 20:36:4614604 // Set up alternative service for server.
danakj1fd259a02016-04-16 03:17:0914605 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc525e175a2016-06-20 12:36:4014606 HttpServerProperties* http_server_properties =
bnc5452e2a2015-05-08 16:27:4214607 session->http_server_properties();
bnc3472afd2016-11-17 15:27:2114608 AlternativeService alternative_service(kProtoHTTP2, alternative);
bnc7dc7e1b42015-07-28 14:43:1214609 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:2114610 http_server_properties->SetHttp2AlternativeService(
14611 server, alternative_service, expiration);
bnc5452e2a2015-05-08 16:27:4214612
14613 // First transaction to alternative to open an HTTP/1.1 socket.
bnc5452e2a2015-05-08 16:27:4214614 HttpRequestInfo request1;
krasinc06a72a2016-12-21 03:42:4614615 HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
bnc5452e2a2015-05-08 16:27:4214616 request1.method = "GET";
14617 request1.url = GURL(alternative_url);
14618 request1.load_flags = 0;
14619 TestCompletionCallback callback1;
14620
tfarina42834112016-09-22 13:38:2014621 int rv = trans1.Start(&request1, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0114622 EXPECT_THAT(callback1.GetResult(rv), IsOk());
bnc691fda62016-08-12 00:43:1614623 const HttpResponseInfo* response1 = trans1.GetResponseInfo();
bnc5452e2a2015-05-08 16:27:4214624 ASSERT_TRUE(response1);
wezca1070932016-05-26 20:30:5214625 ASSERT_TRUE(response1->headers);
bnc5452e2a2015-05-08 16:27:4214626 EXPECT_EQ("HTTP/1.1 200 OK", response1->headers->GetStatusLine());
bnc94c92842016-09-21 15:22:5214627 EXPECT_TRUE(response1->was_alpn_negotiated);
bnc5452e2a2015-05-08 16:27:4214628 EXPECT_FALSE(response1->was_fetched_via_spdy);
14629 std::string response_data1;
bnc691fda62016-08-12 00:43:1614630 ASSERT_THAT(ReadTransaction(&trans1, &response_data1), IsOk());
bnc5452e2a2015-05-08 16:27:4214631 EXPECT_EQ("first HTTP/1.1 response from alternative", response_data1);
14632
14633 // Request for origin.example.org, which has an alternative service. This
14634 // will start two Jobs: the alternative looks for connections to pool to,
14635 // finds one which is HTTP/1.1, and should ignore it, and should not try to
zhongyi3d4a55e72016-04-22 20:36:4614636 // open other connections to alternative server. The Job to server fails, so
bnc5452e2a2015-05-08 16:27:4214637 // this request fails.
bnc5452e2a2015-05-08 16:27:4214638 HttpRequestInfo request2;
krasinc06a72a2016-12-21 03:42:4614639 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
bnc5452e2a2015-05-08 16:27:4214640 request2.method = "GET";
14641 request2.url = GURL(origin_url);
14642 request2.load_flags = 0;
14643 TestCompletionCallback callback2;
14644
tfarina42834112016-09-22 13:38:2014645 rv = trans2.Start(&request2, callback2.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0114646 EXPECT_THAT(callback2.GetResult(rv), IsError(ERR_CONNECTION_REFUSED));
bnc5452e2a2015-05-08 16:27:4214647
14648 // Another transaction to alternative. This is to test that the HTTP/1.1
14649 // socket is still open and in the pool.
bnc5452e2a2015-05-08 16:27:4214650 HttpRequestInfo request3;
krasinc06a72a2016-12-21 03:42:4614651 HttpNetworkTransaction trans3(DEFAULT_PRIORITY, session.get());
bnc5452e2a2015-05-08 16:27:4214652 request3.method = "GET";
14653 request3.url = GURL(alternative_url);
14654 request3.load_flags = 0;
14655 TestCompletionCallback callback3;
14656
tfarina42834112016-09-22 13:38:2014657 rv = trans3.Start(&request3, callback3.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0114658 EXPECT_THAT(callback3.GetResult(rv), IsOk());
bnc691fda62016-08-12 00:43:1614659 const HttpResponseInfo* response3 = trans3.GetResponseInfo();
bnc5452e2a2015-05-08 16:27:4214660 ASSERT_TRUE(response3);
wezca1070932016-05-26 20:30:5214661 ASSERT_TRUE(response3->headers);
bnc5452e2a2015-05-08 16:27:4214662 EXPECT_EQ("HTTP/1.1 200 OK", response3->headers->GetStatusLine());
bnc94c92842016-09-21 15:22:5214663 EXPECT_TRUE(response3->was_alpn_negotiated);
bnc5452e2a2015-05-08 16:27:4214664 EXPECT_FALSE(response3->was_fetched_via_spdy);
14665 std::string response_data3;
bnc691fda62016-08-12 00:43:1614666 ASSERT_THAT(ReadTransaction(&trans3, &response_data3), IsOk());
bnc5452e2a2015-05-08 16:27:4214667 EXPECT_EQ("second HTTP/1.1 response from alternative", response_data3);
14668}
14669
bncd16676a2016-07-20 16:23:0114670TEST_F(HttpNetworkTransactionTest, DoNotUseSpdySessionForHttpOverTunnel) {
bncce36dca22015-04-21 22:11:2314671 const std::string https_url = "https://www.example.org:8080/";
14672 const std::string http_url = "http://www.example.org:8080/";
[email protected]8450d722012-07-02 19:14:0414673
rdsmithebb50aa2015-11-12 03:44:3814674 // Separate SPDY util instance for naked and wrapped requests.
bncd16676a2016-07-20 16:23:0114675 SpdyTestUtil spdy_util_wrapped;
rdsmithebb50aa2015-11-12 03:44:3814676
[email protected]8450d722012-07-02 19:14:0414677 // SPDY GET for HTTPS URL (through CONNECT tunnel)
bncce36dca22015-04-21 22:11:2314678 const HostPortPair host_port_pair("www.example.org", 8080);
bncdf80d44fd2016-07-15 20:27:4114679 SpdySerializedFrame connect(
lgarrona91df87f2014-12-05 00:51:3414680 spdy_util_.ConstructSpdyConnect(NULL, 0, 1, LOWEST, host_port_pair));
bncdf80d44fd2016-07-15 20:27:4114681 SpdySerializedFrame req1(
bnc38dcd392016-02-09 23:19:4914682 spdy_util_wrapped.ConstructSpdyGet(https_url.c_str(), 1, LOWEST));
bncdf80d44fd2016-07-15 20:27:4114683 SpdySerializedFrame wrapped_req1(
[email protected]23e482282013-06-14 16:08:0214684 spdy_util_.ConstructWrappedSpdyFrame(req1, 1));
[email protected]601e03f12014-04-06 16:26:3914685
14686 // SPDY GET for HTTP URL (through the proxy, but not the tunnel).
[email protected]745aa9c2014-06-27 02:21:2914687 SpdyHeaderBlock req2_block;
Bence Békybda82952017-10-02 17:35:2714688 req2_block[kHttp2MethodHeader] = "GET";
14689 req2_block[kHttp2AuthorityHeader] = "www.example.org:8080";
14690 req2_block[kHttp2SchemeHeader] = "http";
14691 req2_block[kHttp2PathHeader] = "/";
bncdf80d44fd2016-07-15 20:27:4114692 SpdySerializedFrame req2(
bnc42331402016-07-25 13:36:1514693 spdy_util_.ConstructSpdyHeaders(3, std::move(req2_block), MEDIUM, true));
[email protected]8450d722012-07-02 19:14:0414694
14695 MockWrite writes1[] = {
bncdf80d44fd2016-07-15 20:27:4114696 CreateMockWrite(connect, 0), CreateMockWrite(wrapped_req1, 2),
14697 CreateMockWrite(req2, 6),
[email protected]8450d722012-07-02 19:14:0414698 };
14699
bncdf80d44fd2016-07-15 20:27:4114700 SpdySerializedFrame conn_resp(
bnc42331402016-07-25 13:36:1514701 spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
bncdf80d44fd2016-07-15 20:27:4114702 SpdySerializedFrame resp1(
bnc42331402016-07-25 13:36:1514703 spdy_util_wrapped.ConstructSpdyGetReply(nullptr, 0, 1));
bncdf80d44fd2016-07-15 20:27:4114704 SpdySerializedFrame body1(spdy_util_wrapped.ConstructSpdyDataFrame(1, true));
14705 SpdySerializedFrame wrapped_resp1(
rdsmithebb50aa2015-11-12 03:44:3814706 spdy_util_wrapped.ConstructWrappedSpdyFrame(resp1, 1));
bncdf80d44fd2016-07-15 20:27:4114707 SpdySerializedFrame wrapped_body1(
rdsmithebb50aa2015-11-12 03:44:3814708 spdy_util_wrapped.ConstructWrappedSpdyFrame(body1, 1));
bnc42331402016-07-25 13:36:1514709 SpdySerializedFrame resp2(spdy_util_.ConstructSpdyGetReply(NULL, 0, 3));
bncdf80d44fd2016-07-15 20:27:4114710 SpdySerializedFrame body2(spdy_util_.ConstructSpdyDataFrame(3, true));
mmenke666a6fea2015-12-19 04:16:3314711 MockRead reads1[] = {
bncdf80d44fd2016-07-15 20:27:4114712 CreateMockRead(conn_resp, 1),
mmenke666a6fea2015-12-19 04:16:3314713 MockRead(ASYNC, ERR_IO_PENDING, 3),
bncdf80d44fd2016-07-15 20:27:4114714 CreateMockRead(wrapped_resp1, 4),
14715 CreateMockRead(wrapped_body1, 5),
mmenke666a6fea2015-12-19 04:16:3314716 MockRead(ASYNC, ERR_IO_PENDING, 7),
bncdf80d44fd2016-07-15 20:27:4114717 CreateMockRead(resp2, 8),
14718 CreateMockRead(body2, 9),
mmenke666a6fea2015-12-19 04:16:3314719 MockRead(SYNCHRONOUS, ERR_IO_PENDING, 10),
14720 };
[email protected]8450d722012-07-02 19:14:0414721
mmenke666a6fea2015-12-19 04:16:3314722 SequencedSocketData data1(reads1, arraysize(reads1), writes1,
14723 arraysize(writes1));
[email protected]8450d722012-07-02 19:14:0414724 MockConnect connect_data1(ASYNC, OK);
[email protected]dd54bd82012-07-19 23:44:5714725 data1.set_connect_data(connect_data1);
[email protected]8450d722012-07-02 19:14:0414726
rdsmith82957ad2015-09-16 19:42:0314727 session_deps_.proxy_service =
14728 ProxyService::CreateFixedFromPacResult("HTTPS proxy:70");
vishal.b62985ca92015-04-17 08:45:5114729 TestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:0714730 session_deps_.net_log = &log;
[email protected]8450d722012-07-02 19:14:0414731 SSLSocketDataProvider ssl1(ASYNC, OK); // to the proxy
bnc3cf2a592016-08-11 14:48:3614732 ssl1.next_proto = kProtoHTTP2;
mmenke666a6fea2015-12-19 04:16:3314733 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl1);
[email protected]8450d722012-07-02 19:14:0414734 SSLSocketDataProvider ssl2(ASYNC, OK); // to the server
bnc3cf2a592016-08-11 14:48:3614735 ssl2.next_proto = kProtoHTTP2;
mmenke666a6fea2015-12-19 04:16:3314736 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
14737 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8450d722012-07-02 19:14:0414738
danakj1fd259a02016-04-16 03:17:0914739 std::unique_ptr<HttpNetworkSession> session = CreateSession(&session_deps_);
[email protected]8450d722012-07-02 19:14:0414740
14741 // Start the first transaction to set up the SpdySession
14742 HttpRequestInfo request1;
14743 request1.method = "GET";
14744 request1.url = GURL(https_url);
[email protected]8450d722012-07-02 19:14:0414745 request1.load_flags = 0;
[email protected]90499482013-06-01 00:39:5014746 HttpNetworkTransaction trans1(LOWEST, session.get());
[email protected]8450d722012-07-02 19:14:0414747 TestCompletionCallback callback1;
tfarina42834112016-09-22 13:38:2014748 int rv = trans1.Start(&request1, callback1.callback(), NetLogWithSource());
[email protected]8450d722012-07-02 19:14:0414749
mmenke666a6fea2015-12-19 04:16:3314750 // This pause is a hack to avoid running into https://crbug.com/497228.
14751 data1.RunUntilPaused();
14752 base::RunLoop().RunUntilIdle();
14753 data1.Resume();
robpercival214763f2016-07-01 23:27:0114754 EXPECT_THAT(callback1.GetResult(rv), IsOk());
[email protected]8450d722012-07-02 19:14:0414755 EXPECT_TRUE(trans1.GetResponseInfo()->was_fetched_via_spdy);
14756
[email protected]f6c63db52013-02-02 00:35:2214757 LoadTimingInfo load_timing_info1;
14758 EXPECT_TRUE(trans1.GetLoadTimingInfo(&load_timing_info1));
14759 TestLoadTimingNotReusedWithPac(load_timing_info1,
14760 CONNECT_TIMING_HAS_SSL_TIMES);
14761
mmenke666a6fea2015-12-19 04:16:3314762 // Now, start the HTTP request.
[email protected]8450d722012-07-02 19:14:0414763 HttpRequestInfo request2;
14764 request2.method = "GET";
14765 request2.url = GURL(http_url);
[email protected]8450d722012-07-02 19:14:0414766 request2.load_flags = 0;
[email protected]90499482013-06-01 00:39:5014767 HttpNetworkTransaction trans2(MEDIUM, session.get());
[email protected]8450d722012-07-02 19:14:0414768 TestCompletionCallback callback2;
tfarina42834112016-09-22 13:38:2014769 rv = trans2.Start(&request2, callback2.callback(), NetLogWithSource());
[email protected]8450d722012-07-02 19:14:0414770
mmenke666a6fea2015-12-19 04:16:3314771 // This pause is a hack to avoid running into https://crbug.com/497228.
14772 data1.RunUntilPaused();
14773 base::RunLoop().RunUntilIdle();
14774 data1.Resume();
robpercival214763f2016-07-01 23:27:0114775 EXPECT_THAT(callback2.GetResult(rv), IsOk());
mmenke666a6fea2015-12-19 04:16:3314776
[email protected]8450d722012-07-02 19:14:0414777 EXPECT_TRUE(trans2.GetResponseInfo()->was_fetched_via_spdy);
[email protected]f6c63db52013-02-02 00:35:2214778
14779 LoadTimingInfo load_timing_info2;
14780 EXPECT_TRUE(trans2.GetLoadTimingInfo(&load_timing_info2));
14781 // The established SPDY sessions is considered reused by the HTTP request.
14782 TestLoadTimingReusedWithPac(load_timing_info2);
14783 // HTTP requests over a SPDY session should have a different connection
14784 // socket_log_id than requests over a tunnel.
14785 EXPECT_NE(load_timing_info1.socket_log_id, load_timing_info2.socket_log_id);
[email protected]8450d722012-07-02 19:14:0414786}
14787
[email protected]2d88e7d2012-07-19 17:55:1714788// Test that in the case where we have a SPDY session to a SPDY proxy
14789// that we do not pool other origins that resolve to the same IP when
14790// the certificate does not match the new origin.
14791// http://crbug.com/134690
bncd16676a2016-07-20 16:23:0114792TEST_F(HttpNetworkTransactionTest, DoNotUseSpdySessionIfCertDoesNotMatch) {
bncce36dca22015-04-21 22:11:2314793 const std::string url1 = "http://www.example.org/";
14794 const std::string url2 = "https://news.example.org/";
[email protected]2d88e7d2012-07-19 17:55:1714795 const std::string ip_addr = "1.2.3.4";
14796
rdsmithebb50aa2015-11-12 03:44:3814797 // Second SpdyTestUtil instance for the second socket.
bncd16676a2016-07-20 16:23:0114798 SpdyTestUtil spdy_util_secure;
rdsmithebb50aa2015-11-12 03:44:3814799
[email protected]2d88e7d2012-07-19 17:55:1714800 // SPDY GET for HTTP URL (through SPDY proxy)
bnc086b39e12016-06-24 13:05:2614801 SpdyHeaderBlock headers(
bncce36dca22015-04-21 22:11:2314802 spdy_util_.ConstructGetHeaderBlockForProxy("http://www.example.org/"));
bncdf80d44fd2016-07-15 20:27:4114803 SpdySerializedFrame req1(
bnc42331402016-07-25 13:36:1514804 spdy_util_.ConstructSpdyHeaders(1, std::move(headers), LOWEST, true));
[email protected]2d88e7d2012-07-19 17:55:1714805
14806 MockWrite writes1[] = {
bncdf80d44fd2016-07-15 20:27:4114807 CreateMockWrite(req1, 0),
[email protected]2d88e7d2012-07-19 17:55:1714808 };
14809
bnc42331402016-07-25 13:36:1514810 SpdySerializedFrame resp1(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
bncdf80d44fd2016-07-15 20:27:4114811 SpdySerializedFrame body1(spdy_util_.ConstructSpdyDataFrame(1, true));
[email protected]2d88e7d2012-07-19 17:55:1714812 MockRead reads1[] = {
bncdf80d44fd2016-07-15 20:27:4114813 MockRead(ASYNC, ERR_IO_PENDING, 1), CreateMockRead(resp1, 2),
14814 CreateMockRead(body1, 3), MockRead(ASYNC, OK, 4), // EOF
[email protected]2d88e7d2012-07-19 17:55:1714815 };
14816
mmenke666a6fea2015-12-19 04:16:3314817 SequencedSocketData data1(reads1, arraysize(reads1), writes1,
14818 arraysize(writes1));
martijnfe9636e2016-02-06 14:33:3214819 IPAddress ip;
martijn654c8c42016-02-10 22:10:5914820 ASSERT_TRUE(ip.AssignFromIPLiteral(ip_addr));
[email protected]2d88e7d2012-07-19 17:55:1714821 IPEndPoint peer_addr = IPEndPoint(ip, 443);
14822 MockConnect connect_data1(ASYNC, OK, peer_addr);
mmenke666a6fea2015-12-19 04:16:3314823 data1.set_connect_data(connect_data1);
[email protected]2d88e7d2012-07-19 17:55:1714824
14825 // SPDY GET for HTTPS URL (direct)
bncdf80d44fd2016-07-15 20:27:4114826 SpdySerializedFrame req2(
bnc38dcd392016-02-09 23:19:4914827 spdy_util_secure.ConstructSpdyGet(url2.c_str(), 1, MEDIUM));
[email protected]2d88e7d2012-07-19 17:55:1714828
14829 MockWrite writes2[] = {
bncdf80d44fd2016-07-15 20:27:4114830 CreateMockWrite(req2, 0),
[email protected]2d88e7d2012-07-19 17:55:1714831 };
14832
bnc42331402016-07-25 13:36:1514833 SpdySerializedFrame resp2(spdy_util_secure.ConstructSpdyGetReply(NULL, 0, 1));
bncdf80d44fd2016-07-15 20:27:4114834 SpdySerializedFrame body2(spdy_util_secure.ConstructSpdyDataFrame(1, true));
14835 MockRead reads2[] = {CreateMockRead(resp2, 1), CreateMockRead(body2, 2),
mmenke666a6fea2015-12-19 04:16:3314836 MockRead(ASYNC, OK, 3)};
[email protected]2d88e7d2012-07-19 17:55:1714837
mmenke666a6fea2015-12-19 04:16:3314838 SequencedSocketData data2(reads2, arraysize(reads2), writes2,
14839 arraysize(writes2));
[email protected]2d88e7d2012-07-19 17:55:1714840 MockConnect connect_data2(ASYNC, OK);
mmenke666a6fea2015-12-19 04:16:3314841 data2.set_connect_data(connect_data2);
[email protected]2d88e7d2012-07-19 17:55:1714842
14843 // Set up a proxy config that sends HTTP requests to a proxy, and
14844 // all others direct.
14845 ProxyConfig proxy_config;
14846 proxy_config.proxy_rules().ParseFromString("http=https://proxy:443");
Jeremy Roman0579ed62017-08-29 15:56:1914847 session_deps_.proxy_service = std::make_unique<ProxyService>(
14848 std::make_unique<ProxyConfigServiceFixed>(proxy_config), nullptr,
bnc87dcefc2017-05-25 12:47:5814849 nullptr);
[email protected]2d88e7d2012-07-19 17:55:1714850
bncce36dca22015-04-21 22:11:2314851 SSLSocketDataProvider ssl1(ASYNC, OK); // to the proxy
bnc3cf2a592016-08-11 14:48:3614852 ssl1.next_proto = kProtoHTTP2;
[email protected]2d88e7d2012-07-19 17:55:1714853 // Load a valid cert. Note, that this does not need to
14854 // be valid for proxy because the MockSSLClientSocket does
14855 // not actually verify it. But SpdySession will use this
14856 // to see if it is valid for the new origin
bncce36dca22015-04-21 22:11:2314857 ssl1.cert = ImportCertFromFile(GetTestCertsDirectory(), "ok_cert.pem");
wezca1070932016-05-26 20:30:5214858 ASSERT_TRUE(ssl1.cert);
mmenke666a6fea2015-12-19 04:16:3314859 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl1);
14860 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]2d88e7d2012-07-19 17:55:1714861
14862 SSLSocketDataProvider ssl2(ASYNC, OK); // to the server
bnc3cf2a592016-08-11 14:48:3614863 ssl2.next_proto = kProtoHTTP2;
mmenke666a6fea2015-12-19 04:16:3314864 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
14865 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]2d88e7d2012-07-19 17:55:1714866
Jeremy Roman0579ed62017-08-29 15:56:1914867 session_deps_.host_resolver = std::make_unique<MockCachingHostResolver>();
bncce36dca22015-04-21 22:11:2314868 session_deps_.host_resolver->rules()->AddRule("news.example.org", ip_addr);
[email protected]bb88e1d32013-05-03 23:11:0714869 session_deps_.host_resolver->rules()->AddRule("proxy", ip_addr);
[email protected]2d88e7d2012-07-19 17:55:1714870
danakj1fd259a02016-04-16 03:17:0914871 std::unique_ptr<HttpNetworkSession> session = CreateSession(&session_deps_);
[email protected]2d88e7d2012-07-19 17:55:1714872
14873 // Start the first transaction to set up the SpdySession
14874 HttpRequestInfo request1;
14875 request1.method = "GET";
14876 request1.url = GURL(url1);
[email protected]2d88e7d2012-07-19 17:55:1714877 request1.load_flags = 0;
[email protected]90499482013-06-01 00:39:5014878 HttpNetworkTransaction trans1(LOWEST, session.get());
[email protected]2d88e7d2012-07-19 17:55:1714879 TestCompletionCallback callback1;
14880 ASSERT_EQ(ERR_IO_PENDING,
tfarina42834112016-09-22 13:38:2014881 trans1.Start(&request1, callback1.callback(), NetLogWithSource()));
mmenke666a6fea2015-12-19 04:16:3314882 // This pause is a hack to avoid running into https://crbug.com/497228.
14883 data1.RunUntilPaused();
14884 base::RunLoop().RunUntilIdle();
14885 data1.Resume();
[email protected]2d88e7d2012-07-19 17:55:1714886
robpercival214763f2016-07-01 23:27:0114887 EXPECT_THAT(callback1.WaitForResult(), IsOk());
[email protected]2d88e7d2012-07-19 17:55:1714888 EXPECT_TRUE(trans1.GetResponseInfo()->was_fetched_via_spdy);
14889
14890 // Now, start the HTTP request
14891 HttpRequestInfo request2;
14892 request2.method = "GET";
14893 request2.url = GURL(url2);
[email protected]2d88e7d2012-07-19 17:55:1714894 request2.load_flags = 0;
[email protected]90499482013-06-01 00:39:5014895 HttpNetworkTransaction trans2(MEDIUM, session.get());
[email protected]2d88e7d2012-07-19 17:55:1714896 TestCompletionCallback callback2;
14897 EXPECT_EQ(ERR_IO_PENDING,
tfarina42834112016-09-22 13:38:2014898 trans2.Start(&request2, callback2.callback(), NetLogWithSource()));
fdoray92e35a72016-06-10 15:54:5514899 base::RunLoop().RunUntilIdle();
[email protected]2d88e7d2012-07-19 17:55:1714900
14901 ASSERT_TRUE(callback2.have_result());
robpercival214763f2016-07-01 23:27:0114902 EXPECT_THAT(callback2.WaitForResult(), IsOk());
[email protected]2d88e7d2012-07-19 17:55:1714903 EXPECT_TRUE(trans2.GetResponseInfo()->was_fetched_via_spdy);
14904}
14905
[email protected]85f97342013-04-17 06:12:2414906// Test to verify that a failed socket read (due to an ERR_CONNECTION_CLOSED
14907// error) in SPDY session, removes the socket from pool and closes the SPDY
14908// session. Verify that new url's from the same HttpNetworkSession (and a new
14909// SpdySession) do work. http://crbug.com/224701
bncd16676a2016-07-20 16:23:0114910TEST_F(HttpNetworkTransactionTest, ErrorSocketNotConnected) {
bncce36dca22015-04-21 22:11:2314911 const std::string https_url = "https://www.example.org/";
[email protected]85f97342013-04-17 06:12:2414912
14913 MockRead reads1[] = {
14914 MockRead(SYNCHRONOUS, ERR_CONNECTION_CLOSED, 0)
14915 };
14916
mmenke11eb5152015-06-09 14:50:5014917 SequencedSocketData data1(reads1, arraysize(reads1), NULL, 0);
[email protected]85f97342013-04-17 06:12:2414918
bncdf80d44fd2016-07-15 20:27:4114919 SpdySerializedFrame req2(
bnc38dcd392016-02-09 23:19:4914920 spdy_util_.ConstructSpdyGet(https_url.c_str(), 1, MEDIUM));
[email protected]85f97342013-04-17 06:12:2414921 MockWrite writes2[] = {
bncdf80d44fd2016-07-15 20:27:4114922 CreateMockWrite(req2, 0),
[email protected]85f97342013-04-17 06:12:2414923 };
14924
bnc42331402016-07-25 13:36:1514925 SpdySerializedFrame resp2(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
bncdf80d44fd2016-07-15 20:27:4114926 SpdySerializedFrame body2(spdy_util_.ConstructSpdyDataFrame(1, true));
[email protected]85f97342013-04-17 06:12:2414927 MockRead reads2[] = {
bncdf80d44fd2016-07-15 20:27:4114928 CreateMockRead(resp2, 1), CreateMockRead(body2, 2),
14929 MockRead(ASYNC, OK, 3) // EOF
[email protected]85f97342013-04-17 06:12:2414930 };
14931
mmenke11eb5152015-06-09 14:50:5014932 SequencedSocketData data2(reads2, arraysize(reads2), writes2,
14933 arraysize(writes2));
[email protected]85f97342013-04-17 06:12:2414934
[email protected]85f97342013-04-17 06:12:2414935 SSLSocketDataProvider ssl1(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3614936 ssl1.next_proto = kProtoHTTP2;
mmenke11eb5152015-06-09 14:50:5014937 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl1);
14938 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]85f97342013-04-17 06:12:2414939
14940 SSLSocketDataProvider ssl2(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3614941 ssl2.next_proto = kProtoHTTP2;
mmenke11eb5152015-06-09 14:50:5014942 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
14943 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]85f97342013-04-17 06:12:2414944
danakj1fd259a02016-04-16 03:17:0914945 std::unique_ptr<HttpNetworkSession> session(
mmenke11eb5152015-06-09 14:50:5014946 SpdySessionDependencies::SpdyCreateSession(&session_deps_));
[email protected]85f97342013-04-17 06:12:2414947
14948 // Start the first transaction to set up the SpdySession and verify that
14949 // connection was closed.
14950 HttpRequestInfo request1;
14951 request1.method = "GET";
14952 request1.url = GURL(https_url);
14953 request1.load_flags = 0;
[email protected]90499482013-06-01 00:39:5014954 HttpNetworkTransaction trans1(MEDIUM, session.get());
[email protected]85f97342013-04-17 06:12:2414955 TestCompletionCallback callback1;
14956 EXPECT_EQ(ERR_IO_PENDING,
tfarina42834112016-09-22 13:38:2014957 trans1.Start(&request1, callback1.callback(), NetLogWithSource()));
robpercival214763f2016-07-01 23:27:0114958 EXPECT_THAT(callback1.WaitForResult(), IsError(ERR_CONNECTION_CLOSED));
[email protected]85f97342013-04-17 06:12:2414959
14960 // Now, start the second request and make sure it succeeds.
14961 HttpRequestInfo request2;
14962 request2.method = "GET";
14963 request2.url = GURL(https_url);
14964 request2.load_flags = 0;
[email protected]90499482013-06-01 00:39:5014965 HttpNetworkTransaction trans2(MEDIUM, session.get());
[email protected]85f97342013-04-17 06:12:2414966 TestCompletionCallback callback2;
14967 EXPECT_EQ(ERR_IO_PENDING,
tfarina42834112016-09-22 13:38:2014968 trans2.Start(&request2, callback2.callback(), NetLogWithSource()));
[email protected]85f97342013-04-17 06:12:2414969
robpercival214763f2016-07-01 23:27:0114970 ASSERT_THAT(callback2.WaitForResult(), IsOk());
[email protected]85f97342013-04-17 06:12:2414971 EXPECT_TRUE(trans2.GetResponseInfo()->was_fetched_via_spdy);
14972}
14973
bncd16676a2016-07-20 16:23:0114974TEST_F(HttpNetworkTransactionTest, CloseIdleSpdySessionToOpenNewOne) {
[email protected]483fa202013-05-14 01:07:0314975 ClientSocketPoolManager::set_max_sockets_per_group(
14976 HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
14977 ClientSocketPoolManager::set_max_sockets_per_pool(
14978 HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
14979
14980 // Use two different hosts with different IPs so they don't get pooled.
14981 session_deps_.host_resolver->rules()->AddRule("www.a.com", "10.0.0.1");
14982 session_deps_.host_resolver->rules()->AddRule("www.b.com", "10.0.0.2");
danakj1fd259a02016-04-16 03:17:0914983 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]483fa202013-05-14 01:07:0314984
14985 SSLSocketDataProvider ssl1(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3614986 ssl1.next_proto = kProtoHTTP2;
[email protected]483fa202013-05-14 01:07:0314987 SSLSocketDataProvider ssl2(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3614988 ssl2.next_proto = kProtoHTTP2;
[email protected]483fa202013-05-14 01:07:0314989 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl1);
14990 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
14991
bncdf80d44fd2016-07-15 20:27:4114992 SpdySerializedFrame host1_req(
bnc38dcd392016-02-09 23:19:4914993 spdy_util_.ConstructSpdyGet("https://www.a.com", 1, DEFAULT_PRIORITY));
[email protected]483fa202013-05-14 01:07:0314994 MockWrite spdy1_writes[] = {
bncdf80d44fd2016-07-15 20:27:4114995 CreateMockWrite(host1_req, 0),
[email protected]483fa202013-05-14 01:07:0314996 };
bnc42331402016-07-25 13:36:1514997 SpdySerializedFrame host1_resp(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
bncdf80d44fd2016-07-15 20:27:4114998 SpdySerializedFrame host1_resp_body(
14999 spdy_util_.ConstructSpdyDataFrame(1, true));
[email protected]483fa202013-05-14 01:07:0315000 MockRead spdy1_reads[] = {
bncdf80d44fd2016-07-15 20:27:4115001 CreateMockRead(host1_resp, 1), CreateMockRead(host1_resp_body, 2),
mmenkee24011922015-12-17 22:12:5915002 MockRead(SYNCHRONOUS, ERR_IO_PENDING, 3),
[email protected]483fa202013-05-14 01:07:0315003 };
15004
rdsmithebb50aa2015-11-12 03:44:3815005 // Use a separate test instance for the separate SpdySession that will be
15006 // created.
bncd16676a2016-07-20 16:23:0115007 SpdyTestUtil spdy_util_2;
Jeremy Roman0579ed62017-08-29 15:56:1915008 auto spdy1_data = std::make_unique<SequencedSocketData>(
bnc87dcefc2017-05-25 12:47:5815009 spdy1_reads, arraysize(spdy1_reads), spdy1_writes,
15010 arraysize(spdy1_writes));
[email protected]483fa202013-05-14 01:07:0315011 session_deps_.socket_factory->AddSocketDataProvider(spdy1_data.get());
15012
bncdf80d44fd2016-07-15 20:27:4115013 SpdySerializedFrame host2_req(
bnc38dcd392016-02-09 23:19:4915014 spdy_util_2.ConstructSpdyGet("https://www.b.com", 1, DEFAULT_PRIORITY));
[email protected]483fa202013-05-14 01:07:0315015 MockWrite spdy2_writes[] = {
bncdf80d44fd2016-07-15 20:27:4115016 CreateMockWrite(host2_req, 0),
[email protected]483fa202013-05-14 01:07:0315017 };
bnc42331402016-07-25 13:36:1515018 SpdySerializedFrame host2_resp(spdy_util_2.ConstructSpdyGetReply(NULL, 0, 1));
bncdf80d44fd2016-07-15 20:27:4115019 SpdySerializedFrame host2_resp_body(
15020 spdy_util_2.ConstructSpdyDataFrame(1, true));
[email protected]483fa202013-05-14 01:07:0315021 MockRead spdy2_reads[] = {
bncdf80d44fd2016-07-15 20:27:4115022 CreateMockRead(host2_resp, 1), CreateMockRead(host2_resp_body, 2),
mmenkee24011922015-12-17 22:12:5915023 MockRead(SYNCHRONOUS, ERR_IO_PENDING, 3),
[email protected]483fa202013-05-14 01:07:0315024 };
15025
Jeremy Roman0579ed62017-08-29 15:56:1915026 auto spdy2_data = std::make_unique<SequencedSocketData>(
bnc87dcefc2017-05-25 12:47:5815027 spdy2_reads, arraysize(spdy2_reads), spdy2_writes,
15028 arraysize(spdy2_writes));
[email protected]483fa202013-05-14 01:07:0315029 session_deps_.socket_factory->AddSocketDataProvider(spdy2_data.get());
15030
15031 MockWrite http_write[] = {
15032 MockWrite("GET / HTTP/1.1\r\n"
15033 "Host: www.a.com\r\n"
15034 "Connection: keep-alive\r\n\r\n"),
15035 };
15036
15037 MockRead http_read[] = {
15038 MockRead("HTTP/1.1 200 OK\r\n"),
15039 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
15040 MockRead("Content-Length: 6\r\n\r\n"),
15041 MockRead("hello!"),
15042 };
15043 StaticSocketDataProvider http_data(http_read, arraysize(http_read),
15044 http_write, arraysize(http_write));
15045 session_deps_.socket_factory->AddSocketDataProvider(&http_data);
15046
15047 HostPortPair host_port_pair_a("www.a.com", 443);
[email protected]e6d017652013-05-17 18:01:4015048 SpdySessionKey spdy_session_key_a(
[email protected]314b03992014-04-01 01:28:5315049 host_port_pair_a, ProxyServer::Direct(), PRIVACY_MODE_DISABLED);
[email protected]483fa202013-05-14 01:07:0315050 EXPECT_FALSE(
[email protected]41d64e82013-07-03 22:44:2615051 HasSpdySession(session->spdy_session_pool(), spdy_session_key_a));
[email protected]483fa202013-05-14 01:07:0315052
15053 TestCompletionCallback callback;
15054 HttpRequestInfo request1;
15055 request1.method = "GET";
15056 request1.url = GURL("https://www.a.com/");
15057 request1.load_flags = 0;
bnc87dcefc2017-05-25 12:47:5815058 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:1915059 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]483fa202013-05-14 01:07:0315060
tfarina42834112016-09-22 13:38:2015061 int rv = trans->Start(&request1, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0115062 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
15063 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]483fa202013-05-14 01:07:0315064
15065 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5215066 ASSERT_TRUE(response);
15067 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0215068 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]483fa202013-05-14 01:07:0315069 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5215070 EXPECT_TRUE(response->was_alpn_negotiated);
[email protected]483fa202013-05-14 01:07:0315071
15072 std::string response_data;
robpercival214763f2016-07-01 23:27:0115073 ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
[email protected]483fa202013-05-14 01:07:0315074 EXPECT_EQ("hello!", response_data);
15075 trans.reset();
15076 EXPECT_TRUE(
[email protected]41d64e82013-07-03 22:44:2615077 HasSpdySession(session->spdy_session_pool(), spdy_session_key_a));
[email protected]483fa202013-05-14 01:07:0315078
15079 HostPortPair host_port_pair_b("www.b.com", 443);
[email protected]e6d017652013-05-17 18:01:4015080 SpdySessionKey spdy_session_key_b(
[email protected]314b03992014-04-01 01:28:5315081 host_port_pair_b, ProxyServer::Direct(), PRIVACY_MODE_DISABLED);
[email protected]483fa202013-05-14 01:07:0315082 EXPECT_FALSE(
[email protected]41d64e82013-07-03 22:44:2615083 HasSpdySession(session->spdy_session_pool(), spdy_session_key_b));
[email protected]483fa202013-05-14 01:07:0315084 HttpRequestInfo request2;
15085 request2.method = "GET";
15086 request2.url = GURL("https://www.b.com/");
15087 request2.load_flags = 0;
bnc87dcefc2017-05-25 12:47:5815088 trans =
Jeremy Roman0579ed62017-08-29 15:56:1915089 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]483fa202013-05-14 01:07:0315090
tfarina42834112016-09-22 13:38:2015091 rv = trans->Start(&request2, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0115092 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
15093 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]483fa202013-05-14 01:07:0315094
15095 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5215096 ASSERT_TRUE(response);
15097 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0215098 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]483fa202013-05-14 01:07:0315099 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5215100 EXPECT_TRUE(response->was_alpn_negotiated);
robpercival214763f2016-07-01 23:27:0115101 ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
[email protected]483fa202013-05-14 01:07:0315102 EXPECT_EQ("hello!", response_data);
15103 EXPECT_FALSE(
[email protected]41d64e82013-07-03 22:44:2615104 HasSpdySession(session->spdy_session_pool(), spdy_session_key_a));
[email protected]483fa202013-05-14 01:07:0315105 EXPECT_TRUE(
[email protected]41d64e82013-07-03 22:44:2615106 HasSpdySession(session->spdy_session_pool(), spdy_session_key_b));
[email protected]483fa202013-05-14 01:07:0315107
15108 HostPortPair host_port_pair_a1("www.a.com", 80);
[email protected]e6d017652013-05-17 18:01:4015109 SpdySessionKey spdy_session_key_a1(
[email protected]314b03992014-04-01 01:28:5315110 host_port_pair_a1, ProxyServer::Direct(), PRIVACY_MODE_DISABLED);
[email protected]483fa202013-05-14 01:07:0315111 EXPECT_FALSE(
[email protected]41d64e82013-07-03 22:44:2615112 HasSpdySession(session->spdy_session_pool(), spdy_session_key_a1));
[email protected]483fa202013-05-14 01:07:0315113 HttpRequestInfo request3;
15114 request3.method = "GET";
15115 request3.url = GURL("http://www.a.com/");
15116 request3.load_flags = 0;
bnc87dcefc2017-05-25 12:47:5815117 trans =
Jeremy Roman0579ed62017-08-29 15:56:1915118 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]483fa202013-05-14 01:07:0315119
tfarina42834112016-09-22 13:38:2015120 rv = trans->Start(&request3, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0115121 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
15122 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]483fa202013-05-14 01:07:0315123
15124 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5215125 ASSERT_TRUE(response);
15126 ASSERT_TRUE(response->headers);
[email protected]483fa202013-05-14 01:07:0315127 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
15128 EXPECT_FALSE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5215129 EXPECT_FALSE(response->was_alpn_negotiated);
robpercival214763f2016-07-01 23:27:0115130 ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
[email protected]483fa202013-05-14 01:07:0315131 EXPECT_EQ("hello!", response_data);
15132 EXPECT_FALSE(
[email protected]41d64e82013-07-03 22:44:2615133 HasSpdySession(session->spdy_session_pool(), spdy_session_key_a));
[email protected]483fa202013-05-14 01:07:0315134 EXPECT_FALSE(
[email protected]41d64e82013-07-03 22:44:2615135 HasSpdySession(session->spdy_session_pool(), spdy_session_key_b));
[email protected]483fa202013-05-14 01:07:0315136}
15137
bncd16676a2016-07-20 16:23:0115138TEST_F(HttpNetworkTransactionTest, HttpSyncConnectError) {
[email protected]79e1fd62013-06-20 06:50:0415139 HttpRequestInfo request;
15140 request.method = "GET";
bncce36dca22015-04-21 22:11:2315141 request.url = GURL("http://www.example.org/");
[email protected]79e1fd62013-06-20 06:50:0415142
danakj1fd259a02016-04-16 03:17:0915143 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1615144 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]79e1fd62013-06-20 06:50:0415145
ttuttled9dbc652015-09-29 20:00:5915146 MockConnect mock_connect(SYNCHRONOUS, ERR_NAME_NOT_RESOLVED);
[email protected]79e1fd62013-06-20 06:50:0415147 StaticSocketDataProvider data;
15148 data.set_connect_data(mock_connect);
15149 session_deps_.socket_factory->AddSocketDataProvider(&data);
15150
15151 TestCompletionCallback callback;
15152
tfarina42834112016-09-22 13:38:2015153 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0115154 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]79e1fd62013-06-20 06:50:0415155
15156 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0115157 EXPECT_THAT(rv, IsError(ERR_NAME_NOT_RESOLVED));
[email protected]79e1fd62013-06-20 06:50:0415158
[email protected]79e1fd62013-06-20 06:50:0415159 // We don't care whether this succeeds or fails, but it shouldn't crash.
15160 HttpRequestHeaders request_headers;
bnc691fda62016-08-12 00:43:1615161 trans.GetFullRequestHeaders(&request_headers);
ttuttle1f2d7e92015-04-28 16:17:4715162
15163 ConnectionAttempts attempts;
bnc691fda62016-08-12 00:43:1615164 trans.GetConnectionAttempts(&attempts);
ttuttle1f2d7e92015-04-28 16:17:4715165 ASSERT_EQ(1u, attempts.size());
robpercival214763f2016-07-01 23:27:0115166 EXPECT_THAT(attempts[0].result, IsError(ERR_NAME_NOT_RESOLVED));
ttuttled9dbc652015-09-29 20:00:5915167
15168 IPEndPoint endpoint;
bnc691fda62016-08-12 00:43:1615169 EXPECT_FALSE(trans.GetRemoteEndpoint(&endpoint));
ttuttled9dbc652015-09-29 20:00:5915170 EXPECT_TRUE(endpoint.address().empty());
[email protected]79e1fd62013-06-20 06:50:0415171}
15172
bncd16676a2016-07-20 16:23:0115173TEST_F(HttpNetworkTransactionTest, HttpAsyncConnectError) {
[email protected]79e1fd62013-06-20 06:50:0415174 HttpRequestInfo request;
15175 request.method = "GET";
bncce36dca22015-04-21 22:11:2315176 request.url = GURL("http://www.example.org/");
[email protected]79e1fd62013-06-20 06:50:0415177
danakj1fd259a02016-04-16 03:17:0915178 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1615179 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]79e1fd62013-06-20 06:50:0415180
ttuttled9dbc652015-09-29 20:00:5915181 MockConnect mock_connect(ASYNC, ERR_NAME_NOT_RESOLVED);
[email protected]79e1fd62013-06-20 06:50:0415182 StaticSocketDataProvider data;
15183 data.set_connect_data(mock_connect);
15184 session_deps_.socket_factory->AddSocketDataProvider(&data);
15185
15186 TestCompletionCallback callback;
15187
tfarina42834112016-09-22 13:38:2015188 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0115189 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]79e1fd62013-06-20 06:50:0415190
15191 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0115192 EXPECT_THAT(rv, IsError(ERR_NAME_NOT_RESOLVED));
[email protected]79e1fd62013-06-20 06:50:0415193
[email protected]79e1fd62013-06-20 06:50:0415194 // We don't care whether this succeeds or fails, but it shouldn't crash.
15195 HttpRequestHeaders request_headers;
bnc691fda62016-08-12 00:43:1615196 trans.GetFullRequestHeaders(&request_headers);
ttuttle1f2d7e92015-04-28 16:17:4715197
15198 ConnectionAttempts attempts;
bnc691fda62016-08-12 00:43:1615199 trans.GetConnectionAttempts(&attempts);
ttuttle1f2d7e92015-04-28 16:17:4715200 ASSERT_EQ(1u, attempts.size());
robpercival214763f2016-07-01 23:27:0115201 EXPECT_THAT(attempts[0].result, IsError(ERR_NAME_NOT_RESOLVED));
ttuttled9dbc652015-09-29 20:00:5915202
15203 IPEndPoint endpoint;
bnc691fda62016-08-12 00:43:1615204 EXPECT_FALSE(trans.GetRemoteEndpoint(&endpoint));
ttuttled9dbc652015-09-29 20:00:5915205 EXPECT_TRUE(endpoint.address().empty());
[email protected]79e1fd62013-06-20 06:50:0415206}
15207
bncd16676a2016-07-20 16:23:0115208TEST_F(HttpNetworkTransactionTest, HttpSyncWriteError) {
[email protected]79e1fd62013-06-20 06:50:0415209 HttpRequestInfo request;
15210 request.method = "GET";
bncce36dca22015-04-21 22:11:2315211 request.url = GURL("http://www.example.org/");
[email protected]79e1fd62013-06-20 06:50:0415212
danakj1fd259a02016-04-16 03:17:0915213 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1615214 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]79e1fd62013-06-20 06:50:0415215
15216 MockWrite data_writes[] = {
15217 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
15218 };
15219 MockRead data_reads[] = {
15220 MockRead(SYNCHRONOUS, ERR_UNEXPECTED), // Should not be reached.
15221 };
15222
15223 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
15224 data_writes, arraysize(data_writes));
15225 session_deps_.socket_factory->AddSocketDataProvider(&data);
15226
15227 TestCompletionCallback callback;
15228
tfarina42834112016-09-22 13:38:2015229 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0115230 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]79e1fd62013-06-20 06:50:0415231
15232 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0115233 EXPECT_THAT(rv, IsError(ERR_CONNECTION_RESET));
[email protected]79e1fd62013-06-20 06:50:0415234
[email protected]79e1fd62013-06-20 06:50:0415235 HttpRequestHeaders request_headers;
bnc691fda62016-08-12 00:43:1615236 EXPECT_TRUE(trans.GetFullRequestHeaders(&request_headers));
[email protected]79e1fd62013-06-20 06:50:0415237 EXPECT_TRUE(request_headers.HasHeader("Host"));
15238}
15239
bncd16676a2016-07-20 16:23:0115240TEST_F(HttpNetworkTransactionTest, HttpAsyncWriteError) {
[email protected]79e1fd62013-06-20 06:50:0415241 HttpRequestInfo request;
15242 request.method = "GET";
bncce36dca22015-04-21 22:11:2315243 request.url = GURL("http://www.example.org/");
[email protected]79e1fd62013-06-20 06:50:0415244
danakj1fd259a02016-04-16 03:17:0915245 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1615246 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]79e1fd62013-06-20 06:50:0415247
15248 MockWrite data_writes[] = {
15249 MockWrite(ASYNC, ERR_CONNECTION_RESET),
15250 };
15251 MockRead data_reads[] = {
15252 MockRead(SYNCHRONOUS, ERR_UNEXPECTED), // Should not be reached.
15253 };
15254
15255 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
15256 data_writes, arraysize(data_writes));
15257 session_deps_.socket_factory->AddSocketDataProvider(&data);
15258
15259 TestCompletionCallback callback;
15260
tfarina42834112016-09-22 13:38:2015261 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0115262 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]79e1fd62013-06-20 06:50:0415263
15264 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0115265 EXPECT_THAT(rv, IsError(ERR_CONNECTION_RESET));
[email protected]79e1fd62013-06-20 06:50:0415266
[email protected]79e1fd62013-06-20 06:50:0415267 HttpRequestHeaders request_headers;
bnc691fda62016-08-12 00:43:1615268 EXPECT_TRUE(trans.GetFullRequestHeaders(&request_headers));
[email protected]79e1fd62013-06-20 06:50:0415269 EXPECT_TRUE(request_headers.HasHeader("Host"));
15270}
15271
bncd16676a2016-07-20 16:23:0115272TEST_F(HttpNetworkTransactionTest, HttpSyncReadError) {
[email protected]79e1fd62013-06-20 06:50:0415273 HttpRequestInfo request;
15274 request.method = "GET";
bncce36dca22015-04-21 22:11:2315275 request.url = GURL("http://www.example.org/");
[email protected]79e1fd62013-06-20 06:50:0415276
danakj1fd259a02016-04-16 03:17:0915277 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1615278 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]79e1fd62013-06-20 06:50:0415279
15280 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:2315281 MockWrite(
15282 "GET / HTTP/1.1\r\n"
15283 "Host: www.example.org\r\n"
15284 "Connection: keep-alive\r\n\r\n"),
[email protected]79e1fd62013-06-20 06:50:0415285 };
15286 MockRead data_reads[] = {
15287 MockRead(SYNCHRONOUS, ERR_CONNECTION_RESET),
15288 };
15289
15290 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
15291 data_writes, arraysize(data_writes));
15292 session_deps_.socket_factory->AddSocketDataProvider(&data);
15293
15294 TestCompletionCallback callback;
15295
tfarina42834112016-09-22 13:38:2015296 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0115297 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]79e1fd62013-06-20 06:50:0415298
15299 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0115300 EXPECT_THAT(rv, IsError(ERR_CONNECTION_RESET));
[email protected]79e1fd62013-06-20 06:50:0415301
[email protected]79e1fd62013-06-20 06:50:0415302 HttpRequestHeaders request_headers;
bnc691fda62016-08-12 00:43:1615303 EXPECT_TRUE(trans.GetFullRequestHeaders(&request_headers));
[email protected]79e1fd62013-06-20 06:50:0415304 EXPECT_TRUE(request_headers.HasHeader("Host"));
15305}
15306
bncd16676a2016-07-20 16:23:0115307TEST_F(HttpNetworkTransactionTest, HttpAsyncReadError) {
[email protected]79e1fd62013-06-20 06:50:0415308 HttpRequestInfo request;
15309 request.method = "GET";
bncce36dca22015-04-21 22:11:2315310 request.url = GURL("http://www.example.org/");
[email protected]79e1fd62013-06-20 06:50:0415311
danakj1fd259a02016-04-16 03:17:0915312 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1615313 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]79e1fd62013-06-20 06:50:0415314
15315 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:2315316 MockWrite(
15317 "GET / HTTP/1.1\r\n"
15318 "Host: www.example.org\r\n"
15319 "Connection: keep-alive\r\n\r\n"),
[email protected]79e1fd62013-06-20 06:50:0415320 };
15321 MockRead data_reads[] = {
15322 MockRead(ASYNC, ERR_CONNECTION_RESET),
15323 };
15324
15325 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
15326 data_writes, arraysize(data_writes));
15327 session_deps_.socket_factory->AddSocketDataProvider(&data);
15328
15329 TestCompletionCallback callback;
15330
tfarina42834112016-09-22 13:38:2015331 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0115332 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]79e1fd62013-06-20 06:50:0415333
15334 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0115335 EXPECT_THAT(rv, IsError(ERR_CONNECTION_RESET));
[email protected]79e1fd62013-06-20 06:50:0415336
[email protected]79e1fd62013-06-20 06:50:0415337 HttpRequestHeaders request_headers;
bnc691fda62016-08-12 00:43:1615338 EXPECT_TRUE(trans.GetFullRequestHeaders(&request_headers));
[email protected]79e1fd62013-06-20 06:50:0415339 EXPECT_TRUE(request_headers.HasHeader("Host"));
15340}
15341
bncd16676a2016-07-20 16:23:0115342TEST_F(HttpNetworkTransactionTest, GetFullRequestHeadersIncludesExtraHeader) {
[email protected]79e1fd62013-06-20 06:50:0415343 HttpRequestInfo request;
15344 request.method = "GET";
bncce36dca22015-04-21 22:11:2315345 request.url = GURL("http://www.example.org/");
[email protected]79e1fd62013-06-20 06:50:0415346 request.extra_headers.SetHeader("X-Foo", "bar");
15347
danakj1fd259a02016-04-16 03:17:0915348 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1615349 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]79e1fd62013-06-20 06:50:0415350
15351 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:2315352 MockWrite(
15353 "GET / HTTP/1.1\r\n"
15354 "Host: www.example.org\r\n"
15355 "Connection: keep-alive\r\n"
15356 "X-Foo: bar\r\n\r\n"),
[email protected]79e1fd62013-06-20 06:50:0415357 };
15358 MockRead data_reads[] = {
15359 MockRead("HTTP/1.1 200 OK\r\n"
15360 "Content-Length: 5\r\n\r\n"
15361 "hello"),
15362 MockRead(ASYNC, ERR_UNEXPECTED),
15363 };
15364
15365 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
15366 data_writes, arraysize(data_writes));
15367 session_deps_.socket_factory->AddSocketDataProvider(&data);
15368
15369 TestCompletionCallback callback;
15370
tfarina42834112016-09-22 13:38:2015371 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0115372 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]79e1fd62013-06-20 06:50:0415373
15374 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0115375 EXPECT_THAT(rv, IsOk());
[email protected]79e1fd62013-06-20 06:50:0415376
15377 HttpRequestHeaders request_headers;
bnc691fda62016-08-12 00:43:1615378 EXPECT_TRUE(trans.GetFullRequestHeaders(&request_headers));
[email protected]79e1fd62013-06-20 06:50:0415379 std::string foo;
15380 EXPECT_TRUE(request_headers.GetHeader("X-Foo", &foo));
15381 EXPECT_EQ("bar", foo);
15382}
15383
[email protected]bf828982013-08-14 18:01:4715384namespace {
15385
yhiranoa7e05bb2014-11-06 05:40:3915386// Fake HttpStream that simply records calls to SetPriority().
15387class FakeStream : public HttpStream,
[email protected]e86839fd2013-08-14 18:29:0315388 public base::SupportsWeakPtr<FakeStream> {
15389 public:
15390 explicit FakeStream(RequestPriority priority) : priority_(priority) {}
dchengb03027d2014-10-21 12:00:2015391 ~FakeStream() override {}
[email protected]e86839fd2013-08-14 18:29:0315392
15393 RequestPriority priority() const { return priority_; }
15394
dchengb03027d2014-10-21 12:00:2015395 int InitializeStream(const HttpRequestInfo* request_info,
15396 RequestPriority priority,
tfarina42834112016-09-22 13:38:2015397 const NetLogWithSource& net_log,
dchengb03027d2014-10-21 12:00:2015398 const CompletionCallback& callback) override {
[email protected]e86839fd2013-08-14 18:29:0315399 return ERR_IO_PENDING;
15400 }
15401
dchengb03027d2014-10-21 12:00:2015402 int SendRequest(const HttpRequestHeaders& request_headers,
15403 HttpResponseInfo* response,
15404 const CompletionCallback& callback) override {
[email protected]e86839fd2013-08-14 18:29:0315405 ADD_FAILURE();
15406 return ERR_UNEXPECTED;
15407 }
15408
dchengb03027d2014-10-21 12:00:2015409 int ReadResponseHeaders(const CompletionCallback& callback) override {
[email protected]e86839fd2013-08-14 18:29:0315410 ADD_FAILURE();
15411 return ERR_UNEXPECTED;
15412 }
15413
dchengb03027d2014-10-21 12:00:2015414 int ReadResponseBody(IOBuffer* buf,
15415 int buf_len,
15416 const CompletionCallback& callback) override {
[email protected]e86839fd2013-08-14 18:29:0315417 ADD_FAILURE();
15418 return ERR_UNEXPECTED;
15419 }
15420
dchengb03027d2014-10-21 12:00:2015421 void Close(bool not_reusable) override {}
[email protected]e86839fd2013-08-14 18:29:0315422
dchengb03027d2014-10-21 12:00:2015423 bool IsResponseBodyComplete() const override {
[email protected]e86839fd2013-08-14 18:29:0315424 ADD_FAILURE();
15425 return false;
15426 }
15427
dchengb03027d2014-10-21 12:00:2015428 bool IsConnectionReused() const override {
[email protected]e86839fd2013-08-14 18:29:0315429 ADD_FAILURE();
15430 return false;
15431 }
15432
dchengb03027d2014-10-21 12:00:2015433 void SetConnectionReused() override { ADD_FAILURE(); }
[email protected]e86839fd2013-08-14 18:29:0315434
mmenkebd84c392015-09-02 14:12:3415435 bool CanReuseConnection() const override { return false; }
[email protected]e86839fd2013-08-14 18:29:0315436
sclittle4de1bab92015-09-22 21:28:2415437 int64_t GetTotalReceivedBytes() const override {
[email protected]bc92bc972013-12-13 08:32:5915438 ADD_FAILURE();
15439 return 0;
15440 }
15441
sclittlebe1ccf62015-09-02 19:40:3615442 int64_t GetTotalSentBytes() const override {
15443 ADD_FAILURE();
15444 return 0;
15445 }
15446
dchengb03027d2014-10-21 12:00:2015447 bool GetLoadTimingInfo(LoadTimingInfo* load_timing_info) const override {
[email protected]e86839fd2013-08-14 18:29:0315448 ADD_FAILURE();
15449 return false;
15450 }
15451
rchcd379012017-04-12 21:53:3215452 bool GetAlternativeService(
15453 AlternativeService* alternative_service) const override {
15454 ADD_FAILURE();
15455 return false;
15456 }
15457
dchengb03027d2014-10-21 12:00:2015458 void GetSSLInfo(SSLInfo* ssl_info) override { ADD_FAILURE(); }
15459
15460 void GetSSLCertRequestInfo(SSLCertRequestInfo* cert_request_info) override {
[email protected]e86839fd2013-08-14 18:29:0315461 ADD_FAILURE();
15462 }
15463
ttuttled9dbc652015-09-29 20:00:5915464 bool GetRemoteEndpoint(IPEndPoint* endpoint) override { return false; }
15465
nharper78e6d2b2016-09-21 05:42:3515466 Error GetTokenBindingSignature(crypto::ECPrivateKey* key,
15467 TokenBindingType tb_type,
15468 std::vector<uint8_t>* out) override {
nharperb7441ef2016-01-25 23:54:1415469 ADD_FAILURE();
15470 return ERR_NOT_IMPLEMENTED;
15471 }
15472
dchengb03027d2014-10-21 12:00:2015473 void Drain(HttpNetworkSession* session) override { ADD_FAILURE(); }
[email protected]e86839fd2013-08-14 18:29:0315474
zhongyica364fbb2015-12-12 03:39:1215475 void PopulateNetErrorDetails(NetErrorDetails* details) override { return; }
15476
dchengb03027d2014-10-21 12:00:2015477 void SetPriority(RequestPriority priority) override { priority_ = priority; }
[email protected]e86839fd2013-08-14 18:29:0315478
yhiranoa7e05bb2014-11-06 05:40:3915479 HttpStream* RenewStreamForAuth() override { return NULL; }
15480
Andrey Kosyakov83a6eee2017-08-14 19:20:0415481 void SetRequestHeadersCallback(RequestHeadersCallback callback) override {}
15482
[email protected]e86839fd2013-08-14 18:29:0315483 private:
15484 RequestPriority priority_;
15485
15486 DISALLOW_COPY_AND_ASSIGN(FakeStream);
15487};
15488
15489// Fake HttpStreamRequest that simply records calls to SetPriority()
15490// and vends FakeStreams with its current priority.
[email protected]bf828982013-08-14 18:01:4715491class FakeStreamRequest : public HttpStreamRequest,
15492 public base::SupportsWeakPtr<FakeStreamRequest> {
15493 public:
[email protected]e86839fd2013-08-14 18:29:0315494 FakeStreamRequest(RequestPriority priority,
15495 HttpStreamRequest::Delegate* delegate)
15496 : priority_(priority),
[email protected]831e4a32013-11-14 02:14:4415497 delegate_(delegate),
15498 websocket_stream_create_helper_(NULL) {}
15499
15500 FakeStreamRequest(RequestPriority priority,
15501 HttpStreamRequest::Delegate* delegate,
15502 WebSocketHandshakeStreamBase::CreateHelper* create_helper)
15503 : priority_(priority),
15504 delegate_(delegate),
15505 websocket_stream_create_helper_(create_helper) {}
[email protected]e86839fd2013-08-14 18:29:0315506
dchengb03027d2014-10-21 12:00:2015507 ~FakeStreamRequest() override {}
[email protected]bf828982013-08-14 18:01:4715508
15509 RequestPriority priority() const { return priority_; }
15510
[email protected]831e4a32013-11-14 02:14:4415511 const WebSocketHandshakeStreamBase::CreateHelper*
15512 websocket_stream_create_helper() const {
15513 return websocket_stream_create_helper_;
15514 }
15515
[email protected]e86839fd2013-08-14 18:29:0315516 // Create a new FakeStream and pass it to the request's
15517 // delegate. Returns a weak pointer to the FakeStream.
15518 base::WeakPtr<FakeStream> FinishStreamRequest() {
Jeremy Roman0579ed62017-08-29 15:56:1915519 auto fake_stream = std::make_unique<FakeStream>(priority_);
[email protected]e86839fd2013-08-14 18:29:0315520 // Do this before calling OnStreamReady() as OnStreamReady() may
15521 // immediately delete |fake_stream|.
15522 base::WeakPtr<FakeStream> weak_stream = fake_stream->AsWeakPtr();
bnc5029f4632017-06-08 16:19:0015523 delegate_->OnStreamReady(SSLConfig(), ProxyInfo(), std::move(fake_stream));
[email protected]e86839fd2013-08-14 18:29:0315524 return weak_stream;
15525 }
15526
asanka681f02d2017-02-22 17:06:3915527 int RestartTunnelWithProxyAuth() override {
[email protected]bf828982013-08-14 18:01:4715528 ADD_FAILURE();
15529 return ERR_UNEXPECTED;
15530 }
15531
dchengb03027d2014-10-21 12:00:2015532 LoadState GetLoadState() const override {
[email protected]bf828982013-08-14 18:01:4715533 ADD_FAILURE();
15534 return LoadState();
15535 }
15536
dchengb03027d2014-10-21 12:00:2015537 void SetPriority(RequestPriority priority) override { priority_ = priority; }
[email protected]bf828982013-08-14 18:01:4715538
bnc94c92842016-09-21 15:22:5215539 bool was_alpn_negotiated() const override { return false; }
[email protected]bf828982013-08-14 18:01:4715540
bnc6227b26e2016-08-12 02:00:4315541 NextProto negotiated_protocol() const override { return kProtoUnknown; }
[email protected]bf828982013-08-14 18:01:4715542
dchengb03027d2014-10-21 12:00:2015543 bool using_spdy() const override { return false; }
[email protected]bf828982013-08-14 18:01:4715544
ttuttle1f2d7e92015-04-28 16:17:4715545 const ConnectionAttempts& connection_attempts() const override {
15546 static ConnectionAttempts no_attempts;
15547 return no_attempts;
15548 }
15549
[email protected]bf828982013-08-14 18:01:4715550 private:
15551 RequestPriority priority_;
[email protected]e86839fd2013-08-14 18:29:0315552 HttpStreamRequest::Delegate* const delegate_;
[email protected]831e4a32013-11-14 02:14:4415553 WebSocketHandshakeStreamBase::CreateHelper* websocket_stream_create_helper_;
[email protected]bf828982013-08-14 18:01:4715554
15555 DISALLOW_COPY_AND_ASSIGN(FakeStreamRequest);
15556};
15557
15558// Fake HttpStreamFactory that vends FakeStreamRequests.
15559class FakeStreamFactory : public HttpStreamFactory {
15560 public:
15561 FakeStreamFactory() {}
dchengb03027d2014-10-21 12:00:2015562 ~FakeStreamFactory() override {}
[email protected]bf828982013-08-14 18:01:4715563
15564 // Returns a WeakPtr<> to the last HttpStreamRequest returned by
15565 // RequestStream() (which may be NULL if it was destroyed already).
15566 base::WeakPtr<FakeStreamRequest> last_stream_request() {
15567 return last_stream_request_;
15568 }
15569
xunjieli96f2a402017-06-05 17:24:2715570 std::unique_ptr<HttpStreamRequest> RequestStream(
15571 const HttpRequestInfo& info,
15572 RequestPriority priority,
15573 const SSLConfig& server_ssl_config,
15574 const SSLConfig& proxy_ssl_config,
15575 HttpStreamRequest::Delegate* delegate,
15576 bool enable_ip_based_pooling,
15577 bool enable_alternative_services,
15578 const NetLogWithSource& net_log) override {
Jeremy Roman0579ed62017-08-29 15:56:1915579 auto fake_request = std::make_unique<FakeStreamRequest>(priority, delegate);
[email protected]bf828982013-08-14 18:01:4715580 last_stream_request_ = fake_request->AsWeakPtr();
xunjieli96f2a402017-06-05 17:24:2715581 return std::move(fake_request);
[email protected]bf828982013-08-14 18:01:4715582 }
15583
xunjieli96f2a402017-06-05 17:24:2715584 std::unique_ptr<HttpStreamRequest> RequestBidirectionalStreamImpl(
xunjieli11834f02015-12-22 04:27:0815585 const HttpRequestInfo& info,
15586 RequestPriority priority,
15587 const SSLConfig& server_ssl_config,
15588 const SSLConfig& proxy_ssl_config,
15589 HttpStreamRequest::Delegate* delegate,
bnc8016c1f2017-03-31 02:11:2915590 bool enable_ip_based_pooling,
bncaccd4962017-04-06 21:00:2615591 bool enable_alternative_services,
tfarina42834112016-09-22 13:38:2015592 const NetLogWithSource& net_log) override {
xunjieli11834f02015-12-22 04:27:0815593 NOTREACHED();
15594 return nullptr;
15595 }
15596
xunjieli96f2a402017-06-05 17:24:2715597 std::unique_ptr<HttpStreamRequest> RequestWebSocketHandshakeStream(
[email protected]bf828982013-08-14 18:01:4715598 const HttpRequestInfo& info,
15599 RequestPriority priority,
15600 const SSLConfig& server_ssl_config,
15601 const SSLConfig& proxy_ssl_config,
15602 HttpStreamRequest::Delegate* delegate,
[email protected]467086b2013-11-12 08:19:4615603 WebSocketHandshakeStreamBase::CreateHelper* create_helper,
bnc8016c1f2017-03-31 02:11:2915604 bool enable_ip_based_pooling,
bncaccd4962017-04-06 21:00:2615605 bool enable_alternative_services,
tfarina42834112016-09-22 13:38:2015606 const NetLogWithSource& net_log) override {
xunjieli96f2a402017-06-05 17:24:2715607 auto fake_request =
Jeremy Roman0579ed62017-08-29 15:56:1915608 std::make_unique<FakeStreamRequest>(priority, delegate, create_helper);
[email protected]831e4a32013-11-14 02:14:4415609 last_stream_request_ = fake_request->AsWeakPtr();
xunjieli96f2a402017-06-05 17:24:2715610 return std::move(fake_request);
[email protected]bf828982013-08-14 18:01:4715611 }
15612
dchengb03027d2014-10-21 12:00:2015613 void PreconnectStreams(int num_streams,
nharper8cdb0fb2016-04-22 21:34:5915614 const HttpRequestInfo& info) override {
[email protected]bf828982013-08-14 18:01:4715615 ADD_FAILURE();
15616 }
15617
dchengb03027d2014-10-21 12:00:2015618 const HostMappingRules* GetHostMappingRules() const override {
[email protected]bf828982013-08-14 18:01:4715619 ADD_FAILURE();
15620 return NULL;
15621 }
15622
xunjielif5267de2017-01-20 21:18:5715623 void DumpMemoryStats(base::trace_event::ProcessMemoryDump* pmd,
15624 const std::string& parent_absolute_name) const override {
15625 ADD_FAILURE();
15626 }
15627
[email protected]bf828982013-08-14 18:01:4715628 private:
15629 base::WeakPtr<FakeStreamRequest> last_stream_request_;
15630
15631 DISALLOW_COPY_AND_ASSIGN(FakeStreamFactory);
15632};
15633
Adam Rice425cf122015-01-19 06:18:2415634// TODO(ricea): Maybe unify this with the one in
15635// url_request_http_job_unittest.cc ?
15636class FakeWebSocketBasicHandshakeStream : public WebSocketHandshakeStreamBase {
15637 public:
danakj1fd259a02016-04-16 03:17:0915638 FakeWebSocketBasicHandshakeStream(
15639 std::unique_ptr<ClientSocketHandle> connection,
15640 bool using_proxy)
mmenkea7da6da2016-09-01 21:56:5215641 : state_(std::move(connection), using_proxy, false) {}
Adam Rice425cf122015-01-19 06:18:2415642
15643 // Fake implementation of HttpStreamBase methods.
15644 // This ends up being quite "real" because this object has to really send data
15645 // on the mock socket. It might be easier to use the real implementation, but
15646 // the fact that the WebSocket code is not compiled on iOS makes that
15647 // difficult.
15648 int InitializeStream(const HttpRequestInfo* request_info,
15649 RequestPriority priority,
tfarina42834112016-09-22 13:38:2015650 const NetLogWithSource& net_log,
Adam Rice425cf122015-01-19 06:18:2415651 const CompletionCallback& callback) override {
15652 state_.Initialize(request_info, priority, net_log, callback);
15653 return OK;
15654 }
15655
15656 int SendRequest(const HttpRequestHeaders& request_headers,
15657 HttpResponseInfo* response,
15658 const CompletionCallback& callback) override {
15659 return parser()->SendRequest(state_.GenerateRequestLine(), request_headers,
15660 response, callback);
15661 }
15662
15663 int ReadResponseHeaders(const CompletionCallback& callback) override {
15664 return parser()->ReadResponseHeaders(callback);
15665 }
15666
15667 int ReadResponseBody(IOBuffer* buf,
15668 int buf_len,
15669 const CompletionCallback& callback) override {
15670 NOTREACHED();
15671 return ERR_IO_PENDING;
15672 }
15673
15674 void Close(bool not_reusable) override {
15675 if (parser())
15676 parser()->Close(true);
15677 }
15678
15679 bool IsResponseBodyComplete() const override {
15680 NOTREACHED();
15681 return false;
15682 }
15683
Adam Rice425cf122015-01-19 06:18:2415684 bool IsConnectionReused() const override {
15685 NOTREACHED();
15686 return false;
15687 }
15688 void SetConnectionReused() override { NOTREACHED(); }
15689
mmenkebd84c392015-09-02 14:12:3415690 bool CanReuseConnection() const override { return false; }
Adam Rice425cf122015-01-19 06:18:2415691
sclittle4de1bab92015-09-22 21:28:2415692 int64_t GetTotalReceivedBytes() const override {
Adam Rice425cf122015-01-19 06:18:2415693 NOTREACHED();
15694 return 0;
15695 }
15696
sclittlebe1ccf62015-09-02 19:40:3615697 int64_t GetTotalSentBytes() const override {
15698 NOTREACHED();
15699 return 0;
15700 }
15701
Adam Rice425cf122015-01-19 06:18:2415702 bool GetLoadTimingInfo(LoadTimingInfo* load_timing_info) const override {
15703 NOTREACHED();
15704 return false;
15705 }
15706
rchcd379012017-04-12 21:53:3215707 bool GetAlternativeService(
15708 AlternativeService* alternative_service) const override {
15709 ADD_FAILURE();
15710 return false;
15711 }
15712
Adam Ricecb76ac62015-02-20 05:33:2515713 void GetSSLInfo(SSLInfo* ssl_info) override {}
Adam Rice425cf122015-01-19 06:18:2415714
15715 void GetSSLCertRequestInfo(SSLCertRequestInfo* cert_request_info) override {
15716 NOTREACHED();
15717 }
15718
ttuttled9dbc652015-09-29 20:00:5915719 bool GetRemoteEndpoint(IPEndPoint* endpoint) override { return false; }
15720
nharper78e6d2b2016-09-21 05:42:3515721 Error GetTokenBindingSignature(crypto::ECPrivateKey* key,
15722 TokenBindingType tb_type,
15723 std::vector<uint8_t>* out) override {
nharperb7441ef2016-01-25 23:54:1415724 ADD_FAILURE();
15725 return ERR_NOT_IMPLEMENTED;
15726 }
15727
Adam Rice425cf122015-01-19 06:18:2415728 void Drain(HttpNetworkSession* session) override { NOTREACHED(); }
15729
zhongyica364fbb2015-12-12 03:39:1215730 void PopulateNetErrorDetails(NetErrorDetails* details) override { return; }
15731
Adam Rice425cf122015-01-19 06:18:2415732 void SetPriority(RequestPriority priority) override { NOTREACHED(); }
15733
Adam Rice425cf122015-01-19 06:18:2415734 HttpStream* RenewStreamForAuth() override {
15735 NOTREACHED();
15736 return nullptr;
15737 }
15738
15739 // Fake implementation of WebSocketHandshakeStreamBase method(s)
danakj1fd259a02016-04-16 03:17:0915740 std::unique_ptr<WebSocketStream> Upgrade() override {
Adam Rice425cf122015-01-19 06:18:2415741 NOTREACHED();
danakj1fd259a02016-04-16 03:17:0915742 return std::unique_ptr<WebSocketStream>();
Adam Rice425cf122015-01-19 06:18:2415743 }
15744
15745 private:
15746 HttpStreamParser* parser() const { return state_.parser(); }
15747 HttpBasicState state_;
15748
15749 DISALLOW_COPY_AND_ASSIGN(FakeWebSocketBasicHandshakeStream);
15750};
15751
[email protected]831e4a32013-11-14 02:14:4415752// TODO(yhirano): Split this class out into a net/websockets file, if it is
15753// worth doing.
15754class FakeWebSocketStreamCreateHelper :
15755 public WebSocketHandshakeStreamBase::CreateHelper {
15756 public:
bnc615cf2f2017-05-19 18:53:2615757 std::unique_ptr<WebSocketHandshakeStreamBase> CreateBasicStream(
danakj1fd259a02016-04-16 03:17:0915758 std::unique_ptr<ClientSocketHandle> connection,
mostynbba063d6032014-10-09 11:01:1315759 bool using_proxy) override {
Jeremy Roman0579ed62017-08-29 15:56:1915760 return std::make_unique<FakeWebSocketBasicHandshakeStream>(
bnc615cf2f2017-05-19 18:53:2615761 std::move(connection), using_proxy);
[email protected]831e4a32013-11-14 02:14:4415762 }
15763
dchengb03027d2014-10-21 12:00:2015764 ~FakeWebSocketStreamCreateHelper() override {}
[email protected]831e4a32013-11-14 02:14:4415765
danakj1fd259a02016-04-16 03:17:0915766 virtual std::unique_ptr<WebSocketStream> Upgrade() {
[email protected]831e4a32013-11-14 02:14:4415767 NOTREACHED();
danakj1fd259a02016-04-16 03:17:0915768 return std::unique_ptr<WebSocketStream>();
[email protected]831e4a32013-11-14 02:14:4415769 }
15770};
15771
[email protected]bf828982013-08-14 18:01:4715772} // namespace
15773
15774// Make sure that HttpNetworkTransaction passes on its priority to its
15775// stream request on start.
bncd16676a2016-07-20 16:23:0115776TEST_F(HttpNetworkTransactionTest, SetStreamRequestPriorityOnStart) {
danakj1fd259a02016-04-16 03:17:0915777 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
mmenkee65e7af2015-10-13 17:16:4215778 HttpNetworkSessionPeer peer(session.get());
[email protected]bf828982013-08-14 18:01:4715779 FakeStreamFactory* fake_factory = new FakeStreamFactory();
danakj1fd259a02016-04-16 03:17:0915780 peer.SetHttpStreamFactory(std::unique_ptr<HttpStreamFactory>(fake_factory));
[email protected]bf828982013-08-14 18:01:4715781
krasinc06a72a2016-12-21 03:42:4615782 HttpRequestInfo request;
dcheng48459ac22014-08-26 00:46:4115783 HttpNetworkTransaction trans(LOW, session.get());
[email protected]bf828982013-08-14 18:01:4715784
wezca1070932016-05-26 20:30:5215785 ASSERT_FALSE(fake_factory->last_stream_request());
[email protected]bf828982013-08-14 18:01:4715786
[email protected]bf828982013-08-14 18:01:4715787 TestCompletionCallback callback;
15788 EXPECT_EQ(ERR_IO_PENDING,
tfarina42834112016-09-22 13:38:2015789 trans.Start(&request, callback.callback(), NetLogWithSource()));
[email protected]bf828982013-08-14 18:01:4715790
15791 base::WeakPtr<FakeStreamRequest> fake_request =
15792 fake_factory->last_stream_request();
wezca1070932016-05-26 20:30:5215793 ASSERT_TRUE(fake_request);
[email protected]bf828982013-08-14 18:01:4715794 EXPECT_EQ(LOW, fake_request->priority());
15795}
15796
15797// Make sure that HttpNetworkTransaction passes on its priority
15798// updates to its stream request.
bncd16676a2016-07-20 16:23:0115799TEST_F(HttpNetworkTransactionTest, SetStreamRequestPriority) {
danakj1fd259a02016-04-16 03:17:0915800 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
mmenkee65e7af2015-10-13 17:16:4215801 HttpNetworkSessionPeer peer(session.get());
[email protected]bf828982013-08-14 18:01:4715802 FakeStreamFactory* fake_factory = new FakeStreamFactory();
danakj1fd259a02016-04-16 03:17:0915803 peer.SetHttpStreamFactory(std::unique_ptr<HttpStreamFactory>(fake_factory));
[email protected]bf828982013-08-14 18:01:4715804
krasinc06a72a2016-12-21 03:42:4615805 HttpRequestInfo request;
dcheng48459ac22014-08-26 00:46:4115806 HttpNetworkTransaction trans(LOW, session.get());
[email protected]bf828982013-08-14 18:01:4715807
[email protected]bf828982013-08-14 18:01:4715808 TestCompletionCallback callback;
15809 EXPECT_EQ(ERR_IO_PENDING,
tfarina42834112016-09-22 13:38:2015810 trans.Start(&request, callback.callback(), NetLogWithSource()));
[email protected]bf828982013-08-14 18:01:4715811
15812 base::WeakPtr<FakeStreamRequest> fake_request =
15813 fake_factory->last_stream_request();
wezca1070932016-05-26 20:30:5215814 ASSERT_TRUE(fake_request);
[email protected]bf828982013-08-14 18:01:4715815 EXPECT_EQ(LOW, fake_request->priority());
15816
15817 trans.SetPriority(LOWEST);
wezca1070932016-05-26 20:30:5215818 ASSERT_TRUE(fake_request);
[email protected]bf828982013-08-14 18:01:4715819 EXPECT_EQ(LOWEST, fake_request->priority());
15820}
15821
[email protected]e86839fd2013-08-14 18:29:0315822// Make sure that HttpNetworkTransaction passes on its priority
15823// updates to its stream.
bncd16676a2016-07-20 16:23:0115824TEST_F(HttpNetworkTransactionTest, SetStreamPriority) {
danakj1fd259a02016-04-16 03:17:0915825 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
mmenkee65e7af2015-10-13 17:16:4215826 HttpNetworkSessionPeer peer(session.get());
[email protected]e86839fd2013-08-14 18:29:0315827 FakeStreamFactory* fake_factory = new FakeStreamFactory();
danakj1fd259a02016-04-16 03:17:0915828 peer.SetHttpStreamFactory(std::unique_ptr<HttpStreamFactory>(fake_factory));
[email protected]e86839fd2013-08-14 18:29:0315829
krasinc06a72a2016-12-21 03:42:4615830 HttpRequestInfo request;
dcheng48459ac22014-08-26 00:46:4115831 HttpNetworkTransaction trans(LOW, session.get());
[email protected]e86839fd2013-08-14 18:29:0315832
[email protected]e86839fd2013-08-14 18:29:0315833 TestCompletionCallback callback;
15834 EXPECT_EQ(ERR_IO_PENDING,
tfarina42834112016-09-22 13:38:2015835 trans.Start(&request, callback.callback(), NetLogWithSource()));
[email protected]e86839fd2013-08-14 18:29:0315836
15837 base::WeakPtr<FakeStreamRequest> fake_request =
15838 fake_factory->last_stream_request();
wezca1070932016-05-26 20:30:5215839 ASSERT_TRUE(fake_request);
[email protected]e86839fd2013-08-14 18:29:0315840 base::WeakPtr<FakeStream> fake_stream = fake_request->FinishStreamRequest();
wezca1070932016-05-26 20:30:5215841 ASSERT_TRUE(fake_stream);
[email protected]e86839fd2013-08-14 18:29:0315842 EXPECT_EQ(LOW, fake_stream->priority());
15843
15844 trans.SetPriority(LOWEST);
15845 EXPECT_EQ(LOWEST, fake_stream->priority());
15846}
15847
bncd16676a2016-07-20 16:23:0115848TEST_F(HttpNetworkTransactionTest, CreateWebSocketHandshakeStream) {
[email protected]831e4a32013-11-14 02:14:4415849 // The same logic needs to be tested for both ws: and wss: schemes, but this
15850 // test is already parameterised on NextProto, so it uses a loop to verify
15851 // that the different schemes work.
bncce36dca22015-04-21 22:11:2315852 std::string test_cases[] = {"ws://www.example.org/",
15853 "wss://www.example.org/"};
[email protected]831e4a32013-11-14 02:14:4415854 for (size_t i = 0; i < arraysize(test_cases); ++i) {
danakj1fd259a02016-04-16 03:17:0915855 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
mmenkee65e7af2015-10-13 17:16:4215856 HttpNetworkSessionPeer peer(session.get());
[email protected]831e4a32013-11-14 02:14:4415857 FakeStreamFactory* fake_factory = new FakeStreamFactory();
15858 FakeWebSocketStreamCreateHelper websocket_stream_create_helper;
[email protected]0191b51c2013-11-18 10:55:2315859 peer.SetHttpStreamFactoryForWebSocket(
danakj1fd259a02016-04-16 03:17:0915860 std::unique_ptr<HttpStreamFactory>(fake_factory));
[email protected]831e4a32013-11-14 02:14:4415861
krasinc06a72a2016-12-21 03:42:4615862 HttpRequestInfo request;
dcheng48459ac22014-08-26 00:46:4115863 HttpNetworkTransaction trans(LOW, session.get());
[email protected]831e4a32013-11-14 02:14:4415864 trans.SetWebSocketHandshakeStreamCreateHelper(
15865 &websocket_stream_create_helper);
15866
[email protected]831e4a32013-11-14 02:14:4415867 TestCompletionCallback callback;
15868 request.method = "GET";
15869 request.url = GURL(test_cases[i]);
15870
15871 EXPECT_EQ(ERR_IO_PENDING,
tfarina42834112016-09-22 13:38:2015872 trans.Start(&request, callback.callback(), NetLogWithSource()));
[email protected]831e4a32013-11-14 02:14:4415873
15874 base::WeakPtr<FakeStreamRequest> fake_request =
15875 fake_factory->last_stream_request();
wezca1070932016-05-26 20:30:5215876 ASSERT_TRUE(fake_request);
[email protected]831e4a32013-11-14 02:14:4415877 EXPECT_EQ(&websocket_stream_create_helper,
15878 fake_request->websocket_stream_create_helper());
15879 }
15880}
15881
[email protected]043b68c82013-08-22 23:41:5215882// Tests that when a used socket is returned to the SSL socket pool, it's closed
15883// if the transport socket pool is stalled on the global socket limit.
bncd16676a2016-07-20 16:23:0115884TEST_F(HttpNetworkTransactionTest, CloseSSLSocketOnIdleForHttpRequest) {
[email protected]043b68c82013-08-22 23:41:5215885 ClientSocketPoolManager::set_max_sockets_per_group(
15886 HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
15887 ClientSocketPoolManager::set_max_sockets_per_pool(
15888 HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
15889
15890 // Set up SSL request.
15891
15892 HttpRequestInfo ssl_request;
15893 ssl_request.method = "GET";
bncce36dca22015-04-21 22:11:2315894 ssl_request.url = GURL("https://www.example.org/");
[email protected]043b68c82013-08-22 23:41:5215895
15896 MockWrite ssl_writes[] = {
bncce36dca22015-04-21 22:11:2315897 MockWrite(
15898 "GET / HTTP/1.1\r\n"
15899 "Host: www.example.org\r\n"
15900 "Connection: keep-alive\r\n\r\n"),
[email protected]043b68c82013-08-22 23:41:5215901 };
15902 MockRead ssl_reads[] = {
15903 MockRead("HTTP/1.1 200 OK\r\n"),
15904 MockRead("Content-Length: 11\r\n\r\n"),
15905 MockRead("hello world"),
15906 MockRead(SYNCHRONOUS, OK),
15907 };
15908 StaticSocketDataProvider ssl_data(ssl_reads, arraysize(ssl_reads),
15909 ssl_writes, arraysize(ssl_writes));
15910 session_deps_.socket_factory->AddSocketDataProvider(&ssl_data);
15911
15912 SSLSocketDataProvider ssl(ASYNC, OK);
15913 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
15914
15915 // Set up HTTP request.
15916
15917 HttpRequestInfo http_request;
15918 http_request.method = "GET";
bncce36dca22015-04-21 22:11:2315919 http_request.url = GURL("http://www.example.org/");
[email protected]043b68c82013-08-22 23:41:5215920
15921 MockWrite http_writes[] = {
bncce36dca22015-04-21 22:11:2315922 MockWrite(
15923 "GET / HTTP/1.1\r\n"
15924 "Host: www.example.org\r\n"
15925 "Connection: keep-alive\r\n\r\n"),
[email protected]043b68c82013-08-22 23:41:5215926 };
15927 MockRead http_reads[] = {
15928 MockRead("HTTP/1.1 200 OK\r\n"),
15929 MockRead("Content-Length: 7\r\n\r\n"),
15930 MockRead("falafel"),
15931 MockRead(SYNCHRONOUS, OK),
15932 };
15933 StaticSocketDataProvider http_data(http_reads, arraysize(http_reads),
15934 http_writes, arraysize(http_writes));
15935 session_deps_.socket_factory->AddSocketDataProvider(&http_data);
15936
danakj1fd259a02016-04-16 03:17:0915937 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]043b68c82013-08-22 23:41:5215938
15939 // Start the SSL request.
15940 TestCompletionCallback ssl_callback;
bnc691fda62016-08-12 00:43:1615941 HttpNetworkTransaction ssl_trans(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:2015942 ASSERT_EQ(ERR_IO_PENDING,
15943 ssl_trans.Start(&ssl_request, ssl_callback.callback(),
15944 NetLogWithSource()));
[email protected]043b68c82013-08-22 23:41:5215945
15946 // Start the HTTP request. Pool should stall.
15947 TestCompletionCallback http_callback;
bnc691fda62016-08-12 00:43:1615948 HttpNetworkTransaction http_trans(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:2015949 ASSERT_EQ(ERR_IO_PENDING,
15950 http_trans.Start(&http_request, http_callback.callback(),
15951 NetLogWithSource()));
dcheng48459ac22014-08-26 00:46:4115952 EXPECT_TRUE(IsTransportSocketPoolStalled(session.get()));
[email protected]043b68c82013-08-22 23:41:5215953
15954 // Wait for response from SSL request.
robpercival214763f2016-07-01 23:27:0115955 ASSERT_THAT(ssl_callback.WaitForResult(), IsOk());
[email protected]043b68c82013-08-22 23:41:5215956 std::string response_data;
bnc691fda62016-08-12 00:43:1615957 ASSERT_THAT(ReadTransaction(&ssl_trans, &response_data), IsOk());
[email protected]043b68c82013-08-22 23:41:5215958 EXPECT_EQ("hello world", response_data);
15959
15960 // The SSL socket should automatically be closed, so the HTTP request can
15961 // start.
dcheng48459ac22014-08-26 00:46:4115962 EXPECT_EQ(0, GetIdleSocketCountInSSLSocketPool(session.get()));
15963 ASSERT_FALSE(IsTransportSocketPoolStalled(session.get()));
[email protected]043b68c82013-08-22 23:41:5215964
15965 // The HTTP request can now complete.
robpercival214763f2016-07-01 23:27:0115966 ASSERT_THAT(http_callback.WaitForResult(), IsOk());
bnc691fda62016-08-12 00:43:1615967 ASSERT_THAT(ReadTransaction(&http_trans, &response_data), IsOk());
[email protected]043b68c82013-08-22 23:41:5215968 EXPECT_EQ("falafel", response_data);
15969
dcheng48459ac22014-08-26 00:46:4115970 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]043b68c82013-08-22 23:41:5215971}
15972
15973// Tests that when a SSL connection is established but there's no corresponding
15974// request that needs it, the new socket is closed if the transport socket pool
15975// is stalled on the global socket limit.
bncd16676a2016-07-20 16:23:0115976TEST_F(HttpNetworkTransactionTest, CloseSSLSocketOnIdleForHttpRequest2) {
[email protected]043b68c82013-08-22 23:41:5215977 ClientSocketPoolManager::set_max_sockets_per_group(
15978 HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
15979 ClientSocketPoolManager::set_max_sockets_per_pool(
15980 HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
15981
15982 // Set up an ssl request.
15983
15984 HttpRequestInfo ssl_request;
15985 ssl_request.method = "GET";
15986 ssl_request.url = GURL("https://www.foopy.com/");
15987
15988 // No data will be sent on the SSL socket.
15989 StaticSocketDataProvider ssl_data;
15990 session_deps_.socket_factory->AddSocketDataProvider(&ssl_data);
15991
15992 SSLSocketDataProvider ssl(ASYNC, OK);
15993 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
15994
15995 // Set up HTTP request.
15996
15997 HttpRequestInfo http_request;
15998 http_request.method = "GET";
bncce36dca22015-04-21 22:11:2315999 http_request.url = GURL("http://www.example.org/");
[email protected]043b68c82013-08-22 23:41:5216000
16001 MockWrite http_writes[] = {
bncce36dca22015-04-21 22:11:2316002 MockWrite(
16003 "GET / HTTP/1.1\r\n"
16004 "Host: www.example.org\r\n"
16005 "Connection: keep-alive\r\n\r\n"),
[email protected]043b68c82013-08-22 23:41:5216006 };
16007 MockRead http_reads[] = {
16008 MockRead("HTTP/1.1 200 OK\r\n"),
16009 MockRead("Content-Length: 7\r\n\r\n"),
16010 MockRead("falafel"),
16011 MockRead(SYNCHRONOUS, OK),
16012 };
16013 StaticSocketDataProvider http_data(http_reads, arraysize(http_reads),
16014 http_writes, arraysize(http_writes));
16015 session_deps_.socket_factory->AddSocketDataProvider(&http_data);
16016
danakj1fd259a02016-04-16 03:17:0916017 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]043b68c82013-08-22 23:41:5216018
16019 // Preconnect an SSL socket. A preconnect is needed because connect jobs are
16020 // cancelled when a normal transaction is cancelled.
ttuttle859dc7a2015-04-23 19:42:2916021 HttpStreamFactory* http_stream_factory = session->http_stream_factory();
nharper8cdb0fb2016-04-22 21:34:5916022 http_stream_factory->PreconnectStreams(1, ssl_request);
dcheng48459ac22014-08-26 00:46:4116023 EXPECT_EQ(0, GetIdleSocketCountInSSLSocketPool(session.get()));
[email protected]043b68c82013-08-22 23:41:5216024
16025 // Start the HTTP request. Pool should stall.
16026 TestCompletionCallback http_callback;
bnc691fda62016-08-12 00:43:1616027 HttpNetworkTransaction http_trans(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:2016028 ASSERT_EQ(ERR_IO_PENDING,
16029 http_trans.Start(&http_request, http_callback.callback(),
16030 NetLogWithSource()));
dcheng48459ac22014-08-26 00:46:4116031 EXPECT_TRUE(IsTransportSocketPoolStalled(session.get()));
[email protected]043b68c82013-08-22 23:41:5216032
16033 // The SSL connection will automatically be closed once the connection is
16034 // established, to let the HTTP request start.
robpercival214763f2016-07-01 23:27:0116035 ASSERT_THAT(http_callback.WaitForResult(), IsOk());
[email protected]043b68c82013-08-22 23:41:5216036 std::string response_data;
bnc691fda62016-08-12 00:43:1616037 ASSERT_THAT(ReadTransaction(&http_trans, &response_data), IsOk());
[email protected]043b68c82013-08-22 23:41:5216038 EXPECT_EQ("falafel", response_data);
16039
dcheng48459ac22014-08-26 00:46:4116040 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]043b68c82013-08-22 23:41:5216041}
16042
bncd16676a2016-07-20 16:23:0116043TEST_F(HttpNetworkTransactionTest, PostReadsErrorResponseAfterReset) {
danakj1fd259a02016-04-16 03:17:0916044 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:2216045 element_readers.push_back(
Jeremy Roman0579ed62017-08-29 15:56:1916046 std::make_unique<UploadBytesElementReader>("foo", 3));
olli.raula6df48b2a2015-11-26 07:40:2216047 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]02d74a02014-04-23 18:10:5416048
16049 HttpRequestInfo request;
16050 request.method = "POST";
16051 request.url = GURL("http://www.foo.com/");
16052 request.upload_data_stream = &upload_data_stream;
[email protected]02d74a02014-04-23 18:10:5416053
danakj1fd259a02016-04-16 03:17:0916054 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1616055 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]02d74a02014-04-23 18:10:5416056 // Send headers successfully, but get an error while sending the body.
16057 MockWrite data_writes[] = {
16058 MockWrite("POST / HTTP/1.1\r\n"
16059 "Host: www.foo.com\r\n"
16060 "Connection: keep-alive\r\n"
16061 "Content-Length: 3\r\n\r\n"),
16062 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
16063 };
16064
16065 MockRead data_reads[] = {
16066 MockRead("HTTP/1.0 400 Not OK\r\n\r\n"),
16067 MockRead("hello world"),
16068 MockRead(SYNCHRONOUS, OK),
16069 };
16070 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
16071 arraysize(data_writes));
16072 session_deps_.socket_factory->AddSocketDataProvider(&data);
16073
16074 TestCompletionCallback callback;
16075
tfarina42834112016-09-22 13:38:2016076 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0116077 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]02d74a02014-04-23 18:10:5416078
16079 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0116080 EXPECT_THAT(rv, IsOk());
[email protected]02d74a02014-04-23 18:10:5416081
bnc691fda62016-08-12 00:43:1616082 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5216083 ASSERT_TRUE(response);
[email protected]02d74a02014-04-23 18:10:5416084
wezca1070932016-05-26 20:30:5216085 EXPECT_TRUE(response->headers);
[email protected]02d74a02014-04-23 18:10:5416086 EXPECT_EQ("HTTP/1.0 400 Not OK", response->headers->GetStatusLine());
16087
16088 std::string response_data;
bnc691fda62016-08-12 00:43:1616089 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:0116090 EXPECT_THAT(rv, IsOk());
[email protected]02d74a02014-04-23 18:10:5416091 EXPECT_EQ("hello world", response_data);
16092}
16093
16094// This test makes sure the retry logic doesn't trigger when reading an error
16095// response from a server that rejected a POST with a CONNECTION_RESET.
bncd16676a2016-07-20 16:23:0116096TEST_F(HttpNetworkTransactionTest,
[email protected]02d74a02014-04-23 18:10:5416097 PostReadsErrorResponseAfterResetOnReusedSocket) {
danakj1fd259a02016-04-16 03:17:0916098 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]02d74a02014-04-23 18:10:5416099 MockWrite data_writes[] = {
16100 MockWrite("GET / HTTP/1.1\r\n"
16101 "Host: www.foo.com\r\n"
16102 "Connection: keep-alive\r\n\r\n"),
16103 MockWrite("POST / HTTP/1.1\r\n"
16104 "Host: www.foo.com\r\n"
16105 "Connection: keep-alive\r\n"
16106 "Content-Length: 3\r\n\r\n"),
16107 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
16108 };
16109
16110 MockRead data_reads[] = {
16111 MockRead("HTTP/1.1 200 Peachy\r\n"
16112 "Content-Length: 14\r\n\r\n"),
16113 MockRead("first response"),
16114 MockRead("HTTP/1.1 400 Not OK\r\n"
16115 "Content-Length: 15\r\n\r\n"),
16116 MockRead("second response"),
16117 MockRead(SYNCHRONOUS, OK),
16118 };
16119 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
16120 arraysize(data_writes));
16121 session_deps_.socket_factory->AddSocketDataProvider(&data);
16122
16123 TestCompletionCallback callback;
16124 HttpRequestInfo request1;
16125 request1.method = "GET";
16126 request1.url = GURL("http://www.foo.com/");
16127 request1.load_flags = 0;
16128
bnc87dcefc2017-05-25 12:47:5816129 auto trans1 =
Jeremy Roman0579ed62017-08-29 15:56:1916130 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:2016131 int rv = trans1->Start(&request1, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0116132 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]02d74a02014-04-23 18:10:5416133
16134 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0116135 EXPECT_THAT(rv, IsOk());
[email protected]02d74a02014-04-23 18:10:5416136
16137 const HttpResponseInfo* response1 = trans1->GetResponseInfo();
wezca1070932016-05-26 20:30:5216138 ASSERT_TRUE(response1);
[email protected]02d74a02014-04-23 18:10:5416139
wezca1070932016-05-26 20:30:5216140 EXPECT_TRUE(response1->headers);
[email protected]02d74a02014-04-23 18:10:5416141 EXPECT_EQ("HTTP/1.1 200 Peachy", response1->headers->GetStatusLine());
16142
16143 std::string response_data1;
16144 rv = ReadTransaction(trans1.get(), &response_data1);
robpercival214763f2016-07-01 23:27:0116145 EXPECT_THAT(rv, IsOk());
[email protected]02d74a02014-04-23 18:10:5416146 EXPECT_EQ("first response", response_data1);
16147 // Delete the transaction to release the socket back into the socket pool.
16148 trans1.reset();
16149
danakj1fd259a02016-04-16 03:17:0916150 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:2216151 element_readers.push_back(
Jeremy Roman0579ed62017-08-29 15:56:1916152 std::make_unique<UploadBytesElementReader>("foo", 3));
olli.raula6df48b2a2015-11-26 07:40:2216153 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]02d74a02014-04-23 18:10:5416154
16155 HttpRequestInfo request2;
16156 request2.method = "POST";
16157 request2.url = GURL("http://www.foo.com/");
16158 request2.upload_data_stream = &upload_data_stream;
16159 request2.load_flags = 0;
16160
bnc691fda62016-08-12 00:43:1616161 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:2016162 rv = trans2.Start(&request2, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0116163 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]02d74a02014-04-23 18:10:5416164
16165 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0116166 EXPECT_THAT(rv, IsOk());
[email protected]02d74a02014-04-23 18:10:5416167
bnc691fda62016-08-12 00:43:1616168 const HttpResponseInfo* response2 = trans2.GetResponseInfo();
wezca1070932016-05-26 20:30:5216169 ASSERT_TRUE(response2);
[email protected]02d74a02014-04-23 18:10:5416170
wezca1070932016-05-26 20:30:5216171 EXPECT_TRUE(response2->headers);
[email protected]02d74a02014-04-23 18:10:5416172 EXPECT_EQ("HTTP/1.1 400 Not OK", response2->headers->GetStatusLine());
16173
16174 std::string response_data2;
bnc691fda62016-08-12 00:43:1616175 rv = ReadTransaction(&trans2, &response_data2);
robpercival214763f2016-07-01 23:27:0116176 EXPECT_THAT(rv, IsOk());
[email protected]02d74a02014-04-23 18:10:5416177 EXPECT_EQ("second response", response_data2);
16178}
16179
bncd16676a2016-07-20 16:23:0116180TEST_F(HttpNetworkTransactionTest,
[email protected]02d74a02014-04-23 18:10:5416181 PostReadsErrorResponseAfterResetPartialBodySent) {
danakj1fd259a02016-04-16 03:17:0916182 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:2216183 element_readers.push_back(
Jeremy Roman0579ed62017-08-29 15:56:1916184 std::make_unique<UploadBytesElementReader>("foo", 3));
olli.raula6df48b2a2015-11-26 07:40:2216185 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]02d74a02014-04-23 18:10:5416186
16187 HttpRequestInfo request;
16188 request.method = "POST";
16189 request.url = GURL("http://www.foo.com/");
16190 request.upload_data_stream = &upload_data_stream;
[email protected]02d74a02014-04-23 18:10:5416191
danakj1fd259a02016-04-16 03:17:0916192 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1616193 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]02d74a02014-04-23 18:10:5416194 // Send headers successfully, but get an error while sending the body.
16195 MockWrite data_writes[] = {
16196 MockWrite("POST / HTTP/1.1\r\n"
16197 "Host: www.foo.com\r\n"
16198 "Connection: keep-alive\r\n"
16199 "Content-Length: 3\r\n\r\n"
16200 "fo"),
16201 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
16202 };
16203
16204 MockRead data_reads[] = {
16205 MockRead("HTTP/1.0 400 Not OK\r\n\r\n"),
16206 MockRead("hello world"),
16207 MockRead(SYNCHRONOUS, OK),
16208 };
16209 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
16210 arraysize(data_writes));
16211 session_deps_.socket_factory->AddSocketDataProvider(&data);
16212
16213 TestCompletionCallback callback;
16214
tfarina42834112016-09-22 13:38:2016215 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0116216 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]02d74a02014-04-23 18:10:5416217
16218 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0116219 EXPECT_THAT(rv, IsOk());
[email protected]02d74a02014-04-23 18:10:5416220
bnc691fda62016-08-12 00:43:1616221 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5216222 ASSERT_TRUE(response);
[email protected]02d74a02014-04-23 18:10:5416223
wezca1070932016-05-26 20:30:5216224 EXPECT_TRUE(response->headers);
[email protected]02d74a02014-04-23 18:10:5416225 EXPECT_EQ("HTTP/1.0 400 Not OK", response->headers->GetStatusLine());
16226
16227 std::string response_data;
bnc691fda62016-08-12 00:43:1616228 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:0116229 EXPECT_THAT(rv, IsOk());
[email protected]02d74a02014-04-23 18:10:5416230 EXPECT_EQ("hello world", response_data);
16231}
16232
16233// This tests the more common case than the previous test, where headers and
16234// body are not merged into a single request.
bncd16676a2016-07-20 16:23:0116235TEST_F(HttpNetworkTransactionTest, ChunkedPostReadsErrorResponseAfterReset) {
mmenkecbc2b712014-10-09 20:29:0716236 ChunkedUploadDataStream upload_data_stream(0);
[email protected]02d74a02014-04-23 18:10:5416237
16238 HttpRequestInfo request;
16239 request.method = "POST";
16240 request.url = GURL("http://www.foo.com/");
16241 request.upload_data_stream = &upload_data_stream;
[email protected]02d74a02014-04-23 18:10:5416242
danakj1fd259a02016-04-16 03:17:0916243 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1616244 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]02d74a02014-04-23 18:10:5416245 // Send headers successfully, but get an error while sending the body.
16246 MockWrite data_writes[] = {
16247 MockWrite("POST / HTTP/1.1\r\n"
16248 "Host: www.foo.com\r\n"
16249 "Connection: keep-alive\r\n"
16250 "Transfer-Encoding: chunked\r\n\r\n"),
16251 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
16252 };
16253
16254 MockRead data_reads[] = {
16255 MockRead("HTTP/1.0 400 Not OK\r\n\r\n"),
16256 MockRead("hello world"),
16257 MockRead(SYNCHRONOUS, OK),
16258 };
16259 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
16260 arraysize(data_writes));
16261 session_deps_.socket_factory->AddSocketDataProvider(&data);
16262
16263 TestCompletionCallback callback;
16264
tfarina42834112016-09-22 13:38:2016265 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0116266 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]02d74a02014-04-23 18:10:5416267 // Make sure the headers are sent before adding a chunk. This ensures that
16268 // they can't be merged with the body in a single send. Not currently
16269 // necessary since a chunked body is never merged with headers, but this makes
16270 // the test more future proof.
16271 base::RunLoop().RunUntilIdle();
16272
mmenkecbc2b712014-10-09 20:29:0716273 upload_data_stream.AppendData("last chunk", 10, true);
[email protected]02d74a02014-04-23 18:10:5416274
16275 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0116276 EXPECT_THAT(rv, IsOk());
[email protected]02d74a02014-04-23 18:10:5416277
bnc691fda62016-08-12 00:43:1616278 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5216279 ASSERT_TRUE(response);
[email protected]02d74a02014-04-23 18:10:5416280
wezca1070932016-05-26 20:30:5216281 EXPECT_TRUE(response->headers);
[email protected]02d74a02014-04-23 18:10:5416282 EXPECT_EQ("HTTP/1.0 400 Not OK", response->headers->GetStatusLine());
16283
16284 std::string response_data;
bnc691fda62016-08-12 00:43:1616285 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:0116286 EXPECT_THAT(rv, IsOk());
[email protected]02d74a02014-04-23 18:10:5416287 EXPECT_EQ("hello world", response_data);
16288}
16289
bncd16676a2016-07-20 16:23:0116290TEST_F(HttpNetworkTransactionTest, PostReadsErrorResponseAfterResetAnd100) {
danakj1fd259a02016-04-16 03:17:0916291 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:2216292 element_readers.push_back(
Jeremy Roman0579ed62017-08-29 15:56:1916293 std::make_unique<UploadBytesElementReader>("foo", 3));
olli.raula6df48b2a2015-11-26 07:40:2216294 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]02d74a02014-04-23 18:10:5416295
16296 HttpRequestInfo request;
16297 request.method = "POST";
16298 request.url = GURL("http://www.foo.com/");
16299 request.upload_data_stream = &upload_data_stream;
[email protected]02d74a02014-04-23 18:10:5416300
danakj1fd259a02016-04-16 03:17:0916301 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1616302 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]02d74a02014-04-23 18:10:5416303
16304 MockWrite data_writes[] = {
16305 MockWrite("POST / HTTP/1.1\r\n"
16306 "Host: www.foo.com\r\n"
16307 "Connection: keep-alive\r\n"
16308 "Content-Length: 3\r\n\r\n"),
16309 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
16310 };
16311
16312 MockRead data_reads[] = {
16313 MockRead("HTTP/1.0 100 Continue\r\n\r\n"),
16314 MockRead("HTTP/1.0 400 Not OK\r\n\r\n"),
16315 MockRead("hello world"),
16316 MockRead(SYNCHRONOUS, OK),
16317 };
16318 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
16319 arraysize(data_writes));
16320 session_deps_.socket_factory->AddSocketDataProvider(&data);
16321
16322 TestCompletionCallback callback;
16323
tfarina42834112016-09-22 13:38:2016324 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0116325 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]02d74a02014-04-23 18:10:5416326
16327 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0116328 EXPECT_THAT(rv, IsOk());
[email protected]02d74a02014-04-23 18:10:5416329
bnc691fda62016-08-12 00:43:1616330 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5216331 ASSERT_TRUE(response);
[email protected]02d74a02014-04-23 18:10:5416332
wezca1070932016-05-26 20:30:5216333 EXPECT_TRUE(response->headers);
[email protected]02d74a02014-04-23 18:10:5416334 EXPECT_EQ("HTTP/1.0 400 Not OK", response->headers->GetStatusLine());
16335
16336 std::string response_data;
bnc691fda62016-08-12 00:43:1616337 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:0116338 EXPECT_THAT(rv, IsOk());
[email protected]02d74a02014-04-23 18:10:5416339 EXPECT_EQ("hello world", response_data);
16340}
16341
bncd16676a2016-07-20 16:23:0116342TEST_F(HttpNetworkTransactionTest, PostIgnoresNonErrorResponseAfterReset) {
danakj1fd259a02016-04-16 03:17:0916343 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:2216344 element_readers.push_back(
Jeremy Roman0579ed62017-08-29 15:56:1916345 std::make_unique<UploadBytesElementReader>("foo", 3));
olli.raula6df48b2a2015-11-26 07:40:2216346 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]02d74a02014-04-23 18:10:5416347
16348 HttpRequestInfo request;
16349 request.method = "POST";
16350 request.url = GURL("http://www.foo.com/");
16351 request.upload_data_stream = &upload_data_stream;
[email protected]02d74a02014-04-23 18:10:5416352
danakj1fd259a02016-04-16 03:17:0916353 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1616354 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]02d74a02014-04-23 18:10:5416355 // Send headers successfully, but get an error while sending the body.
16356 MockWrite data_writes[] = {
16357 MockWrite("POST / HTTP/1.1\r\n"
16358 "Host: www.foo.com\r\n"
16359 "Connection: keep-alive\r\n"
16360 "Content-Length: 3\r\n\r\n"),
16361 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
16362 };
16363
16364 MockRead data_reads[] = {
16365 MockRead("HTTP/1.0 200 Just Dandy\r\n\r\n"),
16366 MockRead("hello world"),
16367 MockRead(SYNCHRONOUS, OK),
16368 };
16369 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
16370 arraysize(data_writes));
16371 session_deps_.socket_factory->AddSocketDataProvider(&data);
16372
16373 TestCompletionCallback callback;
16374
tfarina42834112016-09-22 13:38:2016375 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0116376 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]02d74a02014-04-23 18:10:5416377
16378 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0116379 EXPECT_THAT(rv, IsError(ERR_CONNECTION_RESET));
[email protected]02d74a02014-04-23 18:10:5416380}
16381
bncd16676a2016-07-20 16:23:0116382TEST_F(HttpNetworkTransactionTest,
[email protected]02d74a02014-04-23 18:10:5416383 PostIgnoresNonErrorResponseAfterResetAnd100) {
danakj1fd259a02016-04-16 03:17:0916384 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:2216385 element_readers.push_back(
Jeremy Roman0579ed62017-08-29 15:56:1916386 std::make_unique<UploadBytesElementReader>("foo", 3));
olli.raula6df48b2a2015-11-26 07:40:2216387 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]02d74a02014-04-23 18:10:5416388
16389 HttpRequestInfo request;
16390 request.method = "POST";
16391 request.url = GURL("http://www.foo.com/");
16392 request.upload_data_stream = &upload_data_stream;
[email protected]02d74a02014-04-23 18:10:5416393
danakj1fd259a02016-04-16 03:17:0916394 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1616395 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]02d74a02014-04-23 18:10:5416396 // Send headers successfully, but get an error while sending the body.
16397 MockWrite data_writes[] = {
16398 MockWrite("POST / HTTP/1.1\r\n"
16399 "Host: www.foo.com\r\n"
16400 "Connection: keep-alive\r\n"
16401 "Content-Length: 3\r\n\r\n"),
16402 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
16403 };
16404
16405 MockRead data_reads[] = {
16406 MockRead("HTTP/1.0 100 Continue\r\n\r\n"),
16407 MockRead("HTTP/1.0 302 Redirect\r\n"),
16408 MockRead("Location: http://somewhere-else.com/\r\n"),
16409 MockRead("Content-Length: 0\r\n\r\n"),
16410 MockRead(SYNCHRONOUS, OK),
16411 };
16412 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
16413 arraysize(data_writes));
16414 session_deps_.socket_factory->AddSocketDataProvider(&data);
16415
16416 TestCompletionCallback callback;
16417
tfarina42834112016-09-22 13:38:2016418 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0116419 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]02d74a02014-04-23 18:10:5416420
16421 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0116422 EXPECT_THAT(rv, IsError(ERR_CONNECTION_RESET));
[email protected]02d74a02014-04-23 18:10:5416423}
16424
bncd16676a2016-07-20 16:23:0116425TEST_F(HttpNetworkTransactionTest, PostIgnoresHttp09ResponseAfterReset) {
danakj1fd259a02016-04-16 03:17:0916426 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:2216427 element_readers.push_back(
Jeremy Roman0579ed62017-08-29 15:56:1916428 std::make_unique<UploadBytesElementReader>("foo", 3));
olli.raula6df48b2a2015-11-26 07:40:2216429 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]02d74a02014-04-23 18:10:5416430
16431 HttpRequestInfo request;
16432 request.method = "POST";
16433 request.url = GURL("http://www.foo.com/");
16434 request.upload_data_stream = &upload_data_stream;
[email protected]02d74a02014-04-23 18:10:5416435
danakj1fd259a02016-04-16 03:17:0916436 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1616437 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]02d74a02014-04-23 18:10:5416438 // Send headers successfully, but get an error while sending the body.
16439 MockWrite data_writes[] = {
16440 MockWrite("POST / HTTP/1.1\r\n"
16441 "Host: www.foo.com\r\n"
16442 "Connection: keep-alive\r\n"
16443 "Content-Length: 3\r\n\r\n"),
16444 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
16445 };
16446
16447 MockRead data_reads[] = {
16448 MockRead("HTTP 0.9 rocks!"),
16449 MockRead(SYNCHRONOUS, OK),
16450 };
16451 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
16452 arraysize(data_writes));
16453 session_deps_.socket_factory->AddSocketDataProvider(&data);
16454
16455 TestCompletionCallback callback;
16456
tfarina42834112016-09-22 13:38:2016457 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0116458 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]02d74a02014-04-23 18:10:5416459
16460 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0116461 EXPECT_THAT(rv, IsError(ERR_CONNECTION_RESET));
[email protected]02d74a02014-04-23 18:10:5416462}
16463
bncd16676a2016-07-20 16:23:0116464TEST_F(HttpNetworkTransactionTest, PostIgnoresPartial400HeadersAfterReset) {
danakj1fd259a02016-04-16 03:17:0916465 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:2216466 element_readers.push_back(
Jeremy Roman0579ed62017-08-29 15:56:1916467 std::make_unique<UploadBytesElementReader>("foo", 3));
olli.raula6df48b2a2015-11-26 07:40:2216468 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]02d74a02014-04-23 18:10:5416469
16470 HttpRequestInfo request;
16471 request.method = "POST";
16472 request.url = GURL("http://www.foo.com/");
16473 request.upload_data_stream = &upload_data_stream;
[email protected]02d74a02014-04-23 18:10:5416474
danakj1fd259a02016-04-16 03:17:0916475 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1616476 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]02d74a02014-04-23 18:10:5416477 // Send headers successfully, but get an error while sending the body.
16478 MockWrite data_writes[] = {
16479 MockWrite("POST / HTTP/1.1\r\n"
16480 "Host: www.foo.com\r\n"
16481 "Connection: keep-alive\r\n"
16482 "Content-Length: 3\r\n\r\n"),
16483 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
16484 };
16485
16486 MockRead data_reads[] = {
16487 MockRead("HTTP/1.0 400 Not a Full Response\r\n"),
16488 MockRead(SYNCHRONOUS, OK),
16489 };
16490 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
16491 arraysize(data_writes));
16492 session_deps_.socket_factory->AddSocketDataProvider(&data);
16493
16494 TestCompletionCallback callback;
16495
tfarina42834112016-09-22 13:38:2016496 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0116497 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]02d74a02014-04-23 18:10:5416498
16499 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0116500 EXPECT_THAT(rv, IsError(ERR_CONNECTION_RESET));
[email protected]02d74a02014-04-23 18:10:5416501}
16502
Adam Rice425cf122015-01-19 06:18:2416503// Verify that proxy headers are not sent to the destination server when
16504// establishing a tunnel for a secure WebSocket connection.
bncd16676a2016-07-20 16:23:0116505TEST_F(HttpNetworkTransactionTest, ProxyHeadersNotSentOverWssTunnel) {
Adam Rice425cf122015-01-19 06:18:2416506 HttpRequestInfo request;
16507 request.method = "GET";
bncce36dca22015-04-21 22:11:2316508 request.url = GURL("wss://www.example.org/");
Adam Rice425cf122015-01-19 06:18:2416509 AddWebSocketHeaders(&request.extra_headers);
16510
16511 // Configure against proxy server "myproxy:70".
rdsmith82957ad2015-09-16 19:42:0316512 session_deps_.proxy_service =
16513 ProxyService::CreateFixedFromPacResult("PROXY myproxy:70");
Adam Rice425cf122015-01-19 06:18:2416514
danakj1fd259a02016-04-16 03:17:0916515 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
Adam Rice425cf122015-01-19 06:18:2416516
16517 // Since a proxy is configured, try to establish a tunnel.
16518 MockWrite data_writes[] = {
rsleevidb16bb02015-11-12 23:47:1716519 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
16520 "Host: www.example.org:443\r\n"
16521 "Proxy-Connection: keep-alive\r\n\r\n"),
Adam Rice425cf122015-01-19 06:18:2416522
16523 // After calling trans->RestartWithAuth(), this is the request we should
16524 // be issuing -- the final header line contains the credentials.
rsleevidb16bb02015-11-12 23:47:1716525 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
16526 "Host: www.example.org:443\r\n"
16527 "Proxy-Connection: keep-alive\r\n"
16528 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
Adam Rice425cf122015-01-19 06:18:2416529
rsleevidb16bb02015-11-12 23:47:1716530 MockWrite("GET / HTTP/1.1\r\n"
16531 "Host: www.example.org\r\n"
16532 "Connection: Upgrade\r\n"
16533 "Upgrade: websocket\r\n"
16534 "Origin: http://www.example.org\r\n"
16535 "Sec-WebSocket-Version: 13\r\n"
16536 "Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==\r\n\r\n"),
Adam Rice425cf122015-01-19 06:18:2416537 };
16538
16539 // The proxy responds to the connect with a 407, using a persistent
16540 // connection.
16541 MockRead data_reads[] = {
16542 // No credentials.
16543 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
16544 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
mmenkee71e15332015-10-07 16:39:5416545 MockRead("Content-Length: 0\r\n"),
16546 MockRead("Proxy-Connection: keep-alive\r\n\r\n"),
Adam Rice425cf122015-01-19 06:18:2416547
16548 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
16549
16550 MockRead("HTTP/1.1 101 Switching Protocols\r\n"),
16551 MockRead("Upgrade: websocket\r\n"),
16552 MockRead("Connection: Upgrade\r\n"),
16553 MockRead("Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=\r\n\r\n"),
16554 };
16555
16556 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
16557 arraysize(data_writes));
16558 session_deps_.socket_factory->AddSocketDataProvider(&data);
16559 SSLSocketDataProvider ssl(ASYNC, OK);
16560 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
16561
bnc87dcefc2017-05-25 12:47:5816562 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:1916563 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
Adam Rice425cf122015-01-19 06:18:2416564 FakeWebSocketStreamCreateHelper websocket_stream_create_helper;
16565 trans->SetWebSocketHandshakeStreamCreateHelper(
16566 &websocket_stream_create_helper);
16567
16568 {
16569 TestCompletionCallback callback;
16570
tfarina42834112016-09-22 13:38:2016571 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0116572 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
Adam Rice425cf122015-01-19 06:18:2416573
16574 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0116575 EXPECT_THAT(rv, IsOk());
Adam Rice425cf122015-01-19 06:18:2416576 }
16577
16578 const HttpResponseInfo* response = trans->GetResponseInfo();
16579 ASSERT_TRUE(response);
wezca1070932016-05-26 20:30:5216580 ASSERT_TRUE(response->headers);
Adam Rice425cf122015-01-19 06:18:2416581 EXPECT_EQ(407, response->headers->response_code());
16582
16583 {
16584 TestCompletionCallback callback;
16585
16586 int rv = trans->RestartWithAuth(AuthCredentials(kFoo, kBar),
16587 callback.callback());
robpercival214763f2016-07-01 23:27:0116588 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
Adam Rice425cf122015-01-19 06:18:2416589
16590 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0116591 EXPECT_THAT(rv, IsOk());
Adam Rice425cf122015-01-19 06:18:2416592 }
16593
16594 response = trans->GetResponseInfo();
16595 ASSERT_TRUE(response);
wezca1070932016-05-26 20:30:5216596 ASSERT_TRUE(response->headers);
Adam Rice425cf122015-01-19 06:18:2416597
16598 EXPECT_EQ(101, response->headers->response_code());
16599
16600 trans.reset();
16601 session->CloseAllConnections();
16602}
16603
16604// Verify that proxy headers are not sent to the destination server when
16605// establishing a tunnel for an insecure WebSocket connection.
16606// This requires the authentication info to be injected into the auth cache
16607// due to crbug.com/395064
16608// TODO(ricea): Change to use a 407 response once issue 395064 is fixed.
bncd16676a2016-07-20 16:23:0116609TEST_F(HttpNetworkTransactionTest, ProxyHeadersNotSentOverWsTunnel) {
Adam Rice425cf122015-01-19 06:18:2416610 HttpRequestInfo request;
16611 request.method = "GET";
bncce36dca22015-04-21 22:11:2316612 request.url = GURL("ws://www.example.org/");
Adam Rice425cf122015-01-19 06:18:2416613 AddWebSocketHeaders(&request.extra_headers);
16614
16615 // Configure against proxy server "myproxy:70".
rdsmith82957ad2015-09-16 19:42:0316616 session_deps_.proxy_service =
16617 ProxyService::CreateFixedFromPacResult("PROXY myproxy:70");
Adam Rice425cf122015-01-19 06:18:2416618
danakj1fd259a02016-04-16 03:17:0916619 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
Adam Rice425cf122015-01-19 06:18:2416620
16621 MockWrite data_writes[] = {
16622 // Try to establish a tunnel for the WebSocket connection, with
16623 // credentials. Because WebSockets have a separate set of socket pools,
16624 // they cannot and will not use the same TCP/IP connection as the
16625 // preflight HTTP request.
16626 MockWrite(
bncce36dca22015-04-21 22:11:2316627 "CONNECT www.example.org:80 HTTP/1.1\r\n"
16628 "Host: www.example.org:80\r\n"
Adam Rice425cf122015-01-19 06:18:2416629 "Proxy-Connection: keep-alive\r\n"
16630 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
16631
16632 MockWrite(
16633 "GET / HTTP/1.1\r\n"
bncce36dca22015-04-21 22:11:2316634 "Host: www.example.org\r\n"
Adam Rice425cf122015-01-19 06:18:2416635 "Connection: Upgrade\r\n"
16636 "Upgrade: websocket\r\n"
bncce36dca22015-04-21 22:11:2316637 "Origin: http://www.example.org\r\n"
Adam Rice425cf122015-01-19 06:18:2416638 "Sec-WebSocket-Version: 13\r\n"
16639 "Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==\r\n\r\n"),
16640 };
16641
16642 MockRead data_reads[] = {
16643 // HTTP CONNECT with credentials.
16644 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
16645
16646 // WebSocket connection established inside tunnel.
16647 MockRead("HTTP/1.1 101 Switching Protocols\r\n"),
16648 MockRead("Upgrade: websocket\r\n"),
16649 MockRead("Connection: Upgrade\r\n"),
16650 MockRead("Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=\r\n\r\n"),
16651 };
16652
16653 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
16654 arraysize(data_writes));
16655 session_deps_.socket_factory->AddSocketDataProvider(&data);
16656
16657 session->http_auth_cache()->Add(
16658 GURL("http://myproxy:70/"), "MyRealm1", HttpAuth::AUTH_SCHEME_BASIC,
16659 "Basic realm=MyRealm1", AuthCredentials(kFoo, kBar), "/");
16660
bnc87dcefc2017-05-25 12:47:5816661 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:1916662 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
Adam Rice425cf122015-01-19 06:18:2416663 FakeWebSocketStreamCreateHelper websocket_stream_create_helper;
16664 trans->SetWebSocketHandshakeStreamCreateHelper(
16665 &websocket_stream_create_helper);
16666
16667 TestCompletionCallback callback;
16668
tfarina42834112016-09-22 13:38:2016669 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0116670 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
Adam Rice425cf122015-01-19 06:18:2416671
16672 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0116673 EXPECT_THAT(rv, IsOk());
Adam Rice425cf122015-01-19 06:18:2416674
16675 const HttpResponseInfo* response = trans->GetResponseInfo();
16676 ASSERT_TRUE(response);
wezca1070932016-05-26 20:30:5216677 ASSERT_TRUE(response->headers);
Adam Rice425cf122015-01-19 06:18:2416678
16679 EXPECT_EQ(101, response->headers->response_code());
16680
16681 trans.reset();
16682 session->CloseAllConnections();
16683}
16684
bncd16676a2016-07-20 16:23:0116685TEST_F(HttpNetworkTransactionTest, TotalNetworkBytesPost) {
danakj1fd259a02016-04-16 03:17:0916686 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:2216687 element_readers.push_back(
Jeremy Roman0579ed62017-08-29 15:56:1916688 std::make_unique<UploadBytesElementReader>("foo", 3));
olli.raula6df48b2a2015-11-26 07:40:2216689 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
sclittlefb249892015-09-10 21:33:2216690
16691 HttpRequestInfo request;
16692 request.method = "POST";
16693 request.url = GURL("http://www.foo.com/");
16694 request.upload_data_stream = &upload_data_stream;
16695
danakj1fd259a02016-04-16 03:17:0916696 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1616697 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
sclittlefb249892015-09-10 21:33:2216698 MockWrite data_writes[] = {
16699 MockWrite("POST / HTTP/1.1\r\n"
16700 "Host: www.foo.com\r\n"
16701 "Connection: keep-alive\r\n"
16702 "Content-Length: 3\r\n\r\n"),
16703 MockWrite("foo"),
16704 };
16705
16706 MockRead data_reads[] = {
16707 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello world"),
16708 MockRead(SYNCHRONOUS, OK),
16709 };
16710 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
16711 arraysize(data_writes));
16712 session_deps_.socket_factory->AddSocketDataProvider(&data);
16713
16714 TestCompletionCallback callback;
16715
16716 EXPECT_EQ(ERR_IO_PENDING,
tfarina42834112016-09-22 13:38:2016717 trans.Start(&request, callback.callback(), NetLogWithSource()));
robpercival214763f2016-07-01 23:27:0116718 EXPECT_THAT(callback.WaitForResult(), IsOk());
sclittlefb249892015-09-10 21:33:2216719
16720 std::string response_data;
bnc691fda62016-08-12 00:43:1616721 EXPECT_THAT(ReadTransaction(&trans, &response_data), IsOk());
sclittlefb249892015-09-10 21:33:2216722
16723 EXPECT_EQ(CountWriteBytes(data_writes, arraysize(data_writes)),
bnc691fda62016-08-12 00:43:1616724 trans.GetTotalSentBytes());
sclittlefb249892015-09-10 21:33:2216725 EXPECT_EQ(CountReadBytes(data_reads, arraysize(data_reads)),
bnc691fda62016-08-12 00:43:1616726 trans.GetTotalReceivedBytes());
sclittlefb249892015-09-10 21:33:2216727}
16728
bncd16676a2016-07-20 16:23:0116729TEST_F(HttpNetworkTransactionTest, TotalNetworkBytesPost100Continue) {
danakj1fd259a02016-04-16 03:17:0916730 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:2216731 element_readers.push_back(
Jeremy Roman0579ed62017-08-29 15:56:1916732 std::make_unique<UploadBytesElementReader>("foo", 3));
olli.raula6df48b2a2015-11-26 07:40:2216733 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
sclittlefb249892015-09-10 21:33:2216734
16735 HttpRequestInfo request;
16736 request.method = "POST";
16737 request.url = GURL("http://www.foo.com/");
16738 request.upload_data_stream = &upload_data_stream;
16739
danakj1fd259a02016-04-16 03:17:0916740 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1616741 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
sclittlefb249892015-09-10 21:33:2216742 MockWrite data_writes[] = {
16743 MockWrite("POST / HTTP/1.1\r\n"
16744 "Host: www.foo.com\r\n"
16745 "Connection: keep-alive\r\n"
16746 "Content-Length: 3\r\n\r\n"),
16747 MockWrite("foo"),
16748 };
16749
16750 MockRead data_reads[] = {
16751 MockRead("HTTP/1.1 100 Continue\r\n\r\n"),
16752 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello world"),
16753 MockRead(SYNCHRONOUS, OK),
16754 };
16755 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
16756 arraysize(data_writes));
16757 session_deps_.socket_factory->AddSocketDataProvider(&data);
16758
16759 TestCompletionCallback callback;
16760
16761 EXPECT_EQ(ERR_IO_PENDING,
tfarina42834112016-09-22 13:38:2016762 trans.Start(&request, callback.callback(), NetLogWithSource()));
robpercival214763f2016-07-01 23:27:0116763 EXPECT_THAT(callback.WaitForResult(), IsOk());
sclittlefb249892015-09-10 21:33:2216764
16765 std::string response_data;
bnc691fda62016-08-12 00:43:1616766 EXPECT_THAT(ReadTransaction(&trans, &response_data), IsOk());
sclittlefb249892015-09-10 21:33:2216767
16768 EXPECT_EQ(CountWriteBytes(data_writes, arraysize(data_writes)),
bnc691fda62016-08-12 00:43:1616769 trans.GetTotalSentBytes());
sclittlefb249892015-09-10 21:33:2216770 EXPECT_EQ(CountReadBytes(data_reads, arraysize(data_reads)),
bnc691fda62016-08-12 00:43:1616771 trans.GetTotalReceivedBytes());
sclittlefb249892015-09-10 21:33:2216772}
16773
bncd16676a2016-07-20 16:23:0116774TEST_F(HttpNetworkTransactionTest, TotalNetworkBytesChunkedPost) {
sclittlefb249892015-09-10 21:33:2216775 ChunkedUploadDataStream upload_data_stream(0);
16776
16777 HttpRequestInfo request;
16778 request.method = "POST";
16779 request.url = GURL("http://www.foo.com/");
16780 request.upload_data_stream = &upload_data_stream;
16781
danakj1fd259a02016-04-16 03:17:0916782 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1616783 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
sclittlefb249892015-09-10 21:33:2216784 // Send headers successfully, but get an error while sending the body.
16785 MockWrite data_writes[] = {
16786 MockWrite("POST / HTTP/1.1\r\n"
16787 "Host: www.foo.com\r\n"
16788 "Connection: keep-alive\r\n"
16789 "Transfer-Encoding: chunked\r\n\r\n"),
16790 MockWrite("1\r\nf\r\n"), MockWrite("2\r\noo\r\n"), MockWrite("0\r\n\r\n"),
16791 };
16792
16793 MockRead data_reads[] = {
16794 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello world"),
16795 MockRead(SYNCHRONOUS, OK),
16796 };
16797 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
16798 arraysize(data_writes));
16799 session_deps_.socket_factory->AddSocketDataProvider(&data);
16800
16801 TestCompletionCallback callback;
16802
16803 EXPECT_EQ(ERR_IO_PENDING,
tfarina42834112016-09-22 13:38:2016804 trans.Start(&request, callback.callback(), NetLogWithSource()));
sclittlefb249892015-09-10 21:33:2216805
16806 base::RunLoop().RunUntilIdle();
16807 upload_data_stream.AppendData("f", 1, false);
16808
16809 base::RunLoop().RunUntilIdle();
16810 upload_data_stream.AppendData("oo", 2, true);
16811
robpercival214763f2016-07-01 23:27:0116812 EXPECT_THAT(callback.WaitForResult(), IsOk());
sclittlefb249892015-09-10 21:33:2216813
16814 std::string response_data;
bnc691fda62016-08-12 00:43:1616815 EXPECT_THAT(ReadTransaction(&trans, &response_data), IsOk());
sclittlefb249892015-09-10 21:33:2216816
16817 EXPECT_EQ(CountWriteBytes(data_writes, arraysize(data_writes)),
bnc691fda62016-08-12 00:43:1616818 trans.GetTotalSentBytes());
sclittlefb249892015-09-10 21:33:2216819 EXPECT_EQ(CountReadBytes(data_reads, arraysize(data_reads)),
bnc691fda62016-08-12 00:43:1616820 trans.GetTotalReceivedBytes());
sclittlefb249892015-09-10 21:33:2216821}
16822
rdsmith1d343be52016-10-21 20:37:5016823// Confirm that transactions whose throttle is created in (and stays in)
16824// the unthrottled state are not blocked.
16825TEST_F(HttpNetworkTransactionTest, ThrottlingUnthrottled) {
16826 TestNetworkStreamThrottler* throttler(nullptr);
16827 std::unique_ptr<HttpNetworkSession> session(
16828 CreateSessionWithThrottler(&session_deps_, &throttler));
16829
16830 // Send a simple request and make sure it goes through.
16831 HttpRequestInfo request;
16832 request.method = "GET";
16833 request.url = GURL("http://www.example.org/");
16834
bnc87dcefc2017-05-25 12:47:5816835 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:1916836 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
rdsmith1d343be52016-10-21 20:37:5016837
16838 MockWrite data_writes[] = {
16839 MockWrite("GET / HTTP/1.1\r\n"
16840 "Host: www.example.org\r\n"
16841 "Connection: keep-alive\r\n\r\n"),
16842 };
16843 MockRead data_reads[] = {
16844 MockRead("HTTP/1.0 200 OK\r\n\r\n"), MockRead("hello world"),
16845 MockRead(SYNCHRONOUS, OK),
16846 };
16847 StaticSocketDataProvider reads(data_reads, arraysize(data_reads), data_writes,
16848 arraysize(data_writes));
16849 session_deps_.socket_factory->AddSocketDataProvider(&reads);
16850
16851 TestCompletionCallback callback;
16852 trans->Start(&request, callback.callback(), NetLogWithSource());
16853 EXPECT_EQ(OK, callback.WaitForResult());
16854}
16855
16856// Confirm requests can be blocked by a throttler, and are resumed
16857// when the throttle is unblocked.
16858TEST_F(HttpNetworkTransactionTest, ThrottlingBasic) {
16859 TestNetworkStreamThrottler* throttler(nullptr);
16860 std::unique_ptr<HttpNetworkSession> session(
16861 CreateSessionWithThrottler(&session_deps_, &throttler));
16862
16863 // Send a simple request and make sure it goes through.
16864 HttpRequestInfo request;
16865 request.method = "GET";
16866 request.url = GURL("http://www.example.org/");
16867
16868 MockWrite data_writes[] = {
16869 MockWrite("GET / HTTP/1.1\r\n"
16870 "Host: www.example.org\r\n"
16871 "Connection: keep-alive\r\n\r\n"),
16872 };
16873 MockRead data_reads[] = {
16874 MockRead("HTTP/1.0 200 OK\r\n\r\n"), MockRead("hello world"),
16875 MockRead(SYNCHRONOUS, OK),
16876 };
16877 StaticSocketDataProvider reads(data_reads, arraysize(data_reads), data_writes,
16878 arraysize(data_writes));
16879 session_deps_.socket_factory->AddSocketDataProvider(&reads);
16880
16881 // Start a request that will be throttled at start; confirm it
16882 // doesn't complete.
16883 throttler->set_throttle_new_requests(true);
bnc87dcefc2017-05-25 12:47:5816884 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:1916885 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
rdsmith1d343be52016-10-21 20:37:5016886
16887 TestCompletionCallback callback;
16888 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
16889 EXPECT_EQ(ERR_IO_PENDING, rv);
16890
16891 base::RunLoop().RunUntilIdle();
16892 EXPECT_EQ(LOAD_STATE_THROTTLED, trans->GetLoadState());
16893 EXPECT_FALSE(callback.have_result());
16894
16895 // Confirm the request goes on to complete when unthrottled.
16896 throttler->UnthrottleAllRequests();
16897 base::RunLoop().RunUntilIdle();
16898 ASSERT_TRUE(callback.have_result());
16899 EXPECT_EQ(OK, callback.WaitForResult());
16900}
16901
16902// Destroy a request while it's throttled.
16903TEST_F(HttpNetworkTransactionTest, ThrottlingDestruction) {
16904 TestNetworkStreamThrottler* throttler(nullptr);
16905 std::unique_ptr<HttpNetworkSession> session(
16906 CreateSessionWithThrottler(&session_deps_, &throttler));
16907
16908 // Send a simple request and make sure it goes through.
16909 HttpRequestInfo request;
16910 request.method = "GET";
16911 request.url = GURL("http://www.example.org/");
16912
16913 MockWrite data_writes[] = {
16914 MockWrite("GET / HTTP/1.1\r\n"
16915 "Host: www.example.org\r\n"
16916 "Connection: keep-alive\r\n\r\n"),
16917 };
16918 MockRead data_reads[] = {
16919 MockRead("HTTP/1.0 200 OK\r\n\r\n"), MockRead("hello world"),
16920 MockRead(SYNCHRONOUS, OK),
16921 };
16922 StaticSocketDataProvider reads(data_reads, arraysize(data_reads), data_writes,
16923 arraysize(data_writes));
16924 session_deps_.socket_factory->AddSocketDataProvider(&reads);
16925
16926 // Start a request that will be throttled at start; confirm it
16927 // doesn't complete.
16928 throttler->set_throttle_new_requests(true);
bnc87dcefc2017-05-25 12:47:5816929 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:1916930 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
rdsmith1d343be52016-10-21 20:37:5016931
16932 TestCompletionCallback callback;
16933 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
16934 EXPECT_EQ(ERR_IO_PENDING, rv);
16935
16936 base::RunLoop().RunUntilIdle();
16937 EXPECT_EQ(LOAD_STATE_THROTTLED, trans->GetLoadState());
16938 EXPECT_FALSE(callback.have_result());
16939
16940 EXPECT_EQ(1u, throttler->num_outstanding_requests());
16941 trans.reset();
16942 EXPECT_EQ(0u, throttler->num_outstanding_requests());
16943}
16944
16945// Confirm the throttler receives SetPriority calls.
16946TEST_F(HttpNetworkTransactionTest, ThrottlingPrioritySet) {
16947 TestNetworkStreamThrottler* throttler(nullptr);
16948 std::unique_ptr<HttpNetworkSession> session(
16949 CreateSessionWithThrottler(&session_deps_, &throttler));
16950
16951 // Send a simple request and make sure it goes through.
16952 HttpRequestInfo request;
16953 request.method = "GET";
16954 request.url = GURL("http://www.example.org/");
16955
16956 MockWrite data_writes[] = {
16957 MockWrite("GET / HTTP/1.1\r\n"
16958 "Host: www.example.org\r\n"
16959 "Connection: keep-alive\r\n\r\n"),
16960 };
16961 MockRead data_reads[] = {
16962 MockRead("HTTP/1.0 200 OK\r\n\r\n"), MockRead("hello world"),
16963 MockRead(SYNCHRONOUS, OK),
16964 };
16965 StaticSocketDataProvider reads(data_reads, arraysize(data_reads), data_writes,
16966 arraysize(data_writes));
16967 session_deps_.socket_factory->AddSocketDataProvider(&reads);
16968
16969 throttler->set_throttle_new_requests(true);
Jeremy Roman0579ed62017-08-29 15:56:1916970 auto trans = std::make_unique<HttpNetworkTransaction>(IDLE, session.get());
rdsmith1d343be52016-10-21 20:37:5016971 // Start the transaction to associate a throttle with it.
16972 TestCompletionCallback callback;
16973 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
16974 EXPECT_EQ(ERR_IO_PENDING, rv);
16975
16976 EXPECT_EQ(0, throttler->num_set_priority_calls());
16977 trans->SetPriority(LOW);
16978 EXPECT_EQ(1, throttler->num_set_priority_calls());
16979 EXPECT_EQ(LOW, throttler->last_priority_set());
16980
16981 throttler->UnthrottleAllRequests();
16982 base::RunLoop().RunUntilIdle();
16983 ASSERT_TRUE(callback.have_result());
16984 EXPECT_EQ(OK, callback.WaitForResult());
16985}
16986
16987// Confirm that unthrottling from a SetPriority call by the
16988// throttler works properly.
16989TEST_F(HttpNetworkTransactionTest, ThrottlingPrioritySetUnthrottle) {
16990 TestNetworkStreamThrottler* throttler(nullptr);
16991 std::unique_ptr<HttpNetworkSession> session(
16992 CreateSessionWithThrottler(&session_deps_, &throttler));
16993
16994 // Send a simple request and make sure it goes through.
16995 HttpRequestInfo request;
16996 request.method = "GET";
16997 request.url = GURL("http://www.example.org/");
16998
16999 MockWrite data_writes[] = {
17000 MockWrite("GET / HTTP/1.1\r\n"
17001 "Host: www.example.org\r\n"
17002 "Connection: keep-alive\r\n\r\n"),
17003 };
17004 MockRead data_reads[] = {
17005 MockRead("HTTP/1.0 200 OK\r\n\r\n"), MockRead("hello world"),
17006 MockRead(SYNCHRONOUS, OK),
17007 };
17008 StaticSocketDataProvider reads(data_reads, arraysize(data_reads), data_writes,
17009 arraysize(data_writes));
17010 session_deps_.socket_factory->AddSocketDataProvider(&reads);
17011
17012 StaticSocketDataProvider reads1(data_reads, arraysize(data_reads),
17013 data_writes, arraysize(data_writes));
17014 session_deps_.socket_factory->AddSocketDataProvider(&reads1);
17015
17016 // Start a request that will be throttled at start; confirm it
17017 // doesn't complete.
17018 throttler->set_throttle_new_requests(true);
bnc87dcefc2017-05-25 12:47:5817019 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:1917020 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
rdsmith1d343be52016-10-21 20:37:5017021
17022 TestCompletionCallback callback;
17023 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
17024 EXPECT_EQ(ERR_IO_PENDING, rv);
17025
17026 base::RunLoop().RunUntilIdle();
17027 EXPECT_EQ(LOAD_STATE_THROTTLED, trans->GetLoadState());
17028 EXPECT_FALSE(callback.have_result());
17029
17030 // Create a new request, call SetPriority on it to unthrottle,
17031 // and make sure that allows the original request to complete.
Jeremy Roman0579ed62017-08-29 15:56:1917032 auto trans1 = std::make_unique<HttpNetworkTransaction>(LOW, session.get());
rdsmith1d343be52016-10-21 20:37:5017033 throttler->set_priority_change_closure(
17034 base::Bind(&TestNetworkStreamThrottler::UnthrottleAllRequests,
17035 base::Unretained(throttler)));
17036
17037 // Start the transaction to associate a throttle with it.
17038 TestCompletionCallback callback1;
17039 rv = trans1->Start(&request, callback1.callback(), NetLogWithSource());
17040 EXPECT_EQ(ERR_IO_PENDING, rv);
17041
17042 trans1->SetPriority(IDLE);
17043
17044 base::RunLoop().RunUntilIdle();
17045 ASSERT_TRUE(callback.have_result());
17046 EXPECT_EQ(OK, callback.WaitForResult());
17047 ASSERT_TRUE(callback1.have_result());
17048 EXPECT_EQ(OK, callback1.WaitForResult());
17049}
17050
17051// Transaction will be destroyed when the unique_ptr goes out of scope.
bnc87dcefc2017-05-25 12:47:5817052void DestroyTransaction(std::unique_ptr<HttpNetworkTransaction> transaction) {}
rdsmith1d343be52016-10-21 20:37:5017053
17054// Confirm that destroying a transaction from a SetPriority call by the
17055// throttler works properly.
17056TEST_F(HttpNetworkTransactionTest, ThrottlingPrioritySetDestroy) {
17057 TestNetworkStreamThrottler* throttler(nullptr);
17058 std::unique_ptr<HttpNetworkSession> session(
17059 CreateSessionWithThrottler(&session_deps_, &throttler));
17060
17061 // Send a simple request and make sure it goes through.
17062 HttpRequestInfo request;
17063 request.method = "GET";
17064 request.url = GURL("http://www.example.org/");
17065
17066 MockWrite data_writes[] = {
17067 MockWrite("GET / HTTP/1.1\r\n"
17068 "Host: www.example.org\r\n"
17069 "Connection: keep-alive\r\n\r\n"),
17070 };
17071 MockRead data_reads[] = {
17072 MockRead("HTTP/1.0 200 OK\r\n\r\n"), MockRead("hello world"),
17073 MockRead(SYNCHRONOUS, OK),
17074 };
17075 StaticSocketDataProvider reads(data_reads, arraysize(data_reads), data_writes,
17076 arraysize(data_writes));
17077 session_deps_.socket_factory->AddSocketDataProvider(&reads);
17078
17079 StaticSocketDataProvider reads1(data_reads, arraysize(data_reads),
17080 data_writes, arraysize(data_writes));
17081 session_deps_.socket_factory->AddSocketDataProvider(&reads1);
17082
17083 // Start a request that will be throttled at start; confirm it
17084 // doesn't complete.
17085 throttler->set_throttle_new_requests(true);
bnc87dcefc2017-05-25 12:47:5817086 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:1917087 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
rdsmith1d343be52016-10-21 20:37:5017088
17089 TestCompletionCallback callback;
17090 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
17091 EXPECT_EQ(ERR_IO_PENDING, rv);
17092
17093 base::RunLoop().RunUntilIdle();
17094 EXPECT_EQ(LOAD_STATE_THROTTLED, trans->GetLoadState());
17095 EXPECT_FALSE(callback.have_result());
17096
17097 // Arrange for the set priority call on the above transaction to delete
17098 // the transaction.
bnc87dcefc2017-05-25 12:47:5817099 HttpNetworkTransaction* trans_ptr(trans.get());
rdsmith1d343be52016-10-21 20:37:5017100 throttler->set_priority_change_closure(
17101 base::Bind(&DestroyTransaction, base::Passed(&trans)));
17102
17103 // Call it and check results (partially a "doesn't crash" test).
17104 trans_ptr->SetPriority(IDLE);
17105 trans_ptr = nullptr; // No longer a valid pointer.
17106
17107 base::RunLoop().RunUntilIdle();
17108 ASSERT_FALSE(callback.have_result());
17109}
17110
nharperb7441ef2016-01-25 23:54:1417111#if !defined(OS_IOS)
bncd16676a2016-07-20 16:23:0117112TEST_F(HttpNetworkTransactionTest, TokenBindingSpdy) {
nharperb7441ef2016-01-25 23:54:1417113 const std::string https_url = "https://www.example.com";
17114 HttpRequestInfo request;
17115 request.url = GURL(https_url);
17116 request.method = "GET";
17117
17118 SSLSocketDataProvider ssl(ASYNC, OK);
17119 ssl.token_binding_negotiated = true;
17120 ssl.token_binding_key_param = TB_PARAM_ECDSAP256;
bnc3cf2a592016-08-11 14:48:3617121 ssl.next_proto = kProtoHTTP2;
nharperb7441ef2016-01-25 23:54:1417122 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
17123
bnc42331402016-07-25 13:36:1517124 SpdySerializedFrame resp(spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
bncdf80d44fd2016-07-15 20:27:4117125 SpdySerializedFrame body(spdy_util_.ConstructSpdyDataFrame(1, true));
17126 MockRead reads[] = {CreateMockRead(resp), CreateMockRead(body),
nharperb7441ef2016-01-25 23:54:1417127 MockRead(ASYNC, ERR_IO_PENDING)};
17128 StaticSocketDataProvider data(reads, arraysize(reads), nullptr, 0);
17129 session_deps_.socket_factory->AddSocketDataProvider(&data);
bnc87dcefc2017-05-25 12:47:5817130 session_deps_.channel_id_service =
Jeremy Roman0579ed62017-08-29 15:56:1917131 std::make_unique<ChannelIDService>(new DefaultChannelIDStore(nullptr));
danakj1fd259a02016-04-16 03:17:0917132 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
nharperb7441ef2016-01-25 23:54:1417133
17134 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
17135 TestCompletionCallback callback;
17136 EXPECT_EQ(ERR_IO_PENDING,
tfarina42834112016-09-22 13:38:2017137 trans.Start(&request, callback.callback(), NetLogWithSource()));
fdorayf33fede2017-05-11 21:18:1017138
17139 NetTestSuite::GetScopedTaskEnvironment()->RunUntilIdle();
nharperb7441ef2016-01-25 23:54:1417140
17141 EXPECT_TRUE(trans.GetResponseInfo()->was_fetched_via_spdy);
17142 HttpRequestHeaders headers;
17143 ASSERT_TRUE(trans.GetFullRequestHeaders(&headers));
17144 EXPECT_TRUE(headers.HasHeader(HttpRequestHeaders::kTokenBinding));
17145}
17146#endif // !defined(OS_IOS)
17147
eustasc7d27da2017-04-06 10:33:2017148void CheckContentEncodingMatching(SpdySessionDependencies* session_deps,
17149 const std::string& accept_encoding,
17150 const std::string& content_encoding,
sky50576f32017-05-01 19:28:0317151 const std::string& location,
eustasc7d27da2017-04-06 10:33:2017152 bool should_match) {
17153 HttpRequestInfo request;
17154 request.method = "GET";
17155 request.url = GURL("http://www.foo.com/");
17156 request.extra_headers.SetHeader(HttpRequestHeaders::kAcceptEncoding,
17157 accept_encoding);
17158
17159 std::unique_ptr<HttpNetworkSession> session(CreateSession(session_deps));
17160 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
17161 // Send headers successfully, but get an error while sending the body.
17162 MockWrite data_writes[] = {
17163 MockWrite("GET / HTTP/1.1\r\n"
17164 "Host: www.foo.com\r\n"
17165 "Connection: keep-alive\r\n"
17166 "Accept-Encoding: "),
17167 MockWrite(accept_encoding.data()), MockWrite("\r\n\r\n"),
17168 };
17169
sky50576f32017-05-01 19:28:0317170 std::string response_code = "200 OK";
17171 std::string extra;
17172 if (!location.empty()) {
17173 response_code = "301 Redirect\r\nLocation: ";
17174 response_code.append(location);
17175 }
17176
eustasc7d27da2017-04-06 10:33:2017177 MockRead data_reads[] = {
sky50576f32017-05-01 19:28:0317178 MockRead("HTTP/1.0 "),
17179 MockRead(response_code.data()),
17180 MockRead("\r\nContent-Encoding: "),
17181 MockRead(content_encoding.data()),
17182 MockRead("\r\n\r\n"),
eustasc7d27da2017-04-06 10:33:2017183 MockRead(SYNCHRONOUS, OK),
17184 };
17185 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
17186 arraysize(data_writes));
17187 session_deps->socket_factory->AddSocketDataProvider(&data);
17188
17189 TestCompletionCallback callback;
17190
17191 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
17192 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
17193
17194 rv = callback.WaitForResult();
17195 if (should_match) {
17196 EXPECT_THAT(rv, IsOk());
17197 } else {
17198 EXPECT_THAT(rv, IsError(ERR_CONTENT_DECODING_FAILED));
17199 }
17200}
17201
17202TEST_F(HttpNetworkTransactionTest, MatchContentEncoding1) {
sky50576f32017-05-01 19:28:0317203 CheckContentEncodingMatching(&session_deps_, "gzip,sdch", "br", "", false);
eustasc7d27da2017-04-06 10:33:2017204}
17205
17206TEST_F(HttpNetworkTransactionTest, MatchContentEncoding2) {
sky50576f32017-05-01 19:28:0317207 CheckContentEncodingMatching(&session_deps_, "identity;q=1, *;q=0", "", "",
17208 true);
eustasc7d27da2017-04-06 10:33:2017209}
17210
17211TEST_F(HttpNetworkTransactionTest, MatchContentEncoding3) {
17212 CheckContentEncodingMatching(&session_deps_, "identity;q=1, *;q=0", "gzip",
sky50576f32017-05-01 19:28:0317213 "", false);
17214}
17215
17216TEST_F(HttpNetworkTransactionTest, MatchContentEncoding4) {
17217 CheckContentEncodingMatching(&session_deps_, "identity;q=1, *;q=0", "gzip",
17218 "www.foo.com/other", true);
eustasc7d27da2017-04-06 10:33:2017219}
17220
xunjieli96f2a402017-06-05 17:24:2717221TEST_F(HttpNetworkTransactionTest, ProxyResolutionFailsSync) {
17222 ProxyConfig proxy_config;
17223 proxy_config.set_pac_url(GURL("http://fooproxyurl"));
17224 proxy_config.set_pac_mandatory(true);
17225 MockAsyncProxyResolver resolver;
17226 session_deps_.proxy_service.reset(new ProxyService(
Jeremy Roman0579ed62017-08-29 15:56:1917227 std::make_unique<ProxyConfigServiceFixed>(proxy_config),
Bence Béky8f9d7d3952017-10-09 19:58:0417228 std::make_unique<FailingProxyResolverFactory>(), nullptr));
xunjieli96f2a402017-06-05 17:24:2717229
17230 HttpRequestInfo request;
17231 request.method = "GET";
17232 request.url = GURL("http://www.example.org/");
17233
17234 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
17235 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
17236
17237 TestCompletionCallback callback;
17238
17239 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
17240 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
17241 EXPECT_THAT(callback.WaitForResult(),
17242 IsError(ERR_MANDATORY_PROXY_CONFIGURATION_FAILED));
17243}
17244
17245TEST_F(HttpNetworkTransactionTest, ProxyResolutionFailsAsync) {
17246 ProxyConfig proxy_config;
17247 proxy_config.set_pac_url(GURL("http://fooproxyurl"));
17248 proxy_config.set_pac_mandatory(true);
17249 MockAsyncProxyResolverFactory* proxy_resolver_factory =
17250 new MockAsyncProxyResolverFactory(false);
17251 MockAsyncProxyResolver resolver;
17252 session_deps_.proxy_service.reset(
Jeremy Roman0579ed62017-08-29 15:56:1917253 new ProxyService(std::make_unique<ProxyConfigServiceFixed>(proxy_config),
xunjieli96f2a402017-06-05 17:24:2717254 base::WrapUnique(proxy_resolver_factory), nullptr));
17255 HttpRequestInfo request;
17256 request.method = "GET";
17257 request.url = GURL("http://www.example.org/");
17258
17259 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
17260 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
17261
17262 TestCompletionCallback callback;
17263 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
17264 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
17265
17266 proxy_resolver_factory->pending_requests()[0]->CompleteNowWithForwarder(
17267 ERR_FAILED, &resolver);
17268 EXPECT_THAT(callback.WaitForResult(),
17269 IsError(ERR_MANDATORY_PROXY_CONFIGURATION_FAILED));
17270}
17271
17272TEST_F(HttpNetworkTransactionTest, NoSupportedProxies) {
17273 session_deps_.proxy_service =
17274 ProxyService::CreateFixedFromPacResult("QUIC myproxy.org:443");
17275 session_deps_.enable_quic = false;
17276 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
17277
17278 HttpRequestInfo request;
17279 request.method = "GET";
17280 request.url = GURL("http://www.example.org/");
17281
17282 TestCompletionCallback callback;
17283 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
17284 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
17285 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
17286
17287 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_NO_SUPPORTED_PROXIES));
17288}
17289
[email protected]89ceba9a2009-03-21 03:46:0617290} // namespace net