blob: 6acdc024630f29a155cc2ef9adab0dd4d151da93 [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
robpercival214763f2016-07-01 23:27:01106using net::test::IsError;
107using net::test::IsOk;
108
[email protected]ad65a3e2013-12-25 18:18:01109using base::ASCIIToUTF16;
110
initial.commit586acc5fe2008-07-26 22:42:52111//-----------------------------------------------------------------------------
112
ttuttle859dc7a2015-04-23 19:42:29113namespace net {
114
[email protected]13c8a092010-07-29 06:15:44115namespace {
116
rdsmith1d343be52016-10-21 20:37:50117class TestNetworkStreamThrottler : public NetworkThrottleManager {
118 public:
119 TestNetworkStreamThrottler()
120 : throttle_new_requests_(false),
121 num_set_priority_calls_(0),
122 last_priority_set_(IDLE) {}
123
124 ~TestNetworkStreamThrottler() override {
125 EXPECT_TRUE(outstanding_throttles_.empty());
126 }
127
128 // NetworkThrottleManager
129 std::unique_ptr<Throttle> CreateThrottle(ThrottleDelegate* delegate,
130 RequestPriority priority,
131 bool ignore_limits) override {
bnc87dcefc2017-05-25 12:47:58132 auto test_throttle =
Jeremy Roman0579ed62017-08-29 15:56:19133 std::make_unique<TestThrottle>(throttle_new_requests_, delegate, this);
rdsmith1d343be52016-10-21 20:37:50134 outstanding_throttles_.insert(test_throttle.get());
135 return std::move(test_throttle);
136 }
137
138 void UnthrottleAllRequests() {
139 std::set<TestThrottle*> outstanding_throttles_copy(outstanding_throttles_);
vmpstr6d9996c82017-02-23 00:43:25140 for (auto* throttle : outstanding_throttles_copy) {
rdsmithbf8c3c12016-11-18 18:16:24141 if (throttle->IsBlocked())
rdsmith1d343be52016-10-21 20:37:50142 throttle->Unthrottle();
143 }
144 }
145
146 void set_throttle_new_requests(bool throttle_new_requests) {
147 throttle_new_requests_ = throttle_new_requests;
148 }
149
150 // Includes both throttled and unthrottled throttles.
151 size_t num_outstanding_requests() const {
152 return outstanding_throttles_.size();
153 }
154
155 int num_set_priority_calls() const { return num_set_priority_calls_; }
156 RequestPriority last_priority_set() const { return last_priority_set_; }
157 void set_priority_change_closure(
158 const base::Closure& priority_change_closure) {
159 priority_change_closure_ = priority_change_closure;
160 }
161
162 private:
163 class TestThrottle : public NetworkThrottleManager::Throttle {
164 public:
165 ~TestThrottle() override { throttler_->OnThrottleDestroyed(this); }
166
167 // Throttle
rdsmithbf8c3c12016-11-18 18:16:24168 bool IsBlocked() const override { return throttled_; }
169 RequestPriority Priority() const override {
170 NOTREACHED();
171 return IDLE;
172 }
rdsmith1d343be52016-10-21 20:37:50173 void SetPriority(RequestPriority priority) override {
174 throttler_->SetPriorityCalled(priority);
175 }
176
177 TestThrottle(bool throttled,
178 ThrottleDelegate* delegate,
179 TestNetworkStreamThrottler* throttler)
180 : throttled_(throttled), delegate_(delegate), throttler_(throttler) {}
181
182 void Unthrottle() {
183 EXPECT_TRUE(throttled_);
184
185 throttled_ = false;
rdsmithbf8c3c12016-11-18 18:16:24186 delegate_->OnThrottleUnblocked(this);
rdsmith1d343be52016-10-21 20:37:50187 }
188
189 bool throttled_;
190 ThrottleDelegate* delegate_;
191 TestNetworkStreamThrottler* throttler_;
192 };
193
194 void OnThrottleDestroyed(TestThrottle* throttle) {
195 EXPECT_NE(0u, outstanding_throttles_.count(throttle));
196 outstanding_throttles_.erase(throttle);
197 }
198
199 void SetPriorityCalled(RequestPriority priority) {
200 ++num_set_priority_calls_;
201 last_priority_set_ = priority;
202 if (!priority_change_closure_.is_null())
203 priority_change_closure_.Run();
204 }
205
206 // Includes both throttled and unthrottled throttles.
207 std::set<TestThrottle*> outstanding_throttles_;
208 bool throttle_new_requests_;
209 int num_set_priority_calls_;
210 RequestPriority last_priority_set_;
211 base::Closure priority_change_closure_;
212
213 DISALLOW_COPY_AND_ASSIGN(TestNetworkStreamThrottler);
214};
215
[email protected]42cba2fb2013-03-29 19:58:57216const base::string16 kBar(ASCIIToUTF16("bar"));
217const base::string16 kBar2(ASCIIToUTF16("bar2"));
218const base::string16 kBar3(ASCIIToUTF16("bar3"));
219const base::string16 kBaz(ASCIIToUTF16("baz"));
220const base::string16 kFirst(ASCIIToUTF16("first"));
221const base::string16 kFoo(ASCIIToUTF16("foo"));
222const base::string16 kFoo2(ASCIIToUTF16("foo2"));
223const base::string16 kFoo3(ASCIIToUTF16("foo3"));
224const base::string16 kFou(ASCIIToUTF16("fou"));
225const base::string16 kSecond(ASCIIToUTF16("second"));
226const base::string16 kTestingNTLM(ASCIIToUTF16("testing-ntlm"));
227const base::string16 kWrongPassword(ASCIIToUTF16("wrongpassword"));
[email protected]13c8a092010-07-29 06:15:44228
bnc2df4b522016-07-08 18:17:43229const char kAlternativeServiceHttpHeader[] =
230 "Alt-Svc: h2=\"mail.example.org:443\"\r\n";
231
ttuttle859dc7a2015-04-23 19:42:29232int GetIdleSocketCountInTransportSocketPool(HttpNetworkSession* session) {
233 return session->GetTransportSocketPool(HttpNetworkSession::NORMAL_SOCKET_POOL)
234 ->IdleSocketCount();
[email protected]e5c026642012-03-17 00:14:02235}
236
ttuttle859dc7a2015-04-23 19:42:29237int GetIdleSocketCountInSSLSocketPool(HttpNetworkSession* session) {
238 return session->GetSSLSocketPool(HttpNetworkSession::NORMAL_SOCKET_POOL)
239 ->IdleSocketCount();
[email protected]e5c026642012-03-17 00:14:02240}
241
ttuttle859dc7a2015-04-23 19:42:29242bool IsTransportSocketPoolStalled(HttpNetworkSession* session) {
243 return session->GetTransportSocketPool(HttpNetworkSession::NORMAL_SOCKET_POOL)
244 ->IsStalled();
[email protected]043b68c82013-08-22 23:41:52245}
246
[email protected]f3da152d2012-06-02 01:00:57247// Takes in a Value created from a NetLogHttpResponseParameter, and returns
248// a JSONified list of headers as a single string. Uses single quotes instead
249// of double quotes for easier comparison. Returns false on failure.
[email protected]ea5ef4c2013-06-13 22:50:27250bool GetHeaders(base::DictionaryValue* params, std::string* headers) {
[email protected]f3da152d2012-06-02 01:00:57251 if (!params)
252 return false;
[email protected]ea5ef4c2013-06-13 22:50:27253 base::ListValue* header_list;
[email protected]f3da152d2012-06-02 01:00:57254 if (!params->GetList("headers", &header_list))
255 return false;
256 std::string double_quote_headers;
estade8d046462015-05-16 01:02:34257 base::JSONWriter::Write(*header_list, &double_quote_headers);
[email protected]466c9862013-12-03 22:05:28258 base::ReplaceChars(double_quote_headers, "\"", "'", headers);
[email protected]f3da152d2012-06-02 01:00:57259 return true;
260}
261
[email protected]029c83b62013-01-24 05:28:20262// Tests LoadTimingInfo in the case a socket is reused and no PAC script is
263// used.
ttuttle859dc7a2015-04-23 19:42:29264void TestLoadTimingReused(const LoadTimingInfo& load_timing_info) {
[email protected]029c83b62013-01-24 05:28:20265 EXPECT_TRUE(load_timing_info.socket_reused);
mikecironef22f9812016-10-04 03:40:19266 EXPECT_NE(NetLogSource::kInvalidId, load_timing_info.socket_log_id);
[email protected]58e32bb2013-01-21 18:23:25267
[email protected]029c83b62013-01-24 05:28:20268 EXPECT_TRUE(load_timing_info.proxy_resolve_start.is_null());
269 EXPECT_TRUE(load_timing_info.proxy_resolve_end.is_null());
270
ttuttle859dc7a2015-04-23 19:42:29271 ExpectConnectTimingHasNoTimes(load_timing_info.connect_timing);
[email protected]029c83b62013-01-24 05:28:20272 EXPECT_FALSE(load_timing_info.send_start.is_null());
[email protected]58e32bb2013-01-21 18:23:25273
274 EXPECT_LE(load_timing_info.send_start, load_timing_info.send_end);
[email protected]58e32bb2013-01-21 18:23:25275
[email protected]3b23a222013-05-15 21:33:25276 // Set at a higher level.
[email protected]58e32bb2013-01-21 18:23:25277 EXPECT_TRUE(load_timing_info.request_start_time.is_null());
278 EXPECT_TRUE(load_timing_info.request_start.is_null());
[email protected]3b23a222013-05-15 21:33:25279 EXPECT_TRUE(load_timing_info.receive_headers_end.is_null());
[email protected]58e32bb2013-01-21 18:23:25280}
281
[email protected]029c83b62013-01-24 05:28:20282// Tests LoadTimingInfo in the case a new socket is used and no PAC script is
283// used.
ttuttle859dc7a2015-04-23 19:42:29284void TestLoadTimingNotReused(const LoadTimingInfo& load_timing_info,
[email protected]58e32bb2013-01-21 18:23:25285 int connect_timing_flags) {
[email protected]029c83b62013-01-24 05:28:20286 EXPECT_FALSE(load_timing_info.socket_reused);
mikecironef22f9812016-10-04 03:40:19287 EXPECT_NE(NetLogSource::kInvalidId, load_timing_info.socket_log_id);
[email protected]029c83b62013-01-24 05:28:20288
289 EXPECT_TRUE(load_timing_info.proxy_resolve_start.is_null());
290 EXPECT_TRUE(load_timing_info.proxy_resolve_end.is_null());
291
ttuttle859dc7a2015-04-23 19:42:29292 ExpectConnectTimingHasTimes(load_timing_info.connect_timing,
293 connect_timing_flags);
[email protected]029c83b62013-01-24 05:28:20294 EXPECT_LE(load_timing_info.connect_timing.connect_end,
295 load_timing_info.send_start);
296
297 EXPECT_LE(load_timing_info.send_start, load_timing_info.send_end);
[email protected]029c83b62013-01-24 05:28:20298
[email protected]3b23a222013-05-15 21:33:25299 // Set at a higher level.
[email protected]029c83b62013-01-24 05:28:20300 EXPECT_TRUE(load_timing_info.request_start_time.is_null());
301 EXPECT_TRUE(load_timing_info.request_start.is_null());
[email protected]3b23a222013-05-15 21:33:25302 EXPECT_TRUE(load_timing_info.receive_headers_end.is_null());
[email protected]029c83b62013-01-24 05:28:20303}
304
305// Tests LoadTimingInfo in the case a socket is reused and a PAC script is
306// used.
ttuttle859dc7a2015-04-23 19:42:29307void TestLoadTimingReusedWithPac(const LoadTimingInfo& load_timing_info) {
[email protected]029c83b62013-01-24 05:28:20308 EXPECT_TRUE(load_timing_info.socket_reused);
mikecironef22f9812016-10-04 03:40:19309 EXPECT_NE(NetLogSource::kInvalidId, load_timing_info.socket_log_id);
[email protected]029c83b62013-01-24 05:28:20310
ttuttle859dc7a2015-04-23 19:42:29311 ExpectConnectTimingHasNoTimes(load_timing_info.connect_timing);
[email protected]029c83b62013-01-24 05:28:20312
313 EXPECT_FALSE(load_timing_info.proxy_resolve_start.is_null());
314 EXPECT_LE(load_timing_info.proxy_resolve_start,
315 load_timing_info.proxy_resolve_end);
316 EXPECT_LE(load_timing_info.proxy_resolve_end,
317 load_timing_info.send_start);
318 EXPECT_LE(load_timing_info.send_start, load_timing_info.send_end);
[email protected]029c83b62013-01-24 05:28:20319
[email protected]3b23a222013-05-15 21:33:25320 // Set at a higher level.
[email protected]029c83b62013-01-24 05:28:20321 EXPECT_TRUE(load_timing_info.request_start_time.is_null());
322 EXPECT_TRUE(load_timing_info.request_start.is_null());
[email protected]3b23a222013-05-15 21:33:25323 EXPECT_TRUE(load_timing_info.receive_headers_end.is_null());
[email protected]029c83b62013-01-24 05:28:20324}
325
326// Tests LoadTimingInfo in the case a new socket is used and a PAC script is
327// used.
ttuttle859dc7a2015-04-23 19:42:29328void TestLoadTimingNotReusedWithPac(const LoadTimingInfo& load_timing_info,
[email protected]029c83b62013-01-24 05:28:20329 int connect_timing_flags) {
330 EXPECT_FALSE(load_timing_info.socket_reused);
mikecironef22f9812016-10-04 03:40:19331 EXPECT_NE(NetLogSource::kInvalidId, load_timing_info.socket_log_id);
[email protected]029c83b62013-01-24 05:28:20332
333 EXPECT_FALSE(load_timing_info.proxy_resolve_start.is_null());
334 EXPECT_LE(load_timing_info.proxy_resolve_start,
335 load_timing_info.proxy_resolve_end);
336 EXPECT_LE(load_timing_info.proxy_resolve_end,
337 load_timing_info.connect_timing.connect_start);
ttuttle859dc7a2015-04-23 19:42:29338 ExpectConnectTimingHasTimes(load_timing_info.connect_timing,
339 connect_timing_flags);
[email protected]029c83b62013-01-24 05:28:20340 EXPECT_LE(load_timing_info.connect_timing.connect_end,
341 load_timing_info.send_start);
342
343 EXPECT_LE(load_timing_info.send_start, load_timing_info.send_end);
[email protected]029c83b62013-01-24 05:28:20344
[email protected]3b23a222013-05-15 21:33:25345 // Set at a higher level.
[email protected]029c83b62013-01-24 05:28:20346 EXPECT_TRUE(load_timing_info.request_start_time.is_null());
347 EXPECT_TRUE(load_timing_info.request_start.is_null());
[email protected]3b23a222013-05-15 21:33:25348 EXPECT_TRUE(load_timing_info.receive_headers_end.is_null());
[email protected]58e32bb2013-01-21 18:23:25349}
350
ttuttle859dc7a2015-04-23 19:42:29351void AddWebSocketHeaders(HttpRequestHeaders* headers) {
Adam Rice425cf122015-01-19 06:18:24352 headers->SetHeader("Connection", "Upgrade");
353 headers->SetHeader("Upgrade", "websocket");
bncce36dca22015-04-21 22:11:23354 headers->SetHeader("Origin", "http://www.example.org");
Adam Rice425cf122015-01-19 06:18:24355 headers->SetHeader("Sec-WebSocket-Version", "13");
356 headers->SetHeader("Sec-WebSocket-Key", "dGhlIHNhbXBsZSBub25jZQ==");
357}
358
danakj1fd259a02016-04-16 03:17:09359std::unique_ptr<HttpNetworkSession> CreateSession(
mmenkee65e7af2015-10-13 17:16:42360 SpdySessionDependencies* session_deps) {
[email protected]c6bf8152012-12-02 07:43:34361 return SpdySessionDependencies::SpdyCreateSession(session_deps);
[email protected]e8d536192008-10-17 22:21:14362}
363
rdsmith1d343be52016-10-21 20:37:50364// Note that the pointer written into |*throttler| will only be valid
365// for the lifetime of the returned HttpNetworkSession.
366std::unique_ptr<HttpNetworkSession> CreateSessionWithThrottler(
367 SpdySessionDependencies* session_deps,
368 TestNetworkStreamThrottler** throttler) {
369 std::unique_ptr<HttpNetworkSession> session(
370 SpdySessionDependencies::SpdyCreateSession(session_deps));
371
Jeremy Roman0579ed62017-08-29 15:56:19372 auto owned_throttler = std::make_unique<TestNetworkStreamThrottler>();
rdsmith1d343be52016-10-21 20:37:50373 *throttler = owned_throttler.get();
374
375 HttpNetworkSessionPeer peer(session.get());
376 peer.SetNetworkStreamThrottler(std::move(owned_throttler));
377
378 return session;
379}
380
xunjieli96f2a402017-06-05 17:24:27381class FailingProxyResolverFactory : public ProxyResolverFactory {
382 public:
383 FailingProxyResolverFactory() : ProxyResolverFactory(false) {}
384
385 // ProxyResolverFactory override.
386 int CreateProxyResolver(
387 const scoped_refptr<ProxyResolverScriptData>& script_data,
388 std::unique_ptr<ProxyResolver>* result,
389 const CompletionCallback& callback,
390 std::unique_ptr<Request>* request) override {
391 return ERR_PAC_SCRIPT_FAILED;
392 }
393};
394
[email protected]448d4ca52012-03-04 04:12:23395} // namespace
396
bncd16676a2016-07-20 16:23:01397class HttpNetworkTransactionTest : public PlatformTest {
[email protected]483fa202013-05-14 01:07:03398 public:
bncd16676a2016-07-20 16:23:01399 ~HttpNetworkTransactionTest() override {
[email protected]483fa202013-05-14 01:07:03400 // Important to restore the per-pool limit first, since the pool limit must
401 // always be greater than group limit, and the tests reduce both limits.
402 ClientSocketPoolManager::set_max_sockets_per_pool(
403 HttpNetworkSession::NORMAL_SOCKET_POOL, old_max_pool_sockets_);
404 ClientSocketPoolManager::set_max_sockets_per_group(
405 HttpNetworkSession::NORMAL_SOCKET_POOL, old_max_group_sockets_);
406 }
407
[email protected]e3ceb682011-06-28 23:55:46408 protected:
[email protected]23e482282013-06-14 16:08:02409 HttpNetworkTransactionTest()
bnc032658ba2016-09-26 18:17:15410 : ssl_(ASYNC, OK),
411 old_max_group_sockets_(ClientSocketPoolManager::max_sockets_per_group(
[email protected]483fa202013-05-14 01:07:03412 HttpNetworkSession::NORMAL_SOCKET_POOL)),
413 old_max_pool_sockets_(ClientSocketPoolManager::max_sockets_per_pool(
414 HttpNetworkSession::NORMAL_SOCKET_POOL)) {
bnca86731e2017-04-17 12:31:28415 session_deps_.enable_http2_alternative_service = true;
[email protected]483fa202013-05-14 01:07:03416 }
[email protected]bb88e1d32013-05-03 23:11:07417
[email protected]e3ceb682011-06-28 23:55:46418 struct SimpleGetHelperResult {
419 int rv;
420 std::string status_line;
421 std::string response_data;
sclittlefb249892015-09-10 21:33:22422 int64_t total_received_bytes;
423 int64_t total_sent_bytes;
[email protected]58e32bb2013-01-21 18:23:25424 LoadTimingInfo load_timing_info;
ttuttle1f2d7e92015-04-28 16:17:47425 ConnectionAttempts connection_attempts;
ttuttled9dbc652015-09-29 20:00:59426 IPEndPoint remote_endpoint_after_start;
[email protected]e3ceb682011-06-28 23:55:46427 };
428
dcheng67be2b1f2014-10-27 21:47:29429 void SetUp() override {
[email protected]0b0bf032010-09-21 18:08:50430 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
fdoray92e35a72016-06-10 15:54:55431 base::RunLoop().RunUntilIdle();
[email protected]2ff8b312010-04-26 22:20:54432 }
433
dcheng67be2b1f2014-10-27 21:47:29434 void TearDown() override {
[email protected]0b0bf032010-09-21 18:08:50435 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
fdoray92e35a72016-06-10 15:54:55436 base::RunLoop().RunUntilIdle();
[email protected]0e75a732008-10-16 20:36:09437 // Empty the current queue.
fdoray92e35a72016-06-10 15:54:55438 base::RunLoop().RunUntilIdle();
[email protected]0e75a732008-10-16 20:36:09439 PlatformTest::TearDown();
[email protected]0b0bf032010-09-21 18:08:50440 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
fdoray92e35a72016-06-10 15:54:55441 base::RunLoop().RunUntilIdle();
[email protected]0e75a732008-10-16 20:36:09442 }
443
[email protected]202965992011-12-07 23:04:51444 // Either |write_failure| specifies a write failure or |read_failure|
445 // specifies a read failure when using a reused socket. In either case, the
446 // failure should cause the network transaction to resend the request, and the
447 // other argument should be NULL.
448 void KeepAliveConnectionResendRequestTest(const MockWrite* write_failure,
449 const MockRead* read_failure);
initial.commit586acc5fe2008-07-26 22:42:52450
[email protected]a34f61ee2014-03-18 20:59:49451 // Either |write_failure| specifies a write failure or |read_failure|
452 // specifies a read failure when using a reused socket. In either case, the
453 // failure should cause the network transaction to resend the request, and the
454 // other argument should be NULL.
455 void PreconnectErrorResendRequestTest(const MockWrite* write_failure,
[email protected]09356c652014-03-25 15:36:10456 const MockRead* read_failure,
457 bool use_spdy);
[email protected]a34f61ee2014-03-18 20:59:49458
[email protected]5a60c8b2011-10-19 20:14:29459 SimpleGetHelperResult SimpleGetHelperForData(StaticSocketDataProvider* data[],
460 size_t data_count) {
[email protected]ff007e162009-05-23 09:13:15461 SimpleGetHelperResult out;
initial.commit586acc5fe2008-07-26 22:42:52462
[email protected]ff007e162009-05-23 09:13:15463 HttpRequestInfo request;
464 request.method = "GET";
bncce36dca22015-04-21 22:11:23465 request.url = GURL("http://www.example.org/");
initial.commit586acc5fe2008-07-26 22:42:52466
vishal.b62985ca92015-04-17 08:45:51467 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:07468 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:09469 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:16470 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:27471
[email protected]5a60c8b2011-10-19 20:14:29472 for (size_t i = 0; i < data_count; ++i) {
[email protected]bb88e1d32013-05-03 23:11:07473 session_deps_.socket_factory->AddSocketDataProvider(data[i]);
[email protected]5a60c8b2011-10-19 20:14:29474 }
initial.commit586acc5fe2008-07-26 22:42:52475
[email protected]49639fa2011-12-20 23:22:41476 TestCompletionCallback callback;
initial.commit586acc5fe2008-07-26 22:42:52477
eroman24bc6a12015-05-06 19:55:48478 EXPECT_TRUE(log.bound().IsCapturing());
bnc691fda62016-08-12 00:43:16479 int rv = trans.Start(&request, callback.callback(), log.bound());
robpercival214763f2016-07-01 23:27:01480 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
initial.commit586acc5fe2008-07-26 22:42:52481
[email protected]ff007e162009-05-23 09:13:15482 out.rv = callback.WaitForResult();
bnc691fda62016-08-12 00:43:16483 out.total_received_bytes = trans.GetTotalReceivedBytes();
484 out.total_sent_bytes = trans.GetTotalSentBytes();
[email protected]58e32bb2013-01-21 18:23:25485
486 // Even in the failure cases that use this function, connections are always
487 // successfully established before the error.
bnc691fda62016-08-12 00:43:16488 EXPECT_TRUE(trans.GetLoadTimingInfo(&out.load_timing_info));
[email protected]58e32bb2013-01-21 18:23:25489 TestLoadTimingNotReused(out.load_timing_info, CONNECT_TIMING_HAS_DNS_TIMES);
490
[email protected]ff007e162009-05-23 09:13:15491 if (out.rv != OK)
492 return out;
493
bnc691fda62016-08-12 00:43:16494 const HttpResponseInfo* response = trans.GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:50495 // Can't use ASSERT_* inside helper functions like this, so
496 // return an error.
wezca1070932016-05-26 20:30:52497 if (!response || !response->headers) {
[email protected]fe2255a2011-09-20 19:37:50498 out.rv = ERR_UNEXPECTED;
499 return out;
500 }
[email protected]ff007e162009-05-23 09:13:15501 out.status_line = response->headers->GetStatusLine();
502
[email protected]80a09a82012-11-16 17:40:06503 EXPECT_EQ("127.0.0.1", response->socket_address.host());
504 EXPECT_EQ(80, response->socket_address.port());
[email protected]6d81b482011-02-22 19:47:19505
ttuttled9dbc652015-09-29 20:00:59506 bool got_endpoint =
bnc691fda62016-08-12 00:43:16507 trans.GetRemoteEndpoint(&out.remote_endpoint_after_start);
ttuttled9dbc652015-09-29 20:00:59508 EXPECT_EQ(got_endpoint,
509 out.remote_endpoint_after_start.address().size() > 0);
510
bnc691fda62016-08-12 00:43:16511 rv = ReadTransaction(&trans, &out.response_data);
robpercival214763f2016-07-01 23:27:01512 EXPECT_THAT(rv, IsOk());
[email protected]b2fcd0e2010-12-01 15:19:40513
mmenke43758e62015-05-04 21:09:46514 TestNetLogEntry::List entries;
[email protected]b2fcd0e2010-12-01 15:19:40515 log.GetEntries(&entries);
[email protected]dbb83db2010-05-11 18:13:39516 size_t pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:00517 entries, 0, NetLogEventType::HTTP_TRANSACTION_SEND_REQUEST_HEADERS,
518 NetLogEventPhase::NONE);
[email protected]dbb83db2010-05-11 18:13:39519 ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:00520 entries, pos, NetLogEventType::HTTP_TRANSACTION_READ_RESPONSE_HEADERS,
521 NetLogEventPhase::NONE);
[email protected]ff007e162009-05-23 09:13:15522
[email protected]f3da152d2012-06-02 01:00:57523 std::string line;
524 EXPECT_TRUE(entries[pos].GetStringValue("line", &line));
525 EXPECT_EQ("GET / HTTP/1.1\r\n", line);
526
[email protected]79e1fd62013-06-20 06:50:04527 HttpRequestHeaders request_headers;
bnc691fda62016-08-12 00:43:16528 EXPECT_TRUE(trans.GetFullRequestHeaders(&request_headers));
[email protected]79e1fd62013-06-20 06:50:04529 std::string value;
530 EXPECT_TRUE(request_headers.GetHeader("Host", &value));
bncce36dca22015-04-21 22:11:23531 EXPECT_EQ("www.example.org", value);
[email protected]79e1fd62013-06-20 06:50:04532 EXPECT_TRUE(request_headers.GetHeader("Connection", &value));
533 EXPECT_EQ("keep-alive", value);
534
535 std::string response_headers;
536 EXPECT_TRUE(GetHeaders(entries[pos].params.get(), &response_headers));
bncce36dca22015-04-21 22:11:23537 EXPECT_EQ("['Host: www.example.org','Connection: keep-alive']",
[email protected]79e1fd62013-06-20 06:50:04538 response_headers);
[email protected]3deb9a52010-11-11 00:24:40539
bnc691fda62016-08-12 00:43:16540 out.total_received_bytes = trans.GetTotalReceivedBytes();
sclittlefb249892015-09-10 21:33:22541 // The total number of sent bytes should not have changed.
bnc691fda62016-08-12 00:43:16542 EXPECT_EQ(out.total_sent_bytes, trans.GetTotalSentBytes());
sclittlefb249892015-09-10 21:33:22543
bnc691fda62016-08-12 00:43:16544 trans.GetConnectionAttempts(&out.connection_attempts);
[email protected]aecfbf22008-10-16 02:02:47545 return out;
[email protected]ff007e162009-05-23 09:13:15546 }
initial.commit586acc5fe2008-07-26 22:42:52547
[email protected]5a60c8b2011-10-19 20:14:29548 SimpleGetHelperResult SimpleGetHelper(MockRead data_reads[],
549 size_t reads_count) {
sclittlefb249892015-09-10 21:33:22550 MockWrite data_writes[] = {
551 MockWrite("GET / HTTP/1.1\r\n"
552 "Host: www.example.org\r\n"
553 "Connection: keep-alive\r\n\r\n"),
554 };
[email protected]5a60c8b2011-10-19 20:14:29555
sclittlefb249892015-09-10 21:33:22556 StaticSocketDataProvider reads(data_reads, reads_count, data_writes,
557 arraysize(data_writes));
558 StaticSocketDataProvider* data[] = {&reads};
559 SimpleGetHelperResult out = SimpleGetHelperForData(data, 1);
560
561 EXPECT_EQ(CountWriteBytes(data_writes, arraysize(data_writes)),
562 out.total_sent_bytes);
563 return out;
[email protected]b8015c42013-12-24 15:18:19564 }
565
bnc032658ba2016-09-26 18:17:15566 void AddSSLSocketData() {
567 ssl_.next_proto = kProtoHTTP2;
568 ssl_.cert = ImportCertFromFile(GetTestCertsDirectory(), "spdy_pooling.pem");
569 ASSERT_TRUE(ssl_.cert);
570 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_);
571 }
572
[email protected]ff007e162009-05-23 09:13:15573 void ConnectStatusHelperWithExpectedStatus(const MockRead& status,
574 int expected_status);
initial.commit586acc5fe2008-07-26 22:42:52575
[email protected]ff007e162009-05-23 09:13:15576 void ConnectStatusHelper(const MockRead& status);
[email protected]bb88e1d32013-05-03 23:11:07577
578 void BypassHostCacheOnRefreshHelper(int load_flags);
579
580 void CheckErrorIsPassedBack(int error, IoMode mode);
581
[email protected]4bd46222013-05-14 19:32:23582 SpdyTestUtil spdy_util_;
[email protected]bb88e1d32013-05-03 23:11:07583 SpdySessionDependencies session_deps_;
bnc032658ba2016-09-26 18:17:15584 SSLSocketDataProvider ssl_;
[email protected]483fa202013-05-14 01:07:03585
586 // Original socket limits. Some tests set these. Safest to always restore
587 // them once each test has been run.
588 int old_max_group_sockets_;
589 int old_max_pool_sockets_;
[email protected]ff007e162009-05-23 09:13:15590};
[email protected]231d5a32008-09-13 00:45:27591
[email protected]448d4ca52012-03-04 04:12:23592namespace {
593
ryansturm49a8cb12016-06-15 16:51:09594class BeforeHeadersSentHandler {
[email protected]597a1ab2014-06-26 08:12:27595 public:
ryansturm49a8cb12016-06-15 16:51:09596 BeforeHeadersSentHandler()
597 : observed_before_headers_sent_with_proxy_(false),
598 observed_before_headers_sent_(false) {}
[email protected]597a1ab2014-06-26 08:12:27599
ryansturm49a8cb12016-06-15 16:51:09600 void OnBeforeHeadersSent(const ProxyInfo& proxy_info,
601 HttpRequestHeaders* request_headers) {
602 observed_before_headers_sent_ = true;
603 if (!proxy_info.is_http() && !proxy_info.is_https() &&
604 !proxy_info.is_quic()) {
605 return;
606 }
607 observed_before_headers_sent_with_proxy_ = true;
[email protected]597a1ab2014-06-26 08:12:27608 observed_proxy_server_uri_ = proxy_info.proxy_server().ToURI();
609 }
610
ryansturm49a8cb12016-06-15 16:51:09611 bool observed_before_headers_sent_with_proxy() const {
612 return observed_before_headers_sent_with_proxy_;
613 }
614
615 bool observed_before_headers_sent() const {
616 return observed_before_headers_sent_;
[email protected]597a1ab2014-06-26 08:12:27617 }
618
619 std::string observed_proxy_server_uri() const {
620 return observed_proxy_server_uri_;
621 }
622
623 private:
ryansturm49a8cb12016-06-15 16:51:09624 bool observed_before_headers_sent_with_proxy_;
625 bool observed_before_headers_sent_;
[email protected]597a1ab2014-06-26 08:12:27626 std::string observed_proxy_server_uri_;
627
ryansturm49a8cb12016-06-15 16:51:09628 DISALLOW_COPY_AND_ASSIGN(BeforeHeadersSentHandler);
[email protected]597a1ab2014-06-26 08:12:27629};
630
[email protected]15a5ccf82008-10-23 19:57:43631// Fill |str| with a long header list that consumes >= |size| bytes.
632void FillLargeHeadersString(std::string* str, int size) {
thestig9d3bb0c2015-01-24 00:49:51633 const char row[] =
[email protected]4ddaf2502008-10-23 18:26:19634 "SomeHeaderName: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx\r\n";
635 const int sizeof_row = strlen(row);
636 const int num_rows = static_cast<int>(
637 ceil(static_cast<float>(size) / sizeof_row));
638 const int sizeof_data = num_rows * sizeof_row;
639 DCHECK(sizeof_data >= size);
[email protected]15a5ccf82008-10-23 19:57:43640 str->reserve(sizeof_data);
[email protected]372d34a2008-11-05 21:30:51641
[email protected]4ddaf2502008-10-23 18:26:19642 for (int i = 0; i < num_rows; ++i)
[email protected]15a5ccf82008-10-23 19:57:43643 str->append(row, sizeof_row);
[email protected]4ddaf2502008-10-23 18:26:19644}
645
thakis84dff942015-07-28 20:47:38646#if defined(NTLM_PORTABLE)
[email protected]385a4672009-03-11 22:21:29647// Alternative functions that eliminate randomness and dependency on the local
648// host name so that the generated NTLM messages are reproducible.
avibf0746c2015-12-09 19:53:14649void MockGenerateRandom1(uint8_t* output, size_t n) {
650 static const uint8_t bytes[] = {0x55, 0x29, 0x66, 0x26,
651 0x6b, 0x9c, 0x73, 0x54};
[email protected]385a4672009-03-11 22:21:29652 static size_t current_byte = 0;
653 for (size_t i = 0; i < n; ++i) {
654 output[i] = bytes[current_byte++];
655 current_byte %= arraysize(bytes);
656 }
657}
658
avibf0746c2015-12-09 19:53:14659void MockGenerateRandom2(uint8_t* output, size_t n) {
660 static const uint8_t bytes[] = {0x96, 0x79, 0x85, 0xe7, 0x49, 0x93,
661 0x70, 0xa1, 0x4e, 0xe7, 0x87, 0x45,
662 0x31, 0x5b, 0xd3, 0x1f};
[email protected]385a4672009-03-11 22:21:29663 static size_t current_byte = 0;
664 for (size_t i = 0; i < n; ++i) {
665 output[i] = bytes[current_byte++];
666 current_byte %= arraysize(bytes);
667 }
668}
669
[email protected]fe2bc6a2009-03-23 16:52:20670std::string MockGetHostName() {
671 return "WTC-WIN7";
[email protected]385a4672009-03-11 22:21:29672}
thakis84dff942015-07-28 20:47:38673#endif // defined(NTLM_PORTABLE)
[email protected]385a4672009-03-11 22:21:29674
[email protected]e60e47a2010-07-14 03:37:18675template<typename ParentPool>
676class CaptureGroupNameSocketPool : public ParentPool {
[email protected]04e5be32009-06-26 20:00:31677 public:
[email protected]9e1bdd32011-02-03 21:48:34678 CaptureGroupNameSocketPool(HostResolver* host_resolver,
679 CertVerifier* cert_verifier);
[email protected]e60e47a2010-07-14 03:37:18680
[email protected]d80a4322009-08-14 07:07:49681 const std::string last_group_name_received() const {
682 return last_group_name_;
683 }
684
dmichaeld6e570d2014-12-18 22:30:57685 int RequestSocket(const std::string& group_name,
686 const void* socket_params,
687 RequestPriority priority,
mmenked3641e12016-01-28 16:06:15688 ClientSocketPool::RespectLimits respect_limits,
dmichaeld6e570d2014-12-18 22:30:57689 ClientSocketHandle* handle,
690 const CompletionCallback& callback,
tfarina42834112016-09-22 13:38:20691 const NetLogWithSource& net_log) override {
[email protected]04e5be32009-06-26 20:00:31692 last_group_name_ = group_name;
693 return ERR_IO_PENDING;
694 }
dmichaeld6e570d2014-12-18 22:30:57695 void CancelRequest(const std::string& group_name,
696 ClientSocketHandle* handle) override {}
697 void ReleaseSocket(const std::string& group_name,
danakj1fd259a02016-04-16 03:17:09698 std::unique_ptr<StreamSocket> socket,
dmichaeld6e570d2014-12-18 22:30:57699 int id) override {}
700 void CloseIdleSockets() override {}
xunjieli92feb332017-03-03 17:19:23701 void CloseIdleSocketsInGroup(const std::string& group_name) override {}
dmichaeld6e570d2014-12-18 22:30:57702 int IdleSocketCount() const override { return 0; }
703 int IdleSocketCountInGroup(const std::string& group_name) const override {
[email protected]04e5be32009-06-26 20:00:31704 return 0;
705 }
dmichaeld6e570d2014-12-18 22:30:57706 LoadState GetLoadState(const std::string& group_name,
707 const ClientSocketHandle* handle) const override {
[email protected]04e5be32009-06-26 20:00:31708 return LOAD_STATE_IDLE;
709 }
dmichaeld6e570d2014-12-18 22:30:57710 base::TimeDelta ConnectionTimeout() const override {
[email protected]a796bcec2010-03-22 17:17:26711 return base::TimeDelta();
712 }
[email protected]d80a4322009-08-14 07:07:49713
714 private:
[email protected]04e5be32009-06-26 20:00:31715 std::string last_group_name_;
716};
717
[email protected]ab739042011-04-07 15:22:28718typedef CaptureGroupNameSocketPool<TransportClientSocketPool>
719CaptureGroupNameTransportSocketPool;
[email protected]e772db3f2010-07-12 18:11:13720typedef CaptureGroupNameSocketPool<HttpProxyClientSocketPool>
721CaptureGroupNameHttpProxySocketPool;
[email protected]2d731a32010-04-29 01:04:06722typedef CaptureGroupNameSocketPool<SOCKSClientSocketPool>
[email protected]2227c692010-05-04 15:36:11723CaptureGroupNameSOCKSSocketPool;
[email protected]e60e47a2010-07-14 03:37:18724typedef CaptureGroupNameSocketPool<SSLClientSocketPool>
725CaptureGroupNameSSLSocketPool;
726
rkaplowd90695c2015-03-25 22:12:41727template <typename ParentPool>
[email protected]e60e47a2010-07-14 03:37:18728CaptureGroupNameSocketPool<ParentPool>::CaptureGroupNameSocketPool(
[email protected]9e1bdd32011-02-03 21:48:34729 HostResolver* host_resolver,
730 CertVerifier* /* cert_verifier */)
tbansal7b403bcc2016-04-13 22:33:21731 : ParentPool(0, 0, host_resolver, NULL, NULL, NULL) {}
[email protected]e60e47a2010-07-14 03:37:18732
hashimoto0d3e4fb2015-01-09 05:02:50733template <>
[email protected]2df19bb2010-08-25 20:13:46734CaptureGroupNameHttpProxySocketPool::CaptureGroupNameSocketPool(
hashimotodae13b02015-01-15 04:28:21735 HostResolver* /* host_resolver */,
[email protected]9e1bdd32011-02-03 21:48:34736 CertVerifier* /* cert_verifier */)
tbansal16196a1e2017-06-09 01:50:09737 : HttpProxyClientSocketPool(0, 0, NULL, NULL, NULL, NULL) {}
[email protected]2df19bb2010-08-25 20:13:46738
[email protected]007b3f82013-04-09 08:46:45739template <>
[email protected]e60e47a2010-07-14 03:37:18740CaptureGroupNameSSLSocketPool::CaptureGroupNameSocketPool(
hashimotodae13b02015-01-15 04:28:21741 HostResolver* /* host_resolver */,
[email protected]9e1bdd32011-02-03 21:48:34742 CertVerifier* cert_verifier)
[email protected]007b3f82013-04-09 08:46:45743 : SSLClientSocketPool(0,
744 0,
[email protected]007b3f82013-04-09 08:46:45745 cert_verifier,
746 NULL,
747 NULL,
[email protected]284303b62013-11-28 15:11:54748 NULL,
eranm6571b2b2014-12-03 15:53:23749 NULL,
[email protected]007b3f82013-04-09 08:46:45750 std::string(),
751 NULL,
752 NULL,
753 NULL,
754 NULL,
755 NULL,
[email protected]8e458552014-08-05 00:02:15756 NULL) {
757}
[email protected]2227c692010-05-04 15:36:11758
[email protected]231d5a32008-09-13 00:45:27759//-----------------------------------------------------------------------------
760
[email protected]79cb5c12011-09-12 13:12:04761// Helper functions for validating that AuthChallengeInfo's are correctly
762// configured for common cases.
763bool CheckBasicServerAuth(const AuthChallengeInfo* auth_challenge) {
764 if (!auth_challenge)
765 return false;
766 EXPECT_FALSE(auth_challenge->is_proxy);
asanka098c0092016-06-16 20:18:43767 EXPECT_EQ("http://www.example.org", auth_challenge->challenger.Serialize());
[email protected]79cb5c12011-09-12 13:12:04768 EXPECT_EQ("MyRealm1", auth_challenge->realm);
aberentbba302d2015-12-03 10:20:19769 EXPECT_EQ(kBasicAuthScheme, auth_challenge->scheme);
[email protected]79cb5c12011-09-12 13:12:04770 return true;
771}
772
773bool CheckBasicProxyAuth(const AuthChallengeInfo* auth_challenge) {
774 if (!auth_challenge)
775 return false;
776 EXPECT_TRUE(auth_challenge->is_proxy);
asanka098c0092016-06-16 20:18:43777 EXPECT_EQ("http://myproxy:70", auth_challenge->challenger.Serialize());
778 EXPECT_EQ("MyRealm1", auth_challenge->realm);
779 EXPECT_EQ(kBasicAuthScheme, auth_challenge->scheme);
780 return true;
781}
782
783bool CheckBasicSecureProxyAuth(const AuthChallengeInfo* auth_challenge) {
784 if (!auth_challenge)
785 return false;
786 EXPECT_TRUE(auth_challenge->is_proxy);
787 EXPECT_EQ("https://myproxy:70", auth_challenge->challenger.Serialize());
[email protected]79cb5c12011-09-12 13:12:04788 EXPECT_EQ("MyRealm1", auth_challenge->realm);
aberentbba302d2015-12-03 10:20:19789 EXPECT_EQ(kBasicAuthScheme, auth_challenge->scheme);
[email protected]79cb5c12011-09-12 13:12:04790 return true;
791}
792
793bool CheckDigestServerAuth(const AuthChallengeInfo* auth_challenge) {
794 if (!auth_challenge)
795 return false;
796 EXPECT_FALSE(auth_challenge->is_proxy);
asanka098c0092016-06-16 20:18:43797 EXPECT_EQ("http://www.example.org", auth_challenge->challenger.Serialize());
[email protected]79cb5c12011-09-12 13:12:04798 EXPECT_EQ("digestive", auth_challenge->realm);
aberentbba302d2015-12-03 10:20:19799 EXPECT_EQ(kDigestAuthScheme, auth_challenge->scheme);
[email protected]79cb5c12011-09-12 13:12:04800 return true;
801}
802
thakis84dff942015-07-28 20:47:38803#if defined(NTLM_PORTABLE)
[email protected]79cb5c12011-09-12 13:12:04804bool CheckNTLMServerAuth(const AuthChallengeInfo* auth_challenge) {
805 if (!auth_challenge)
806 return false;
807 EXPECT_FALSE(auth_challenge->is_proxy);
Bence Béky83eb3512017-09-05 12:56:09808 EXPECT_EQ("https://172.22.68.17", auth_challenge->challenger.Serialize());
[email protected]79cb5c12011-09-12 13:12:04809 EXPECT_EQ(std::string(), auth_challenge->realm);
aberentbba302d2015-12-03 10:20:19810 EXPECT_EQ(kNtlmAuthScheme, auth_challenge->scheme);
[email protected]79cb5c12011-09-12 13:12:04811 return true;
812}
thakis84dff942015-07-28 20:47:38813#endif // defined(NTLM_PORTABLE)
[email protected]79cb5c12011-09-12 13:12:04814
[email protected]448d4ca52012-03-04 04:12:23815} // namespace
816
bncd16676a2016-07-20 16:23:01817TEST_F(HttpNetworkTransactionTest, Basic) {
danakj1fd259a02016-04-16 03:17:09818 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:16819 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]231d5a32008-09-13 00:45:27820}
821
bncd16676a2016-07-20 16:23:01822TEST_F(HttpNetworkTransactionTest, SimpleGET) {
[email protected]231d5a32008-09-13 00:45:27823 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:35824 MockRead("HTTP/1.0 200 OK\r\n\r\n"),
825 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:06826 MockRead(SYNCHRONOUS, OK),
[email protected]231d5a32008-09-13 00:45:27827 };
[email protected]31a2bfe2010-02-09 08:03:39828 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
829 arraysize(data_reads));
robpercival214763f2016-07-01 23:27:01830 EXPECT_THAT(out.rv, IsOk());
[email protected]231d5a32008-09-13 00:45:27831 EXPECT_EQ("HTTP/1.0 200 OK", out.status_line);
832 EXPECT_EQ("hello world", out.response_data);
sclittlefb249892015-09-10 21:33:22833 int64_t reads_size = CountReadBytes(data_reads, arraysize(data_reads));
834 EXPECT_EQ(reads_size, out.total_received_bytes);
ttuttle1f2d7e92015-04-28 16:17:47835 EXPECT_EQ(0u, out.connection_attempts.size());
ttuttled9dbc652015-09-29 20:00:59836
837 EXPECT_FALSE(out.remote_endpoint_after_start.address().empty());
[email protected]231d5a32008-09-13 00:45:27838}
839
840// Response with no status line.
bncd16676a2016-07-20 16:23:01841TEST_F(HttpNetworkTransactionTest, SimpleGETNoHeaders) {
[email protected]231d5a32008-09-13 00:45:27842 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:35843 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:06844 MockRead(SYNCHRONOUS, OK),
[email protected]231d5a32008-09-13 00:45:27845 };
[email protected]31a2bfe2010-02-09 08:03:39846 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
847 arraysize(data_reads));
mmenkea2dcd3bf2016-08-16 21:49:41848 EXPECT_THAT(out.rv, IsOk());
849 EXPECT_EQ("HTTP/0.9 200 OK", out.status_line);
850 EXPECT_EQ("hello world", out.response_data);
851 int64_t reads_size = CountReadBytes(data_reads, arraysize(data_reads));
852 EXPECT_EQ(reads_size, out.total_received_bytes);
[email protected]231d5a32008-09-13 00:45:27853}
854
mmenkea7da6da2016-09-01 21:56:52855// Response with no status line, and a weird port. Should fail by default.
856TEST_F(HttpNetworkTransactionTest, SimpleGETNoHeadersWeirdPort) {
857 MockRead data_reads[] = {
858 MockRead("hello world"), MockRead(SYNCHRONOUS, OK),
859 };
860
861 StaticSocketDataProvider data(data_reads, arraysize(data_reads), nullptr, 0);
862 session_deps_.socket_factory->AddSocketDataProvider(&data);
863
864 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
865
krasinc06a72a2016-12-21 03:42:46866 HttpRequestInfo request;
bnc87dcefc2017-05-25 12:47:58867 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:19868 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
mmenkea7da6da2016-09-01 21:56:52869
mmenkea7da6da2016-09-01 21:56:52870 request.method = "GET";
871 request.url = GURL("http://www.example.com:2000/");
872 TestCompletionCallback callback;
tfarina42834112016-09-22 13:38:20873 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
mmenkea7da6da2016-09-01 21:56:52874 EXPECT_THAT(callback.GetResult(rv), IsError(ERR_INVALID_HTTP_RESPONSE));
875}
876
877// Response with no status line, and a weird port. Option to allow weird ports
878// enabled.
879TEST_F(HttpNetworkTransactionTest, SimpleGETNoHeadersWeirdPortAllowed) {
880 MockRead data_reads[] = {
881 MockRead("hello world"), MockRead(SYNCHRONOUS, OK),
882 };
883
884 StaticSocketDataProvider data(data_reads, arraysize(data_reads), nullptr, 0);
885 session_deps_.socket_factory->AddSocketDataProvider(&data);
886 session_deps_.http_09_on_non_default_ports_enabled = true;
887 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
888
krasinc06a72a2016-12-21 03:42:46889 HttpRequestInfo request;
bnc87dcefc2017-05-25 12:47:58890 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:19891 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
mmenkea7da6da2016-09-01 21:56:52892
mmenkea7da6da2016-09-01 21:56:52893 request.method = "GET";
894 request.url = GURL("http://www.example.com:2000/");
895 TestCompletionCallback callback;
tfarina42834112016-09-22 13:38:20896 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
mmenkea7da6da2016-09-01 21:56:52897 EXPECT_THAT(callback.GetResult(rv), IsOk());
898
899 const HttpResponseInfo* info = trans->GetResponseInfo();
900 ASSERT_TRUE(info->headers);
901 EXPECT_EQ("HTTP/0.9 200 OK", info->headers->GetStatusLine());
902
903 // Don't bother to read the body - that's verified elsewhere, important thing
904 // is that the option to allow HTTP/0.9 on non-default ports is respected.
905}
906
[email protected]231d5a32008-09-13 00:45:27907// Allow up to 4 bytes of junk to precede status line.
bncd16676a2016-07-20 16:23:01908TEST_F(HttpNetworkTransactionTest, StatusLineJunk3Bytes) {
[email protected]231d5a32008-09-13 00:45:27909 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:35910 MockRead("xxxHTTP/1.0 404 Not Found\nServer: blah\n\nDATA"),
[email protected]8ddf8322012-02-23 18:08:06911 MockRead(SYNCHRONOUS, OK),
[email protected]231d5a32008-09-13 00:45:27912 };
[email protected]31a2bfe2010-02-09 08:03:39913 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
914 arraysize(data_reads));
robpercival214763f2016-07-01 23:27:01915 EXPECT_THAT(out.rv, IsOk());
[email protected]231d5a32008-09-13 00:45:27916 EXPECT_EQ("HTTP/1.0 404 Not Found", out.status_line);
917 EXPECT_EQ("DATA", out.response_data);
sclittlefb249892015-09-10 21:33:22918 int64_t reads_size = CountReadBytes(data_reads, arraysize(data_reads));
919 EXPECT_EQ(reads_size, out.total_received_bytes);
[email protected]231d5a32008-09-13 00:45:27920}
921
922// Allow up to 4 bytes of junk to precede status line.
bncd16676a2016-07-20 16:23:01923TEST_F(HttpNetworkTransactionTest, StatusLineJunk4Bytes) {
[email protected]231d5a32008-09-13 00:45:27924 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:35925 MockRead("\n\nQJHTTP/1.0 404 Not Found\nServer: blah\n\nDATA"),
[email protected]8ddf8322012-02-23 18:08:06926 MockRead(SYNCHRONOUS, OK),
[email protected]231d5a32008-09-13 00:45:27927 };
[email protected]31a2bfe2010-02-09 08:03:39928 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
929 arraysize(data_reads));
robpercival214763f2016-07-01 23:27:01930 EXPECT_THAT(out.rv, IsOk());
[email protected]231d5a32008-09-13 00:45:27931 EXPECT_EQ("HTTP/1.0 404 Not Found", out.status_line);
932 EXPECT_EQ("DATA", out.response_data);
sclittlefb249892015-09-10 21:33:22933 int64_t reads_size = CountReadBytes(data_reads, arraysize(data_reads));
934 EXPECT_EQ(reads_size, out.total_received_bytes);
[email protected]231d5a32008-09-13 00:45:27935}
936
937// Beyond 4 bytes of slop and it should fail to find a status line.
bncd16676a2016-07-20 16:23:01938TEST_F(HttpNetworkTransactionTest, StatusLineJunk5Bytes) {
[email protected]231d5a32008-09-13 00:45:27939 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:35940 MockRead("xxxxxHTTP/1.1 404 Not Found\nServer: blah"),
[email protected]8ddf8322012-02-23 18:08:06941 MockRead(SYNCHRONOUS, OK),
[email protected]231d5a32008-09-13 00:45:27942 };
[email protected]31a2bfe2010-02-09 08:03:39943 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
944 arraysize(data_reads));
mmenkea2dcd3bf2016-08-16 21:49:41945 EXPECT_THAT(out.rv, IsOk());
946 EXPECT_EQ("HTTP/0.9 200 OK", out.status_line);
947 EXPECT_EQ("xxxxxHTTP/1.1 404 Not Found\nServer: blah", out.response_data);
948 int64_t reads_size = CountReadBytes(data_reads, arraysize(data_reads));
949 EXPECT_EQ(reads_size, out.total_received_bytes);
[email protected]231d5a32008-09-13 00:45:27950}
951
952// Same as StatusLineJunk4Bytes, except the read chunks are smaller.
bncd16676a2016-07-20 16:23:01953TEST_F(HttpNetworkTransactionTest, StatusLineJunk4Bytes_Slow) {
[email protected]231d5a32008-09-13 00:45:27954 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:35955 MockRead("\n"),
956 MockRead("\n"),
957 MockRead("Q"),
958 MockRead("J"),
959 MockRead("HTTP/1.0 404 Not Found\nServer: blah\n\nDATA"),
[email protected]8ddf8322012-02-23 18:08:06960 MockRead(SYNCHRONOUS, OK),
[email protected]231d5a32008-09-13 00:45:27961 };
[email protected]31a2bfe2010-02-09 08:03:39962 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
963 arraysize(data_reads));
robpercival214763f2016-07-01 23:27:01964 EXPECT_THAT(out.rv, IsOk());
[email protected]231d5a32008-09-13 00:45:27965 EXPECT_EQ("HTTP/1.0 404 Not Found", out.status_line);
966 EXPECT_EQ("DATA", out.response_data);
sclittlefb249892015-09-10 21:33:22967 int64_t reads_size = CountReadBytes(data_reads, arraysize(data_reads));
968 EXPECT_EQ(reads_size, out.total_received_bytes);
[email protected]231d5a32008-09-13 00:45:27969}
970
971// Close the connection before enough bytes to have a status line.
bncd16676a2016-07-20 16:23:01972TEST_F(HttpNetworkTransactionTest, StatusLinePartial) {
[email protected]231d5a32008-09-13 00:45:27973 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:35974 MockRead("HTT"),
[email protected]8ddf8322012-02-23 18:08:06975 MockRead(SYNCHRONOUS, OK),
[email protected]231d5a32008-09-13 00:45:27976 };
[email protected]31a2bfe2010-02-09 08:03:39977 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
978 arraysize(data_reads));
mmenkea2dcd3bf2016-08-16 21:49:41979 EXPECT_THAT(out.rv, IsOk());
980 EXPECT_EQ("HTTP/0.9 200 OK", out.status_line);
981 EXPECT_EQ("HTT", out.response_data);
982 int64_t reads_size = CountReadBytes(data_reads, arraysize(data_reads));
983 EXPECT_EQ(reads_size, out.total_received_bytes);
initial.commit586acc5fe2008-07-26 22:42:52984}
985
[email protected]f9d44aa2008-09-23 23:57:17986// Simulate a 204 response, lacking a Content-Length header, sent over a
987// persistent connection. The response should still terminate since a 204
988// cannot have a response body.
bncd16676a2016-07-20 16:23:01989TEST_F(HttpNetworkTransactionTest, StopsReading204) {
[email protected]b8015c42013-12-24 15:18:19990 char junk[] = "junk";
[email protected]f9d44aa2008-09-23 23:57:17991 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:35992 MockRead("HTTP/1.1 204 No Content\r\n\r\n"),
[email protected]b8015c42013-12-24 15:18:19993 MockRead(junk), // Should not be read!!
[email protected]8ddf8322012-02-23 18:08:06994 MockRead(SYNCHRONOUS, OK),
[email protected]f9d44aa2008-09-23 23:57:17995 };
[email protected]31a2bfe2010-02-09 08:03:39996 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
997 arraysize(data_reads));
robpercival214763f2016-07-01 23:27:01998 EXPECT_THAT(out.rv, IsOk());
[email protected]f9d44aa2008-09-23 23:57:17999 EXPECT_EQ("HTTP/1.1 204 No Content", out.status_line);
1000 EXPECT_EQ("", out.response_data);
sclittlefb249892015-09-10 21:33:221001 int64_t reads_size = CountReadBytes(data_reads, arraysize(data_reads));
1002 int64_t response_size = reads_size - strlen(junk);
1003 EXPECT_EQ(response_size, out.total_received_bytes);
[email protected]f9d44aa2008-09-23 23:57:171004}
1005
[email protected]0877e3d2009-10-17 22:29:571006// A simple request using chunked encoding with some extra data after.
bncd16676a2016-07-20 16:23:011007TEST_F(HttpNetworkTransactionTest, ChunkedEncoding) {
[email protected]b8015c42013-12-24 15:18:191008 std::string final_chunk = "0\r\n\r\n";
1009 std::string extra_data = "HTTP/1.1 200 OK\r\n";
1010 std::string last_read = final_chunk + extra_data;
[email protected]0877e3d2009-10-17 22:29:571011 MockRead data_reads[] = {
1012 MockRead("HTTP/1.1 200 OK\r\nTransfer-Encoding: chunked\r\n\r\n"),
1013 MockRead("5\r\nHello\r\n"),
1014 MockRead("1\r\n"),
1015 MockRead(" \r\n"),
1016 MockRead("5\r\nworld\r\n"),
[email protected]b8015c42013-12-24 15:18:191017 MockRead(last_read.data()),
[email protected]8ddf8322012-02-23 18:08:061018 MockRead(SYNCHRONOUS, OK),
[email protected]0877e3d2009-10-17 22:29:571019 };
[email protected]31a2bfe2010-02-09 08:03:391020 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
1021 arraysize(data_reads));
robpercival214763f2016-07-01 23:27:011022 EXPECT_THAT(out.rv, IsOk());
[email protected]0877e3d2009-10-17 22:29:571023 EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
1024 EXPECT_EQ("Hello world", out.response_data);
sclittlefb249892015-09-10 21:33:221025 int64_t reads_size = CountReadBytes(data_reads, arraysize(data_reads));
1026 int64_t response_size = reads_size - extra_data.size();
1027 EXPECT_EQ(response_size, out.total_received_bytes);
[email protected]0877e3d2009-10-17 22:29:571028}
1029
[email protected]9fe44f52010-09-23 18:36:001030// Next tests deal with http://crbug.com/56344.
1031
bncd16676a2016-07-20 16:23:011032TEST_F(HttpNetworkTransactionTest,
[email protected]9fe44f52010-09-23 18:36:001033 MultipleContentLengthHeadersNoTransferEncoding) {
1034 MockRead data_reads[] = {
1035 MockRead("HTTP/1.1 200 OK\r\n"),
1036 MockRead("Content-Length: 10\r\n"),
1037 MockRead("Content-Length: 5\r\n\r\n"),
1038 };
1039 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
1040 arraysize(data_reads));
robpercival214763f2016-07-01 23:27:011041 EXPECT_THAT(out.rv, IsError(ERR_RESPONSE_HEADERS_MULTIPLE_CONTENT_LENGTH));
[email protected]9fe44f52010-09-23 18:36:001042}
1043
bncd16676a2016-07-20 16:23:011044TEST_F(HttpNetworkTransactionTest,
[email protected]44b52042010-10-29 22:48:041045 DuplicateContentLengthHeadersNoTransferEncoding) {
1046 MockRead data_reads[] = {
1047 MockRead("HTTP/1.1 200 OK\r\n"),
1048 MockRead("Content-Length: 5\r\n"),
1049 MockRead("Content-Length: 5\r\n\r\n"),
1050 MockRead("Hello"),
1051 };
1052 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
1053 arraysize(data_reads));
robpercival214763f2016-07-01 23:27:011054 EXPECT_THAT(out.rv, IsOk());
[email protected]44b52042010-10-29 22:48:041055 EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
1056 EXPECT_EQ("Hello", out.response_data);
1057}
1058
bncd16676a2016-07-20 16:23:011059TEST_F(HttpNetworkTransactionTest,
[email protected]44b52042010-10-29 22:48:041060 ComplexContentLengthHeadersNoTransferEncoding) {
1061 // More than 2 dupes.
1062 {
1063 MockRead data_reads[] = {
1064 MockRead("HTTP/1.1 200 OK\r\n"),
1065 MockRead("Content-Length: 5\r\n"),
1066 MockRead("Content-Length: 5\r\n"),
1067 MockRead("Content-Length: 5\r\n\r\n"),
1068 MockRead("Hello"),
1069 };
1070 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
1071 arraysize(data_reads));
robpercival214763f2016-07-01 23:27:011072 EXPECT_THAT(out.rv, IsOk());
[email protected]44b52042010-10-29 22:48:041073 EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
1074 EXPECT_EQ("Hello", out.response_data);
1075 }
1076 // HTTP/1.0
1077 {
1078 MockRead data_reads[] = {
1079 MockRead("HTTP/1.0 200 OK\r\n"),
1080 MockRead("Content-Length: 5\r\n"),
1081 MockRead("Content-Length: 5\r\n"),
1082 MockRead("Content-Length: 5\r\n\r\n"),
1083 MockRead("Hello"),
1084 };
1085 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
1086 arraysize(data_reads));
robpercival214763f2016-07-01 23:27:011087 EXPECT_THAT(out.rv, IsOk());
[email protected]44b52042010-10-29 22:48:041088 EXPECT_EQ("HTTP/1.0 200 OK", out.status_line);
1089 EXPECT_EQ("Hello", out.response_data);
1090 }
1091 // 2 dupes and one mismatched.
1092 {
1093 MockRead data_reads[] = {
1094 MockRead("HTTP/1.1 200 OK\r\n"),
1095 MockRead("Content-Length: 10\r\n"),
1096 MockRead("Content-Length: 10\r\n"),
1097 MockRead("Content-Length: 5\r\n\r\n"),
1098 };
1099 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
1100 arraysize(data_reads));
robpercival214763f2016-07-01 23:27:011101 EXPECT_THAT(out.rv, IsError(ERR_RESPONSE_HEADERS_MULTIPLE_CONTENT_LENGTH));
[email protected]44b52042010-10-29 22:48:041102 }
1103}
1104
bncd16676a2016-07-20 16:23:011105TEST_F(HttpNetworkTransactionTest,
[email protected]9fe44f52010-09-23 18:36:001106 MultipleContentLengthHeadersTransferEncoding) {
1107 MockRead data_reads[] = {
1108 MockRead("HTTP/1.1 200 OK\r\n"),
1109 MockRead("Content-Length: 666\r\n"),
1110 MockRead("Content-Length: 1337\r\n"),
1111 MockRead("Transfer-Encoding: chunked\r\n\r\n"),
1112 MockRead("5\r\nHello\r\n"),
1113 MockRead("1\r\n"),
1114 MockRead(" \r\n"),
1115 MockRead("5\r\nworld\r\n"),
1116 MockRead("0\r\n\r\nHTTP/1.1 200 OK\r\n"),
[email protected]8ddf8322012-02-23 18:08:061117 MockRead(SYNCHRONOUS, OK),
[email protected]9fe44f52010-09-23 18:36:001118 };
1119 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
1120 arraysize(data_reads));
robpercival214763f2016-07-01 23:27:011121 EXPECT_THAT(out.rv, IsOk());
[email protected]9fe44f52010-09-23 18:36:001122 EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
1123 EXPECT_EQ("Hello world", out.response_data);
1124}
1125
[email protected]1628fe92011-10-04 23:04:551126// Next tests deal with http://crbug.com/98895.
1127
1128// Checks that a single Content-Disposition header results in no error.
bncd16676a2016-07-20 16:23:011129TEST_F(HttpNetworkTransactionTest, SingleContentDispositionHeader) {
[email protected]1628fe92011-10-04 23:04:551130 MockRead data_reads[] = {
1131 MockRead("HTTP/1.1 200 OK\r\n"),
1132 MockRead("Content-Disposition: attachment;filename=\"salutations.txt\"r\n"),
1133 MockRead("Content-Length: 5\r\n\r\n"),
1134 MockRead("Hello"),
1135 };
1136 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
1137 arraysize(data_reads));
robpercival214763f2016-07-01 23:27:011138 EXPECT_THAT(out.rv, IsOk());
[email protected]1628fe92011-10-04 23:04:551139 EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
1140 EXPECT_EQ("Hello", out.response_data);
1141}
1142
[email protected]54a9c6e52012-03-21 20:10:591143// Checks that two identical Content-Disposition headers result in no error.
bncd16676a2016-07-20 16:23:011144TEST_F(HttpNetworkTransactionTest, TwoIdenticalContentDispositionHeaders) {
[email protected]1628fe92011-10-04 23:04:551145 MockRead data_reads[] = {
1146 MockRead("HTTP/1.1 200 OK\r\n"),
1147 MockRead("Content-Disposition: attachment;filename=\"greetings.txt\"r\n"),
1148 MockRead("Content-Disposition: attachment;filename=\"greetings.txt\"r\n"),
1149 MockRead("Content-Length: 5\r\n\r\n"),
1150 MockRead("Hello"),
1151 };
1152 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
1153 arraysize(data_reads));
robpercival214763f2016-07-01 23:27:011154 EXPECT_THAT(out.rv, IsOk());
[email protected]54a9c6e52012-03-21 20:10:591155 EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
1156 EXPECT_EQ("Hello", out.response_data);
[email protected]1628fe92011-10-04 23:04:551157}
1158
1159// Checks that two distinct Content-Disposition headers result in an error.
bncd16676a2016-07-20 16:23:011160TEST_F(HttpNetworkTransactionTest, TwoDistinctContentDispositionHeaders) {
[email protected]1628fe92011-10-04 23:04:551161 MockRead data_reads[] = {
1162 MockRead("HTTP/1.1 200 OK\r\n"),
1163 MockRead("Content-Disposition: attachment;filename=\"greetings.txt\"r\n"),
1164 MockRead("Content-Disposition: attachment;filename=\"hi.txt\"r\n"),
1165 MockRead("Content-Length: 5\r\n\r\n"),
1166 MockRead("Hello"),
1167 };
1168 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
1169 arraysize(data_reads));
robpercival214763f2016-07-01 23:27:011170 EXPECT_THAT(out.rv,
1171 IsError(ERR_RESPONSE_HEADERS_MULTIPLE_CONTENT_DISPOSITION));
[email protected]1628fe92011-10-04 23:04:551172}
1173
[email protected]54a9c6e52012-03-21 20:10:591174// Checks that two identical Location headers result in no error.
1175// Also tests Location header behavior.
bncd16676a2016-07-20 16:23:011176TEST_F(HttpNetworkTransactionTest, TwoIdenticalLocationHeaders) {
[email protected]1628fe92011-10-04 23:04:551177 MockRead data_reads[] = {
1178 MockRead("HTTP/1.1 302 Redirect\r\n"),
1179 MockRead("Location: http://good.com/\r\n"),
[email protected]54a9c6e52012-03-21 20:10:591180 MockRead("Location: http://good.com/\r\n"),
[email protected]1628fe92011-10-04 23:04:551181 MockRead("Content-Length: 0\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:061182 MockRead(SYNCHRONOUS, OK),
[email protected]1628fe92011-10-04 23:04:551183 };
1184
1185 HttpRequestInfo request;
1186 request.method = "GET";
1187 request.url = GURL("http://redirect.com/");
[email protected]1628fe92011-10-04 23:04:551188
danakj1fd259a02016-04-16 03:17:091189 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:161190 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]1628fe92011-10-04 23:04:551191
1192 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:071193 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1628fe92011-10-04 23:04:551194
[email protected]49639fa2011-12-20 23:22:411195 TestCompletionCallback callback;
[email protected]1628fe92011-10-04 23:04:551196
tfarina42834112016-09-22 13:38:201197 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:011198 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]1628fe92011-10-04 23:04:551199
robpercival214763f2016-07-01 23:27:011200 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]1628fe92011-10-04 23:04:551201
bnc691fda62016-08-12 00:43:161202 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:521203 ASSERT_TRUE(response);
1204 ASSERT_TRUE(response->headers);
[email protected]1628fe92011-10-04 23:04:551205 EXPECT_EQ("HTTP/1.1 302 Redirect", response->headers->GetStatusLine());
1206 std::string url;
1207 EXPECT_TRUE(response->headers->IsRedirect(&url));
1208 EXPECT_EQ("http://good.com/", url);
tbansal2ecbbc72016-10-06 17:15:471209 EXPECT_TRUE(response->proxy_server.is_direct());
[email protected]1628fe92011-10-04 23:04:551210}
1211
[email protected]1628fe92011-10-04 23:04:551212// Checks that two distinct Location headers result in an error.
bncd16676a2016-07-20 16:23:011213TEST_F(HttpNetworkTransactionTest, TwoDistinctLocationHeaders) {
[email protected]1628fe92011-10-04 23:04:551214 MockRead data_reads[] = {
1215 MockRead("HTTP/1.1 302 Redirect\r\n"),
1216 MockRead("Location: http://good.com/\r\n"),
1217 MockRead("Location: http://evil.com/\r\n"),
1218 MockRead("Content-Length: 0\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:061219 MockRead(SYNCHRONOUS, OK),
[email protected]1628fe92011-10-04 23:04:551220 };
1221 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
1222 arraysize(data_reads));
robpercival214763f2016-07-01 23:27:011223 EXPECT_THAT(out.rv, IsError(ERR_RESPONSE_HEADERS_MULTIPLE_LOCATION));
[email protected]1628fe92011-10-04 23:04:551224}
1225
[email protected]ef0faf2e72009-03-05 23:27:231226// Do a request using the HEAD method. Verify that we don't try to read the
1227// message body (since HEAD has none).
bncd16676a2016-07-20 16:23:011228TEST_F(HttpNetworkTransactionTest, Head) {
[email protected]1c773ea12009-04-28 19:58:421229 HttpRequestInfo request;
[email protected]ef0faf2e72009-03-05 23:27:231230 request.method = "HEAD";
bncce36dca22015-04-21 22:11:231231 request.url = GURL("http://www.example.org/");
[email protected]ef0faf2e72009-03-05 23:27:231232
danakj1fd259a02016-04-16 03:17:091233 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:161234 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
ryansturm49a8cb12016-06-15 16:51:091235 BeforeHeadersSentHandler headers_handler;
bnc691fda62016-08-12 00:43:161236 trans.SetBeforeHeadersSentCallback(
ryansturm49a8cb12016-06-15 16:51:091237 base::Bind(&BeforeHeadersSentHandler::OnBeforeHeadersSent,
1238 base::Unretained(&headers_handler)));
[email protected]cb9bf6ca2011-01-28 13:15:271239
[email protected]ef0faf2e72009-03-05 23:27:231240 MockWrite data_writes1[] = {
csharrisonf473dd192015-08-18 13:54:131241 MockWrite("HEAD / HTTP/1.1\r\n"
1242 "Host: www.example.org\r\n"
1243 "Connection: keep-alive\r\n\r\n"),
[email protected]ef0faf2e72009-03-05 23:27:231244 };
1245 MockRead data_reads1[] = {
mmenked39192ee2015-12-09 00:57:231246 MockRead("HTTP/1.1 404 Not Found\r\n"), MockRead("Server: Blah\r\n"),
1247 MockRead("Content-Length: 1234\r\n\r\n"),
[email protected]ef0faf2e72009-03-05 23:27:231248
mmenked39192ee2015-12-09 00:57:231249 // No response body because the test stops reading here.
1250 MockRead(SYNCHRONOUS, ERR_UNEXPECTED),
[email protected]ef0faf2e72009-03-05 23:27:231251 };
1252
[email protected]31a2bfe2010-02-09 08:03:391253 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
1254 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:071255 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]ef0faf2e72009-03-05 23:27:231256
[email protected]49639fa2011-12-20 23:22:411257 TestCompletionCallback callback1;
[email protected]ef0faf2e72009-03-05 23:27:231258
tfarina42834112016-09-22 13:38:201259 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:011260 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]ef0faf2e72009-03-05 23:27:231261
1262 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:011263 EXPECT_THAT(rv, IsOk());
[email protected]ef0faf2e72009-03-05 23:27:231264
bnc691fda62016-08-12 00:43:161265 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:521266 ASSERT_TRUE(response);
[email protected]ef0faf2e72009-03-05 23:27:231267
1268 // Check that the headers got parsed.
wezca1070932016-05-26 20:30:521269 EXPECT_TRUE(response->headers);
[email protected]ef0faf2e72009-03-05 23:27:231270 EXPECT_EQ(1234, response->headers->GetContentLength());
1271 EXPECT_EQ("HTTP/1.1 404 Not Found", response->headers->GetStatusLine());
tbansal2ecbbc72016-10-06 17:15:471272 EXPECT_TRUE(response->proxy_server.is_direct());
ryansturm49a8cb12016-06-15 16:51:091273 EXPECT_TRUE(headers_handler.observed_before_headers_sent());
1274 EXPECT_FALSE(headers_handler.observed_before_headers_sent_with_proxy());
[email protected]ef0faf2e72009-03-05 23:27:231275
1276 std::string server_header;
olli.raulaee489a52016-01-25 08:37:101277 size_t iter = 0;
[email protected]ef0faf2e72009-03-05 23:27:231278 bool has_server_header = response->headers->EnumerateHeader(
1279 &iter, "Server", &server_header);
1280 EXPECT_TRUE(has_server_header);
1281 EXPECT_EQ("Blah", server_header);
1282
1283 // Reading should give EOF right away, since there is no message body
1284 // (despite non-zero content-length).
1285 std::string response_data;
bnc691fda62016-08-12 00:43:161286 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:011287 EXPECT_THAT(rv, IsOk());
[email protected]ef0faf2e72009-03-05 23:27:231288 EXPECT_EQ("", response_data);
1289}
1290
bncd16676a2016-07-20 16:23:011291TEST_F(HttpNetworkTransactionTest, ReuseConnection) {
danakj1fd259a02016-04-16 03:17:091292 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
initial.commit586acc5fe2008-07-26 22:42:521293
1294 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:351295 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
1296 MockRead("hello"),
1297 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
1298 MockRead("world"),
[email protected]8ddf8322012-02-23 18:08:061299 MockRead(SYNCHRONOUS, OK),
initial.commit586acc5fe2008-07-26 22:42:521300 };
[email protected]31a2bfe2010-02-09 08:03:391301 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:071302 session_deps_.socket_factory->AddSocketDataProvider(&data);
initial.commit586acc5fe2008-07-26 22:42:521303
[email protected]0b0bf032010-09-21 18:08:501304 const char* const kExpectedResponseData[] = {
initial.commit586acc5fe2008-07-26 22:42:521305 "hello", "world"
1306 };
1307
1308 for (int i = 0; i < 2; ++i) {
[email protected]1c773ea12009-04-28 19:58:421309 HttpRequestInfo request;
initial.commit586acc5fe2008-07-26 22:42:521310 request.method = "GET";
bncce36dca22015-04-21 22:11:231311 request.url = GURL("http://www.example.org/");
initial.commit586acc5fe2008-07-26 22:42:521312
bnc691fda62016-08-12 00:43:161313 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:271314
[email protected]49639fa2011-12-20 23:22:411315 TestCompletionCallback callback;
initial.commit586acc5fe2008-07-26 22:42:521316
tfarina42834112016-09-22 13:38:201317 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:011318 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
initial.commit586acc5fe2008-07-26 22:42:521319
1320 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:011321 EXPECT_THAT(rv, IsOk());
initial.commit586acc5fe2008-07-26 22:42:521322
bnc691fda62016-08-12 00:43:161323 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:521324 ASSERT_TRUE(response);
initial.commit586acc5fe2008-07-26 22:42:521325
wezca1070932016-05-26 20:30:521326 EXPECT_TRUE(response->headers);
[email protected]3d2a59b2008-09-26 19:44:251327 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
tbansal2ecbbc72016-10-06 17:15:471328 EXPECT_TRUE(response->proxy_server.is_direct());
initial.commit586acc5fe2008-07-26 22:42:521329
1330 std::string response_data;
bnc691fda62016-08-12 00:43:161331 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:011332 EXPECT_THAT(rv, IsOk());
[email protected]3d2a59b2008-09-26 19:44:251333 EXPECT_EQ(kExpectedResponseData[i], response_data);
initial.commit586acc5fe2008-07-26 22:42:521334 }
1335}
1336
bncd16676a2016-07-20 16:23:011337TEST_F(HttpNetworkTransactionTest, Ignores100) {
danakj1fd259a02016-04-16 03:17:091338 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:221339 element_readers.push_back(
Jeremy Roman0579ed62017-08-29 15:56:191340 std::make_unique<UploadBytesElementReader>("foo", 3));
olli.raula6df48b2a2015-11-26 07:40:221341 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]329b68b2012-11-14 17:54:271342
[email protected]1c773ea12009-04-28 19:58:421343 HttpRequestInfo request;
initial.commit586acc5fe2008-07-26 22:42:521344 request.method = "POST";
1345 request.url = GURL("http://www.foo.com/");
[email protected]329b68b2012-11-14 17:54:271346 request.upload_data_stream = &upload_data_stream;
initial.commit586acc5fe2008-07-26 22:42:521347
shivanishab9a143952016-09-19 17:23:411348 // Check the upload progress returned before initialization is correct.
1349 UploadProgress progress = request.upload_data_stream->GetUploadProgress();
1350 EXPECT_EQ(0u, progress.size());
1351 EXPECT_EQ(0u, progress.position());
1352
danakj1fd259a02016-04-16 03:17:091353 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:161354 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:271355
initial.commit586acc5fe2008-07-26 22:42:521356 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:351357 MockRead("HTTP/1.0 100 Continue\r\n\r\n"),
1358 MockRead("HTTP/1.0 200 OK\r\n\r\n"),
1359 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:061360 MockRead(SYNCHRONOUS, OK),
initial.commit586acc5fe2008-07-26 22:42:521361 };
[email protected]31a2bfe2010-02-09 08:03:391362 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:071363 session_deps_.socket_factory->AddSocketDataProvider(&data);
initial.commit586acc5fe2008-07-26 22:42:521364
[email protected]49639fa2011-12-20 23:22:411365 TestCompletionCallback callback;
initial.commit586acc5fe2008-07-26 22:42:521366
tfarina42834112016-09-22 13:38:201367 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:011368 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
initial.commit586acc5fe2008-07-26 22:42:521369
1370 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:011371 EXPECT_THAT(rv, IsOk());
initial.commit586acc5fe2008-07-26 22:42:521372
bnc691fda62016-08-12 00:43:161373 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:521374 ASSERT_TRUE(response);
initial.commit586acc5fe2008-07-26 22:42:521375
wezca1070932016-05-26 20:30:521376 EXPECT_TRUE(response->headers);
[email protected]3d2a59b2008-09-26 19:44:251377 EXPECT_EQ("HTTP/1.0 200 OK", response->headers->GetStatusLine());
initial.commit586acc5fe2008-07-26 22:42:521378
1379 std::string response_data;
bnc691fda62016-08-12 00:43:161380 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:011381 EXPECT_THAT(rv, IsOk());
[email protected]3d2a59b2008-09-26 19:44:251382 EXPECT_EQ("hello world", response_data);
initial.commit586acc5fe2008-07-26 22:42:521383}
1384
[email protected]3a2d3662009-03-27 03:49:141385// This test is almost the same as Ignores100 above, but the response contains
1386// a 102 instead of a 100. Also, instead of HTTP/1.0 the response is
[email protected]0877e3d2009-10-17 22:29:571387// HTTP/1.1 and the two status headers are read in one read.
bncd16676a2016-07-20 16:23:011388TEST_F(HttpNetworkTransactionTest, Ignores1xx) {
[email protected]1c773ea12009-04-28 19:58:421389 HttpRequestInfo request;
[email protected]3a2d3662009-03-27 03:49:141390 request.method = "GET";
1391 request.url = GURL("http://www.foo.com/");
[email protected]3a2d3662009-03-27 03:49:141392
danakj1fd259a02016-04-16 03:17:091393 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:161394 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:271395
[email protected]3a2d3662009-03-27 03:49:141396 MockRead data_reads[] = {
[email protected]0877e3d2009-10-17 22:29:571397 MockRead("HTTP/1.1 102 Unspecified status code\r\n\r\n"
1398 "HTTP/1.1 200 OK\r\n\r\n"),
[email protected]3a2d3662009-03-27 03:49:141399 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:061400 MockRead(SYNCHRONOUS, OK),
[email protected]3a2d3662009-03-27 03:49:141401 };
[email protected]31a2bfe2010-02-09 08:03:391402 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:071403 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]3a2d3662009-03-27 03:49:141404
[email protected]49639fa2011-12-20 23:22:411405 TestCompletionCallback callback;
[email protected]3a2d3662009-03-27 03:49:141406
tfarina42834112016-09-22 13:38:201407 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:011408 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]3a2d3662009-03-27 03:49:141409
1410 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:011411 EXPECT_THAT(rv, IsOk());
[email protected]3a2d3662009-03-27 03:49:141412
bnc691fda62016-08-12 00:43:161413 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:521414 ASSERT_TRUE(response);
[email protected]3a2d3662009-03-27 03:49:141415
wezca1070932016-05-26 20:30:521416 EXPECT_TRUE(response->headers);
[email protected]3a2d3662009-03-27 03:49:141417 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
1418
1419 std::string response_data;
bnc691fda62016-08-12 00:43:161420 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:011421 EXPECT_THAT(rv, IsOk());
[email protected]3a2d3662009-03-27 03:49:141422 EXPECT_EQ("hello world", response_data);
1423}
1424
bncd16676a2016-07-20 16:23:011425TEST_F(HttpNetworkTransactionTest, Incomplete100ThenEOF) {
zmo9528c9f42015-08-04 22:12:081426 HttpRequestInfo request;
1427 request.method = "POST";
1428 request.url = GURL("http://www.foo.com/");
zmo9528c9f42015-08-04 22:12:081429
danakj1fd259a02016-04-16 03:17:091430 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:161431 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
zmo9528c9f42015-08-04 22:12:081432
1433 MockRead data_reads[] = {
1434 MockRead(SYNCHRONOUS, "HTTP/1.0 100 Continue\r\n"),
1435 MockRead(ASYNC, 0),
[email protected]ee9410e72010-01-07 01:42:381436 };
zmo9528c9f42015-08-04 22:12:081437 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
1438 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]ee9410e72010-01-07 01:42:381439
zmo9528c9f42015-08-04 22:12:081440 TestCompletionCallback callback;
[email protected]ee9410e72010-01-07 01:42:381441
tfarina42834112016-09-22 13:38:201442 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:011443 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]ee9410e72010-01-07 01:42:381444
zmo9528c9f42015-08-04 22:12:081445 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:011446 EXPECT_THAT(rv, IsOk());
[email protected]ee9410e72010-01-07 01:42:381447
zmo9528c9f42015-08-04 22:12:081448 std::string response_data;
bnc691fda62016-08-12 00:43:161449 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:011450 EXPECT_THAT(rv, IsOk());
zmo9528c9f42015-08-04 22:12:081451 EXPECT_EQ("", response_data);
[email protected]ee9410e72010-01-07 01:42:381452}
1453
bncd16676a2016-07-20 16:23:011454TEST_F(HttpNetworkTransactionTest, EmptyResponse) {
[email protected]ee9410e72010-01-07 01:42:381455 HttpRequestInfo request;
1456 request.method = "POST";
1457 request.url = GURL("http://www.foo.com/");
[email protected]ee9410e72010-01-07 01:42:381458
danakj1fd259a02016-04-16 03:17:091459 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:161460 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:271461
[email protected]ee9410e72010-01-07 01:42:381462 MockRead data_reads[] = {
[email protected]8ddf8322012-02-23 18:08:061463 MockRead(ASYNC, 0),
[email protected]ee9410e72010-01-07 01:42:381464 };
[email protected]31a2bfe2010-02-09 08:03:391465 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:071466 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]ee9410e72010-01-07 01:42:381467
[email protected]49639fa2011-12-20 23:22:411468 TestCompletionCallback callback;
[email protected]ee9410e72010-01-07 01:42:381469
tfarina42834112016-09-22 13:38:201470 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:011471 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]ee9410e72010-01-07 01:42:381472
1473 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:011474 EXPECT_THAT(rv, IsError(ERR_EMPTY_RESPONSE));
[email protected]ee9410e72010-01-07 01:42:381475}
1476
[email protected]23e482282013-06-14 16:08:021477void HttpNetworkTransactionTest::KeepAliveConnectionResendRequestTest(
[email protected]202965992011-12-07 23:04:511478 const MockWrite* write_failure,
1479 const MockRead* read_failure) {
[email protected]1c773ea12009-04-28 19:58:421480 HttpRequestInfo request;
initial.commit586acc5fe2008-07-26 22:42:521481 request.method = "GET";
1482 request.url = GURL("http://www.foo.com/");
initial.commit586acc5fe2008-07-26 22:42:521483
vishal.b62985ca92015-04-17 08:45:511484 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:071485 session_deps_.net_log = &net_log;
danakj1fd259a02016-04-16 03:17:091486 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:271487
[email protected]202965992011-12-07 23:04:511488 // Written data for successfully sending both requests.
1489 MockWrite data1_writes[] = {
1490 MockWrite("GET / HTTP/1.1\r\n"
1491 "Host: www.foo.com\r\n"
1492 "Connection: keep-alive\r\n\r\n"),
1493 MockWrite("GET / HTTP/1.1\r\n"
1494 "Host: www.foo.com\r\n"
1495 "Connection: keep-alive\r\n\r\n")
1496 };
1497
1498 // Read results for the first request.
initial.commit586acc5fe2008-07-26 22:42:521499 MockRead data1_reads[] = {
[email protected]217e6022008-09-29 18:18:351500 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
1501 MockRead("hello"),
[email protected]8ddf8322012-02-23 18:08:061502 MockRead(ASYNC, OK),
initial.commit586acc5fe2008-07-26 22:42:521503 };
[email protected]202965992011-12-07 23:04:511504
1505 if (write_failure) {
[email protected]a34f61ee2014-03-18 20:59:491506 ASSERT_FALSE(read_failure);
[email protected]202965992011-12-07 23:04:511507 data1_writes[1] = *write_failure;
1508 } else {
1509 ASSERT_TRUE(read_failure);
1510 data1_reads[2] = *read_failure;
1511 }
1512
1513 StaticSocketDataProvider data1(data1_reads, arraysize(data1_reads),
1514 data1_writes, arraysize(data1_writes));
[email protected]bb88e1d32013-05-03 23:11:071515 session_deps_.socket_factory->AddSocketDataProvider(&data1);
initial.commit586acc5fe2008-07-26 22:42:521516
1517 MockRead data2_reads[] = {
[email protected]217e6022008-09-29 18:18:351518 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
1519 MockRead("world"),
[email protected]8ddf8322012-02-23 18:08:061520 MockRead(ASYNC, OK),
initial.commit586acc5fe2008-07-26 22:42:521521 };
[email protected]31a2bfe2010-02-09 08:03:391522 StaticSocketDataProvider data2(data2_reads, arraysize(data2_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:071523 session_deps_.socket_factory->AddSocketDataProvider(&data2);
initial.commit586acc5fe2008-07-26 22:42:521524
thestig9d3bb0c2015-01-24 00:49:511525 const char* const kExpectedResponseData[] = {
initial.commit586acc5fe2008-07-26 22:42:521526 "hello", "world"
1527 };
1528
mikecironef22f9812016-10-04 03:40:191529 uint32_t first_socket_log_id = NetLogSource::kInvalidId;
initial.commit586acc5fe2008-07-26 22:42:521530 for (int i = 0; i < 2; ++i) {
[email protected]49639fa2011-12-20 23:22:411531 TestCompletionCallback callback;
initial.commit586acc5fe2008-07-26 22:42:521532
bnc691fda62016-08-12 00:43:161533 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
initial.commit586acc5fe2008-07-26 22:42:521534
tfarina42834112016-09-22 13:38:201535 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:011536 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
initial.commit586acc5fe2008-07-26 22:42:521537
1538 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:011539 EXPECT_THAT(rv, IsOk());
initial.commit586acc5fe2008-07-26 22:42:521540
[email protected]58e32bb2013-01-21 18:23:251541 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:161542 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]58e32bb2013-01-21 18:23:251543 TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_DNS_TIMES);
1544 if (i == 0) {
1545 first_socket_log_id = load_timing_info.socket_log_id;
1546 } else {
1547 // The second request should be using a new socket.
1548 EXPECT_NE(first_socket_log_id, load_timing_info.socket_log_id);
1549 }
1550
bnc691fda62016-08-12 00:43:161551 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:521552 ASSERT_TRUE(response);
initial.commit586acc5fe2008-07-26 22:42:521553
wezca1070932016-05-26 20:30:521554 EXPECT_TRUE(response->headers);
tbansal2ecbbc72016-10-06 17:15:471555 EXPECT_TRUE(response->proxy_server.is_direct());
[email protected]3d2a59b2008-09-26 19:44:251556 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
initial.commit586acc5fe2008-07-26 22:42:521557
1558 std::string response_data;
bnc691fda62016-08-12 00:43:161559 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:011560 EXPECT_THAT(rv, IsOk());
[email protected]3d2a59b2008-09-26 19:44:251561 EXPECT_EQ(kExpectedResponseData[i], response_data);
initial.commit586acc5fe2008-07-26 22:42:521562 }
1563}
[email protected]3d2a59b2008-09-26 19:44:251564
[email protected]a34f61ee2014-03-18 20:59:491565void HttpNetworkTransactionTest::PreconnectErrorResendRequestTest(
1566 const MockWrite* write_failure,
[email protected]09356c652014-03-25 15:36:101567 const MockRead* read_failure,
1568 bool use_spdy) {
[email protected]a34f61ee2014-03-18 20:59:491569 HttpRequestInfo request;
1570 request.method = "GET";
[email protected]09356c652014-03-25 15:36:101571 request.url = GURL("https://www.foo.com/");
[email protected]a34f61ee2014-03-18 20:59:491572
vishal.b62985ca92015-04-17 08:45:511573 TestNetLog net_log;
[email protected]a34f61ee2014-03-18 20:59:491574 session_deps_.net_log = &net_log;
danakj1fd259a02016-04-16 03:17:091575 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]a34f61ee2014-03-18 20:59:491576
[email protected]09356c652014-03-25 15:36:101577 SSLSocketDataProvider ssl1(ASYNC, OK);
1578 SSLSocketDataProvider ssl2(ASYNC, OK);
1579 if (use_spdy) {
bnc3cf2a592016-08-11 14:48:361580 ssl1.next_proto = kProtoHTTP2;
1581 ssl2.next_proto = kProtoHTTP2;
[email protected]09356c652014-03-25 15:36:101582 }
1583 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl1);
1584 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
[email protected]a34f61ee2014-03-18 20:59:491585
[email protected]09356c652014-03-25 15:36:101586 // SPDY versions of the request and response.
bncdf80d44fd2016-07-15 20:27:411587 SpdySerializedFrame spdy_request(spdy_util_.ConstructSpdyGet(
bnc38dcd392016-02-09 23:19:491588 request.url.spec().c_str(), 1, DEFAULT_PRIORITY));
bncdf80d44fd2016-07-15 20:27:411589 SpdySerializedFrame spdy_response(
bnc42331402016-07-25 13:36:151590 spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
bncdf80d44fd2016-07-15 20:27:411591 SpdySerializedFrame spdy_data(
1592 spdy_util_.ConstructSpdyDataFrame(1, "hello", 5, true));
[email protected]a34f61ee2014-03-18 20:59:491593
[email protected]09356c652014-03-25 15:36:101594 // HTTP/1.1 versions of the request and response.
1595 const char kHttpRequest[] = "GET / HTTP/1.1\r\n"
1596 "Host: www.foo.com\r\n"
1597 "Connection: keep-alive\r\n\r\n";
1598 const char kHttpResponse[] = "HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n";
1599 const char kHttpData[] = "hello";
1600
1601 std::vector<MockRead> data1_reads;
1602 std::vector<MockWrite> data1_writes;
[email protected]a34f61ee2014-03-18 20:59:491603 if (write_failure) {
1604 ASSERT_FALSE(read_failure);
[email protected]09356c652014-03-25 15:36:101605 data1_writes.push_back(*write_failure);
1606 data1_reads.push_back(MockRead(ASYNC, OK));
[email protected]a34f61ee2014-03-18 20:59:491607 } else {
1608 ASSERT_TRUE(read_failure);
[email protected]09356c652014-03-25 15:36:101609 if (use_spdy) {
bncdf80d44fd2016-07-15 20:27:411610 data1_writes.push_back(CreateMockWrite(spdy_request));
[email protected]09356c652014-03-25 15:36:101611 } else {
1612 data1_writes.push_back(MockWrite(kHttpRequest));
1613 }
1614 data1_reads.push_back(*read_failure);
[email protected]a34f61ee2014-03-18 20:59:491615 }
1616
[email protected]09356c652014-03-25 15:36:101617 StaticSocketDataProvider data1(&data1_reads[0], data1_reads.size(),
1618 &data1_writes[0], data1_writes.size());
[email protected]a34f61ee2014-03-18 20:59:491619 session_deps_.socket_factory->AddSocketDataProvider(&data1);
1620
[email protected]09356c652014-03-25 15:36:101621 std::vector<MockRead> data2_reads;
1622 std::vector<MockWrite> data2_writes;
1623
1624 if (use_spdy) {
bncdf80d44fd2016-07-15 20:27:411625 data2_writes.push_back(CreateMockWrite(spdy_request, 0, ASYNC));
[email protected]09356c652014-03-25 15:36:101626
bncdf80d44fd2016-07-15 20:27:411627 data2_reads.push_back(CreateMockRead(spdy_response, 1, ASYNC));
1628 data2_reads.push_back(CreateMockRead(spdy_data, 2, ASYNC));
[email protected]09356c652014-03-25 15:36:101629 data2_reads.push_back(MockRead(ASYNC, OK, 3));
1630 } else {
1631 data2_writes.push_back(
1632 MockWrite(ASYNC, kHttpRequest, strlen(kHttpRequest), 0));
1633
1634 data2_reads.push_back(
1635 MockRead(ASYNC, kHttpResponse, strlen(kHttpResponse), 1));
1636 data2_reads.push_back(MockRead(ASYNC, kHttpData, strlen(kHttpData), 2));
1637 data2_reads.push_back(MockRead(ASYNC, OK, 3));
1638 }
rch8e6c6c42015-05-01 14:05:131639 SequencedSocketData data2(&data2_reads[0], data2_reads.size(),
1640 &data2_writes[0], data2_writes.size());
[email protected]a34f61ee2014-03-18 20:59:491641 session_deps_.socket_factory->AddSocketDataProvider(&data2);
1642
1643 // Preconnect a socket.
nharper8cdb0fb2016-04-22 21:34:591644 session->http_stream_factory()->PreconnectStreams(1, request);
[email protected]a34f61ee2014-03-18 20:59:491645 // Wait for the preconnect to complete.
1646 // TODO(davidben): Some way to wait for an idle socket count might be handy.
1647 base::RunLoop().RunUntilIdle();
[email protected]09356c652014-03-25 15:36:101648 EXPECT_EQ(1, GetIdleSocketCountInSSLSocketPool(session.get()));
[email protected]a34f61ee2014-03-18 20:59:491649
1650 // Make the request.
1651 TestCompletionCallback callback;
1652
bnc691fda62016-08-12 00:43:161653 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]a34f61ee2014-03-18 20:59:491654
tfarina42834112016-09-22 13:38:201655 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:011656 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]a34f61ee2014-03-18 20:59:491657
1658 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:011659 EXPECT_THAT(rv, IsOk());
[email protected]a34f61ee2014-03-18 20:59:491660
1661 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:161662 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]09356c652014-03-25 15:36:101663 TestLoadTimingNotReused(
1664 load_timing_info,
1665 CONNECT_TIMING_HAS_DNS_TIMES|CONNECT_TIMING_HAS_SSL_TIMES);
[email protected]a34f61ee2014-03-18 20:59:491666
bnc691fda62016-08-12 00:43:161667 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:521668 ASSERT_TRUE(response);
[email protected]a34f61ee2014-03-18 20:59:491669
wezca1070932016-05-26 20:30:521670 EXPECT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:021671 if (response->was_fetched_via_spdy) {
1672 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
1673 } else {
1674 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
1675 }
[email protected]a34f61ee2014-03-18 20:59:491676
1677 std::string response_data;
bnc691fda62016-08-12 00:43:161678 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:011679 EXPECT_THAT(rv, IsOk());
[email protected]09356c652014-03-25 15:36:101680 EXPECT_EQ(kHttpData, response_data);
[email protected]a34f61ee2014-03-18 20:59:491681}
1682
Biljith Jayan45a41722017-08-16 18:43:141683// Test that we do not retry indefinitely when a server sends an error like
1684// ERR_SPDY_PING_FAILED, ERR_SPDY_SERVER_REFUSED_STREAM,
1685// ERR_QUIC_HANDSHAKE_FAILED or ERR_QUIC_PROTOCOL_ERROR.
1686TEST_F(HttpNetworkTransactionTest, FiniteRetriesOnIOError) {
1687 HttpRequestInfo request;
1688 request.method = "GET";
1689 request.url = GURL("https://www.foo.com/");
1690
1691 // Check whether we give up after the third try.
1692
1693 // Construct an HTTP2 request and a "Go away" response.
1694 SpdySerializedFrame spdy_request(spdy_util_.ConstructSpdyGet(
1695 request.url.spec().c_str(), 1, DEFAULT_PRIORITY));
1696 SpdySerializedFrame spdy_response_go_away(spdy_util_.ConstructSpdyGoAway());
1697 MockRead data_read1 = CreateMockRead(spdy_response_go_away);
1698 MockWrite data_write = CreateMockWrite(spdy_request, 0);
1699
1700 // Three go away responses.
1701 StaticSocketDataProvider data1(&data_read1, 1, &data_write, 1);
1702 StaticSocketDataProvider data2(&data_read1, 1, &data_write, 1);
1703 StaticSocketDataProvider data3(&data_read1, 1, &data_write, 1);
1704
1705 session_deps_.socket_factory->AddSocketDataProvider(&data1);
1706 AddSSLSocketData();
1707 session_deps_.socket_factory->AddSocketDataProvider(&data2);
1708 AddSSLSocketData();
1709 session_deps_.socket_factory->AddSocketDataProvider(&data3);
1710 AddSSLSocketData();
1711
1712 TestCompletionCallback callback;
1713 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
1714 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
1715
1716 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
1717 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
1718
1719 rv = callback.WaitForResult();
1720 EXPECT_THAT(rv, IsError(ERR_SPDY_SERVER_REFUSED_STREAM));
1721}
1722
1723TEST_F(HttpNetworkTransactionTest, RetryTwiceOnIOError) {
1724 HttpRequestInfo request;
1725 request.method = "GET";
1726 request.url = GURL("https://www.foo.com/");
1727
1728 // Check whether we try atleast thrice before giving up.
1729
1730 // Construct an HTTP2 request and a "Go away" response.
1731 SpdySerializedFrame spdy_request(spdy_util_.ConstructSpdyGet(
1732 request.url.spec().c_str(), 1, DEFAULT_PRIORITY));
1733 SpdySerializedFrame spdy_response_go_away(spdy_util_.ConstructSpdyGoAway());
1734 MockRead data_read1 = CreateMockRead(spdy_response_go_away);
1735 MockWrite data_write = CreateMockWrite(spdy_request, 0);
1736
1737 // Construct a non error HTTP2 response.
1738 SpdySerializedFrame spdy_response_no_error(
1739 spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
1740 SpdySerializedFrame spdy_data(spdy_util_.ConstructSpdyDataFrame(1, true));
1741 MockRead data_read2[] = {CreateMockRead(spdy_response_no_error, 1),
1742 CreateMockRead(spdy_data, 2)};
1743
1744 // Two error responses.
1745 StaticSocketDataProvider data1(&data_read1, 1, &data_write, 1);
1746 StaticSocketDataProvider data2(&data_read1, 1, &data_write, 1);
1747 // Followed by a success response.
1748 SequencedSocketData data3(data_read2, 2, &data_write, 1);
1749
1750 session_deps_.socket_factory->AddSocketDataProvider(&data1);
1751 AddSSLSocketData();
1752 session_deps_.socket_factory->AddSocketDataProvider(&data2);
1753 AddSSLSocketData();
1754 session_deps_.socket_factory->AddSocketDataProvider(&data3);
1755 AddSSLSocketData();
1756
1757 TestCompletionCallback callback;
1758 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
1759 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
1760
1761 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
1762 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
1763
1764 rv = callback.WaitForResult();
1765 EXPECT_THAT(rv, IsOk());
1766}
1767
bncd16676a2016-07-20 16:23:011768TEST_F(HttpNetworkTransactionTest, KeepAliveConnectionNotConnectedOnWrite) {
[email protected]8ddf8322012-02-23 18:08:061769 MockWrite write_failure(ASYNC, ERR_SOCKET_NOT_CONNECTED);
[email protected]202965992011-12-07 23:04:511770 KeepAliveConnectionResendRequestTest(&write_failure, NULL);
1771}
1772
bncd16676a2016-07-20 16:23:011773TEST_F(HttpNetworkTransactionTest, KeepAliveConnectionReset) {
[email protected]8ddf8322012-02-23 18:08:061774 MockRead read_failure(ASYNC, ERR_CONNECTION_RESET);
[email protected]202965992011-12-07 23:04:511775 KeepAliveConnectionResendRequestTest(NULL, &read_failure);
[email protected]3d2a59b2008-09-26 19:44:251776}
1777
bncd16676a2016-07-20 16:23:011778TEST_F(HttpNetworkTransactionTest, KeepAliveConnectionEOF) {
[email protected]8ddf8322012-02-23 18:08:061779 MockRead read_failure(SYNCHRONOUS, OK); // EOF
[email protected]202965992011-12-07 23:04:511780 KeepAliveConnectionResendRequestTest(NULL, &read_failure);
[email protected]3d2a59b2008-09-26 19:44:251781}
1782
[email protected]d58ceea82014-06-04 10:55:541783// Make sure that on a 408 response (Request Timeout), the request is retried,
1784// if the socket was a reused keep alive socket.
bncd16676a2016-07-20 16:23:011785TEST_F(HttpNetworkTransactionTest, KeepAlive408) {
[email protected]d58ceea82014-06-04 10:55:541786 MockRead read_failure(SYNCHRONOUS,
1787 "HTTP/1.1 408 Request Timeout\r\n"
1788 "Connection: Keep-Alive\r\n"
1789 "Content-Length: 6\r\n\r\n"
1790 "Pickle");
1791 KeepAliveConnectionResendRequestTest(NULL, &read_failure);
1792}
1793
bncd16676a2016-07-20 16:23:011794TEST_F(HttpNetworkTransactionTest, PreconnectErrorNotConnectedOnWrite) {
[email protected]a34f61ee2014-03-18 20:59:491795 MockWrite write_failure(ASYNC, ERR_SOCKET_NOT_CONNECTED);
[email protected]09356c652014-03-25 15:36:101796 PreconnectErrorResendRequestTest(&write_failure, NULL, false);
[email protected]a34f61ee2014-03-18 20:59:491797}
1798
bncd16676a2016-07-20 16:23:011799TEST_F(HttpNetworkTransactionTest, PreconnectErrorReset) {
[email protected]a34f61ee2014-03-18 20:59:491800 MockRead read_failure(ASYNC, ERR_CONNECTION_RESET);
[email protected]09356c652014-03-25 15:36:101801 PreconnectErrorResendRequestTest(NULL, &read_failure, false);
[email protected]a34f61ee2014-03-18 20:59:491802}
1803
bncd16676a2016-07-20 16:23:011804TEST_F(HttpNetworkTransactionTest, PreconnectErrorEOF) {
[email protected]a34f61ee2014-03-18 20:59:491805 MockRead read_failure(SYNCHRONOUS, OK); // EOF
[email protected]09356c652014-03-25 15:36:101806 PreconnectErrorResendRequestTest(NULL, &read_failure, false);
1807}
1808
bncd16676a2016-07-20 16:23:011809TEST_F(HttpNetworkTransactionTest, PreconnectErrorAsyncEOF) {
[email protected]09356c652014-03-25 15:36:101810 MockRead read_failure(ASYNC, OK); // EOF
1811 PreconnectErrorResendRequestTest(NULL, &read_failure, false);
1812}
1813
[email protected]d58ceea82014-06-04 10:55:541814// Make sure that on a 408 response (Request Timeout), the request is retried,
1815// if the socket was a preconnected (UNUSED_IDLE) socket.
bncd16676a2016-07-20 16:23:011816TEST_F(HttpNetworkTransactionTest, RetryOnIdle408) {
[email protected]d58ceea82014-06-04 10:55:541817 MockRead read_failure(SYNCHRONOUS,
1818 "HTTP/1.1 408 Request Timeout\r\n"
1819 "Connection: Keep-Alive\r\n"
1820 "Content-Length: 6\r\n\r\n"
1821 "Pickle");
1822 KeepAliveConnectionResendRequestTest(NULL, &read_failure);
1823 PreconnectErrorResendRequestTest(NULL, &read_failure, false);
1824}
1825
bncd16676a2016-07-20 16:23:011826TEST_F(HttpNetworkTransactionTest, SpdyPreconnectErrorNotConnectedOnWrite) {
[email protected]09356c652014-03-25 15:36:101827 MockWrite write_failure(ASYNC, ERR_SOCKET_NOT_CONNECTED);
1828 PreconnectErrorResendRequestTest(&write_failure, NULL, true);
1829}
1830
bncd16676a2016-07-20 16:23:011831TEST_F(HttpNetworkTransactionTest, SpdyPreconnectErrorReset) {
[email protected]09356c652014-03-25 15:36:101832 MockRead read_failure(ASYNC, ERR_CONNECTION_RESET);
1833 PreconnectErrorResendRequestTest(NULL, &read_failure, true);
1834}
1835
bncd16676a2016-07-20 16:23:011836TEST_F(HttpNetworkTransactionTest, SpdyPreconnectErrorEOF) {
[email protected]09356c652014-03-25 15:36:101837 MockRead read_failure(SYNCHRONOUS, OK); // EOF
1838 PreconnectErrorResendRequestTest(NULL, &read_failure, true);
1839}
1840
bncd16676a2016-07-20 16:23:011841TEST_F(HttpNetworkTransactionTest, SpdyPreconnectErrorAsyncEOF) {
[email protected]09356c652014-03-25 15:36:101842 MockRead read_failure(ASYNC, OK); // EOF
1843 PreconnectErrorResendRequestTest(NULL, &read_failure, true);
[email protected]a34f61ee2014-03-18 20:59:491844}
1845
bncd16676a2016-07-20 16:23:011846TEST_F(HttpNetworkTransactionTest, NonKeepAliveConnectionReset) {
[email protected]1c773ea12009-04-28 19:58:421847 HttpRequestInfo request;
[email protected]3d2a59b2008-09-26 19:44:251848 request.method = "GET";
bncce36dca22015-04-21 22:11:231849 request.url = GURL("http://www.example.org/");
[email protected]3d2a59b2008-09-26 19:44:251850
danakj1fd259a02016-04-16 03:17:091851 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:161852 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:271853
[email protected]3d2a59b2008-09-26 19:44:251854 MockRead data_reads[] = {
[email protected]8ddf8322012-02-23 18:08:061855 MockRead(ASYNC, ERR_CONNECTION_RESET),
[email protected]217e6022008-09-29 18:18:351856 MockRead("HTTP/1.0 200 OK\r\n\r\n"), // Should not be used
1857 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:061858 MockRead(SYNCHRONOUS, OK),
[email protected]3d2a59b2008-09-26 19:44:251859 };
[email protected]31a2bfe2010-02-09 08:03:391860 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:071861 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]3d2a59b2008-09-26 19:44:251862
[email protected]49639fa2011-12-20 23:22:411863 TestCompletionCallback callback;
[email protected]3d2a59b2008-09-26 19:44:251864
tfarina42834112016-09-22 13:38:201865 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:011866 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]3d2a59b2008-09-26 19:44:251867
1868 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:011869 EXPECT_THAT(rv, IsError(ERR_CONNECTION_RESET));
ttuttled9dbc652015-09-29 20:00:591870
1871 IPEndPoint endpoint;
bnc691fda62016-08-12 00:43:161872 EXPECT_TRUE(trans.GetRemoteEndpoint(&endpoint));
ttuttled9dbc652015-09-29 20:00:591873 EXPECT_LT(0u, endpoint.address().size());
[email protected]3d2a59b2008-09-26 19:44:251874}
1875
1876// What do various browsers do when the server closes a non-keepalive
1877// connection without sending any response header or body?
1878//
1879// IE7: error page
1880// Safari 3.1.2 (Windows): error page
1881// Firefox 3.0.1: blank page
1882// Opera 9.52: after five attempts, blank page
[email protected]1c773ea12009-04-28 19:58:421883// Us with WinHTTP: error page (ERR_INVALID_RESPONSE)
1884// Us: error page (EMPTY_RESPONSE)
bncd16676a2016-07-20 16:23:011885TEST_F(HttpNetworkTransactionTest, NonKeepAliveConnectionEOF) {
[email protected]3d2a59b2008-09-26 19:44:251886 MockRead data_reads[] = {
[email protected]8ddf8322012-02-23 18:08:061887 MockRead(SYNCHRONOUS, OK), // EOF
[email protected]217e6022008-09-29 18:18:351888 MockRead("HTTP/1.0 200 OK\r\n\r\n"), // Should not be used
1889 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:061890 MockRead(SYNCHRONOUS, OK),
[email protected]3d2a59b2008-09-26 19:44:251891 };
[email protected]31a2bfe2010-02-09 08:03:391892 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
1893 arraysize(data_reads));
robpercival214763f2016-07-01 23:27:011894 EXPECT_THAT(out.rv, IsError(ERR_EMPTY_RESPONSE));
[email protected]3d2a59b2008-09-26 19:44:251895}
[email protected]1826a402014-01-08 15:40:481896
[email protected]7a5378b2012-11-04 03:25:171897// Next 2 cases (KeepAliveEarlyClose and KeepAliveEarlyClose2) are regression
1898// tests. There was a bug causing HttpNetworkTransaction to hang in the
1899// destructor in such situations.
1900// See http://crbug.com/154712 and http://crbug.com/156609.
bncd16676a2016-07-20 16:23:011901TEST_F(HttpNetworkTransactionTest, KeepAliveEarlyClose) {
[email protected]7a5378b2012-11-04 03:25:171902 HttpRequestInfo request;
1903 request.method = "GET";
bncce36dca22015-04-21 22:11:231904 request.url = GURL("http://www.example.org/");
[email protected]7a5378b2012-11-04 03:25:171905
danakj1fd259a02016-04-16 03:17:091906 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc87dcefc2017-05-25 12:47:581907 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:191908 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]7a5378b2012-11-04 03:25:171909
1910 MockRead data_reads[] = {
1911 MockRead("HTTP/1.0 200 OK\r\n"),
1912 MockRead("Connection: keep-alive\r\n"),
1913 MockRead("Content-Length: 100\r\n\r\n"),
1914 MockRead("hello"),
1915 MockRead(SYNCHRONOUS, 0),
1916 };
1917 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:071918 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]7a5378b2012-11-04 03:25:171919
1920 TestCompletionCallback callback;
1921
tfarina42834112016-09-22 13:38:201922 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:011923 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]7a5378b2012-11-04 03:25:171924
1925 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:011926 EXPECT_THAT(rv, IsOk());
[email protected]7a5378b2012-11-04 03:25:171927
1928 scoped_refptr<IOBufferWithSize> io_buf(new IOBufferWithSize(100));
[email protected]90499482013-06-01 00:39:501929 rv = trans->Read(io_buf.get(), io_buf->size(), callback.callback());
[email protected]7a5378b2012-11-04 03:25:171930 if (rv == ERR_IO_PENDING)
1931 rv = callback.WaitForResult();
1932 EXPECT_EQ(5, rv);
[email protected]90499482013-06-01 00:39:501933 rv = trans->Read(io_buf.get(), io_buf->size(), callback.callback());
robpercival214763f2016-07-01 23:27:011934 EXPECT_THAT(rv, IsError(ERR_CONTENT_LENGTH_MISMATCH));
[email protected]7a5378b2012-11-04 03:25:171935
1936 trans.reset();
fdoray92e35a72016-06-10 15:54:551937 base::RunLoop().RunUntilIdle();
[email protected]7a5378b2012-11-04 03:25:171938 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
1939}
1940
bncd16676a2016-07-20 16:23:011941TEST_F(HttpNetworkTransactionTest, KeepAliveEarlyClose2) {
[email protected]7a5378b2012-11-04 03:25:171942 HttpRequestInfo request;
1943 request.method = "GET";
bncce36dca22015-04-21 22:11:231944 request.url = GURL("http://www.example.org/");
[email protected]7a5378b2012-11-04 03:25:171945
danakj1fd259a02016-04-16 03:17:091946 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc87dcefc2017-05-25 12:47:581947 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:191948 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]7a5378b2012-11-04 03:25:171949
1950 MockRead data_reads[] = {
1951 MockRead("HTTP/1.0 200 OK\r\n"),
1952 MockRead("Connection: keep-alive\r\n"),
1953 MockRead("Content-Length: 100\r\n\r\n"),
1954 MockRead(SYNCHRONOUS, 0),
1955 };
1956 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:071957 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]7a5378b2012-11-04 03:25:171958
1959 TestCompletionCallback callback;
1960
tfarina42834112016-09-22 13:38:201961 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:011962 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]7a5378b2012-11-04 03:25:171963
1964 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:011965 EXPECT_THAT(rv, IsOk());
[email protected]7a5378b2012-11-04 03:25:171966
1967 scoped_refptr<IOBufferWithSize> io_buf(new IOBufferWithSize(100));
[email protected]90499482013-06-01 00:39:501968 rv = trans->Read(io_buf.get(), io_buf->size(), callback.callback());
[email protected]7a5378b2012-11-04 03:25:171969 if (rv == ERR_IO_PENDING)
1970 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:011971 EXPECT_THAT(rv, IsError(ERR_CONTENT_LENGTH_MISMATCH));
[email protected]7a5378b2012-11-04 03:25:171972
1973 trans.reset();
fdoray92e35a72016-06-10 15:54:551974 base::RunLoop().RunUntilIdle();
[email protected]7a5378b2012-11-04 03:25:171975 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
1976}
1977
[email protected]0b0bf032010-09-21 18:08:501978// Test that we correctly reuse a keep-alive connection after not explicitly
1979// reading the body.
bncd16676a2016-07-20 16:23:011980TEST_F(HttpNetworkTransactionTest, KeepAliveAfterUnreadBody) {
[email protected]fc31d6a42010-06-24 18:05:131981 HttpRequestInfo request;
1982 request.method = "GET";
1983 request.url = GURL("http://www.foo.com/");
[email protected]fc31d6a42010-06-24 18:05:131984
vishal.b62985ca92015-04-17 08:45:511985 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:071986 session_deps_.net_log = &net_log;
danakj1fd259a02016-04-16 03:17:091987 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:271988
mmenkecc2298e2015-12-07 18:20:181989 const char* request_data =
1990 "GET / HTTP/1.1\r\n"
1991 "Host: www.foo.com\r\n"
1992 "Connection: keep-alive\r\n\r\n";
1993 MockWrite data_writes[] = {
1994 MockWrite(ASYNC, 0, request_data), MockWrite(ASYNC, 2, request_data),
1995 MockWrite(ASYNC, 4, request_data), MockWrite(ASYNC, 6, request_data),
1996 MockWrite(ASYNC, 8, request_data), MockWrite(ASYNC, 10, request_data),
1997 MockWrite(ASYNC, 12, request_data), MockWrite(ASYNC, 14, request_data),
1998 MockWrite(ASYNC, 17, request_data), MockWrite(ASYNC, 20, request_data),
1999 };
2000
[email protected]0b0bf032010-09-21 18:08:502001 // Note that because all these reads happen in the same
2002 // StaticSocketDataProvider, it shows that the same socket is being reused for
2003 // all transactions.
mmenkecc2298e2015-12-07 18:20:182004 MockRead data_reads[] = {
2005 MockRead(ASYNC, 1, "HTTP/1.1 204 No Content\r\n\r\n"),
2006 MockRead(ASYNC, 3, "HTTP/1.1 205 Reset Content\r\n\r\n"),
2007 MockRead(ASYNC, 5, "HTTP/1.1 304 Not Modified\r\n\r\n"),
2008 MockRead(ASYNC, 7,
2009 "HTTP/1.1 302 Found\r\n"
2010 "Content-Length: 0\r\n\r\n"),
2011 MockRead(ASYNC, 9,
2012 "HTTP/1.1 302 Found\r\n"
2013 "Content-Length: 5\r\n\r\n"
2014 "hello"),
2015 MockRead(ASYNC, 11,
2016 "HTTP/1.1 301 Moved Permanently\r\n"
2017 "Content-Length: 0\r\n\r\n"),
2018 MockRead(ASYNC, 13,
2019 "HTTP/1.1 301 Moved Permanently\r\n"
2020 "Content-Length: 5\r\n\r\n"
2021 "hello"),
[email protected]fc31d6a42010-06-24 18:05:132022
mmenkecc2298e2015-12-07 18:20:182023 // In the next two rounds, IsConnectedAndIdle returns false, due to
2024 // the set_busy_before_sync_reads(true) call, while the
2025 // HttpNetworkTransaction is being shut down, but the socket is still
2026 // reuseable. See http://crbug.com/544255.
2027 MockRead(ASYNC, 15,
2028 "HTTP/1.1 200 Hunky-Dory\r\n"
2029 "Content-Length: 5\r\n\r\n"),
2030 MockRead(SYNCHRONOUS, 16, "hello"),
[email protected]fc31d6a42010-06-24 18:05:132031
mmenkecc2298e2015-12-07 18:20:182032 MockRead(ASYNC, 18,
2033 "HTTP/1.1 200 Hunky-Dory\r\n"
2034 "Content-Length: 5\r\n\r\n"
2035 "he"),
2036 MockRead(SYNCHRONOUS, 19, "llo"),
2037
2038 // The body of the final request is actually read.
2039 MockRead(ASYNC, 21, "HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
2040 MockRead(ASYNC, 22, "hello"),
2041 };
2042 SequencedSocketData data(data_reads, arraysize(data_reads), data_writes,
2043 arraysize(data_writes));
2044 data.set_busy_before_sync_reads(true);
2045 session_deps_.socket_factory->AddSocketDataProvider(&data);
2046
2047 const int kNumUnreadBodies = arraysize(data_writes) - 1;
[email protected]0b0bf032010-09-21 18:08:502048 std::string response_lines[kNumUnreadBodies];
2049
mikecironef22f9812016-10-04 03:40:192050 uint32_t first_socket_log_id = NetLogSource::kInvalidId;
mmenkecc2298e2015-12-07 18:20:182051 for (size_t i = 0; i < kNumUnreadBodies; ++i) {
[email protected]49639fa2011-12-20 23:22:412052 TestCompletionCallback callback;
[email protected]fc31d6a42010-06-24 18:05:132053
Jeremy Roman0579ed62017-08-29 15:56:192054 auto trans = std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY,
bnc87dcefc2017-05-25 12:47:582055 session.get());
[email protected]fc31d6a42010-06-24 18:05:132056
tfarina42834112016-09-22 13:38:202057 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012058 EXPECT_THAT(callback.GetResult(rv), IsOk());
[email protected]fc31d6a42010-06-24 18:05:132059
[email protected]58e32bb2013-01-21 18:23:252060 LoadTimingInfo load_timing_info;
2061 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
2062 if (i == 0) {
2063 TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_DNS_TIMES);
2064 first_socket_log_id = load_timing_info.socket_log_id;
2065 } else {
2066 TestLoadTimingReused(load_timing_info);
2067 EXPECT_EQ(first_socket_log_id, load_timing_info.socket_log_id);
2068 }
2069
[email protected]fc31d6a42010-06-24 18:05:132070 const HttpResponseInfo* response = trans->GetResponseInfo();
mmenkecc2298e2015-12-07 18:20:182071 ASSERT_TRUE(response);
[email protected]fc31d6a42010-06-24 18:05:132072
mmenkecc2298e2015-12-07 18:20:182073 ASSERT_TRUE(response->headers);
[email protected]0b0bf032010-09-21 18:08:502074 response_lines[i] = response->headers->GetStatusLine();
2075
mmenkecc2298e2015-12-07 18:20:182076 // Delete the transaction without reading the response bodies. Then spin
2077 // the message loop, so the response bodies are drained.
2078 trans.reset();
2079 base::RunLoop().RunUntilIdle();
[email protected]fc31d6a42010-06-24 18:05:132080 }
[email protected]0b0bf032010-09-21 18:08:502081
2082 const char* const kStatusLines[] = {
mmenkecc2298e2015-12-07 18:20:182083 "HTTP/1.1 204 No Content",
2084 "HTTP/1.1 205 Reset Content",
2085 "HTTP/1.1 304 Not Modified",
2086 "HTTP/1.1 302 Found",
2087 "HTTP/1.1 302 Found",
2088 "HTTP/1.1 301 Moved Permanently",
2089 "HTTP/1.1 301 Moved Permanently",
2090 "HTTP/1.1 200 Hunky-Dory",
2091 "HTTP/1.1 200 Hunky-Dory",
[email protected]0b0bf032010-09-21 18:08:502092 };
2093
mostynb91e0da982015-01-20 19:17:272094 static_assert(kNumUnreadBodies == arraysize(kStatusLines),
2095 "forgot to update kStatusLines");
[email protected]0b0bf032010-09-21 18:08:502096
2097 for (int i = 0; i < kNumUnreadBodies; ++i)
2098 EXPECT_EQ(kStatusLines[i], response_lines[i]);
2099
[email protected]49639fa2011-12-20 23:22:412100 TestCompletionCallback callback;
bnc691fda62016-08-12 00:43:162101 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:202102 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012103 EXPECT_THAT(callback.GetResult(rv), IsOk());
bnc691fda62016-08-12 00:43:162104 const HttpResponseInfo* response = trans.GetResponseInfo();
mmenkecc2298e2015-12-07 18:20:182105 ASSERT_TRUE(response);
2106 ASSERT_TRUE(response->headers);
[email protected]0b0bf032010-09-21 18:08:502107 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
2108 std::string response_data;
bnc691fda62016-08-12 00:43:162109 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:012110 EXPECT_THAT(rv, IsOk());
[email protected]0b0bf032010-09-21 18:08:502111 EXPECT_EQ("hello", response_data);
[email protected]fc31d6a42010-06-24 18:05:132112}
2113
mmenke5f94fda2016-06-02 20:54:132114// Sockets that receive extra data after a response is complete should not be
2115// reused.
bncd16676a2016-07-20 16:23:012116TEST_F(HttpNetworkTransactionTest, KeepAliveWithUnusedData1) {
mmenke5f94fda2016-06-02 20:54:132117 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
2118 MockWrite data_writes1[] = {
2119 MockWrite("HEAD / HTTP/1.1\r\n"
2120 "Host: www.borked.com\r\n"
2121 "Connection: keep-alive\r\n\r\n"),
2122 };
2123
2124 MockRead data_reads1[] = {
2125 MockRead("HTTP/1.1 200 OK\r\n"
2126 "Connection: keep-alive\r\n"
2127 "Content-Length: 22\r\n\r\n"
2128 "This server is borked."),
2129 };
2130
2131 MockWrite data_writes2[] = {
2132 MockWrite("GET /foo HTTP/1.1\r\n"
2133 "Host: www.borked.com\r\n"
2134 "Connection: keep-alive\r\n\r\n"),
2135 };
2136
2137 MockRead data_reads2[] = {
2138 MockRead("HTTP/1.1 200 OK\r\n"
2139 "Content-Length: 3\r\n\r\n"
2140 "foo"),
2141 };
2142 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
2143 data_writes1, arraysize(data_writes1));
2144 session_deps_.socket_factory->AddSocketDataProvider(&data1);
2145 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
2146 data_writes2, arraysize(data_writes2));
2147 session_deps_.socket_factory->AddSocketDataProvider(&data2);
2148
2149 TestCompletionCallback callback;
2150 HttpRequestInfo request1;
2151 request1.method = "HEAD";
2152 request1.url = GURL("http://www.borked.com/");
2153
bnc87dcefc2017-05-25 12:47:582154 auto trans1 =
Jeremy Roman0579ed62017-08-29 15:56:192155 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:202156 int rv = trans1->Start(&request1, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012157 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenke5f94fda2016-06-02 20:54:132158
2159 const HttpResponseInfo* response1 = trans1->GetResponseInfo();
2160 ASSERT_TRUE(response1);
2161 ASSERT_TRUE(response1->headers);
2162 EXPECT_EQ(200, response1->headers->response_code());
2163 EXPECT_TRUE(response1->headers->IsKeepAlive());
2164
2165 std::string response_data1;
robpercival214763f2016-07-01 23:27:012166 EXPECT_THAT(ReadTransaction(trans1.get(), &response_data1), IsOk());
mmenke5f94fda2016-06-02 20:54:132167 EXPECT_EQ("", response_data1);
2168 // Deleting the transaction attempts to release the socket back into the
2169 // socket pool.
2170 trans1.reset();
2171
2172 HttpRequestInfo request2;
2173 request2.method = "GET";
2174 request2.url = GURL("http://www.borked.com/foo");
2175
bnc87dcefc2017-05-25 12:47:582176 auto trans2 =
Jeremy Roman0579ed62017-08-29 15:56:192177 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:202178 rv = trans2->Start(&request2, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012179 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenke5f94fda2016-06-02 20:54:132180
2181 const HttpResponseInfo* response2 = trans2->GetResponseInfo();
2182 ASSERT_TRUE(response2);
2183 ASSERT_TRUE(response2->headers);
2184 EXPECT_EQ(200, response2->headers->response_code());
2185
2186 std::string response_data2;
robpercival214763f2016-07-01 23:27:012187 EXPECT_THAT(ReadTransaction(trans2.get(), &response_data2), IsOk());
mmenke5f94fda2016-06-02 20:54:132188 EXPECT_EQ("foo", response_data2);
2189}
2190
bncd16676a2016-07-20 16:23:012191TEST_F(HttpNetworkTransactionTest, KeepAliveWithUnusedData2) {
mmenke5f94fda2016-06-02 20:54:132192 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
2193 MockWrite data_writes1[] = {
2194 MockWrite("GET / HTTP/1.1\r\n"
2195 "Host: www.borked.com\r\n"
2196 "Connection: keep-alive\r\n\r\n"),
2197 };
2198
2199 MockRead data_reads1[] = {
2200 MockRead("HTTP/1.1 200 OK\r\n"
2201 "Connection: keep-alive\r\n"
2202 "Content-Length: 22\r\n\r\n"
2203 "This server is borked."
2204 "Bonus data!"),
2205 };
2206
2207 MockWrite data_writes2[] = {
2208 MockWrite("GET /foo HTTP/1.1\r\n"
2209 "Host: www.borked.com\r\n"
2210 "Connection: keep-alive\r\n\r\n"),
2211 };
2212
2213 MockRead data_reads2[] = {
2214 MockRead("HTTP/1.1 200 OK\r\n"
2215 "Content-Length: 3\r\n\r\n"
2216 "foo"),
2217 };
2218 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
2219 data_writes1, arraysize(data_writes1));
2220 session_deps_.socket_factory->AddSocketDataProvider(&data1);
2221 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
2222 data_writes2, arraysize(data_writes2));
2223 session_deps_.socket_factory->AddSocketDataProvider(&data2);
2224
2225 TestCompletionCallback callback;
2226 HttpRequestInfo request1;
2227 request1.method = "GET";
2228 request1.url = GURL("http://www.borked.com/");
2229
bnc87dcefc2017-05-25 12:47:582230 auto trans1 =
Jeremy Roman0579ed62017-08-29 15:56:192231 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:202232 int rv = trans1->Start(&request1, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012233 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenke5f94fda2016-06-02 20:54:132234
2235 const HttpResponseInfo* response1 = trans1->GetResponseInfo();
2236 ASSERT_TRUE(response1);
2237 ASSERT_TRUE(response1->headers);
2238 EXPECT_EQ(200, response1->headers->response_code());
2239 EXPECT_TRUE(response1->headers->IsKeepAlive());
2240
2241 std::string response_data1;
robpercival214763f2016-07-01 23:27:012242 EXPECT_THAT(ReadTransaction(trans1.get(), &response_data1), IsOk());
mmenke5f94fda2016-06-02 20:54:132243 EXPECT_EQ("This server is borked.", response_data1);
2244 // Deleting the transaction attempts to release the socket back into the
2245 // socket pool.
2246 trans1.reset();
2247
2248 HttpRequestInfo request2;
2249 request2.method = "GET";
2250 request2.url = GURL("http://www.borked.com/foo");
2251
bnc87dcefc2017-05-25 12:47:582252 auto trans2 =
Jeremy Roman0579ed62017-08-29 15:56:192253 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:202254 rv = trans2->Start(&request2, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012255 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenke5f94fda2016-06-02 20:54:132256
2257 const HttpResponseInfo* response2 = trans2->GetResponseInfo();
2258 ASSERT_TRUE(response2);
2259 ASSERT_TRUE(response2->headers);
2260 EXPECT_EQ(200, response2->headers->response_code());
2261
2262 std::string response_data2;
robpercival214763f2016-07-01 23:27:012263 EXPECT_THAT(ReadTransaction(trans2.get(), &response_data2), IsOk());
mmenke5f94fda2016-06-02 20:54:132264 EXPECT_EQ("foo", response_data2);
2265}
2266
bncd16676a2016-07-20 16:23:012267TEST_F(HttpNetworkTransactionTest, KeepAliveWithUnusedData3) {
mmenke5f94fda2016-06-02 20:54:132268 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
2269 MockWrite data_writes1[] = {
2270 MockWrite("GET / HTTP/1.1\r\n"
2271 "Host: www.borked.com\r\n"
2272 "Connection: keep-alive\r\n\r\n"),
2273 };
2274
2275 MockRead data_reads1[] = {
2276 MockRead("HTTP/1.1 200 OK\r\n"
2277 "Connection: keep-alive\r\n"
2278 "Transfer-Encoding: chunked\r\n\r\n"),
2279 MockRead("16\r\nThis server is borked.\r\n"),
2280 MockRead("0\r\n\r\nBonus data!"),
2281 };
2282
2283 MockWrite data_writes2[] = {
2284 MockWrite("GET /foo HTTP/1.1\r\n"
2285 "Host: www.borked.com\r\n"
2286 "Connection: keep-alive\r\n\r\n"),
2287 };
2288
2289 MockRead data_reads2[] = {
2290 MockRead("HTTP/1.1 200 OK\r\n"
2291 "Content-Length: 3\r\n\r\n"
2292 "foo"),
2293 };
2294 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
2295 data_writes1, arraysize(data_writes1));
2296 session_deps_.socket_factory->AddSocketDataProvider(&data1);
2297 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
2298 data_writes2, arraysize(data_writes2));
2299 session_deps_.socket_factory->AddSocketDataProvider(&data2);
2300
2301 TestCompletionCallback callback;
2302 HttpRequestInfo request1;
2303 request1.method = "GET";
2304 request1.url = GURL("http://www.borked.com/");
2305
bnc87dcefc2017-05-25 12:47:582306 auto trans1 =
Jeremy Roman0579ed62017-08-29 15:56:192307 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:202308 int rv = trans1->Start(&request1, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012309 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenke5f94fda2016-06-02 20:54:132310
2311 const HttpResponseInfo* response1 = trans1->GetResponseInfo();
2312 ASSERT_TRUE(response1);
2313 ASSERT_TRUE(response1->headers);
2314 EXPECT_EQ(200, response1->headers->response_code());
2315 EXPECT_TRUE(response1->headers->IsKeepAlive());
2316
2317 std::string response_data1;
robpercival214763f2016-07-01 23:27:012318 EXPECT_THAT(ReadTransaction(trans1.get(), &response_data1), IsOk());
mmenke5f94fda2016-06-02 20:54:132319 EXPECT_EQ("This server is borked.", response_data1);
2320 // Deleting the transaction attempts to release the socket back into the
2321 // socket pool.
2322 trans1.reset();
2323
2324 HttpRequestInfo request2;
2325 request2.method = "GET";
2326 request2.url = GURL("http://www.borked.com/foo");
2327
bnc87dcefc2017-05-25 12:47:582328 auto trans2 =
Jeremy Roman0579ed62017-08-29 15:56:192329 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:202330 rv = trans2->Start(&request2, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012331 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenke5f94fda2016-06-02 20:54:132332
2333 const HttpResponseInfo* response2 = trans2->GetResponseInfo();
2334 ASSERT_TRUE(response2);
2335 ASSERT_TRUE(response2->headers);
2336 EXPECT_EQ(200, response2->headers->response_code());
2337
2338 std::string response_data2;
robpercival214763f2016-07-01 23:27:012339 EXPECT_THAT(ReadTransaction(trans2.get(), &response_data2), IsOk());
mmenke5f94fda2016-06-02 20:54:132340 EXPECT_EQ("foo", response_data2);
2341}
2342
2343// This is a little different from the others - it tests the case that the
2344// HttpStreamParser doesn't know if there's extra data on a socket or not when
2345// the HttpNetworkTransaction is torn down, because the response body hasn't
2346// been read from yet, but the request goes through the HttpResponseBodyDrainer.
bncd16676a2016-07-20 16:23:012347TEST_F(HttpNetworkTransactionTest, KeepAliveWithUnusedData4) {
mmenke5f94fda2016-06-02 20:54:132348 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
2349 MockWrite data_writes1[] = {
2350 MockWrite("GET / HTTP/1.1\r\n"
2351 "Host: www.borked.com\r\n"
2352 "Connection: keep-alive\r\n\r\n"),
2353 };
2354
2355 MockRead data_reads1[] = {
2356 MockRead("HTTP/1.1 200 OK\r\n"
2357 "Connection: keep-alive\r\n"
2358 "Transfer-Encoding: chunked\r\n\r\n"),
2359 MockRead("16\r\nThis server is borked.\r\n"),
2360 MockRead("0\r\n\r\nBonus data!"),
2361 };
2362 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
2363 data_writes1, arraysize(data_writes1));
2364 session_deps_.socket_factory->AddSocketDataProvider(&data1);
2365
2366 TestCompletionCallback callback;
2367 HttpRequestInfo request1;
2368 request1.method = "GET";
2369 request1.url = GURL("http://www.borked.com/");
2370
bnc87dcefc2017-05-25 12:47:582371 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:192372 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
bnc87dcefc2017-05-25 12:47:582373 int rv = trans->Start(&request1, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012374 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenke5f94fda2016-06-02 20:54:132375
bnc87dcefc2017-05-25 12:47:582376 const HttpResponseInfo* response1 = trans->GetResponseInfo();
mmenke5f94fda2016-06-02 20:54:132377 ASSERT_TRUE(response1);
2378 ASSERT_TRUE(response1->headers);
2379 EXPECT_EQ(200, response1->headers->response_code());
2380 EXPECT_TRUE(response1->headers->IsKeepAlive());
2381
2382 // Deleting the transaction creates an HttpResponseBodyDrainer to read the
2383 // response body.
bnc87dcefc2017-05-25 12:47:582384 trans.reset();
mmenke5f94fda2016-06-02 20:54:132385
2386 // Let the HttpResponseBodyDrainer drain the socket. It should determine the
2387 // socket can't be reused, rather than returning it to the socket pool.
2388 base::RunLoop().RunUntilIdle();
2389
2390 // There should be no idle sockets in the pool.
2391 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
2392}
2393
[email protected]038e9a32008-10-08 22:40:162394// Test the request-challenge-retry sequence for basic auth.
2395// (basic auth is the easiest to mock, because it has no randomness).
bncd16676a2016-07-20 16:23:012396TEST_F(HttpNetworkTransactionTest, BasicAuth) {
[email protected]1c773ea12009-04-28 19:58:422397 HttpRequestInfo request;
[email protected]038e9a32008-10-08 22:40:162398 request.method = "GET";
bncce36dca22015-04-21 22:11:232399 request.url = GURL("http://www.example.org/");
[email protected]038e9a32008-10-08 22:40:162400
vishal.b62985ca92015-04-17 08:45:512401 TestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:072402 session_deps_.net_log = &log;
danakj1fd259a02016-04-16 03:17:092403 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:162404 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:272405
[email protected]f9ee6b52008-11-08 06:46:232406 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:232407 MockWrite(
2408 "GET / HTTP/1.1\r\n"
2409 "Host: www.example.org\r\n"
2410 "Connection: keep-alive\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:232411 };
2412
[email protected]038e9a32008-10-08 22:40:162413 MockRead data_reads1[] = {
2414 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
2415 // Give a couple authenticate options (only the middle one is actually
2416 // supported).
[email protected]22927ad2009-09-21 19:56:192417 MockRead("WWW-Authenticate: Basic invalid\r\n"), // Malformed.
[email protected]038e9a32008-10-08 22:40:162418 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2419 MockRead("WWW-Authenticate: UNSUPPORTED realm=\"FOO\"\r\n"),
2420 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
2421 // Large content-length -- won't matter, as connection will be reset.
2422 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:062423 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]038e9a32008-10-08 22:40:162424 };
2425
2426 // After calling trans->RestartWithAuth(), this is the request we should
2427 // be issuing -- the final header line contains the credentials.
2428 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:232429 MockWrite(
2430 "GET / HTTP/1.1\r\n"
2431 "Host: www.example.org\r\n"
2432 "Connection: keep-alive\r\n"
2433 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]038e9a32008-10-08 22:40:162434 };
2435
2436 // Lastly, the server responds with the actual content.
2437 MockRead data_reads2[] = {
2438 MockRead("HTTP/1.0 200 OK\r\n"),
2439 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
2440 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:062441 MockRead(SYNCHRONOUS, OK),
[email protected]038e9a32008-10-08 22:40:162442 };
2443
[email protected]31a2bfe2010-02-09 08:03:392444 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
2445 data_writes1, arraysize(data_writes1));
2446 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
2447 data_writes2, arraysize(data_writes2));
[email protected]bb88e1d32013-05-03 23:11:072448 session_deps_.socket_factory->AddSocketDataProvider(&data1);
2449 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]038e9a32008-10-08 22:40:162450
[email protected]49639fa2011-12-20 23:22:412451 TestCompletionCallback callback1;
[email protected]038e9a32008-10-08 22:40:162452
tfarina42834112016-09-22 13:38:202453 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012454 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]038e9a32008-10-08 22:40:162455
2456 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:012457 EXPECT_THAT(rv, IsOk());
[email protected]038e9a32008-10-08 22:40:162458
[email protected]58e32bb2013-01-21 18:23:252459 LoadTimingInfo load_timing_info1;
bnc691fda62016-08-12 00:43:162460 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info1));
[email protected]58e32bb2013-01-21 18:23:252461 TestLoadTimingNotReused(load_timing_info1, CONNECT_TIMING_HAS_DNS_TIMES);
2462
sclittlefb249892015-09-10 21:33:222463 int64_t writes_size1 = CountWriteBytes(data_writes1, arraysize(data_writes1));
bnc691fda62016-08-12 00:43:162464 EXPECT_EQ(writes_size1, trans.GetTotalSentBytes());
sclittlefb249892015-09-10 21:33:222465 int64_t reads_size1 = CountReadBytes(data_reads1, arraysize(data_reads1));
bnc691fda62016-08-12 00:43:162466 EXPECT_EQ(reads_size1, trans.GetTotalReceivedBytes());
[email protected]b8015c42013-12-24 15:18:192467
bnc691fda62016-08-12 00:43:162468 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:522469 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:042470 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]038e9a32008-10-08 22:40:162471
[email protected]49639fa2011-12-20 23:22:412472 TestCompletionCallback callback2;
[email protected]038e9a32008-10-08 22:40:162473
bnc691fda62016-08-12 00:43:162474 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar), callback2.callback());
robpercival214763f2016-07-01 23:27:012475 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]038e9a32008-10-08 22:40:162476
2477 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:012478 EXPECT_THAT(rv, IsOk());
[email protected]038e9a32008-10-08 22:40:162479
[email protected]58e32bb2013-01-21 18:23:252480 LoadTimingInfo load_timing_info2;
bnc691fda62016-08-12 00:43:162481 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info2));
[email protected]58e32bb2013-01-21 18:23:252482 TestLoadTimingNotReused(load_timing_info2, CONNECT_TIMING_HAS_DNS_TIMES);
2483 // The load timing after restart should have a new socket ID, and times after
2484 // those of the first load timing.
2485 EXPECT_LE(load_timing_info1.receive_headers_end,
2486 load_timing_info2.connect_timing.connect_start);
2487 EXPECT_NE(load_timing_info1.socket_log_id, load_timing_info2.socket_log_id);
2488
sclittlefb249892015-09-10 21:33:222489 int64_t writes_size2 = CountWriteBytes(data_writes2, arraysize(data_writes2));
bnc691fda62016-08-12 00:43:162490 EXPECT_EQ(writes_size1 + writes_size2, trans.GetTotalSentBytes());
sclittlefb249892015-09-10 21:33:222491 int64_t reads_size2 = CountReadBytes(data_reads2, arraysize(data_reads2));
bnc691fda62016-08-12 00:43:162492 EXPECT_EQ(reads_size1 + reads_size2, trans.GetTotalReceivedBytes());
[email protected]b8015c42013-12-24 15:18:192493
bnc691fda62016-08-12 00:43:162494 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:522495 ASSERT_TRUE(response);
2496 EXPECT_FALSE(response->auth_challenge);
[email protected]038e9a32008-10-08 22:40:162497 EXPECT_EQ(100, response->headers->GetContentLength());
[email protected]038e9a32008-10-08 22:40:162498}
2499
ttuttled9dbc652015-09-29 20:00:592500// Test the request-challenge-retry sequence for basic auth.
2501// (basic auth is the easiest to mock, because it has no randomness).
bncd16676a2016-07-20 16:23:012502TEST_F(HttpNetworkTransactionTest, BasicAuthWithAddressChange) {
ttuttled9dbc652015-09-29 20:00:592503 HttpRequestInfo request;
2504 request.method = "GET";
2505 request.url = GURL("http://www.example.org/");
ttuttled9dbc652015-09-29 20:00:592506
2507 TestNetLog log;
2508 MockHostResolver* resolver = new MockHostResolver();
2509 session_deps_.net_log = &log;
2510 session_deps_.host_resolver.reset(resolver);
danakj1fd259a02016-04-16 03:17:092511 std::unique_ptr<HttpNetworkSession> session = CreateSession(&session_deps_);
bnc691fda62016-08-12 00:43:162512 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
ttuttled9dbc652015-09-29 20:00:592513
2514 resolver->rules()->ClearRules();
2515 resolver->rules()->AddRule("www.example.org", "127.0.0.1");
2516
2517 MockWrite data_writes1[] = {
2518 MockWrite("GET / HTTP/1.1\r\n"
2519 "Host: www.example.org\r\n"
2520 "Connection: keep-alive\r\n\r\n"),
2521 };
2522
2523 MockRead data_reads1[] = {
2524 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
2525 // Give a couple authenticate options (only the middle one is actually
2526 // supported).
2527 MockRead("WWW-Authenticate: Basic invalid\r\n"), // Malformed.
2528 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2529 MockRead("WWW-Authenticate: UNSUPPORTED realm=\"FOO\"\r\n"),
2530 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
2531 // Large content-length -- won't matter, as connection will be reset.
2532 MockRead("Content-Length: 10000\r\n\r\n"),
2533 MockRead(SYNCHRONOUS, ERR_FAILED),
2534 };
2535
2536 // After calling trans->RestartWithAuth(), this is the request we should
2537 // be issuing -- the final header line contains the credentials.
2538 MockWrite data_writes2[] = {
2539 MockWrite("GET / HTTP/1.1\r\n"
2540 "Host: www.example.org\r\n"
2541 "Connection: keep-alive\r\n"
2542 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
2543 };
2544
2545 // Lastly, the server responds with the actual content.
2546 MockRead data_reads2[] = {
2547 MockRead("HTTP/1.0 200 OK\r\n"),
2548 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
2549 MockRead("Content-Length: 100\r\n\r\n"), MockRead(SYNCHRONOUS, OK),
2550 };
2551
2552 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
2553 data_writes1, arraysize(data_writes1));
2554 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
2555 data_writes2, arraysize(data_writes2));
2556 session_deps_.socket_factory->AddSocketDataProvider(&data1);
2557 session_deps_.socket_factory->AddSocketDataProvider(&data2);
2558
2559 TestCompletionCallback callback1;
2560
bnc691fda62016-08-12 00:43:162561 EXPECT_EQ(OK, callback1.GetResult(trans.Start(&request, callback1.callback(),
tfarina42834112016-09-22 13:38:202562 NetLogWithSource())));
ttuttled9dbc652015-09-29 20:00:592563
2564 LoadTimingInfo load_timing_info1;
bnc691fda62016-08-12 00:43:162565 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info1));
ttuttled9dbc652015-09-29 20:00:592566 TestLoadTimingNotReused(load_timing_info1, CONNECT_TIMING_HAS_DNS_TIMES);
2567
2568 int64_t writes_size1 = CountWriteBytes(data_writes1, arraysize(data_writes1));
bnc691fda62016-08-12 00:43:162569 EXPECT_EQ(writes_size1, trans.GetTotalSentBytes());
ttuttled9dbc652015-09-29 20:00:592570 int64_t reads_size1 = CountReadBytes(data_reads1, arraysize(data_reads1));
bnc691fda62016-08-12 00:43:162571 EXPECT_EQ(reads_size1, trans.GetTotalReceivedBytes());
ttuttled9dbc652015-09-29 20:00:592572
bnc691fda62016-08-12 00:43:162573 const HttpResponseInfo* response = trans.GetResponseInfo();
ttuttled9dbc652015-09-29 20:00:592574 ASSERT_TRUE(response);
2575 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
2576
2577 IPEndPoint endpoint;
bnc691fda62016-08-12 00:43:162578 EXPECT_TRUE(trans.GetRemoteEndpoint(&endpoint));
ttuttled9dbc652015-09-29 20:00:592579 ASSERT_FALSE(endpoint.address().empty());
2580 EXPECT_EQ("127.0.0.1:80", endpoint.ToString());
2581
2582 resolver->rules()->ClearRules();
2583 resolver->rules()->AddRule("www.example.org", "127.0.0.2");
2584
2585 TestCompletionCallback callback2;
2586
bnc691fda62016-08-12 00:43:162587 EXPECT_EQ(OK, callback2.GetResult(trans.RestartWithAuth(
ttuttled9dbc652015-09-29 20:00:592588 AuthCredentials(kFoo, kBar), callback2.callback())));
2589
2590 LoadTimingInfo load_timing_info2;
bnc691fda62016-08-12 00:43:162591 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info2));
ttuttled9dbc652015-09-29 20:00:592592 TestLoadTimingNotReused(load_timing_info2, CONNECT_TIMING_HAS_DNS_TIMES);
2593 // The load timing after restart should have a new socket ID, and times after
2594 // those of the first load timing.
2595 EXPECT_LE(load_timing_info1.receive_headers_end,
2596 load_timing_info2.connect_timing.connect_start);
2597 EXPECT_NE(load_timing_info1.socket_log_id, load_timing_info2.socket_log_id);
2598
2599 int64_t writes_size2 = CountWriteBytes(data_writes2, arraysize(data_writes2));
bnc691fda62016-08-12 00:43:162600 EXPECT_EQ(writes_size1 + writes_size2, trans.GetTotalSentBytes());
ttuttled9dbc652015-09-29 20:00:592601 int64_t reads_size2 = CountReadBytes(data_reads2, arraysize(data_reads2));
bnc691fda62016-08-12 00:43:162602 EXPECT_EQ(reads_size1 + reads_size2, trans.GetTotalReceivedBytes());
ttuttled9dbc652015-09-29 20:00:592603
bnc691fda62016-08-12 00:43:162604 response = trans.GetResponseInfo();
ttuttled9dbc652015-09-29 20:00:592605 ASSERT_TRUE(response);
wezca1070932016-05-26 20:30:522606 EXPECT_FALSE(response->auth_challenge);
ttuttled9dbc652015-09-29 20:00:592607 EXPECT_EQ(100, response->headers->GetContentLength());
2608
bnc691fda62016-08-12 00:43:162609 EXPECT_TRUE(trans.GetRemoteEndpoint(&endpoint));
ttuttled9dbc652015-09-29 20:00:592610 ASSERT_FALSE(endpoint.address().empty());
2611 EXPECT_EQ("127.0.0.2:80", endpoint.ToString());
2612}
2613
bncd16676a2016-07-20 16:23:012614TEST_F(HttpNetworkTransactionTest, DoNotSendAuth) {
[email protected]861fcd52009-08-26 02:33:462615 HttpRequestInfo request;
2616 request.method = "GET";
bncce36dca22015-04-21 22:11:232617 request.url = GURL("http://www.example.org/");
ttuttle859dc7a2015-04-23 19:42:292618 request.load_flags = LOAD_DO_NOT_SEND_AUTH_DATA;
[email protected]861fcd52009-08-26 02:33:462619
danakj1fd259a02016-04-16 03:17:092620 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:162621 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:272622
[email protected]861fcd52009-08-26 02:33:462623 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:232624 MockWrite(
2625 "GET / HTTP/1.1\r\n"
2626 "Host: www.example.org\r\n"
2627 "Connection: keep-alive\r\n\r\n"),
[email protected]861fcd52009-08-26 02:33:462628 };
2629
2630 MockRead data_reads[] = {
2631 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
2632 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2633 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
2634 // Large content-length -- won't matter, as connection will be reset.
2635 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:062636 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]861fcd52009-08-26 02:33:462637 };
2638
[email protected]31a2bfe2010-02-09 08:03:392639 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
2640 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:072641 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]49639fa2011-12-20 23:22:412642 TestCompletionCallback callback;
[email protected]861fcd52009-08-26 02:33:462643
tfarina42834112016-09-22 13:38:202644 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012645 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]861fcd52009-08-26 02:33:462646
2647 rv = callback.WaitForResult();
2648 EXPECT_EQ(0, rv);
2649
sclittlefb249892015-09-10 21:33:222650 int64_t writes_size = CountWriteBytes(data_writes, arraysize(data_writes));
bnc691fda62016-08-12 00:43:162651 EXPECT_EQ(writes_size, trans.GetTotalSentBytes());
sclittlefb249892015-09-10 21:33:222652 int64_t reads_size = CountReadBytes(data_reads, arraysize(data_reads));
bnc691fda62016-08-12 00:43:162653 EXPECT_EQ(reads_size, trans.GetTotalReceivedBytes());
[email protected]b8015c42013-12-24 15:18:192654
bnc691fda62016-08-12 00:43:162655 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:522656 ASSERT_TRUE(response);
2657 EXPECT_FALSE(response->auth_challenge);
[email protected]861fcd52009-08-26 02:33:462658}
2659
[email protected]2d2697f92009-02-18 21:00:322660// Test the request-challenge-retry sequence for basic auth, over a keep-alive
2661// connection.
bncd16676a2016-07-20 16:23:012662TEST_F(HttpNetworkTransactionTest, BasicAuthKeepAlive) {
mmenkecc2298e2015-12-07 18:20:182663 // On the second pass, the body read of the auth challenge is synchronous, so
2664 // IsConnectedAndIdle returns false. The socket should still be drained and
2665 // reused. See http://crbug.com/544255.
2666 for (int i = 0; i < 2; ++i) {
2667 HttpRequestInfo request;
2668 request.method = "GET";
2669 request.url = GURL("http://www.example.org/");
[email protected]2d2697f92009-02-18 21:00:322670
mmenkecc2298e2015-12-07 18:20:182671 TestNetLog log;
2672 session_deps_.net_log = &log;
danakj1fd259a02016-04-16 03:17:092673 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:272674
mmenkecc2298e2015-12-07 18:20:182675 MockWrite data_writes[] = {
2676 MockWrite(ASYNC, 0,
2677 "GET / HTTP/1.1\r\n"
2678 "Host: www.example.org\r\n"
2679 "Connection: keep-alive\r\n\r\n"),
[email protected]2d2697f92009-02-18 21:00:322680
bnc691fda62016-08-12 00:43:162681 // After calling trans.RestartWithAuth(), this is the request we should
mmenkecc2298e2015-12-07 18:20:182682 // be issuing -- the final header line contains the credentials.
2683 MockWrite(ASYNC, 6,
2684 "GET / HTTP/1.1\r\n"
2685 "Host: www.example.org\r\n"
2686 "Connection: keep-alive\r\n"
2687 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
2688 };
[email protected]2d2697f92009-02-18 21:00:322689
mmenkecc2298e2015-12-07 18:20:182690 MockRead data_reads[] = {
2691 MockRead(ASYNC, 1, "HTTP/1.1 401 Unauthorized\r\n"),
2692 MockRead(ASYNC, 2, "WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2693 MockRead(ASYNC, 3, "Content-Type: text/html; charset=iso-8859-1\r\n"),
2694 MockRead(ASYNC, 4, "Content-Length: 14\r\n\r\n"),
2695 MockRead(i == 0 ? ASYNC : SYNCHRONOUS, 5, "Unauthorized\r\n"),
[email protected]2d2697f92009-02-18 21:00:322696
mmenkecc2298e2015-12-07 18:20:182697 // Lastly, the server responds with the actual content.
2698 MockRead(ASYNC, 7, "HTTP/1.1 200 OK\r\n"),
2699 MockRead(ASYNC, 8, "Content-Type: text/html; charset=iso-8859-1\r\n"),
2700 MockRead(ASYNC, 9, "Content-Length: 5\r\n\r\n"),
2701 MockRead(ASYNC, 10, "Hello"),
2702 };
[email protected]2d2697f92009-02-18 21:00:322703
mmenkecc2298e2015-12-07 18:20:182704 SequencedSocketData data(data_reads, arraysize(data_reads), data_writes,
2705 arraysize(data_writes));
2706 data.set_busy_before_sync_reads(true);
2707 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]2d0a4f92011-05-05 16:38:462708
mmenkecc2298e2015-12-07 18:20:182709 TestCompletionCallback callback1;
[email protected]2d2697f92009-02-18 21:00:322710
bnc691fda62016-08-12 00:43:162711 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:202712 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012713 ASSERT_THAT(callback1.GetResult(rv), IsOk());
[email protected]2d2697f92009-02-18 21:00:322714
mmenkecc2298e2015-12-07 18:20:182715 LoadTimingInfo load_timing_info1;
bnc691fda62016-08-12 00:43:162716 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info1));
mmenkecc2298e2015-12-07 18:20:182717 TestLoadTimingNotReused(load_timing_info1, CONNECT_TIMING_HAS_DNS_TIMES);
[email protected]2d2697f92009-02-18 21:00:322718
bnc691fda62016-08-12 00:43:162719 const HttpResponseInfo* response = trans.GetResponseInfo();
mmenkecc2298e2015-12-07 18:20:182720 ASSERT_TRUE(response);
2721 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]2d2697f92009-02-18 21:00:322722
mmenkecc2298e2015-12-07 18:20:182723 TestCompletionCallback callback2;
[email protected]58e32bb2013-01-21 18:23:252724
bnc691fda62016-08-12 00:43:162725 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar),
2726 callback2.callback());
robpercival214763f2016-07-01 23:27:012727 ASSERT_THAT(callback2.GetResult(rv), IsOk());
[email protected]2d2697f92009-02-18 21:00:322728
mmenkecc2298e2015-12-07 18:20:182729 LoadTimingInfo load_timing_info2;
bnc691fda62016-08-12 00:43:162730 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info2));
mmenkecc2298e2015-12-07 18:20:182731 TestLoadTimingReused(load_timing_info2);
2732 // The load timing after restart should have the same socket ID, and times
2733 // those of the first load timing.
2734 EXPECT_LE(load_timing_info1.receive_headers_end,
2735 load_timing_info2.send_start);
2736 EXPECT_EQ(load_timing_info1.socket_log_id, load_timing_info2.socket_log_id);
[email protected]2d2697f92009-02-18 21:00:322737
bnc691fda62016-08-12 00:43:162738 response = trans.GetResponseInfo();
mmenkecc2298e2015-12-07 18:20:182739 ASSERT_TRUE(response);
2740 EXPECT_FALSE(response->auth_challenge);
2741 EXPECT_EQ(5, response->headers->GetContentLength());
[email protected]2d2697f92009-02-18 21:00:322742
mmenkecc2298e2015-12-07 18:20:182743 std::string response_data;
bnc691fda62016-08-12 00:43:162744 EXPECT_THAT(ReadTransaction(&trans, &response_data), IsOk());
[email protected]2d2697f92009-02-18 21:00:322745
mmenkecc2298e2015-12-07 18:20:182746 int64_t writes_size = CountWriteBytes(data_writes, arraysize(data_writes));
bnc691fda62016-08-12 00:43:162747 EXPECT_EQ(writes_size, trans.GetTotalSentBytes());
mmenkecc2298e2015-12-07 18:20:182748 int64_t reads_size = CountReadBytes(data_reads, arraysize(data_reads));
bnc691fda62016-08-12 00:43:162749 EXPECT_EQ(reads_size, trans.GetTotalReceivedBytes());
mmenkecc2298e2015-12-07 18:20:182750 }
[email protected]2d2697f92009-02-18 21:00:322751}
2752
2753// Test the request-challenge-retry sequence for basic auth, over a keep-alive
2754// connection and with no response body to drain.
bncd16676a2016-07-20 16:23:012755TEST_F(HttpNetworkTransactionTest, BasicAuthKeepAliveNoBody) {
[email protected]1c773ea12009-04-28 19:58:422756 HttpRequestInfo request;
[email protected]2d2697f92009-02-18 21:00:322757 request.method = "GET";
bncce36dca22015-04-21 22:11:232758 request.url = GURL("http://www.example.org/");
[email protected]2d2697f92009-02-18 21:00:322759
danakj1fd259a02016-04-16 03:17:092760 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:272761
[email protected]2d2697f92009-02-18 21:00:322762 MockWrite data_writes1[] = {
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\r\n"),
[email protected]2d2697f92009-02-18 21:00:322766
bnc691fda62016-08-12 00:43:162767 // After calling trans.RestartWithAuth(), this is the request we should
bncce36dca22015-04-21 22:11:232768 // be issuing -- the final header line contains the credentials.
bnc691fda62016-08-12 00:43:162769 MockWrite("GET / HTTP/1.1\r\n"
2770 "Host: www.example.org\r\n"
2771 "Connection: keep-alive\r\n"
2772 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]2d2697f92009-02-18 21:00:322773 };
2774
[email protected]2d2697f92009-02-18 21:00:322775 MockRead data_reads1[] = {
2776 MockRead("HTTP/1.1 401 Unauthorized\r\n"),
2777 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
[email protected]11203f012009-11-12 23:02:312778 MockRead("Content-Length: 0\r\n\r\n"), // No response body.
[email protected]2d2697f92009-02-18 21:00:322779
2780 // Lastly, the server responds with the actual content.
2781 MockRead("HTTP/1.1 200 OK\r\n"),
2782 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
[email protected]0b0bf032010-09-21 18:08:502783 MockRead("Content-Length: 5\r\n\r\n"),
2784 MockRead("hello"),
[email protected]2d2697f92009-02-18 21:00:322785 };
2786
[email protected]2d0a4f92011-05-05 16:38:462787 // An incorrect reconnect would cause this to be read.
2788 MockRead data_reads2[] = {
[email protected]8ddf8322012-02-23 18:08:062789 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]2d0a4f92011-05-05 16:38:462790 };
2791
[email protected]31a2bfe2010-02-09 08:03:392792 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
2793 data_writes1, arraysize(data_writes1));
[email protected]2d0a4f92011-05-05 16:38:462794 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
2795 NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:072796 session_deps_.socket_factory->AddSocketDataProvider(&data1);
2797 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]2d2697f92009-02-18 21:00:322798
[email protected]49639fa2011-12-20 23:22:412799 TestCompletionCallback callback1;
[email protected]2d2697f92009-02-18 21:00:322800
bnc691fda62016-08-12 00:43:162801 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:202802 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012803 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2d2697f92009-02-18 21:00:322804
2805 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:012806 EXPECT_THAT(rv, IsOk());
[email protected]2d2697f92009-02-18 21:00:322807
bnc691fda62016-08-12 00:43:162808 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:522809 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:042810 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]2d2697f92009-02-18 21:00:322811
[email protected]49639fa2011-12-20 23:22:412812 TestCompletionCallback callback2;
[email protected]2d2697f92009-02-18 21:00:322813
bnc691fda62016-08-12 00:43:162814 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar), callback2.callback());
robpercival214763f2016-07-01 23:27:012815 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2d2697f92009-02-18 21:00:322816
2817 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:012818 EXPECT_THAT(rv, IsOk());
[email protected]2d2697f92009-02-18 21:00:322819
bnc691fda62016-08-12 00:43:162820 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:522821 ASSERT_TRUE(response);
2822 EXPECT_FALSE(response->auth_challenge);
[email protected]0b0bf032010-09-21 18:08:502823 EXPECT_EQ(5, response->headers->GetContentLength());
[email protected]2d2697f92009-02-18 21:00:322824}
2825
2826// Test the request-challenge-retry sequence for basic auth, over a keep-alive
2827// connection and with a large response body to drain.
bncd16676a2016-07-20 16:23:012828TEST_F(HttpNetworkTransactionTest, BasicAuthKeepAliveLargeBody) {
[email protected]1c773ea12009-04-28 19:58:422829 HttpRequestInfo request;
[email protected]2d2697f92009-02-18 21:00:322830 request.method = "GET";
bncce36dca22015-04-21 22:11:232831 request.url = GURL("http://www.example.org/");
[email protected]2d2697f92009-02-18 21:00:322832
danakj1fd259a02016-04-16 03:17:092833 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:272834
[email protected]2d2697f92009-02-18 21:00:322835 MockWrite data_writes1[] = {
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\r\n"),
[email protected]2d2697f92009-02-18 21:00:322839
bnc691fda62016-08-12 00:43:162840 // After calling trans.RestartWithAuth(), this is the request we should
bncce36dca22015-04-21 22:11:232841 // be issuing -- the final header line contains the credentials.
bnc691fda62016-08-12 00:43:162842 MockWrite("GET / HTTP/1.1\r\n"
2843 "Host: www.example.org\r\n"
2844 "Connection: keep-alive\r\n"
2845 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]2d2697f92009-02-18 21:00:322846 };
2847
2848 // Respond with 5 kb of response body.
2849 std::string large_body_string("Unauthorized");
2850 large_body_string.append(5 * 1024, ' ');
2851 large_body_string.append("\r\n");
2852
2853 MockRead data_reads1[] = {
2854 MockRead("HTTP/1.1 401 Unauthorized\r\n"),
2855 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2856 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
2857 // 5134 = 12 + 5 * 1024 + 2
2858 MockRead("Content-Length: 5134\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:062859 MockRead(ASYNC, large_body_string.data(), large_body_string.size()),
[email protected]2d2697f92009-02-18 21:00:322860
2861 // Lastly, the server responds with the actual content.
2862 MockRead("HTTP/1.1 200 OK\r\n"),
2863 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
[email protected]0b0bf032010-09-21 18:08:502864 MockRead("Content-Length: 5\r\n\r\n"),
2865 MockRead("hello"),
[email protected]2d2697f92009-02-18 21:00:322866 };
2867
[email protected]2d0a4f92011-05-05 16:38:462868 // An incorrect reconnect would cause this to be read.
2869 MockRead data_reads2[] = {
[email protected]8ddf8322012-02-23 18:08:062870 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]2d0a4f92011-05-05 16:38:462871 };
2872
[email protected]31a2bfe2010-02-09 08:03:392873 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
2874 data_writes1, arraysize(data_writes1));
[email protected]2d0a4f92011-05-05 16:38:462875 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
2876 NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:072877 session_deps_.socket_factory->AddSocketDataProvider(&data1);
2878 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]2d2697f92009-02-18 21:00:322879
[email protected]49639fa2011-12-20 23:22:412880 TestCompletionCallback callback1;
[email protected]2d2697f92009-02-18 21:00:322881
bnc691fda62016-08-12 00:43:162882 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:202883 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012884 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2d2697f92009-02-18 21:00:322885
2886 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:012887 EXPECT_THAT(rv, IsOk());
[email protected]2d2697f92009-02-18 21:00:322888
bnc691fda62016-08-12 00:43:162889 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:522890 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:042891 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]2d2697f92009-02-18 21:00:322892
[email protected]49639fa2011-12-20 23:22:412893 TestCompletionCallback callback2;
[email protected]2d2697f92009-02-18 21:00:322894
bnc691fda62016-08-12 00:43:162895 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar), callback2.callback());
robpercival214763f2016-07-01 23:27:012896 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2d2697f92009-02-18 21:00:322897
2898 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:012899 EXPECT_THAT(rv, IsOk());
[email protected]2d2697f92009-02-18 21:00:322900
bnc691fda62016-08-12 00:43:162901 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:522902 ASSERT_TRUE(response);
2903 EXPECT_FALSE(response->auth_challenge);
[email protected]0b0bf032010-09-21 18:08:502904 EXPECT_EQ(5, response->headers->GetContentLength());
[email protected]2d2697f92009-02-18 21:00:322905}
2906
2907// Test the request-challenge-retry sequence for basic auth, over a keep-alive
[email protected]11203f012009-11-12 23:02:312908// connection, but the server gets impatient and closes the connection.
bncd16676a2016-07-20 16:23:012909TEST_F(HttpNetworkTransactionTest, BasicAuthKeepAliveImpatientServer) {
[email protected]11203f012009-11-12 23:02:312910 HttpRequestInfo request;
2911 request.method = "GET";
bncce36dca22015-04-21 22:11:232912 request.url = GURL("http://www.example.org/");
[email protected]11203f012009-11-12 23:02:312913
danakj1fd259a02016-04-16 03:17:092914 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:272915
[email protected]11203f012009-11-12 23:02:312916 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:232917 MockWrite(
2918 "GET / HTTP/1.1\r\n"
2919 "Host: www.example.org\r\n"
2920 "Connection: keep-alive\r\n\r\n"),
2921 // This simulates the seemingly successful write to a closed connection
2922 // if the bug is not fixed.
2923 MockWrite(
2924 "GET / HTTP/1.1\r\n"
2925 "Host: www.example.org\r\n"
2926 "Connection: keep-alive\r\n"
2927 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]11203f012009-11-12 23:02:312928 };
2929
2930 MockRead data_reads1[] = {
2931 MockRead("HTTP/1.1 401 Unauthorized\r\n"),
2932 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2933 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
2934 MockRead("Content-Length: 14\r\n\r\n"),
2935 // Tell MockTCPClientSocket to simulate the server closing the connection.
[email protected]8ddf8322012-02-23 18:08:062936 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
[email protected]11203f012009-11-12 23:02:312937 MockRead("Unauthorized\r\n"),
[email protected]8ddf8322012-02-23 18:08:062938 MockRead(SYNCHRONOUS, OK), // The server closes the connection.
[email protected]11203f012009-11-12 23:02:312939 };
2940
bnc691fda62016-08-12 00:43:162941 // After calling trans.RestartWithAuth(), this is the request we should
[email protected]11203f012009-11-12 23:02:312942 // be issuing -- the final header line contains the credentials.
2943 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:232944 MockWrite(
2945 "GET / HTTP/1.1\r\n"
2946 "Host: www.example.org\r\n"
2947 "Connection: keep-alive\r\n"
2948 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]11203f012009-11-12 23:02:312949 };
2950
2951 // Lastly, the server responds with the actual content.
2952 MockRead data_reads2[] = {
2953 MockRead("HTTP/1.1 200 OK\r\n"),
2954 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
[email protected]0b0bf032010-09-21 18:08:502955 MockRead("Content-Length: 5\r\n\r\n"),
2956 MockRead("hello"),
[email protected]11203f012009-11-12 23:02:312957 };
2958
[email protected]31a2bfe2010-02-09 08:03:392959 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
2960 data_writes1, arraysize(data_writes1));
2961 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
2962 data_writes2, arraysize(data_writes2));
[email protected]bb88e1d32013-05-03 23:11:072963 session_deps_.socket_factory->AddSocketDataProvider(&data1);
2964 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]11203f012009-11-12 23:02:312965
[email protected]49639fa2011-12-20 23:22:412966 TestCompletionCallback callback1;
[email protected]11203f012009-11-12 23:02:312967
bnc691fda62016-08-12 00:43:162968 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:202969 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012970 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]11203f012009-11-12 23:02:312971
2972 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:012973 EXPECT_THAT(rv, IsOk());
[email protected]11203f012009-11-12 23:02:312974
bnc691fda62016-08-12 00:43:162975 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:522976 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:042977 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]11203f012009-11-12 23:02:312978
[email protected]49639fa2011-12-20 23:22:412979 TestCompletionCallback callback2;
[email protected]11203f012009-11-12 23:02:312980
bnc691fda62016-08-12 00:43:162981 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar), callback2.callback());
robpercival214763f2016-07-01 23:27:012982 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]11203f012009-11-12 23:02:312983
2984 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:012985 EXPECT_THAT(rv, IsOk());
[email protected]11203f012009-11-12 23:02:312986
bnc691fda62016-08-12 00:43:162987 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:522988 ASSERT_TRUE(response);
2989 EXPECT_FALSE(response->auth_challenge);
[email protected]0b0bf032010-09-21 18:08:502990 EXPECT_EQ(5, response->headers->GetContentLength());
[email protected]11203f012009-11-12 23:02:312991}
2992
[email protected]394816e92010-08-03 07:38:592993// Test the request-challenge-retry sequence for basic auth, over a connection
2994// that requires a restart when setting up an SSL tunnel.
bncd16676a2016-07-20 16:23:012995TEST_F(HttpNetworkTransactionTest, BasicAuthProxyNoKeepAliveHttp10) {
ttuttle34f63b52015-03-05 04:33:012996 HttpRequestInfo request;
2997 request.method = "GET";
bncce36dca22015-04-21 22:11:232998 request.url = GURL("https://www.example.org/");
ttuttle34f63b52015-03-05 04:33:012999 // when the no authentication data flag is set.
ttuttle859dc7a2015-04-23 19:42:293000 request.load_flags = LOAD_DO_NOT_SEND_AUTH_DATA;
ttuttle34f63b52015-03-05 04:33:013001
3002 // Configure against proxy server "myproxy:70".
rdsmith82957ad2015-09-16 19:42:033003 session_deps_.proxy_service =
3004 ProxyService::CreateFixedFromPacResult("PROXY myproxy:70");
vishal.b62985ca92015-04-17 08:45:513005 BoundTestNetLog log;
ttuttle34f63b52015-03-05 04:33:013006 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:093007 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
ttuttle34f63b52015-03-05 04:33:013008
3009 // Since we have proxy, should try to establish tunnel.
3010 MockWrite data_writes1[] = {
mmenkee71e15332015-10-07 16:39:543011 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:173012 "Host: www.example.org:443\r\n"
mmenkee71e15332015-10-07 16:39:543013 "Proxy-Connection: keep-alive\r\n\r\n"),
ttuttle34f63b52015-03-05 04:33:013014 };
3015
mmenkee71e15332015-10-07 16:39:543016 // The proxy responds to the connect with a 407, using a non-persistent
ttuttle34f63b52015-03-05 04:33:013017 // connection.
3018 MockRead data_reads1[] = {
3019 // No credentials.
3020 MockRead("HTTP/1.0 407 Proxy Authentication Required\r\n"),
3021 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n\r\n"),
mmenkee71e15332015-10-07 16:39:543022 };
ttuttle34f63b52015-03-05 04:33:013023
mmenkee71e15332015-10-07 16:39:543024 // Since the first connection couldn't be reused, need to establish another
3025 // once given credentials.
3026 MockWrite data_writes2[] = {
3027 // After calling trans->RestartWithAuth(), this is the request we should
3028 // be issuing -- the final header line contains the credentials.
3029 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:173030 "Host: www.example.org:443\r\n"
mmenkee71e15332015-10-07 16:39:543031 "Proxy-Connection: keep-alive\r\n"
3032 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
3033
3034 MockWrite("GET / HTTP/1.1\r\n"
3035 "Host: www.example.org\r\n"
3036 "Connection: keep-alive\r\n\r\n"),
3037 };
3038
3039 MockRead data_reads2[] = {
ttuttle34f63b52015-03-05 04:33:013040 MockRead("HTTP/1.0 200 Connection Established\r\n\r\n"),
3041
3042 MockRead("HTTP/1.1 200 OK\r\n"),
3043 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
3044 MockRead("Content-Length: 5\r\n\r\n"),
3045 MockRead(SYNCHRONOUS, "hello"),
3046 };
3047
3048 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
3049 data_writes1, arraysize(data_writes1));
3050 session_deps_.socket_factory->AddSocketDataProvider(&data1);
mmenkee71e15332015-10-07 16:39:543051 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
3052 data_writes2, arraysize(data_writes2));
3053 session_deps_.socket_factory->AddSocketDataProvider(&data2);
ttuttle34f63b52015-03-05 04:33:013054 SSLSocketDataProvider ssl(ASYNC, OK);
3055 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
3056
3057 TestCompletionCallback callback1;
3058
bnc87dcefc2017-05-25 12:47:583059 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:193060 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
ttuttle34f63b52015-03-05 04:33:013061
3062 int rv = trans->Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:013063 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
ttuttle34f63b52015-03-05 04:33:013064
3065 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:013066 EXPECT_THAT(rv, IsOk());
mmenke43758e62015-05-04 21:09:463067 TestNetLogEntry::List entries;
ttuttle34f63b52015-03-05 04:33:013068 log.GetEntries(&entries);
3069 size_t pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:003070 entries, 0, NetLogEventType::HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
3071 NetLogEventPhase::NONE);
ttuttle34f63b52015-03-05 04:33:013072 ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:003073 entries, pos,
3074 NetLogEventType::HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
3075 NetLogEventPhase::NONE);
ttuttle34f63b52015-03-05 04:33:013076
3077 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:523078 ASSERT_TRUE(response);
ttuttle34f63b52015-03-05 04:33:013079 EXPECT_FALSE(response->headers->IsKeepAlive());
wezca1070932016-05-26 20:30:523080 ASSERT_TRUE(response->headers);
ttuttle34f63b52015-03-05 04:33:013081 EXPECT_EQ(407, response->headers->response_code());
3082 EXPECT_TRUE(HttpVersion(1, 0) == response->headers->GetHttpVersion());
3083 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
3084
3085 LoadTimingInfo load_timing_info;
3086 // CONNECT requests and responses are handled at the connect job level, so
3087 // the transaction does not yet have a connection.
3088 EXPECT_FALSE(trans->GetLoadTimingInfo(&load_timing_info));
3089
3090 TestCompletionCallback callback2;
3091
3092 rv =
3093 trans->RestartWithAuth(AuthCredentials(kFoo, kBar), callback2.callback());
robpercival214763f2016-07-01 23:27:013094 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
ttuttle34f63b52015-03-05 04:33:013095
3096 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:013097 EXPECT_THAT(rv, IsOk());
ttuttle34f63b52015-03-05 04:33:013098
3099 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:523100 ASSERT_TRUE(response);
ttuttle34f63b52015-03-05 04:33:013101
3102 EXPECT_TRUE(response->headers->IsKeepAlive());
3103 EXPECT_EQ(200, response->headers->response_code());
3104 EXPECT_EQ(5, response->headers->GetContentLength());
3105 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
3106
3107 // The password prompt info should not be set.
wezca1070932016-05-26 20:30:523108 EXPECT_FALSE(response->auth_challenge);
ttuttle34f63b52015-03-05 04:33:013109
3110 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
3111 TestLoadTimingNotReusedWithPac(load_timing_info,
3112 CONNECT_TIMING_HAS_SSL_TIMES);
3113
3114 trans.reset();
3115 session->CloseAllConnections();
3116}
3117
3118// Test the request-challenge-retry sequence for basic auth, over a connection
3119// that requires a restart when setting up an SSL tunnel.
bncd16676a2016-07-20 16:23:013120TEST_F(HttpNetworkTransactionTest, BasicAuthProxyNoKeepAliveHttp11) {
[email protected]394816e92010-08-03 07:38:593121 HttpRequestInfo request;
3122 request.method = "GET";
bncce36dca22015-04-21 22:11:233123 request.url = GURL("https://www.example.org/");
[email protected]394816e92010-08-03 07:38:593124 // when the no authentication data flag is set.
ttuttle859dc7a2015-04-23 19:42:293125 request.load_flags = LOAD_DO_NOT_SEND_AUTH_DATA;
[email protected]394816e92010-08-03 07:38:593126
[email protected]cb9bf6ca2011-01-28 13:15:273127 // Configure against proxy server "myproxy:70".
rdsmith82957ad2015-09-16 19:42:033128 session_deps_.proxy_service =
3129 ProxyService::CreateFixedFromPacResult("PROXY myproxy:70");
vishal.b62985ca92015-04-17 08:45:513130 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:073131 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:093132 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:273133
[email protected]394816e92010-08-03 07:38:593134 // Since we have proxy, should try to establish tunnel.
3135 MockWrite data_writes1[] = {
mmenkee71e15332015-10-07 16:39:543136 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:173137 "Host: www.example.org:443\r\n"
mmenkee71e15332015-10-07 16:39:543138 "Proxy-Connection: keep-alive\r\n\r\n"),
mmenkee0b5c882015-08-26 20:29:113139 };
3140
mmenkee71e15332015-10-07 16:39:543141 // The proxy responds to the connect with a 407, using a non-persistent
mmenke0fd148d2015-09-30 23:00:083142 // connection.
3143 MockRead data_reads1[] = {
mmenkee71e15332015-10-07 16:39:543144 // No credentials.
3145 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
3146 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
3147 MockRead("Proxy-Connection: close\r\n\r\n"),
3148 };
mmenkee0b5c882015-08-26 20:29:113149
mmenkee71e15332015-10-07 16:39:543150 MockWrite data_writes2[] = {
3151 // After calling trans->RestartWithAuth(), this is the request we should
3152 // be issuing -- the final header line contains the credentials.
3153 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:173154 "Host: www.example.org:443\r\n"
mmenkee71e15332015-10-07 16:39:543155 "Proxy-Connection: keep-alive\r\n"
3156 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
mmenke0fd148d2015-09-30 23:00:083157
mmenkee71e15332015-10-07 16:39:543158 MockWrite("GET / HTTP/1.1\r\n"
3159 "Host: www.example.org\r\n"
3160 "Connection: keep-alive\r\n\r\n"),
3161 };
3162
3163 MockRead data_reads2[] = {
3164 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
3165
3166 MockRead("HTTP/1.1 200 OK\r\n"),
3167 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
3168 MockRead("Content-Length: 5\r\n\r\n"),
3169 MockRead(SYNCHRONOUS, "hello"),
[email protected]394816e92010-08-03 07:38:593170 };
3171
3172 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
3173 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:073174 session_deps_.socket_factory->AddSocketDataProvider(&data1);
mmenkee71e15332015-10-07 16:39:543175 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
3176 data_writes2, arraysize(data_writes2));
3177 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]8ddf8322012-02-23 18:08:063178 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:073179 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]394816e92010-08-03 07:38:593180
[email protected]49639fa2011-12-20 23:22:413181 TestCompletionCallback callback1;
[email protected]394816e92010-08-03 07:38:593182
bnc87dcefc2017-05-25 12:47:583183 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:193184 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]0b0bf032010-09-21 18:08:503185
[email protected]49639fa2011-12-20 23:22:413186 int rv = trans->Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:013187 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]394816e92010-08-03 07:38:593188
3189 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:013190 EXPECT_THAT(rv, IsOk());
mmenke43758e62015-05-04 21:09:463191 TestNetLogEntry::List entries;
[email protected]b2fcd0e2010-12-01 15:19:403192 log.GetEntries(&entries);
[email protected]394816e92010-08-03 07:38:593193 size_t pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:003194 entries, 0, NetLogEventType::HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
3195 NetLogEventPhase::NONE);
[email protected]394816e92010-08-03 07:38:593196 ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:403197 entries, pos,
mikecirone8b85c432016-09-08 19:11:003198 NetLogEventType::HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
3199 NetLogEventPhase::NONE);
[email protected]394816e92010-08-03 07:38:593200
3201 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:523202 ASSERT_TRUE(response);
ttuttle34f63b52015-03-05 04:33:013203 EXPECT_FALSE(response->headers->IsKeepAlive());
wezca1070932016-05-26 20:30:523204 ASSERT_TRUE(response->headers);
[email protected]394816e92010-08-03 07:38:593205 EXPECT_EQ(407, response->headers->response_code());
3206 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
[email protected]79cb5c12011-09-12 13:12:043207 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
[email protected]394816e92010-08-03 07:38:593208
[email protected]029c83b62013-01-24 05:28:203209 LoadTimingInfo load_timing_info;
3210 // CONNECT requests and responses are handled at the connect job level, so
3211 // the transaction does not yet have a connection.
3212 EXPECT_FALSE(trans->GetLoadTimingInfo(&load_timing_info));
3213
[email protected]49639fa2011-12-20 23:22:413214 TestCompletionCallback callback2;
[email protected]394816e92010-08-03 07:38:593215
[email protected]49639fa2011-12-20 23:22:413216 rv = trans->RestartWithAuth(
3217 AuthCredentials(kFoo, kBar), callback2.callback());
robpercival214763f2016-07-01 23:27:013218 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]394816e92010-08-03 07:38:593219
3220 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:013221 EXPECT_THAT(rv, IsOk());
[email protected]394816e92010-08-03 07:38:593222
3223 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:523224 ASSERT_TRUE(response);
[email protected]394816e92010-08-03 07:38:593225
3226 EXPECT_TRUE(response->headers->IsKeepAlive());
3227 EXPECT_EQ(200, response->headers->response_code());
[email protected]0b0bf032010-09-21 18:08:503228 EXPECT_EQ(5, response->headers->GetContentLength());
[email protected]394816e92010-08-03 07:38:593229 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
3230
3231 // The password prompt info should not be set.
wezca1070932016-05-26 20:30:523232 EXPECT_FALSE(response->auth_challenge);
[email protected]0b0bf032010-09-21 18:08:503233
[email protected]029c83b62013-01-24 05:28:203234 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
3235 TestLoadTimingNotReusedWithPac(load_timing_info,
3236 CONNECT_TIMING_HAS_SSL_TIMES);
3237
[email protected]0b0bf032010-09-21 18:08:503238 trans.reset();
[email protected]102e27c2011-02-23 01:01:313239 session->CloseAllConnections();
[email protected]394816e92010-08-03 07:38:593240}
3241
[email protected]11203f012009-11-12 23:02:313242// Test the request-challenge-retry sequence for basic auth, over a keep-alive
ttuttle34f63b52015-03-05 04:33:013243// proxy connection with HTTP/1.0 responses, when setting up an SSL tunnel.
bncd16676a2016-07-20 16:23:013244TEST_F(HttpNetworkTransactionTest, BasicAuthProxyKeepAliveHttp10) {
mmenked39192ee2015-12-09 00:57:233245 // On the second pass, the body read of the auth challenge is synchronous, so
3246 // IsConnectedAndIdle returns false. The socket should still be drained and
3247 // reused. See http://crbug.com/544255.
3248 for (int i = 0; i < 2; ++i) {
3249 HttpRequestInfo request;
3250 request.method = "GET";
3251 request.url = GURL("https://www.example.org/");
3252 // Ensure that proxy authentication is attempted even
3253 // when the no authentication data flag is set.
3254 request.load_flags = LOAD_DO_NOT_SEND_AUTH_DATA;
ttuttle34f63b52015-03-05 04:33:013255
mmenked39192ee2015-12-09 00:57:233256 // Configure against proxy server "myproxy:70".
3257 session_deps_.proxy_service = ProxyService::CreateFixed("myproxy:70");
3258 BoundTestNetLog log;
3259 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:093260 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
ttuttle34f63b52015-03-05 04:33:013261
bnc691fda62016-08-12 00:43:163262 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
ttuttle34f63b52015-03-05 04:33:013263
mmenked39192ee2015-12-09 00:57:233264 // Since we have proxy, should try to establish tunnel.
3265 MockWrite data_writes1[] = {
3266 MockWrite(ASYNC, 0,
3267 "CONNECT www.example.org:443 HTTP/1.1\r\n"
3268 "Host: www.example.org:443\r\n"
3269 "Proxy-Connection: keep-alive\r\n\r\n"),
ttuttle34f63b52015-03-05 04:33:013270
bnc691fda62016-08-12 00:43:163271 // After calling trans.RestartWithAuth(), this is the request we should
mmenked39192ee2015-12-09 00:57:233272 // be issuing -- the final header line contains the credentials.
3273 MockWrite(ASYNC, 3,
3274 "CONNECT www.example.org:443 HTTP/1.1\r\n"
3275 "Host: www.example.org:443\r\n"
3276 "Proxy-Connection: keep-alive\r\n"
3277 "Proxy-Authorization: Basic Zm9vOmJheg==\r\n\r\n"),
3278 };
ttuttle34f63b52015-03-05 04:33:013279
mmenked39192ee2015-12-09 00:57:233280 // The proxy responds to the connect with a 407, using a persistent
3281 // connection. (Since it's HTTP/1.0, keep-alive has to be explicit.)
3282 MockRead data_reads1[] = {
3283 // No credentials.
3284 MockRead(ASYNC, 1,
3285 "HTTP/1.0 407 Proxy Authentication Required\r\n"
3286 "Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"
3287 "Proxy-Connection: keep-alive\r\n"
3288 "Content-Length: 10\r\n\r\n"),
3289 MockRead(i == 0 ? ASYNC : SYNCHRONOUS, 2, "0123456789"),
ttuttle34f63b52015-03-05 04:33:013290
mmenked39192ee2015-12-09 00:57:233291 // Wrong credentials (wrong password).
3292 MockRead(ASYNC, 4,
3293 "HTTP/1.0 407 Proxy Authentication Required\r\n"
3294 "Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"
3295 "Proxy-Connection: keep-alive\r\n"
3296 "Content-Length: 10\r\n\r\n"),
3297 // No response body because the test stops reading here.
3298 MockRead(SYNCHRONOUS, ERR_UNEXPECTED, 5),
3299 };
ttuttle34f63b52015-03-05 04:33:013300
mmenked39192ee2015-12-09 00:57:233301 SequencedSocketData data1(data_reads1, arraysize(data_reads1), data_writes1,
3302 arraysize(data_writes1));
3303 data1.set_busy_before_sync_reads(true);
3304 session_deps_.socket_factory->AddSocketDataProvider(&data1);
ttuttle34f63b52015-03-05 04:33:013305
mmenked39192ee2015-12-09 00:57:233306 TestCompletionCallback callback1;
ttuttle34f63b52015-03-05 04:33:013307
bnc691fda62016-08-12 00:43:163308 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:013309 EXPECT_THAT(callback1.GetResult(rv), IsOk());
ttuttle34f63b52015-03-05 04:33:013310
mmenked39192ee2015-12-09 00:57:233311 TestNetLogEntry::List entries;
3312 log.GetEntries(&entries);
3313 size_t pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:003314 entries, 0, NetLogEventType::HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
3315 NetLogEventPhase::NONE);
mmenked39192ee2015-12-09 00:57:233316 ExpectLogContainsSomewhere(
3317 entries, pos,
mikecirone8b85c432016-09-08 19:11:003318 NetLogEventType::HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
3319 NetLogEventPhase::NONE);
ttuttle34f63b52015-03-05 04:33:013320
bnc691fda62016-08-12 00:43:163321 const HttpResponseInfo* response = trans.GetResponseInfo();
mmenked39192ee2015-12-09 00:57:233322 ASSERT_TRUE(response);
3323 ASSERT_TRUE(response->headers);
3324 EXPECT_TRUE(response->headers->IsKeepAlive());
3325 EXPECT_EQ(407, response->headers->response_code());
3326 EXPECT_EQ(10, response->headers->GetContentLength());
3327 EXPECT_TRUE(HttpVersion(1, 0) == response->headers->GetHttpVersion());
3328 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
ttuttle34f63b52015-03-05 04:33:013329
mmenked39192ee2015-12-09 00:57:233330 TestCompletionCallback callback2;
ttuttle34f63b52015-03-05 04:33:013331
mmenked39192ee2015-12-09 00:57:233332 // Wrong password (should be "bar").
bnc691fda62016-08-12 00:43:163333 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBaz),
3334 callback2.callback());
robpercival214763f2016-07-01 23:27:013335 EXPECT_THAT(callback2.GetResult(rv), IsOk());
ttuttle34f63b52015-03-05 04:33:013336
bnc691fda62016-08-12 00:43:163337 response = trans.GetResponseInfo();
mmenked39192ee2015-12-09 00:57:233338 ASSERT_TRUE(response);
3339 ASSERT_TRUE(response->headers);
3340 EXPECT_TRUE(response->headers->IsKeepAlive());
3341 EXPECT_EQ(407, response->headers->response_code());
3342 EXPECT_EQ(10, response->headers->GetContentLength());
3343 EXPECT_TRUE(HttpVersion(1, 0) == response->headers->GetHttpVersion());
3344 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
ttuttle34f63b52015-03-05 04:33:013345
mmenked39192ee2015-12-09 00:57:233346 // Flush the idle socket before the NetLog and HttpNetworkTransaction go
3347 // out of scope.
3348 session->CloseAllConnections();
3349 }
ttuttle34f63b52015-03-05 04:33:013350}
3351
3352// Test the request-challenge-retry sequence for basic auth, over a keep-alive
3353// proxy connection with HTTP/1.1 responses, when setting up an SSL tunnel.
bncd16676a2016-07-20 16:23:013354TEST_F(HttpNetworkTransactionTest, BasicAuthProxyKeepAliveHttp11) {
mmenked39192ee2015-12-09 00:57:233355 // On the second pass, the body read of the auth challenge is synchronous, so
3356 // IsConnectedAndIdle returns false. The socket should still be drained and
3357 // reused. See http://crbug.com/544255.
3358 for (int i = 0; i < 2; ++i) {
3359 HttpRequestInfo request;
3360 request.method = "GET";
3361 request.url = GURL("https://www.example.org/");
3362 // Ensure that proxy authentication is attempted even
3363 // when the no authentication data flag is set.
3364 request.load_flags = LOAD_DO_NOT_SEND_AUTH_DATA;
3365
3366 // Configure against proxy server "myproxy:70".
3367 session_deps_.proxy_service = ProxyService::CreateFixed("myproxy:70");
3368 BoundTestNetLog log;
3369 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:093370 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
mmenked39192ee2015-12-09 00:57:233371
bnc691fda62016-08-12 00:43:163372 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
mmenked39192ee2015-12-09 00:57:233373
3374 // Since we have proxy, should try to establish tunnel.
3375 MockWrite data_writes1[] = {
3376 MockWrite(ASYNC, 0,
3377 "CONNECT www.example.org:443 HTTP/1.1\r\n"
3378 "Host: www.example.org:443\r\n"
3379 "Proxy-Connection: keep-alive\r\n\r\n"),
3380
bnc691fda62016-08-12 00:43:163381 // After calling trans.RestartWithAuth(), this is the request we should
mmenked39192ee2015-12-09 00:57:233382 // be issuing -- the final header line contains the credentials.
3383 MockWrite(ASYNC, 3,
3384 "CONNECT www.example.org:443 HTTP/1.1\r\n"
3385 "Host: www.example.org:443\r\n"
3386 "Proxy-Connection: keep-alive\r\n"
3387 "Proxy-Authorization: Basic Zm9vOmJheg==\r\n\r\n"),
3388 };
3389
3390 // The proxy responds to the connect with a 407, using a persistent
3391 // connection. (Since it's HTTP/1.0, keep-alive has to be explicit.)
3392 MockRead data_reads1[] = {
3393 // No credentials.
3394 MockRead(ASYNC, 1,
3395 "HTTP/1.1 407 Proxy Authentication Required\r\n"
3396 "Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"
3397 "Content-Length: 10\r\n\r\n"),
3398 MockRead(i == 0 ? ASYNC : SYNCHRONOUS, 2, "0123456789"),
3399
3400 // Wrong credentials (wrong password).
3401 MockRead(ASYNC, 4,
3402 "HTTP/1.1 407 Proxy Authentication Required\r\n"
3403 "Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"
3404 "Content-Length: 10\r\n\r\n"),
3405 // No response body because the test stops reading here.
3406 MockRead(SYNCHRONOUS, ERR_UNEXPECTED, 5),
3407 };
3408
3409 SequencedSocketData data1(data_reads1, arraysize(data_reads1), data_writes1,
3410 arraysize(data_writes1));
3411 data1.set_busy_before_sync_reads(true);
3412 session_deps_.socket_factory->AddSocketDataProvider(&data1);
3413
3414 TestCompletionCallback callback1;
3415
bnc691fda62016-08-12 00:43:163416 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:013417 EXPECT_THAT(callback1.GetResult(rv), IsOk());
mmenked39192ee2015-12-09 00:57:233418
3419 TestNetLogEntry::List entries;
3420 log.GetEntries(&entries);
3421 size_t pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:003422 entries, 0, NetLogEventType::HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
3423 NetLogEventPhase::NONE);
mmenked39192ee2015-12-09 00:57:233424 ExpectLogContainsSomewhere(
3425 entries, pos,
mikecirone8b85c432016-09-08 19:11:003426 NetLogEventType::HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
3427 NetLogEventPhase::NONE);
mmenked39192ee2015-12-09 00:57:233428
bnc691fda62016-08-12 00:43:163429 const HttpResponseInfo* response = trans.GetResponseInfo();
mmenked39192ee2015-12-09 00:57:233430 ASSERT_TRUE(response);
3431 ASSERT_TRUE(response->headers);
3432 EXPECT_TRUE(response->headers->IsKeepAlive());
3433 EXPECT_EQ(407, response->headers->response_code());
3434 EXPECT_EQ(10, response->headers->GetContentLength());
3435 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
3436 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
3437
3438 TestCompletionCallback callback2;
3439
3440 // Wrong password (should be "bar").
bnc691fda62016-08-12 00:43:163441 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBaz),
3442 callback2.callback());
robpercival214763f2016-07-01 23:27:013443 EXPECT_THAT(callback2.GetResult(rv), IsOk());
mmenked39192ee2015-12-09 00:57:233444
bnc691fda62016-08-12 00:43:163445 response = trans.GetResponseInfo();
mmenked39192ee2015-12-09 00:57:233446 ASSERT_TRUE(response);
3447 ASSERT_TRUE(response->headers);
3448 EXPECT_TRUE(response->headers->IsKeepAlive());
3449 EXPECT_EQ(407, response->headers->response_code());
3450 EXPECT_EQ(10, response->headers->GetContentLength());
3451 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
3452 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
3453
3454 // Flush the idle socket before the NetLog and HttpNetworkTransaction go
3455 // out of scope.
3456 session->CloseAllConnections();
3457 }
3458}
3459
3460// Test the request-challenge-retry sequence for basic auth, over a keep-alive
3461// proxy connection with HTTP/1.1 responses, when setting up an SSL tunnel, in
3462// the case the server sends extra data on the original socket, so it can't be
3463// reused.
bncd16676a2016-07-20 16:23:013464TEST_F(HttpNetworkTransactionTest, BasicAuthProxyKeepAliveExtraData) {
[email protected]cb9bf6ca2011-01-28 13:15:273465 HttpRequestInfo request;
3466 request.method = "GET";
bncce36dca22015-04-21 22:11:233467 request.url = GURL("https://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:273468 // when the no authentication data flag is set.
ttuttle859dc7a2015-04-23 19:42:293469 request.load_flags = LOAD_DO_NOT_SEND_AUTH_DATA;
[email protected]cb9bf6ca2011-01-28 13:15:273470
[email protected]2d2697f92009-02-18 21:00:323471 // Configure against proxy server "myproxy:70".
mmenked39192ee2015-12-09 00:57:233472 session_deps_.proxy_service =
3473 ProxyService::CreateFixedFromPacResult("PROXY myproxy:70");
vishal.b62985ca92015-04-17 08:45:513474 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:073475 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:093476 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]2d2697f92009-02-18 21:00:323477
[email protected]2d2697f92009-02-18 21:00:323478 // Since we have proxy, should try to establish tunnel.
3479 MockWrite data_writes1[] = {
mmenked39192ee2015-12-09 00:57:233480 MockWrite(ASYNC, 0,
3481 "CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:173482 "Host: www.example.org:443\r\n"
3483 "Proxy-Connection: keep-alive\r\n\r\n"),
mmenked39192ee2015-12-09 00:57:233484 };
[email protected]2d2697f92009-02-18 21:00:323485
mmenked39192ee2015-12-09 00:57:233486 // The proxy responds to the connect with a 407, using a persistent, but sends
3487 // extra data, so the socket cannot be reused.
3488 MockRead data_reads1[] = {
3489 // No credentials.
3490 MockRead(ASYNC, 1,
3491 "HTTP/1.1 407 Proxy Authentication Required\r\n"
3492 "Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"
3493 "Content-Length: 10\r\n\r\n"),
3494 MockRead(SYNCHRONOUS, 2, "0123456789"),
3495 MockRead(SYNCHRONOUS, 3, "I'm broken!"),
3496 };
3497
3498 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:233499 // After calling trans->RestartWithAuth(), this is the request we should
3500 // be issuing -- the final header line contains the credentials.
mmenked39192ee2015-12-09 00:57:233501 MockWrite(ASYNC, 0,
3502 "CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:173503 "Host: www.example.org:443\r\n"
3504 "Proxy-Connection: keep-alive\r\n"
mmenked39192ee2015-12-09 00:57:233505 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
3506
3507 MockWrite(ASYNC, 2,
3508 "GET / HTTP/1.1\r\n"
3509 "Host: www.example.org\r\n"
3510 "Connection: keep-alive\r\n\r\n"),
[email protected]2d2697f92009-02-18 21:00:323511 };
3512
mmenked39192ee2015-12-09 00:57:233513 MockRead data_reads2[] = {
3514 MockRead(ASYNC, 1, "HTTP/1.1 200 Connection Established\r\n\r\n"),
[email protected]2d2697f92009-02-18 21:00:323515
mmenked39192ee2015-12-09 00:57:233516 MockRead(ASYNC, 3,
3517 "HTTP/1.1 200 OK\r\n"
3518 "Content-Type: text/html; charset=iso-8859-1\r\n"
3519 "Content-Length: 5\r\n\r\n"),
3520 // No response body because the test stops reading here.
3521 MockRead(SYNCHRONOUS, ERR_UNEXPECTED, 4),
[email protected]2d2697f92009-02-18 21:00:323522 };
3523
mmenked39192ee2015-12-09 00:57:233524 SequencedSocketData data1(data_reads1, arraysize(data_reads1), data_writes1,
3525 arraysize(data_writes1));
3526 data1.set_busy_before_sync_reads(true);
[email protected]bb88e1d32013-05-03 23:11:073527 session_deps_.socket_factory->AddSocketDataProvider(&data1);
mmenked39192ee2015-12-09 00:57:233528 SequencedSocketData data2(data_reads2, arraysize(data_reads2), data_writes2,
3529 arraysize(data_writes2));
3530 session_deps_.socket_factory->AddSocketDataProvider(&data2);
3531 SSLSocketDataProvider ssl(ASYNC, OK);
3532 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]2d2697f92009-02-18 21:00:323533
[email protected]49639fa2011-12-20 23:22:413534 TestCompletionCallback callback1;
[email protected]2d2697f92009-02-18 21:00:323535
bnc87dcefc2017-05-25 12:47:583536 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:193537 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]2d2697f92009-02-18 21:00:323538
mmenked39192ee2015-12-09 00:57:233539 int rv = trans->Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:013540 EXPECT_THAT(callback1.GetResult(rv), IsOk());
mmenked39192ee2015-12-09 00:57:233541
mmenke43758e62015-05-04 21:09:463542 TestNetLogEntry::List entries;
[email protected]b2fcd0e2010-12-01 15:19:403543 log.GetEntries(&entries);
[email protected]dbb83db2010-05-11 18:13:393544 size_t pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:003545 entries, 0, NetLogEventType::HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
3546 NetLogEventPhase::NONE);
[email protected]dbb83db2010-05-11 18:13:393547 ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:403548 entries, pos,
mikecirone8b85c432016-09-08 19:11:003549 NetLogEventType::HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
3550 NetLogEventPhase::NONE);
[email protected]2d2697f92009-02-18 21:00:323551
[email protected]1c773ea12009-04-28 19:58:423552 const HttpResponseInfo* response = trans->GetResponseInfo();
ttuttle7933c112015-01-06 00:55:243553 ASSERT_TRUE(response);
3554 ASSERT_TRUE(response->headers);
[email protected]2d2697f92009-02-18 21:00:323555 EXPECT_TRUE(response->headers->IsKeepAlive());
3556 EXPECT_EQ(407, response->headers->response_code());
[email protected]1c773ea12009-04-28 19:58:423557 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
[email protected]79cb5c12011-09-12 13:12:043558 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
[email protected]2d2697f92009-02-18 21:00:323559
mmenked39192ee2015-12-09 00:57:233560 LoadTimingInfo load_timing_info;
3561 // CONNECT requests and responses are handled at the connect job level, so
3562 // the transaction does not yet have a connection.
3563 EXPECT_FALSE(trans->GetLoadTimingInfo(&load_timing_info));
3564
[email protected]49639fa2011-12-20 23:22:413565 TestCompletionCallback callback2;
[email protected]2d2697f92009-02-18 21:00:323566
mmenked39192ee2015-12-09 00:57:233567 rv =
3568 trans->RestartWithAuth(AuthCredentials(kFoo, kBar), callback2.callback());
robpercival214763f2016-07-01 23:27:013569 EXPECT_THAT(callback2.GetResult(rv), IsOk());
[email protected]2d2697f92009-02-18 21:00:323570
[email protected]2d2697f92009-02-18 21:00:323571 EXPECT_TRUE(response->headers->IsKeepAlive());
mmenked39192ee2015-12-09 00:57:233572 EXPECT_EQ(200, response->headers->response_code());
3573 EXPECT_EQ(5, response->headers->GetContentLength());
[email protected]1c773ea12009-04-28 19:58:423574 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
[email protected]e772db3f2010-07-12 18:11:133575
mmenked39192ee2015-12-09 00:57:233576 // The password prompt info should not be set.
3577 EXPECT_FALSE(response->auth_challenge);
3578
3579 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
3580 TestLoadTimingNotReusedWithPac(load_timing_info,
3581 CONNECT_TIMING_HAS_SSL_TIMES);
3582
3583 trans.reset();
[email protected]102e27c2011-02-23 01:01:313584 session->CloseAllConnections();
[email protected]2d2697f92009-02-18 21:00:323585}
3586
mmenkee71e15332015-10-07 16:39:543587// Test the case a proxy closes a socket while the challenge body is being
3588// drained.
bncd16676a2016-07-20 16:23:013589TEST_F(HttpNetworkTransactionTest, BasicAuthProxyKeepAliveHangupDuringBody) {
mmenkee71e15332015-10-07 16:39:543590 HttpRequestInfo request;
3591 request.method = "GET";
3592 request.url = GURL("https://www.example.org/");
3593 // Ensure that proxy authentication is attempted even
3594 // when the no authentication data flag is set.
3595 request.load_flags = LOAD_DO_NOT_SEND_AUTH_DATA;
3596
3597 // Configure against proxy server "myproxy:70".
3598 session_deps_.proxy_service = ProxyService::CreateFixed("myproxy:70");
danakj1fd259a02016-04-16 03:17:093599 std::unique_ptr<HttpNetworkSession> session = CreateSession(&session_deps_);
mmenkee71e15332015-10-07 16:39:543600
bnc691fda62016-08-12 00:43:163601 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
mmenkee71e15332015-10-07 16:39:543602
3603 // Since we have proxy, should try to establish tunnel.
3604 MockWrite data_writes1[] = {
3605 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:173606 "Host: www.example.org:443\r\n"
mmenkee71e15332015-10-07 16:39:543607 "Proxy-Connection: keep-alive\r\n\r\n"),
3608 };
3609
3610 // The proxy responds to the connect with a 407, using a persistent
3611 // connection.
3612 MockRead data_reads1[] = {
3613 // No credentials.
3614 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
3615 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
3616 MockRead("Content-Length: 10\r\n\r\n"), MockRead("spam!"),
3617 // Server hands up in the middle of the body.
3618 MockRead(ASYNC, ERR_CONNECTION_CLOSED),
3619 };
3620
3621 MockWrite data_writes2[] = {
bnc691fda62016-08-12 00:43:163622 // After calling trans.RestartWithAuth(), this is the request we should
mmenkee71e15332015-10-07 16:39:543623 // be issuing -- the final header line contains the credentials.
3624 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:173625 "Host: www.example.org:443\r\n"
mmenkee71e15332015-10-07 16:39:543626 "Proxy-Connection: keep-alive\r\n"
3627 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
3628
3629 MockWrite("GET / HTTP/1.1\r\n"
3630 "Host: www.example.org\r\n"
3631 "Connection: keep-alive\r\n\r\n"),
3632 };
3633
3634 MockRead data_reads2[] = {
3635 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
3636
3637 MockRead("HTTP/1.1 200 OK\r\n"),
3638 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
3639 MockRead("Content-Length: 5\r\n\r\n"),
3640 MockRead(SYNCHRONOUS, "hello"),
3641 };
3642
3643 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
3644 data_writes1, arraysize(data_writes1));
3645 session_deps_.socket_factory->AddSocketDataProvider(&data1);
3646 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
3647 data_writes2, arraysize(data_writes2));
3648 session_deps_.socket_factory->AddSocketDataProvider(&data2);
3649 SSLSocketDataProvider ssl(ASYNC, OK);
3650 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
3651
3652 TestCompletionCallback callback;
3653
tfarina42834112016-09-22 13:38:203654 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:013655 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenkee71e15332015-10-07 16:39:543656
bnc691fda62016-08-12 00:43:163657 const HttpResponseInfo* response = trans.GetResponseInfo();
mmenkee71e15332015-10-07 16:39:543658 ASSERT_TRUE(response);
3659 ASSERT_TRUE(response->headers);
3660 EXPECT_TRUE(response->headers->IsKeepAlive());
3661 EXPECT_EQ(407, response->headers->response_code());
3662 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
3663
bnc691fda62016-08-12 00:43:163664 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar), callback.callback());
robpercival214763f2016-07-01 23:27:013665 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenkee71e15332015-10-07 16:39:543666
bnc691fda62016-08-12 00:43:163667 response = trans.GetResponseInfo();
mmenkee71e15332015-10-07 16:39:543668 ASSERT_TRUE(response);
3669 ASSERT_TRUE(response->headers);
3670 EXPECT_TRUE(response->headers->IsKeepAlive());
3671 EXPECT_EQ(200, response->headers->response_code());
3672 std::string body;
bnc691fda62016-08-12 00:43:163673 EXPECT_THAT(ReadTransaction(&trans, &body), IsOk());
mmenkee71e15332015-10-07 16:39:543674 EXPECT_EQ("hello", body);
3675}
3676
[email protected]a8e9b162009-03-12 00:06:443677// Test that we don't read the response body when we fail to establish a tunnel,
3678// even if the user cancels the proxy's auth attempt.
bncd16676a2016-07-20 16:23:013679TEST_F(HttpNetworkTransactionTest, BasicAuthProxyCancelTunnel) {
[email protected]cb9bf6ca2011-01-28 13:15:273680 HttpRequestInfo request;
3681 request.method = "GET";
bncce36dca22015-04-21 22:11:233682 request.url = GURL("https://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:273683
[email protected]a8e9b162009-03-12 00:06:443684 // Configure against proxy server "myproxy:70".
rdsmith82957ad2015-09-16 19:42:033685 session_deps_.proxy_service = ProxyService::CreateFixed("myproxy:70");
[email protected]a8e9b162009-03-12 00:06:443686
danakj1fd259a02016-04-16 03:17:093687 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]a8e9b162009-03-12 00:06:443688
bnc691fda62016-08-12 00:43:163689 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]a8e9b162009-03-12 00:06:443690
[email protected]a8e9b162009-03-12 00:06:443691 // Since we have proxy, should try to establish tunnel.
3692 MockWrite data_writes[] = {
rsleevidb16bb02015-11-12 23:47:173693 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
3694 "Host: www.example.org:443\r\n"
3695 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]a8e9b162009-03-12 00:06:443696 };
3697
3698 // The proxy responds to the connect with a 407.
3699 MockRead data_reads[] = {
ttuttle7933c112015-01-06 00:55:243700 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
3701 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
3702 MockRead("Content-Length: 10\r\n\r\n"),
mmenked39192ee2015-12-09 00:57:233703 MockRead("0123456789"),
ttuttle7933c112015-01-06 00:55:243704 MockRead(SYNCHRONOUS, ERR_UNEXPECTED),
[email protected]a8e9b162009-03-12 00:06:443705 };
3706
[email protected]31a2bfe2010-02-09 08:03:393707 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
3708 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:073709 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]a8e9b162009-03-12 00:06:443710
[email protected]49639fa2011-12-20 23:22:413711 TestCompletionCallback callback;
[email protected]a8e9b162009-03-12 00:06:443712
tfarina42834112016-09-22 13:38:203713 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:013714 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]a8e9b162009-03-12 00:06:443715
3716 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:013717 EXPECT_THAT(rv, IsOk());
[email protected]a8e9b162009-03-12 00:06:443718
bnc691fda62016-08-12 00:43:163719 const HttpResponseInfo* response = trans.GetResponseInfo();
ttuttle7933c112015-01-06 00:55:243720 ASSERT_TRUE(response);
3721 ASSERT_TRUE(response->headers);
[email protected]a8e9b162009-03-12 00:06:443722 EXPECT_TRUE(response->headers->IsKeepAlive());
3723 EXPECT_EQ(407, response->headers->response_code());
[email protected]1c773ea12009-04-28 19:58:423724 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
[email protected]a8e9b162009-03-12 00:06:443725
3726 std::string response_data;
bnc691fda62016-08-12 00:43:163727 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:013728 EXPECT_THAT(rv, IsError(ERR_TUNNEL_CONNECTION_FAILED));
[email protected]e60e47a2010-07-14 03:37:183729
3730 // Flush the idle socket before the HttpNetworkTransaction goes out of scope.
[email protected]102e27c2011-02-23 01:01:313731 session->CloseAllConnections();
[email protected]a8e9b162009-03-12 00:06:443732}
3733
ttuttle7933c112015-01-06 00:55:243734// Test that we don't pass extraneous headers from the proxy's response to the
3735// caller when the proxy responds to CONNECT with 407.
bncd16676a2016-07-20 16:23:013736TEST_F(HttpNetworkTransactionTest, SanitizeProxyAuthHeaders) {
ttuttle7933c112015-01-06 00:55:243737 HttpRequestInfo request;
3738 request.method = "GET";
bncce36dca22015-04-21 22:11:233739 request.url = GURL("https://www.example.org/");
ttuttle7933c112015-01-06 00:55:243740
3741 // Configure against proxy server "myproxy:70".
rdsmith82957ad2015-09-16 19:42:033742 session_deps_.proxy_service = ProxyService::CreateFixed("myproxy:70");
ttuttle7933c112015-01-06 00:55:243743
danakj1fd259a02016-04-16 03:17:093744 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
ttuttle7933c112015-01-06 00:55:243745
bnc691fda62016-08-12 00:43:163746 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
ttuttle7933c112015-01-06 00:55:243747
3748 // Since we have proxy, should try to establish tunnel.
3749 MockWrite data_writes[] = {
rsleevidb16bb02015-11-12 23:47:173750 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
3751 "Host: www.example.org:443\r\n"
3752 "Proxy-Connection: keep-alive\r\n\r\n"),
ttuttle7933c112015-01-06 00:55:243753 };
3754
3755 // The proxy responds to the connect with a 407.
3756 MockRead data_reads[] = {
3757 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
3758 MockRead("X-Foo: bar\r\n"),
3759 MockRead("Set-Cookie: foo=bar\r\n"),
3760 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
3761 MockRead("Content-Length: 10\r\n\r\n"),
mmenked39192ee2015-12-09 00:57:233762 MockRead(SYNCHRONOUS, ERR_UNEXPECTED),
ttuttle7933c112015-01-06 00:55:243763 };
3764
3765 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
3766 arraysize(data_writes));
3767 session_deps_.socket_factory->AddSocketDataProvider(&data);
3768
3769 TestCompletionCallback callback;
3770
tfarina42834112016-09-22 13:38:203771 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:013772 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
ttuttle7933c112015-01-06 00:55:243773
3774 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:013775 EXPECT_THAT(rv, IsOk());
ttuttle7933c112015-01-06 00:55:243776
bnc691fda62016-08-12 00:43:163777 const HttpResponseInfo* response = trans.GetResponseInfo();
ttuttle7933c112015-01-06 00:55:243778 ASSERT_TRUE(response);
3779 ASSERT_TRUE(response->headers);
3780 EXPECT_TRUE(response->headers->IsKeepAlive());
3781 EXPECT_EQ(407, response->headers->response_code());
3782 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
3783 EXPECT_FALSE(response->headers->HasHeader("X-Foo"));
3784 EXPECT_FALSE(response->headers->HasHeader("Set-Cookie"));
3785
3786 std::string response_data;
bnc691fda62016-08-12 00:43:163787 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:013788 EXPECT_THAT(rv, IsError(ERR_TUNNEL_CONNECTION_FAILED));
ttuttle7933c112015-01-06 00:55:243789
3790 // Flush the idle socket before the HttpNetworkTransaction goes out of scope.
3791 session->CloseAllConnections();
3792}
3793
[email protected]8fdbcd22010-05-05 02:54:523794// Test when a server (non-proxy) returns a 407 (proxy-authenticate).
3795// The request should fail with ERR_UNEXPECTED_PROXY_AUTH.
bncd16676a2016-07-20 16:23:013796TEST_F(HttpNetworkTransactionTest, UnexpectedProxyAuth) {
[email protected]8fdbcd22010-05-05 02:54:523797 HttpRequestInfo request;
3798 request.method = "GET";
bncce36dca22015-04-21 22:11:233799 request.url = GURL("http://www.example.org/");
[email protected]8fdbcd22010-05-05 02:54:523800
[email protected]cb9bf6ca2011-01-28 13:15:273801 // We are using a DIRECT connection (i.e. no proxy) for this session.
danakj1fd259a02016-04-16 03:17:093802 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:163803 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:273804
[email protected]8fdbcd22010-05-05 02:54:523805 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:233806 MockWrite(
3807 "GET / HTTP/1.1\r\n"
3808 "Host: www.example.org\r\n"
3809 "Connection: keep-alive\r\n\r\n"),
[email protected]8fdbcd22010-05-05 02:54:523810 };
3811
3812 MockRead data_reads1[] = {
3813 MockRead("HTTP/1.0 407 Proxy Auth required\r\n"),
3814 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
3815 // Large content-length -- won't matter, as connection will be reset.
3816 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:063817 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]8fdbcd22010-05-05 02:54:523818 };
3819
3820 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
3821 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:073822 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8fdbcd22010-05-05 02:54:523823
[email protected]49639fa2011-12-20 23:22:413824 TestCompletionCallback callback;
[email protected]8fdbcd22010-05-05 02:54:523825
tfarina42834112016-09-22 13:38:203826 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:013827 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]8fdbcd22010-05-05 02:54:523828
3829 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:013830 EXPECT_THAT(rv, IsError(ERR_UNEXPECTED_PROXY_AUTH));
[email protected]8fdbcd22010-05-05 02:54:523831}
3832
[email protected]7a67a8152010-11-05 18:31:103833// Tests when an HTTPS server (non-proxy) returns a 407 (proxy-authentication)
3834// through a non-authenticating proxy. The request should fail with
3835// ERR_UNEXPECTED_PROXY_AUTH.
3836// Note that it is impossible to detect if an HTTP server returns a 407 through
3837// a non-authenticating proxy - there is nothing to indicate whether the
3838// response came from the proxy or the server, so it is treated as if the proxy
3839// issued the challenge.
bncd16676a2016-07-20 16:23:013840TEST_F(HttpNetworkTransactionTest, HttpsServerRequestsProxyAuthThroughProxy) {
[email protected]cb9bf6ca2011-01-28 13:15:273841 HttpRequestInfo request;
3842 request.method = "GET";
bncce36dca22015-04-21 22:11:233843 request.url = GURL("https://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:273844
rdsmith82957ad2015-09-16 19:42:033845 session_deps_.proxy_service = ProxyService::CreateFixed("myproxy:70");
vishal.b62985ca92015-04-17 08:45:513846 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:073847 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:093848 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]7a67a8152010-11-05 18:31:103849
[email protected]7a67a8152010-11-05 18:31:103850 // Since we have proxy, should try to establish tunnel.
3851 MockWrite data_writes1[] = {
rsleevidb16bb02015-11-12 23:47:173852 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
3853 "Host: www.example.org:443\r\n"
3854 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]7a67a8152010-11-05 18:31:103855
rsleevidb16bb02015-11-12 23:47:173856 MockWrite("GET / HTTP/1.1\r\n"
3857 "Host: www.example.org\r\n"
3858 "Connection: keep-alive\r\n\r\n"),
[email protected]7a67a8152010-11-05 18:31:103859 };
3860
3861 MockRead data_reads1[] = {
3862 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
3863
3864 MockRead("HTTP/1.1 407 Unauthorized\r\n"),
3865 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
3866 MockRead("\r\n"),
[email protected]8ddf8322012-02-23 18:08:063867 MockRead(SYNCHRONOUS, OK),
[email protected]7a67a8152010-11-05 18:31:103868 };
3869
3870 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
3871 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:073872 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8ddf8322012-02-23 18:08:063873 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:073874 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]7a67a8152010-11-05 18:31:103875
[email protected]49639fa2011-12-20 23:22:413876 TestCompletionCallback callback1;
[email protected]7a67a8152010-11-05 18:31:103877
bnc691fda62016-08-12 00:43:163878 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]7a67a8152010-11-05 18:31:103879
bnc691fda62016-08-12 00:43:163880 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:013881 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]7a67a8152010-11-05 18:31:103882
3883 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:013884 EXPECT_THAT(rv, IsError(ERR_UNEXPECTED_PROXY_AUTH));
mmenke43758e62015-05-04 21:09:463885 TestNetLogEntry::List entries;
[email protected]b2fcd0e2010-12-01 15:19:403886 log.GetEntries(&entries);
[email protected]7a67a8152010-11-05 18:31:103887 size_t pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:003888 entries, 0, NetLogEventType::HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
3889 NetLogEventPhase::NONE);
[email protected]7a67a8152010-11-05 18:31:103890 ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:403891 entries, pos,
mikecirone8b85c432016-09-08 19:11:003892 NetLogEventType::HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
3893 NetLogEventPhase::NONE);
[email protected]7a67a8152010-11-05 18:31:103894}
[email protected]2df19bb2010-08-25 20:13:463895
mmenke2a1781d2015-10-07 19:25:333896// Test a proxy auth scheme that allows default credentials and a proxy server
3897// that uses non-persistent connections.
bncd16676a2016-07-20 16:23:013898TEST_F(HttpNetworkTransactionTest,
mmenke2a1781d2015-10-07 19:25:333899 AuthAllowsDefaultCredentialsTunnelConnectionClose) {
3900 HttpRequestInfo request;
3901 request.method = "GET";
3902 request.url = GURL("https://www.example.org/");
3903
3904 // Configure against proxy server "myproxy:70".
3905 session_deps_.proxy_service =
3906 ProxyService::CreateFixedFromPacResult("PROXY myproxy:70");
3907
Jeremy Roman0579ed62017-08-29 15:56:193908 auto auth_handler_factory = std::make_unique<HttpAuthHandlerMock::Factory>();
mmenke2a1781d2015-10-07 19:25:333909 auth_handler_factory->set_do_init_from_challenge(true);
Jeremy Roman0579ed62017-08-29 15:56:193910 auto mock_handler = std::make_unique<HttpAuthHandlerMock>();
mmenke2a1781d2015-10-07 19:25:333911 mock_handler->set_allows_default_credentials(true);
3912 auth_handler_factory->AddMockHandler(mock_handler.release(),
3913 HttpAuth::AUTH_PROXY);
dchengc7eeda422015-12-26 03:56:483914 session_deps_.http_auth_handler_factory = std::move(auth_handler_factory);
mmenke2a1781d2015-10-07 19:25:333915
3916 // Add NetLog just so can verify load timing information gets a NetLog ID.
3917 NetLog net_log;
3918 session_deps_.net_log = &net_log;
danakj1fd259a02016-04-16 03:17:093919 std::unique_ptr<HttpNetworkSession> session = CreateSession(&session_deps_);
mmenke2a1781d2015-10-07 19:25:333920
3921 // Since we have proxy, should try to establish tunnel.
3922 MockWrite data_writes1[] = {
3923 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:173924 "Host: www.example.org:443\r\n"
mmenke2a1781d2015-10-07 19:25:333925 "Proxy-Connection: keep-alive\r\n\r\n"),
3926 };
3927
3928 // The proxy responds to the connect with a 407, using a non-persistent
3929 // connection.
3930 MockRead data_reads1[] = {
3931 // No credentials.
3932 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
3933 MockRead("Proxy-Authenticate: Mock\r\n"),
3934 MockRead("Proxy-Connection: close\r\n\r\n"),
3935 };
3936
3937 // Since the first connection couldn't be reused, need to establish another
3938 // once given credentials.
3939 MockWrite data_writes2[] = {
3940 // After calling trans->RestartWithAuth(), this is the request we should
3941 // be issuing -- the final header line contains the credentials.
3942 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:173943 "Host: www.example.org:443\r\n"
mmenke2a1781d2015-10-07 19:25:333944 "Proxy-Connection: keep-alive\r\n"
3945 "Proxy-Authorization: auth_token\r\n\r\n"),
3946
3947 MockWrite("GET / HTTP/1.1\r\n"
3948 "Host: www.example.org\r\n"
3949 "Connection: keep-alive\r\n\r\n"),
3950 };
3951
3952 MockRead data_reads2[] = {
3953 MockRead("HTTP/1.0 200 Connection Established\r\n\r\n"),
3954
3955 MockRead("HTTP/1.1 200 OK\r\n"),
3956 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
3957 MockRead("Content-Length: 5\r\n\r\n"),
3958 MockRead(SYNCHRONOUS, "hello"),
3959 };
3960
3961 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
3962 data_writes1, arraysize(data_writes1));
3963 session_deps_.socket_factory->AddSocketDataProvider(&data1);
3964 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
3965 data_writes2, arraysize(data_writes2));
3966 session_deps_.socket_factory->AddSocketDataProvider(&data2);
3967 SSLSocketDataProvider ssl(ASYNC, OK);
3968 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
3969
bnc87dcefc2017-05-25 12:47:583970 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:193971 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
mmenke2a1781d2015-10-07 19:25:333972
3973 TestCompletionCallback callback;
tfarina42834112016-09-22 13:38:203974 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:013975 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenke2a1781d2015-10-07 19:25:333976
3977 const HttpResponseInfo* response = trans->GetResponseInfo();
3978 ASSERT_TRUE(response);
3979 ASSERT_TRUE(response->headers);
3980 EXPECT_FALSE(response->headers->IsKeepAlive());
3981 EXPECT_EQ(407, response->headers->response_code());
3982 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
3983 EXPECT_TRUE(trans->IsReadyToRestartForAuth());
wezca1070932016-05-26 20:30:523984 EXPECT_FALSE(response->auth_challenge);
mmenke2a1781d2015-10-07 19:25:333985
3986 LoadTimingInfo load_timing_info;
3987 // CONNECT requests and responses are handled at the connect job level, so
3988 // the transaction does not yet have a connection.
3989 EXPECT_FALSE(trans->GetLoadTimingInfo(&load_timing_info));
3990
3991 rv = trans->RestartWithAuth(AuthCredentials(), callback.callback());
robpercival214763f2016-07-01 23:27:013992 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenke2a1781d2015-10-07 19:25:333993 response = trans->GetResponseInfo();
3994 ASSERT_TRUE(response);
3995 ASSERT_TRUE(response->headers);
3996 EXPECT_TRUE(response->headers->IsKeepAlive());
3997 EXPECT_EQ(200, response->headers->response_code());
3998 EXPECT_EQ(5, response->headers->GetContentLength());
3999 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
4000
4001 // The password prompt info should not be set.
4002 EXPECT_FALSE(response->auth_challenge);
4003
4004 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
4005 TestLoadTimingNotReusedWithPac(load_timing_info,
4006 CONNECT_TIMING_HAS_SSL_TIMES);
4007
4008 trans.reset();
4009 session->CloseAllConnections();
4010}
4011
4012// Test a proxy auth scheme that allows default credentials and a proxy server
4013// that hangs up when credentials are initially sent.
bncd16676a2016-07-20 16:23:014014TEST_F(HttpNetworkTransactionTest,
mmenke2a1781d2015-10-07 19:25:334015 AuthAllowsDefaultCredentialsTunnelServerClosesConnection) {
4016 HttpRequestInfo request;
4017 request.method = "GET";
4018 request.url = GURL("https://www.example.org/");
4019
4020 // Configure against proxy server "myproxy:70".
4021 session_deps_.proxy_service =
4022 ProxyService::CreateFixedFromPacResult("PROXY myproxy:70");
4023
Jeremy Roman0579ed62017-08-29 15:56:194024 auto auth_handler_factory = std::make_unique<HttpAuthHandlerMock::Factory>();
mmenke2a1781d2015-10-07 19:25:334025 auth_handler_factory->set_do_init_from_challenge(true);
Jeremy Roman0579ed62017-08-29 15:56:194026 auto mock_handler = std::make_unique<HttpAuthHandlerMock>();
mmenke2a1781d2015-10-07 19:25:334027 mock_handler->set_allows_default_credentials(true);
4028 auth_handler_factory->AddMockHandler(mock_handler.release(),
4029 HttpAuth::AUTH_PROXY);
dchengc7eeda422015-12-26 03:56:484030 session_deps_.http_auth_handler_factory = std::move(auth_handler_factory);
mmenke2a1781d2015-10-07 19:25:334031
4032 // Add NetLog just so can verify load timing information gets a NetLog ID.
4033 NetLog net_log;
4034 session_deps_.net_log = &net_log;
danakj1fd259a02016-04-16 03:17:094035 std::unique_ptr<HttpNetworkSession> session = CreateSession(&session_deps_);
mmenke2a1781d2015-10-07 19:25:334036
4037 // Should try to establish tunnel.
4038 MockWrite data_writes1[] = {
4039 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:174040 "Host: www.example.org:443\r\n"
mmenke2a1781d2015-10-07 19:25:334041 "Proxy-Connection: keep-alive\r\n\r\n"),
4042
4043 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:174044 "Host: www.example.org:443\r\n"
mmenke2a1781d2015-10-07 19:25:334045 "Proxy-Connection: keep-alive\r\n"
4046 "Proxy-Authorization: auth_token\r\n\r\n"),
4047 };
4048
4049 // The proxy responds to the connect with a 407, using a non-persistent
4050 // connection.
4051 MockRead data_reads1[] = {
4052 // No credentials.
4053 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
4054 MockRead("Proxy-Authenticate: Mock\r\n\r\n"),
4055 MockRead(SYNCHRONOUS, ERR_CONNECTION_CLOSED),
4056 };
4057
4058 // Since the first connection was closed, need to establish another once given
4059 // credentials.
4060 MockWrite data_writes2[] = {
4061 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:174062 "Host: www.example.org:443\r\n"
mmenke2a1781d2015-10-07 19:25:334063 "Proxy-Connection: keep-alive\r\n"
4064 "Proxy-Authorization: auth_token\r\n\r\n"),
4065
4066 MockWrite("GET / HTTP/1.1\r\n"
4067 "Host: www.example.org\r\n"
4068 "Connection: keep-alive\r\n\r\n"),
4069 };
4070
4071 MockRead data_reads2[] = {
4072 MockRead("HTTP/1.0 200 Connection Established\r\n\r\n"),
4073
4074 MockRead("HTTP/1.1 200 OK\r\n"),
4075 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
4076 MockRead("Content-Length: 5\r\n\r\n"),
4077 MockRead(SYNCHRONOUS, "hello"),
4078 };
4079
4080 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
4081 data_writes1, arraysize(data_writes1));
4082 session_deps_.socket_factory->AddSocketDataProvider(&data1);
4083 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
4084 data_writes2, arraysize(data_writes2));
4085 session_deps_.socket_factory->AddSocketDataProvider(&data2);
4086 SSLSocketDataProvider ssl(ASYNC, OK);
4087 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
4088
bnc87dcefc2017-05-25 12:47:584089 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:194090 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
mmenke2a1781d2015-10-07 19:25:334091
4092 TestCompletionCallback callback;
tfarina42834112016-09-22 13:38:204093 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:014094 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenke2a1781d2015-10-07 19:25:334095
4096 const HttpResponseInfo* response = trans->GetResponseInfo();
4097 ASSERT_TRUE(response);
4098 ASSERT_TRUE(response->headers);
4099 EXPECT_TRUE(response->headers->IsKeepAlive());
4100 EXPECT_EQ(407, response->headers->response_code());
4101 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
4102 EXPECT_TRUE(trans->IsReadyToRestartForAuth());
4103 EXPECT_FALSE(response->auth_challenge);
4104
4105 LoadTimingInfo load_timing_info;
4106 // CONNECT requests and responses are handled at the connect job level, so
4107 // the transaction does not yet have a connection.
4108 EXPECT_FALSE(trans->GetLoadTimingInfo(&load_timing_info));
4109
4110 rv = trans->RestartWithAuth(AuthCredentials(), callback.callback());
robpercival214763f2016-07-01 23:27:014111 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenke2a1781d2015-10-07 19:25:334112
4113 response = trans->GetResponseInfo();
4114 ASSERT_TRUE(response);
4115 ASSERT_TRUE(response->headers);
4116 EXPECT_TRUE(response->headers->IsKeepAlive());
4117 EXPECT_EQ(200, response->headers->response_code());
4118 EXPECT_EQ(5, response->headers->GetContentLength());
4119 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
4120
4121 // The password prompt info should not be set.
wezca1070932016-05-26 20:30:524122 EXPECT_FALSE(response->auth_challenge);
mmenke2a1781d2015-10-07 19:25:334123
4124 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
4125 TestLoadTimingNotReusedWithPac(load_timing_info,
4126 CONNECT_TIMING_HAS_SSL_TIMES);
4127
4128 trans.reset();
4129 session->CloseAllConnections();
4130}
4131
4132// Test a proxy auth scheme that allows default credentials and a proxy server
4133// that hangs up when credentials are initially sent, and hangs up again when
4134// they are retried.
bncd16676a2016-07-20 16:23:014135TEST_F(HttpNetworkTransactionTest,
mmenke2a1781d2015-10-07 19:25:334136 AuthAllowsDefaultCredentialsTunnelServerClosesConnectionTwice) {
4137 HttpRequestInfo request;
4138 request.method = "GET";
4139 request.url = GURL("https://www.example.org/");
4140
4141 // Configure against proxy server "myproxy:70".
4142 session_deps_.proxy_service =
4143 ProxyService::CreateFixedFromPacResult("PROXY myproxy:70");
4144
Jeremy Roman0579ed62017-08-29 15:56:194145 auto auth_handler_factory = std::make_unique<HttpAuthHandlerMock::Factory>();
mmenke2a1781d2015-10-07 19:25:334146 auth_handler_factory->set_do_init_from_challenge(true);
Jeremy Roman0579ed62017-08-29 15:56:194147 auto mock_handler = std::make_unique<HttpAuthHandlerMock>();
mmenke2a1781d2015-10-07 19:25:334148 mock_handler->set_allows_default_credentials(true);
4149 auth_handler_factory->AddMockHandler(mock_handler.release(),
4150 HttpAuth::AUTH_PROXY);
dchengc7eeda422015-12-26 03:56:484151 session_deps_.http_auth_handler_factory = std::move(auth_handler_factory);
mmenke2a1781d2015-10-07 19:25:334152
4153 // Add NetLog just so can verify load timing information gets a NetLog ID.
4154 NetLog net_log;
4155 session_deps_.net_log = &net_log;
danakj1fd259a02016-04-16 03:17:094156 std::unique_ptr<HttpNetworkSession> session = CreateSession(&session_deps_);
mmenke2a1781d2015-10-07 19:25:334157
4158 // Should try to establish tunnel.
4159 MockWrite data_writes1[] = {
4160 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:174161 "Host: www.example.org:443\r\n"
mmenke2a1781d2015-10-07 19:25:334162 "Proxy-Connection: keep-alive\r\n\r\n"),
4163
4164 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:174165 "Host: www.example.org:443\r\n"
mmenke2a1781d2015-10-07 19:25:334166 "Proxy-Connection: keep-alive\r\n"
4167 "Proxy-Authorization: auth_token\r\n\r\n"),
4168 };
4169
4170 // The proxy responds to the connect with a 407, and then hangs up after the
4171 // second request is sent.
4172 MockRead data_reads1[] = {
4173 // No credentials.
4174 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
4175 MockRead("Content-Length: 0\r\n"),
4176 MockRead("Proxy-Connection: keep-alive\r\n"),
4177 MockRead("Proxy-Authenticate: Mock\r\n\r\n"),
4178 MockRead(SYNCHRONOUS, ERR_CONNECTION_CLOSED),
4179 };
4180
4181 // HttpNetworkTransaction sees a reused connection that was closed with
4182 // ERR_CONNECTION_CLOSED, realized it might have been a race, so retries the
4183 // request.
4184 MockWrite data_writes2[] = {
4185 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:174186 "Host: www.example.org:443\r\n"
mmenke2a1781d2015-10-07 19:25:334187 "Proxy-Connection: keep-alive\r\n\r\n"),
4188 };
4189
4190 // The proxy, having had more than enough of us, just hangs up.
4191 MockRead data_reads2[] = {
4192 // No credentials.
4193 MockRead(SYNCHRONOUS, ERR_CONNECTION_CLOSED),
4194 };
4195
4196 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
4197 data_writes1, arraysize(data_writes1));
4198 session_deps_.socket_factory->AddSocketDataProvider(&data1);
4199 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
4200 data_writes2, arraysize(data_writes2));
4201 session_deps_.socket_factory->AddSocketDataProvider(&data2);
4202
bnc87dcefc2017-05-25 12:47:584203 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:194204 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
mmenke2a1781d2015-10-07 19:25:334205
4206 TestCompletionCallback callback;
tfarina42834112016-09-22 13:38:204207 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:014208 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenke2a1781d2015-10-07 19:25:334209
4210 const HttpResponseInfo* response = trans->GetResponseInfo();
4211 ASSERT_TRUE(response);
4212 ASSERT_TRUE(response->headers);
4213 EXPECT_TRUE(response->headers->IsKeepAlive());
4214 EXPECT_EQ(407, response->headers->response_code());
4215 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
4216 EXPECT_TRUE(trans->IsReadyToRestartForAuth());
4217 EXPECT_FALSE(response->auth_challenge);
4218
4219 LoadTimingInfo load_timing_info;
4220 EXPECT_FALSE(trans->GetLoadTimingInfo(&load_timing_info));
4221
4222 rv = trans->RestartWithAuth(AuthCredentials(), callback.callback());
robpercival214763f2016-07-01 23:27:014223 EXPECT_THAT(callback.GetResult(rv), IsError(ERR_EMPTY_RESPONSE));
mmenke2a1781d2015-10-07 19:25:334224
4225 trans.reset();
4226 session->CloseAllConnections();
4227}
4228
4229// Test a proxy auth scheme that allows default credentials and a proxy server
4230// that hangs up when credentials are initially sent, and sends a challenge
4231// again they are retried.
bncd16676a2016-07-20 16:23:014232TEST_F(HttpNetworkTransactionTest,
mmenke2a1781d2015-10-07 19:25:334233 AuthAllowsDefaultCredentialsTunnelServerChallengesTwice) {
4234 HttpRequestInfo request;
4235 request.method = "GET";
4236 request.url = GURL("https://www.example.org/");
4237
4238 // Configure against proxy server "myproxy:70".
4239 session_deps_.proxy_service =
4240 ProxyService::CreateFixedFromPacResult("PROXY myproxy:70");
4241
Jeremy Roman0579ed62017-08-29 15:56:194242 auto auth_handler_factory = std::make_unique<HttpAuthHandlerMock::Factory>();
mmenke2a1781d2015-10-07 19:25:334243 auth_handler_factory->set_do_init_from_challenge(true);
Jeremy Roman0579ed62017-08-29 15:56:194244 auto 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);
4248 // Add another handler for the second challenge. It supports default
4249 // credentials, but they shouldn't be used, since they were already tried.
Jeremy Roman0579ed62017-08-29 15:56:194250 mock_handler = std::make_unique<HttpAuthHandlerMock>();
mmenke2a1781d2015-10-07 19:25:334251 mock_handler->set_allows_default_credentials(true);
4252 auth_handler_factory->AddMockHandler(mock_handler.release(),
4253 HttpAuth::AUTH_PROXY);
dchengc7eeda422015-12-26 03:56:484254 session_deps_.http_auth_handler_factory = std::move(auth_handler_factory);
mmenke2a1781d2015-10-07 19:25:334255
4256 // Add NetLog just so can verify load timing information gets a NetLog ID.
4257 NetLog net_log;
4258 session_deps_.net_log = &net_log;
danakj1fd259a02016-04-16 03:17:094259 std::unique_ptr<HttpNetworkSession> session = CreateSession(&session_deps_);
mmenke2a1781d2015-10-07 19:25:334260
4261 // Should try to establish tunnel.
4262 MockWrite data_writes1[] = {
4263 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:174264 "Host: www.example.org:443\r\n"
mmenke2a1781d2015-10-07 19:25:334265 "Proxy-Connection: keep-alive\r\n\r\n"),
4266 };
4267
4268 // The proxy responds to the connect with a 407, using a non-persistent
4269 // connection.
4270 MockRead data_reads1[] = {
4271 // No credentials.
4272 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
4273 MockRead("Proxy-Authenticate: Mock\r\n"),
4274 MockRead("Proxy-Connection: close\r\n\r\n"),
4275 };
4276
4277 // Since the first connection was closed, need to establish another once given
4278 // credentials.
4279 MockWrite data_writes2[] = {
4280 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:174281 "Host: www.example.org:443\r\n"
mmenke2a1781d2015-10-07 19:25:334282 "Proxy-Connection: keep-alive\r\n"
4283 "Proxy-Authorization: auth_token\r\n\r\n"),
4284 };
4285
4286 MockRead data_reads2[] = {
4287 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
4288 MockRead("Proxy-Authenticate: Mock\r\n"),
4289 MockRead("Proxy-Connection: close\r\n\r\n"),
4290 };
4291
4292 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
4293 data_writes1, arraysize(data_writes1));
4294 session_deps_.socket_factory->AddSocketDataProvider(&data1);
4295 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
4296 data_writes2, arraysize(data_writes2));
4297 session_deps_.socket_factory->AddSocketDataProvider(&data2);
4298 SSLSocketDataProvider ssl(ASYNC, OK);
4299 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
4300
bnc87dcefc2017-05-25 12:47:584301 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:194302 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
mmenke2a1781d2015-10-07 19:25:334303
4304 TestCompletionCallback callback;
tfarina42834112016-09-22 13:38:204305 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:014306 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenke2a1781d2015-10-07 19:25:334307
4308 const HttpResponseInfo* response = trans->GetResponseInfo();
4309 ASSERT_TRUE(response);
4310 ASSERT_TRUE(response->headers);
4311 EXPECT_EQ(407, response->headers->response_code());
4312 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
4313 EXPECT_TRUE(trans->IsReadyToRestartForAuth());
4314 EXPECT_FALSE(response->auth_challenge);
4315
4316 LoadTimingInfo load_timing_info;
4317 EXPECT_FALSE(trans->GetLoadTimingInfo(&load_timing_info));
4318
4319 rv = trans->RestartWithAuth(AuthCredentials(), callback.callback());
robpercival214763f2016-07-01 23:27:014320 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenke2a1781d2015-10-07 19:25:334321 response = trans->GetResponseInfo();
4322 ASSERT_TRUE(response);
4323 ASSERT_TRUE(response->headers);
4324 EXPECT_EQ(407, response->headers->response_code());
4325 EXPECT_FALSE(trans->IsReadyToRestartForAuth());
4326 EXPECT_TRUE(response->auth_challenge);
4327
4328 trans.reset();
4329 session->CloseAllConnections();
4330}
4331
asankae2257db2016-10-11 22:03:164332// A more nuanced test than GenerateAuthToken test which asserts that
4333// ERR_INVALID_AUTH_CREDENTIALS does not cause the auth scheme to be
4334// unnecessarily invalidated, and that if the server co-operates, the
4335// authentication handshake can continue with the same scheme but with a
4336// different identity.
4337TEST_F(HttpNetworkTransactionTest, NonPermanentGenerateAuthTokenError) {
4338 HttpRequestInfo request;
4339 request.method = "GET";
4340 request.url = GURL("http://www.example.org/");
4341
Jeremy Roman0579ed62017-08-29 15:56:194342 auto auth_handler_factory = std::make_unique<HttpAuthHandlerMock::Factory>();
asankae2257db2016-10-11 22:03:164343 auth_handler_factory->set_do_init_from_challenge(true);
4344
4345 // First handler. Uses default credentials, but barfs at generate auth token.
Jeremy Roman0579ed62017-08-29 15:56:194346 auto mock_handler = std::make_unique<HttpAuthHandlerMock>();
asankae2257db2016-10-11 22:03:164347 mock_handler->set_allows_default_credentials(true);
4348 mock_handler->set_allows_explicit_credentials(true);
4349 mock_handler->set_connection_based(true);
4350 mock_handler->SetGenerateExpectation(true, ERR_INVALID_AUTH_CREDENTIALS);
4351 auth_handler_factory->AddMockHandler(mock_handler.release(),
4352 HttpAuth::AUTH_SERVER);
4353
4354 // Add another handler for the second challenge. It supports default
4355 // credentials, but they shouldn't be used, since they were already tried.
Jeremy Roman0579ed62017-08-29 15:56:194356 mock_handler = std::make_unique<HttpAuthHandlerMock>();
asankae2257db2016-10-11 22:03:164357 mock_handler->set_allows_default_credentials(true);
4358 mock_handler->set_allows_explicit_credentials(true);
4359 mock_handler->set_connection_based(true);
4360 auth_handler_factory->AddMockHandler(mock_handler.release(),
4361 HttpAuth::AUTH_SERVER);
4362 session_deps_.http_auth_handler_factory = std::move(auth_handler_factory);
4363
4364 std::unique_ptr<HttpNetworkSession> session = CreateSession(&session_deps_);
4365
4366 MockWrite data_writes1[] = {
4367 MockWrite("GET / HTTP/1.1\r\n"
4368 "Host: www.example.org\r\n"
4369 "Connection: keep-alive\r\n\r\n"),
4370 };
4371
4372 MockRead data_reads1[] = {
4373 MockRead("HTTP/1.1 401 Authentication Required\r\n"
4374 "WWW-Authenticate: Mock\r\n"
4375 "Connection: keep-alive\r\n\r\n"),
4376 };
4377
4378 // Identical to data_writes1[]. The AuthHandler encounters a
4379 // ERR_INVALID_AUTH_CREDENTIALS during the GenerateAuthToken stage, so the
4380 // transaction procceds without an authorization header.
4381 MockWrite data_writes2[] = {
4382 MockWrite("GET / HTTP/1.1\r\n"
4383 "Host: www.example.org\r\n"
4384 "Connection: keep-alive\r\n\r\n"),
4385 };
4386
4387 MockRead data_reads2[] = {
4388 MockRead("HTTP/1.1 401 Authentication Required\r\n"
4389 "WWW-Authenticate: Mock\r\n"
4390 "Connection: keep-alive\r\n\r\n"),
4391 };
4392
4393 MockWrite data_writes3[] = {
4394 MockWrite("GET / HTTP/1.1\r\n"
4395 "Host: www.example.org\r\n"
4396 "Connection: keep-alive\r\n"
4397 "Authorization: auth_token\r\n\r\n"),
4398 };
4399
4400 MockRead data_reads3[] = {
4401 MockRead("HTTP/1.1 200 OK\r\n"
4402 "Content-Length: 5\r\n"
4403 "Content-Type: text/plain\r\n"
4404 "Connection: keep-alive\r\n\r\n"
4405 "Hello"),
4406 };
4407
4408 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
4409 data_writes1, arraysize(data_writes1));
4410 session_deps_.socket_factory->AddSocketDataProvider(&data1);
4411
4412 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
4413 data_writes2, arraysize(data_writes2));
4414 session_deps_.socket_factory->AddSocketDataProvider(&data2);
4415
4416 StaticSocketDataProvider data3(data_reads3, arraysize(data_reads3),
4417 data_writes3, arraysize(data_writes3));
4418 session_deps_.socket_factory->AddSocketDataProvider(&data3);
4419
bnc87dcefc2017-05-25 12:47:584420 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:194421 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
asankae2257db2016-10-11 22:03:164422
4423 TestCompletionCallback callback;
4424 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
4425 EXPECT_THAT(callback.GetResult(rv), IsOk());
4426
4427 const HttpResponseInfo* response = trans->GetResponseInfo();
4428 ASSERT_TRUE(response);
4429 ASSERT_TRUE(response->headers);
4430 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
4431
4432 // The following three tests assert that an authentication challenge was
4433 // received and that the stack is ready to respond to the challenge using
4434 // ambient credentials.
4435 EXPECT_EQ(401, response->headers->response_code());
4436 EXPECT_TRUE(trans->IsReadyToRestartForAuth());
4437 EXPECT_FALSE(response->auth_challenge);
4438
4439 rv = trans->RestartWithAuth(AuthCredentials(), callback.callback());
4440 EXPECT_THAT(callback.GetResult(rv), IsOk());
4441 response = trans->GetResponseInfo();
4442 ASSERT_TRUE(response);
4443 ASSERT_TRUE(response->headers);
4444
4445 // The following three tests assert that an authentication challenge was
4446 // received and that the stack needs explicit credentials before it is ready
4447 // to respond to the challenge.
4448 EXPECT_EQ(401, response->headers->response_code());
4449 EXPECT_FALSE(trans->IsReadyToRestartForAuth());
4450 EXPECT_TRUE(response->auth_challenge);
4451
4452 rv = trans->RestartWithAuth(AuthCredentials(), callback.callback());
4453 EXPECT_THAT(callback.GetResult(rv), IsOk());
4454 response = trans->GetResponseInfo();
4455 ASSERT_TRUE(response);
4456 ASSERT_TRUE(response->headers);
4457 EXPECT_EQ(200, response->headers->response_code());
4458
4459 trans.reset();
4460 session->CloseAllConnections();
4461}
4462
[email protected]029c83b62013-01-24 05:28:204463// Test the load timing for HTTPS requests with an HTTP proxy.
bncd16676a2016-07-20 16:23:014464TEST_F(HttpNetworkTransactionTest, HttpProxyLoadTimingNoPacTwoRequests) {
[email protected]029c83b62013-01-24 05:28:204465 HttpRequestInfo request1;
4466 request1.method = "GET";
bncce36dca22015-04-21 22:11:234467 request1.url = GURL("https://www.example.org/1");
[email protected]029c83b62013-01-24 05:28:204468
4469 HttpRequestInfo request2;
4470 request2.method = "GET";
bncce36dca22015-04-21 22:11:234471 request2.url = GURL("https://www.example.org/2");
[email protected]029c83b62013-01-24 05:28:204472
4473 // Configure against proxy server "myproxy:70".
brettwc1213d92016-11-12 03:41:134474 session_deps_.proxy_service = ProxyService::CreateFixed("myproxy:70");
vishal.b62985ca92015-04-17 08:45:514475 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:074476 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:094477 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]029c83b62013-01-24 05:28:204478
4479 // Since we have proxy, should try to establish tunnel.
4480 MockWrite data_writes1[] = {
rsleevidb16bb02015-11-12 23:47:174481 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
4482 "Host: www.example.org:443\r\n"
4483 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]029c83b62013-01-24 05:28:204484
rsleevidb16bb02015-11-12 23:47:174485 MockWrite("GET /1 HTTP/1.1\r\n"
4486 "Host: www.example.org\r\n"
4487 "Connection: keep-alive\r\n\r\n"),
[email protected]029c83b62013-01-24 05:28:204488
rsleevidb16bb02015-11-12 23:47:174489 MockWrite("GET /2 HTTP/1.1\r\n"
4490 "Host: www.example.org\r\n"
4491 "Connection: keep-alive\r\n\r\n"),
[email protected]029c83b62013-01-24 05:28:204492 };
4493
4494 // The proxy responds to the connect with a 407, using a persistent
4495 // connection.
4496 MockRead data_reads1[] = {
4497 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
4498
4499 MockRead("HTTP/1.1 200 OK\r\n"),
4500 MockRead("Content-Length: 1\r\n\r\n"),
4501 MockRead(SYNCHRONOUS, "1"),
4502
4503 MockRead("HTTP/1.1 200 OK\r\n"),
4504 MockRead("Content-Length: 2\r\n\r\n"),
4505 MockRead(SYNCHRONOUS, "22"),
4506 };
4507
4508 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
4509 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:074510 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]029c83b62013-01-24 05:28:204511 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:074512 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]029c83b62013-01-24 05:28:204513
4514 TestCompletionCallback callback1;
bnc87dcefc2017-05-25 12:47:584515 auto trans1 =
Jeremy Roman0579ed62017-08-29 15:56:194516 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]029c83b62013-01-24 05:28:204517
4518 int rv = trans1->Start(&request1, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:014519 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]029c83b62013-01-24 05:28:204520
4521 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:014522 EXPECT_THAT(rv, IsOk());
[email protected]029c83b62013-01-24 05:28:204523
4524 const HttpResponseInfo* response1 = trans1->GetResponseInfo();
wezca1070932016-05-26 20:30:524525 ASSERT_TRUE(response1);
tbansal2ecbbc72016-10-06 17:15:474526 EXPECT_TRUE(response1->proxy_server.is_http());
wezca1070932016-05-26 20:30:524527 ASSERT_TRUE(response1->headers);
[email protected]029c83b62013-01-24 05:28:204528 EXPECT_EQ(1, response1->headers->GetContentLength());
4529
4530 LoadTimingInfo load_timing_info1;
4531 EXPECT_TRUE(trans1->GetLoadTimingInfo(&load_timing_info1));
4532 TestLoadTimingNotReused(load_timing_info1, CONNECT_TIMING_HAS_SSL_TIMES);
4533
4534 trans1.reset();
4535
4536 TestCompletionCallback callback2;
bnc87dcefc2017-05-25 12:47:584537 auto trans2 =
Jeremy Roman0579ed62017-08-29 15:56:194538 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]029c83b62013-01-24 05:28:204539
4540 rv = trans2->Start(&request2, callback2.callback(), log.bound());
robpercival214763f2016-07-01 23:27:014541 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]029c83b62013-01-24 05:28:204542
4543 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:014544 EXPECT_THAT(rv, IsOk());
[email protected]029c83b62013-01-24 05:28:204545
4546 const HttpResponseInfo* response2 = trans2->GetResponseInfo();
wezca1070932016-05-26 20:30:524547 ASSERT_TRUE(response2);
tbansal2ecbbc72016-10-06 17:15:474548 EXPECT_TRUE(response2->proxy_server.is_http());
wezca1070932016-05-26 20:30:524549 ASSERT_TRUE(response2->headers);
[email protected]029c83b62013-01-24 05:28:204550 EXPECT_EQ(2, response2->headers->GetContentLength());
4551
4552 LoadTimingInfo load_timing_info2;
4553 EXPECT_TRUE(trans2->GetLoadTimingInfo(&load_timing_info2));
4554 TestLoadTimingReused(load_timing_info2);
4555
4556 EXPECT_EQ(load_timing_info1.socket_log_id, load_timing_info2.socket_log_id);
4557
4558 trans2.reset();
4559 session->CloseAllConnections();
4560}
4561
4562// Test the load timing for HTTPS requests with an HTTP proxy and a PAC script.
bncd16676a2016-07-20 16:23:014563TEST_F(HttpNetworkTransactionTest, HttpProxyLoadTimingWithPacTwoRequests) {
[email protected]029c83b62013-01-24 05:28:204564 HttpRequestInfo request1;
4565 request1.method = "GET";
bncce36dca22015-04-21 22:11:234566 request1.url = GURL("https://www.example.org/1");
[email protected]029c83b62013-01-24 05:28:204567
4568 HttpRequestInfo request2;
4569 request2.method = "GET";
bncce36dca22015-04-21 22:11:234570 request2.url = GURL("https://www.example.org/2");
[email protected]029c83b62013-01-24 05:28:204571
4572 // Configure against proxy server "myproxy:70".
rdsmith82957ad2015-09-16 19:42:034573 session_deps_.proxy_service =
4574 ProxyService::CreateFixedFromPacResult("PROXY myproxy:70");
vishal.b62985ca92015-04-17 08:45:514575 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:074576 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:094577 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]029c83b62013-01-24 05:28:204578
4579 // Since we have proxy, should try to establish tunnel.
4580 MockWrite data_writes1[] = {
rsleevidb16bb02015-11-12 23:47:174581 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
4582 "Host: www.example.org:443\r\n"
4583 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]029c83b62013-01-24 05:28:204584
rsleevidb16bb02015-11-12 23:47:174585 MockWrite("GET /1 HTTP/1.1\r\n"
4586 "Host: www.example.org\r\n"
4587 "Connection: keep-alive\r\n\r\n"),
[email protected]029c83b62013-01-24 05:28:204588
rsleevidb16bb02015-11-12 23:47:174589 MockWrite("GET /2 HTTP/1.1\r\n"
4590 "Host: www.example.org\r\n"
4591 "Connection: keep-alive\r\n\r\n"),
[email protected]029c83b62013-01-24 05:28:204592 };
4593
4594 // The proxy responds to the connect with a 407, using a persistent
4595 // connection.
4596 MockRead data_reads1[] = {
4597 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
4598
4599 MockRead("HTTP/1.1 200 OK\r\n"),
4600 MockRead("Content-Length: 1\r\n\r\n"),
4601 MockRead(SYNCHRONOUS, "1"),
4602
4603 MockRead("HTTP/1.1 200 OK\r\n"),
4604 MockRead("Content-Length: 2\r\n\r\n"),
4605 MockRead(SYNCHRONOUS, "22"),
4606 };
4607
4608 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
4609 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:074610 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]029c83b62013-01-24 05:28:204611 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:074612 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]029c83b62013-01-24 05:28:204613
4614 TestCompletionCallback callback1;
bnc87dcefc2017-05-25 12:47:584615 auto trans1 =
Jeremy Roman0579ed62017-08-29 15:56:194616 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]029c83b62013-01-24 05:28:204617
4618 int rv = trans1->Start(&request1, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:014619 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]029c83b62013-01-24 05:28:204620
4621 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:014622 EXPECT_THAT(rv, IsOk());
[email protected]029c83b62013-01-24 05:28:204623
4624 const HttpResponseInfo* response1 = trans1->GetResponseInfo();
wezca1070932016-05-26 20:30:524625 ASSERT_TRUE(response1);
4626 ASSERT_TRUE(response1->headers);
[email protected]029c83b62013-01-24 05:28:204627 EXPECT_EQ(1, response1->headers->GetContentLength());
4628
4629 LoadTimingInfo load_timing_info1;
4630 EXPECT_TRUE(trans1->GetLoadTimingInfo(&load_timing_info1));
4631 TestLoadTimingNotReusedWithPac(load_timing_info1,
4632 CONNECT_TIMING_HAS_SSL_TIMES);
4633
4634 trans1.reset();
4635
4636 TestCompletionCallback callback2;
bnc87dcefc2017-05-25 12:47:584637 auto trans2 =
Jeremy Roman0579ed62017-08-29 15:56:194638 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]029c83b62013-01-24 05:28:204639
4640 rv = trans2->Start(&request2, callback2.callback(), log.bound());
robpercival214763f2016-07-01 23:27:014641 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]029c83b62013-01-24 05:28:204642
4643 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:014644 EXPECT_THAT(rv, IsOk());
[email protected]029c83b62013-01-24 05:28:204645
4646 const HttpResponseInfo* response2 = trans2->GetResponseInfo();
wezca1070932016-05-26 20:30:524647 ASSERT_TRUE(response2);
4648 ASSERT_TRUE(response2->headers);
[email protected]029c83b62013-01-24 05:28:204649 EXPECT_EQ(2, response2->headers->GetContentLength());
4650
4651 LoadTimingInfo load_timing_info2;
4652 EXPECT_TRUE(trans2->GetLoadTimingInfo(&load_timing_info2));
4653 TestLoadTimingReusedWithPac(load_timing_info2);
4654
4655 EXPECT_EQ(load_timing_info1.socket_log_id, load_timing_info2.socket_log_id);
4656
4657 trans2.reset();
4658 session->CloseAllConnections();
4659}
4660
[email protected]2df19bb2010-08-25 20:13:464661// Test a simple get through an HTTPS Proxy.
bncd16676a2016-07-20 16:23:014662TEST_F(HttpNetworkTransactionTest, HttpsProxyGet) {
[email protected]cb9bf6ca2011-01-28 13:15:274663 HttpRequestInfo request;
4664 request.method = "GET";
bncce36dca22015-04-21 22:11:234665 request.url = GURL("http://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:274666
[email protected]2df19bb2010-08-25 20:13:464667 // Configure against https proxy server "proxy:70".
rdsmith82957ad2015-09-16 19:42:034668 session_deps_.proxy_service = ProxyService::CreateFixed("https://proxy:70");
vishal.b62985ca92015-04-17 08:45:514669 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:074670 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:094671 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]2df19bb2010-08-25 20:13:464672
[email protected]2df19bb2010-08-25 20:13:464673 // Since we have proxy, should use full url
4674 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:234675 MockWrite(
4676 "GET http://www.example.org/ HTTP/1.1\r\n"
4677 "Host: www.example.org\r\n"
4678 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]2df19bb2010-08-25 20:13:464679 };
4680
4681 MockRead data_reads1[] = {
4682 MockRead("HTTP/1.1 200 OK\r\n"),
4683 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
4684 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:064685 MockRead(SYNCHRONOUS, OK),
[email protected]2df19bb2010-08-25 20:13:464686 };
4687
4688 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
4689 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:074690 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8ddf8322012-02-23 18:08:064691 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:074692 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]2df19bb2010-08-25 20:13:464693
[email protected]49639fa2011-12-20 23:22:414694 TestCompletionCallback callback1;
[email protected]2df19bb2010-08-25 20:13:464695
bnc691fda62016-08-12 00:43:164696 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]0b0bf032010-09-21 18:08:504697
bnc691fda62016-08-12 00:43:164698 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:014699 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2df19bb2010-08-25 20:13:464700
4701 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:014702 EXPECT_THAT(rv, IsOk());
[email protected]2df19bb2010-08-25 20:13:464703
[email protected]58e32bb2013-01-21 18:23:254704 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:164705 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]58e32bb2013-01-21 18:23:254706 TestLoadTimingNotReused(load_timing_info,
4707 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
4708
bnc691fda62016-08-12 00:43:164709 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:524710 ASSERT_TRUE(response);
[email protected]2df19bb2010-08-25 20:13:464711
tbansal2ecbbc72016-10-06 17:15:474712 EXPECT_TRUE(response->proxy_server.is_https());
[email protected]2df19bb2010-08-25 20:13:464713 EXPECT_TRUE(response->headers->IsKeepAlive());
4714 EXPECT_EQ(200, response->headers->response_code());
4715 EXPECT_EQ(100, response->headers->GetContentLength());
4716 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
4717
4718 // The password prompt info should not be set.
wezca1070932016-05-26 20:30:524719 EXPECT_FALSE(response->auth_challenge);
[email protected]2df19bb2010-08-25 20:13:464720}
4721
[email protected]7642b5ae2010-09-01 20:55:174722// Test a SPDY get through an HTTPS Proxy.
bncd16676a2016-07-20 16:23:014723TEST_F(HttpNetworkTransactionTest, HttpsProxySpdyGet) {
[email protected]cb9bf6ca2011-01-28 13:15:274724 HttpRequestInfo request;
4725 request.method = "GET";
bncce36dca22015-04-21 22:11:234726 request.url = GURL("http://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:274727
[email protected]7642b5ae2010-09-01 20:55:174728 // Configure against https proxy server "proxy:70".
rdsmith82957ad2015-09-16 19:42:034729 session_deps_.proxy_service = ProxyService::CreateFixed("https://proxy:70");
vishal.b62985ca92015-04-17 08:45:514730 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:074731 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:094732 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]7642b5ae2010-09-01 20:55:174733
bncce36dca22015-04-21 22:11:234734 // fetch http://www.example.org/ via SPDY
bncdf80d44fd2016-07-15 20:27:414735 SpdySerializedFrame req(
bncb26024382016-06-29 02:39:454736 spdy_util_.ConstructSpdyGet("http://www.example.org/", 1, LOWEST));
bncdf80d44fd2016-07-15 20:27:414737 MockWrite spdy_writes[] = {CreateMockWrite(req, 0)};
[email protected]7642b5ae2010-09-01 20:55:174738
bnc42331402016-07-25 13:36:154739 SpdySerializedFrame resp(spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
bncdf80d44fd2016-07-15 20:27:414740 SpdySerializedFrame data(spdy_util_.ConstructSpdyDataFrame(1, true));
[email protected]7642b5ae2010-09-01 20:55:174741 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:414742 CreateMockRead(resp, 1), CreateMockRead(data, 2), MockRead(ASYNC, 0, 3),
[email protected]7642b5ae2010-09-01 20:55:174743 };
4744
rch8e6c6c42015-05-01 14:05:134745 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
4746 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:074747 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]7642b5ae2010-09-01 20:55:174748
[email protected]8ddf8322012-02-23 18:08:064749 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:364750 ssl.next_proto = kProtoHTTP2;
[email protected]bb88e1d32013-05-03 23:11:074751 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]7642b5ae2010-09-01 20:55:174752
[email protected]49639fa2011-12-20 23:22:414753 TestCompletionCallback callback1;
[email protected]7642b5ae2010-09-01 20:55:174754
bnc691fda62016-08-12 00:43:164755 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]0b0bf032010-09-21 18:08:504756
bnc691fda62016-08-12 00:43:164757 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:014758 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]7642b5ae2010-09-01 20:55:174759
4760 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:014761 EXPECT_THAT(rv, IsOk());
[email protected]7642b5ae2010-09-01 20:55:174762
[email protected]58e32bb2013-01-21 18:23:254763 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:164764 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]58e32bb2013-01-21 18:23:254765 TestLoadTimingNotReused(load_timing_info,
4766 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
4767
bnc691fda62016-08-12 00:43:164768 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:524769 ASSERT_TRUE(response);
tbansal2ecbbc72016-10-06 17:15:474770 EXPECT_TRUE(response->proxy_server.is_https());
wezca1070932016-05-26 20:30:524771 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:024772 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]7642b5ae2010-09-01 20:55:174773
4774 std::string response_data;
bnc691fda62016-08-12 00:43:164775 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
[email protected]448d4ca52012-03-04 04:12:234776 EXPECT_EQ(kUploadData, response_data);
[email protected]7642b5ae2010-09-01 20:55:174777}
4778
[email protected]1c173852014-06-19 12:51:504779// Verifies that a session which races and wins against the owning transaction
4780// (completing prior to host resolution), doesn't fail the transaction.
4781// Regression test for crbug.com/334413.
bncd16676a2016-07-20 16:23:014782TEST_F(HttpNetworkTransactionTest, HttpsProxySpdyGetWithSessionRace) {
[email protected]1c173852014-06-19 12:51:504783 HttpRequestInfo request;
4784 request.method = "GET";
bncce36dca22015-04-21 22:11:234785 request.url = GURL("http://www.example.org/");
[email protected]1c173852014-06-19 12:51:504786
4787 // Configure SPDY proxy server "proxy:70".
rdsmith82957ad2015-09-16 19:42:034788 session_deps_.proxy_service = ProxyService::CreateFixed("https://proxy:70");
vishal.b62985ca92015-04-17 08:45:514789 BoundTestNetLog log;
[email protected]1c173852014-06-19 12:51:504790 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:094791 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]1c173852014-06-19 12:51:504792
bncce36dca22015-04-21 22:11:234793 // Fetch http://www.example.org/ through the SPDY proxy.
bncdf80d44fd2016-07-15 20:27:414794 SpdySerializedFrame req(
bncb26024382016-06-29 02:39:454795 spdy_util_.ConstructSpdyGet("http://www.example.org/", 1, LOWEST));
bncdf80d44fd2016-07-15 20:27:414796 MockWrite spdy_writes[] = {CreateMockWrite(req, 0)};
[email protected]1c173852014-06-19 12:51:504797
bnc42331402016-07-25 13:36:154798 SpdySerializedFrame resp(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
bncdf80d44fd2016-07-15 20:27:414799 SpdySerializedFrame data(spdy_util_.ConstructSpdyDataFrame(1, true));
[email protected]1c173852014-06-19 12:51:504800 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:414801 CreateMockRead(resp, 1), CreateMockRead(data, 2), MockRead(ASYNC, 0, 3),
[email protected]1c173852014-06-19 12:51:504802 };
4803
rch8e6c6c42015-05-01 14:05:134804 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
4805 arraysize(spdy_writes));
[email protected]1c173852014-06-19 12:51:504806 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
4807
4808 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:364809 ssl.next_proto = kProtoHTTP2;
[email protected]1c173852014-06-19 12:51:504810 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
4811
4812 TestCompletionCallback callback1;
4813
bnc691fda62016-08-12 00:43:164814 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]1c173852014-06-19 12:51:504815
4816 // Stall the hostname resolution begun by the transaction.
4817 session_deps_.host_resolver->set_synchronous_mode(false);
4818 session_deps_.host_resolver->set_ondemand_mode(true);
4819
bnc691fda62016-08-12 00:43:164820 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:014821 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]1c173852014-06-19 12:51:504822
4823 // Race a session to the proxy, which completes first.
4824 session_deps_.host_resolver->set_ondemand_mode(false);
4825 SpdySessionKey key(
4826 HostPortPair("proxy", 70), ProxyServer::Direct(), PRIVACY_MODE_DISABLED);
4827 base::WeakPtr<SpdySession> spdy_session =
Bence Béky0ef1556e2017-06-30 19:52:524828 CreateSpdySession(session.get(), key, log.bound());
[email protected]1c173852014-06-19 12:51:504829
4830 // Unstall the resolution begun by the transaction.
4831 session_deps_.host_resolver->set_ondemand_mode(true);
4832 session_deps_.host_resolver->ResolveAllPending();
4833
4834 EXPECT_FALSE(callback1.have_result());
4835 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:014836 EXPECT_THAT(rv, IsOk());
[email protected]1c173852014-06-19 12:51:504837
bnc691fda62016-08-12 00:43:164838 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:524839 ASSERT_TRUE(response);
4840 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:024841 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]1c173852014-06-19 12:51:504842
4843 std::string response_data;
bnc691fda62016-08-12 00:43:164844 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
[email protected]1c173852014-06-19 12:51:504845 EXPECT_EQ(kUploadData, response_data);
4846}
4847
[email protected]dc7bd1c52010-11-12 00:01:134848// Test a SPDY get through an HTTPS Proxy.
bncd16676a2016-07-20 16:23:014849TEST_F(HttpNetworkTransactionTest, HttpsProxySpdyGetWithProxyAuth) {
[email protected]cb9bf6ca2011-01-28 13:15:274850 HttpRequestInfo request;
4851 request.method = "GET";
bncce36dca22015-04-21 22:11:234852 request.url = GURL("http://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:274853
[email protected]79cb5c12011-09-12 13:12:044854 // Configure against https proxy server "myproxy:70".
rdsmith82957ad2015-09-16 19:42:034855 session_deps_.proxy_service = ProxyService::CreateFixed("https://myproxy:70");
vishal.b62985ca92015-04-17 08:45:514856 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:074857 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:094858 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]dc7bd1c52010-11-12 00:01:134859
[email protected]dc7bd1c52010-11-12 00:01:134860 // The first request will be a bare GET, the second request will be a
4861 // GET with a Proxy-Authorization header.
bncb26024382016-06-29 02:39:454862 spdy_util_.set_default_url(request.url);
bncdf80d44fd2016-07-15 20:27:414863 SpdySerializedFrame req_get(
bnc38dcd392016-02-09 23:19:494864 spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST, false));
rdsmithebb50aa2015-11-12 03:44:384865 spdy_util_.UpdateWithStreamDestruction(1);
[email protected]dc7bd1c52010-11-12 00:01:134866 const char* const kExtraAuthorizationHeaders[] = {
[email protected]cdf8f7e72013-05-23 10:56:464867 "proxy-authorization", "Basic Zm9vOmJhcg=="
[email protected]dc7bd1c52010-11-12 00:01:134868 };
bncdf80d44fd2016-07-15 20:27:414869 SpdySerializedFrame req_get_authorization(spdy_util_.ConstructSpdyGet(
4870 kExtraAuthorizationHeaders, arraysize(kExtraAuthorizationHeaders) / 2, 3,
4871 LOWEST, false));
[email protected]dc7bd1c52010-11-12 00:01:134872 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:414873 CreateMockWrite(req_get, 0), CreateMockWrite(req_get_authorization, 3),
[email protected]dc7bd1c52010-11-12 00:01:134874 };
4875
4876 // The first response is a 407 proxy authentication challenge, and the second
4877 // response will be a 200 response since the second request includes a valid
4878 // Authorization header.
4879 const char* const kExtraAuthenticationHeaders[] = {
[email protected]cdf8f7e72013-05-23 10:56:464880 "proxy-authenticate", "Basic realm=\"MyRealm1\""
[email protected]dc7bd1c52010-11-12 00:01:134881 };
bnc42331402016-07-25 13:36:154882 SpdySerializedFrame resp_authentication(spdy_util_.ConstructSpdyReplyError(
bncc9f762a2016-12-06 20:38:234883 "407", kExtraAuthenticationHeaders,
bncdf80d44fd2016-07-15 20:27:414884 arraysize(kExtraAuthenticationHeaders) / 2, 1));
4885 SpdySerializedFrame body_authentication(
4886 spdy_util_.ConstructSpdyDataFrame(1, true));
bnc42331402016-07-25 13:36:154887 SpdySerializedFrame resp_data(spdy_util_.ConstructSpdyGetReply(NULL, 0, 3));
bncdf80d44fd2016-07-15 20:27:414888 SpdySerializedFrame body_data(spdy_util_.ConstructSpdyDataFrame(3, true));
[email protected]dc7bd1c52010-11-12 00:01:134889 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:414890 CreateMockRead(resp_authentication, 1),
bnceb9aa7112017-01-05 01:03:464891 CreateMockRead(body_authentication, 2, SYNCHRONOUS),
bncdf80d44fd2016-07-15 20:27:414892 CreateMockRead(resp_data, 4),
4893 CreateMockRead(body_data, 5),
rch8e6c6c42015-05-01 14:05:134894 MockRead(ASYNC, 0, 6),
[email protected]dc7bd1c52010-11-12 00:01:134895 };
4896
rch8e6c6c42015-05-01 14:05:134897 SequencedSocketData data(spdy_reads, arraysize(spdy_reads), spdy_writes,
4898 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:074899 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]dc7bd1c52010-11-12 00:01:134900
[email protected]8ddf8322012-02-23 18:08:064901 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:364902 ssl.next_proto = kProtoHTTP2;
[email protected]bb88e1d32013-05-03 23:11:074903 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]dc7bd1c52010-11-12 00:01:134904
[email protected]49639fa2011-12-20 23:22:414905 TestCompletionCallback callback1;
[email protected]dc7bd1c52010-11-12 00:01:134906
bnc691fda62016-08-12 00:43:164907 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]dc7bd1c52010-11-12 00:01:134908
bnc691fda62016-08-12 00:43:164909 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:014910 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]dc7bd1c52010-11-12 00:01:134911
4912 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:014913 EXPECT_THAT(rv, IsOk());
[email protected]dc7bd1c52010-11-12 00:01:134914
bnc691fda62016-08-12 00:43:164915 const HttpResponseInfo* const response = trans.GetResponseInfo();
[email protected]dc7bd1c52010-11-12 00:01:134916
wezca1070932016-05-26 20:30:524917 ASSERT_TRUE(response);
4918 ASSERT_TRUE(response->headers);
[email protected]dc7bd1c52010-11-12 00:01:134919 EXPECT_EQ(407, response->headers->response_code());
4920 EXPECT_TRUE(response->was_fetched_via_spdy);
asanka098c0092016-06-16 20:18:434921 EXPECT_TRUE(CheckBasicSecureProxyAuth(response->auth_challenge.get()));
[email protected]dc7bd1c52010-11-12 00:01:134922
[email protected]49639fa2011-12-20 23:22:414923 TestCompletionCallback callback2;
[email protected]dc7bd1c52010-11-12 00:01:134924
bnc691fda62016-08-12 00:43:164925 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar), callback2.callback());
robpercival214763f2016-07-01 23:27:014926 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]dc7bd1c52010-11-12 00:01:134927
4928 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:014929 EXPECT_THAT(rv, IsOk());
[email protected]dc7bd1c52010-11-12 00:01:134930
bnc691fda62016-08-12 00:43:164931 const HttpResponseInfo* const response_restart = trans.GetResponseInfo();
[email protected]dc7bd1c52010-11-12 00:01:134932
wezca1070932016-05-26 20:30:524933 ASSERT_TRUE(response_restart);
4934 ASSERT_TRUE(response_restart->headers);
[email protected]dc7bd1c52010-11-12 00:01:134935 EXPECT_EQ(200, response_restart->headers->response_code());
4936 // The password prompt info should not be set.
wezca1070932016-05-26 20:30:524937 EXPECT_FALSE(response_restart->auth_challenge);
[email protected]dc7bd1c52010-11-12 00:01:134938}
4939
[email protected]d9da5fe2010-10-13 22:37:164940// Test a SPDY CONNECT through an HTTPS Proxy to an HTTPS (non-SPDY) Server.
bncd16676a2016-07-20 16:23:014941TEST_F(HttpNetworkTransactionTest, HttpsProxySpdyConnectHttps) {
[email protected]cb9bf6ca2011-01-28 13:15:274942 HttpRequestInfo request;
4943 request.method = "GET";
bncce36dca22015-04-21 22:11:234944 request.url = GURL("https://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:274945
[email protected]d9da5fe2010-10-13 22:37:164946 // Configure against https proxy server "proxy:70".
rdsmith82957ad2015-09-16 19:42:034947 session_deps_.proxy_service = ProxyService::CreateFixed("https://proxy:70");
vishal.b62985ca92015-04-17 08:45:514948 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:074949 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:094950 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]d9da5fe2010-10-13 22:37:164951
bnc691fda62016-08-12 00:43:164952 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]d9da5fe2010-10-13 22:37:164953
bncce36dca22015-04-21 22:11:234954 // CONNECT to www.example.org:443 via SPDY
bncdf80d44fd2016-07-15 20:27:414955 SpdySerializedFrame connect(spdy_util_.ConstructSpdyConnect(
bncce36dca22015-04-21 22:11:234956 NULL, 0, 1, LOWEST, HostPortPair("www.example.org", 443)));
4957 // fetch https://www.example.org/ via HTTP
[email protected]d9da5fe2010-10-13 22:37:164958
bncce36dca22015-04-21 22:11:234959 const char get[] =
4960 "GET / HTTP/1.1\r\n"
4961 "Host: www.example.org\r\n"
4962 "Connection: keep-alive\r\n\r\n";
bncdf80d44fd2016-07-15 20:27:414963 SpdySerializedFrame wrapped_get(
4964 spdy_util_.ConstructSpdyDataFrame(1, get, strlen(get), false));
bnc42331402016-07-25 13:36:154965 SpdySerializedFrame conn_resp(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
[email protected]d9da5fe2010-10-13 22:37:164966 const char resp[] = "HTTP/1.1 200 OK\r\n"
4967 "Content-Length: 10\r\n\r\n";
bncdf80d44fd2016-07-15 20:27:414968 SpdySerializedFrame wrapped_get_resp(
4969 spdy_util_.ConstructSpdyDataFrame(1, resp, strlen(resp), false));
4970 SpdySerializedFrame wrapped_body(
4971 spdy_util_.ConstructSpdyDataFrame(1, "1234567890", 10, false));
4972 SpdySerializedFrame window_update(
4973 spdy_util_.ConstructSpdyWindowUpdate(1, wrapped_get_resp.size()));
[email protected]8d2f7012012-02-16 00:08:044974
4975 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:414976 CreateMockWrite(connect, 0), CreateMockWrite(wrapped_get, 2),
4977 CreateMockWrite(window_update, 6),
[email protected]8d2f7012012-02-16 00:08:044978 };
4979
[email protected]d9da5fe2010-10-13 22:37:164980 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:414981 CreateMockRead(conn_resp, 1, ASYNC),
4982 CreateMockRead(wrapped_get_resp, 3, ASYNC),
4983 CreateMockRead(wrapped_body, 4, ASYNC),
4984 CreateMockRead(wrapped_body, 5, ASYNC),
rch8e6c6c42015-05-01 14:05:134985 MockRead(ASYNC, 0, 7),
[email protected]d9da5fe2010-10-13 22:37:164986 };
4987
rch8e6c6c42015-05-01 14:05:134988 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
4989 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:074990 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]d9da5fe2010-10-13 22:37:164991
[email protected]8ddf8322012-02-23 18:08:064992 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:364993 ssl.next_proto = kProtoHTTP2;
[email protected]bb88e1d32013-05-03 23:11:074994 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]8ddf8322012-02-23 18:08:064995 SSLSocketDataProvider ssl2(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:074996 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
[email protected]d9da5fe2010-10-13 22:37:164997
[email protected]49639fa2011-12-20 23:22:414998 TestCompletionCallback callback1;
[email protected]d9da5fe2010-10-13 22:37:164999
bnc691fda62016-08-12 00:43:165000 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:015001 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]d9da5fe2010-10-13 22:37:165002
5003 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:015004 ASSERT_THAT(rv, IsOk());
[email protected]d9da5fe2010-10-13 22:37:165005
[email protected]58e32bb2013-01-21 18:23:255006 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:165007 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]58e32bb2013-01-21 18:23:255008 TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_SSL_TIMES);
5009
bnc691fda62016-08-12 00:43:165010 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:525011 ASSERT_TRUE(response);
5012 ASSERT_TRUE(response->headers);
[email protected]d9da5fe2010-10-13 22:37:165013 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
5014
5015 std::string response_data;
bnc691fda62016-08-12 00:43:165016 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
[email protected]d9da5fe2010-10-13 22:37:165017 EXPECT_EQ("1234567890", response_data);
5018}
5019
5020// Test a SPDY CONNECT through an HTTPS Proxy to a SPDY server.
bncd16676a2016-07-20 16:23:015021TEST_F(HttpNetworkTransactionTest, HttpsProxySpdyConnectSpdy) {
5022 SpdyTestUtil spdy_util_wrapped;
rdsmithebb50aa2015-11-12 03:44:385023
[email protected]cb9bf6ca2011-01-28 13:15:275024 HttpRequestInfo request;
5025 request.method = "GET";
bncce36dca22015-04-21 22:11:235026 request.url = GURL("https://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:275027
[email protected]d9da5fe2010-10-13 22:37:165028 // Configure against https proxy server "proxy:70".
rdsmith82957ad2015-09-16 19:42:035029 session_deps_.proxy_service = ProxyService::CreateFixed("https://proxy:70");
vishal.b62985ca92015-04-17 08:45:515030 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:075031 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:095032 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]d9da5fe2010-10-13 22:37:165033
bnc691fda62016-08-12 00:43:165034 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]d9da5fe2010-10-13 22:37:165035
bncce36dca22015-04-21 22:11:235036 // CONNECT to www.example.org:443 via SPDY
bncdf80d44fd2016-07-15 20:27:415037 SpdySerializedFrame connect(spdy_util_.ConstructSpdyConnect(
bncce36dca22015-04-21 22:11:235038 NULL, 0, 1, LOWEST, HostPortPair("www.example.org", 443)));
5039 // fetch https://www.example.org/ via SPDY
5040 const char kMyUrl[] = "https://www.example.org/";
bncdf80d44fd2016-07-15 20:27:415041 SpdySerializedFrame get(
bnc38dcd392016-02-09 23:19:495042 spdy_util_wrapped.ConstructSpdyGet(kMyUrl, 1, LOWEST));
bncdf80d44fd2016-07-15 20:27:415043 SpdySerializedFrame wrapped_get(spdy_util_.ConstructWrappedSpdyFrame(get, 1));
bnc42331402016-07-25 13:36:155044 SpdySerializedFrame conn_resp(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
bncdf80d44fd2016-07-15 20:27:415045 SpdySerializedFrame get_resp(
bnc42331402016-07-25 13:36:155046 spdy_util_wrapped.ConstructSpdyGetReply(NULL, 0, 1));
bncdf80d44fd2016-07-15 20:27:415047 SpdySerializedFrame wrapped_get_resp(
[email protected]23e482282013-06-14 16:08:025048 spdy_util_.ConstructWrappedSpdyFrame(get_resp, 1));
bncdf80d44fd2016-07-15 20:27:415049 SpdySerializedFrame body(spdy_util_wrapped.ConstructSpdyDataFrame(1, true));
5050 SpdySerializedFrame wrapped_body(
[email protected]23e482282013-06-14 16:08:025051 spdy_util_.ConstructWrappedSpdyFrame(body, 1));
bncdf80d44fd2016-07-15 20:27:415052 SpdySerializedFrame window_update_get_resp(
5053 spdy_util_.ConstructSpdyWindowUpdate(1, wrapped_get_resp.size()));
5054 SpdySerializedFrame window_update_body(
5055 spdy_util_.ConstructSpdyWindowUpdate(1, wrapped_body.size()));
[email protected]8d2f7012012-02-16 00:08:045056
5057 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:415058 CreateMockWrite(connect, 0), CreateMockWrite(wrapped_get, 2),
5059 CreateMockWrite(window_update_get_resp, 6),
5060 CreateMockWrite(window_update_body, 7),
[email protected]8d2f7012012-02-16 00:08:045061 };
5062
[email protected]d9da5fe2010-10-13 22:37:165063 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:415064 CreateMockRead(conn_resp, 1, ASYNC),
rch32320842015-05-16 15:57:095065 MockRead(ASYNC, ERR_IO_PENDING, 3),
bncdf80d44fd2016-07-15 20:27:415066 CreateMockRead(wrapped_get_resp, 4, ASYNC),
5067 CreateMockRead(wrapped_body, 5, ASYNC),
rch8e6c6c42015-05-01 14:05:135068 MockRead(ASYNC, 0, 8),
[email protected]d9da5fe2010-10-13 22:37:165069 };
5070
rch32320842015-05-16 15:57:095071 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
5072 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:075073 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]d9da5fe2010-10-13 22:37:165074
[email protected]8ddf8322012-02-23 18:08:065075 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:365076 ssl.next_proto = kProtoHTTP2;
[email protected]bb88e1d32013-05-03 23:11:075077 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]8ddf8322012-02-23 18:08:065078 SSLSocketDataProvider ssl2(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:365079 ssl2.next_proto = kProtoHTTP2;
[email protected]bb88e1d32013-05-03 23:11:075080 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
[email protected]d9da5fe2010-10-13 22:37:165081
[email protected]49639fa2011-12-20 23:22:415082 TestCompletionCallback callback1;
[email protected]d9da5fe2010-10-13 22:37:165083
bnc691fda62016-08-12 00:43:165084 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:015085 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]d9da5fe2010-10-13 22:37:165086
rch32320842015-05-16 15:57:095087 // Allow the SpdyProxyClientSocket's write callback to complete.
fdoray92e35a72016-06-10 15:54:555088 base::RunLoop().RunUntilIdle();
rch32320842015-05-16 15:57:095089 // Now allow the read of the response to complete.
mmenkee24011922015-12-17 22:12:595090 spdy_data.Resume();
[email protected]d9da5fe2010-10-13 22:37:165091 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:015092 EXPECT_THAT(rv, IsOk());
[email protected]d9da5fe2010-10-13 22:37:165093
[email protected]58e32bb2013-01-21 18:23:255094 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:165095 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]58e32bb2013-01-21 18:23:255096 TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_SSL_TIMES);
5097
bnc691fda62016-08-12 00:43:165098 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:525099 ASSERT_TRUE(response);
5100 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:025101 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]d9da5fe2010-10-13 22:37:165102
5103 std::string response_data;
bnc691fda62016-08-12 00:43:165104 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
[email protected]448d4ca52012-03-04 04:12:235105 EXPECT_EQ(kUploadData, response_data);
[email protected]d9da5fe2010-10-13 22:37:165106}
5107
5108// Test a SPDY CONNECT failure through an HTTPS Proxy.
bncd16676a2016-07-20 16:23:015109TEST_F(HttpNetworkTransactionTest, HttpsProxySpdyConnectFailure) {
[email protected]cb9bf6ca2011-01-28 13:15:275110 HttpRequestInfo request;
5111 request.method = "GET";
bncce36dca22015-04-21 22:11:235112 request.url = GURL("https://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:275113
[email protected]d9da5fe2010-10-13 22:37:165114 // Configure against https proxy server "proxy:70".
rdsmith82957ad2015-09-16 19:42:035115 session_deps_.proxy_service = ProxyService::CreateFixed("https://proxy:70");
vishal.b62985ca92015-04-17 08:45:515116 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:075117 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:095118 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]d9da5fe2010-10-13 22:37:165119
bnc691fda62016-08-12 00:43:165120 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]d9da5fe2010-10-13 22:37:165121
bncce36dca22015-04-21 22:11:235122 // CONNECT to www.example.org:443 via SPDY
bncdf80d44fd2016-07-15 20:27:415123 SpdySerializedFrame connect(spdy_util_.ConstructSpdyConnect(
bncce36dca22015-04-21 22:11:235124 NULL, 0, 1, LOWEST, HostPortPair("www.example.org", 443)));
bncdf80d44fd2016-07-15 20:27:415125 SpdySerializedFrame get(
diannahu9904e272017-02-03 14:40:085126 spdy_util_.ConstructSpdyRstStream(1, ERROR_CODE_CANCEL));
[email protected]d9da5fe2010-10-13 22:37:165127
5128 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:415129 CreateMockWrite(connect, 0), CreateMockWrite(get, 2),
[email protected]d9da5fe2010-10-13 22:37:165130 };
5131
bnc42331402016-07-25 13:36:155132 SpdySerializedFrame resp(spdy_util_.ConstructSpdyReplyError(1));
bncdf80d44fd2016-07-15 20:27:415133 SpdySerializedFrame data(spdy_util_.ConstructSpdyDataFrame(1, true));
[email protected]d9da5fe2010-10-13 22:37:165134 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:415135 CreateMockRead(resp, 1, ASYNC), MockRead(ASYNC, 0, 3),
[email protected]d9da5fe2010-10-13 22:37:165136 };
5137
rch8e6c6c42015-05-01 14:05:135138 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
5139 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:075140 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]d9da5fe2010-10-13 22:37:165141
[email protected]8ddf8322012-02-23 18:08:065142 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:365143 ssl.next_proto = kProtoHTTP2;
[email protected]bb88e1d32013-05-03 23:11:075144 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]8ddf8322012-02-23 18:08:065145 SSLSocketDataProvider ssl2(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:365146 ssl2.next_proto = kProtoHTTP2;
[email protected]bb88e1d32013-05-03 23:11:075147 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
[email protected]d9da5fe2010-10-13 22:37:165148
[email protected]49639fa2011-12-20 23:22:415149 TestCompletionCallback callback1;
[email protected]d9da5fe2010-10-13 22:37:165150
bnc691fda62016-08-12 00:43:165151 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:015152 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]d9da5fe2010-10-13 22:37:165153
5154 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:015155 EXPECT_THAT(rv, IsError(ERR_TUNNEL_CONNECTION_FAILED));
[email protected]d9da5fe2010-10-13 22:37:165156
ttuttle960fcbf2016-04-19 13:26:325157 // TODO(juliatuttle): Anything else to check here?
[email protected]d9da5fe2010-10-13 22:37:165158}
5159
[email protected]f6c63db52013-02-02 00:35:225160// Test load timing in the case of two HTTPS (non-SPDY) requests through a SPDY
5161// HTTPS Proxy to different servers.
bncd16676a2016-07-20 16:23:015162TEST_F(HttpNetworkTransactionTest,
[email protected]f6c63db52013-02-02 00:35:225163 HttpsProxySpdyConnectHttpsLoadTimingTwoRequestsTwoServers) {
5164 // Configure against https proxy server "proxy:70".
rdsmith82957ad2015-09-16 19:42:035165 session_deps_.proxy_service = ProxyService::CreateFixed("https://proxy:70");
vishal.b62985ca92015-04-17 08:45:515166 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:075167 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:095168 std::unique_ptr<HttpNetworkSession> session(
mmenke11eb5152015-06-09 14:50:505169 SpdySessionDependencies::SpdyCreateSession(&session_deps_));
[email protected]f6c63db52013-02-02 00:35:225170
5171 HttpRequestInfo request1;
5172 request1.method = "GET";
bncce36dca22015-04-21 22:11:235173 request1.url = GURL("https://www.example.org/");
[email protected]f6c63db52013-02-02 00:35:225174 request1.load_flags = 0;
5175
5176 HttpRequestInfo request2;
5177 request2.method = "GET";
bncce36dca22015-04-21 22:11:235178 request2.url = GURL("https://mail.example.org/");
[email protected]f6c63db52013-02-02 00:35:225179 request2.load_flags = 0;
5180
bncce36dca22015-04-21 22:11:235181 // CONNECT to www.example.org:443 via SPDY.
bncdf80d44fd2016-07-15 20:27:415182 SpdySerializedFrame connect1(spdy_util_.ConstructSpdyConnect(
bncce36dca22015-04-21 22:11:235183 NULL, 0, 1, LOWEST, HostPortPair("www.example.org", 443)));
bnc42331402016-07-25 13:36:155184 SpdySerializedFrame conn_resp1(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
[email protected]f6c63db52013-02-02 00:35:225185
bncce36dca22015-04-21 22:11:235186 // Fetch https://www.example.org/ via HTTP.
5187 const char get1[] =
5188 "GET / HTTP/1.1\r\n"
5189 "Host: www.example.org\r\n"
[email protected]f6c63db52013-02-02 00:35:225190 "Connection: keep-alive\r\n\r\n";
bncdf80d44fd2016-07-15 20:27:415191 SpdySerializedFrame wrapped_get1(
5192 spdy_util_.ConstructSpdyDataFrame(1, get1, strlen(get1), false));
[email protected]f6c63db52013-02-02 00:35:225193 const char resp1[] = "HTTP/1.1 200 OK\r\n"
5194 "Content-Length: 1\r\n\r\n";
bncdf80d44fd2016-07-15 20:27:415195 SpdySerializedFrame wrapped_get_resp1(
5196 spdy_util_.ConstructSpdyDataFrame(1, resp1, strlen(resp1), false));
5197 SpdySerializedFrame wrapped_body1(
5198 spdy_util_.ConstructSpdyDataFrame(1, "1", 1, false));
5199 SpdySerializedFrame window_update(
5200 spdy_util_.ConstructSpdyWindowUpdate(1, wrapped_get_resp1.size()));
[email protected]f6c63db52013-02-02 00:35:225201
bncce36dca22015-04-21 22:11:235202 // CONNECT to mail.example.org:443 via SPDY.
[email protected]745aa9c2014-06-27 02:21:295203 SpdyHeaderBlock connect2_block;
5204 connect2_block[spdy_util_.GetMethodKey()] = "CONNECT";
bnca9b9e222016-07-11 20:10:405205 connect2_block[spdy_util_.GetHostKey()] = "mail.example.org:443";
bnc42331402016-07-25 13:36:155206 SpdySerializedFrame connect2(spdy_util_.ConstructSpdyHeaders(
5207 3, std::move(connect2_block), LOWEST, false));
[email protected]601e03f12014-04-06 16:26:395208
bnc42331402016-07-25 13:36:155209 SpdySerializedFrame conn_resp2(spdy_util_.ConstructSpdyGetReply(NULL, 0, 3));
[email protected]f6c63db52013-02-02 00:35:225210
bncce36dca22015-04-21 22:11:235211 // Fetch https://mail.example.org/ via HTTP.
5212 const char get2[] =
5213 "GET / HTTP/1.1\r\n"
5214 "Host: mail.example.org\r\n"
[email protected]f6c63db52013-02-02 00:35:225215 "Connection: keep-alive\r\n\r\n";
bncdf80d44fd2016-07-15 20:27:415216 SpdySerializedFrame wrapped_get2(
5217 spdy_util_.ConstructSpdyDataFrame(3, get2, strlen(get2), false));
[email protected]f6c63db52013-02-02 00:35:225218 const char resp2[] = "HTTP/1.1 200 OK\r\n"
5219 "Content-Length: 2\r\n\r\n";
bncdf80d44fd2016-07-15 20:27:415220 SpdySerializedFrame wrapped_get_resp2(
5221 spdy_util_.ConstructSpdyDataFrame(3, resp2, strlen(resp2), false));
5222 SpdySerializedFrame wrapped_body2(
5223 spdy_util_.ConstructSpdyDataFrame(3, "22", 2, false));
[email protected]f6c63db52013-02-02 00:35:225224
5225 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:415226 CreateMockWrite(connect1, 0), CreateMockWrite(wrapped_get1, 2),
5227 CreateMockWrite(connect2, 5), CreateMockWrite(wrapped_get2, 7),
[email protected]f6c63db52013-02-02 00:35:225228 };
5229
5230 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:415231 CreateMockRead(conn_resp1, 1, ASYNC),
5232 CreateMockRead(wrapped_get_resp1, 3, ASYNC),
5233 CreateMockRead(wrapped_body1, 4, ASYNC),
5234 CreateMockRead(conn_resp2, 6, ASYNC),
5235 CreateMockRead(wrapped_get_resp2, 8, ASYNC),
5236 CreateMockRead(wrapped_body2, 9, ASYNC),
5237 MockRead(ASYNC, 0, 10),
[email protected]f6c63db52013-02-02 00:35:225238 };
5239
mmenke11eb5152015-06-09 14:50:505240 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
5241 arraysize(spdy_writes));
5242 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]f6c63db52013-02-02 00:35:225243
5244 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:365245 ssl.next_proto = kProtoHTTP2;
mmenke11eb5152015-06-09 14:50:505246 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]f6c63db52013-02-02 00:35:225247 SSLSocketDataProvider ssl2(ASYNC, OK);
mmenke11eb5152015-06-09 14:50:505248 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
[email protected]f6c63db52013-02-02 00:35:225249 SSLSocketDataProvider ssl3(ASYNC, OK);
mmenke11eb5152015-06-09 14:50:505250 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl3);
[email protected]f6c63db52013-02-02 00:35:225251
5252 TestCompletionCallback callback;
5253
bnc691fda62016-08-12 00:43:165254 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:205255 int rv = trans.Start(&request1, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:015256 EXPECT_THAT(callback.GetResult(rv), IsOk());
[email protected]f6c63db52013-02-02 00:35:225257
5258 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:165259 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]f6c63db52013-02-02 00:35:225260 TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_SSL_TIMES);
5261
bnc691fda62016-08-12 00:43:165262 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:525263 ASSERT_TRUE(response);
5264 ASSERT_TRUE(response->headers);
[email protected]f6c63db52013-02-02 00:35:225265 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
5266
5267 std::string response_data;
ttuttle859dc7a2015-04-23 19:42:295268 scoped_refptr<IOBuffer> buf(new IOBuffer(256));
bnc691fda62016-08-12 00:43:165269 rv = trans.Read(buf.get(), 256, callback.callback());
mmenke11eb5152015-06-09 14:50:505270 EXPECT_EQ(1, callback.GetResult(rv));
[email protected]f6c63db52013-02-02 00:35:225271
bnc691fda62016-08-12 00:43:165272 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:205273 rv = trans2.Start(&request2, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:015274 EXPECT_THAT(callback.GetResult(rv), IsOk());
[email protected]f6c63db52013-02-02 00:35:225275
5276 LoadTimingInfo load_timing_info2;
bnc691fda62016-08-12 00:43:165277 EXPECT_TRUE(trans2.GetLoadTimingInfo(&load_timing_info2));
[email protected]f6c63db52013-02-02 00:35:225278 // Even though the SPDY connection is reused, a new tunnelled connection has
5279 // to be created, so the socket's load timing looks like a fresh connection.
5280 TestLoadTimingNotReused(load_timing_info2, CONNECT_TIMING_HAS_SSL_TIMES);
5281
5282 // The requests should have different IDs, since they each are using their own
5283 // separate stream.
5284 EXPECT_NE(load_timing_info.socket_log_id, load_timing_info2.socket_log_id);
5285
bnc691fda62016-08-12 00:43:165286 rv = trans2.Read(buf.get(), 256, callback.callback());
mmenke11eb5152015-06-09 14:50:505287 EXPECT_EQ(2, callback.GetResult(rv));
[email protected]f6c63db52013-02-02 00:35:225288}
5289
5290// Test load timing in the case of two HTTPS (non-SPDY) requests through a SPDY
5291// HTTPS Proxy to the same server.
bncd16676a2016-07-20 16:23:015292TEST_F(HttpNetworkTransactionTest,
[email protected]f6c63db52013-02-02 00:35:225293 HttpsProxySpdyConnectHttpsLoadTimingTwoRequestsSameServer) {
5294 // Configure against https proxy server "proxy:70".
rdsmith82957ad2015-09-16 19:42:035295 session_deps_.proxy_service = ProxyService::CreateFixed("https://proxy:70");
vishal.b62985ca92015-04-17 08:45:515296 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:075297 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:095298 std::unique_ptr<HttpNetworkSession> session(
mmenke11eb5152015-06-09 14:50:505299 SpdySessionDependencies::SpdyCreateSession(&session_deps_));
[email protected]f6c63db52013-02-02 00:35:225300
5301 HttpRequestInfo request1;
5302 request1.method = "GET";
bncce36dca22015-04-21 22:11:235303 request1.url = GURL("https://www.example.org/");
[email protected]f6c63db52013-02-02 00:35:225304 request1.load_flags = 0;
5305
5306 HttpRequestInfo request2;
5307 request2.method = "GET";
bncce36dca22015-04-21 22:11:235308 request2.url = GURL("https://www.example.org/2");
[email protected]f6c63db52013-02-02 00:35:225309 request2.load_flags = 0;
5310
bncce36dca22015-04-21 22:11:235311 // CONNECT to www.example.org:443 via SPDY.
bncdf80d44fd2016-07-15 20:27:415312 SpdySerializedFrame connect1(spdy_util_.ConstructSpdyConnect(
bncce36dca22015-04-21 22:11:235313 NULL, 0, 1, LOWEST, HostPortPair("www.example.org", 443)));
bnc42331402016-07-25 13:36:155314 SpdySerializedFrame conn_resp1(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
[email protected]f6c63db52013-02-02 00:35:225315
bncce36dca22015-04-21 22:11:235316 // Fetch https://www.example.org/ via HTTP.
5317 const char get1[] =
5318 "GET / HTTP/1.1\r\n"
5319 "Host: www.example.org\r\n"
[email protected]f6c63db52013-02-02 00:35:225320 "Connection: keep-alive\r\n\r\n";
bncdf80d44fd2016-07-15 20:27:415321 SpdySerializedFrame wrapped_get1(
5322 spdy_util_.ConstructSpdyDataFrame(1, get1, strlen(get1), false));
[email protected]f6c63db52013-02-02 00:35:225323 const char resp1[] = "HTTP/1.1 200 OK\r\n"
5324 "Content-Length: 1\r\n\r\n";
bncdf80d44fd2016-07-15 20:27:415325 SpdySerializedFrame wrapped_get_resp1(
5326 spdy_util_.ConstructSpdyDataFrame(1, resp1, strlen(resp1), false));
5327 SpdySerializedFrame wrapped_body1(
5328 spdy_util_.ConstructSpdyDataFrame(1, "1", 1, false));
5329 SpdySerializedFrame window_update(
5330 spdy_util_.ConstructSpdyWindowUpdate(1, wrapped_get_resp1.size()));
[email protected]f6c63db52013-02-02 00:35:225331
bncce36dca22015-04-21 22:11:235332 // Fetch https://www.example.org/2 via HTTP.
5333 const char get2[] =
5334 "GET /2 HTTP/1.1\r\n"
5335 "Host: www.example.org\r\n"
[email protected]f6c63db52013-02-02 00:35:225336 "Connection: keep-alive\r\n\r\n";
bncdf80d44fd2016-07-15 20:27:415337 SpdySerializedFrame wrapped_get2(
5338 spdy_util_.ConstructSpdyDataFrame(1, get2, strlen(get2), false));
[email protected]f6c63db52013-02-02 00:35:225339 const char resp2[] = "HTTP/1.1 200 OK\r\n"
5340 "Content-Length: 2\r\n\r\n";
bncdf80d44fd2016-07-15 20:27:415341 SpdySerializedFrame wrapped_get_resp2(
5342 spdy_util_.ConstructSpdyDataFrame(1, resp2, strlen(resp2), false));
5343 SpdySerializedFrame wrapped_body2(
5344 spdy_util_.ConstructSpdyDataFrame(1, "22", 2, false));
[email protected]f6c63db52013-02-02 00:35:225345
5346 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:415347 CreateMockWrite(connect1, 0), CreateMockWrite(wrapped_get1, 2),
5348 CreateMockWrite(wrapped_get2, 5),
[email protected]f6c63db52013-02-02 00:35:225349 };
5350
5351 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:415352 CreateMockRead(conn_resp1, 1, ASYNC),
5353 CreateMockRead(wrapped_get_resp1, 3, ASYNC),
bnceb9aa7112017-01-05 01:03:465354 CreateMockRead(wrapped_body1, 4, SYNCHRONOUS),
bncdf80d44fd2016-07-15 20:27:415355 CreateMockRead(wrapped_get_resp2, 6, ASYNC),
bnceb9aa7112017-01-05 01:03:465356 CreateMockRead(wrapped_body2, 7, SYNCHRONOUS),
bncdf80d44fd2016-07-15 20:27:415357 MockRead(ASYNC, 0, 8),
[email protected]f6c63db52013-02-02 00:35:225358 };
5359
mmenke11eb5152015-06-09 14:50:505360 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
5361 arraysize(spdy_writes));
5362 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]f6c63db52013-02-02 00:35:225363
5364 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:365365 ssl.next_proto = kProtoHTTP2;
mmenke11eb5152015-06-09 14:50:505366 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]f6c63db52013-02-02 00:35:225367 SSLSocketDataProvider ssl2(ASYNC, OK);
mmenke11eb5152015-06-09 14:50:505368 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
[email protected]f6c63db52013-02-02 00:35:225369
5370 TestCompletionCallback callback;
5371
bnc87dcefc2017-05-25 12:47:585372 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:195373 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:205374 int rv = trans->Start(&request1, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:015375 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]f6c63db52013-02-02 00:35:225376
5377 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:015378 EXPECT_THAT(rv, IsOk());
[email protected]f6c63db52013-02-02 00:35:225379
5380 LoadTimingInfo load_timing_info;
5381 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
5382 TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_SSL_TIMES);
5383
5384 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:525385 ASSERT_TRUE(response);
5386 ASSERT_TRUE(response->headers);
[email protected]f6c63db52013-02-02 00:35:225387 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
5388
5389 std::string response_data;
ttuttle859dc7a2015-04-23 19:42:295390 scoped_refptr<IOBuffer> buf(new IOBuffer(256));
[email protected]90499482013-06-01 00:39:505391 EXPECT_EQ(1, trans->Read(buf.get(), 256, callback.callback()));
[email protected]f6c63db52013-02-02 00:35:225392 trans.reset();
5393
bnc87dcefc2017-05-25 12:47:585394 auto trans2 =
Jeremy Roman0579ed62017-08-29 15:56:195395 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:205396 rv = trans2->Start(&request2, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:015397 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]f6c63db52013-02-02 00:35:225398
[email protected]f6c63db52013-02-02 00:35:225399 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:015400 EXPECT_THAT(rv, IsOk());
[email protected]f6c63db52013-02-02 00:35:225401
5402 LoadTimingInfo load_timing_info2;
5403 EXPECT_TRUE(trans2->GetLoadTimingInfo(&load_timing_info2));
5404 TestLoadTimingReused(load_timing_info2);
5405
5406 // The requests should have the same ID.
5407 EXPECT_EQ(load_timing_info.socket_log_id, load_timing_info2.socket_log_id);
5408
[email protected]90499482013-06-01 00:39:505409 EXPECT_EQ(2, trans2->Read(buf.get(), 256, callback.callback()));
[email protected]f6c63db52013-02-02 00:35:225410}
5411
5412// Test load timing in the case of of two HTTP requests through a SPDY HTTPS
5413// Proxy to different servers.
bncd16676a2016-07-20 16:23:015414TEST_F(HttpNetworkTransactionTest, HttpsProxySpdyLoadTimingTwoHttpRequests) {
[email protected]f6c63db52013-02-02 00:35:225415 // Configure against https proxy server "proxy:70".
rdsmith82957ad2015-09-16 19:42:035416 session_deps_.proxy_service = ProxyService::CreateFixed("https://proxy:70");
vishal.b62985ca92015-04-17 08:45:515417 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:075418 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:095419 std::unique_ptr<HttpNetworkSession> session(
mmenke11eb5152015-06-09 14:50:505420 SpdySessionDependencies::SpdyCreateSession(&session_deps_));
[email protected]f6c63db52013-02-02 00:35:225421
5422 HttpRequestInfo request1;
5423 request1.method = "GET";
bncce36dca22015-04-21 22:11:235424 request1.url = GURL("http://www.example.org/");
[email protected]f6c63db52013-02-02 00:35:225425 request1.load_flags = 0;
5426
5427 HttpRequestInfo request2;
5428 request2.method = "GET";
bncce36dca22015-04-21 22:11:235429 request2.url = GURL("http://mail.example.org/");
[email protected]f6c63db52013-02-02 00:35:225430 request2.load_flags = 0;
5431
bncce36dca22015-04-21 22:11:235432 // http://www.example.org/
bnc086b39e12016-06-24 13:05:265433 SpdyHeaderBlock headers(
bncce36dca22015-04-21 22:11:235434 spdy_util_.ConstructGetHeaderBlockForProxy("http://www.example.org/"));
bncdf80d44fd2016-07-15 20:27:415435 SpdySerializedFrame get1(
bnc42331402016-07-25 13:36:155436 spdy_util_.ConstructSpdyHeaders(1, std::move(headers), LOWEST, true));
5437 SpdySerializedFrame get_resp1(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
bncdf80d44fd2016-07-15 20:27:415438 SpdySerializedFrame body1(spdy_util_.ConstructSpdyDataFrame(1, "1", 1, true));
rdsmithebb50aa2015-11-12 03:44:385439 spdy_util_.UpdateWithStreamDestruction(1);
[email protected]f6c63db52013-02-02 00:35:225440
bncce36dca22015-04-21 22:11:235441 // http://mail.example.org/
bnc086b39e12016-06-24 13:05:265442 SpdyHeaderBlock headers2(
bncce36dca22015-04-21 22:11:235443 spdy_util_.ConstructGetHeaderBlockForProxy("http://mail.example.org/"));
bncdf80d44fd2016-07-15 20:27:415444 SpdySerializedFrame get2(
bnc42331402016-07-25 13:36:155445 spdy_util_.ConstructSpdyHeaders(3, std::move(headers2), LOWEST, true));
5446 SpdySerializedFrame get_resp2(spdy_util_.ConstructSpdyGetReply(NULL, 0, 3));
bncdf80d44fd2016-07-15 20:27:415447 SpdySerializedFrame body2(
5448 spdy_util_.ConstructSpdyDataFrame(3, "22", 2, true));
[email protected]f6c63db52013-02-02 00:35:225449
5450 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:415451 CreateMockWrite(get1, 0), CreateMockWrite(get2, 3),
[email protected]f6c63db52013-02-02 00:35:225452 };
5453
5454 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:415455 CreateMockRead(get_resp1, 1, ASYNC),
5456 CreateMockRead(body1, 2, ASYNC),
5457 CreateMockRead(get_resp2, 4, ASYNC),
5458 CreateMockRead(body2, 5, ASYNC),
5459 MockRead(ASYNC, 0, 6),
[email protected]f6c63db52013-02-02 00:35:225460 };
5461
mmenke11eb5152015-06-09 14:50:505462 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
5463 arraysize(spdy_writes));
5464 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]f6c63db52013-02-02 00:35:225465
5466 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:365467 ssl.next_proto = kProtoHTTP2;
mmenke11eb5152015-06-09 14:50:505468 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]f6c63db52013-02-02 00:35:225469
5470 TestCompletionCallback callback;
5471
bnc87dcefc2017-05-25 12:47:585472 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:195473 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:205474 int rv = trans->Start(&request1, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:015475 EXPECT_THAT(callback.GetResult(rv), IsOk());
[email protected]f6c63db52013-02-02 00:35:225476
5477 LoadTimingInfo load_timing_info;
5478 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
5479 TestLoadTimingNotReused(load_timing_info,
5480 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
5481
5482 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:525483 ASSERT_TRUE(response);
5484 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:025485 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]f6c63db52013-02-02 00:35:225486
5487 std::string response_data;
ttuttle859dc7a2015-04-23 19:42:295488 scoped_refptr<IOBuffer> buf(new IOBuffer(256));
mmenke11eb5152015-06-09 14:50:505489 rv = trans->Read(buf.get(), 256, callback.callback());
5490 EXPECT_EQ(1, callback.GetResult(rv));
[email protected]f6c63db52013-02-02 00:35:225491 // Delete the first request, so the second one can reuse the socket.
5492 trans.reset();
5493
bnc691fda62016-08-12 00:43:165494 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:205495 rv = trans2.Start(&request2, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:015496 EXPECT_THAT(callback.GetResult(rv), IsOk());
[email protected]f6c63db52013-02-02 00:35:225497
5498 LoadTimingInfo load_timing_info2;
bnc691fda62016-08-12 00:43:165499 EXPECT_TRUE(trans2.GetLoadTimingInfo(&load_timing_info2));
[email protected]f6c63db52013-02-02 00:35:225500 TestLoadTimingReused(load_timing_info2);
5501
5502 // The requests should have the same ID.
5503 EXPECT_EQ(load_timing_info.socket_log_id, load_timing_info2.socket_log_id);
5504
bnc691fda62016-08-12 00:43:165505 rv = trans2.Read(buf.get(), 256, callback.callback());
mmenke11eb5152015-06-09 14:50:505506 EXPECT_EQ(2, callback.GetResult(rv));
[email protected]f6c63db52013-02-02 00:35:225507}
5508
[email protected]2df19bb2010-08-25 20:13:465509// Test the challenge-response-retry sequence through an HTTPS Proxy
bncd16676a2016-07-20 16:23:015510TEST_F(HttpNetworkTransactionTest, HttpsProxyAuthRetry) {
[email protected]2df19bb2010-08-25 20:13:465511 HttpRequestInfo request;
5512 request.method = "GET";
bncce36dca22015-04-21 22:11:235513 request.url = GURL("http://www.example.org/");
[email protected]2df19bb2010-08-25 20:13:465514 // when the no authentication data flag is set.
ttuttle859dc7a2015-04-23 19:42:295515 request.load_flags = LOAD_DO_NOT_SEND_AUTH_DATA;
[email protected]2df19bb2010-08-25 20:13:465516
[email protected]79cb5c12011-09-12 13:12:045517 // Configure against https proxy server "myproxy:70".
rdsmith82957ad2015-09-16 19:42:035518 session_deps_.proxy_service = ProxyService::CreateFixed("https://myproxy:70");
vishal.b62985ca92015-04-17 08:45:515519 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:075520 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:095521 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:275522
[email protected]2df19bb2010-08-25 20:13:465523 // Since we have proxy, should use full url
5524 MockWrite data_writes1[] = {
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\r\n"),
[email protected]2df19bb2010-08-25 20:13:465528
bnc691fda62016-08-12 00:43:165529 // After calling trans.RestartWithAuth(), this is the request we should
bncce36dca22015-04-21 22:11:235530 // be issuing -- the final header line contains the credentials.
bnc691fda62016-08-12 00:43:165531 MockWrite("GET http://www.example.org/ HTTP/1.1\r\n"
5532 "Host: www.example.org\r\n"
5533 "Proxy-Connection: keep-alive\r\n"
5534 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]2df19bb2010-08-25 20:13:465535 };
5536
5537 // The proxy responds to the GET with a 407, using a persistent
5538 // connection.
5539 MockRead data_reads1[] = {
5540 // No credentials.
5541 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
5542 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
5543 MockRead("Proxy-Connection: keep-alive\r\n"),
5544 MockRead("Content-Length: 0\r\n\r\n"),
5545
5546 MockRead("HTTP/1.1 200 OK\r\n"),
5547 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
5548 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:065549 MockRead(SYNCHRONOUS, OK),
[email protected]2df19bb2010-08-25 20:13:465550 };
5551
5552 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
5553 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:075554 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8ddf8322012-02-23 18:08:065555 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:075556 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]2df19bb2010-08-25 20:13:465557
[email protected]49639fa2011-12-20 23:22:415558 TestCompletionCallback callback1;
[email protected]2df19bb2010-08-25 20:13:465559
bnc691fda62016-08-12 00:43:165560 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]0b0bf032010-09-21 18:08:505561
bnc691fda62016-08-12 00:43:165562 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:015563 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2df19bb2010-08-25 20:13:465564
5565 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:015566 EXPECT_THAT(rv, IsOk());
[email protected]2df19bb2010-08-25 20:13:465567
[email protected]58e32bb2013-01-21 18:23:255568 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:165569 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]58e32bb2013-01-21 18:23:255570 TestLoadTimingNotReused(load_timing_info,
5571 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
5572
bnc691fda62016-08-12 00:43:165573 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:525574 ASSERT_TRUE(response);
5575 ASSERT_TRUE(response->headers);
[email protected]2df19bb2010-08-25 20:13:465576 EXPECT_EQ(407, response->headers->response_code());
5577 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
asanka098c0092016-06-16 20:18:435578 EXPECT_TRUE(CheckBasicSecureProxyAuth(response->auth_challenge.get()));
[email protected]2df19bb2010-08-25 20:13:465579
[email protected]49639fa2011-12-20 23:22:415580 TestCompletionCallback callback2;
[email protected]2df19bb2010-08-25 20:13:465581
bnc691fda62016-08-12 00:43:165582 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar), callback2.callback());
robpercival214763f2016-07-01 23:27:015583 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2df19bb2010-08-25 20:13:465584
5585 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:015586 EXPECT_THAT(rv, IsOk());
[email protected]2df19bb2010-08-25 20:13:465587
[email protected]58e32bb2013-01-21 18:23:255588 load_timing_info = LoadTimingInfo();
bnc691fda62016-08-12 00:43:165589 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]58e32bb2013-01-21 18:23:255590 // Retrying with HTTP AUTH is considered to be reusing a socket.
5591 TestLoadTimingReused(load_timing_info);
5592
bnc691fda62016-08-12 00:43:165593 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:525594 ASSERT_TRUE(response);
[email protected]2df19bb2010-08-25 20:13:465595
5596 EXPECT_TRUE(response->headers->IsKeepAlive());
5597 EXPECT_EQ(200, response->headers->response_code());
5598 EXPECT_EQ(100, response->headers->GetContentLength());
5599 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
5600
5601 // The password prompt info should not be set.
wezca1070932016-05-26 20:30:525602 EXPECT_FALSE(response->auth_challenge);
[email protected]2df19bb2010-08-25 20:13:465603}
5604
[email protected]23e482282013-06-14 16:08:025605void HttpNetworkTransactionTest::ConnectStatusHelperWithExpectedStatus(
[email protected]c744cf22009-02-27 07:28:085606 const MockRead& status, int expected_status) {
[email protected]1c773ea12009-04-28 19:58:425607 HttpRequestInfo request;
[email protected]c744cf22009-02-27 07:28:085608 request.method = "GET";
bncce36dca22015-04-21 22:11:235609 request.url = GURL("https://www.example.org/");
[email protected]c744cf22009-02-27 07:28:085610
[email protected]cb9bf6ca2011-01-28 13:15:275611 // Configure against proxy server "myproxy:70".
rdsmith82957ad2015-09-16 19:42:035612 session_deps_.proxy_service = ProxyService::CreateFixed("myproxy:70");
danakj1fd259a02016-04-16 03:17:095613 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:275614
[email protected]c744cf22009-02-27 07:28:085615 // Since we have proxy, should try to establish tunnel.
5616 MockWrite data_writes[] = {
rsleevidb16bb02015-11-12 23:47:175617 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
5618 "Host: www.example.org:443\r\n"
5619 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]c744cf22009-02-27 07:28:085620 };
5621
5622 MockRead data_reads[] = {
mmenked39192ee2015-12-09 00:57:235623 status, MockRead("Content-Length: 10\r\n\r\n"),
5624 // No response body because the test stops reading here.
5625 MockRead(SYNCHRONOUS, ERR_UNEXPECTED),
[email protected]c744cf22009-02-27 07:28:085626 };
5627
[email protected]31a2bfe2010-02-09 08:03:395628 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
5629 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:075630 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]c744cf22009-02-27 07:28:085631
[email protected]49639fa2011-12-20 23:22:415632 TestCompletionCallback callback;
[email protected]c744cf22009-02-27 07:28:085633
bnc691fda62016-08-12 00:43:165634 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]0b0bf032010-09-21 18:08:505635
tfarina42834112016-09-22 13:38:205636 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:015637 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]c744cf22009-02-27 07:28:085638
5639 rv = callback.WaitForResult();
5640 EXPECT_EQ(expected_status, rv);
5641}
5642
[email protected]23e482282013-06-14 16:08:025643void HttpNetworkTransactionTest::ConnectStatusHelper(
[email protected]448d4ca52012-03-04 04:12:235644 const MockRead& status) {
[email protected]c744cf22009-02-27 07:28:085645 ConnectStatusHelperWithExpectedStatus(
[email protected]1c773ea12009-04-28 19:58:425646 status, ERR_TUNNEL_CONNECTION_FAILED);
[email protected]c744cf22009-02-27 07:28:085647}
5648
bncd16676a2016-07-20 16:23:015649TEST_F(HttpNetworkTransactionTest, ConnectStatus100) {
[email protected]c744cf22009-02-27 07:28:085650 ConnectStatusHelper(MockRead("HTTP/1.1 100 Continue\r\n"));
5651}
5652
bncd16676a2016-07-20 16:23:015653TEST_F(HttpNetworkTransactionTest, ConnectStatus101) {
[email protected]c744cf22009-02-27 07:28:085654 ConnectStatusHelper(MockRead("HTTP/1.1 101 Switching Protocols\r\n"));
5655}
5656
bncd16676a2016-07-20 16:23:015657TEST_F(HttpNetworkTransactionTest, ConnectStatus201) {
[email protected]c744cf22009-02-27 07:28:085658 ConnectStatusHelper(MockRead("HTTP/1.1 201 Created\r\n"));
5659}
5660
bncd16676a2016-07-20 16:23:015661TEST_F(HttpNetworkTransactionTest, ConnectStatus202) {
[email protected]c744cf22009-02-27 07:28:085662 ConnectStatusHelper(MockRead("HTTP/1.1 202 Accepted\r\n"));
5663}
5664
bncd16676a2016-07-20 16:23:015665TEST_F(HttpNetworkTransactionTest, ConnectStatus203) {
[email protected]c744cf22009-02-27 07:28:085666 ConnectStatusHelper(
5667 MockRead("HTTP/1.1 203 Non-Authoritative Information\r\n"));
5668}
5669
bncd16676a2016-07-20 16:23:015670TEST_F(HttpNetworkTransactionTest, ConnectStatus204) {
[email protected]c744cf22009-02-27 07:28:085671 ConnectStatusHelper(MockRead("HTTP/1.1 204 No Content\r\n"));
5672}
5673
bncd16676a2016-07-20 16:23:015674TEST_F(HttpNetworkTransactionTest, ConnectStatus205) {
[email protected]c744cf22009-02-27 07:28:085675 ConnectStatusHelper(MockRead("HTTP/1.1 205 Reset Content\r\n"));
5676}
5677
bncd16676a2016-07-20 16:23:015678TEST_F(HttpNetworkTransactionTest, ConnectStatus206) {
[email protected]c744cf22009-02-27 07:28:085679 ConnectStatusHelper(MockRead("HTTP/1.1 206 Partial Content\r\n"));
5680}
5681
bncd16676a2016-07-20 16:23:015682TEST_F(HttpNetworkTransactionTest, ConnectStatus300) {
[email protected]c744cf22009-02-27 07:28:085683 ConnectStatusHelper(MockRead("HTTP/1.1 300 Multiple Choices\r\n"));
5684}
5685
bncd16676a2016-07-20 16:23:015686TEST_F(HttpNetworkTransactionTest, ConnectStatus301) {
[email protected]c744cf22009-02-27 07:28:085687 ConnectStatusHelper(MockRead("HTTP/1.1 301 Moved Permanently\r\n"));
5688}
5689
bncd16676a2016-07-20 16:23:015690TEST_F(HttpNetworkTransactionTest, ConnectStatus302) {
[email protected]c744cf22009-02-27 07:28:085691 ConnectStatusHelper(MockRead("HTTP/1.1 302 Found\r\n"));
5692}
5693
bncd16676a2016-07-20 16:23:015694TEST_F(HttpNetworkTransactionTest, ConnectStatus303) {
[email protected]c744cf22009-02-27 07:28:085695 ConnectStatusHelper(MockRead("HTTP/1.1 303 See Other\r\n"));
5696}
5697
bncd16676a2016-07-20 16:23:015698TEST_F(HttpNetworkTransactionTest, ConnectStatus304) {
[email protected]c744cf22009-02-27 07:28:085699 ConnectStatusHelper(MockRead("HTTP/1.1 304 Not Modified\r\n"));
5700}
5701
bncd16676a2016-07-20 16:23:015702TEST_F(HttpNetworkTransactionTest, ConnectStatus305) {
[email protected]c744cf22009-02-27 07:28:085703 ConnectStatusHelper(MockRead("HTTP/1.1 305 Use Proxy\r\n"));
5704}
5705
bncd16676a2016-07-20 16:23:015706TEST_F(HttpNetworkTransactionTest, ConnectStatus306) {
[email protected]c744cf22009-02-27 07:28:085707 ConnectStatusHelper(MockRead("HTTP/1.1 306\r\n"));
5708}
5709
bncd16676a2016-07-20 16:23:015710TEST_F(HttpNetworkTransactionTest, ConnectStatus307) {
[email protected]c744cf22009-02-27 07:28:085711 ConnectStatusHelper(MockRead("HTTP/1.1 307 Temporary Redirect\r\n"));
5712}
5713
bncd16676a2016-07-20 16:23:015714TEST_F(HttpNetworkTransactionTest, ConnectStatus308) {
[email protected]0a17aab32014-04-24 03:32:375715 ConnectStatusHelper(MockRead("HTTP/1.1 308 Permanent Redirect\r\n"));
5716}
5717
bncd16676a2016-07-20 16:23:015718TEST_F(HttpNetworkTransactionTest, ConnectStatus400) {
[email protected]c744cf22009-02-27 07:28:085719 ConnectStatusHelper(MockRead("HTTP/1.1 400 Bad Request\r\n"));
5720}
5721
bncd16676a2016-07-20 16:23:015722TEST_F(HttpNetworkTransactionTest, ConnectStatus401) {
[email protected]c744cf22009-02-27 07:28:085723 ConnectStatusHelper(MockRead("HTTP/1.1 401 Unauthorized\r\n"));
5724}
5725
bncd16676a2016-07-20 16:23:015726TEST_F(HttpNetworkTransactionTest, ConnectStatus402) {
[email protected]c744cf22009-02-27 07:28:085727 ConnectStatusHelper(MockRead("HTTP/1.1 402 Payment Required\r\n"));
5728}
5729
bncd16676a2016-07-20 16:23:015730TEST_F(HttpNetworkTransactionTest, ConnectStatus403) {
[email protected]c744cf22009-02-27 07:28:085731 ConnectStatusHelper(MockRead("HTTP/1.1 403 Forbidden\r\n"));
5732}
5733
bncd16676a2016-07-20 16:23:015734TEST_F(HttpNetworkTransactionTest, ConnectStatus404) {
[email protected]c744cf22009-02-27 07:28:085735 ConnectStatusHelper(MockRead("HTTP/1.1 404 Not Found\r\n"));
5736}
5737
bncd16676a2016-07-20 16:23:015738TEST_F(HttpNetworkTransactionTest, ConnectStatus405) {
[email protected]c744cf22009-02-27 07:28:085739 ConnectStatusHelper(MockRead("HTTP/1.1 405 Method Not Allowed\r\n"));
5740}
5741
bncd16676a2016-07-20 16:23:015742TEST_F(HttpNetworkTransactionTest, ConnectStatus406) {
[email protected]c744cf22009-02-27 07:28:085743 ConnectStatusHelper(MockRead("HTTP/1.1 406 Not Acceptable\r\n"));
5744}
5745
bncd16676a2016-07-20 16:23:015746TEST_F(HttpNetworkTransactionTest, ConnectStatus407) {
[email protected]c744cf22009-02-27 07:28:085747 ConnectStatusHelperWithExpectedStatus(
5748 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
[email protected]a7ea8832010-07-12 17:54:545749 ERR_PROXY_AUTH_UNSUPPORTED);
[email protected]c744cf22009-02-27 07:28:085750}
5751
bncd16676a2016-07-20 16:23:015752TEST_F(HttpNetworkTransactionTest, ConnectStatus408) {
[email protected]c744cf22009-02-27 07:28:085753 ConnectStatusHelper(MockRead("HTTP/1.1 408 Request Timeout\r\n"));
5754}
5755
bncd16676a2016-07-20 16:23:015756TEST_F(HttpNetworkTransactionTest, ConnectStatus409) {
[email protected]c744cf22009-02-27 07:28:085757 ConnectStatusHelper(MockRead("HTTP/1.1 409 Conflict\r\n"));
5758}
5759
bncd16676a2016-07-20 16:23:015760TEST_F(HttpNetworkTransactionTest, ConnectStatus410) {
[email protected]c744cf22009-02-27 07:28:085761 ConnectStatusHelper(MockRead("HTTP/1.1 410 Gone\r\n"));
5762}
5763
bncd16676a2016-07-20 16:23:015764TEST_F(HttpNetworkTransactionTest, ConnectStatus411) {
[email protected]c744cf22009-02-27 07:28:085765 ConnectStatusHelper(MockRead("HTTP/1.1 411 Length Required\r\n"));
5766}
5767
bncd16676a2016-07-20 16:23:015768TEST_F(HttpNetworkTransactionTest, ConnectStatus412) {
[email protected]c744cf22009-02-27 07:28:085769 ConnectStatusHelper(MockRead("HTTP/1.1 412 Precondition Failed\r\n"));
5770}
5771
bncd16676a2016-07-20 16:23:015772TEST_F(HttpNetworkTransactionTest, ConnectStatus413) {
[email protected]c744cf22009-02-27 07:28:085773 ConnectStatusHelper(MockRead("HTTP/1.1 413 Request Entity Too Large\r\n"));
5774}
5775
bncd16676a2016-07-20 16:23:015776TEST_F(HttpNetworkTransactionTest, ConnectStatus414) {
[email protected]c744cf22009-02-27 07:28:085777 ConnectStatusHelper(MockRead("HTTP/1.1 414 Request-URI Too Long\r\n"));
5778}
5779
bncd16676a2016-07-20 16:23:015780TEST_F(HttpNetworkTransactionTest, ConnectStatus415) {
[email protected]c744cf22009-02-27 07:28:085781 ConnectStatusHelper(MockRead("HTTP/1.1 415 Unsupported Media Type\r\n"));
5782}
5783
bncd16676a2016-07-20 16:23:015784TEST_F(HttpNetworkTransactionTest, ConnectStatus416) {
[email protected]c744cf22009-02-27 07:28:085785 ConnectStatusHelper(
5786 MockRead("HTTP/1.1 416 Requested Range Not Satisfiable\r\n"));
5787}
5788
bncd16676a2016-07-20 16:23:015789TEST_F(HttpNetworkTransactionTest, ConnectStatus417) {
[email protected]c744cf22009-02-27 07:28:085790 ConnectStatusHelper(MockRead("HTTP/1.1 417 Expectation Failed\r\n"));
5791}
5792
bncd16676a2016-07-20 16:23:015793TEST_F(HttpNetworkTransactionTest, ConnectStatus500) {
[email protected]c744cf22009-02-27 07:28:085794 ConnectStatusHelper(MockRead("HTTP/1.1 500 Internal Server Error\r\n"));
5795}
5796
bncd16676a2016-07-20 16:23:015797TEST_F(HttpNetworkTransactionTest, ConnectStatus501) {
[email protected]c744cf22009-02-27 07:28:085798 ConnectStatusHelper(MockRead("HTTP/1.1 501 Not Implemented\r\n"));
5799}
5800
bncd16676a2016-07-20 16:23:015801TEST_F(HttpNetworkTransactionTest, ConnectStatus502) {
[email protected]c744cf22009-02-27 07:28:085802 ConnectStatusHelper(MockRead("HTTP/1.1 502 Bad Gateway\r\n"));
5803}
5804
bncd16676a2016-07-20 16:23:015805TEST_F(HttpNetworkTransactionTest, ConnectStatus503) {
[email protected]c744cf22009-02-27 07:28:085806 ConnectStatusHelper(MockRead("HTTP/1.1 503 Service Unavailable\r\n"));
5807}
5808
bncd16676a2016-07-20 16:23:015809TEST_F(HttpNetworkTransactionTest, ConnectStatus504) {
[email protected]c744cf22009-02-27 07:28:085810 ConnectStatusHelper(MockRead("HTTP/1.1 504 Gateway Timeout\r\n"));
5811}
5812
bncd16676a2016-07-20 16:23:015813TEST_F(HttpNetworkTransactionTest, ConnectStatus505) {
[email protected]c744cf22009-02-27 07:28:085814 ConnectStatusHelper(MockRead("HTTP/1.1 505 HTTP Version Not Supported\r\n"));
5815}
5816
[email protected]038e9a32008-10-08 22:40:165817// Test the flow when both the proxy server AND origin server require
5818// authentication. Again, this uses basic auth for both since that is
5819// the simplest to mock.
bncd16676a2016-07-20 16:23:015820TEST_F(HttpNetworkTransactionTest, BasicAuthProxyThenServer) {
[email protected]cb9bf6ca2011-01-28 13:15:275821 HttpRequestInfo request;
5822 request.method = "GET";
bncce36dca22015-04-21 22:11:235823 request.url = GURL("http://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:275824
[email protected]038e9a32008-10-08 22:40:165825 // Configure against proxy server "myproxy:70".
rdsmith82957ad2015-09-16 19:42:035826 session_deps_.proxy_service = ProxyService::CreateFixed("myproxy:70");
danakj1fd259a02016-04-16 03:17:095827 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]3fe8d2f82013-10-17 08:56:075828
bnc691fda62016-08-12 00:43:165829 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]038e9a32008-10-08 22:40:165830
[email protected]f9ee6b52008-11-08 06:46:235831 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:235832 MockWrite(
5833 "GET http://www.example.org/ HTTP/1.1\r\n"
5834 "Host: www.example.org\r\n"
5835 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:235836 };
5837
[email protected]038e9a32008-10-08 22:40:165838 MockRead data_reads1[] = {
5839 MockRead("HTTP/1.0 407 Unauthorized\r\n"),
5840 // Give a couple authenticate options (only the middle one is actually
5841 // supported).
[email protected]22927ad2009-09-21 19:56:195842 MockRead("Proxy-Authenticate: Basic invalid\r\n"), // Malformed.
[email protected]038e9a32008-10-08 22:40:165843 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
5844 MockRead("Proxy-Authenticate: UNSUPPORTED realm=\"FOO\"\r\n"),
5845 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
5846 // Large content-length -- won't matter, as connection will be reset.
5847 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:065848 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]038e9a32008-10-08 22:40:165849 };
5850
bnc691fda62016-08-12 00:43:165851 // After calling trans.RestartWithAuth() the first time, this is the
[email protected]038e9a32008-10-08 22:40:165852 // request we should be issuing -- the final header line contains the
5853 // proxy's credentials.
5854 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:235855 MockWrite(
5856 "GET http://www.example.org/ HTTP/1.1\r\n"
5857 "Host: www.example.org\r\n"
5858 "Proxy-Connection: keep-alive\r\n"
5859 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]038e9a32008-10-08 22:40:165860 };
5861
5862 // Now the proxy server lets the request pass through to origin server.
5863 // The origin server responds with a 401.
5864 MockRead data_reads2[] = {
5865 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
5866 // Note: We are using the same realm-name as the proxy server. This is
5867 // completely valid, as realms are unique across hosts.
5868 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
5869 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
5870 MockRead("Content-Length: 2000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:065871 MockRead(SYNCHRONOUS, ERR_FAILED), // Won't be reached.
[email protected]038e9a32008-10-08 22:40:165872 };
5873
bnc691fda62016-08-12 00:43:165874 // After calling trans.RestartWithAuth() the second time, we should send
[email protected]038e9a32008-10-08 22:40:165875 // the credentials for both the proxy and origin server.
5876 MockWrite data_writes3[] = {
bncce36dca22015-04-21 22:11:235877 MockWrite(
5878 "GET http://www.example.org/ HTTP/1.1\r\n"
5879 "Host: www.example.org\r\n"
5880 "Proxy-Connection: keep-alive\r\n"
5881 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n"
5882 "Authorization: Basic Zm9vMjpiYXIy\r\n\r\n"),
[email protected]038e9a32008-10-08 22:40:165883 };
5884
5885 // Lastly we get the desired content.
5886 MockRead data_reads3[] = {
5887 MockRead("HTTP/1.0 200 OK\r\n"),
5888 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
5889 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:065890 MockRead(SYNCHRONOUS, OK),
[email protected]038e9a32008-10-08 22:40:165891 };
5892
[email protected]31a2bfe2010-02-09 08:03:395893 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
5894 data_writes1, arraysize(data_writes1));
5895 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
5896 data_writes2, arraysize(data_writes2));
5897 StaticSocketDataProvider data3(data_reads3, arraysize(data_reads3),
5898 data_writes3, arraysize(data_writes3));
[email protected]bb88e1d32013-05-03 23:11:075899 session_deps_.socket_factory->AddSocketDataProvider(&data1);
5900 session_deps_.socket_factory->AddSocketDataProvider(&data2);
5901 session_deps_.socket_factory->AddSocketDataProvider(&data3);
[email protected]038e9a32008-10-08 22:40:165902
[email protected]49639fa2011-12-20 23:22:415903 TestCompletionCallback callback1;
[email protected]038e9a32008-10-08 22:40:165904
tfarina42834112016-09-22 13:38:205905 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:015906 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]038e9a32008-10-08 22:40:165907
5908 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:015909 EXPECT_THAT(rv, IsOk());
[email protected]038e9a32008-10-08 22:40:165910
bnc691fda62016-08-12 00:43:165911 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:525912 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:045913 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
[email protected]038e9a32008-10-08 22:40:165914
[email protected]49639fa2011-12-20 23:22:415915 TestCompletionCallback callback2;
[email protected]038e9a32008-10-08 22:40:165916
bnc691fda62016-08-12 00:43:165917 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar), callback2.callback());
robpercival214763f2016-07-01 23:27:015918 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]038e9a32008-10-08 22:40:165919
5920 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:015921 EXPECT_THAT(rv, IsOk());
[email protected]038e9a32008-10-08 22:40:165922
bnc691fda62016-08-12 00:43:165923 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:525924 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:045925 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]038e9a32008-10-08 22:40:165926
[email protected]49639fa2011-12-20 23:22:415927 TestCompletionCallback callback3;
[email protected]038e9a32008-10-08 22:40:165928
bnc691fda62016-08-12 00:43:165929 rv = trans.RestartWithAuth(AuthCredentials(kFoo2, kBar2),
5930 callback3.callback());
robpercival214763f2016-07-01 23:27:015931 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]038e9a32008-10-08 22:40:165932
5933 rv = callback3.WaitForResult();
robpercival214763f2016-07-01 23:27:015934 EXPECT_THAT(rv, IsOk());
[email protected]038e9a32008-10-08 22:40:165935
bnc691fda62016-08-12 00:43:165936 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:525937 EXPECT_FALSE(response->auth_challenge);
[email protected]038e9a32008-10-08 22:40:165938 EXPECT_EQ(100, response->headers->GetContentLength());
[email protected]038e9a32008-10-08 22:40:165939}
[email protected]4ddaf2502008-10-23 18:26:195940
[email protected]ea9dc9a2009-09-05 00:43:325941// For the NTLM implementation using SSPI, we skip the NTLM tests since we
5942// can't hook into its internals to cause it to generate predictable NTLM
5943// authorization headers.
5944#if defined(NTLM_PORTABLE)
[email protected]385a4672009-03-11 22:21:295945// The NTLM authentication unit tests were generated by capturing the HTTP
5946// requests and responses using Fiddler 2 and inspecting the generated random
5947// bytes in the debugger.
5948
5949// Enter the correct password and authenticate successfully.
bncd16676a2016-07-20 16:23:015950TEST_F(HttpNetworkTransactionTest, NTLMAuth1) {
[email protected]1c773ea12009-04-28 19:58:425951 HttpRequestInfo request;
[email protected]3f918782009-02-28 01:29:245952 request.method = "GET";
Bence Béky83eb3512017-09-05 12:56:095953 request.url = GURL("https://172.22.68.17/kids/login.aspx");
[email protected]2217aa22013-10-11 03:03:545954
5955 // Ensure load is not disrupted by flags which suppress behaviour specific
5956 // to other auth schemes.
5957 request.load_flags = LOAD_DO_NOT_USE_EMBEDDED_IDENTITY;
[email protected]3f918782009-02-28 01:29:245958
[email protected]cb9bf6ca2011-01-28 13:15:275959 HttpAuthHandlerNTLM::ScopedProcSetter proc_setter(MockGenerateRandom1,
5960 MockGetHostName);
danakj1fd259a02016-04-16 03:17:095961 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:275962
[email protected]3f918782009-02-28 01:29:245963 MockWrite data_writes1[] = {
5964 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
5965 "Host: 172.22.68.17\r\n"
5966 "Connection: keep-alive\r\n\r\n"),
5967 };
5968
5969 MockRead data_reads1[] = {
5970 MockRead("HTTP/1.1 401 Access Denied\r\n"),
[email protected]aef04272010-06-28 18:03:045971 // Negotiate and NTLM are often requested together. However, we only want
5972 // to test NTLM. Since Negotiate is preferred over NTLM, we have to skip
5973 // the header that requests Negotiate for this test.
[email protected]3f918782009-02-28 01:29:245974 MockRead("WWW-Authenticate: NTLM\r\n"),
5975 MockRead("Connection: close\r\n"),
5976 MockRead("Content-Length: 42\r\n"),
[email protected]076c85082009-04-10 23:21:365977 MockRead("Content-Type: text/html\r\n\r\n"),
[email protected]3f918782009-02-28 01:29:245978 // Missing content -- won't matter, as connection will be reset.
[email protected]8ddf8322012-02-23 18:08:065979 MockRead(SYNCHRONOUS, ERR_UNEXPECTED),
[email protected]3f918782009-02-28 01:29:245980 };
5981
5982 MockWrite data_writes2[] = {
bnc691fda62016-08-12 00:43:165983 // After restarting with a null identity, this is the
5984 // request we should be issuing -- the final header line contains a Type
5985 // 1 message.
5986 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
5987 "Host: 172.22.68.17\r\n"
5988 "Connection: keep-alive\r\n"
5989 "Authorization: NTLM "
5990 "TlRMTVNTUAABAAAAB4IIAAAAAAAAAAAAAAAAAAAAAAA=\r\n\r\n"),
[email protected]3f918782009-02-28 01:29:245991
bnc691fda62016-08-12 00:43:165992 // After calling trans.RestartWithAuth(), we should send a Type 3 message
5993 // (the credentials for the origin server). The second request continues
5994 // on the same connection.
5995 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
5996 "Host: 172.22.68.17\r\n"
5997 "Connection: keep-alive\r\n"
5998 "Authorization: NTLM TlRMTVNTUAADAAAAGAAYAGgAAAAYABgAgA"
5999 "AAAAAAAABAAAAAGAAYAEAAAAAQABAAWAAAAAAAAAAAAAAABYIIAHQA"
6000 "ZQBzAHQAaQBuAGcALQBuAHQAbABtAFcAVABDAC0AVwBJAE4ANwBVKW"
6001 "Yma5xzVAAAAAAAAAAAAAAAAAAAAACH+gWcm+YsP9Tqb9zCR3WAeZZX"
6002 "ahlhx5I=\r\n\r\n"),
[email protected]3f918782009-02-28 01:29:246003 };
6004
6005 MockRead data_reads2[] = {
6006 // The origin server responds with a Type 2 message.
6007 MockRead("HTTP/1.1 401 Access Denied\r\n"),
6008 MockRead("WWW-Authenticate: NTLM "
[email protected]385a4672009-03-11 22:21:296009 "TlRMTVNTUAACAAAADAAMADgAAAAFgokCjGpMpPGlYKkAAAAAAAAAALo"
[email protected]3f918782009-02-28 01:29:246010 "AugBEAAAABQEoCgAAAA9HAE8ATwBHAEwARQACAAwARwBPAE8ARwBMAE"
6011 "UAAQAaAEEASwBFAEUAUwBBAFIAQQAtAEMATwBSAFAABAAeAGMAbwByA"
6012 "HAALgBnAG8AbwBnAGwAZQAuAGMAbwBtAAMAQABhAGsAZQBlAHMAYQBy"
6013 "AGEALQBjAG8AcgBwAC4AYQBkAC4AYwBvAHIAcAAuAGcAbwBvAGcAbAB"
6014 "lAC4AYwBvAG0ABQAeAGMAbwByAHAALgBnAG8AbwBnAGwAZQAuAGMAbw"
6015 "BtAAAAAAA=\r\n"),
6016 MockRead("Content-Length: 42\r\n"),
[email protected]076c85082009-04-10 23:21:366017 MockRead("Content-Type: text/html\r\n\r\n"),
[email protected]3f918782009-02-28 01:29:246018 MockRead("You are not authorized to view this page\r\n"),
6019
6020 // Lastly we get the desired content.
6021 MockRead("HTTP/1.1 200 OK\r\n"),
6022 MockRead("Content-Type: text/html; charset=utf-8\r\n"),
6023 MockRead("Content-Length: 13\r\n\r\n"),
6024 MockRead("Please Login\r\n"),
[email protected]8ddf8322012-02-23 18:08:066025 MockRead(SYNCHRONOUS, OK),
[email protected]3f918782009-02-28 01:29:246026 };
6027
[email protected]31a2bfe2010-02-09 08:03:396028 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
6029 data_writes1, arraysize(data_writes1));
6030 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
6031 data_writes2, arraysize(data_writes2));
[email protected]bb88e1d32013-05-03 23:11:076032 session_deps_.socket_factory->AddSocketDataProvider(&data1);
6033 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]3f918782009-02-28 01:29:246034
Bence Béky83eb3512017-09-05 12:56:096035 SSLSocketDataProvider ssl1(ASYNC, OK);
6036 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl1);
6037 SSLSocketDataProvider ssl2(ASYNC, OK);
6038 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
6039
[email protected]49639fa2011-12-20 23:22:416040 TestCompletionCallback callback1;
[email protected]3f918782009-02-28 01:29:246041
bnc691fda62016-08-12 00:43:166042 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]0b0bf032010-09-21 18:08:506043
tfarina42834112016-09-22 13:38:206044 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:016045 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]3f918782009-02-28 01:29:246046
6047 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:016048 EXPECT_THAT(rv, IsOk());
[email protected]3f918782009-02-28 01:29:246049
bnc691fda62016-08-12 00:43:166050 EXPECT_FALSE(trans.IsReadyToRestartForAuth());
[email protected]0757e7702009-03-27 04:00:226051
bnc691fda62016-08-12 00:43:166052 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:526053 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:046054 EXPECT_TRUE(CheckNTLMServerAuth(response->auth_challenge.get()));
[email protected]3f918782009-02-28 01:29:246055
[email protected]49639fa2011-12-20 23:22:416056 TestCompletionCallback callback2;
[email protected]10af5fe72011-01-31 16:17:256057
bnc691fda62016-08-12 00:43:166058 rv = trans.RestartWithAuth(AuthCredentials(kTestingNTLM, kTestingNTLM),
6059 callback2.callback());
robpercival214763f2016-07-01 23:27:016060 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]10af5fe72011-01-31 16:17:256061
6062 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:016063 EXPECT_THAT(rv, IsOk());
[email protected]10af5fe72011-01-31 16:17:256064
bnc691fda62016-08-12 00:43:166065 EXPECT_TRUE(trans.IsReadyToRestartForAuth());
[email protected]10af5fe72011-01-31 16:17:256066
bnc691fda62016-08-12 00:43:166067 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:526068 ASSERT_TRUE(response);
6069 EXPECT_FALSE(response->auth_challenge);
[email protected]10af5fe72011-01-31 16:17:256070
[email protected]49639fa2011-12-20 23:22:416071 TestCompletionCallback callback3;
[email protected]3f918782009-02-28 01:29:246072
bnc691fda62016-08-12 00:43:166073 rv = trans.RestartWithAuth(AuthCredentials(), callback3.callback());
robpercival214763f2016-07-01 23:27:016074 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]3f918782009-02-28 01:29:246075
[email protected]0757e7702009-03-27 04:00:226076 rv = callback3.WaitForResult();
robpercival214763f2016-07-01 23:27:016077 EXPECT_THAT(rv, IsOk());
[email protected]3f918782009-02-28 01:29:246078
bnc691fda62016-08-12 00:43:166079 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:526080 ASSERT_TRUE(response);
6081 EXPECT_FALSE(response->auth_challenge);
[email protected]3f918782009-02-28 01:29:246082 EXPECT_EQ(13, response->headers->GetContentLength());
6083}
6084
[email protected]385a4672009-03-11 22:21:296085// Enter a wrong password, and then the correct one.
bncd16676a2016-07-20 16:23:016086TEST_F(HttpNetworkTransactionTest, NTLMAuth2) {
[email protected]1c773ea12009-04-28 19:58:426087 HttpRequestInfo request;
[email protected]385a4672009-03-11 22:21:296088 request.method = "GET";
Bence Béky83eb3512017-09-05 12:56:096089 request.url = GURL("https://172.22.68.17/kids/login.aspx");
[email protected]385a4672009-03-11 22:21:296090
[email protected]cb9bf6ca2011-01-28 13:15:276091 HttpAuthHandlerNTLM::ScopedProcSetter proc_setter(MockGenerateRandom2,
6092 MockGetHostName);
danakj1fd259a02016-04-16 03:17:096093 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:276094
[email protected]385a4672009-03-11 22:21:296095 MockWrite data_writes1[] = {
6096 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
6097 "Host: 172.22.68.17\r\n"
6098 "Connection: keep-alive\r\n\r\n"),
6099 };
6100
6101 MockRead data_reads1[] = {
6102 MockRead("HTTP/1.1 401 Access Denied\r\n"),
[email protected]aef04272010-06-28 18:03:046103 // Negotiate and NTLM are often requested together. However, we only want
6104 // to test NTLM. Since Negotiate is preferred over NTLM, we have to skip
6105 // the header that requests Negotiate for this test.
[email protected]385a4672009-03-11 22:21:296106 MockRead("WWW-Authenticate: NTLM\r\n"),
6107 MockRead("Connection: close\r\n"),
6108 MockRead("Content-Length: 42\r\n"),
[email protected]076c85082009-04-10 23:21:366109 MockRead("Content-Type: text/html\r\n\r\n"),
[email protected]385a4672009-03-11 22:21:296110 // Missing content -- won't matter, as connection will be reset.
[email protected]8ddf8322012-02-23 18:08:066111 MockRead(SYNCHRONOUS, ERR_UNEXPECTED),
[email protected]385a4672009-03-11 22:21:296112 };
6113
6114 MockWrite data_writes2[] = {
bnc691fda62016-08-12 00:43:166115 // After restarting with a null identity, this is the
6116 // request we should be issuing -- the final header line contains a Type
6117 // 1 message.
6118 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
6119 "Host: 172.22.68.17\r\n"
6120 "Connection: keep-alive\r\n"
6121 "Authorization: NTLM "
6122 "TlRMTVNTUAABAAAAB4IIAAAAAAAAAAAAAAAAAAAAAAA=\r\n\r\n"),
[email protected]385a4672009-03-11 22:21:296123
bnc691fda62016-08-12 00:43:166124 // After calling trans.RestartWithAuth(), we should send a Type 3 message
6125 // (the credentials for the origin server). The second request continues
6126 // on the same connection.
6127 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
6128 "Host: 172.22.68.17\r\n"
6129 "Connection: keep-alive\r\n"
6130 "Authorization: NTLM TlRMTVNTUAADAAAAGAAYAGgAAAAYABgAgA"
6131 "AAAAAAAABAAAAAGAAYAEAAAAAQABAAWAAAAAAAAAAAAAAABYIIAHQA"
6132 "ZQBzAHQAaQBuAGcALQBuAHQAbABtAFcAVABDAC0AVwBJAE4ANwCWeY"
6133 "XnSZNwoQAAAAAAAAAAAAAAAAAAAADLa34/phTTKzNTWdub+uyFleOj"
6134 "4Ww7b7E=\r\n\r\n"),
[email protected]385a4672009-03-11 22:21:296135 };
6136
6137 MockRead data_reads2[] = {
6138 // The origin server responds with a Type 2 message.
6139 MockRead("HTTP/1.1 401 Access Denied\r\n"),
6140 MockRead("WWW-Authenticate: NTLM "
6141 "TlRMTVNTUAACAAAADAAMADgAAAAFgokCbVWUZezVGpAAAAAAAAAAALo"
6142 "AugBEAAAABQEoCgAAAA9HAE8ATwBHAEwARQACAAwARwBPAE8ARwBMAE"
6143 "UAAQAaAEEASwBFAEUAUwBBAFIAQQAtAEMATwBSAFAABAAeAGMAbwByA"
6144 "HAALgBnAG8AbwBnAGwAZQAuAGMAbwBtAAMAQABhAGsAZQBlAHMAYQBy"
6145 "AGEALQBjAG8AcgBwAC4AYQBkAC4AYwBvAHIAcAAuAGcAbwBvAGcAbAB"
6146 "lAC4AYwBvAG0ABQAeAGMAbwByAHAALgBnAG8AbwBnAGwAZQAuAGMAbw"
6147 "BtAAAAAAA=\r\n"),
6148 MockRead("Content-Length: 42\r\n"),
[email protected]076c85082009-04-10 23:21:366149 MockRead("Content-Type: text/html\r\n\r\n"),
[email protected]385a4672009-03-11 22:21:296150 MockRead("You are not authorized to view this page\r\n"),
6151
6152 // Wrong password.
6153 MockRead("HTTP/1.1 401 Access Denied\r\n"),
[email protected]385a4672009-03-11 22:21:296154 MockRead("WWW-Authenticate: NTLM\r\n"),
6155 MockRead("Connection: close\r\n"),
6156 MockRead("Content-Length: 42\r\n"),
[email protected]076c85082009-04-10 23:21:366157 MockRead("Content-Type: text/html\r\n\r\n"),
[email protected]385a4672009-03-11 22:21:296158 // Missing content -- won't matter, as connection will be reset.
[email protected]8ddf8322012-02-23 18:08:066159 MockRead(SYNCHRONOUS, ERR_UNEXPECTED),
[email protected]385a4672009-03-11 22:21:296160 };
6161
6162 MockWrite data_writes3[] = {
bnc691fda62016-08-12 00:43:166163 // After restarting with a null identity, this is the
6164 // request we should be issuing -- the final header line contains a Type
6165 // 1 message.
6166 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
6167 "Host: 172.22.68.17\r\n"
6168 "Connection: keep-alive\r\n"
6169 "Authorization: NTLM "
6170 "TlRMTVNTUAABAAAAB4IIAAAAAAAAAAAAAAAAAAAAAAA=\r\n\r\n"),
[email protected]385a4672009-03-11 22:21:296171
bnc691fda62016-08-12 00:43:166172 // After calling trans.RestartWithAuth(), we should send a Type 3 message
6173 // (the credentials for the origin server). The second request continues
6174 // on the same connection.
6175 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
6176 "Host: 172.22.68.17\r\n"
6177 "Connection: keep-alive\r\n"
6178 "Authorization: NTLM TlRMTVNTUAADAAAAGAAYAGgAAAAYABgAgA"
6179 "AAAAAAAABAAAAAGAAYAEAAAAAQABAAWAAAAAAAAAAAAAAABYIIAHQA"
6180 "ZQBzAHQAaQBuAGcALQBuAHQAbABtAFcAVABDAC0AVwBJAE4ANwBO54"
6181 "dFMVvTHwAAAAAAAAAAAAAAAAAAAACS7sT6Uzw7L0L//WUqlIaVWpbI"
6182 "+4MUm7c=\r\n\r\n"),
[email protected]385a4672009-03-11 22:21:296183 };
6184
6185 MockRead data_reads3[] = {
6186 // The origin server responds with a Type 2 message.
6187 MockRead("HTTP/1.1 401 Access Denied\r\n"),
6188 MockRead("WWW-Authenticate: NTLM "
6189 "TlRMTVNTUAACAAAADAAMADgAAAAFgokCL24VN8dgOR8AAAAAAAAAALo"
6190 "AugBEAAAABQEoCgAAAA9HAE8ATwBHAEwARQACAAwARwBPAE8ARwBMAE"
6191 "UAAQAaAEEASwBFAEUAUwBBAFIAQQAtAEMATwBSAFAABAAeAGMAbwByA"
6192 "HAALgBnAG8AbwBnAGwAZQAuAGMAbwBtAAMAQABhAGsAZQBlAHMAYQBy"
6193 "AGEALQBjAG8AcgBwAC4AYQBkAC4AYwBvAHIAcAAuAGcAbwBvAGcAbAB"
6194 "lAC4AYwBvAG0ABQAeAGMAbwByAHAALgBnAG8AbwBnAGwAZQAuAGMAbw"
6195 "BtAAAAAAA=\r\n"),
6196 MockRead("Content-Length: 42\r\n"),
[email protected]076c85082009-04-10 23:21:366197 MockRead("Content-Type: text/html\r\n\r\n"),
[email protected]385a4672009-03-11 22:21:296198 MockRead("You are not authorized to view this page\r\n"),
6199
6200 // Lastly we get the desired content.
6201 MockRead("HTTP/1.1 200 OK\r\n"),
6202 MockRead("Content-Type: text/html; charset=utf-8\r\n"),
6203 MockRead("Content-Length: 13\r\n\r\n"),
6204 MockRead("Please Login\r\n"),
[email protected]8ddf8322012-02-23 18:08:066205 MockRead(SYNCHRONOUS, OK),
[email protected]385a4672009-03-11 22:21:296206 };
6207
[email protected]31a2bfe2010-02-09 08:03:396208 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
6209 data_writes1, arraysize(data_writes1));
6210 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
6211 data_writes2, arraysize(data_writes2));
6212 StaticSocketDataProvider data3(data_reads3, arraysize(data_reads3),
6213 data_writes3, arraysize(data_writes3));
[email protected]bb88e1d32013-05-03 23:11:076214 session_deps_.socket_factory->AddSocketDataProvider(&data1);
6215 session_deps_.socket_factory->AddSocketDataProvider(&data2);
6216 session_deps_.socket_factory->AddSocketDataProvider(&data3);
[email protected]385a4672009-03-11 22:21:296217
Bence Béky83eb3512017-09-05 12:56:096218 SSLSocketDataProvider ssl1(ASYNC, OK);
6219 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl1);
6220 SSLSocketDataProvider ssl2(ASYNC, OK);
6221 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
6222 SSLSocketDataProvider ssl3(ASYNC, OK);
6223 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl3);
6224
[email protected]49639fa2011-12-20 23:22:416225 TestCompletionCallback callback1;
[email protected]385a4672009-03-11 22:21:296226
bnc691fda62016-08-12 00:43:166227 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]0b0bf032010-09-21 18:08:506228
tfarina42834112016-09-22 13:38:206229 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:016230 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]385a4672009-03-11 22:21:296231
6232 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:016233 EXPECT_THAT(rv, IsOk());
[email protected]385a4672009-03-11 22:21:296234
bnc691fda62016-08-12 00:43:166235 EXPECT_FALSE(trans.IsReadyToRestartForAuth());
[email protected]385a4672009-03-11 22:21:296236
bnc691fda62016-08-12 00:43:166237 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:526238 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:046239 EXPECT_TRUE(CheckNTLMServerAuth(response->auth_challenge.get()));
[email protected]385a4672009-03-11 22:21:296240
[email protected]49639fa2011-12-20 23:22:416241 TestCompletionCallback callback2;
[email protected]385a4672009-03-11 22:21:296242
[email protected]0757e7702009-03-27 04:00:226243 // Enter the wrong password.
bnc691fda62016-08-12 00:43:166244 rv = trans.RestartWithAuth(AuthCredentials(kTestingNTLM, kWrongPassword),
6245 callback2.callback());
robpercival214763f2016-07-01 23:27:016246 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]385a4672009-03-11 22:21:296247
[email protected]10af5fe72011-01-31 16:17:256248 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:016249 EXPECT_THAT(rv, IsOk());
[email protected]385a4672009-03-11 22:21:296250
bnc691fda62016-08-12 00:43:166251 EXPECT_TRUE(trans.IsReadyToRestartForAuth());
[email protected]49639fa2011-12-20 23:22:416252 TestCompletionCallback callback3;
bnc691fda62016-08-12 00:43:166253 rv = trans.RestartWithAuth(AuthCredentials(), callback3.callback());
robpercival214763f2016-07-01 23:27:016254 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]10af5fe72011-01-31 16:17:256255 rv = callback3.WaitForResult();
robpercival214763f2016-07-01 23:27:016256 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:166257 EXPECT_FALSE(trans.IsReadyToRestartForAuth());
[email protected]0757e7702009-03-27 04:00:226258
bnc691fda62016-08-12 00:43:166259 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:526260 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:046261 EXPECT_TRUE(CheckNTLMServerAuth(response->auth_challenge.get()));
[email protected]0757e7702009-03-27 04:00:226262
[email protected]49639fa2011-12-20 23:22:416263 TestCompletionCallback callback4;
[email protected]0757e7702009-03-27 04:00:226264
6265 // Now enter the right password.
bnc691fda62016-08-12 00:43:166266 rv = trans.RestartWithAuth(AuthCredentials(kTestingNTLM, kTestingNTLM),
6267 callback4.callback());
robpercival214763f2016-07-01 23:27:016268 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]10af5fe72011-01-31 16:17:256269
6270 rv = callback4.WaitForResult();
robpercival214763f2016-07-01 23:27:016271 EXPECT_THAT(rv, IsOk());
[email protected]10af5fe72011-01-31 16:17:256272
bnc691fda62016-08-12 00:43:166273 EXPECT_TRUE(trans.IsReadyToRestartForAuth());
[email protected]10af5fe72011-01-31 16:17:256274
[email protected]49639fa2011-12-20 23:22:416275 TestCompletionCallback callback5;
[email protected]10af5fe72011-01-31 16:17:256276
6277 // One more roundtrip
bnc691fda62016-08-12 00:43:166278 rv = trans.RestartWithAuth(AuthCredentials(), callback5.callback());
robpercival214763f2016-07-01 23:27:016279 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]0757e7702009-03-27 04:00:226280
6281 rv = callback5.WaitForResult();
robpercival214763f2016-07-01 23:27:016282 EXPECT_THAT(rv, IsOk());
[email protected]0757e7702009-03-27 04:00:226283
bnc691fda62016-08-12 00:43:166284 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:526285 EXPECT_FALSE(response->auth_challenge);
[email protected]385a4672009-03-11 22:21:296286 EXPECT_EQ(13, response->headers->GetContentLength());
6287}
Bence Béky83eb3512017-09-05 12:56:096288
6289// NTLM is not supported over HTTP/2, therefore the server requests a downgrade,
6290// and the request is retried on an HTTP/1.1 connection.
6291TEST_F(HttpNetworkTransactionTest, NTLMOverHttp2) {
6292 HttpAuthHandlerNTLM::ScopedProcSetter proc_setter(MockGenerateRandom1,
6293 MockGetHostName);
6294
6295 const char* kUrl = "https://172.22.68.17/kids/login.aspx";
6296
6297 HttpRequestInfo request;
6298 request.method = "GET";
6299 request.url = GURL(kUrl);
6300
6301 // First request without credentials.
6302 SpdyHeaderBlock request_headers0(spdy_util_.ConstructGetHeaderBlock(kUrl));
6303 SpdySerializedFrame request0(spdy_util_.ConstructSpdyHeaders(
6304 1, std::move(request_headers0), LOWEST, true));
6305
6306 SpdyHeaderBlock response_headers0;
6307 response_headers0[spdy_util_.GetStatusKey()] = "401";
6308 response_headers0["www-authenticate"] = "NTLM";
6309 SpdySerializedFrame resp(spdy_util_.ConstructSpdyResponseHeaders(
6310 1, std::move(response_headers0), true));
6311
6312 // Stream 1 is closed.
6313 spdy_util_.UpdateWithStreamDestruction(1);
6314
6315 // Retry with authorization header.
6316 SpdyHeaderBlock request_headers1(spdy_util_.ConstructGetHeaderBlock(kUrl));
6317 request_headers1["authorization"] =
6318 "NTLM TlRMTVNTUAABAAAAB4IIAAAAAAAAAAAAAAAAAAAAAAA=";
6319 SpdySerializedFrame request1(spdy_util_.ConstructSpdyHeaders(
6320 3, std::move(request_headers1), LOWEST, true));
6321
6322 SpdySerializedFrame go_away(spdy_util_.ConstructSpdyGoAway(
6323 0, ERROR_CODE_HTTP_1_1_REQUIRED, "NTLM not supported over HTTP/2."));
6324
6325 MockWrite writes0[] = {
6326 CreateMockWrite(request0, 0), CreateMockWrite(request1, 2),
6327 };
6328 MockRead reads0[] = {CreateMockRead(resp, 1), CreateMockRead(go_away, 3)};
6329
6330 // Retry yet again using HTTP/1.1.
6331 MockWrite writes1[] = {
6332 // After restarting with a null identity, this is the
6333 // request we should be issuing -- the final header line contains a Type
6334 // 1 message.
6335 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
6336 "Host: 172.22.68.17\r\n"
6337 "Connection: keep-alive\r\n"
6338 "Authorization: NTLM "
6339 "TlRMTVNTUAABAAAAB4IIAAAAAAAAAAAAAAAAAAAAAAA=\r\n\r\n"),
6340
6341 // After calling trans.RestartWithAuth(), we should send a Type 3 message
6342 // (the credentials for the origin server). The second request continues
6343 // on the same connection.
6344 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
6345 "Host: 172.22.68.17\r\n"
6346 "Connection: keep-alive\r\n"
6347 "Authorization: NTLM TlRMTVNTUAADAAAAGAAYAGgAAAAYABgAgA"
6348 "AAAAAAAABAAAAAGAAYAEAAAAAQABAAWAAAAAAAAAAAAAAABYIIAHQA"
6349 "ZQBzAHQAaQBuAGcALQBuAHQAbABtAFcAVABDAC0AVwBJAE4ANwBVKW"
6350 "Yma5xzVAAAAAAAAAAAAAAAAAAAAACH+gWcm+YsP9Tqb9zCR3WAeZZX"
6351 "ahlhx5I=\r\n\r\n"),
6352 };
6353
6354 MockRead reads1[] = {
6355 // The origin server responds with a Type 2 message.
6356 MockRead("HTTP/1.1 401 Access Denied\r\n"),
6357 MockRead("WWW-Authenticate: NTLM "
6358 "TlRMTVNTUAACAAAADAAMADgAAAAFgokCjGpMpPGlYKkAAAAAAAAAALo"
6359 "AugBEAAAABQEoCgAAAA9HAE8ATwBHAEwARQACAAwARwBPAE8ARwBMAE"
6360 "UAAQAaAEEASwBFAEUAUwBBAFIAQQAtAEMATwBSAFAABAAeAGMAbwByA"
6361 "HAALgBnAG8AbwBnAGwAZQAuAGMAbwBtAAMAQABhAGsAZQBlAHMAYQBy"
6362 "AGEALQBjAG8AcgBwAC4AYQBkAC4AYwBvAHIAcAAuAGcAbwBvAGcAbAB"
6363 "lAC4AYwBvAG0ABQAeAGMAbwByAHAALgBnAG8AbwBnAGwAZQAuAGMAbw"
6364 "BtAAAAAAA=\r\n"),
6365 MockRead("Content-Length: 42\r\n"),
6366 MockRead("Content-Type: text/html\r\n\r\n"),
6367 MockRead("You are not authorized to view this page\r\n"),
6368
6369 // Lastly we get the desired content.
6370 MockRead("HTTP/1.1 200 OK\r\n"),
6371 MockRead("Content-Type: text/html; charset=utf-8\r\n"),
6372 MockRead("Content-Length: 13\r\n\r\n"), MockRead("Please Login\r\n"),
6373 MockRead(SYNCHRONOUS, OK),
6374 };
6375 SequencedSocketData data0(reads0, arraysize(reads0), writes0,
6376 arraysize(writes0));
6377 StaticSocketDataProvider data1(reads1, arraysize(reads1), writes1,
6378 arraysize(writes1));
6379 session_deps_.socket_factory->AddSocketDataProvider(&data0);
6380 session_deps_.socket_factory->AddSocketDataProvider(&data1);
6381
6382 SSLSocketDataProvider ssl0(ASYNC, OK);
6383 ssl0.next_proto = kProtoHTTP2;
6384 SSLSocketDataProvider ssl1(ASYNC, OK);
6385 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl0);
6386 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl1);
6387
6388 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
6389 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
6390
6391 TestCompletionCallback callback1;
6392 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
6393 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
6394
6395 rv = callback1.WaitForResult();
6396 EXPECT_THAT(rv, IsOk());
6397
6398 EXPECT_FALSE(trans.IsReadyToRestartForAuth());
6399
6400 const HttpResponseInfo* response = trans.GetResponseInfo();
6401 ASSERT_TRUE(response);
6402 EXPECT_TRUE(CheckNTLMServerAuth(response->auth_challenge.get()));
6403
6404 TestCompletionCallback callback2;
6405
6406 rv = trans.RestartWithAuth(AuthCredentials(kTestingNTLM, kTestingNTLM),
6407 callback2.callback());
6408 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
6409
6410 rv = callback2.WaitForResult();
6411 EXPECT_THAT(rv, IsOk());
6412
6413 EXPECT_TRUE(trans.IsReadyToRestartForAuth());
6414
6415 response = trans.GetResponseInfo();
6416 ASSERT_TRUE(response);
6417 EXPECT_FALSE(response->auth_challenge);
6418
6419 TestCompletionCallback callback3;
6420
6421 rv = trans.RestartWithAuth(AuthCredentials(), callback3.callback());
6422 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
6423
6424 rv = callback3.WaitForResult();
6425 EXPECT_THAT(rv, IsOk());
6426
6427 response = trans.GetResponseInfo();
6428 ASSERT_TRUE(response);
6429 EXPECT_FALSE(response->auth_challenge);
6430 EXPECT_EQ(13, response->headers->GetContentLength());
6431}
[email protected]ea9dc9a2009-09-05 00:43:326432#endif // NTLM_PORTABLE
[email protected]385a4672009-03-11 22:21:296433
[email protected]4ddaf2502008-10-23 18:26:196434// Test reading a server response which has only headers, and no body.
6435// After some maximum number of bytes is consumed, the transaction should
6436// fail with ERR_RESPONSE_HEADERS_TOO_BIG.
bncd16676a2016-07-20 16:23:016437TEST_F(HttpNetworkTransactionTest, LargeHeadersNoBody) {
[email protected]1c773ea12009-04-28 19:58:426438 HttpRequestInfo request;
[email protected]4ddaf2502008-10-23 18:26:196439 request.method = "GET";
bncce36dca22015-04-21 22:11:236440 request.url = GURL("http://www.example.org/");
[email protected]4ddaf2502008-10-23 18:26:196441
danakj1fd259a02016-04-16 03:17:096442 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:166443 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:276444
[email protected]b75b7b2f2009-10-06 00:54:536445 // Respond with 300 kb of headers (we should fail after 256 kb).
[email protected]15a5ccf82008-10-23 19:57:436446 std::string large_headers_string;
[email protected]b75b7b2f2009-10-06 00:54:536447 FillLargeHeadersString(&large_headers_string, 300 * 1024);
[email protected]4ddaf2502008-10-23 18:26:196448
6449 MockRead data_reads[] = {
6450 MockRead("HTTP/1.0 200 OK\r\n"),
[email protected]8ddf8322012-02-23 18:08:066451 MockRead(ASYNC, large_headers_string.data(), large_headers_string.size()),
[email protected]4ddaf2502008-10-23 18:26:196452 MockRead("\r\nBODY"),
[email protected]8ddf8322012-02-23 18:08:066453 MockRead(SYNCHRONOUS, OK),
[email protected]4ddaf2502008-10-23 18:26:196454 };
[email protected]31a2bfe2010-02-09 08:03:396455 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:076456 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]4ddaf2502008-10-23 18:26:196457
[email protected]49639fa2011-12-20 23:22:416458 TestCompletionCallback callback;
[email protected]4ddaf2502008-10-23 18:26:196459
tfarina42834112016-09-22 13:38:206460 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:016461 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]4ddaf2502008-10-23 18:26:196462
6463 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:016464 EXPECT_THAT(rv, IsError(ERR_RESPONSE_HEADERS_TOO_BIG));
[email protected]4ddaf2502008-10-23 18:26:196465}
[email protected]f4e426b2008-11-05 00:24:496466
6467// Make sure that we don't try to reuse a TCPClientSocket when failing to
6468// establish tunnel.
6469// http://code.google.com/p/chromium/issues/detail?id=3772
bncd16676a2016-07-20 16:23:016470TEST_F(HttpNetworkTransactionTest, DontRecycleTransportSocketForSSLTunnel) {
[email protected]cb9bf6ca2011-01-28 13:15:276471 HttpRequestInfo request;
6472 request.method = "GET";
bncce36dca22015-04-21 22:11:236473 request.url = GURL("https://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:276474
[email protected]f4e426b2008-11-05 00:24:496475 // Configure against proxy server "myproxy:70".
rdsmith82957ad2015-09-16 19:42:036476 session_deps_.proxy_service = ProxyService::CreateFixed("myproxy:70");
[email protected]db8f44c2008-12-13 04:52:016477
danakj1fd259a02016-04-16 03:17:096478 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]f4e426b2008-11-05 00:24:496479
bnc87dcefc2017-05-25 12:47:586480 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:196481 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]f4e426b2008-11-05 00:24:496482
[email protected]f4e426b2008-11-05 00:24:496483 // Since we have proxy, should try to establish tunnel.
6484 MockWrite data_writes1[] = {
rsleevidb16bb02015-11-12 23:47:176485 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
6486 "Host: www.example.org:443\r\n"
6487 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]f4e426b2008-11-05 00:24:496488 };
6489
[email protected]77848d12008-11-14 00:00:226490 // The proxy responds to the connect with a 404, using a persistent
[email protected]f4e426b2008-11-05 00:24:496491 // connection. Usually a proxy would return 501 (not implemented),
6492 // or 200 (tunnel established).
6493 MockRead data_reads1[] = {
mmenked39192ee2015-12-09 00:57:236494 MockRead("HTTP/1.1 404 Not Found\r\n"),
6495 MockRead("Content-Length: 10\r\n\r\n"),
6496 MockRead(SYNCHRONOUS, ERR_UNEXPECTED),
[email protected]f4e426b2008-11-05 00:24:496497 };
6498
[email protected]31a2bfe2010-02-09 08:03:396499 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
6500 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:076501 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]f4e426b2008-11-05 00:24:496502
[email protected]49639fa2011-12-20 23:22:416503 TestCompletionCallback callback1;
[email protected]f4e426b2008-11-05 00:24:496504
tfarina42834112016-09-22 13:38:206505 int rv = trans->Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:016506 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]f4e426b2008-11-05 00:24:496507
6508 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:016509 EXPECT_THAT(rv, IsError(ERR_TUNNEL_CONNECTION_FAILED));
[email protected]f4e426b2008-11-05 00:24:496510
[email protected]b4404c02009-04-10 16:38:526511 // Empty the current queue. This is necessary because idle sockets are
6512 // added to the connection pool asynchronously with a PostTask.
fdoray92e35a72016-06-10 15:54:556513 base::RunLoop().RunUntilIdle();
[email protected]b4404c02009-04-10 16:38:526514
[email protected]f4e426b2008-11-05 00:24:496515 // We now check to make sure the TCPClientSocket was not added back to
6516 // the pool.
[email protected]90499482013-06-01 00:39:506517 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]f4e426b2008-11-05 00:24:496518 trans.reset();
fdoray92e35a72016-06-10 15:54:556519 base::RunLoop().RunUntilIdle();
[email protected]f4e426b2008-11-05 00:24:496520 // Make sure that the socket didn't get recycled after calling the destructor.
[email protected]90499482013-06-01 00:39:506521 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]f4e426b2008-11-05 00:24:496522}
[email protected]372d34a2008-11-05 21:30:516523
[email protected]1b157c02009-04-21 01:55:406524// Make sure that we recycle a socket after reading all of the response body.
bncd16676a2016-07-20 16:23:016525TEST_F(HttpNetworkTransactionTest, RecycleSocket) {
[email protected]1c773ea12009-04-28 19:58:426526 HttpRequestInfo request;
[email protected]1b157c02009-04-21 01:55:406527 request.method = "GET";
bncce36dca22015-04-21 22:11:236528 request.url = GURL("http://www.example.org/");
[email protected]1b157c02009-04-21 01:55:406529
danakj1fd259a02016-04-16 03:17:096530 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:276531
bnc691fda62016-08-12 00:43:166532 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:276533
[email protected]1b157c02009-04-21 01:55:406534 MockRead data_reads[] = {
6535 // A part of the response body is received with the response headers.
6536 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 11\r\n\r\nhel"),
6537 // The rest of the response body is received in two parts.
6538 MockRead("lo"),
6539 MockRead(" world"),
6540 MockRead("junk"), // Should not be read!!
[email protected]8ddf8322012-02-23 18:08:066541 MockRead(SYNCHRONOUS, OK),
[email protected]1b157c02009-04-21 01:55:406542 };
6543
[email protected]31a2bfe2010-02-09 08:03:396544 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:076545 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1b157c02009-04-21 01:55:406546
[email protected]49639fa2011-12-20 23:22:416547 TestCompletionCallback callback;
[email protected]1b157c02009-04-21 01:55:406548
tfarina42834112016-09-22 13:38:206549 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:016550 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]1b157c02009-04-21 01:55:406551
6552 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:016553 EXPECT_THAT(rv, IsOk());
[email protected]1b157c02009-04-21 01:55:406554
bnc691fda62016-08-12 00:43:166555 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:526556 ASSERT_TRUE(response);
[email protected]1b157c02009-04-21 01:55:406557
wezca1070932016-05-26 20:30:526558 EXPECT_TRUE(response->headers);
[email protected]1b157c02009-04-21 01:55:406559 std::string status_line = response->headers->GetStatusLine();
6560 EXPECT_EQ("HTTP/1.1 200 OK", status_line);
6561
[email protected]90499482013-06-01 00:39:506562 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]1b157c02009-04-21 01:55:406563
6564 std::string response_data;
bnc691fda62016-08-12 00:43:166565 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:016566 EXPECT_THAT(rv, IsOk());
[email protected]1b157c02009-04-21 01:55:406567 EXPECT_EQ("hello world", response_data);
6568
6569 // 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]1b157c02009-04-21 01:55:406572
6573 // We now check to make sure the socket was added back to the pool.
[email protected]90499482013-06-01 00:39:506574 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]1b157c02009-04-21 01:55:406575}
6576
[email protected]76a505b2010-08-25 06:23:006577// Make sure that we recycle a SSL socket after reading all of the response
6578// body.
bncd16676a2016-07-20 16:23:016579TEST_F(HttpNetworkTransactionTest, RecycleSSLSocket) {
[email protected]76a505b2010-08-25 06:23:006580 HttpRequestInfo request;
6581 request.method = "GET";
bncce36dca22015-04-21 22:11:236582 request.url = GURL("https://www.example.org/");
[email protected]76a505b2010-08-25 06:23:006583
6584 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:236585 MockWrite(
6586 "GET / HTTP/1.1\r\n"
6587 "Host: www.example.org\r\n"
6588 "Connection: keep-alive\r\n\r\n"),
[email protected]76a505b2010-08-25 06:23:006589 };
6590
6591 MockRead data_reads[] = {
6592 MockRead("HTTP/1.1 200 OK\r\n"),
6593 MockRead("Content-Length: 11\r\n\r\n"),
6594 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:066595 MockRead(SYNCHRONOUS, OK),
[email protected]76a505b2010-08-25 06:23:006596 };
6597
[email protected]8ddf8322012-02-23 18:08:066598 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:076599 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]76a505b2010-08-25 06:23:006600
6601 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
6602 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:076603 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]76a505b2010-08-25 06:23:006604
[email protected]49639fa2011-12-20 23:22:416605 TestCompletionCallback callback;
[email protected]76a505b2010-08-25 06:23:006606
danakj1fd259a02016-04-16 03:17:096607 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:166608 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]76a505b2010-08-25 06:23:006609
tfarina42834112016-09-22 13:38:206610 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
[email protected]76a505b2010-08-25 06:23:006611
robpercival214763f2016-07-01 23:27:016612 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
6613 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]76a505b2010-08-25 06:23:006614
bnc691fda62016-08-12 00:43:166615 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:526616 ASSERT_TRUE(response);
6617 ASSERT_TRUE(response->headers);
[email protected]76a505b2010-08-25 06:23:006618 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
6619
[email protected]90499482013-06-01 00:39:506620 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]76a505b2010-08-25 06:23:006621
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]76a505b2010-08-25 06:23:006625 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]76a505b2010-08-25 06:23:006630
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, GetIdleSocketCountInSSLSocketPool(session.get()));
[email protected]76a505b2010-08-25 06:23:006633}
6634
6635// Grab a SSL socket, use it, and put it back into the pool. Then, reuse it
6636// from the pool and make sure that we recover okay.
bncd16676a2016-07-20 16:23:016637TEST_F(HttpNetworkTransactionTest, RecycleDeadSSLSocket) {
[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"),
6647 MockWrite(
6648 "GET / HTTP/1.1\r\n"
6649 "Host: www.example.org\r\n"
6650 "Connection: keep-alive\r\n\r\n"),
[email protected]76a505b2010-08-25 06:23:006651 };
6652
6653 MockRead data_reads[] = {
mmenke911ee0222015-12-04 03:58:426654 MockRead("HTTP/1.1 200 OK\r\n"), MockRead("Content-Length: 11\r\n\r\n"),
6655 MockRead("hello world"), MockRead(ASYNC, ERR_CONNECTION_CLOSED)};
[email protected]76a505b2010-08-25 06:23:006656
[email protected]8ddf8322012-02-23 18:08:066657 SSLSocketDataProvider ssl(ASYNC, OK);
6658 SSLSocketDataProvider ssl2(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:076659 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
6660 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
[email protected]76a505b2010-08-25 06:23:006661
6662 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
6663 data_writes, arraysize(data_writes));
6664 StaticSocketDataProvider data2(data_reads, arraysize(data_reads),
6665 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:076666 session_deps_.socket_factory->AddSocketDataProvider(&data);
6667 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]76a505b2010-08-25 06:23:006668
[email protected]49639fa2011-12-20 23:22:416669 TestCompletionCallback callback;
[email protected]76a505b2010-08-25 06:23:006670
danakj1fd259a02016-04-16 03:17:096671 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc87dcefc2017-05-25 12:47:586672 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:196673 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]76a505b2010-08-25 06:23:006674
tfarina42834112016-09-22 13:38:206675 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
[email protected]76a505b2010-08-25 06:23:006676
robpercival214763f2016-07-01 23:27:016677 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
6678 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]76a505b2010-08-25 06:23:006679
6680 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:526681 ASSERT_TRUE(response);
6682 ASSERT_TRUE(response->headers);
[email protected]76a505b2010-08-25 06:23:006683 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
6684
[email protected]90499482013-06-01 00:39:506685 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]76a505b2010-08-25 06:23:006686
6687 std::string response_data;
6688 rv = ReadTransaction(trans.get(), &response_data);
robpercival214763f2016-07-01 23:27:016689 EXPECT_THAT(rv, IsOk());
[email protected]76a505b2010-08-25 06:23:006690 EXPECT_EQ("hello world", response_data);
6691
6692 // Empty the current queue. This is necessary because idle sockets are
6693 // added to the connection pool asynchronously with a PostTask.
fdoray92e35a72016-06-10 15:54:556694 base::RunLoop().RunUntilIdle();
[email protected]76a505b2010-08-25 06:23:006695
6696 // We now check to make sure the socket was added back to the pool.
[email protected]90499482013-06-01 00:39:506697 EXPECT_EQ(1, GetIdleSocketCountInSSLSocketPool(session.get()));
[email protected]76a505b2010-08-25 06:23:006698
6699 // Now start the second transaction, which should reuse the previous socket.
6700
bnc87dcefc2017-05-25 12:47:586701 trans =
Jeremy Roman0579ed62017-08-29 15:56:196702 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]76a505b2010-08-25 06:23:006703
tfarina42834112016-09-22 13:38:206704 rv = trans->Start(&request, callback.callback(), NetLogWithSource());
[email protected]76a505b2010-08-25 06:23:006705
robpercival214763f2016-07-01 23:27:016706 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
6707 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]76a505b2010-08-25 06:23:006708
6709 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:526710 ASSERT_TRUE(response);
6711 ASSERT_TRUE(response->headers);
[email protected]76a505b2010-08-25 06:23:006712 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
6713
[email protected]90499482013-06-01 00:39:506714 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]76a505b2010-08-25 06:23:006715
6716 rv = ReadTransaction(trans.get(), &response_data);
robpercival214763f2016-07-01 23:27:016717 EXPECT_THAT(rv, IsOk());
[email protected]76a505b2010-08-25 06:23:006718 EXPECT_EQ("hello world", response_data);
6719
6720 // Empty the current queue. This is necessary because idle sockets are
6721 // added to the connection pool asynchronously with a PostTask.
fdoray92e35a72016-06-10 15:54:556722 base::RunLoop().RunUntilIdle();
[email protected]76a505b2010-08-25 06:23:006723
6724 // We now check to make sure the socket was added back to the pool.
[email protected]90499482013-06-01 00:39:506725 EXPECT_EQ(1, GetIdleSocketCountInSSLSocketPool(session.get()));
[email protected]76a505b2010-08-25 06:23:006726}
6727
maksim.sisov0adf8592016-07-15 06:25:566728// Grab a socket, use it, and put it back into the pool. Then, make
6729// low memory notification and ensure the socket pool is flushed.
bncd16676a2016-07-20 16:23:016730TEST_F(HttpNetworkTransactionTest, FlushSocketPoolOnLowMemoryNotifications) {
maksim.sisov0adf8592016-07-15 06:25:566731 HttpRequestInfo request;
6732 request.method = "GET";
6733 request.url = GURL("http://www.example.org/");
6734 request.load_flags = 0;
6735
6736 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
6737
bnc691fda62016-08-12 00:43:166738 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
maksim.sisov0adf8592016-07-15 06:25:566739
6740 MockRead data_reads[] = {
6741 // A part of the response body is received with the response headers.
6742 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 11\r\n\r\nhel"),
6743 // The rest of the response body is received in two parts.
6744 MockRead("lo"), MockRead(" world"),
6745 MockRead("junk"), // Should not be read!!
6746 MockRead(SYNCHRONOUS, OK),
6747 };
6748
6749 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
6750 session_deps_.socket_factory->AddSocketDataProvider(&data);
6751
6752 TestCompletionCallback callback;
6753
tfarina42834112016-09-22 13:38:206754 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
maksim.sisov0adf8592016-07-15 06:25:566755 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
6756
6757 EXPECT_THAT(callback.GetResult(rv), IsOk());
6758
bnc691fda62016-08-12 00:43:166759 const HttpResponseInfo* response = trans.GetResponseInfo();
maksim.sisov0adf8592016-07-15 06:25:566760 ASSERT_TRUE(response);
6761 EXPECT_TRUE(response->headers);
6762 std::string status_line = response->headers->GetStatusLine();
6763 EXPECT_EQ("HTTP/1.1 200 OK", status_line);
6764
6765 // Make memory critical notification and ensure the transaction still has been
6766 // operating right.
6767 base::MemoryPressureListener::NotifyMemoryPressure(
6768 base::MemoryPressureListener::MEMORY_PRESSURE_LEVEL_CRITICAL);
6769 base::RunLoop().RunUntilIdle();
6770
6771 // Socket should not be flushed as long as it is not idle.
6772 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
6773
6774 std::string response_data;
bnc691fda62016-08-12 00:43:166775 rv = ReadTransaction(&trans, &response_data);
maksim.sisov0adf8592016-07-15 06:25:566776 EXPECT_THAT(rv, IsOk());
6777 EXPECT_EQ("hello world", response_data);
6778
6779 // Empty the current queue. This is necessary because idle sockets are
6780 // added to the connection pool asynchronously with a PostTask.
6781 base::RunLoop().RunUntilIdle();
6782
6783 // We now check to make sure the socket was added back to the pool.
6784 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
6785
6786 // Idle sockets should be flushed now.
6787 base::MemoryPressureListener::NotifyMemoryPressure(
6788 base::MemoryPressureListener::MEMORY_PRESSURE_LEVEL_CRITICAL);
6789 base::RunLoop().RunUntilIdle();
6790
6791 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
6792}
6793
6794// Grab an SSL socket, use it, and put it back into the pool. Then, make
6795// low memory notification and ensure the socket pool is flushed.
bncd16676a2016-07-20 16:23:016796TEST_F(HttpNetworkTransactionTest, FlushSSLSocketPoolOnLowMemoryNotifications) {
maksim.sisov0adf8592016-07-15 06:25:566797 HttpRequestInfo request;
6798 request.method = "GET";
6799 request.url = GURL("https://www.example.org/");
6800 request.load_flags = 0;
6801
6802 MockWrite data_writes[] = {
6803 MockWrite("GET / HTTP/1.1\r\n"
6804 "Host: www.example.org\r\n"
6805 "Connection: keep-alive\r\n\r\n"),
6806 };
6807
6808 MockRead data_reads[] = {
6809 MockRead("HTTP/1.1 200 OK\r\n"), MockRead("Content-Length: 11\r\n\r\n"),
6810 MockRead("hello world"), MockRead(ASYNC, ERR_CONNECTION_CLOSED)};
6811
6812 SSLSocketDataProvider ssl(ASYNC, OK);
6813 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
6814
6815 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
6816 arraysize(data_writes));
6817 session_deps_.socket_factory->AddSocketDataProvider(&data);
6818
6819 TestCompletionCallback callback;
6820
6821 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:166822 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
maksim.sisov0adf8592016-07-15 06:25:566823
6824 EXPECT_EQ(0, GetIdleSocketCountInSSLSocketPool(session.get()));
tfarina42834112016-09-22 13:38:206825 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
maksim.sisov0adf8592016-07-15 06:25:566826
6827 EXPECT_THAT(callback.GetResult(rv), IsOk());
6828
bnc691fda62016-08-12 00:43:166829 const HttpResponseInfo* response = trans.GetResponseInfo();
maksim.sisov0adf8592016-07-15 06:25:566830 ASSERT_TRUE(response);
6831 ASSERT_TRUE(response->headers);
6832 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
6833
6834 // Make memory critical notification and ensure the transaction still has been
6835 // operating right.
6836 base::MemoryPressureListener::NotifyMemoryPressure(
6837 base::MemoryPressureListener::MEMORY_PRESSURE_LEVEL_CRITICAL);
6838 base::RunLoop().RunUntilIdle();
6839
6840 EXPECT_EQ(0, GetIdleSocketCountInSSLSocketPool(session.get()));
6841
6842 std::string response_data;
bnc691fda62016-08-12 00:43:166843 rv = ReadTransaction(&trans, &response_data);
maksim.sisov0adf8592016-07-15 06:25:566844 EXPECT_THAT(rv, IsOk());
6845 EXPECT_EQ("hello world", response_data);
6846
6847 // Empty the current queue. This is necessary because idle sockets are
6848 // added to the connection pool asynchronously with a PostTask.
6849 base::RunLoop().RunUntilIdle();
6850
6851 // We now check to make sure the socket was added back to the pool.
6852 EXPECT_EQ(1, GetIdleSocketCountInSSLSocketPool(session.get()));
6853
6854 // Make memory notification once again and ensure idle socket is closed.
6855 base::MemoryPressureListener::NotifyMemoryPressure(
6856 base::MemoryPressureListener::MEMORY_PRESSURE_LEVEL_CRITICAL);
6857 base::RunLoop().RunUntilIdle();
6858
6859 EXPECT_EQ(0, GetIdleSocketCountInSSLSocketPool(session.get()));
6860}
6861
[email protected]b4404c02009-04-10 16:38:526862// Make sure that we recycle a socket after a zero-length response.
6863// http://crbug.com/9880
bncd16676a2016-07-20 16:23:016864TEST_F(HttpNetworkTransactionTest, RecycleSocketAfterZeroContentLength) {
[email protected]1c773ea12009-04-28 19:58:426865 HttpRequestInfo request;
[email protected]b4404c02009-04-10 16:38:526866 request.method = "GET";
bncce36dca22015-04-21 22:11:236867 request.url = GURL(
6868 "http://www.example.org/csi?v=3&s=web&action=&"
6869 "tran=undefined&ei=mAXcSeegAo-SMurloeUN&"
6870 "e=17259,18167,19592,19773,19981,20133,20173,20233&"
6871 "rt=prt.2642,ol.2649,xjs.2951");
[email protected]b4404c02009-04-10 16:38:526872
danakj1fd259a02016-04-16 03:17:096873 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:276874
[email protected]b4404c02009-04-10 16:38:526875 MockRead data_reads[] = {
6876 MockRead("HTTP/1.1 204 No Content\r\n"
6877 "Content-Length: 0\r\n"
6878 "Content-Type: text/html\r\n\r\n"),
6879 MockRead("junk"), // Should not be read!!
[email protected]8ddf8322012-02-23 18:08:066880 MockRead(SYNCHRONOUS, OK),
[email protected]b4404c02009-04-10 16:38:526881 };
6882
[email protected]31a2bfe2010-02-09 08:03:396883 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:076884 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]b4404c02009-04-10 16:38:526885
mmenkecc2298e2015-12-07 18:20:186886 // Transaction must be created after the MockReads, so it's destroyed before
6887 // them.
bnc691fda62016-08-12 00:43:166888 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
mmenkecc2298e2015-12-07 18:20:186889
[email protected]49639fa2011-12-20 23:22:416890 TestCompletionCallback callback;
[email protected]b4404c02009-04-10 16:38:526891
tfarina42834112016-09-22 13:38:206892 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:016893 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]b4404c02009-04-10 16:38:526894
6895 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:016896 EXPECT_THAT(rv, IsOk());
[email protected]b4404c02009-04-10 16:38:526897
bnc691fda62016-08-12 00:43:166898 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:526899 ASSERT_TRUE(response);
[email protected]b4404c02009-04-10 16:38:526900
wezca1070932016-05-26 20:30:526901 EXPECT_TRUE(response->headers);
[email protected]b4404c02009-04-10 16:38:526902 std::string status_line = response->headers->GetStatusLine();
6903 EXPECT_EQ("HTTP/1.1 204 No Content", status_line);
6904
[email protected]90499482013-06-01 00:39:506905 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]b4404c02009-04-10 16:38:526906
6907 std::string response_data;
bnc691fda62016-08-12 00:43:166908 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:016909 EXPECT_THAT(rv, IsOk());
[email protected]b4404c02009-04-10 16:38:526910 EXPECT_EQ("", response_data);
6911
6912 // Empty the current queue. This is necessary because idle sockets are
6913 // added to the connection pool asynchronously with a PostTask.
fdoray92e35a72016-06-10 15:54:556914 base::RunLoop().RunUntilIdle();
[email protected]b4404c02009-04-10 16:38:526915
6916 // We now check to make sure the socket was added back to the pool.
[email protected]90499482013-06-01 00:39:506917 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]b4404c02009-04-10 16:38:526918}
6919
bncd16676a2016-07-20 16:23:016920TEST_F(HttpNetworkTransactionTest, ResendRequestOnWriteBodyError) {
danakj1fd259a02016-04-16 03:17:096921 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:226922 element_readers.push_back(
Jeremy Roman0579ed62017-08-29 15:56:196923 std::make_unique<UploadBytesElementReader>("foo", 3));
olli.raula6df48b2a2015-11-26 07:40:226924 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]329b68b2012-11-14 17:54:276925
[email protected]1c773ea12009-04-28 19:58:426926 HttpRequestInfo request[2];
[email protected]372d34a2008-11-05 21:30:516927 // Transaction 1: a GET request that succeeds. The socket is recycled
6928 // after use.
6929 request[0].method = "GET";
6930 request[0].url = GURL("http://www.google.com/");
6931 request[0].load_flags = 0;
6932 // Transaction 2: a POST request. Reuses the socket kept alive from
6933 // transaction 1. The first attempts fails when writing the POST data.
6934 // This causes the transaction to retry with a new socket. The second
6935 // attempt succeeds.
6936 request[1].method = "POST";
6937 request[1].url = GURL("http://www.google.com/login.cgi");
[email protected]329b68b2012-11-14 17:54:276938 request[1].upload_data_stream = &upload_data_stream;
[email protected]372d34a2008-11-05 21:30:516939 request[1].load_flags = 0;
6940
danakj1fd259a02016-04-16 03:17:096941 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]372d34a2008-11-05 21:30:516942
6943 // The first socket is used for transaction 1 and the first attempt of
6944 // transaction 2.
6945
6946 // The response of transaction 1.
6947 MockRead data_reads1[] = {
6948 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 11\r\n\r\n"),
6949 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:066950 MockRead(SYNCHRONOUS, OK),
[email protected]372d34a2008-11-05 21:30:516951 };
6952 // The mock write results of transaction 1 and the first attempt of
6953 // transaction 2.
6954 MockWrite data_writes1[] = {
[email protected]8ddf8322012-02-23 18:08:066955 MockWrite(SYNCHRONOUS, 64), // GET
6956 MockWrite(SYNCHRONOUS, 93), // POST
6957 MockWrite(SYNCHRONOUS, ERR_CONNECTION_ABORTED), // POST data
[email protected]372d34a2008-11-05 21:30:516958 };
[email protected]31a2bfe2010-02-09 08:03:396959 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
6960 data_writes1, arraysize(data_writes1));
[email protected]372d34a2008-11-05 21:30:516961
6962 // The second socket is used for the second attempt of transaction 2.
6963
6964 // The response of transaction 2.
6965 MockRead data_reads2[] = {
6966 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 7\r\n\r\n"),
6967 MockRead("welcome"),
[email protected]8ddf8322012-02-23 18:08:066968 MockRead(SYNCHRONOUS, OK),
[email protected]372d34a2008-11-05 21:30:516969 };
6970 // The mock write results of the second attempt of transaction 2.
6971 MockWrite data_writes2[] = {
[email protected]8ddf8322012-02-23 18:08:066972 MockWrite(SYNCHRONOUS, 93), // POST
6973 MockWrite(SYNCHRONOUS, 3), // POST data
[email protected]372d34a2008-11-05 21:30:516974 };
[email protected]31a2bfe2010-02-09 08:03:396975 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
6976 data_writes2, arraysize(data_writes2));
[email protected]372d34a2008-11-05 21:30:516977
[email protected]bb88e1d32013-05-03 23:11:076978 session_deps_.socket_factory->AddSocketDataProvider(&data1);
6979 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]372d34a2008-11-05 21:30:516980
thestig9d3bb0c2015-01-24 00:49:516981 const char* const kExpectedResponseData[] = {
[email protected]372d34a2008-11-05 21:30:516982 "hello world", "welcome"
6983 };
6984
6985 for (int i = 0; i < 2; ++i) {
bnc691fda62016-08-12 00:43:166986 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]372d34a2008-11-05 21:30:516987
[email protected]49639fa2011-12-20 23:22:416988 TestCompletionCallback callback;
[email protected]372d34a2008-11-05 21:30:516989
tfarina42834112016-09-22 13:38:206990 int rv = trans.Start(&request[i], callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:016991 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]372d34a2008-11-05 21:30:516992
6993 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:016994 EXPECT_THAT(rv, IsOk());
[email protected]372d34a2008-11-05 21:30:516995
bnc691fda62016-08-12 00:43:166996 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:526997 ASSERT_TRUE(response);
[email protected]372d34a2008-11-05 21:30:516998
wezca1070932016-05-26 20:30:526999 EXPECT_TRUE(response->headers);
[email protected]372d34a2008-11-05 21:30:517000 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
7001
7002 std::string response_data;
bnc691fda62016-08-12 00:43:167003 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:017004 EXPECT_THAT(rv, IsOk());
[email protected]372d34a2008-11-05 21:30:517005 EXPECT_EQ(kExpectedResponseData[i], response_data);
7006 }
7007}
[email protected]f9ee6b52008-11-08 06:46:237008
7009// Test the request-challenge-retry sequence for basic auth when there is
7010// an identity in the URL. The request should be sent as normal, but when
[email protected]2262e3a2012-05-22 16:08:167011// it fails the identity from the URL is used to answer the challenge.
bncd16676a2016-07-20 16:23:017012TEST_F(HttpNetworkTransactionTest, AuthIdentityInURL) {
[email protected]1c773ea12009-04-28 19:58:427013 HttpRequestInfo request;
[email protected]f9ee6b52008-11-08 06:46:237014 request.method = "GET";
bncce36dca22015-04-21 22:11:237015 request.url = GURL("http://foo:b@[email protected]/");
[email protected]7b08ba62012-02-10 20:19:417016 request.load_flags = LOAD_NORMAL;
[email protected]a97cca42009-08-14 01:00:297017
danakj1fd259a02016-04-16 03:17:097018 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:167019 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:277020
[email protected]a97cca42009-08-14 01:00:297021 // The password contains an escaped character -- for this test to pass it
7022 // will need to be unescaped by HttpNetworkTransaction.
7023 EXPECT_EQ("b%40r", request.url.password());
7024
[email protected]f9ee6b52008-11-08 06:46:237025 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:237026 MockWrite(
7027 "GET / HTTP/1.1\r\n"
7028 "Host: www.example.org\r\n"
7029 "Connection: keep-alive\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:237030 };
7031
7032 MockRead data_reads1[] = {
7033 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
7034 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
7035 MockRead("Content-Length: 10\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067036 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]f9ee6b52008-11-08 06:46:237037 };
7038
[email protected]2262e3a2012-05-22 16:08:167039 // After the challenge above, the transaction will be restarted using the
7040 // identity from the url (foo, b@r) to answer the challenge.
7041 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:237042 MockWrite(
7043 "GET / HTTP/1.1\r\n"
7044 "Host: www.example.org\r\n"
7045 "Connection: keep-alive\r\n"
7046 "Authorization: Basic Zm9vOmJAcg==\r\n\r\n"),
[email protected]2262e3a2012-05-22 16:08:167047 };
7048
7049 MockRead data_reads2[] = {
7050 MockRead("HTTP/1.0 200 OK\r\n"),
7051 MockRead("Content-Length: 100\r\n\r\n"),
7052 MockRead(SYNCHRONOUS, OK),
7053 };
7054
[email protected]31a2bfe2010-02-09 08:03:397055 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
7056 data_writes1, arraysize(data_writes1));
[email protected]2262e3a2012-05-22 16:08:167057 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
7058 data_writes2, arraysize(data_writes2));
[email protected]bb88e1d32013-05-03 23:11:077059 session_deps_.socket_factory->AddSocketDataProvider(&data1);
7060 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]f9ee6b52008-11-08 06:46:237061
[email protected]49639fa2011-12-20 23:22:417062 TestCompletionCallback callback1;
tfarina42834112016-09-22 13:38:207063 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:017064 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]f9ee6b52008-11-08 06:46:237065 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:017066 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:167067 EXPECT_TRUE(trans.IsReadyToRestartForAuth());
[email protected]2262e3a2012-05-22 16:08:167068
7069 TestCompletionCallback callback2;
bnc691fda62016-08-12 00:43:167070 rv = trans.RestartWithAuth(AuthCredentials(), callback2.callback());
robpercival214763f2016-07-01 23:27:017071 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2262e3a2012-05-22 16:08:167072 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:017073 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:167074 EXPECT_FALSE(trans.IsReadyToRestartForAuth());
[email protected]0757e7702009-03-27 04:00:227075
bnc691fda62016-08-12 00:43:167076 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:527077 ASSERT_TRUE(response);
[email protected]2262e3a2012-05-22 16:08:167078
7079 // There is no challenge info, since the identity in URL worked.
wezca1070932016-05-26 20:30:527080 EXPECT_FALSE(response->auth_challenge);
[email protected]2262e3a2012-05-22 16:08:167081
7082 EXPECT_EQ(100, response->headers->GetContentLength());
7083
7084 // Empty the current queue.
fdoray92e35a72016-06-10 15:54:557085 base::RunLoop().RunUntilIdle();
[email protected]2262e3a2012-05-22 16:08:167086}
7087
7088// Test the request-challenge-retry sequence for basic auth when there is an
7089// incorrect identity in the URL. The identity from the URL should be used only
7090// once.
bncd16676a2016-07-20 16:23:017091TEST_F(HttpNetworkTransactionTest, WrongAuthIdentityInURL) {
[email protected]2262e3a2012-05-22 16:08:167092 HttpRequestInfo request;
7093 request.method = "GET";
7094 // Note: the URL has a username:password in it. The password "baz" is
7095 // wrong (should be "bar").
bncce36dca22015-04-21 22:11:237096 request.url = GURL("http://foo:[email protected]/");
[email protected]2262e3a2012-05-22 16:08:167097
7098 request.load_flags = LOAD_NORMAL;
7099
danakj1fd259a02016-04-16 03:17:097100 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:167101 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]2262e3a2012-05-22 16:08:167102
7103 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:237104 MockWrite(
7105 "GET / HTTP/1.1\r\n"
7106 "Host: www.example.org\r\n"
7107 "Connection: keep-alive\r\n\r\n"),
[email protected]2262e3a2012-05-22 16:08:167108 };
7109
7110 MockRead data_reads1[] = {
7111 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
7112 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
7113 MockRead("Content-Length: 10\r\n\r\n"),
7114 MockRead(SYNCHRONOUS, ERR_FAILED),
7115 };
7116
7117 // After the challenge above, the transaction will be restarted using the
7118 // identity from the url (foo, baz) to answer the challenge.
7119 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:237120 MockWrite(
7121 "GET / HTTP/1.1\r\n"
7122 "Host: www.example.org\r\n"
7123 "Connection: keep-alive\r\n"
7124 "Authorization: Basic Zm9vOmJheg==\r\n\r\n"),
[email protected]2262e3a2012-05-22 16:08:167125 };
7126
7127 MockRead data_reads2[] = {
7128 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
7129 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
7130 MockRead("Content-Length: 10\r\n\r\n"),
7131 MockRead(SYNCHRONOUS, ERR_FAILED),
7132 };
7133
7134 // After the challenge above, the transaction will be restarted using the
7135 // identity supplied by the user (foo, bar) to answer the challenge.
7136 MockWrite data_writes3[] = {
bncce36dca22015-04-21 22:11:237137 MockWrite(
7138 "GET / HTTP/1.1\r\n"
7139 "Host: www.example.org\r\n"
7140 "Connection: keep-alive\r\n"
7141 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]2262e3a2012-05-22 16:08:167142 };
7143
7144 MockRead data_reads3[] = {
7145 MockRead("HTTP/1.0 200 OK\r\n"),
7146 MockRead("Content-Length: 100\r\n\r\n"),
7147 MockRead(SYNCHRONOUS, OK),
7148 };
7149
7150 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
7151 data_writes1, arraysize(data_writes1));
7152 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
7153 data_writes2, arraysize(data_writes2));
7154 StaticSocketDataProvider data3(data_reads3, arraysize(data_reads3),
7155 data_writes3, arraysize(data_writes3));
[email protected]bb88e1d32013-05-03 23:11:077156 session_deps_.socket_factory->AddSocketDataProvider(&data1);
7157 session_deps_.socket_factory->AddSocketDataProvider(&data2);
7158 session_deps_.socket_factory->AddSocketDataProvider(&data3);
[email protected]2262e3a2012-05-22 16:08:167159
7160 TestCompletionCallback callback1;
7161
tfarina42834112016-09-22 13:38:207162 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:017163 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2262e3a2012-05-22 16:08:167164
7165 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:017166 EXPECT_THAT(rv, IsOk());
[email protected]2262e3a2012-05-22 16:08:167167
bnc691fda62016-08-12 00:43:167168 EXPECT_TRUE(trans.IsReadyToRestartForAuth());
[email protected]2262e3a2012-05-22 16:08:167169 TestCompletionCallback callback2;
bnc691fda62016-08-12 00:43:167170 rv = trans.RestartWithAuth(AuthCredentials(), callback2.callback());
robpercival214763f2016-07-01 23:27:017171 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2262e3a2012-05-22 16:08:167172 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:017173 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:167174 EXPECT_FALSE(trans.IsReadyToRestartForAuth());
[email protected]2262e3a2012-05-22 16:08:167175
bnc691fda62016-08-12 00:43:167176 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:527177 ASSERT_TRUE(response);
[email protected]2262e3a2012-05-22 16:08:167178 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
7179
7180 TestCompletionCallback callback3;
bnc691fda62016-08-12 00:43:167181 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar), callback3.callback());
robpercival214763f2016-07-01 23:27:017182 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2262e3a2012-05-22 16:08:167183 rv = callback3.WaitForResult();
robpercival214763f2016-07-01 23:27:017184 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:167185 EXPECT_FALSE(trans.IsReadyToRestartForAuth());
[email protected]2262e3a2012-05-22 16:08:167186
bnc691fda62016-08-12 00:43:167187 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:527188 ASSERT_TRUE(response);
[email protected]2262e3a2012-05-22 16:08:167189
7190 // There is no challenge info, since the identity worked.
wezca1070932016-05-26 20:30:527191 EXPECT_FALSE(response->auth_challenge);
[email protected]2262e3a2012-05-22 16:08:167192
7193 EXPECT_EQ(100, response->headers->GetContentLength());
7194
[email protected]ea9dc9a2009-09-05 00:43:327195 // Empty the current queue.
fdoray92e35a72016-06-10 15:54:557196 base::RunLoop().RunUntilIdle();
[email protected]ea9dc9a2009-09-05 00:43:327197}
7198
[email protected]2217aa22013-10-11 03:03:547199
7200// Test the request-challenge-retry sequence for basic auth when there is a
7201// correct identity in the URL, but its use is being suppressed. The identity
7202// from the URL should never be used.
bncd16676a2016-07-20 16:23:017203TEST_F(HttpNetworkTransactionTest, AuthIdentityInURLSuppressed) {
[email protected]2217aa22013-10-11 03:03:547204 HttpRequestInfo request;
7205 request.method = "GET";
bncce36dca22015-04-21 22:11:237206 request.url = GURL("http://foo:[email protected]/");
[email protected]2217aa22013-10-11 03:03:547207 request.load_flags = LOAD_DO_NOT_USE_EMBEDDED_IDENTITY;
7208
danakj1fd259a02016-04-16 03:17:097209 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:167210 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]2217aa22013-10-11 03:03:547211
7212 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:237213 MockWrite(
7214 "GET / HTTP/1.1\r\n"
7215 "Host: www.example.org\r\n"
7216 "Connection: keep-alive\r\n\r\n"),
[email protected]2217aa22013-10-11 03:03:547217 };
7218
7219 MockRead data_reads1[] = {
7220 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
7221 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
7222 MockRead("Content-Length: 10\r\n\r\n"),
7223 MockRead(SYNCHRONOUS, ERR_FAILED),
7224 };
7225
7226 // After the challenge above, the transaction will be restarted using the
7227 // identity supplied by the user, not the one in the URL, to answer the
7228 // challenge.
7229 MockWrite data_writes3[] = {
bncce36dca22015-04-21 22:11:237230 MockWrite(
7231 "GET / HTTP/1.1\r\n"
7232 "Host: www.example.org\r\n"
7233 "Connection: keep-alive\r\n"
7234 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]2217aa22013-10-11 03:03:547235 };
7236
7237 MockRead data_reads3[] = {
7238 MockRead("HTTP/1.0 200 OK\r\n"),
7239 MockRead("Content-Length: 100\r\n\r\n"),
7240 MockRead(SYNCHRONOUS, OK),
7241 };
7242
7243 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
7244 data_writes1, arraysize(data_writes1));
7245 StaticSocketDataProvider data3(data_reads3, arraysize(data_reads3),
7246 data_writes3, arraysize(data_writes3));
7247 session_deps_.socket_factory->AddSocketDataProvider(&data1);
7248 session_deps_.socket_factory->AddSocketDataProvider(&data3);
7249
7250 TestCompletionCallback callback1;
tfarina42834112016-09-22 13:38:207251 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:017252 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2217aa22013-10-11 03:03:547253 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:017254 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:167255 EXPECT_FALSE(trans.IsReadyToRestartForAuth());
[email protected]2217aa22013-10-11 03:03:547256
bnc691fda62016-08-12 00:43:167257 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:527258 ASSERT_TRUE(response);
[email protected]2217aa22013-10-11 03:03:547259 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
7260
7261 TestCompletionCallback callback3;
bnc691fda62016-08-12 00:43:167262 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar), callback3.callback());
robpercival214763f2016-07-01 23:27:017263 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2217aa22013-10-11 03:03:547264 rv = callback3.WaitForResult();
robpercival214763f2016-07-01 23:27:017265 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:167266 EXPECT_FALSE(trans.IsReadyToRestartForAuth());
[email protected]2217aa22013-10-11 03:03:547267
bnc691fda62016-08-12 00:43:167268 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:527269 ASSERT_TRUE(response);
[email protected]2217aa22013-10-11 03:03:547270
7271 // There is no challenge info, since the identity worked.
wezca1070932016-05-26 20:30:527272 EXPECT_FALSE(response->auth_challenge);
[email protected]2217aa22013-10-11 03:03:547273 EXPECT_EQ(100, response->headers->GetContentLength());
7274
7275 // Empty the current queue.
fdoray92e35a72016-06-10 15:54:557276 base::RunLoop().RunUntilIdle();
[email protected]2217aa22013-10-11 03:03:547277}
7278
[email protected]f9ee6b52008-11-08 06:46:237279// Test that previously tried username/passwords for a realm get re-used.
bncd16676a2016-07-20 16:23:017280TEST_F(HttpNetworkTransactionTest, BasicAuthCacheAndPreauth) {
danakj1fd259a02016-04-16 03:17:097281 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]f9ee6b52008-11-08 06:46:237282
7283 // Transaction 1: authenticate (foo, bar) on MyRealm1
7284 {
[email protected]1c773ea12009-04-28 19:58:427285 HttpRequestInfo request;
[email protected]f9ee6b52008-11-08 06:46:237286 request.method = "GET";
bncce36dca22015-04-21 22:11:237287 request.url = GURL("http://www.example.org/x/y/z");
[email protected]f9ee6b52008-11-08 06:46:237288
bnc691fda62016-08-12 00:43:167289 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:277290
[email protected]f9ee6b52008-11-08 06:46:237291 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:237292 MockWrite(
7293 "GET /x/y/z HTTP/1.1\r\n"
7294 "Host: www.example.org\r\n"
7295 "Connection: keep-alive\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:237296 };
7297
7298 MockRead data_reads1[] = {
7299 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
7300 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
7301 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067302 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]f9ee6b52008-11-08 06:46:237303 };
7304
7305 // Resend with authorization (username=foo, password=bar)
7306 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:237307 MockWrite(
7308 "GET /x/y/z HTTP/1.1\r\n"
7309 "Host: www.example.org\r\n"
7310 "Connection: keep-alive\r\n"
7311 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:237312 };
7313
7314 // Sever accepts the authorization.
7315 MockRead data_reads2[] = {
7316 MockRead("HTTP/1.0 200 OK\r\n"),
7317 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067318 MockRead(SYNCHRONOUS, OK),
[email protected]f9ee6b52008-11-08 06:46:237319 };
7320
[email protected]31a2bfe2010-02-09 08:03:397321 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
7322 data_writes1, arraysize(data_writes1));
7323 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
7324 data_writes2, arraysize(data_writes2));
[email protected]bb88e1d32013-05-03 23:11:077325 session_deps_.socket_factory->AddSocketDataProvider(&data1);
7326 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]f9ee6b52008-11-08 06:46:237327
[email protected]49639fa2011-12-20 23:22:417328 TestCompletionCallback callback1;
[email protected]f9ee6b52008-11-08 06:46:237329
tfarina42834112016-09-22 13:38:207330 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:017331 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]f9ee6b52008-11-08 06:46:237332
7333 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:017334 EXPECT_THAT(rv, IsOk());
[email protected]f9ee6b52008-11-08 06:46:237335
bnc691fda62016-08-12 00:43:167336 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:527337 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:047338 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]f9ee6b52008-11-08 06:46:237339
[email protected]49639fa2011-12-20 23:22:417340 TestCompletionCallback callback2;
[email protected]f9ee6b52008-11-08 06:46:237341
bnc691fda62016-08-12 00:43:167342 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar),
7343 callback2.callback());
robpercival214763f2016-07-01 23:27:017344 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]f9ee6b52008-11-08 06:46:237345
7346 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:017347 EXPECT_THAT(rv, IsOk());
[email protected]f9ee6b52008-11-08 06:46:237348
bnc691fda62016-08-12 00:43:167349 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:527350 ASSERT_TRUE(response);
7351 EXPECT_FALSE(response->auth_challenge);
[email protected]f9ee6b52008-11-08 06:46:237352 EXPECT_EQ(100, response->headers->GetContentLength());
7353 }
7354
7355 // ------------------------------------------------------------------------
7356
7357 // Transaction 2: authenticate (foo2, bar2) on MyRealm2
7358 {
[email protected]1c773ea12009-04-28 19:58:427359 HttpRequestInfo request;
[email protected]f9ee6b52008-11-08 06:46:237360 request.method = "GET";
7361 // Note that Transaction 1 was at /x/y/z, so this is in the same
7362 // protection space as MyRealm1.
bncce36dca22015-04-21 22:11:237363 request.url = GURL("http://www.example.org/x/y/a/b");
[email protected]f9ee6b52008-11-08 06:46:237364
bnc691fda62016-08-12 00:43:167365 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:277366
[email protected]f9ee6b52008-11-08 06:46:237367 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:237368 MockWrite(
7369 "GET /x/y/a/b HTTP/1.1\r\n"
7370 "Host: www.example.org\r\n"
7371 "Connection: keep-alive\r\n"
7372 // Send preemptive authorization for MyRealm1
7373 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:237374 };
7375
7376 // The server didn't like the preemptive authorization, and
7377 // challenges us for a different realm (MyRealm2).
7378 MockRead data_reads1[] = {
7379 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
7380 MockRead("WWW-Authenticate: Basic realm=\"MyRealm2\"\r\n"),
7381 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067382 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]f9ee6b52008-11-08 06:46:237383 };
7384
7385 // Resend with authorization for MyRealm2 (username=foo2, password=bar2)
7386 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:237387 MockWrite(
7388 "GET /x/y/a/b HTTP/1.1\r\n"
7389 "Host: www.example.org\r\n"
7390 "Connection: keep-alive\r\n"
7391 "Authorization: Basic Zm9vMjpiYXIy\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:237392 };
7393
7394 // Sever accepts the authorization.
7395 MockRead data_reads2[] = {
7396 MockRead("HTTP/1.0 200 OK\r\n"),
7397 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067398 MockRead(SYNCHRONOUS, OK),
[email protected]f9ee6b52008-11-08 06:46:237399 };
7400
[email protected]31a2bfe2010-02-09 08:03:397401 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
7402 data_writes1, arraysize(data_writes1));
7403 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
7404 data_writes2, arraysize(data_writes2));
[email protected]bb88e1d32013-05-03 23:11:077405 session_deps_.socket_factory->AddSocketDataProvider(&data1);
7406 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]f9ee6b52008-11-08 06:46:237407
[email protected]49639fa2011-12-20 23:22:417408 TestCompletionCallback callback1;
[email protected]f9ee6b52008-11-08 06:46:237409
tfarina42834112016-09-22 13:38:207410 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:017411 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]f9ee6b52008-11-08 06:46:237412
7413 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:017414 EXPECT_THAT(rv, IsOk());
[email protected]f9ee6b52008-11-08 06:46:237415
bnc691fda62016-08-12 00:43:167416 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:527417 ASSERT_TRUE(response);
7418 ASSERT_TRUE(response->auth_challenge);
[email protected]79cb5c12011-09-12 13:12:047419 EXPECT_FALSE(response->auth_challenge->is_proxy);
asanka098c0092016-06-16 20:18:437420 EXPECT_EQ("http://www.example.org",
7421 response->auth_challenge->challenger.Serialize());
[email protected]79cb5c12011-09-12 13:12:047422 EXPECT_EQ("MyRealm2", response->auth_challenge->realm);
aberentbba302d2015-12-03 10:20:197423 EXPECT_EQ(kBasicAuthScheme, response->auth_challenge->scheme);
[email protected]f9ee6b52008-11-08 06:46:237424
[email protected]49639fa2011-12-20 23:22:417425 TestCompletionCallback callback2;
[email protected]f9ee6b52008-11-08 06:46:237426
bnc691fda62016-08-12 00:43:167427 rv = trans.RestartWithAuth(AuthCredentials(kFoo2, kBar2),
7428 callback2.callback());
robpercival214763f2016-07-01 23:27:017429 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]f9ee6b52008-11-08 06:46:237430
7431 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:017432 EXPECT_THAT(rv, IsOk());
[email protected]f9ee6b52008-11-08 06:46:237433
bnc691fda62016-08-12 00:43:167434 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:527435 ASSERT_TRUE(response);
7436 EXPECT_FALSE(response->auth_challenge);
[email protected]f9ee6b52008-11-08 06:46:237437 EXPECT_EQ(100, response->headers->GetContentLength());
7438 }
7439
7440 // ------------------------------------------------------------------------
7441
7442 // Transaction 3: Resend a request in MyRealm's protection space --
7443 // succeed with preemptive authorization.
7444 {
[email protected]1c773ea12009-04-28 19:58:427445 HttpRequestInfo request;
[email protected]f9ee6b52008-11-08 06:46:237446 request.method = "GET";
bncce36dca22015-04-21 22:11:237447 request.url = GURL("http://www.example.org/x/y/z2");
[email protected]f9ee6b52008-11-08 06:46:237448
bnc691fda62016-08-12 00:43:167449 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:277450
[email protected]f9ee6b52008-11-08 06:46:237451 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:237452 MockWrite(
7453 "GET /x/y/z2 HTTP/1.1\r\n"
7454 "Host: www.example.org\r\n"
7455 "Connection: keep-alive\r\n"
7456 // The authorization for MyRealm1 gets sent preemptively
7457 // (since the url is in the same protection space)
7458 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:237459 };
7460
7461 // Sever accepts the preemptive authorization
7462 MockRead data_reads1[] = {
7463 MockRead("HTTP/1.0 200 OK\r\n"),
7464 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067465 MockRead(SYNCHRONOUS, OK),
[email protected]f9ee6b52008-11-08 06:46:237466 };
7467
[email protected]31a2bfe2010-02-09 08:03:397468 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
7469 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:077470 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]f9ee6b52008-11-08 06:46:237471
[email protected]49639fa2011-12-20 23:22:417472 TestCompletionCallback callback1;
[email protected]f9ee6b52008-11-08 06:46:237473
tfarina42834112016-09-22 13:38:207474 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:017475 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]f9ee6b52008-11-08 06:46:237476
7477 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:017478 EXPECT_THAT(rv, IsOk());
[email protected]f9ee6b52008-11-08 06:46:237479
bnc691fda62016-08-12 00:43:167480 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:527481 ASSERT_TRUE(response);
[email protected]f9ee6b52008-11-08 06:46:237482
wezca1070932016-05-26 20:30:527483 EXPECT_FALSE(response->auth_challenge);
[email protected]f9ee6b52008-11-08 06:46:237484 EXPECT_EQ(100, response->headers->GetContentLength());
7485 }
7486
7487 // ------------------------------------------------------------------------
7488
7489 // Transaction 4: request another URL in MyRealm (however the
7490 // url is not known to belong to the protection space, so no pre-auth).
7491 {
[email protected]1c773ea12009-04-28 19:58:427492 HttpRequestInfo request;
[email protected]f9ee6b52008-11-08 06:46:237493 request.method = "GET";
bncce36dca22015-04-21 22:11:237494 request.url = GURL("http://www.example.org/x/1");
[email protected]f9ee6b52008-11-08 06:46:237495
bnc691fda62016-08-12 00:43:167496 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:277497
[email protected]f9ee6b52008-11-08 06:46:237498 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:237499 MockWrite(
7500 "GET /x/1 HTTP/1.1\r\n"
7501 "Host: www.example.org\r\n"
7502 "Connection: keep-alive\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:237503 };
7504
7505 MockRead data_reads1[] = {
7506 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
7507 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
7508 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067509 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]f9ee6b52008-11-08 06:46:237510 };
7511
7512 // Resend with authorization from MyRealm's cache.
7513 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:237514 MockWrite(
7515 "GET /x/1 HTTP/1.1\r\n"
7516 "Host: www.example.org\r\n"
7517 "Connection: keep-alive\r\n"
7518 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:237519 };
7520
7521 // Sever accepts the authorization.
7522 MockRead data_reads2[] = {
7523 MockRead("HTTP/1.0 200 OK\r\n"),
7524 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067525 MockRead(SYNCHRONOUS, OK),
[email protected]f9ee6b52008-11-08 06:46:237526 };
7527
[email protected]31a2bfe2010-02-09 08:03:397528 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
7529 data_writes1, arraysize(data_writes1));
7530 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
7531 data_writes2, arraysize(data_writes2));
[email protected]bb88e1d32013-05-03 23:11:077532 session_deps_.socket_factory->AddSocketDataProvider(&data1);
7533 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]f9ee6b52008-11-08 06:46:237534
[email protected]49639fa2011-12-20 23:22:417535 TestCompletionCallback callback1;
[email protected]f9ee6b52008-11-08 06:46:237536
tfarina42834112016-09-22 13:38:207537 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:017538 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]f9ee6b52008-11-08 06:46:237539
7540 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:017541 EXPECT_THAT(rv, IsOk());
[email protected]f9ee6b52008-11-08 06:46:237542
bnc691fda62016-08-12 00:43:167543 EXPECT_TRUE(trans.IsReadyToRestartForAuth());
[email protected]49639fa2011-12-20 23:22:417544 TestCompletionCallback callback2;
bnc691fda62016-08-12 00:43:167545 rv = trans.RestartWithAuth(AuthCredentials(), callback2.callback());
robpercival214763f2016-07-01 23:27:017546 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]0757e7702009-03-27 04:00:227547 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:017548 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:167549 EXPECT_FALSE(trans.IsReadyToRestartForAuth());
[email protected]0757e7702009-03-27 04:00:227550
bnc691fda62016-08-12 00:43:167551 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:527552 ASSERT_TRUE(response);
7553 EXPECT_FALSE(response->auth_challenge);
[email protected]f9ee6b52008-11-08 06:46:237554 EXPECT_EQ(100, response->headers->GetContentLength());
7555 }
7556
7557 // ------------------------------------------------------------------------
7558
7559 // Transaction 5: request a URL in MyRealm, but the server rejects the
7560 // cached identity. Should invalidate and re-prompt.
7561 {
[email protected]1c773ea12009-04-28 19:58:427562 HttpRequestInfo request;
[email protected]f9ee6b52008-11-08 06:46:237563 request.method = "GET";
bncce36dca22015-04-21 22:11:237564 request.url = GURL("http://www.example.org/p/q/t");
[email protected]f9ee6b52008-11-08 06:46:237565
bnc691fda62016-08-12 00:43:167566 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:277567
[email protected]f9ee6b52008-11-08 06:46:237568 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:237569 MockWrite(
7570 "GET /p/q/t HTTP/1.1\r\n"
7571 "Host: www.example.org\r\n"
7572 "Connection: keep-alive\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:237573 };
7574
7575 MockRead data_reads1[] = {
7576 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
7577 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
7578 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067579 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]f9ee6b52008-11-08 06:46:237580 };
7581
7582 // Resend with authorization from cache for MyRealm.
7583 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:237584 MockWrite(
7585 "GET /p/q/t HTTP/1.1\r\n"
7586 "Host: www.example.org\r\n"
7587 "Connection: keep-alive\r\n"
7588 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:237589 };
7590
7591 // Sever rejects the authorization.
7592 MockRead data_reads2[] = {
7593 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
7594 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
7595 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067596 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]f9ee6b52008-11-08 06:46:237597 };
7598
7599 // At this point we should prompt for new credentials for MyRealm.
7600 // Restart with username=foo3, password=foo4.
7601 MockWrite data_writes3[] = {
bncce36dca22015-04-21 22:11:237602 MockWrite(
7603 "GET /p/q/t HTTP/1.1\r\n"
7604 "Host: www.example.org\r\n"
7605 "Connection: keep-alive\r\n"
7606 "Authorization: Basic Zm9vMzpiYXIz\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:237607 };
7608
7609 // Sever accepts the authorization.
7610 MockRead data_reads3[] = {
7611 MockRead("HTTP/1.0 200 OK\r\n"),
7612 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067613 MockRead(SYNCHRONOUS, OK),
[email protected]f9ee6b52008-11-08 06:46:237614 };
7615
[email protected]31a2bfe2010-02-09 08:03:397616 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
7617 data_writes1, arraysize(data_writes1));
7618 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
7619 data_writes2, arraysize(data_writes2));
7620 StaticSocketDataProvider data3(data_reads3, arraysize(data_reads3),
7621 data_writes3, arraysize(data_writes3));
[email protected]bb88e1d32013-05-03 23:11:077622 session_deps_.socket_factory->AddSocketDataProvider(&data1);
7623 session_deps_.socket_factory->AddSocketDataProvider(&data2);
7624 session_deps_.socket_factory->AddSocketDataProvider(&data3);
[email protected]f9ee6b52008-11-08 06:46:237625
[email protected]49639fa2011-12-20 23:22:417626 TestCompletionCallback callback1;
[email protected]f9ee6b52008-11-08 06:46:237627
tfarina42834112016-09-22 13:38:207628 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:017629 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]f9ee6b52008-11-08 06:46:237630
7631 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:017632 EXPECT_THAT(rv, IsOk());
[email protected]f9ee6b52008-11-08 06:46:237633
bnc691fda62016-08-12 00:43:167634 EXPECT_TRUE(trans.IsReadyToRestartForAuth());
[email protected]49639fa2011-12-20 23:22:417635 TestCompletionCallback callback2;
bnc691fda62016-08-12 00:43:167636 rv = trans.RestartWithAuth(AuthCredentials(), callback2.callback());
robpercival214763f2016-07-01 23:27:017637 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]0757e7702009-03-27 04:00:227638 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:017639 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:167640 EXPECT_FALSE(trans.IsReadyToRestartForAuth());
[email protected]0757e7702009-03-27 04:00:227641
bnc691fda62016-08-12 00:43:167642 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:527643 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:047644 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]f9ee6b52008-11-08 06:46:237645
[email protected]49639fa2011-12-20 23:22:417646 TestCompletionCallback callback3;
[email protected]f9ee6b52008-11-08 06:46:237647
bnc691fda62016-08-12 00:43:167648 rv = trans.RestartWithAuth(AuthCredentials(kFoo3, kBar3),
7649 callback3.callback());
robpercival214763f2016-07-01 23:27:017650 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]f9ee6b52008-11-08 06:46:237651
[email protected]0757e7702009-03-27 04:00:227652 rv = callback3.WaitForResult();
robpercival214763f2016-07-01 23:27:017653 EXPECT_THAT(rv, IsOk());
[email protected]f9ee6b52008-11-08 06:46:237654
bnc691fda62016-08-12 00:43:167655 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:527656 ASSERT_TRUE(response);
7657 EXPECT_FALSE(response->auth_challenge);
[email protected]f9ee6b52008-11-08 06:46:237658 EXPECT_EQ(100, response->headers->GetContentLength());
7659 }
7660}
[email protected]89ceba9a2009-03-21 03:46:067661
[email protected]3c32c5f2010-05-18 15:18:127662// Tests that nonce count increments when multiple auth attempts
7663// are started with the same nonce.
bncd16676a2016-07-20 16:23:017664TEST_F(HttpNetworkTransactionTest, DigestPreAuthNonceCount) {
[email protected]54fea2562010-11-17 14:40:447665 HttpAuthHandlerDigest::Factory* digest_factory =
7666 new HttpAuthHandlerDigest::Factory();
7667 HttpAuthHandlerDigest::FixedNonceGenerator* nonce_generator =
7668 new HttpAuthHandlerDigest::FixedNonceGenerator("0123456789abcdef");
7669 digest_factory->set_nonce_generator(nonce_generator);
[email protected]bb88e1d32013-05-03 23:11:077670 session_deps_.http_auth_handler_factory.reset(digest_factory);
danakj1fd259a02016-04-16 03:17:097671 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]3c32c5f2010-05-18 15:18:127672
7673 // Transaction 1: authenticate (foo, bar) on MyRealm1
7674 {
[email protected]3c32c5f2010-05-18 15:18:127675 HttpRequestInfo request;
7676 request.method = "GET";
bncce36dca22015-04-21 22:11:237677 request.url = GURL("http://www.example.org/x/y/z");
[email protected]3c32c5f2010-05-18 15:18:127678
bnc691fda62016-08-12 00:43:167679 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:277680
[email protected]3c32c5f2010-05-18 15:18:127681 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:237682 MockWrite(
7683 "GET /x/y/z HTTP/1.1\r\n"
7684 "Host: www.example.org\r\n"
7685 "Connection: keep-alive\r\n\r\n"),
[email protected]3c32c5f2010-05-18 15:18:127686 };
7687
7688 MockRead data_reads1[] = {
7689 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
7690 MockRead("WWW-Authenticate: Digest realm=\"digestive\", nonce=\"OU812\", "
7691 "algorithm=MD5, qop=\"auth\"\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067692 MockRead(SYNCHRONOUS, OK),
[email protected]3c32c5f2010-05-18 15:18:127693 };
7694
7695 // Resend with authorization (username=foo, password=bar)
7696 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:237697 MockWrite(
7698 "GET /x/y/z HTTP/1.1\r\n"
7699 "Host: www.example.org\r\n"
7700 "Connection: keep-alive\r\n"
7701 "Authorization: Digest username=\"foo\", realm=\"digestive\", "
7702 "nonce=\"OU812\", uri=\"/x/y/z\", algorithm=MD5, "
7703 "response=\"03ffbcd30add722589c1de345d7a927f\", qop=auth, "
7704 "nc=00000001, cnonce=\"0123456789abcdef\"\r\n\r\n"),
[email protected]3c32c5f2010-05-18 15:18:127705 };
7706
7707 // Sever accepts the authorization.
7708 MockRead data_reads2[] = {
zmo9528c9f42015-08-04 22:12:087709 MockRead("HTTP/1.0 200 OK\r\n"),
7710 MockRead(SYNCHRONOUS, OK),
[email protected]3c32c5f2010-05-18 15:18:127711 };
7712
7713 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
7714 data_writes1, arraysize(data_writes1));
7715 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
7716 data_writes2, arraysize(data_writes2));
[email protected]bb88e1d32013-05-03 23:11:077717 session_deps_.socket_factory->AddSocketDataProvider(&data1);
7718 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]3c32c5f2010-05-18 15:18:127719
[email protected]49639fa2011-12-20 23:22:417720 TestCompletionCallback callback1;
[email protected]3c32c5f2010-05-18 15:18:127721
tfarina42834112016-09-22 13:38:207722 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:017723 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]3c32c5f2010-05-18 15:18:127724
7725 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:017726 EXPECT_THAT(rv, IsOk());
[email protected]3c32c5f2010-05-18 15:18:127727
bnc691fda62016-08-12 00:43:167728 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:527729 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:047730 EXPECT_TRUE(CheckDigestServerAuth(response->auth_challenge.get()));
[email protected]3c32c5f2010-05-18 15:18:127731
[email protected]49639fa2011-12-20 23:22:417732 TestCompletionCallback callback2;
[email protected]3c32c5f2010-05-18 15:18:127733
bnc691fda62016-08-12 00:43:167734 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar),
7735 callback2.callback());
robpercival214763f2016-07-01 23:27:017736 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]3c32c5f2010-05-18 15:18:127737
7738 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:017739 EXPECT_THAT(rv, IsOk());
[email protected]3c32c5f2010-05-18 15:18:127740
bnc691fda62016-08-12 00:43:167741 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:527742 ASSERT_TRUE(response);
7743 EXPECT_FALSE(response->auth_challenge);
[email protected]3c32c5f2010-05-18 15:18:127744 }
7745
7746 // ------------------------------------------------------------------------
7747
7748 // Transaction 2: Request another resource in digestive's protection space.
7749 // This will preemptively add an Authorization header which should have an
7750 // "nc" value of 2 (as compared to 1 in the first use.
7751 {
[email protected]3c32c5f2010-05-18 15:18:127752 HttpRequestInfo request;
7753 request.method = "GET";
7754 // Note that Transaction 1 was at /x/y/z, so this is in the same
7755 // protection space as digest.
bncce36dca22015-04-21 22:11:237756 request.url = GURL("http://www.example.org/x/y/a/b");
[email protected]3c32c5f2010-05-18 15:18:127757
bnc691fda62016-08-12 00:43:167758 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:277759
[email protected]3c32c5f2010-05-18 15:18:127760 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:237761 MockWrite(
7762 "GET /x/y/a/b HTTP/1.1\r\n"
7763 "Host: www.example.org\r\n"
7764 "Connection: keep-alive\r\n"
7765 "Authorization: Digest username=\"foo\", realm=\"digestive\", "
7766 "nonce=\"OU812\", uri=\"/x/y/a/b\", algorithm=MD5, "
7767 "response=\"d6f9a2c07d1c5df7b89379dca1269b35\", qop=auth, "
7768 "nc=00000002, cnonce=\"0123456789abcdef\"\r\n\r\n"),
[email protected]3c32c5f2010-05-18 15:18:127769 };
7770
7771 // Sever accepts the authorization.
7772 MockRead data_reads1[] = {
7773 MockRead("HTTP/1.0 200 OK\r\n"),
7774 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067775 MockRead(SYNCHRONOUS, OK),
[email protected]3c32c5f2010-05-18 15:18:127776 };
7777
7778 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
7779 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:077780 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]3c32c5f2010-05-18 15:18:127781
[email protected]49639fa2011-12-20 23:22:417782 TestCompletionCallback callback1;
[email protected]3c32c5f2010-05-18 15:18:127783
tfarina42834112016-09-22 13:38:207784 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:017785 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]3c32c5f2010-05-18 15:18:127786
7787 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:017788 EXPECT_THAT(rv, IsOk());
[email protected]3c32c5f2010-05-18 15:18:127789
bnc691fda62016-08-12 00:43:167790 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:527791 ASSERT_TRUE(response);
7792 EXPECT_FALSE(response->auth_challenge);
[email protected]3c32c5f2010-05-18 15:18:127793 }
7794}
7795
[email protected]89ceba9a2009-03-21 03:46:067796// Test the ResetStateForRestart() private method.
bncd16676a2016-07-20 16:23:017797TEST_F(HttpNetworkTransactionTest, ResetStateForRestart) {
[email protected]89ceba9a2009-03-21 03:46:067798 // Create a transaction (the dependencies aren't important).
danakj1fd259a02016-04-16 03:17:097799 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:167800 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]89ceba9a2009-03-21 03:46:067801
7802 // Setup some state (which we expect ResetStateForRestart() will clear).
bnc691fda62016-08-12 00:43:167803 trans.read_buf_ = new IOBuffer(15);
7804 trans.read_buf_len_ = 15;
7805 trans.request_headers_.SetHeader("Authorization", "NTLM");
[email protected]89ceba9a2009-03-21 03:46:067806
7807 // Setup state in response_
bnc691fda62016-08-12 00:43:167808 HttpResponseInfo* response = &trans.response_;
[email protected]0877e3d2009-10-17 22:29:577809 response->auth_challenge = new AuthChallengeInfo();
[email protected]70d66502011-09-23 00:55:087810 response->ssl_info.cert_status = static_cast<CertStatus>(-1); // Nonsensical.
[email protected]0877e3d2009-10-17 22:29:577811 response->response_time = base::Time::Now();
7812 response->was_cached = true; // (Wouldn't ever actually be true...)
[email protected]89ceba9a2009-03-21 03:46:067813
7814 { // Setup state for response_.vary_data
7815 HttpRequestInfo request;
7816 std::string temp("HTTP/1.1 200 OK\nVary: foo, bar\n\n");
7817 std::replace(temp.begin(), temp.end(), '\n', '\0');
[email protected]ad8e04a2010-11-01 04:16:277818 scoped_refptr<HttpResponseHeaders> headers(new HttpResponseHeaders(temp));
[email protected]8c76ae22010-04-20 22:15:437819 request.extra_headers.SetHeader("Foo", "1");
7820 request.extra_headers.SetHeader("bar", "23");
[email protected]90499482013-06-01 00:39:507821 EXPECT_TRUE(response->vary_data.Init(request, *headers.get()));
[email protected]89ceba9a2009-03-21 03:46:067822 }
7823
7824 // Cause the above state to be reset.
bnc691fda62016-08-12 00:43:167825 trans.ResetStateForRestart();
[email protected]89ceba9a2009-03-21 03:46:067826
7827 // Verify that the state that needed to be reset, has been reset.
bnc691fda62016-08-12 00:43:167828 EXPECT_FALSE(trans.read_buf_);
7829 EXPECT_EQ(0, trans.read_buf_len_);
7830 EXPECT_TRUE(trans.request_headers_.IsEmpty());
wezca1070932016-05-26 20:30:527831 EXPECT_FALSE(response->auth_challenge);
7832 EXPECT_FALSE(response->headers);
[email protected]34f40942010-10-04 00:34:047833 EXPECT_FALSE(response->was_cached);
[email protected]70d66502011-09-23 00:55:087834 EXPECT_EQ(0U, response->ssl_info.cert_status);
[email protected]0877e3d2009-10-17 22:29:577835 EXPECT_FALSE(response->vary_data.is_valid());
[email protected]89ceba9a2009-03-21 03:46:067836}
7837
[email protected]bacff652009-03-31 17:50:337838// Test HTTPS connections to a site with a bad certificate
bncd16676a2016-07-20 16:23:017839TEST_F(HttpNetworkTransactionTest, HTTPSBadCertificate) {
[email protected]bacff652009-03-31 17:50:337840 HttpRequestInfo request;
7841 request.method = "GET";
bncce36dca22015-04-21 22:11:237842 request.url = GURL("https://www.example.org/");
[email protected]bacff652009-03-31 17:50:337843
danakj1fd259a02016-04-16 03:17:097844 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:167845 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:277846
[email protected]bacff652009-03-31 17:50:337847 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:237848 MockWrite(
7849 "GET / HTTP/1.1\r\n"
7850 "Host: www.example.org\r\n"
7851 "Connection: keep-alive\r\n\r\n"),
[email protected]bacff652009-03-31 17:50:337852 };
7853
7854 MockRead data_reads[] = {
7855 MockRead("HTTP/1.0 200 OK\r\n"),
7856 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
7857 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067858 MockRead(SYNCHRONOUS, OK),
[email protected]bacff652009-03-31 17:50:337859 };
7860
[email protected]5ecc992a42009-11-11 01:41:597861 StaticSocketDataProvider ssl_bad_certificate;
[email protected]31a2bfe2010-02-09 08:03:397862 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
7863 data_writes, arraysize(data_writes));
[email protected]8ddf8322012-02-23 18:08:067864 SSLSocketDataProvider ssl_bad(ASYNC, ERR_CERT_AUTHORITY_INVALID);
7865 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bacff652009-03-31 17:50:337866
[email protected]bb88e1d32013-05-03 23:11:077867 session_deps_.socket_factory->AddSocketDataProvider(&ssl_bad_certificate);
7868 session_deps_.socket_factory->AddSocketDataProvider(&data);
7869 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_bad);
7870 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]bacff652009-03-31 17:50:337871
[email protected]49639fa2011-12-20 23:22:417872 TestCompletionCallback callback;
[email protected]bacff652009-03-31 17:50:337873
tfarina42834112016-09-22 13:38:207874 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:017875 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]bacff652009-03-31 17:50:337876
7877 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:017878 EXPECT_THAT(rv, IsError(ERR_CERT_AUTHORITY_INVALID));
[email protected]bacff652009-03-31 17:50:337879
bnc691fda62016-08-12 00:43:167880 rv = trans.RestartIgnoringLastError(callback.callback());
robpercival214763f2016-07-01 23:27:017881 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]bacff652009-03-31 17:50:337882
7883 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:017884 EXPECT_THAT(rv, IsOk());
[email protected]bacff652009-03-31 17:50:337885
bnc691fda62016-08-12 00:43:167886 const HttpResponseInfo* response = trans.GetResponseInfo();
[email protected]bacff652009-03-31 17:50:337887
wezca1070932016-05-26 20:30:527888 ASSERT_TRUE(response);
[email protected]bacff652009-03-31 17:50:337889 EXPECT_EQ(100, response->headers->GetContentLength());
7890}
7891
7892// Test HTTPS connections to a site with a bad certificate, going through a
7893// proxy
bncd16676a2016-07-20 16:23:017894TEST_F(HttpNetworkTransactionTest, HTTPSBadCertificateViaProxy) {
rdsmith82957ad2015-09-16 19:42:037895 session_deps_.proxy_service = ProxyService::CreateFixed("myproxy:70");
[email protected]bacff652009-03-31 17:50:337896
7897 HttpRequestInfo request;
7898 request.method = "GET";
bncce36dca22015-04-21 22:11:237899 request.url = GURL("https://www.example.org/");
[email protected]bacff652009-03-31 17:50:337900
7901 MockWrite proxy_writes[] = {
rsleevidb16bb02015-11-12 23:47:177902 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
7903 "Host: www.example.org:443\r\n"
7904 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]bacff652009-03-31 17:50:337905 };
7906
7907 MockRead proxy_reads[] = {
7908 MockRead("HTTP/1.0 200 Connected\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067909 MockRead(SYNCHRONOUS, OK)
[email protected]bacff652009-03-31 17:50:337910 };
7911
7912 MockWrite data_writes[] = {
rsleevidb16bb02015-11-12 23:47:177913 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
7914 "Host: www.example.org:443\r\n"
7915 "Proxy-Connection: keep-alive\r\n\r\n"),
7916 MockWrite("GET / HTTP/1.1\r\n"
7917 "Host: www.example.org\r\n"
7918 "Connection: keep-alive\r\n\r\n"),
[email protected]bacff652009-03-31 17:50:337919 };
7920
7921 MockRead data_reads[] = {
7922 MockRead("HTTP/1.0 200 Connected\r\n\r\n"),
7923 MockRead("HTTP/1.0 200 OK\r\n"),
7924 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
7925 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067926 MockRead(SYNCHRONOUS, OK),
[email protected]bacff652009-03-31 17:50:337927 };
7928
[email protected]31a2bfe2010-02-09 08:03:397929 StaticSocketDataProvider ssl_bad_certificate(
7930 proxy_reads, arraysize(proxy_reads),
7931 proxy_writes, arraysize(proxy_writes));
7932 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
7933 data_writes, arraysize(data_writes));
[email protected]8ddf8322012-02-23 18:08:067934 SSLSocketDataProvider ssl_bad(ASYNC, ERR_CERT_AUTHORITY_INVALID);
7935 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bacff652009-03-31 17:50:337936
[email protected]bb88e1d32013-05-03 23:11:077937 session_deps_.socket_factory->AddSocketDataProvider(&ssl_bad_certificate);
7938 session_deps_.socket_factory->AddSocketDataProvider(&data);
7939 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_bad);
7940 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]bacff652009-03-31 17:50:337941
[email protected]49639fa2011-12-20 23:22:417942 TestCompletionCallback callback;
[email protected]bacff652009-03-31 17:50:337943
7944 for (int i = 0; i < 2; i++) {
[email protected]bb88e1d32013-05-03 23:11:077945 session_deps_.socket_factory->ResetNextMockIndexes();
[email protected]bacff652009-03-31 17:50:337946
danakj1fd259a02016-04-16 03:17:097947 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:167948 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]bacff652009-03-31 17:50:337949
tfarina42834112016-09-22 13:38:207950 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:017951 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]bacff652009-03-31 17:50:337952
7953 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:017954 EXPECT_THAT(rv, IsError(ERR_CERT_AUTHORITY_INVALID));
[email protected]bacff652009-03-31 17:50:337955
bnc691fda62016-08-12 00:43:167956 rv = trans.RestartIgnoringLastError(callback.callback());
robpercival214763f2016-07-01 23:27:017957 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]bacff652009-03-31 17:50:337958
7959 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:017960 EXPECT_THAT(rv, IsOk());
[email protected]bacff652009-03-31 17:50:337961
bnc691fda62016-08-12 00:43:167962 const HttpResponseInfo* response = trans.GetResponseInfo();
[email protected]bacff652009-03-31 17:50:337963
wezca1070932016-05-26 20:30:527964 ASSERT_TRUE(response);
[email protected]bacff652009-03-31 17:50:337965 EXPECT_EQ(100, response->headers->GetContentLength());
7966 }
7967}
7968
[email protected]2df19bb2010-08-25 20:13:467969
7970// Test HTTPS connections to a site, going through an HTTPS proxy
bncd16676a2016-07-20 16:23:017971TEST_F(HttpNetworkTransactionTest, HTTPSViaHttpsProxy) {
rdsmith82957ad2015-09-16 19:42:037972 session_deps_.proxy_service =
7973 ProxyService::CreateFixedFromPacResult("HTTPS proxy:70");
vishal.b62985ca92015-04-17 08:45:517974 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:077975 session_deps_.net_log = &net_log;
[email protected]2df19bb2010-08-25 20:13:467976
7977 HttpRequestInfo request;
7978 request.method = "GET";
bncce36dca22015-04-21 22:11:237979 request.url = GURL("https://www.example.org/");
[email protected]2df19bb2010-08-25 20:13:467980
7981 MockWrite data_writes[] = {
rsleevidb16bb02015-11-12 23:47:177982 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
7983 "Host: www.example.org:443\r\n"
7984 "Proxy-Connection: keep-alive\r\n\r\n"),
7985 MockWrite("GET / HTTP/1.1\r\n"
7986 "Host: www.example.org\r\n"
7987 "Connection: keep-alive\r\n\r\n"),
[email protected]2df19bb2010-08-25 20:13:467988 };
7989
7990 MockRead data_reads[] = {
7991 MockRead("HTTP/1.0 200 Connected\r\n\r\n"),
7992 MockRead("HTTP/1.1 200 OK\r\n"),
7993 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
7994 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067995 MockRead(SYNCHRONOUS, OK),
[email protected]2df19bb2010-08-25 20:13:467996 };
7997
7998 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
7999 data_writes, arraysize(data_writes));
[email protected]8ddf8322012-02-23 18:08:068000 SSLSocketDataProvider proxy_ssl(ASYNC, OK); // SSL to the proxy
8001 SSLSocketDataProvider tunnel_ssl(ASYNC, OK); // SSL through the tunnel
[email protected]2df19bb2010-08-25 20:13:468002
[email protected]bb88e1d32013-05-03 23:11:078003 session_deps_.socket_factory->AddSocketDataProvider(&data);
8004 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy_ssl);
8005 session_deps_.socket_factory->AddSSLSocketDataProvider(&tunnel_ssl);
[email protected]2df19bb2010-08-25 20:13:468006
[email protected]49639fa2011-12-20 23:22:418007 TestCompletionCallback callback;
[email protected]2df19bb2010-08-25 20:13:468008
danakj1fd259a02016-04-16 03:17:098009 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:168010 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]2df19bb2010-08-25 20:13:468011
tfarina42834112016-09-22 13:38:208012 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:018013 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2df19bb2010-08-25 20:13:468014
8015 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:018016 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:168017 const HttpResponseInfo* response = trans.GetResponseInfo();
[email protected]2df19bb2010-08-25 20:13:468018
wezca1070932016-05-26 20:30:528019 ASSERT_TRUE(response);
[email protected]2df19bb2010-08-25 20:13:468020
tbansal2ecbbc72016-10-06 17:15:478021 EXPECT_TRUE(response->proxy_server.is_https());
[email protected]2df19bb2010-08-25 20:13:468022 EXPECT_TRUE(response->headers->IsKeepAlive());
8023 EXPECT_EQ(200, response->headers->response_code());
8024 EXPECT_EQ(100, response->headers->GetContentLength());
8025 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
[email protected]029c83b62013-01-24 05:28:208026
8027 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:168028 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]029c83b62013-01-24 05:28:208029 TestLoadTimingNotReusedWithPac(load_timing_info,
8030 CONNECT_TIMING_HAS_SSL_TIMES);
[email protected]2df19bb2010-08-25 20:13:468031}
8032
[email protected]511f6f52010-12-17 03:58:298033// Test an HTTPS Proxy's ability to redirect a CONNECT request
bncd16676a2016-07-20 16:23:018034TEST_F(HttpNetworkTransactionTest, RedirectOfHttpsConnectViaHttpsProxy) {
rdsmith82957ad2015-09-16 19:42:038035 session_deps_.proxy_service =
8036 ProxyService::CreateFixedFromPacResult("HTTPS proxy:70");
vishal.b62985ca92015-04-17 08:45:518037 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:078038 session_deps_.net_log = &net_log;
[email protected]511f6f52010-12-17 03:58:298039
8040 HttpRequestInfo request;
8041 request.method = "GET";
bncce36dca22015-04-21 22:11:238042 request.url = GURL("https://www.example.org/");
[email protected]511f6f52010-12-17 03:58:298043
8044 MockWrite data_writes[] = {
rsleevidb16bb02015-11-12 23:47:178045 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
8046 "Host: www.example.org:443\r\n"
8047 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]511f6f52010-12-17 03:58:298048 };
8049
8050 MockRead data_reads[] = {
8051 MockRead("HTTP/1.1 302 Redirect\r\n"),
8052 MockRead("Location: http://login.example.com/\r\n"),
8053 MockRead("Content-Length: 0\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:068054 MockRead(SYNCHRONOUS, OK),
[email protected]511f6f52010-12-17 03:58:298055 };
8056
8057 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
8058 data_writes, arraysize(data_writes));
[email protected]8ddf8322012-02-23 18:08:068059 SSLSocketDataProvider proxy_ssl(ASYNC, OK); // SSL to the proxy
[email protected]511f6f52010-12-17 03:58:298060
[email protected]bb88e1d32013-05-03 23:11:078061 session_deps_.socket_factory->AddSocketDataProvider(&data);
8062 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy_ssl);
[email protected]511f6f52010-12-17 03:58:298063
[email protected]49639fa2011-12-20 23:22:418064 TestCompletionCallback callback;
[email protected]511f6f52010-12-17 03:58:298065
danakj1fd259a02016-04-16 03:17:098066 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:168067 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]511f6f52010-12-17 03:58:298068
tfarina42834112016-09-22 13:38:208069 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:018070 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]511f6f52010-12-17 03:58:298071
8072 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:018073 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:168074 const HttpResponseInfo* response = trans.GetResponseInfo();
[email protected]511f6f52010-12-17 03:58:298075
wezca1070932016-05-26 20:30:528076 ASSERT_TRUE(response);
[email protected]511f6f52010-12-17 03:58:298077
8078 EXPECT_EQ(302, response->headers->response_code());
8079 std::string url;
8080 EXPECT_TRUE(response->headers->IsRedirect(&url));
8081 EXPECT_EQ("http://login.example.com/", url);
[email protected]029c83b62013-01-24 05:28:208082
8083 // In the case of redirects from proxies, HttpNetworkTransaction returns
8084 // timing for the proxy connection instead of the connection to the host,
8085 // and no send / receive times.
8086 // See HttpNetworkTransaction::OnHttpsProxyTunnelResponse.
8087 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:168088 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]029c83b62013-01-24 05:28:208089
8090 EXPECT_FALSE(load_timing_info.socket_reused);
mikecironef22f9812016-10-04 03:40:198091 EXPECT_NE(NetLogSource::kInvalidId, load_timing_info.socket_log_id);
[email protected]029c83b62013-01-24 05:28:208092
8093 EXPECT_FALSE(load_timing_info.proxy_resolve_start.is_null());
8094 EXPECT_LE(load_timing_info.proxy_resolve_start,
8095 load_timing_info.proxy_resolve_end);
8096 EXPECT_LE(load_timing_info.proxy_resolve_end,
8097 load_timing_info.connect_timing.connect_start);
8098 ExpectConnectTimingHasTimes(
8099 load_timing_info.connect_timing,
8100 CONNECT_TIMING_HAS_DNS_TIMES | CONNECT_TIMING_HAS_SSL_TIMES);
8101
8102 EXPECT_TRUE(load_timing_info.send_start.is_null());
8103 EXPECT_TRUE(load_timing_info.send_end.is_null());
8104 EXPECT_TRUE(load_timing_info.receive_headers_end.is_null());
[email protected]511f6f52010-12-17 03:58:298105}
8106
8107// Test an HTTPS (SPDY) Proxy's ability to redirect a CONNECT request
bncd16676a2016-07-20 16:23:018108TEST_F(HttpNetworkTransactionTest, RedirectOfHttpsConnectViaSpdyProxy) {
rdsmith82957ad2015-09-16 19:42:038109 session_deps_.proxy_service = ProxyService::CreateFixed("https://proxy:70");
[email protected]511f6f52010-12-17 03:58:298110
8111 HttpRequestInfo request;
8112 request.method = "GET";
bncce36dca22015-04-21 22:11:238113 request.url = GURL("https://www.example.org/");
[email protected]511f6f52010-12-17 03:58:298114
bncdf80d44fd2016-07-15 20:27:418115 SpdySerializedFrame conn(spdy_util_.ConstructSpdyConnect(
bncce36dca22015-04-21 22:11:238116 NULL, 0, 1, LOWEST, HostPortPair("www.example.org", 443)));
bncdf80d44fd2016-07-15 20:27:418117 SpdySerializedFrame goaway(
diannahu9904e272017-02-03 14:40:088118 spdy_util_.ConstructSpdyRstStream(1, ERROR_CODE_CANCEL));
[email protected]511f6f52010-12-17 03:58:298119 MockWrite data_writes[] = {
bncdf80d44fd2016-07-15 20:27:418120 CreateMockWrite(conn, 0, SYNCHRONOUS),
8121 CreateMockWrite(goaway, 2, SYNCHRONOUS),
[email protected]511f6f52010-12-17 03:58:298122 };
8123
8124 static const char* const kExtraHeaders[] = {
8125 "location",
8126 "http://login.example.com/",
8127 };
bnc42331402016-07-25 13:36:158128 SpdySerializedFrame resp(spdy_util_.ConstructSpdyReplyError(
bncc9f762a2016-12-06 20:38:238129 "302", kExtraHeaders, arraysize(kExtraHeaders) / 2, 1));
[email protected]511f6f52010-12-17 03:58:298130 MockRead data_reads[] = {
bncdf80d44fd2016-07-15 20:27:418131 CreateMockRead(resp, 1), MockRead(ASYNC, 0, 3), // EOF
[email protected]511f6f52010-12-17 03:58:298132 };
8133
rch8e6c6c42015-05-01 14:05:138134 SequencedSocketData data(data_reads, arraysize(data_reads), data_writes,
8135 arraysize(data_writes));
[email protected]8ddf8322012-02-23 18:08:068136 SSLSocketDataProvider proxy_ssl(ASYNC, OK); // SSL to the proxy
bnc3cf2a592016-08-11 14:48:368137 proxy_ssl.next_proto = kProtoHTTP2;
[email protected]511f6f52010-12-17 03:58:298138
[email protected]bb88e1d32013-05-03 23:11:078139 session_deps_.socket_factory->AddSocketDataProvider(&data);
8140 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy_ssl);
[email protected]511f6f52010-12-17 03:58:298141
[email protected]49639fa2011-12-20 23:22:418142 TestCompletionCallback callback;
[email protected]511f6f52010-12-17 03:58:298143
danakj1fd259a02016-04-16 03:17:098144 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:168145 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]511f6f52010-12-17 03:58:298146
tfarina42834112016-09-22 13:38:208147 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:018148 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]511f6f52010-12-17 03:58:298149
8150 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:018151 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:168152 const HttpResponseInfo* response = trans.GetResponseInfo();
[email protected]511f6f52010-12-17 03:58:298153
wezca1070932016-05-26 20:30:528154 ASSERT_TRUE(response);
[email protected]511f6f52010-12-17 03:58:298155
8156 EXPECT_EQ(302, response->headers->response_code());
8157 std::string url;
8158 EXPECT_TRUE(response->headers->IsRedirect(&url));
8159 EXPECT_EQ("http://login.example.com/", url);
8160}
8161
[email protected]4eddbc732012-08-09 05:40:178162// Test that an HTTPS proxy's response to a CONNECT request is filtered.
bncd16676a2016-07-20 16:23:018163TEST_F(HttpNetworkTransactionTest, ErrorResponseToHttpsConnectViaHttpsProxy) {
rdsmith82957ad2015-09-16 19:42:038164 session_deps_.proxy_service = ProxyService::CreateFixed("https://proxy:70");
[email protected]511f6f52010-12-17 03:58:298165
8166 HttpRequestInfo request;
8167 request.method = "GET";
bncce36dca22015-04-21 22:11:238168 request.url = GURL("https://www.example.org/");
[email protected]511f6f52010-12-17 03:58:298169
8170 MockWrite data_writes[] = {
rsleevidb16bb02015-11-12 23:47:178171 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
8172 "Host: www.example.org:443\r\n"
8173 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]511f6f52010-12-17 03:58:298174 };
8175
8176 MockRead data_reads[] = {
8177 MockRead("HTTP/1.1 404 Not Found\r\n"),
8178 MockRead("Content-Length: 23\r\n\r\n"),
8179 MockRead("The host does not exist"),
[email protected]8ddf8322012-02-23 18:08:068180 MockRead(SYNCHRONOUS, OK),
[email protected]511f6f52010-12-17 03:58:298181 };
8182
8183 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
8184 data_writes, arraysize(data_writes));
[email protected]8ddf8322012-02-23 18:08:068185 SSLSocketDataProvider proxy_ssl(ASYNC, OK); // SSL to the proxy
[email protected]511f6f52010-12-17 03:58:298186
[email protected]bb88e1d32013-05-03 23:11:078187 session_deps_.socket_factory->AddSocketDataProvider(&data);
8188 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy_ssl);
[email protected]511f6f52010-12-17 03:58:298189
[email protected]49639fa2011-12-20 23:22:418190 TestCompletionCallback callback;
[email protected]511f6f52010-12-17 03:58:298191
danakj1fd259a02016-04-16 03:17:098192 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:168193 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]511f6f52010-12-17 03:58:298194
tfarina42834112016-09-22 13:38:208195 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:018196 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]511f6f52010-12-17 03:58:298197
8198 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:018199 EXPECT_THAT(rv, IsError(ERR_TUNNEL_CONNECTION_FAILED));
[email protected]511f6f52010-12-17 03:58:298200
ttuttle960fcbf2016-04-19 13:26:328201 // TODO(juliatuttle): Anything else to check here?
[email protected]511f6f52010-12-17 03:58:298202}
8203
[email protected]4eddbc732012-08-09 05:40:178204// Test that a SPDY proxy's response to a CONNECT request is filtered.
bncd16676a2016-07-20 16:23:018205TEST_F(HttpNetworkTransactionTest, ErrorResponseToHttpsConnectViaSpdyProxy) {
rdsmith82957ad2015-09-16 19:42:038206 session_deps_.proxy_service = ProxyService::CreateFixed("https://proxy:70");
[email protected]511f6f52010-12-17 03:58:298207
8208 HttpRequestInfo request;
8209 request.method = "GET";
bncce36dca22015-04-21 22:11:238210 request.url = GURL("https://www.example.org/");
[email protected]511f6f52010-12-17 03:58:298211
bncdf80d44fd2016-07-15 20:27:418212 SpdySerializedFrame conn(spdy_util_.ConstructSpdyConnect(
bncce36dca22015-04-21 22:11:238213 NULL, 0, 1, LOWEST, HostPortPair("www.example.org", 443)));
bncdf80d44fd2016-07-15 20:27:418214 SpdySerializedFrame rst(
diannahu9904e272017-02-03 14:40:088215 spdy_util_.ConstructSpdyRstStream(1, ERROR_CODE_CANCEL));
[email protected]511f6f52010-12-17 03:58:298216 MockWrite data_writes[] = {
bncdf80d44fd2016-07-15 20:27:418217 CreateMockWrite(conn, 0), CreateMockWrite(rst, 3),
[email protected]511f6f52010-12-17 03:58:298218 };
8219
8220 static const char* const kExtraHeaders[] = {
8221 "location",
8222 "http://login.example.com/",
8223 };
bnc42331402016-07-25 13:36:158224 SpdySerializedFrame resp(spdy_util_.ConstructSpdyReplyError(
bncc9f762a2016-12-06 20:38:238225 "404", kExtraHeaders, arraysize(kExtraHeaders) / 2, 1));
bncdf80d44fd2016-07-15 20:27:418226 SpdySerializedFrame body(spdy_util_.ConstructSpdyDataFrame(
bncb03b1092016-04-06 11:19:558227 1, "The host does not exist", 23, true));
[email protected]511f6f52010-12-17 03:58:298228 MockRead data_reads[] = {
bncdf80d44fd2016-07-15 20:27:418229 CreateMockRead(resp, 1), CreateMockRead(body, 2),
rch8e6c6c42015-05-01 14:05:138230 MockRead(ASYNC, 0, 4), // EOF
[email protected]511f6f52010-12-17 03:58:298231 };
8232
rch8e6c6c42015-05-01 14:05:138233 SequencedSocketData data(data_reads, arraysize(data_reads), data_writes,
8234 arraysize(data_writes));
[email protected]8ddf8322012-02-23 18:08:068235 SSLSocketDataProvider proxy_ssl(ASYNC, OK); // SSL to the proxy
bnc3cf2a592016-08-11 14:48:368236 proxy_ssl.next_proto = kProtoHTTP2;
[email protected]511f6f52010-12-17 03:58:298237
[email protected]bb88e1d32013-05-03 23:11:078238 session_deps_.socket_factory->AddSocketDataProvider(&data);
8239 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy_ssl);
[email protected]511f6f52010-12-17 03:58:298240
[email protected]49639fa2011-12-20 23:22:418241 TestCompletionCallback callback;
[email protected]511f6f52010-12-17 03:58:298242
danakj1fd259a02016-04-16 03:17:098243 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:168244 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]511f6f52010-12-17 03:58:298245
tfarina42834112016-09-22 13:38:208246 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:018247 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]511f6f52010-12-17 03:58:298248
8249 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:018250 EXPECT_THAT(rv, IsError(ERR_TUNNEL_CONNECTION_FAILED));
[email protected]511f6f52010-12-17 03:58:298251
ttuttle960fcbf2016-04-19 13:26:328252 // TODO(juliatuttle): Anything else to check here?
[email protected]511f6f52010-12-17 03:58:298253}
8254
[email protected]0c5fb722012-02-28 11:50:358255// Test the request-challenge-retry sequence for basic auth, through
8256// a SPDY proxy over a single SPDY session.
bncd16676a2016-07-20 16:23:018257TEST_F(HttpNetworkTransactionTest, BasicAuthSpdyProxy) {
[email protected]0c5fb722012-02-28 11:50:358258 HttpRequestInfo request;
8259 request.method = "GET";
bncce36dca22015-04-21 22:11:238260 request.url = GURL("https://www.example.org/");
[email protected]0c5fb722012-02-28 11:50:358261 // when the no authentication data flag is set.
ttuttle859dc7a2015-04-23 19:42:298262 request.load_flags = LOAD_DO_NOT_SEND_AUTH_DATA;
[email protected]0c5fb722012-02-28 11:50:358263
8264 // Configure against https proxy server "myproxy:70".
rdsmith82957ad2015-09-16 19:42:038265 session_deps_.proxy_service =
8266 ProxyService::CreateFixedFromPacResult("HTTPS myproxy:70");
vishal.b62985ca92015-04-17 08:45:518267 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:078268 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:098269 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]0c5fb722012-02-28 11:50:358270
8271 // Since we have proxy, should try to establish tunnel.
bncdf80d44fd2016-07-15 20:27:418272 SpdySerializedFrame req(spdy_util_.ConstructSpdyConnect(
bncce36dca22015-04-21 22:11:238273 NULL, 0, 1, LOWEST, HostPortPair("www.example.org", 443)));
bncdf80d44fd2016-07-15 20:27:418274 SpdySerializedFrame rst(
diannahu9904e272017-02-03 14:40:088275 spdy_util_.ConstructSpdyRstStream(1, ERROR_CODE_CANCEL));
rdsmithebb50aa2015-11-12 03:44:388276 spdy_util_.UpdateWithStreamDestruction(1);
[email protected]0c5fb722012-02-28 11:50:358277
bnc691fda62016-08-12 00:43:168278 // After calling trans.RestartWithAuth(), this is the request we should
[email protected]0c5fb722012-02-28 11:50:358279 // be issuing -- the final header line contains the credentials.
8280 const char* const kAuthCredentials[] = {
8281 "proxy-authorization", "Basic Zm9vOmJhcg==",
8282 };
bncdf80d44fd2016-07-15 20:27:418283 SpdySerializedFrame connect2(spdy_util_.ConstructSpdyConnect(
lgarrona91df87f2014-12-05 00:51:348284 kAuthCredentials, arraysize(kAuthCredentials) / 2, 3, LOWEST,
bncce36dca22015-04-21 22:11:238285 HostPortPair("www.example.org", 443)));
8286 // fetch https://www.example.org/ via HTTP
8287 const char get[] =
8288 "GET / HTTP/1.1\r\n"
8289 "Host: www.example.org\r\n"
8290 "Connection: keep-alive\r\n\r\n";
bncdf80d44fd2016-07-15 20:27:418291 SpdySerializedFrame wrapped_get(
8292 spdy_util_.ConstructSpdyDataFrame(3, get, strlen(get), false));
[email protected]0c5fb722012-02-28 11:50:358293
8294 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:418295 CreateMockWrite(req, 0, ASYNC), CreateMockWrite(rst, 2, ASYNC),
8296 CreateMockWrite(connect2, 3), CreateMockWrite(wrapped_get, 5),
[email protected]0c5fb722012-02-28 11:50:358297 };
8298
8299 // The proxy responds to the connect with a 407, using a persistent
8300 // connection.
thestig9d3bb0c2015-01-24 00:49:518301 const char kAuthStatus[] = "407";
[email protected]0c5fb722012-02-28 11:50:358302 const char* const kAuthChallenge[] = {
[email protected]0c5fb722012-02-28 11:50:358303 "proxy-authenticate", "Basic realm=\"MyRealm1\"",
8304 };
bnc42331402016-07-25 13:36:158305 SpdySerializedFrame conn_auth_resp(spdy_util_.ConstructSpdyReplyError(
bncdf80d44fd2016-07-15 20:27:418306 kAuthStatus, kAuthChallenge, arraysize(kAuthChallenge) / 2, 1));
[email protected]0c5fb722012-02-28 11:50:358307
bnc42331402016-07-25 13:36:158308 SpdySerializedFrame conn_resp(spdy_util_.ConstructSpdyGetReply(NULL, 0, 3));
[email protected]0c5fb722012-02-28 11:50:358309 const char resp[] = "HTTP/1.1 200 OK\r\n"
8310 "Content-Length: 5\r\n\r\n";
8311
bncdf80d44fd2016-07-15 20:27:418312 SpdySerializedFrame wrapped_get_resp(
8313 spdy_util_.ConstructSpdyDataFrame(3, resp, strlen(resp), false));
8314 SpdySerializedFrame wrapped_body(
8315 spdy_util_.ConstructSpdyDataFrame(3, "hello", 5, false));
[email protected]0c5fb722012-02-28 11:50:358316 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:418317 CreateMockRead(conn_auth_resp, 1, ASYNC),
8318 CreateMockRead(conn_resp, 4, ASYNC),
8319 CreateMockRead(wrapped_get_resp, 6, ASYNC),
8320 CreateMockRead(wrapped_body, 7, ASYNC),
rch8e6c6c42015-05-01 14:05:138321 MockRead(ASYNC, OK, 8), // EOF. May or may not be read.
[email protected]0c5fb722012-02-28 11:50:358322 };
8323
rch8e6c6c42015-05-01 14:05:138324 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
8325 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:078326 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]0c5fb722012-02-28 11:50:358327 // Negotiate SPDY to the proxy
8328 SSLSocketDataProvider proxy(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:368329 proxy.next_proto = kProtoHTTP2;
[email protected]bb88e1d32013-05-03 23:11:078330 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy);
[email protected]0c5fb722012-02-28 11:50:358331 // Vanilla SSL to the server
8332 SSLSocketDataProvider server(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:078333 session_deps_.socket_factory->AddSSLSocketDataProvider(&server);
[email protected]0c5fb722012-02-28 11:50:358334
8335 TestCompletionCallback callback1;
8336
bnc87dcefc2017-05-25 12:47:588337 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:198338 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]0c5fb722012-02-28 11:50:358339
8340 int rv = trans->Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:018341 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]0c5fb722012-02-28 11:50:358342
8343 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:018344 EXPECT_THAT(rv, IsOk());
mmenke43758e62015-05-04 21:09:468345 TestNetLogEntry::List entries;
[email protected]0c5fb722012-02-28 11:50:358346 log.GetEntries(&entries);
8347 size_t pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:008348 entries, 0, NetLogEventType::HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
8349 NetLogEventPhase::NONE);
[email protected]0c5fb722012-02-28 11:50:358350 ExpectLogContainsSomewhere(
8351 entries, pos,
mikecirone8b85c432016-09-08 19:11:008352 NetLogEventType::HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
8353 NetLogEventPhase::NONE);
[email protected]0c5fb722012-02-28 11:50:358354
8355 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:528356 ASSERT_TRUE(response);
8357 ASSERT_TRUE(response->headers);
[email protected]0c5fb722012-02-28 11:50:358358 EXPECT_EQ(407, response->headers->response_code());
8359 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
wezca1070932016-05-26 20:30:528360 EXPECT_TRUE(response->auth_challenge);
asanka098c0092016-06-16 20:18:438361 EXPECT_TRUE(CheckBasicSecureProxyAuth(response->auth_challenge.get()));
[email protected]0c5fb722012-02-28 11:50:358362
8363 TestCompletionCallback callback2;
8364
8365 rv = trans->RestartWithAuth(AuthCredentials(kFoo, kBar),
8366 callback2.callback());
robpercival214763f2016-07-01 23:27:018367 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]0c5fb722012-02-28 11:50:358368
8369 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:018370 EXPECT_THAT(rv, IsOk());
[email protected]0c5fb722012-02-28 11:50:358371
8372 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:528373 ASSERT_TRUE(response);
[email protected]0c5fb722012-02-28 11:50:358374
8375 EXPECT_TRUE(response->headers->IsKeepAlive());
8376 EXPECT_EQ(200, response->headers->response_code());
8377 EXPECT_EQ(5, response->headers->GetContentLength());
8378 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
8379
8380 // The password prompt info should not be set.
wezca1070932016-05-26 20:30:528381 EXPECT_FALSE(response->auth_challenge);
[email protected]0c5fb722012-02-28 11:50:358382
[email protected]029c83b62013-01-24 05:28:208383 LoadTimingInfo load_timing_info;
8384 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
8385 TestLoadTimingNotReusedWithPac(load_timing_info,
8386 CONNECT_TIMING_HAS_SSL_TIMES);
8387
[email protected]0c5fb722012-02-28 11:50:358388 trans.reset();
8389 session->CloseAllConnections();
8390}
8391
[email protected]7c6f7ba2012-04-03 04:09:298392// Test that an explicitly trusted SPDY proxy can push a resource from an
8393// origin that is different from that of its associated resource.
bncd16676a2016-07-20 16:23:018394TEST_F(HttpNetworkTransactionTest, CrossOriginSPDYProxyPush) {
tbansal28e68f82016-02-04 02:56:158395 // Configure the proxy delegate to allow cross-origin SPDY pushes.
Jeremy Roman0579ed62017-08-29 15:56:198396 auto proxy_delegate = std::make_unique<TestProxyDelegate>();
tbansal28e68f82016-02-04 02:56:158397 proxy_delegate->set_trusted_spdy_proxy(net::ProxyServer::FromURI(
8398 "https://myproxy:443", net::ProxyServer::SCHEME_HTTP));
[email protected]7c6f7ba2012-04-03 04:09:298399 HttpRequestInfo request;
8400 HttpRequestInfo push_request;
8401
[email protected]7c6f7ba2012-04-03 04:09:298402 request.method = "GET";
bncce36dca22015-04-21 22:11:238403 request.url = GURL("http://www.example.org/");
[email protected]7c6f7ba2012-04-03 04:09:298404 push_request.method = "GET";
8405 push_request.url = GURL("http://www.another-origin.com/foo.dat");
8406
tbansal28e68f82016-02-04 02:56:158407 // Configure against https proxy server "myproxy:443".
rdsmith82957ad2015-09-16 19:42:038408 session_deps_.proxy_service =
tbansal28e68f82016-02-04 02:56:158409 ProxyService::CreateFixedFromPacResult("HTTPS myproxy:443");
vishal.b62985ca92015-04-17 08:45:518410 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:078411 session_deps_.net_log = log.bound().net_log();
[email protected]61b4efc2012-04-27 18:12:508412
inlinechan894515af2016-12-09 02:40:108413 session_deps_.proxy_delegate = std::move(proxy_delegate);
[email protected]61b4efc2012-04-27 18:12:508414
danakj1fd259a02016-04-16 03:17:098415 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]7c6f7ba2012-04-03 04:09:298416
bncdf80d44fd2016-07-15 20:27:418417 SpdySerializedFrame stream1_syn(
bncb26024382016-06-29 02:39:458418 spdy_util_.ConstructSpdyGet("http://www.example.org/", 1, LOWEST));
tombergan5d22c182017-01-11 02:05:358419 SpdySerializedFrame stream2_priority(
8420 spdy_util_.ConstructSpdyPriority(2, 1, IDLE, true));
[email protected]7c6f7ba2012-04-03 04:09:298421
8422 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:418423 CreateMockWrite(stream1_syn, 0, ASYNC),
tombergan5d22c182017-01-11 02:05:358424 CreateMockWrite(stream2_priority, 3, ASYNC),
[email protected]7c6f7ba2012-04-03 04:09:298425 };
8426
bncdf80d44fd2016-07-15 20:27:418427 SpdySerializedFrame stream1_reply(
bnc42331402016-07-25 13:36:158428 spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
[email protected]7c6f7ba2012-04-03 04:09:298429
bncdf80d44fd2016-07-15 20:27:418430 SpdySerializedFrame stream1_body(spdy_util_.ConstructSpdyDataFrame(1, true));
[email protected]7c6f7ba2012-04-03 04:09:298431
bncdf80d44fd2016-07-15 20:27:418432 SpdySerializedFrame stream2_syn(spdy_util_.ConstructSpdyPush(
bncb03b1092016-04-06 11:19:558433 NULL, 0, 2, 1, "http://www.another-origin.com/foo.dat"));
[email protected]8a0fc822013-06-27 20:52:438434 const char kPushedData[] = "pushed";
bncdf80d44fd2016-07-15 20:27:418435 SpdySerializedFrame stream2_body(spdy_util_.ConstructSpdyDataFrame(
8436 2, kPushedData, strlen(kPushedData), true));
[email protected]7c6f7ba2012-04-03 04:09:298437
8438 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:418439 CreateMockRead(stream1_reply, 1, ASYNC),
8440 CreateMockRead(stream2_syn, 2, ASYNC),
tombergan5d22c182017-01-11 02:05:358441 CreateMockRead(stream1_body, 4, ASYNC),
8442 CreateMockRead(stream2_body, 5, ASYNC),
8443 MockRead(SYNCHRONOUS, ERR_IO_PENDING, 6), // Force a hang
[email protected]7c6f7ba2012-04-03 04:09:298444 };
8445
rch8e6c6c42015-05-01 14:05:138446 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
8447 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:078448 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]7c6f7ba2012-04-03 04:09:298449 // Negotiate SPDY to the proxy
8450 SSLSocketDataProvider proxy(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:368451 proxy.next_proto = kProtoHTTP2;
[email protected]bb88e1d32013-05-03 23:11:078452 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy);
[email protected]7c6f7ba2012-04-03 04:09:298453
bnc87dcefc2017-05-25 12:47:588454 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:198455 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]7c6f7ba2012-04-03 04:09:298456 TestCompletionCallback callback;
8457 int rv = trans->Start(&request, callback.callback(), log.bound());
robpercival214763f2016-07-01 23:27:018458 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]7c6f7ba2012-04-03 04:09:298459
8460 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:018461 EXPECT_THAT(rv, IsOk());
[email protected]7c6f7ba2012-04-03 04:09:298462 const HttpResponseInfo* response = trans->GetResponseInfo();
8463
bnc87dcefc2017-05-25 12:47:588464 auto push_trans =
Jeremy Roman0579ed62017-08-29 15:56:198465 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]90499482013-06-01 00:39:508466 rv = push_trans->Start(&push_request, callback.callback(), log.bound());
robpercival214763f2016-07-01 23:27:018467 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]7c6f7ba2012-04-03 04:09:298468
8469 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:018470 EXPECT_THAT(rv, IsOk());
[email protected]7c6f7ba2012-04-03 04:09:298471 const HttpResponseInfo* push_response = push_trans->GetResponseInfo();
8472
wezca1070932016-05-26 20:30:528473 ASSERT_TRUE(response);
[email protected]7c6f7ba2012-04-03 04:09:298474 EXPECT_TRUE(response->headers->IsKeepAlive());
8475
8476 EXPECT_EQ(200, response->headers->response_code());
8477 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
8478
8479 std::string response_data;
8480 rv = ReadTransaction(trans.get(), &response_data);
robpercival214763f2016-07-01 23:27:018481 EXPECT_THAT(rv, IsOk());
[email protected]7c6f7ba2012-04-03 04:09:298482 EXPECT_EQ("hello!", response_data);
8483
[email protected]029c83b62013-01-24 05:28:208484 LoadTimingInfo load_timing_info;
8485 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
8486 TestLoadTimingNotReusedWithPac(load_timing_info,
8487 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
8488
[email protected]7c6f7ba2012-04-03 04:09:298489 // Verify the pushed stream.
wezca1070932016-05-26 20:30:528490 EXPECT_TRUE(push_response->headers);
[email protected]7c6f7ba2012-04-03 04:09:298491 EXPECT_EQ(200, push_response->headers->response_code());
8492
8493 rv = ReadTransaction(push_trans.get(), &response_data);
robpercival214763f2016-07-01 23:27:018494 EXPECT_THAT(rv, IsOk());
[email protected]7c6f7ba2012-04-03 04:09:298495 EXPECT_EQ("pushed", response_data);
8496
[email protected]029c83b62013-01-24 05:28:208497 LoadTimingInfo push_load_timing_info;
8498 EXPECT_TRUE(push_trans->GetLoadTimingInfo(&push_load_timing_info));
8499 TestLoadTimingReusedWithPac(push_load_timing_info);
8500 // The transactions should share a socket ID, despite being for different
8501 // origins.
8502 EXPECT_EQ(load_timing_info.socket_log_id,
8503 push_load_timing_info.socket_log_id);
8504
[email protected]7c6f7ba2012-04-03 04:09:298505 trans.reset();
8506 push_trans.reset();
8507 session->CloseAllConnections();
8508}
8509
[email protected]8c843192012-04-05 07:15:008510// Test that an explicitly trusted SPDY proxy cannot push HTTPS content.
bncd16676a2016-07-20 16:23:018511TEST_F(HttpNetworkTransactionTest, CrossOriginProxyPushCorrectness) {
tbansal28e68f82016-02-04 02:56:158512 // Configure the proxy delegate to allow cross-origin SPDY pushes.
Jeremy Roman0579ed62017-08-29 15:56:198513 auto proxy_delegate = std::make_unique<TestProxyDelegate>();
tbansal28e68f82016-02-04 02:56:158514 proxy_delegate->set_trusted_spdy_proxy(net::ProxyServer::FromURI(
8515 "https://myproxy:443", net::ProxyServer::SCHEME_HTTP));
[email protected]8c843192012-04-05 07:15:008516 HttpRequestInfo request;
8517
8518 request.method = "GET";
bncce36dca22015-04-21 22:11:238519 request.url = GURL("http://www.example.org/");
[email protected]8c843192012-04-05 07:15:008520
tbansal28e68f82016-02-04 02:56:158521 session_deps_.proxy_service =
8522 ProxyService::CreateFixed("https://myproxy:443");
vishal.b62985ca92015-04-17 08:45:518523 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:078524 session_deps_.net_log = log.bound().net_log();
[email protected]61b4efc2012-04-27 18:12:508525
8526 // Enable cross-origin push.
inlinechan894515af2016-12-09 02:40:108527 session_deps_.proxy_delegate = std::move(proxy_delegate);
[email protected]61b4efc2012-04-27 18:12:508528
danakj1fd259a02016-04-16 03:17:098529 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]8c843192012-04-05 07:15:008530
bncdf80d44fd2016-07-15 20:27:418531 SpdySerializedFrame stream1_syn(
bncb26024382016-06-29 02:39:458532 spdy_util_.ConstructSpdyGet("http://www.example.org/", 1, LOWEST));
[email protected]8c843192012-04-05 07:15:008533
bncdf80d44fd2016-07-15 20:27:418534 SpdySerializedFrame push_rst(
diannahu9904e272017-02-03 14:40:088535 spdy_util_.ConstructSpdyRstStream(2, ERROR_CODE_REFUSED_STREAM));
[email protected]8c843192012-04-05 07:15:008536
8537 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:418538 CreateMockWrite(stream1_syn, 0, ASYNC), CreateMockWrite(push_rst, 3),
[email protected]8c843192012-04-05 07:15:008539 };
8540
bncdf80d44fd2016-07-15 20:27:418541 SpdySerializedFrame stream1_reply(
bnc42331402016-07-25 13:36:158542 spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
[email protected]8c843192012-04-05 07:15:008543
bncdf80d44fd2016-07-15 20:27:418544 SpdySerializedFrame stream1_body(spdy_util_.ConstructSpdyDataFrame(1, true));
[email protected]8c843192012-04-05 07:15:008545
bncdf80d44fd2016-07-15 20:27:418546 SpdySerializedFrame stream2_syn(spdy_util_.ConstructSpdyPush(
bncb03b1092016-04-06 11:19:558547 NULL, 0, 2, 1, "https://www.another-origin.com/foo.dat"));
[email protected]8c843192012-04-05 07:15:008548
8549 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:418550 CreateMockRead(stream1_reply, 1, ASYNC),
8551 CreateMockRead(stream2_syn, 2, ASYNC),
8552 CreateMockRead(stream1_body, 4, ASYNC),
mmenkee24011922015-12-17 22:12:598553 MockRead(SYNCHRONOUS, ERR_IO_PENDING, 5), // Force a hang
[email protected]8c843192012-04-05 07:15:008554 };
8555
rch8e6c6c42015-05-01 14:05:138556 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
8557 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:078558 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]8c843192012-04-05 07:15:008559 // Negotiate SPDY to the proxy
8560 SSLSocketDataProvider proxy(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:368561 proxy.next_proto = kProtoHTTP2;
[email protected]bb88e1d32013-05-03 23:11:078562 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy);
[email protected]8c843192012-04-05 07:15:008563
bnc87dcefc2017-05-25 12:47:588564 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:198565 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]8c843192012-04-05 07:15:008566 TestCompletionCallback callback;
8567 int rv = trans->Start(&request, callback.callback(), log.bound());
robpercival214763f2016-07-01 23:27:018568 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]8c843192012-04-05 07:15:008569
8570 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:018571 EXPECT_THAT(rv, IsOk());
[email protected]8c843192012-04-05 07:15:008572 const HttpResponseInfo* response = trans->GetResponseInfo();
8573
wezca1070932016-05-26 20:30:528574 ASSERT_TRUE(response);
[email protected]8c843192012-04-05 07:15:008575 EXPECT_TRUE(response->headers->IsKeepAlive());
8576
8577 EXPECT_EQ(200, response->headers->response_code());
8578 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
8579
8580 std::string response_data;
8581 rv = ReadTransaction(trans.get(), &response_data);
robpercival214763f2016-07-01 23:27:018582 EXPECT_THAT(rv, IsOk());
[email protected]8c843192012-04-05 07:15:008583 EXPECT_EQ("hello!", response_data);
8584
8585 trans.reset();
8586 session->CloseAllConnections();
8587}
8588
tbansal8ef1d3e2016-02-03 04:05:428589// Test that an explicitly trusted SPDY proxy can push same-origin HTTPS
8590// resources.
bncd16676a2016-07-20 16:23:018591TEST_F(HttpNetworkTransactionTest, SameOriginProxyPushCorrectness) {
tbansal28e68f82016-02-04 02:56:158592 // Configure the proxy delegate to allow cross-origin SPDY pushes.
Jeremy Roman0579ed62017-08-29 15:56:198593 auto proxy_delegate = std::make_unique<TestProxyDelegate>();
tbansal28e68f82016-02-04 02:56:158594 proxy_delegate->set_trusted_spdy_proxy(
8595 net::ProxyServer::FromURI("myproxy:70", net::ProxyServer::SCHEME_HTTP));
8596
tbansal8ef1d3e2016-02-03 04:05:428597 HttpRequestInfo request;
8598
8599 request.method = "GET";
8600 request.url = GURL("http://www.example.org/");
8601
8602 // Configure against https proxy server "myproxy:70".
8603 session_deps_.proxy_service = ProxyService::CreateFixed("https://myproxy:70");
8604 BoundTestNetLog log;
8605 session_deps_.net_log = log.bound().net_log();
8606
8607 // Enable cross-origin push.
inlinechan894515af2016-12-09 02:40:108608 session_deps_.proxy_delegate = std::move(proxy_delegate);
tbansal8ef1d3e2016-02-03 04:05:428609
danakj1fd259a02016-04-16 03:17:098610 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
tbansal8ef1d3e2016-02-03 04:05:428611
bncdf80d44fd2016-07-15 20:27:418612 SpdySerializedFrame stream1_syn(
bncb26024382016-06-29 02:39:458613 spdy_util_.ConstructSpdyGet("http://www.example.org/", 1, LOWEST));
tombergan5d22c182017-01-11 02:05:358614 SpdySerializedFrame stream2_priority(
8615 spdy_util_.ConstructSpdyPriority(2, 1, IDLE, true));
tbansal8ef1d3e2016-02-03 04:05:428616
8617 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:418618 CreateMockWrite(stream1_syn, 0, ASYNC),
tombergan5d22c182017-01-11 02:05:358619 CreateMockWrite(stream2_priority, 3, ASYNC),
tbansal8ef1d3e2016-02-03 04:05:428620 };
8621
bncdf80d44fd2016-07-15 20:27:418622 SpdySerializedFrame stream1_reply(
bnc42331402016-07-25 13:36:158623 spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
tbansal8ef1d3e2016-02-03 04:05:428624
bncdf80d44fd2016-07-15 20:27:418625 SpdySerializedFrame stream2_syn(spdy_util_.ConstructSpdyPush(
Bence Béky096cf052017-08-08 23:55:338626 nullptr, 0, 2, 1, "http://www.example.org/foo.dat"));
bnc38dcd392016-02-09 23:19:498627
bncdf80d44fd2016-07-15 20:27:418628 SpdySerializedFrame stream1_body(spdy_util_.ConstructSpdyDataFrame(1, true));
tbansal8ef1d3e2016-02-03 04:05:428629
bncdf80d44fd2016-07-15 20:27:418630 SpdySerializedFrame stream2_reply(
bnc42331402016-07-25 13:36:158631 spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
tbansal8ef1d3e2016-02-03 04:05:428632
bncdf80d44fd2016-07-15 20:27:418633 SpdySerializedFrame stream2_body(spdy_util_.ConstructSpdyDataFrame(1, true));
tbansal8ef1d3e2016-02-03 04:05:428634
8635 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:418636 CreateMockRead(stream1_reply, 1, ASYNC),
8637 CreateMockRead(stream2_syn, 2, ASYNC),
tombergan5d22c182017-01-11 02:05:358638 CreateMockRead(stream1_body, 4, ASYNC),
8639 CreateMockRead(stream2_body, 5, ASYNC),
8640 MockRead(SYNCHRONOUS, ERR_IO_PENDING, 6), // Force a hang
tbansal8ef1d3e2016-02-03 04:05:428641 };
8642
8643 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
8644 arraysize(spdy_writes));
8645 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
8646 // Negotiate SPDY to the proxy
8647 SSLSocketDataProvider proxy(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:368648 proxy.next_proto = kProtoHTTP2;
tbansal8ef1d3e2016-02-03 04:05:428649 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy);
8650
bnc87dcefc2017-05-25 12:47:588651 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:198652 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
tbansal8ef1d3e2016-02-03 04:05:428653 TestCompletionCallback callback;
8654 int rv = trans->Start(&request, callback.callback(), log.bound());
robpercival214763f2016-07-01 23:27:018655 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
tbansal8ef1d3e2016-02-03 04:05:428656
8657 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:018658 EXPECT_THAT(rv, IsOk());
tbansal8ef1d3e2016-02-03 04:05:428659 const HttpResponseInfo* response = trans->GetResponseInfo();
8660
wezca1070932016-05-26 20:30:528661 ASSERT_TRUE(response);
tbansal8ef1d3e2016-02-03 04:05:428662 EXPECT_TRUE(response->headers->IsKeepAlive());
8663
8664 EXPECT_EQ(200, response->headers->response_code());
8665 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
8666
8667 std::string response_data;
8668 rv = ReadTransaction(trans.get(), &response_data);
robpercival214763f2016-07-01 23:27:018669 EXPECT_THAT(rv, IsOk());
tbansal8ef1d3e2016-02-03 04:05:428670 EXPECT_EQ("hello!", response_data);
8671
8672 trans.reset();
8673 session->CloseAllConnections();
8674}
8675
[email protected]2df19bb2010-08-25 20:13:468676// Test HTTPS connections to a site with a bad certificate, going through an
8677// HTTPS proxy
bncd16676a2016-07-20 16:23:018678TEST_F(HttpNetworkTransactionTest, HTTPSBadCertificateViaHttpsProxy) {
rdsmith82957ad2015-09-16 19:42:038679 session_deps_.proxy_service = ProxyService::CreateFixed("https://proxy:70");
[email protected]2df19bb2010-08-25 20:13:468680
8681 HttpRequestInfo request;
8682 request.method = "GET";
bncce36dca22015-04-21 22:11:238683 request.url = GURL("https://www.example.org/");
[email protected]2df19bb2010-08-25 20:13:468684
8685 // Attempt to fetch the URL from a server with a bad cert
8686 MockWrite bad_cert_writes[] = {
rsleevidb16bb02015-11-12 23:47:178687 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
8688 "Host: www.example.org:443\r\n"
8689 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]2df19bb2010-08-25 20:13:468690 };
8691
8692 MockRead bad_cert_reads[] = {
8693 MockRead("HTTP/1.0 200 Connected\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:068694 MockRead(SYNCHRONOUS, OK)
[email protected]2df19bb2010-08-25 20:13:468695 };
8696
8697 // Attempt to fetch the URL with a good cert
8698 MockWrite good_data_writes[] = {
rsleevidb16bb02015-11-12 23:47:178699 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
8700 "Host: www.example.org:443\r\n"
8701 "Proxy-Connection: keep-alive\r\n\r\n"),
8702 MockWrite("GET / HTTP/1.1\r\n"
8703 "Host: www.example.org\r\n"
8704 "Connection: keep-alive\r\n\r\n"),
[email protected]2df19bb2010-08-25 20:13:468705 };
8706
8707 MockRead good_cert_reads[] = {
8708 MockRead("HTTP/1.0 200 Connected\r\n\r\n"),
8709 MockRead("HTTP/1.0 200 OK\r\n"),
8710 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
8711 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:068712 MockRead(SYNCHRONOUS, OK),
[email protected]2df19bb2010-08-25 20:13:468713 };
8714
8715 StaticSocketDataProvider ssl_bad_certificate(
8716 bad_cert_reads, arraysize(bad_cert_reads),
8717 bad_cert_writes, arraysize(bad_cert_writes));
8718 StaticSocketDataProvider data(good_cert_reads, arraysize(good_cert_reads),
8719 good_data_writes, arraysize(good_data_writes));
[email protected]8ddf8322012-02-23 18:08:068720 SSLSocketDataProvider ssl_bad(ASYNC, ERR_CERT_AUTHORITY_INVALID);
8721 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]2df19bb2010-08-25 20:13:468722
8723 // SSL to the proxy, then CONNECT request, then SSL with bad certificate
[email protected]bb88e1d32013-05-03 23:11:078724 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
8725 session_deps_.socket_factory->AddSocketDataProvider(&ssl_bad_certificate);
8726 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_bad);
[email protected]2df19bb2010-08-25 20:13:468727
8728 // SSL to the proxy, then CONNECT request, then valid SSL certificate
[email protected]bb88e1d32013-05-03 23:11:078729 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
8730 session_deps_.socket_factory->AddSocketDataProvider(&data);
8731 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]2df19bb2010-08-25 20:13:468732
[email protected]49639fa2011-12-20 23:22:418733 TestCompletionCallback callback;
[email protected]2df19bb2010-08-25 20:13:468734
danakj1fd259a02016-04-16 03:17:098735 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:168736 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]2df19bb2010-08-25 20:13:468737
tfarina42834112016-09-22 13:38:208738 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:018739 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2df19bb2010-08-25 20:13:468740
8741 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:018742 EXPECT_THAT(rv, IsError(ERR_CERT_AUTHORITY_INVALID));
[email protected]2df19bb2010-08-25 20:13:468743
bnc691fda62016-08-12 00:43:168744 rv = trans.RestartIgnoringLastError(callback.callback());
robpercival214763f2016-07-01 23:27:018745 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2df19bb2010-08-25 20:13:468746
8747 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:018748 EXPECT_THAT(rv, IsOk());
[email protected]2df19bb2010-08-25 20:13:468749
bnc691fda62016-08-12 00:43:168750 const HttpResponseInfo* response = trans.GetResponseInfo();
[email protected]2df19bb2010-08-25 20:13:468751
wezca1070932016-05-26 20:30:528752 ASSERT_TRUE(response);
[email protected]2df19bb2010-08-25 20:13:468753 EXPECT_EQ(100, response->headers->GetContentLength());
8754}
8755
bncd16676a2016-07-20 16:23:018756TEST_F(HttpNetworkTransactionTest, BuildRequest_UserAgent) {
[email protected]1c773ea12009-04-28 19:58:428757 HttpRequestInfo request;
8758 request.method = "GET";
bncce36dca22015-04-21 22:11:238759 request.url = GURL("http://www.example.org/");
[email protected]8c76ae22010-04-20 22:15:438760 request.extra_headers.SetHeader(HttpRequestHeaders::kUserAgent,
8761 "Chromium Ultra Awesome X Edition");
[email protected]1c773ea12009-04-28 19:58:428762
danakj1fd259a02016-04-16 03:17:098763 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:168764 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:278765
[email protected]1c773ea12009-04-28 19:58:428766 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:238767 MockWrite(
8768 "GET / HTTP/1.1\r\n"
8769 "Host: www.example.org\r\n"
8770 "Connection: keep-alive\r\n"
8771 "User-Agent: Chromium Ultra Awesome X Edition\r\n\r\n"),
[email protected]1c773ea12009-04-28 19:58:428772 };
8773
8774 // Lastly, the server responds with the actual content.
8775 MockRead data_reads[] = {
8776 MockRead("HTTP/1.0 200 OK\r\n"),
8777 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
8778 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:068779 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:428780 };
8781
[email protected]31a2bfe2010-02-09 08:03:398782 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
8783 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:078784 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:428785
[email protected]49639fa2011-12-20 23:22:418786 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:428787
tfarina42834112016-09-22 13:38:208788 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:018789 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]1c773ea12009-04-28 19:58:428790
8791 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:018792 EXPECT_THAT(rv, IsOk());
[email protected]1c773ea12009-04-28 19:58:428793}
8794
bncd16676a2016-07-20 16:23:018795TEST_F(HttpNetworkTransactionTest, BuildRequest_UserAgentOverTunnel) {
[email protected]da81f132010-08-18 23:39:298796 HttpRequestInfo request;
8797 request.method = "GET";
bncce36dca22015-04-21 22:11:238798 request.url = GURL("https://www.example.org/");
[email protected]da81f132010-08-18 23:39:298799 request.extra_headers.SetHeader(HttpRequestHeaders::kUserAgent,
8800 "Chromium Ultra Awesome X Edition");
8801
rdsmith82957ad2015-09-16 19:42:038802 session_deps_.proxy_service = ProxyService::CreateFixed("myproxy:70");
danakj1fd259a02016-04-16 03:17:098803 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:168804 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:278805
[email protected]da81f132010-08-18 23:39:298806 MockWrite data_writes[] = {
rsleevidb16bb02015-11-12 23:47:178807 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
8808 "Host: www.example.org:443\r\n"
8809 "Proxy-Connection: keep-alive\r\n"
8810 "User-Agent: Chromium Ultra Awesome X Edition\r\n\r\n"),
[email protected]da81f132010-08-18 23:39:298811 };
8812 MockRead data_reads[] = {
8813 // Return an error, so the transaction stops here (this test isn't
8814 // interested in the rest).
8815 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
8816 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
8817 MockRead("Proxy-Connection: close\r\n\r\n"),
8818 };
8819
8820 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
8821 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:078822 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]da81f132010-08-18 23:39:298823
[email protected]49639fa2011-12-20 23:22:418824 TestCompletionCallback callback;
[email protected]da81f132010-08-18 23:39:298825
tfarina42834112016-09-22 13:38:208826 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:018827 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]da81f132010-08-18 23:39:298828
8829 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:018830 EXPECT_THAT(rv, IsOk());
[email protected]da81f132010-08-18 23:39:298831}
8832
bncd16676a2016-07-20 16:23:018833TEST_F(HttpNetworkTransactionTest, BuildRequest_Referer) {
[email protected]1c773ea12009-04-28 19:58:428834 HttpRequestInfo request;
8835 request.method = "GET";
bncce36dca22015-04-21 22:11:238836 request.url = GURL("http://www.example.org/");
[email protected]c10450102011-06-27 09:06:168837 request.extra_headers.SetHeader(HttpRequestHeaders::kReferer,
8838 "http://the.previous.site.com/");
[email protected]1c773ea12009-04-28 19:58:428839
danakj1fd259a02016-04-16 03:17:098840 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:168841 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:278842
[email protected]1c773ea12009-04-28 19:58:428843 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:238844 MockWrite(
8845 "GET / HTTP/1.1\r\n"
8846 "Host: www.example.org\r\n"
8847 "Connection: keep-alive\r\n"
8848 "Referer: http://the.previous.site.com/\r\n\r\n"),
[email protected]1c773ea12009-04-28 19:58:428849 };
8850
8851 // Lastly, the server responds with the actual content.
8852 MockRead data_reads[] = {
8853 MockRead("HTTP/1.0 200 OK\r\n"),
8854 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
8855 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:068856 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:428857 };
8858
[email protected]31a2bfe2010-02-09 08:03:398859 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
8860 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:078861 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:428862
[email protected]49639fa2011-12-20 23:22:418863 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:428864
tfarina42834112016-09-22 13:38:208865 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:018866 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]1c773ea12009-04-28 19:58:428867
8868 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:018869 EXPECT_THAT(rv, IsOk());
[email protected]1c773ea12009-04-28 19:58:428870}
8871
bncd16676a2016-07-20 16:23:018872TEST_F(HttpNetworkTransactionTest, BuildRequest_PostContentLengthZero) {
[email protected]1c773ea12009-04-28 19:58:428873 HttpRequestInfo request;
8874 request.method = "POST";
bncce36dca22015-04-21 22:11:238875 request.url = GURL("http://www.example.org/");
[email protected]1c773ea12009-04-28 19:58:428876
danakj1fd259a02016-04-16 03:17:098877 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:168878 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:278879
[email protected]1c773ea12009-04-28 19:58:428880 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:238881 MockWrite(
8882 "POST / HTTP/1.1\r\n"
8883 "Host: www.example.org\r\n"
8884 "Connection: keep-alive\r\n"
8885 "Content-Length: 0\r\n\r\n"),
[email protected]1c773ea12009-04-28 19:58:428886 };
8887
8888 // Lastly, the server responds with the actual content.
8889 MockRead data_reads[] = {
8890 MockRead("HTTP/1.0 200 OK\r\n"),
8891 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
8892 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:068893 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:428894 };
8895
[email protected]31a2bfe2010-02-09 08:03:398896 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
8897 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:078898 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:428899
[email protected]49639fa2011-12-20 23:22:418900 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:428901
tfarina42834112016-09-22 13:38:208902 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:018903 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]1c773ea12009-04-28 19:58:428904
8905 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:018906 EXPECT_THAT(rv, IsOk());
[email protected]1c773ea12009-04-28 19:58:428907}
8908
bncd16676a2016-07-20 16:23:018909TEST_F(HttpNetworkTransactionTest, BuildRequest_PutContentLengthZero) {
[email protected]1c773ea12009-04-28 19:58:428910 HttpRequestInfo request;
8911 request.method = "PUT";
bncce36dca22015-04-21 22:11:238912 request.url = GURL("http://www.example.org/");
[email protected]1c773ea12009-04-28 19:58:428913
danakj1fd259a02016-04-16 03:17:098914 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:168915 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:278916
[email protected]1c773ea12009-04-28 19:58:428917 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:238918 MockWrite(
8919 "PUT / HTTP/1.1\r\n"
8920 "Host: www.example.org\r\n"
8921 "Connection: keep-alive\r\n"
8922 "Content-Length: 0\r\n\r\n"),
[email protected]1c773ea12009-04-28 19:58:428923 };
8924
8925 // Lastly, the server responds with the actual content.
8926 MockRead data_reads[] = {
8927 MockRead("HTTP/1.0 200 OK\r\n"),
8928 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
8929 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:068930 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:428931 };
8932
[email protected]31a2bfe2010-02-09 08:03:398933 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
8934 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:078935 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:428936
[email protected]49639fa2011-12-20 23:22:418937 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:428938
tfarina42834112016-09-22 13:38:208939 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:018940 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]1c773ea12009-04-28 19:58:428941
8942 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:018943 EXPECT_THAT(rv, IsOk());
[email protected]1c773ea12009-04-28 19:58:428944}
8945
bncd16676a2016-07-20 16:23:018946TEST_F(HttpNetworkTransactionTest, BuildRequest_HeadContentLengthZero) {
[email protected]1c773ea12009-04-28 19:58:428947 HttpRequestInfo request;
8948 request.method = "HEAD";
bncce36dca22015-04-21 22:11:238949 request.url = GURL("http://www.example.org/");
[email protected]1c773ea12009-04-28 19:58:428950
danakj1fd259a02016-04-16 03:17:098951 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:168952 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:278953
[email protected]1c773ea12009-04-28 19:58:428954 MockWrite data_writes[] = {
csharrisonf473dd192015-08-18 13:54:138955 MockWrite("HEAD / HTTP/1.1\r\n"
8956 "Host: www.example.org\r\n"
8957 "Connection: keep-alive\r\n\r\n"),
[email protected]1c773ea12009-04-28 19:58:428958 };
8959
8960 // Lastly, the server responds with the actual content.
8961 MockRead data_reads[] = {
8962 MockRead("HTTP/1.0 200 OK\r\n"),
8963 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
8964 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:068965 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:428966 };
8967
[email protected]31a2bfe2010-02-09 08:03:398968 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
8969 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:078970 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:428971
[email protected]49639fa2011-12-20 23:22:418972 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:428973
tfarina42834112016-09-22 13:38:208974 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:018975 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]1c773ea12009-04-28 19:58:428976
8977 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:018978 EXPECT_THAT(rv, IsOk());
[email protected]1c773ea12009-04-28 19:58:428979}
8980
bncd16676a2016-07-20 16:23:018981TEST_F(HttpNetworkTransactionTest, BuildRequest_CacheControlNoCache) {
[email protected]1c773ea12009-04-28 19:58:428982 HttpRequestInfo request;
8983 request.method = "GET";
bncce36dca22015-04-21 22:11:238984 request.url = GURL("http://www.example.org/");
[email protected]1c773ea12009-04-28 19:58:428985 request.load_flags = LOAD_BYPASS_CACHE;
8986
danakj1fd259a02016-04-16 03:17:098987 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:168988 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:278989
[email protected]1c773ea12009-04-28 19:58:428990 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:238991 MockWrite(
8992 "GET / HTTP/1.1\r\n"
8993 "Host: www.example.org\r\n"
8994 "Connection: keep-alive\r\n"
8995 "Pragma: no-cache\r\n"
8996 "Cache-Control: no-cache\r\n\r\n"),
[email protected]1c773ea12009-04-28 19:58:428997 };
8998
8999 // Lastly, the server responds with the actual content.
9000 MockRead data_reads[] = {
9001 MockRead("HTTP/1.0 200 OK\r\n"),
9002 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
9003 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:069004 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:429005 };
9006
[email protected]31a2bfe2010-02-09 08:03:399007 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
9008 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:079009 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:429010
[email protected]49639fa2011-12-20 23:22:419011 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:429012
tfarina42834112016-09-22 13:38:209013 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:019014 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]1c773ea12009-04-28 19:58:429015
9016 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:019017 EXPECT_THAT(rv, IsOk());
[email protected]1c773ea12009-04-28 19:58:429018}
9019
bncd16676a2016-07-20 16:23:019020TEST_F(HttpNetworkTransactionTest, BuildRequest_CacheControlValidateCache) {
[email protected]1c773ea12009-04-28 19:58:429021 HttpRequestInfo request;
9022 request.method = "GET";
bncce36dca22015-04-21 22:11:239023 request.url = GURL("http://www.example.org/");
[email protected]1c773ea12009-04-28 19:58:429024 request.load_flags = LOAD_VALIDATE_CACHE;
9025
danakj1fd259a02016-04-16 03:17:099026 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:169027 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:279028
[email protected]1c773ea12009-04-28 19:58:429029 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:239030 MockWrite(
9031 "GET / HTTP/1.1\r\n"
9032 "Host: www.example.org\r\n"
9033 "Connection: keep-alive\r\n"
9034 "Cache-Control: max-age=0\r\n\r\n"),
[email protected]1c773ea12009-04-28 19:58:429035 };
9036
9037 // Lastly, the server responds with the actual content.
9038 MockRead data_reads[] = {
9039 MockRead("HTTP/1.0 200 OK\r\n"),
9040 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
9041 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:069042 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:429043 };
9044
[email protected]31a2bfe2010-02-09 08:03:399045 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
9046 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:079047 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:429048
[email protected]49639fa2011-12-20 23:22:419049 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:429050
tfarina42834112016-09-22 13:38:209051 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:019052 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]1c773ea12009-04-28 19:58:429053
9054 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:019055 EXPECT_THAT(rv, IsOk());
[email protected]1c773ea12009-04-28 19:58:429056}
9057
bncd16676a2016-07-20 16:23:019058TEST_F(HttpNetworkTransactionTest, BuildRequest_ExtraHeaders) {
[email protected]1c773ea12009-04-28 19:58:429059 HttpRequestInfo request;
9060 request.method = "GET";
bncce36dca22015-04-21 22:11:239061 request.url = GURL("http://www.example.org/");
[email protected]8c76ae22010-04-20 22:15:439062 request.extra_headers.SetHeader("FooHeader", "Bar");
[email protected]1c773ea12009-04-28 19:58:429063
danakj1fd259a02016-04-16 03:17:099064 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:169065 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:279066
[email protected]1c773ea12009-04-28 19:58:429067 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:239068 MockWrite(
9069 "GET / HTTP/1.1\r\n"
9070 "Host: www.example.org\r\n"
9071 "Connection: keep-alive\r\n"
9072 "FooHeader: Bar\r\n\r\n"),
[email protected]1c773ea12009-04-28 19:58:429073 };
9074
9075 // Lastly, the server responds with the actual content.
9076 MockRead data_reads[] = {
9077 MockRead("HTTP/1.0 200 OK\r\n"),
9078 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
9079 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:069080 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:429081 };
9082
[email protected]31a2bfe2010-02-09 08:03:399083 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
9084 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:079085 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:429086
[email protected]49639fa2011-12-20 23:22:419087 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:429088
tfarina42834112016-09-22 13:38:209089 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:019090 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]1c773ea12009-04-28 19:58:429091
9092 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:019093 EXPECT_THAT(rv, IsOk());
[email protected]1c773ea12009-04-28 19:58:429094}
9095
bncd16676a2016-07-20 16:23:019096TEST_F(HttpNetworkTransactionTest, BuildRequest_ExtraHeadersStripped) {
[email protected]270c6412010-03-29 22:02:479097 HttpRequestInfo request;
9098 request.method = "GET";
bncce36dca22015-04-21 22:11:239099 request.url = GURL("http://www.example.org/");
[email protected]8c76ae22010-04-20 22:15:439100 request.extra_headers.SetHeader("referer", "www.foo.com");
9101 request.extra_headers.SetHeader("hEllo", "Kitty");
9102 request.extra_headers.SetHeader("FoO", "bar");
[email protected]270c6412010-03-29 22:02:479103
danakj1fd259a02016-04-16 03:17:099104 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:169105 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:279106
[email protected]270c6412010-03-29 22:02:479107 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:239108 MockWrite(
9109 "GET / HTTP/1.1\r\n"
9110 "Host: www.example.org\r\n"
9111 "Connection: keep-alive\r\n"
9112 "referer: www.foo.com\r\n"
9113 "hEllo: Kitty\r\n"
9114 "FoO: bar\r\n\r\n"),
[email protected]270c6412010-03-29 22:02:479115 };
9116
9117 // Lastly, the server responds with the actual content.
9118 MockRead data_reads[] = {
9119 MockRead("HTTP/1.0 200 OK\r\n"),
9120 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
9121 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:069122 MockRead(SYNCHRONOUS, OK),
[email protected]270c6412010-03-29 22:02:479123 };
9124
9125 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
9126 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:079127 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]270c6412010-03-29 22:02:479128
[email protected]49639fa2011-12-20 23:22:419129 TestCompletionCallback callback;
[email protected]270c6412010-03-29 22:02:479130
tfarina42834112016-09-22 13:38:209131 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:019132 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]270c6412010-03-29 22:02:479133
9134 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:019135 EXPECT_THAT(rv, IsOk());
[email protected]270c6412010-03-29 22:02:479136}
9137
bncd16676a2016-07-20 16:23:019138TEST_F(HttpNetworkTransactionTest, SOCKS4_HTTP_GET) {
[email protected]cb9bf6ca2011-01-28 13:15:279139 HttpRequestInfo request;
9140 request.method = "GET";
bncce36dca22015-04-21 22:11:239141 request.url = GURL("http://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:279142
rdsmith82957ad2015-09-16 19:42:039143 session_deps_.proxy_service =
9144 ProxyService::CreateFixedFromPacResult("SOCKS myproxy:1080");
vishal.b62985ca92015-04-17 08:45:519145 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:079146 session_deps_.net_log = &net_log;
[email protected]3cd17242009-06-23 02:59:029147
danakj1fd259a02016-04-16 03:17:099148 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:169149 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]3cd17242009-06-23 02:59:029150
[email protected]3cd17242009-06-23 02:59:029151 char write_buffer[] = { 0x04, 0x01, 0x00, 0x50, 127, 0, 0, 1, 0 };
9152 char read_buffer[] = { 0x00, 0x5A, 0x00, 0x00, 0, 0, 0, 0 };
9153
9154 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:239155 MockWrite(ASYNC, write_buffer, arraysize(write_buffer)),
9156 MockWrite(
9157 "GET / HTTP/1.1\r\n"
9158 "Host: www.example.org\r\n"
9159 "Connection: keep-alive\r\n\r\n")};
[email protected]3cd17242009-06-23 02:59:029160
9161 MockRead data_reads[] = {
[email protected]8ddf8322012-02-23 18:08:069162 MockRead(ASYNC, read_buffer, arraysize(read_buffer)),
[email protected]3cd17242009-06-23 02:59:029163 MockRead("HTTP/1.0 200 OK\r\n"),
9164 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n\r\n"),
9165 MockRead("Payload"),
[email protected]8ddf8322012-02-23 18:08:069166 MockRead(SYNCHRONOUS, OK)
[email protected]3cd17242009-06-23 02:59:029167 };
9168
[email protected]31a2bfe2010-02-09 08:03:399169 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
9170 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:079171 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]3cd17242009-06-23 02:59:029172
[email protected]49639fa2011-12-20 23:22:419173 TestCompletionCallback callback;
[email protected]3cd17242009-06-23 02:59:029174
tfarina42834112016-09-22 13:38:209175 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:019176 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]3cd17242009-06-23 02:59:029177
9178 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:019179 EXPECT_THAT(rv, IsOk());
[email protected]3cd17242009-06-23 02:59:029180
bnc691fda62016-08-12 00:43:169181 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:529182 ASSERT_TRUE(response);
[email protected]3cd17242009-06-23 02:59:029183
tbansal2ecbbc72016-10-06 17:15:479184 EXPECT_EQ(ProxyServer::SCHEME_SOCKS4, response->proxy_server.scheme());
[email protected]029c83b62013-01-24 05:28:209185 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:169186 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]029c83b62013-01-24 05:28:209187 TestLoadTimingNotReusedWithPac(load_timing_info,
9188 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
9189
[email protected]3cd17242009-06-23 02:59:029190 std::string response_text;
bnc691fda62016-08-12 00:43:169191 rv = ReadTransaction(&trans, &response_text);
robpercival214763f2016-07-01 23:27:019192 EXPECT_THAT(rv, IsOk());
[email protected]3cd17242009-06-23 02:59:029193 EXPECT_EQ("Payload", response_text);
9194}
9195
bncd16676a2016-07-20 16:23:019196TEST_F(HttpNetworkTransactionTest, SOCKS4_SSL_GET) {
[email protected]cb9bf6ca2011-01-28 13:15:279197 HttpRequestInfo request;
9198 request.method = "GET";
bncce36dca22015-04-21 22:11:239199 request.url = GURL("https://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 unsigned char write_buffer[] = { 0x04, 0x01, 0x01, 0xBB, 127, 0, 0, 1, 0 };
9210 unsigned char read_buffer[] = { 0x00, 0x5A, 0x00, 0x00, 0, 0, 0, 0 };
9211
9212 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:239213 MockWrite(ASYNC, reinterpret_cast<char*>(write_buffer),
9214 arraysize(write_buffer)),
9215 MockWrite(
9216 "GET / HTTP/1.1\r\n"
9217 "Host: www.example.org\r\n"
9218 "Connection: keep-alive\r\n\r\n")};
[email protected]3cd17242009-06-23 02:59:029219
9220 MockRead data_reads[] = {
[email protected]f871ee152012-07-27 19:02:019221 MockRead(ASYNC, reinterpret_cast<char*>(read_buffer),
9222 arraysize(read_buffer)),
[email protected]e0c27be2009-07-15 13:09:359223 MockRead("HTTP/1.0 200 OK\r\n"),
9224 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n\r\n"),
9225 MockRead("Payload"),
[email protected]8ddf8322012-02-23 18:08:069226 MockRead(SYNCHRONOUS, OK)
[email protected]e0c27be2009-07-15 13:09:359227 };
9228
[email protected]31a2bfe2010-02-09 08:03:399229 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
9230 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:079231 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]e0c27be2009-07-15 13:09:359232
[email protected]8ddf8322012-02-23 18:08:069233 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:079234 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]e0c27be2009-07-15 13:09:359235
[email protected]49639fa2011-12-20 23:22:419236 TestCompletionCallback callback;
[email protected]e0c27be2009-07-15 13:09:359237
tfarina42834112016-09-22 13:38:209238 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:019239 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]e0c27be2009-07-15 13:09:359240
9241 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:019242 EXPECT_THAT(rv, IsOk());
[email protected]e0c27be2009-07-15 13:09:359243
[email protected]029c83b62013-01-24 05:28:209244 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:169245 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]029c83b62013-01-24 05:28:209246 TestLoadTimingNotReusedWithPac(load_timing_info,
9247 CONNECT_TIMING_HAS_SSL_TIMES);
9248
bnc691fda62016-08-12 00:43:169249 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:529250 ASSERT_TRUE(response);
tbansal2ecbbc72016-10-06 17:15:479251 EXPECT_EQ(ProxyServer::SCHEME_SOCKS4, response->proxy_server.scheme());
[email protected]e0c27be2009-07-15 13:09:359252
9253 std::string response_text;
bnc691fda62016-08-12 00:43:169254 rv = ReadTransaction(&trans, &response_text);
robpercival214763f2016-07-01 23:27:019255 EXPECT_THAT(rv, IsOk());
[email protected]e0c27be2009-07-15 13:09:359256 EXPECT_EQ("Payload", response_text);
9257}
9258
bncd16676a2016-07-20 16:23:019259TEST_F(HttpNetworkTransactionTest, SOCKS4_HTTP_GET_no_PAC) {
[email protected]029c83b62013-01-24 05:28:209260 HttpRequestInfo request;
9261 request.method = "GET";
bncce36dca22015-04-21 22:11:239262 request.url = GURL("http://www.example.org/");
[email protected]029c83b62013-01-24 05:28:209263
rdsmith82957ad2015-09-16 19:42:039264 session_deps_.proxy_service =
9265 ProxyService::CreateFixed("socks4://myproxy:1080");
vishal.b62985ca92015-04-17 08:45:519266 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:079267 session_deps_.net_log = &net_log;
[email protected]029c83b62013-01-24 05:28:209268
danakj1fd259a02016-04-16 03:17:099269 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:169270 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]029c83b62013-01-24 05:28:209271
9272 char write_buffer[] = { 0x04, 0x01, 0x00, 0x50, 127, 0, 0, 1, 0 };
9273 char read_buffer[] = { 0x00, 0x5A, 0x00, 0x00, 0, 0, 0, 0 };
9274
9275 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:239276 MockWrite(ASYNC, write_buffer, arraysize(write_buffer)),
9277 MockWrite(
9278 "GET / HTTP/1.1\r\n"
9279 "Host: www.example.org\r\n"
9280 "Connection: keep-alive\r\n\r\n")};
[email protected]029c83b62013-01-24 05:28:209281
9282 MockRead data_reads[] = {
9283 MockRead(ASYNC, read_buffer, arraysize(read_buffer)),
9284 MockRead("HTTP/1.0 200 OK\r\n"),
9285 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n\r\n"),
9286 MockRead("Payload"),
9287 MockRead(SYNCHRONOUS, OK)
9288 };
9289
9290 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
9291 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:079292 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]029c83b62013-01-24 05:28:209293
9294 TestCompletionCallback callback;
9295
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]029c83b62013-01-24 05:28:209298
9299 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:019300 EXPECT_THAT(rv, IsOk());
[email protected]029c83b62013-01-24 05:28:209301
bnc691fda62016-08-12 00:43:169302 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:529303 ASSERT_TRUE(response);
[email protected]029c83b62013-01-24 05:28:209304
9305 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:169306 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]029c83b62013-01-24 05:28:209307 TestLoadTimingNotReused(load_timing_info,
9308 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
9309
9310 std::string response_text;
bnc691fda62016-08-12 00:43:169311 rv = ReadTransaction(&trans, &response_text);
robpercival214763f2016-07-01 23:27:019312 EXPECT_THAT(rv, IsOk());
[email protected]029c83b62013-01-24 05:28:209313 EXPECT_EQ("Payload", response_text);
9314}
9315
bncd16676a2016-07-20 16:23:019316TEST_F(HttpNetworkTransactionTest, SOCKS5_HTTP_GET) {
[email protected]cb9bf6ca2011-01-28 13:15:279317 HttpRequestInfo request;
9318 request.method = "GET";
bncce36dca22015-04-21 22:11:239319 request.url = GURL("http://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:279320
rdsmith82957ad2015-09-16 19:42:039321 session_deps_.proxy_service =
9322 ProxyService::CreateFixedFromPacResult("SOCKS5 myproxy:1080");
vishal.b62985ca92015-04-17 08:45:519323 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:079324 session_deps_.net_log = &net_log;
[email protected]e0c27be2009-07-15 13:09:359325
danakj1fd259a02016-04-16 03:17:099326 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:169327 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]e0c27be2009-07-15 13:09:359328
[email protected]e0c27be2009-07-15 13:09:359329 const char kSOCKS5GreetRequest[] = { 0x05, 0x01, 0x00 };
9330 const char kSOCKS5GreetResponse[] = { 0x05, 0x00 };
[email protected]f209dba2009-12-18 00:24:379331 const char kSOCKS5OkRequest[] = {
bncce36dca22015-04-21 22:11:239332 0x05, // Version
9333 0x01, // Command (CONNECT)
9334 0x00, // Reserved.
9335 0x03, // Address type (DOMAINNAME).
9336 0x0F, // Length of domain (15)
9337 'w', 'w', 'w', '.', 'e', 'x', 'a', 'm', 'p', 'l', 'e', // Domain string
9338 '.', 'o', 'r', 'g', 0x00, 0x50, // 16-bit port (80)
[email protected]f209dba2009-12-18 00:24:379339 };
[email protected]e0c27be2009-07-15 13:09:359340 const char kSOCKS5OkResponse[] =
9341 { 0x05, 0x00, 0x00, 0x01, 127, 0, 0, 1, 0x00, 0x50 };
9342
9343 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:239344 MockWrite(ASYNC, kSOCKS5GreetRequest, arraysize(kSOCKS5GreetRequest)),
9345 MockWrite(ASYNC, kSOCKS5OkRequest, arraysize(kSOCKS5OkRequest)),
9346 MockWrite(
9347 "GET / HTTP/1.1\r\n"
9348 "Host: www.example.org\r\n"
9349 "Connection: keep-alive\r\n\r\n")};
[email protected]e0c27be2009-07-15 13:09:359350
9351 MockRead data_reads[] = {
[email protected]f871ee152012-07-27 19:02:019352 MockRead(ASYNC, kSOCKS5GreetResponse, arraysize(kSOCKS5GreetResponse)),
9353 MockRead(ASYNC, kSOCKS5OkResponse, arraysize(kSOCKS5OkResponse)),
[email protected]e0c27be2009-07-15 13:09:359354 MockRead("HTTP/1.0 200 OK\r\n"),
9355 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n\r\n"),
9356 MockRead("Payload"),
[email protected]8ddf8322012-02-23 18:08:069357 MockRead(SYNCHRONOUS, OK)
[email protected]e0c27be2009-07-15 13:09:359358 };
9359
[email protected]31a2bfe2010-02-09 08:03:399360 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
9361 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:079362 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]e0c27be2009-07-15 13:09:359363
[email protected]49639fa2011-12-20 23:22:419364 TestCompletionCallback callback;
[email protected]e0c27be2009-07-15 13:09:359365
tfarina42834112016-09-22 13:38:209366 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:019367 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]e0c27be2009-07-15 13:09:359368
9369 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:019370 EXPECT_THAT(rv, IsOk());
[email protected]e0c27be2009-07-15 13:09:359371
bnc691fda62016-08-12 00:43:169372 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:529373 ASSERT_TRUE(response);
tbansal2ecbbc72016-10-06 17:15:479374 EXPECT_EQ(ProxyServer::SCHEME_SOCKS5, response->proxy_server.scheme());
[email protected]e0c27be2009-07-15 13:09:359375
[email protected]029c83b62013-01-24 05:28:209376 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:169377 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]029c83b62013-01-24 05:28:209378 TestLoadTimingNotReusedWithPac(load_timing_info,
9379 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
9380
[email protected]e0c27be2009-07-15 13:09:359381 std::string response_text;
bnc691fda62016-08-12 00:43:169382 rv = ReadTransaction(&trans, &response_text);
robpercival214763f2016-07-01 23:27:019383 EXPECT_THAT(rv, IsOk());
[email protected]e0c27be2009-07-15 13:09:359384 EXPECT_EQ("Payload", response_text);
9385}
9386
bncd16676a2016-07-20 16:23:019387TEST_F(HttpNetworkTransactionTest, SOCKS5_SSL_GET) {
[email protected]cb9bf6ca2011-01-28 13:15:279388 HttpRequestInfo request;
9389 request.method = "GET";
bncce36dca22015-04-21 22:11:239390 request.url = GURL("https://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:279391
rdsmith82957ad2015-09-16 19:42:039392 session_deps_.proxy_service =
9393 ProxyService::CreateFixedFromPacResult("SOCKS5 myproxy:1080");
vishal.b62985ca92015-04-17 08:45:519394 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:079395 session_deps_.net_log = &net_log;
[email protected]e0c27be2009-07-15 13:09:359396
danakj1fd259a02016-04-16 03:17:099397 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:169398 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]e0c27be2009-07-15 13:09:359399
[email protected]e0c27be2009-07-15 13:09:359400 const char kSOCKS5GreetRequest[] = { 0x05, 0x01, 0x00 };
9401 const char kSOCKS5GreetResponse[] = { 0x05, 0x00 };
[email protected]f209dba2009-12-18 00:24:379402 const unsigned char kSOCKS5OkRequest[] = {
bncce36dca22015-04-21 22:11:239403 0x05, // Version
9404 0x01, // Command (CONNECT)
9405 0x00, // Reserved.
9406 0x03, // Address type (DOMAINNAME).
9407 0x0F, // Length of domain (15)
9408 'w', 'w', 'w', '.', 'e', 'x', 'a', 'm', 'p', 'l', 'e', // Domain string
9409 '.', 'o', 'r', 'g', 0x01, 0xBB, // 16-bit port (443)
[email protected]f209dba2009-12-18 00:24:379410 };
9411
[email protected]e0c27be2009-07-15 13:09:359412 const char kSOCKS5OkResponse[] =
9413 { 0x05, 0x00, 0x00, 0x01, 0, 0, 0, 0, 0x00, 0x00 };
9414
9415 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:239416 MockWrite(ASYNC, kSOCKS5GreetRequest, arraysize(kSOCKS5GreetRequest)),
9417 MockWrite(ASYNC, reinterpret_cast<const char*>(kSOCKS5OkRequest),
9418 arraysize(kSOCKS5OkRequest)),
9419 MockWrite(
9420 "GET / HTTP/1.1\r\n"
9421 "Host: www.example.org\r\n"
9422 "Connection: keep-alive\r\n\r\n")};
[email protected]e0c27be2009-07-15 13:09:359423
9424 MockRead data_reads[] = {
[email protected]f871ee152012-07-27 19:02:019425 MockRead(ASYNC, kSOCKS5GreetResponse, arraysize(kSOCKS5GreetResponse)),
9426 MockRead(ASYNC, kSOCKS5OkResponse, arraysize(kSOCKS5OkResponse)),
[email protected]3cd17242009-06-23 02:59:029427 MockRead("HTTP/1.0 200 OK\r\n"),
9428 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n\r\n"),
9429 MockRead("Payload"),
[email protected]8ddf8322012-02-23 18:08:069430 MockRead(SYNCHRONOUS, OK)
[email protected]3cd17242009-06-23 02:59:029431 };
9432
[email protected]31a2bfe2010-02-09 08:03:399433 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
9434 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:079435 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]3cd17242009-06-23 02:59:029436
[email protected]8ddf8322012-02-23 18:08:069437 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:079438 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]3cd17242009-06-23 02:59:029439
[email protected]49639fa2011-12-20 23:22:419440 TestCompletionCallback callback;
[email protected]3cd17242009-06-23 02:59:029441
tfarina42834112016-09-22 13:38:209442 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:019443 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]3cd17242009-06-23 02:59:029444
9445 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:019446 EXPECT_THAT(rv, IsOk());
[email protected]3cd17242009-06-23 02:59:029447
bnc691fda62016-08-12 00:43:169448 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:529449 ASSERT_TRUE(response);
tbansal2ecbbc72016-10-06 17:15:479450 EXPECT_EQ(ProxyServer::SCHEME_SOCKS5, response->proxy_server.scheme());
[email protected]3cd17242009-06-23 02:59:029451
[email protected]029c83b62013-01-24 05:28:209452 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:169453 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]029c83b62013-01-24 05:28:209454 TestLoadTimingNotReusedWithPac(load_timing_info,
9455 CONNECT_TIMING_HAS_SSL_TIMES);
9456
[email protected]3cd17242009-06-23 02:59:029457 std::string response_text;
bnc691fda62016-08-12 00:43:169458 rv = ReadTransaction(&trans, &response_text);
robpercival214763f2016-07-01 23:27:019459 EXPECT_THAT(rv, IsOk());
[email protected]3cd17242009-06-23 02:59:029460 EXPECT_EQ("Payload", response_text);
9461}
9462
[email protected]448d4ca52012-03-04 04:12:239463namespace {
9464
[email protected]04e5be32009-06-26 20:00:319465// Tests that for connection endpoints the group names are correctly set.
[email protected]2d731a32010-04-29 01:04:069466
9467struct GroupNameTest {
9468 std::string proxy_server;
9469 std::string url;
9470 std::string expected_group_name;
[email protected]e60e47a2010-07-14 03:37:189471 bool ssl;
[email protected]2d731a32010-04-29 01:04:069472};
9473
danakj1fd259a02016-04-16 03:17:099474std::unique_ptr<HttpNetworkSession> SetupSessionForGroupNameTests(
[email protected]bb88e1d32013-05-03 23:11:079475 SpdySessionDependencies* session_deps_) {
danakj1fd259a02016-04-16 03:17:099476 std::unique_ptr<HttpNetworkSession> session(CreateSession(session_deps_));
[email protected]2d731a32010-04-29 01:04:069477
bnc525e175a2016-06-20 12:36:409478 HttpServerProperties* http_server_properties =
[email protected]17291a022011-10-10 07:32:539479 session->http_server_properties();
bnc3472afd2016-11-17 15:27:219480 AlternativeService alternative_service(kProtoHTTP2, "", 444);
bnc7dc7e1b42015-07-28 14:43:129481 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:219482 http_server_properties->SetHttp2AlternativeService(
bncaa60ff402016-06-22 19:12:429483 url::SchemeHostPort("https", "host.with.alternate", 443),
zhongyi3d4a55e72016-04-22 20:36:469484 alternative_service, expiration);
[email protected]2d731a32010-04-29 01:04:069485
9486 return session;
9487}
9488
mmenkee65e7af2015-10-13 17:16:429489int GroupNameTransactionHelper(const std::string& url,
9490 HttpNetworkSession* session) {
[email protected]2d731a32010-04-29 01:04:069491 HttpRequestInfo request;
9492 request.method = "GET";
9493 request.url = GURL(url);
[email protected]2d731a32010-04-29 01:04:069494
bnc691fda62016-08-12 00:43:169495 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session);
[email protected]cb9bf6ca2011-01-28 13:15:279496
[email protected]49639fa2011-12-20 23:22:419497 TestCompletionCallback callback;
[email protected]2d731a32010-04-29 01:04:069498
9499 // We do not complete this request, the dtor will clean the transaction up.
tfarina42834112016-09-22 13:38:209500 return trans.Start(&request, callback.callback(), NetLogWithSource());
[email protected]2d731a32010-04-29 01:04:069501}
9502
[email protected]448d4ca52012-03-04 04:12:239503} // namespace
9504
bncd16676a2016-07-20 16:23:019505TEST_F(HttpNetworkTransactionTest, GroupNameForDirectConnections) {
[email protected]2d731a32010-04-29 01:04:069506 const GroupNameTest tests[] = {
bncce36dca22015-04-21 22:11:239507 {
9508 "", // unused
9509 "http://www.example.org/direct",
9510 "www.example.org:80",
9511 false,
9512 },
9513 {
9514 "", // unused
9515 "http://[2001:1418:13:1::25]/direct",
9516 "[2001:1418:13:1::25]:80",
9517 false,
9518 },
[email protected]04e5be32009-06-26 20:00:319519
bncce36dca22015-04-21 22:11:239520 // SSL Tests
9521 {
9522 "", // unused
9523 "https://www.example.org/direct_ssl",
9524 "ssl/www.example.org:443",
9525 true,
9526 },
9527 {
9528 "", // unused
9529 "https://[2001:1418:13:1::25]/direct",
9530 "ssl/[2001:1418:13:1::25]:443",
9531 true,
9532 },
9533 {
9534 "", // unused
bncaa60ff402016-06-22 19:12:429535 "https://host.with.alternate/direct",
bncce36dca22015-04-21 22:11:239536 "ssl/host.with.alternate:443",
9537 true,
9538 },
[email protected]2d731a32010-04-29 01:04:069539 };
[email protected]2ff8b312010-04-26 22:20:549540
viettrungluue4a8b882014-10-16 06:17:389541 for (size_t i = 0; i < arraysize(tests); ++i) {
rdsmith82957ad2015-09-16 19:42:039542 session_deps_.proxy_service =
9543 ProxyService::CreateFixed(tests[i].proxy_server);
danakj1fd259a02016-04-16 03:17:099544 std::unique_ptr<HttpNetworkSession> session(
bnca9b9e222016-07-11 20:10:409545 SetupSessionForGroupNameTests(&session_deps_));
[email protected]2d731a32010-04-29 01:04:069546
mmenkee65e7af2015-10-13 17:16:429547 HttpNetworkSessionPeer peer(session.get());
[email protected]ab739042011-04-07 15:22:289548 CaptureGroupNameTransportSocketPool* transport_conn_pool =
bnc87dcefc2017-05-25 12:47:589549 new CaptureGroupNameTransportSocketPool(nullptr, nullptr);
[email protected]2431756e2010-09-29 20:26:139550 CaptureGroupNameSSLSocketPool* ssl_conn_pool =
bnc87dcefc2017-05-25 12:47:589551 new CaptureGroupNameSSLSocketPool(nullptr, nullptr);
Jeremy Roman0579ed62017-08-29 15:56:199552 auto mock_pool_manager = std::make_unique<MockClientSocketPoolManager>();
[email protected]a42dbd142011-11-17 16:42:029553 mock_pool_manager->SetTransportSocketPool(transport_conn_pool);
9554 mock_pool_manager->SetSSLSocketPool(ssl_conn_pool);
dchengc7eeda422015-12-26 03:56:489555 peer.SetClientSocketPoolManager(std::move(mock_pool_manager));
[email protected]2d731a32010-04-29 01:04:069556
9557 EXPECT_EQ(ERR_IO_PENDING,
mmenkee65e7af2015-10-13 17:16:429558 GroupNameTransactionHelper(tests[i].url, session.get()));
[email protected]e60e47a2010-07-14 03:37:189559 if (tests[i].ssl)
9560 EXPECT_EQ(tests[i].expected_group_name,
9561 ssl_conn_pool->last_group_name_received());
9562 else
9563 EXPECT_EQ(tests[i].expected_group_name,
[email protected]ab739042011-04-07 15:22:289564 transport_conn_pool->last_group_name_received());
[email protected]2d731a32010-04-29 01:04:069565 }
[email protected]2d731a32010-04-29 01:04:069566}
9567
bncd16676a2016-07-20 16:23:019568TEST_F(HttpNetworkTransactionTest, GroupNameForHTTPProxyConnections) {
[email protected]2d731a32010-04-29 01:04:069569 const GroupNameTest tests[] = {
bncce36dca22015-04-21 22:11:239570 {
9571 "http_proxy",
9572 "http://www.example.org/http_proxy_normal",
9573 "www.example.org:80",
9574 false,
9575 },
[email protected]2d731a32010-04-29 01:04:069576
bncce36dca22015-04-21 22:11:239577 // SSL Tests
9578 {
9579 "http_proxy",
9580 "https://www.example.org/http_connect_ssl",
9581 "ssl/www.example.org:443",
9582 true,
9583 },
[email protected]af3490e2010-10-16 21:02:299584
bncce36dca22015-04-21 22:11:239585 {
9586 "http_proxy",
bncaa60ff402016-06-22 19:12:429587 "https://host.with.alternate/direct",
bncce36dca22015-04-21 22:11:239588 "ssl/host.with.alternate:443",
9589 true,
9590 },
[email protected]45499252013-01-23 17:12:569591
bncce36dca22015-04-21 22:11:239592 {
9593 "http_proxy",
9594 "ftp://ftp.google.com/http_proxy_normal",
9595 "ftp/ftp.google.com:21",
9596 false,
9597 },
[email protected]2d731a32010-04-29 01:04:069598 };
9599
viettrungluue4a8b882014-10-16 06:17:389600 for (size_t i = 0; i < arraysize(tests); ++i) {
rdsmith82957ad2015-09-16 19:42:039601 session_deps_.proxy_service =
9602 ProxyService::CreateFixed(tests[i].proxy_server);
danakj1fd259a02016-04-16 03:17:099603 std::unique_ptr<HttpNetworkSession> session(
bnca9b9e222016-07-11 20:10:409604 SetupSessionForGroupNameTests(&session_deps_));
[email protected]2d731a32010-04-29 01:04:069605
mmenkee65e7af2015-10-13 17:16:429606 HttpNetworkSessionPeer peer(session.get());
[email protected]2d731a32010-04-29 01:04:069607
[email protected]e60e47a2010-07-14 03:37:189608 HostPortPair proxy_host("http_proxy", 80);
[email protected]2431756e2010-09-29 20:26:139609 CaptureGroupNameHttpProxySocketPool* http_proxy_pool =
[email protected]9e1bdd32011-02-03 21:48:349610 new CaptureGroupNameHttpProxySocketPool(NULL, NULL);
[email protected]2431756e2010-09-29 20:26:139611 CaptureGroupNameSSLSocketPool* ssl_conn_pool =
[email protected]9e1bdd32011-02-03 21:48:349612 new CaptureGroupNameSSLSocketPool(NULL, NULL);
Jeremy Roman0579ed62017-08-29 15:56:199613 auto mock_pool_manager = std::make_unique<MockClientSocketPoolManager>();
aviadef3442016-10-03 18:50:399614 mock_pool_manager->SetSocketPoolForHTTPProxy(
9615 proxy_host, base::WrapUnique(http_proxy_pool));
9616 mock_pool_manager->SetSocketPoolForSSLWithProxy(
9617 proxy_host, base::WrapUnique(ssl_conn_pool));
dchengc7eeda422015-12-26 03:56:489618 peer.SetClientSocketPoolManager(std::move(mock_pool_manager));
[email protected]2d731a32010-04-29 01:04:069619
9620 EXPECT_EQ(ERR_IO_PENDING,
mmenkee65e7af2015-10-13 17:16:429621 GroupNameTransactionHelper(tests[i].url, session.get()));
[email protected]e60e47a2010-07-14 03:37:189622 if (tests[i].ssl)
9623 EXPECT_EQ(tests[i].expected_group_name,
9624 ssl_conn_pool->last_group_name_received());
9625 else
9626 EXPECT_EQ(tests[i].expected_group_name,
9627 http_proxy_pool->last_group_name_received());
[email protected]2d731a32010-04-29 01:04:069628 }
[email protected]2d731a32010-04-29 01:04:069629}
9630
bncd16676a2016-07-20 16:23:019631TEST_F(HttpNetworkTransactionTest, GroupNameForSOCKSConnections) {
[email protected]2d731a32010-04-29 01:04:069632 const GroupNameTest tests[] = {
bncce36dca22015-04-21 22:11:239633 {
9634 "socks4://socks_proxy:1080",
9635 "http://www.example.org/socks4_direct",
9636 "socks4/www.example.org:80",
9637 false,
9638 },
9639 {
9640 "socks5://socks_proxy:1080",
9641 "http://www.example.org/socks5_direct",
9642 "socks5/www.example.org:80",
9643 false,
9644 },
[email protected]2d731a32010-04-29 01:04:069645
bncce36dca22015-04-21 22:11:239646 // SSL Tests
9647 {
9648 "socks4://socks_proxy:1080",
9649 "https://www.example.org/socks4_ssl",
9650 "socks4/ssl/www.example.org:443",
9651 true,
9652 },
9653 {
9654 "socks5://socks_proxy:1080",
9655 "https://www.example.org/socks5_ssl",
9656 "socks5/ssl/www.example.org:443",
9657 true,
9658 },
[email protected]af3490e2010-10-16 21:02:299659
bncce36dca22015-04-21 22:11:239660 {
9661 "socks4://socks_proxy:1080",
bncaa60ff402016-06-22 19:12:429662 "https://host.with.alternate/direct",
bncce36dca22015-04-21 22:11:239663 "socks4/ssl/host.with.alternate:443",
9664 true,
9665 },
[email protected]04e5be32009-06-26 20:00:319666 };
9667
viettrungluue4a8b882014-10-16 06:17:389668 for (size_t i = 0; i < arraysize(tests); ++i) {
rdsmith82957ad2015-09-16 19:42:039669 session_deps_.proxy_service =
9670 ProxyService::CreateFixed(tests[i].proxy_server);
danakj1fd259a02016-04-16 03:17:099671 std::unique_ptr<HttpNetworkSession> session(
bnca9b9e222016-07-11 20:10:409672 SetupSessionForGroupNameTests(&session_deps_));
[email protected]8b114dd72011-03-25 05:33:029673
mmenkee65e7af2015-10-13 17:16:429674 HttpNetworkSessionPeer peer(session.get());
[email protected]04e5be32009-06-26 20:00:319675
[email protected]e60e47a2010-07-14 03:37:189676 HostPortPair proxy_host("socks_proxy", 1080);
[email protected]2431756e2010-09-29 20:26:139677 CaptureGroupNameSOCKSSocketPool* socks_conn_pool =
[email protected]9e1bdd32011-02-03 21:48:349678 new CaptureGroupNameSOCKSSocketPool(NULL, NULL);
[email protected]2431756e2010-09-29 20:26:139679 CaptureGroupNameSSLSocketPool* ssl_conn_pool =
[email protected]9e1bdd32011-02-03 21:48:349680 new CaptureGroupNameSSLSocketPool(NULL, NULL);
Jeremy Roman0579ed62017-08-29 15:56:199681 auto mock_pool_manager = std::make_unique<MockClientSocketPoolManager>();
aviadef3442016-10-03 18:50:399682 mock_pool_manager->SetSocketPoolForSOCKSProxy(
9683 proxy_host, base::WrapUnique(socks_conn_pool));
9684 mock_pool_manager->SetSocketPoolForSSLWithProxy(
9685 proxy_host, base::WrapUnique(ssl_conn_pool));
dchengc7eeda422015-12-26 03:56:489686 peer.SetClientSocketPoolManager(std::move(mock_pool_manager));
[email protected]04e5be32009-06-26 20:00:319687
bnc691fda62016-08-12 00:43:169688 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]04e5be32009-06-26 20:00:319689
[email protected]2d731a32010-04-29 01:04:069690 EXPECT_EQ(ERR_IO_PENDING,
mmenkee65e7af2015-10-13 17:16:429691 GroupNameTransactionHelper(tests[i].url, session.get()));
[email protected]e60e47a2010-07-14 03:37:189692 if (tests[i].ssl)
9693 EXPECT_EQ(tests[i].expected_group_name,
9694 ssl_conn_pool->last_group_name_received());
9695 else
9696 EXPECT_EQ(tests[i].expected_group_name,
9697 socks_conn_pool->last_group_name_received());
[email protected]04e5be32009-06-26 20:00:319698 }
9699}
9700
bncd16676a2016-07-20 16:23:019701TEST_F(HttpNetworkTransactionTest, ReconsiderProxyAfterFailedConnection) {
[email protected]cb9bf6ca2011-01-28 13:15:279702 HttpRequestInfo request;
9703 request.method = "GET";
bncce36dca22015-04-21 22:11:239704 request.url = GURL("http://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:279705
rdsmith82957ad2015-09-16 19:42:039706 session_deps_.proxy_service =
9707 ProxyService::CreateFixed("myproxy:70;foobar:80");
[email protected]b59ff372009-07-15 22:04:329708
[email protected]69719062010-01-05 20:09:219709 // This simulates failure resolving all hostnames; that means we will fail
9710 // connecting to both proxies (myproxy:70 and foobar:80).
[email protected]bb88e1d32013-05-03 23:11:079711 session_deps_.host_resolver->rules()->AddSimulatedFailure("*");
[email protected]b59ff372009-07-15 22:04:329712
danakj1fd259a02016-04-16 03:17:099713 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:169714 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]9172a982009-06-06 00:30:259715
[email protected]49639fa2011-12-20 23:22:419716 TestCompletionCallback callback;
[email protected]9172a982009-06-06 00:30:259717
tfarina42834112016-09-22 13:38:209718 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:019719 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]9172a982009-06-06 00:30:259720
[email protected]9172a982009-06-06 00:30:259721 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:019722 EXPECT_THAT(rv, IsError(ERR_PROXY_CONNECTION_FAILED));
[email protected]9172a982009-06-06 00:30:259723}
9724
[email protected]685af592010-05-11 19:31:249725// Base test to make sure that when the load flags for a request specify to
9726// bypass the cache, the DNS cache is not used.
[email protected]23e482282013-06-14 16:08:029727void HttpNetworkTransactionTest::BypassHostCacheOnRefreshHelper(
[email protected]bb88e1d32013-05-03 23:11:079728 int load_flags) {
[email protected]cb9bf6ca2011-01-28 13:15:279729 // Issue a request, asking to bypass the cache(s).
maksim.sisov31452af2016-07-27 06:38:109730 HttpRequestInfo request_info;
9731 request_info.method = "GET";
9732 request_info.load_flags = load_flags;
9733 request_info.url = GURL("http://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:279734
[email protected]a2c2fb92009-07-18 07:31:049735 // Select a host resolver that does caching.
Jeremy Roman0579ed62017-08-29 15:56:199736 session_deps_.host_resolver = std::make_unique<MockCachingHostResolver>();
[email protected]b59ff372009-07-15 22:04:329737
danakj1fd259a02016-04-16 03:17:099738 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:169739 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]3b9cca42009-06-16 01:08:289740
bncce36dca22015-04-21 22:11:239741 // Warm up the host cache so it has an entry for "www.example.org".
[email protected]3b9cca42009-06-16 01:08:289742 AddressList addrlist;
[email protected]aa22b242011-11-16 18:58:299743 TestCompletionCallback callback;
maksim.sisov31452af2016-07-27 06:38:109744 std::unique_ptr<HostResolver::Request> request1;
[email protected]bb88e1d32013-05-03 23:11:079745 int rv = session_deps_.host_resolver->Resolve(
bncce36dca22015-04-21 22:11:239746 HostResolver::RequestInfo(HostPortPair("www.example.org", 80)),
maksim.sisov31452af2016-07-27 06:38:109747 DEFAULT_PRIORITY, &addrlist, callback.callback(), &request1,
tfarina42834112016-09-22 13:38:209748 NetLogWithSource());
robpercival214763f2016-07-01 23:27:019749 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]6e78dfb2011-07-28 21:34:479750 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:019751 EXPECT_THAT(rv, IsOk());
[email protected]3b9cca42009-06-16 01:08:289752
9753 // Verify that it was added to host cache, by doing a subsequent async lookup
9754 // and confirming it completes synchronously.
maksim.sisov31452af2016-07-27 06:38:109755 std::unique_ptr<HostResolver::Request> request2;
[email protected]bb88e1d32013-05-03 23:11:079756 rv = session_deps_.host_resolver->Resolve(
bncce36dca22015-04-21 22:11:239757 HostResolver::RequestInfo(HostPortPair("www.example.org", 80)),
maksim.sisov31452af2016-07-27 06:38:109758 DEFAULT_PRIORITY, &addrlist, callback.callback(), &request2,
tfarina42834112016-09-22 13:38:209759 NetLogWithSource());
robpercival214763f2016-07-01 23:27:019760 ASSERT_THAT(rv, IsOk());
[email protected]3b9cca42009-06-16 01:08:289761
bncce36dca22015-04-21 22:11:239762 // Inject a failure the next time that "www.example.org" is resolved. This way
[email protected]3b9cca42009-06-16 01:08:289763 // we can tell if the next lookup hit the cache, or the "network".
9764 // (cache --> success, "network" --> failure).
bncce36dca22015-04-21 22:11:239765 session_deps_.host_resolver->rules()->AddSimulatedFailure("www.example.org");
[email protected]3b9cca42009-06-16 01:08:289766
9767 // Connect up a mock socket which will fail with ERR_UNEXPECTED during the
9768 // first read -- this won't be reached as the host resolution will fail first.
[email protected]8ddf8322012-02-23 18:08:069769 MockRead data_reads[] = { MockRead(SYNCHRONOUS, ERR_UNEXPECTED) };
[email protected]31a2bfe2010-02-09 08:03:399770 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:079771 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]3b9cca42009-06-16 01:08:289772
[email protected]3b9cca42009-06-16 01:08:289773 // Run the request.
tfarina42834112016-09-22 13:38:209774 rv = trans.Start(&request_info, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:019775 ASSERT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]49639fa2011-12-20 23:22:419776 rv = callback.WaitForResult();
[email protected]3b9cca42009-06-16 01:08:289777
9778 // If we bypassed the cache, we would have gotten a failure while resolving
bncce36dca22015-04-21 22:11:239779 // "www.example.org".
robpercival214763f2016-07-01 23:27:019780 EXPECT_THAT(rv, IsError(ERR_NAME_NOT_RESOLVED));
[email protected]3b9cca42009-06-16 01:08:289781}
9782
[email protected]685af592010-05-11 19:31:249783// There are multiple load flags that should trigger the host cache bypass.
9784// Test each in isolation:
bncd16676a2016-07-20 16:23:019785TEST_F(HttpNetworkTransactionTest, BypassHostCacheOnRefresh1) {
[email protected]685af592010-05-11 19:31:249786 BypassHostCacheOnRefreshHelper(LOAD_BYPASS_CACHE);
9787}
9788
bncd16676a2016-07-20 16:23:019789TEST_F(HttpNetworkTransactionTest, BypassHostCacheOnRefresh2) {
[email protected]685af592010-05-11 19:31:249790 BypassHostCacheOnRefreshHelper(LOAD_VALIDATE_CACHE);
9791}
9792
bncd16676a2016-07-20 16:23:019793TEST_F(HttpNetworkTransactionTest, BypassHostCacheOnRefresh3) {
[email protected]685af592010-05-11 19:31:249794 BypassHostCacheOnRefreshHelper(LOAD_DISABLE_CACHE);
9795}
9796
[email protected]0877e3d2009-10-17 22:29:579797// Make sure we can handle an error when writing the request.
bncd16676a2016-07-20 16:23:019798TEST_F(HttpNetworkTransactionTest, RequestWriteError) {
[email protected]0877e3d2009-10-17 22:29:579799 HttpRequestInfo request;
9800 request.method = "GET";
9801 request.url = GURL("http://www.foo.com/");
[email protected]0877e3d2009-10-17 22:29:579802
9803 MockWrite write_failure[] = {
[email protected]8ddf8322012-02-23 18:08:069804 MockWrite(ASYNC, ERR_CONNECTION_RESET),
[email protected]0877e3d2009-10-17 22:29:579805 };
[email protected]31a2bfe2010-02-09 08:03:399806 StaticSocketDataProvider data(NULL, 0,
9807 write_failure, arraysize(write_failure));
[email protected]bb88e1d32013-05-03 23:11:079808 session_deps_.socket_factory->AddSocketDataProvider(&data);
danakj1fd259a02016-04-16 03:17:099809 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]0877e3d2009-10-17 22:29:579810
[email protected]49639fa2011-12-20 23:22:419811 TestCompletionCallback callback;
[email protected]0877e3d2009-10-17 22:29:579812
bnc691fda62016-08-12 00:43:169813 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]0877e3d2009-10-17 22:29:579814
tfarina42834112016-09-22 13:38:209815 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:019816 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]0877e3d2009-10-17 22:29:579817
9818 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:019819 EXPECT_THAT(rv, IsError(ERR_CONNECTION_RESET));
ttuttled9dbc652015-09-29 20:00:599820
9821 IPEndPoint endpoint;
bnc691fda62016-08-12 00:43:169822 EXPECT_TRUE(trans.GetRemoteEndpoint(&endpoint));
ttuttled9dbc652015-09-29 20:00:599823 EXPECT_LT(0u, endpoint.address().size());
[email protected]0877e3d2009-10-17 22:29:579824}
9825
zmo9528c9f42015-08-04 22:12:089826// Check that a connection closed after the start of the headers finishes ok.
bncd16676a2016-07-20 16:23:019827TEST_F(HttpNetworkTransactionTest, ConnectionClosedAfterStartOfHeaders) {
[email protected]0877e3d2009-10-17 22:29:579828 HttpRequestInfo request;
9829 request.method = "GET";
9830 request.url = GURL("http://www.foo.com/");
[email protected]0877e3d2009-10-17 22:29:579831
9832 MockRead data_reads[] = {
9833 MockRead("HTTP/1."),
[email protected]8ddf8322012-02-23 18:08:069834 MockRead(SYNCHRONOUS, OK),
[email protected]0877e3d2009-10-17 22:29:579835 };
9836
[email protected]31a2bfe2010-02-09 08:03:399837 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:079838 session_deps_.socket_factory->AddSocketDataProvider(&data);
danakj1fd259a02016-04-16 03:17:099839 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]0877e3d2009-10-17 22:29:579840
[email protected]49639fa2011-12-20 23:22:419841 TestCompletionCallback callback;
[email protected]0877e3d2009-10-17 22:29:579842
bnc691fda62016-08-12 00:43:169843 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]0877e3d2009-10-17 22:29:579844
tfarina42834112016-09-22 13:38:209845 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:019846 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]0877e3d2009-10-17 22:29:579847
9848 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:019849 EXPECT_THAT(rv, IsOk());
zmo9528c9f42015-08-04 22:12:089850
bnc691fda62016-08-12 00:43:169851 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:529852 ASSERT_TRUE(response);
zmo9528c9f42015-08-04 22:12:089853
wezca1070932016-05-26 20:30:529854 EXPECT_TRUE(response->headers);
zmo9528c9f42015-08-04 22:12:089855 EXPECT_EQ("HTTP/1.0 200 OK", response->headers->GetStatusLine());
9856
9857 std::string response_data;
bnc691fda62016-08-12 00:43:169858 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:019859 EXPECT_THAT(rv, IsOk());
zmo9528c9f42015-08-04 22:12:089860 EXPECT_EQ("", response_data);
ttuttled9dbc652015-09-29 20:00:599861
9862 IPEndPoint endpoint;
bnc691fda62016-08-12 00:43:169863 EXPECT_TRUE(trans.GetRemoteEndpoint(&endpoint));
ttuttled9dbc652015-09-29 20:00:599864 EXPECT_LT(0u, endpoint.address().size());
[email protected]0877e3d2009-10-17 22:29:579865}
9866
9867// Make sure that a dropped connection while draining the body for auth
9868// restart does the right thing.
bncd16676a2016-07-20 16:23:019869TEST_F(HttpNetworkTransactionTest, DrainResetOK) {
[email protected]0877e3d2009-10-17 22:29:579870 HttpRequestInfo request;
9871 request.method = "GET";
bncce36dca22015-04-21 22:11:239872 request.url = GURL("http://www.example.org/");
[email protected]0877e3d2009-10-17 22:29:579873
9874 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:239875 MockWrite(
9876 "GET / HTTP/1.1\r\n"
9877 "Host: www.example.org\r\n"
9878 "Connection: keep-alive\r\n\r\n"),
[email protected]0877e3d2009-10-17 22:29:579879 };
9880
9881 MockRead data_reads1[] = {
9882 MockRead("HTTP/1.1 401 Unauthorized\r\n"),
9883 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
9884 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
9885 MockRead("Content-Length: 14\r\n\r\n"),
9886 MockRead("Unauth"),
[email protected]8ddf8322012-02-23 18:08:069887 MockRead(ASYNC, ERR_CONNECTION_RESET),
[email protected]0877e3d2009-10-17 22:29:579888 };
9889
[email protected]31a2bfe2010-02-09 08:03:399890 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
9891 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:079892 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]0877e3d2009-10-17 22:29:579893
bnc691fda62016-08-12 00:43:169894 // After calling trans.RestartWithAuth(), this is the request we should
[email protected]0877e3d2009-10-17 22:29:579895 // be issuing -- the final header line contains the credentials.
9896 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:239897 MockWrite(
9898 "GET / HTTP/1.1\r\n"
9899 "Host: www.example.org\r\n"
9900 "Connection: keep-alive\r\n"
9901 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]0877e3d2009-10-17 22:29:579902 };
9903
9904 // Lastly, the server responds with the actual content.
9905 MockRead data_reads2[] = {
9906 MockRead("HTTP/1.1 200 OK\r\n"),
9907 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
9908 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:069909 MockRead(SYNCHRONOUS, OK),
[email protected]0877e3d2009-10-17 22:29:579910 };
9911
[email protected]31a2bfe2010-02-09 08:03:399912 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
9913 data_writes2, arraysize(data_writes2));
[email protected]bb88e1d32013-05-03 23:11:079914 session_deps_.socket_factory->AddSocketDataProvider(&data2);
danakj1fd259a02016-04-16 03:17:099915 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]0877e3d2009-10-17 22:29:579916
[email protected]49639fa2011-12-20 23:22:419917 TestCompletionCallback callback1;
[email protected]0877e3d2009-10-17 22:29:579918
bnc691fda62016-08-12 00:43:169919 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]0b0bf032010-09-21 18:08:509920
tfarina42834112016-09-22 13:38:209921 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:019922 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]0877e3d2009-10-17 22:29:579923
9924 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:019925 EXPECT_THAT(rv, IsOk());
[email protected]0877e3d2009-10-17 22:29:579926
bnc691fda62016-08-12 00:43:169927 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:529928 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:049929 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]0877e3d2009-10-17 22:29:579930
[email protected]49639fa2011-12-20 23:22:419931 TestCompletionCallback callback2;
[email protected]0877e3d2009-10-17 22:29:579932
bnc691fda62016-08-12 00:43:169933 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar), callback2.callback());
robpercival214763f2016-07-01 23:27:019934 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]0877e3d2009-10-17 22:29:579935
9936 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:019937 EXPECT_THAT(rv, IsOk());
[email protected]0877e3d2009-10-17 22:29:579938
bnc691fda62016-08-12 00:43:169939 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:529940 ASSERT_TRUE(response);
9941 EXPECT_FALSE(response->auth_challenge);
[email protected]0877e3d2009-10-17 22:29:579942 EXPECT_EQ(100, response->headers->GetContentLength());
9943}
9944
9945// Test HTTPS connections going through a proxy that sends extra data.
bncd16676a2016-07-20 16:23:019946TEST_F(HttpNetworkTransactionTest, HTTPSViaProxyWithExtraData) {
rdsmith82957ad2015-09-16 19:42:039947 session_deps_.proxy_service = ProxyService::CreateFixed("myproxy:70");
[email protected]0877e3d2009-10-17 22:29:579948
9949 HttpRequestInfo request;
9950 request.method = "GET";
bncce36dca22015-04-21 22:11:239951 request.url = GURL("https://www.example.org/");
[email protected]0877e3d2009-10-17 22:29:579952
9953 MockRead proxy_reads[] = {
9954 MockRead("HTTP/1.0 200 Connected\r\n\r\nExtra data"),
[email protected]8ddf8322012-02-23 18:08:069955 MockRead(SYNCHRONOUS, OK)
[email protected]0877e3d2009-10-17 22:29:579956 };
9957
[email protected]31a2bfe2010-02-09 08:03:399958 StaticSocketDataProvider data(proxy_reads, arraysize(proxy_reads), NULL, 0);
[email protected]8ddf8322012-02-23 18:08:069959 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]0877e3d2009-10-17 22:29:579960
[email protected]bb88e1d32013-05-03 23:11:079961 session_deps_.socket_factory->AddSocketDataProvider(&data);
9962 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]0877e3d2009-10-17 22:29:579963
[email protected]49639fa2011-12-20 23:22:419964 TestCompletionCallback callback;
[email protected]0877e3d2009-10-17 22:29:579965
[email protected]bb88e1d32013-05-03 23:11:079966 session_deps_.socket_factory->ResetNextMockIndexes();
[email protected]0877e3d2009-10-17 22:29:579967
danakj1fd259a02016-04-16 03:17:099968 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:169969 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]0877e3d2009-10-17 22:29:579970
tfarina42834112016-09-22 13:38:209971 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:019972 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]0877e3d2009-10-17 22:29:579973
9974 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:019975 EXPECT_THAT(rv, IsError(ERR_TUNNEL_CONNECTION_FAILED));
[email protected]0877e3d2009-10-17 22:29:579976}
9977
bncd16676a2016-07-20 16:23:019978TEST_F(HttpNetworkTransactionTest, LargeContentLengthThenClose) {
[email protected]9492e4a2010-02-24 00:58:469979 HttpRequestInfo request;
9980 request.method = "GET";
bncce36dca22015-04-21 22:11:239981 request.url = GURL("http://www.example.org/");
[email protected]9492e4a2010-02-24 00:58:469982
danakj1fd259a02016-04-16 03:17:099983 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:169984 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:279985
[email protected]e22e1362009-11-23 21:31:129986 MockRead data_reads[] = {
9987 MockRead("HTTP/1.0 200 OK\r\nContent-Length:6719476739\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:069988 MockRead(SYNCHRONOUS, OK),
[email protected]e22e1362009-11-23 21:31:129989 };
[email protected]9492e4a2010-02-24 00:58:469990
9991 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:079992 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]9492e4a2010-02-24 00:58:469993
[email protected]49639fa2011-12-20 23:22:419994 TestCompletionCallback callback;
[email protected]9492e4a2010-02-24 00:58:469995
tfarina42834112016-09-22 13:38:209996 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:019997 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]9492e4a2010-02-24 00:58:469998
robpercival214763f2016-07-01 23:27:019999 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]9492e4a2010-02-24 00:58:4610000
bnc691fda62016-08-12 00:43:1610001 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5210002 ASSERT_TRUE(response);
[email protected]9492e4a2010-02-24 00:58:4610003
wezca1070932016-05-26 20:30:5210004 EXPECT_TRUE(response->headers);
[email protected]9492e4a2010-02-24 00:58:4610005 EXPECT_EQ("HTTP/1.0 200 OK", response->headers->GetStatusLine());
10006
10007 std::string response_data;
bnc691fda62016-08-12 00:43:1610008 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:0110009 EXPECT_THAT(rv, IsError(ERR_CONTENT_LENGTH_MISMATCH));
[email protected]e22e1362009-11-23 21:31:1210010}
10011
bncd16676a2016-07-20 16:23:0110012TEST_F(HttpNetworkTransactionTest, UploadFileSmallerThanLength) {
[email protected]6cdfd7f2013-02-08 20:40:1510013 base::FilePath temp_file_path;
[email protected]03d9afc02013-12-03 17:55:5210014 ASSERT_TRUE(base::CreateTemporaryFile(&temp_file_path));
avibf0746c2015-12-09 19:53:1410015 const uint64_t kFakeSize = 100000; // file is actually blank
[email protected]d98961652012-09-11 20:27:2110016 UploadFileElementReader::ScopedOverridingContentLengthForTests
10017 overriding_content_length(kFakeSize);
[email protected]95d88ffe2010-02-04 21:25:3310018
danakj1fd259a02016-04-16 03:17:0910019 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
Jeremy Roman0579ed62017-08-29 15:56:1910020 element_readers.push_back(std::make_unique<UploadFileElementReader>(
avibf0746c2015-12-09 19:53:1410021 base::ThreadTaskRunnerHandle::Get().get(), temp_file_path, 0,
ricea2deef682016-09-09 08:04:0710022 std::numeric_limits<uint64_t>::max(), base::Time()));
olli.raula6df48b2a2015-11-26 07:40:2210023 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]329b68b2012-11-14 17:54:2710024
10025 HttpRequestInfo request;
10026 request.method = "POST";
bncce36dca22015-04-21 22:11:2310027 request.url = GURL("http://www.example.org/upload");
[email protected]329b68b2012-11-14 17:54:2710028 request.upload_data_stream = &upload_data_stream;
[email protected]329b68b2012-11-14 17:54:2710029
danakj1fd259a02016-04-16 03:17:0910030 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1610031 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]95d88ffe2010-02-04 21:25:3310032
10033 MockRead data_reads[] = {
10034 MockRead("HTTP/1.0 200 OK\r\n\r\n"),
10035 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:0610036 MockRead(SYNCHRONOUS, OK),
[email protected]95d88ffe2010-02-04 21:25:3310037 };
[email protected]31a2bfe2010-02-09 08:03:3910038 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0710039 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]95d88ffe2010-02-04 21:25:3310040
[email protected]49639fa2011-12-20 23:22:4110041 TestCompletionCallback callback;
[email protected]95d88ffe2010-02-04 21:25:3310042
tfarina42834112016-09-22 13:38:2010043 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110044 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]95d88ffe2010-02-04 21:25:3310045
10046 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0110047 EXPECT_THAT(rv, IsError(ERR_UPLOAD_FILE_CHANGED));
[email protected]95d88ffe2010-02-04 21:25:3310048
bnc691fda62016-08-12 00:43:1610049 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5210050 ASSERT_TRUE(response);
[email protected]95d88ffe2010-02-04 21:25:3310051
maksim.sisove869bf52016-06-23 17:11:5210052 EXPECT_FALSE(response->headers);
[email protected]95d88ffe2010-02-04 21:25:3310053
[email protected]dd3aa792013-07-16 19:10:2310054 base::DeleteFile(temp_file_path, false);
[email protected]95d88ffe2010-02-04 21:25:3310055}
10056
bncd16676a2016-07-20 16:23:0110057TEST_F(HttpNetworkTransactionTest, UploadUnreadableFile) {
[email protected]6cdfd7f2013-02-08 20:40:1510058 base::FilePath temp_file;
[email protected]03d9afc02013-12-03 17:55:5210059 ASSERT_TRUE(base::CreateTemporaryFile(&temp_file));
[email protected]6624b4622010-03-29 19:58:3610060 std::string temp_file_content("Unreadable file.");
lazyboy8df84fc2017-04-12 02:12:4810061 ASSERT_EQ(static_cast<int>(temp_file_content.length()),
10062 base::WriteFile(temp_file, temp_file_content.c_str(),
10063 temp_file_content.length()));
[email protected]92be8eb2014-08-07 22:57:1110064 ASSERT_TRUE(base::MakeFileUnreadable(temp_file));
[email protected]6624b4622010-03-29 19:58:3610065
danakj1fd259a02016-04-16 03:17:0910066 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
Jeremy Roman0579ed62017-08-29 15:56:1910067 element_readers.push_back(std::make_unique<UploadFileElementReader>(
avibf0746c2015-12-09 19:53:1410068 base::ThreadTaskRunnerHandle::Get().get(), temp_file, 0,
ricea2deef682016-09-09 08:04:0710069 std::numeric_limits<uint64_t>::max(), base::Time()));
olli.raula6df48b2a2015-11-26 07:40:2210070 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]329b68b2012-11-14 17:54:2710071
10072 HttpRequestInfo request;
10073 request.method = "POST";
bncce36dca22015-04-21 22:11:2310074 request.url = GURL("http://www.example.org/upload");
[email protected]329b68b2012-11-14 17:54:2710075 request.upload_data_stream = &upload_data_stream;
[email protected]329b68b2012-11-14 17:54:2710076
[email protected]999dd8c2013-11-12 06:45:5410077 // If we try to upload an unreadable file, the transaction should fail.
danakj1fd259a02016-04-16 03:17:0910078 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1610079 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]6624b4622010-03-29 19:58:3610080
[email protected]999dd8c2013-11-12 06:45:5410081 StaticSocketDataProvider data(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0710082 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]6624b4622010-03-29 19:58:3610083
[email protected]49639fa2011-12-20 23:22:4110084 TestCompletionCallback callback;
[email protected]6624b4622010-03-29 19:58:3610085
tfarina42834112016-09-22 13:38:2010086 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110087 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]6624b4622010-03-29 19:58:3610088
10089 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0110090 EXPECT_THAT(rv, IsError(ERR_ACCESS_DENIED));
[email protected]6624b4622010-03-29 19:58:3610091
[email protected]dd3aa792013-07-16 19:10:2310092 base::DeleteFile(temp_file, false);
[email protected]6624b4622010-03-29 19:58:3610093}
10094
bncd16676a2016-07-20 16:23:0110095TEST_F(HttpNetworkTransactionTest, CancelDuringInitRequestBody) {
[email protected]02cad5d2013-10-02 08:14:0310096 class FakeUploadElementReader : public UploadElementReader {
10097 public:
10098 FakeUploadElementReader() {}
dchengb03027d2014-10-21 12:00:2010099 ~FakeUploadElementReader() override {}
[email protected]02cad5d2013-10-02 08:14:0310100
10101 const CompletionCallback& callback() const { return callback_; }
10102
10103 // UploadElementReader overrides:
dchengb03027d2014-10-21 12:00:2010104 int Init(const CompletionCallback& callback) override {
[email protected]02cad5d2013-10-02 08:14:0310105 callback_ = callback;
10106 return ERR_IO_PENDING;
10107 }
avibf0746c2015-12-09 19:53:1410108 uint64_t GetContentLength() const override { return 0; }
10109 uint64_t BytesRemaining() const override { return 0; }
dchengb03027d2014-10-21 12:00:2010110 int Read(IOBuffer* buf,
10111 int buf_length,
10112 const CompletionCallback& callback) override {
[email protected]02cad5d2013-10-02 08:14:0310113 return ERR_FAILED;
10114 }
10115
10116 private:
10117 CompletionCallback callback_;
10118 };
10119
10120 FakeUploadElementReader* fake_reader = new FakeUploadElementReader;
danakj1fd259a02016-04-16 03:17:0910121 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
10122 element_readers.push_back(base::WrapUnique(fake_reader));
olli.raula6df48b2a2015-11-26 07:40:2210123 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]02cad5d2013-10-02 08:14:0310124
10125 HttpRequestInfo request;
10126 request.method = "POST";
bncce36dca22015-04-21 22:11:2310127 request.url = GURL("http://www.example.org/upload");
[email protected]02cad5d2013-10-02 08:14:0310128 request.upload_data_stream = &upload_data_stream;
[email protected]02cad5d2013-10-02 08:14:0310129
danakj1fd259a02016-04-16 03:17:0910130 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc87dcefc2017-05-25 12:47:5810131 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:1910132 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]02cad5d2013-10-02 08:14:0310133
10134 StaticSocketDataProvider data;
10135 session_deps_.socket_factory->AddSocketDataProvider(&data);
10136
10137 TestCompletionCallback callback;
tfarina42834112016-09-22 13:38:2010138 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110139 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
fdoray92e35a72016-06-10 15:54:5510140 base::RunLoop().RunUntilIdle();
[email protected]02cad5d2013-10-02 08:14:0310141
10142 // Transaction is pending on request body initialization.
10143 ASSERT_FALSE(fake_reader->callback().is_null());
10144
10145 // Return Init()'s result after the transaction gets destroyed.
10146 trans.reset();
10147 fake_reader->callback().Run(OK); // Should not crash.
10148}
10149
[email protected]aeefc9e82010-02-19 16:18:2710150// Tests that changes to Auth realms are treated like auth rejections.
bncd16676a2016-07-20 16:23:0110151TEST_F(HttpNetworkTransactionTest, ChangeAuthRealms) {
[email protected]aeefc9e82010-02-19 16:18:2710152 HttpRequestInfo request;
10153 request.method = "GET";
bncce36dca22015-04-21 22:11:2310154 request.url = GURL("http://www.example.org/");
[email protected]aeefc9e82010-02-19 16:18:2710155
10156 // First transaction will request a resource and receive a Basic challenge
10157 // with realm="first_realm".
10158 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:2310159 MockWrite(
10160 "GET / HTTP/1.1\r\n"
10161 "Host: www.example.org\r\n"
10162 "Connection: keep-alive\r\n"
10163 "\r\n"),
[email protected]aeefc9e82010-02-19 16:18:2710164 };
10165 MockRead data_reads1[] = {
10166 MockRead("HTTP/1.1 401 Unauthorized\r\n"
10167 "WWW-Authenticate: Basic realm=\"first_realm\"\r\n"
10168 "\r\n"),
10169 };
10170
bnc691fda62016-08-12 00:43:1610171 // After calling trans.RestartWithAuth(), provide an Authentication header
[email protected]aeefc9e82010-02-19 16:18:2710172 // for first_realm. The server will reject and provide a challenge with
10173 // second_realm.
10174 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:2310175 MockWrite(
10176 "GET / HTTP/1.1\r\n"
10177 "Host: www.example.org\r\n"
10178 "Connection: keep-alive\r\n"
10179 "Authorization: Basic Zmlyc3Q6YmF6\r\n"
10180 "\r\n"),
[email protected]aeefc9e82010-02-19 16:18:2710181 };
10182 MockRead data_reads2[] = {
10183 MockRead("HTTP/1.1 401 Unauthorized\r\n"
10184 "WWW-Authenticate: Basic realm=\"second_realm\"\r\n"
10185 "\r\n"),
10186 };
10187
10188 // This again fails, and goes back to first_realm. Make sure that the
10189 // entry is removed from cache.
10190 MockWrite data_writes3[] = {
bncce36dca22015-04-21 22:11:2310191 MockWrite(
10192 "GET / HTTP/1.1\r\n"
10193 "Host: www.example.org\r\n"
10194 "Connection: keep-alive\r\n"
10195 "Authorization: Basic c2Vjb25kOmZvdQ==\r\n"
10196 "\r\n"),
[email protected]aeefc9e82010-02-19 16:18:2710197 };
10198 MockRead data_reads3[] = {
10199 MockRead("HTTP/1.1 401 Unauthorized\r\n"
10200 "WWW-Authenticate: Basic realm=\"first_realm\"\r\n"
10201 "\r\n"),
10202 };
10203
10204 // Try one last time (with the correct password) and get the resource.
10205 MockWrite data_writes4[] = {
bncce36dca22015-04-21 22:11:2310206 MockWrite(
10207 "GET / HTTP/1.1\r\n"
10208 "Host: www.example.org\r\n"
10209 "Connection: keep-alive\r\n"
10210 "Authorization: Basic Zmlyc3Q6YmFy\r\n"
10211 "\r\n"),
[email protected]aeefc9e82010-02-19 16:18:2710212 };
10213 MockRead data_reads4[] = {
10214 MockRead("HTTP/1.1 200 OK\r\n"
10215 "Content-Type: text/html; charset=iso-8859-1\r\n"
[email protected]0b0bf032010-09-21 18:08:5010216 "Content-Length: 5\r\n"
10217 "\r\n"
10218 "hello"),
[email protected]aeefc9e82010-02-19 16:18:2710219 };
10220
10221 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
10222 data_writes1, arraysize(data_writes1));
10223 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
10224 data_writes2, arraysize(data_writes2));
10225 StaticSocketDataProvider data3(data_reads3, arraysize(data_reads3),
10226 data_writes3, arraysize(data_writes3));
10227 StaticSocketDataProvider data4(data_reads4, arraysize(data_reads4),
10228 data_writes4, arraysize(data_writes4));
[email protected]bb88e1d32013-05-03 23:11:0710229 session_deps_.socket_factory->AddSocketDataProvider(&data1);
10230 session_deps_.socket_factory->AddSocketDataProvider(&data2);
10231 session_deps_.socket_factory->AddSocketDataProvider(&data3);
10232 session_deps_.socket_factory->AddSocketDataProvider(&data4);
[email protected]aeefc9e82010-02-19 16:18:2710233
[email protected]49639fa2011-12-20 23:22:4110234 TestCompletionCallback callback1;
[email protected]aeefc9e82010-02-19 16:18:2710235
danakj1fd259a02016-04-16 03:17:0910236 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1610237 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]0b0bf032010-09-21 18:08:5010238
[email protected]aeefc9e82010-02-19 16:18:2710239 // Issue the first request with Authorize headers. There should be a
10240 // password prompt for first_realm waiting to be filled in after the
10241 // transaction completes.
tfarina42834112016-09-22 13:38:2010242 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110243 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]aeefc9e82010-02-19 16:18:2710244 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:0110245 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:1610246 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5210247 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:0410248 const AuthChallengeInfo* challenge = response->auth_challenge.get();
wezca1070932016-05-26 20:30:5210249 ASSERT_TRUE(challenge);
[email protected]79cb5c12011-09-12 13:12:0410250 EXPECT_FALSE(challenge->is_proxy);
asanka098c0092016-06-16 20:18:4310251 EXPECT_EQ("http://www.example.org", challenge->challenger.Serialize());
[email protected]79cb5c12011-09-12 13:12:0410252 EXPECT_EQ("first_realm", challenge->realm);
aberentbba302d2015-12-03 10:20:1910253 EXPECT_EQ(kBasicAuthScheme, challenge->scheme);
[email protected]aeefc9e82010-02-19 16:18:2710254
10255 // Issue the second request with an incorrect password. There should be a
10256 // password prompt for second_realm waiting to be filled in after the
10257 // transaction completes.
[email protected]49639fa2011-12-20 23:22:4110258 TestCompletionCallback callback2;
bnc691fda62016-08-12 00:43:1610259 rv = trans.RestartWithAuth(AuthCredentials(kFirst, kBaz),
10260 callback2.callback());
robpercival214763f2016-07-01 23:27:0110261 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]aeefc9e82010-02-19 16:18:2710262 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:0110263 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:1610264 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5210265 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:0410266 challenge = response->auth_challenge.get();
wezca1070932016-05-26 20:30:5210267 ASSERT_TRUE(challenge);
[email protected]79cb5c12011-09-12 13:12:0410268 EXPECT_FALSE(challenge->is_proxy);
asanka098c0092016-06-16 20:18:4310269 EXPECT_EQ("http://www.example.org", challenge->challenger.Serialize());
[email protected]79cb5c12011-09-12 13:12:0410270 EXPECT_EQ("second_realm", challenge->realm);
aberentbba302d2015-12-03 10:20:1910271 EXPECT_EQ(kBasicAuthScheme, challenge->scheme);
[email protected]aeefc9e82010-02-19 16:18:2710272
10273 // Issue the third request with another incorrect password. There should be
10274 // a password prompt for first_realm waiting to be filled in. If the password
10275 // prompt is not present, it indicates that the HttpAuthCacheEntry for
10276 // first_realm was not correctly removed.
[email protected]49639fa2011-12-20 23:22:4110277 TestCompletionCallback callback3;
bnc691fda62016-08-12 00:43:1610278 rv = trans.RestartWithAuth(AuthCredentials(kSecond, kFou),
10279 callback3.callback());
robpercival214763f2016-07-01 23:27:0110280 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]aeefc9e82010-02-19 16:18:2710281 rv = callback3.WaitForResult();
robpercival214763f2016-07-01 23:27:0110282 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:1610283 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5210284 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:0410285 challenge = response->auth_challenge.get();
wezca1070932016-05-26 20:30:5210286 ASSERT_TRUE(challenge);
[email protected]79cb5c12011-09-12 13:12:0410287 EXPECT_FALSE(challenge->is_proxy);
asanka098c0092016-06-16 20:18:4310288 EXPECT_EQ("http://www.example.org", challenge->challenger.Serialize());
[email protected]79cb5c12011-09-12 13:12:0410289 EXPECT_EQ("first_realm", challenge->realm);
aberentbba302d2015-12-03 10:20:1910290 EXPECT_EQ(kBasicAuthScheme, challenge->scheme);
[email protected]aeefc9e82010-02-19 16:18:2710291
10292 // Issue the fourth request with the correct password and username.
[email protected]49639fa2011-12-20 23:22:4110293 TestCompletionCallback callback4;
bnc691fda62016-08-12 00:43:1610294 rv = trans.RestartWithAuth(AuthCredentials(kFirst, kBar),
10295 callback4.callback());
robpercival214763f2016-07-01 23:27:0110296 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]aeefc9e82010-02-19 16:18:2710297 rv = callback4.WaitForResult();
robpercival214763f2016-07-01 23:27:0110298 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:1610299 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5210300 ASSERT_TRUE(response);
10301 EXPECT_FALSE(response->auth_challenge);
[email protected]aeefc9e82010-02-19 16:18:2710302}
10303
Bence Béky230ac612017-08-30 19:17:0810304// Regression test for https://crbug.com/754395.
10305TEST_F(HttpNetworkTransactionTest, IgnoreAltSvcWithInvalidCert) {
10306 MockRead data_reads[] = {
10307 MockRead("HTTP/1.1 200 OK\r\n"),
10308 MockRead(kAlternativeServiceHttpHeader),
10309 MockRead("\r\n"),
10310 MockRead("hello world"),
10311 MockRead(SYNCHRONOUS, OK),
10312 };
10313
10314 HttpRequestInfo request;
10315 request.method = "GET";
10316 request.url = GURL("https://www.example.org/");
10317
10318 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
10319 session_deps_.socket_factory->AddSocketDataProvider(&data);
10320
10321 SSLSocketDataProvider ssl(ASYNC, OK);
10322 ssl.cert = ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem");
10323 ASSERT_TRUE(ssl.cert);
10324 ssl.cert_status = CERT_STATUS_COMMON_NAME_INVALID;
10325 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
10326
10327 TestCompletionCallback callback;
10328
10329 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
10330 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
10331
10332 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
10333 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
10334
10335 url::SchemeHostPort test_server(request.url);
10336 HttpServerProperties* http_server_properties =
10337 session->http_server_properties();
10338 EXPECT_TRUE(
10339 http_server_properties->GetAlternativeServiceInfos(test_server).empty());
10340
10341 EXPECT_THAT(callback.WaitForResult(), IsOk());
10342
10343 const HttpResponseInfo* response = trans.GetResponseInfo();
10344 ASSERT_TRUE(response);
10345 ASSERT_TRUE(response->headers);
10346 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
10347 EXPECT_FALSE(response->was_fetched_via_spdy);
10348 EXPECT_FALSE(response->was_alpn_negotiated);
10349
10350 std::string response_data;
10351 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
10352 EXPECT_EQ("hello world", response_data);
10353
10354 EXPECT_TRUE(
10355 http_server_properties->GetAlternativeServiceInfos(test_server).empty());
10356}
10357
bncd16676a2016-07-20 16:23:0110358TEST_F(HttpNetworkTransactionTest, HonorAlternativeServiceHeader) {
bncc958faa2015-07-31 18:14:5210359 MockRead data_reads[] = {
10360 MockRead("HTTP/1.1 200 OK\r\n"),
bnc2df4b522016-07-08 18:17:4310361 MockRead(kAlternativeServiceHttpHeader),
bncc958faa2015-07-31 18:14:5210362 MockRead("\r\n"),
10363 MockRead("hello world"),
10364 MockRead(SYNCHRONOUS, OK),
10365 };
10366
10367 HttpRequestInfo request;
10368 request.method = "GET";
bncb26024382016-06-29 02:39:4510369 request.url = GURL("https://www.example.org/");
bncc958faa2015-07-31 18:14:5210370
10371 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
bncc958faa2015-07-31 18:14:5210372 session_deps_.socket_factory->AddSocketDataProvider(&data);
10373
bncb26024382016-06-29 02:39:4510374 SSLSocketDataProvider ssl(ASYNC, OK);
Bence Béky230ac612017-08-30 19:17:0810375 ssl.cert = ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem");
10376 ASSERT_TRUE(ssl.cert);
bncb26024382016-06-29 02:39:4510377 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
10378
bncc958faa2015-07-31 18:14:5210379 TestCompletionCallback callback;
10380
danakj1fd259a02016-04-16 03:17:0910381 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1610382 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
bncc958faa2015-07-31 18:14:5210383
tfarina42834112016-09-22 13:38:2010384 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110385 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
bncc958faa2015-07-31 18:14:5210386
bncb26024382016-06-29 02:39:4510387 url::SchemeHostPort test_server(request.url);
bnc525e175a2016-06-20 12:36:4010388 HttpServerProperties* http_server_properties =
10389 session->http_server_properties();
zhongyic4de03032017-05-19 04:07:3410390 EXPECT_TRUE(
10391 http_server_properties->GetAlternativeServiceInfos(test_server).empty());
bncc958faa2015-07-31 18:14:5210392
robpercival214763f2016-07-01 23:27:0110393 EXPECT_THAT(callback.WaitForResult(), IsOk());
bncc958faa2015-07-31 18:14:5210394
bnc691fda62016-08-12 00:43:1610395 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5210396 ASSERT_TRUE(response);
10397 ASSERT_TRUE(response->headers);
bncc958faa2015-07-31 18:14:5210398 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
10399 EXPECT_FALSE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5210400 EXPECT_FALSE(response->was_alpn_negotiated);
bncc958faa2015-07-31 18:14:5210401
10402 std::string response_data;
bnc691fda62016-08-12 00:43:1610403 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
bncc958faa2015-07-31 18:14:5210404 EXPECT_EQ("hello world", response_data);
10405
zhongyic4de03032017-05-19 04:07:3410406 AlternativeServiceInfoVector alternative_service_info_vector =
10407 http_server_properties->GetAlternativeServiceInfos(test_server);
10408 ASSERT_EQ(1u, alternative_service_info_vector.size());
10409 AlternativeService alternative_service(kProtoHTTP2, "mail.example.org", 443);
10410 EXPECT_EQ(alternative_service,
zhongyi422ce352017-06-09 23:28:5410411 alternative_service_info_vector[0].alternative_service());
bncc958faa2015-07-31 18:14:5210412}
10413
bnce3dd56f2016-06-01 10:37:1110414// Regression test for https://crbug.com/615497.
bncd16676a2016-07-20 16:23:0110415TEST_F(HttpNetworkTransactionTest,
bnce3dd56f2016-06-01 10:37:1110416 DoNotParseAlternativeServiceHeaderOnInsecureRequest) {
bnce3dd56f2016-06-01 10:37:1110417 MockRead data_reads[] = {
10418 MockRead("HTTP/1.1 200 OK\r\n"),
bnc2df4b522016-07-08 18:17:4310419 MockRead(kAlternativeServiceHttpHeader),
bnce3dd56f2016-06-01 10:37:1110420 MockRead("\r\n"),
10421 MockRead("hello world"),
10422 MockRead(SYNCHRONOUS, OK),
10423 };
10424
10425 HttpRequestInfo request;
10426 request.method = "GET";
10427 request.url = GURL("http://www.example.org/");
10428 request.load_flags = 0;
10429
10430 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
10431 session_deps_.socket_factory->AddSocketDataProvider(&data);
10432
10433 TestCompletionCallback callback;
10434
10435 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1610436 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
bnce3dd56f2016-06-01 10:37:1110437
10438 url::SchemeHostPort test_server(request.url);
bnc525e175a2016-06-20 12:36:4010439 HttpServerProperties* http_server_properties =
10440 session->http_server_properties();
zhongyic4de03032017-05-19 04:07:3410441 EXPECT_TRUE(
10442 http_server_properties->GetAlternativeServiceInfos(test_server).empty());
bnce3dd56f2016-06-01 10:37:1110443
tfarina42834112016-09-22 13:38:2010444 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110445 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
10446 EXPECT_THAT(callback.WaitForResult(), IsOk());
bnce3dd56f2016-06-01 10:37:1110447
bnc691fda62016-08-12 00:43:1610448 const HttpResponseInfo* response = trans.GetResponseInfo();
bnce3dd56f2016-06-01 10:37:1110449 ASSERT_TRUE(response);
10450 ASSERT_TRUE(response->headers);
10451 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
10452 EXPECT_FALSE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5210453 EXPECT_FALSE(response->was_alpn_negotiated);
bnce3dd56f2016-06-01 10:37:1110454
10455 std::string response_data;
bnc691fda62016-08-12 00:43:1610456 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
bnce3dd56f2016-06-01 10:37:1110457 EXPECT_EQ("hello world", response_data);
10458
zhongyic4de03032017-05-19 04:07:3410459 EXPECT_TRUE(
10460 http_server_properties->GetAlternativeServiceInfos(test_server).empty());
bnce3dd56f2016-06-01 10:37:1110461}
10462
bnca86731e2017-04-17 12:31:2810463// HTTP/2 Alternative Services should be disabled by default.
bnc8bef8da22016-05-30 01:28:2510464// TODO(bnc): Remove when https://crbug.com/615413 is fixed.
bncd16676a2016-07-20 16:23:0110465TEST_F(HttpNetworkTransactionTest,
bnc8bef8da22016-05-30 01:28:2510466 DisableHTTP2AlternativeServicesWithDifferentHost) {
bnca86731e2017-04-17 12:31:2810467 session_deps_.enable_http2_alternative_service = false;
bncb26024382016-06-29 02:39:4510468
bnc8bef8da22016-05-30 01:28:2510469 HttpRequestInfo request;
10470 request.method = "GET";
bncb26024382016-06-29 02:39:4510471 request.url = GURL("https://www.example.org/");
bnc8bef8da22016-05-30 01:28:2510472 request.load_flags = 0;
10473
10474 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
10475 StaticSocketDataProvider first_data;
10476 first_data.set_connect_data(mock_connect);
10477 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
bncb26024382016-06-29 02:39:4510478 SSLSocketDataProvider ssl_http11(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3610479 ssl_http11.next_proto = kProtoHTTP11;
bncb26024382016-06-29 02:39:4510480 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_http11);
bnc8bef8da22016-05-30 01:28:2510481
10482 MockRead data_reads[] = {
10483 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello world"),
10484 MockRead(ASYNC, OK),
10485 };
10486 StaticSocketDataProvider second_data(data_reads, arraysize(data_reads), NULL,
10487 0);
10488 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
10489
10490 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
10491
bnc525e175a2016-06-20 12:36:4010492 HttpServerProperties* http_server_properties =
bnc8bef8da22016-05-30 01:28:2510493 session->http_server_properties();
bnc3472afd2016-11-17 15:27:2110494 AlternativeService alternative_service(kProtoHTTP2, "different.example.org",
10495 444);
bnc8bef8da22016-05-30 01:28:2510496 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:2110497 http_server_properties->SetHttp2AlternativeService(
bnc8bef8da22016-05-30 01:28:2510498 url::SchemeHostPort(request.url), alternative_service, expiration);
10499
bnc691fda62016-08-12 00:43:1610500 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
bnc8bef8da22016-05-30 01:28:2510501 TestCompletionCallback callback;
10502
tfarina42834112016-09-22 13:38:2010503 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
bnc8bef8da22016-05-30 01:28:2510504 // Alternative service is not used, request fails.
robpercival214763f2016-07-01 23:27:0110505 EXPECT_THAT(callback.GetResult(rv), IsError(ERR_CONNECTION_REFUSED));
bnc8bef8da22016-05-30 01:28:2510506}
10507
bnce3dd56f2016-06-01 10:37:1110508// Regression test for https://crbug.com/615497:
10509// Alternative Services should be disabled for http origin.
bncd16676a2016-07-20 16:23:0110510TEST_F(HttpNetworkTransactionTest,
bnce3dd56f2016-06-01 10:37:1110511 DisableAlternativeServicesForInsecureOrigin) {
bnce3dd56f2016-06-01 10:37:1110512 HttpRequestInfo request;
10513 request.method = "GET";
10514 request.url = GURL("http://www.example.org/");
10515 request.load_flags = 0;
10516
10517 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
10518 StaticSocketDataProvider first_data;
10519 first_data.set_connect_data(mock_connect);
10520 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
10521
10522 MockRead data_reads[] = {
10523 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello world"),
10524 MockRead(ASYNC, OK),
10525 };
10526 StaticSocketDataProvider second_data(data_reads, arraysize(data_reads), NULL,
10527 0);
10528 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
10529
10530 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
10531
bnc525e175a2016-06-20 12:36:4010532 HttpServerProperties* http_server_properties =
bnce3dd56f2016-06-01 10:37:1110533 session->http_server_properties();
bnc3472afd2016-11-17 15:27:2110534 AlternativeService alternative_service(kProtoHTTP2, "", 444);
bnce3dd56f2016-06-01 10:37:1110535 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:2110536 http_server_properties->SetHttp2AlternativeService(
bnce3dd56f2016-06-01 10:37:1110537 url::SchemeHostPort(request.url), alternative_service, expiration);
10538
bnc691fda62016-08-12 00:43:1610539 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
bnce3dd56f2016-06-01 10:37:1110540 TestCompletionCallback callback;
10541
tfarina42834112016-09-22 13:38:2010542 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
bnce3dd56f2016-06-01 10:37:1110543 // Alternative service is not used, request fails.
robpercival214763f2016-07-01 23:27:0110544 EXPECT_THAT(callback.GetResult(rv), IsError(ERR_CONNECTION_REFUSED));
bnce3dd56f2016-06-01 10:37:1110545}
10546
bncd16676a2016-07-20 16:23:0110547TEST_F(HttpNetworkTransactionTest, ClearAlternativeServices) {
bnc4f575852015-10-14 18:35:0810548 // Set an alternative service for origin.
danakj1fd259a02016-04-16 03:17:0910549 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc525e175a2016-06-20 12:36:4010550 HttpServerProperties* http_server_properties =
10551 session->http_server_properties();
bncb26024382016-06-29 02:39:4510552 url::SchemeHostPort test_server("https", "www.example.org", 443);
bnc3472afd2016-11-17 15:27:2110553 AlternativeService alternative_service(kProtoQUIC, "", 80);
bnc4f575852015-10-14 18:35:0810554 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:2110555 http_server_properties->SetQuicAlternativeService(
10556 test_server, alternative_service, expiration,
10557 session->params().quic_supported_versions);
zhongyic4de03032017-05-19 04:07:3410558 EXPECT_EQ(
10559 1u,
10560 http_server_properties->GetAlternativeServiceInfos(test_server).size());
bnc4f575852015-10-14 18:35:0810561
10562 // Send a clear header.
10563 MockRead data_reads[] = {
10564 MockRead("HTTP/1.1 200 OK\r\n"),
10565 MockRead("Alt-Svc: clear\r\n"),
10566 MockRead("\r\n"),
10567 MockRead("hello world"),
10568 MockRead(SYNCHRONOUS, OK),
10569 };
10570 StaticSocketDataProvider data(data_reads, arraysize(data_reads), nullptr, 0);
10571 session_deps_.socket_factory->AddSocketDataProvider(&data);
10572
bncb26024382016-06-29 02:39:4510573 SSLSocketDataProvider ssl(ASYNC, OK);
Bence Béky230ac612017-08-30 19:17:0810574 ssl.cert = ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem");
10575 ASSERT_TRUE(ssl.cert);
bncb26024382016-06-29 02:39:4510576 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
10577
bnc4f575852015-10-14 18:35:0810578 HttpRequestInfo request;
10579 request.method = "GET";
bncb26024382016-06-29 02:39:4510580 request.url = GURL("https://www.example.org/");
bnc4f575852015-10-14 18:35:0810581
10582 TestCompletionCallback callback;
10583
bnc691fda62016-08-12 00:43:1610584 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
bnc4f575852015-10-14 18:35:0810585
tfarina42834112016-09-22 13:38:2010586 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110587 EXPECT_THAT(callback.GetResult(rv), IsOk());
bnc4f575852015-10-14 18:35:0810588
bnc691fda62016-08-12 00:43:1610589 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5210590 ASSERT_TRUE(response);
10591 ASSERT_TRUE(response->headers);
bnc4f575852015-10-14 18:35:0810592 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
10593 EXPECT_FALSE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5210594 EXPECT_FALSE(response->was_alpn_negotiated);
bnc4f575852015-10-14 18:35:0810595
10596 std::string response_data;
bnc691fda62016-08-12 00:43:1610597 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
bnc4f575852015-10-14 18:35:0810598 EXPECT_EQ("hello world", response_data);
10599
zhongyic4de03032017-05-19 04:07:3410600 EXPECT_TRUE(
10601 http_server_properties->GetAlternativeServiceInfos(test_server).empty());
bnc4f575852015-10-14 18:35:0810602}
10603
bncd16676a2016-07-20 16:23:0110604TEST_F(HttpNetworkTransactionTest, HonorMultipleAlternativeServiceHeaders) {
bncc958faa2015-07-31 18:14:5210605 MockRead data_reads[] = {
10606 MockRead("HTTP/1.1 200 OK\r\n"),
bnc2df4b522016-07-08 18:17:4310607 MockRead("Alt-Svc: h2=\"www.example.com:443\","),
10608 MockRead("h2=\":1234\"\r\n\r\n"),
bncc958faa2015-07-31 18:14:5210609 MockRead("hello world"),
10610 MockRead(SYNCHRONOUS, OK),
10611 };
10612
10613 HttpRequestInfo request;
10614 request.method = "GET";
bncb26024382016-06-29 02:39:4510615 request.url = GURL("https://www.example.org/");
bncc958faa2015-07-31 18:14:5210616
10617 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
bncc958faa2015-07-31 18:14:5210618 session_deps_.socket_factory->AddSocketDataProvider(&data);
10619
bncb26024382016-06-29 02:39:4510620 SSLSocketDataProvider ssl(ASYNC, OK);
Bence Béky230ac612017-08-30 19:17:0810621 ssl.cert = ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem");
10622 ASSERT_TRUE(ssl.cert);
bncb26024382016-06-29 02:39:4510623 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
10624
bncc958faa2015-07-31 18:14:5210625 TestCompletionCallback callback;
10626
danakj1fd259a02016-04-16 03:17:0910627 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1610628 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
bncc958faa2015-07-31 18:14:5210629
tfarina42834112016-09-22 13:38:2010630 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110631 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
bncc958faa2015-07-31 18:14:5210632
bncb26024382016-06-29 02:39:4510633 url::SchemeHostPort test_server("https", "www.example.org", 443);
bnc525e175a2016-06-20 12:36:4010634 HttpServerProperties* http_server_properties =
10635 session->http_server_properties();
zhongyic4de03032017-05-19 04:07:3410636 EXPECT_TRUE(
10637 http_server_properties->GetAlternativeServiceInfos(test_server).empty());
bncc958faa2015-07-31 18:14:5210638
robpercival214763f2016-07-01 23:27:0110639 EXPECT_THAT(callback.WaitForResult(), IsOk());
bncc958faa2015-07-31 18:14:5210640
bnc691fda62016-08-12 00:43:1610641 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5210642 ASSERT_TRUE(response);
10643 ASSERT_TRUE(response->headers);
bncc958faa2015-07-31 18:14:5210644 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
10645 EXPECT_FALSE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5210646 EXPECT_FALSE(response->was_alpn_negotiated);
bncc958faa2015-07-31 18:14:5210647
10648 std::string response_data;
bnc691fda62016-08-12 00:43:1610649 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
bncc958faa2015-07-31 18:14:5210650 EXPECT_EQ("hello world", response_data);
10651
zhongyic4de03032017-05-19 04:07:3410652 AlternativeServiceInfoVector alternative_service_info_vector =
10653 http_server_properties->GetAlternativeServiceInfos(test_server);
10654 ASSERT_EQ(2u, alternative_service_info_vector.size());
10655
10656 AlternativeService alternative_service(kProtoHTTP2, "www.example.com", 443);
10657 EXPECT_EQ(alternative_service,
zhongyi422ce352017-06-09 23:28:5410658 alternative_service_info_vector[0].alternative_service());
zhongyic4de03032017-05-19 04:07:3410659 AlternativeService alternative_service_2(kProtoHTTP2, "www.example.org",
10660 1234);
10661 EXPECT_EQ(alternative_service_2,
zhongyi422ce352017-06-09 23:28:5410662 alternative_service_info_vector[1].alternative_service());
bncc958faa2015-07-31 18:14:5210663}
10664
bncd16676a2016-07-20 16:23:0110665TEST_F(HttpNetworkTransactionTest, IdentifyQuicBroken) {
zhongyi3d4a55e72016-04-22 20:36:4610666 url::SchemeHostPort server("https", "origin.example.org", 443);
zhongyi48704c182015-12-07 07:52:0210667 HostPortPair alternative("alternative.example.org", 443);
10668 std::string origin_url = "https://origin.example.org:443";
10669 std::string alternative_url = "https://alternative.example.org:443";
10670
10671 // Negotiate HTTP/1.1 with alternative.example.org.
10672 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3610673 ssl.next_proto = kProtoHTTP11;
zhongyi48704c182015-12-07 07:52:0210674 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
10675
10676 // HTTP/1.1 data for request.
10677 MockWrite http_writes[] = {
10678 MockWrite("GET / HTTP/1.1\r\n"
10679 "Host: alternative.example.org\r\n"
10680 "Connection: keep-alive\r\n\r\n"),
10681 };
10682
10683 MockRead http_reads[] = {
10684 MockRead("HTTP/1.1 200 OK\r\n"
10685 "Content-Type: text/html; charset=iso-8859-1\r\n"
10686 "Content-Length: 40\r\n\r\n"
10687 "first HTTP/1.1 response from alternative"),
10688 };
10689 StaticSocketDataProvider http_data(http_reads, arraysize(http_reads),
10690 http_writes, arraysize(http_writes));
10691 session_deps_.socket_factory->AddSocketDataProvider(&http_data);
10692
10693 StaticSocketDataProvider data_refused;
10694 data_refused.set_connect_data(MockConnect(ASYNC, ERR_CONNECTION_REFUSED));
10695 session_deps_.socket_factory->AddSocketDataProvider(&data_refused);
10696
zhongyi3d4a55e72016-04-22 20:36:4610697 // Set up a QUIC alternative service for server.
danakj1fd259a02016-04-16 03:17:0910698 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc525e175a2016-06-20 12:36:4010699 HttpServerProperties* http_server_properties =
zhongyi48704c182015-12-07 07:52:0210700 session->http_server_properties();
bnc3472afd2016-11-17 15:27:2110701 AlternativeService alternative_service(kProtoQUIC, alternative);
zhongyi48704c182015-12-07 07:52:0210702 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:2110703 http_server_properties->SetQuicAlternativeService(
10704 server, alternative_service, expiration,
10705 HttpNetworkSession::Params().quic_supported_versions);
zhongyi48704c182015-12-07 07:52:0210706 // Mark the QUIC alternative service as broken.
10707 http_server_properties->MarkAlternativeServiceBroken(alternative_service);
10708
zhongyi48704c182015-12-07 07:52:0210709 HttpRequestInfo request;
krasinc06a72a2016-12-21 03:42:4610710 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
zhongyi48704c182015-12-07 07:52:0210711 request.method = "GET";
10712 request.url = GURL(origin_url);
zhongyi48704c182015-12-07 07:52:0210713 TestCompletionCallback callback;
10714 NetErrorDetails details;
10715 EXPECT_FALSE(details.quic_broken);
10716
tfarina42834112016-09-22 13:38:2010717 trans.Start(&request, callback.callback(), NetLogWithSource());
bnc691fda62016-08-12 00:43:1610718 trans.PopulateNetErrorDetails(&details);
zhongyi48704c182015-12-07 07:52:0210719 EXPECT_TRUE(details.quic_broken);
10720}
10721
bncd16676a2016-07-20 16:23:0110722TEST_F(HttpNetworkTransactionTest, IdentifyQuicNotBroken) {
zhongyi3d4a55e72016-04-22 20:36:4610723 url::SchemeHostPort server("https", "origin.example.org", 443);
zhongyi48704c182015-12-07 07:52:0210724 HostPortPair alternative1("alternative1.example.org", 443);
10725 HostPortPair alternative2("alternative2.example.org", 443);
10726 std::string origin_url = "https://origin.example.org:443";
10727 std::string alternative_url1 = "https://alternative1.example.org:443";
10728 std::string alternative_url2 = "https://alternative2.example.org:443";
10729
10730 // Negotiate HTTP/1.1 with alternative1.example.org.
10731 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3610732 ssl.next_proto = kProtoHTTP11;
zhongyi48704c182015-12-07 07:52:0210733 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
10734
10735 // HTTP/1.1 data for request.
10736 MockWrite http_writes[] = {
10737 MockWrite("GET / HTTP/1.1\r\n"
10738 "Host: alternative1.example.org\r\n"
10739 "Connection: keep-alive\r\n\r\n"),
10740 };
10741
10742 MockRead http_reads[] = {
10743 MockRead("HTTP/1.1 200 OK\r\n"
10744 "Content-Type: text/html; charset=iso-8859-1\r\n"
10745 "Content-Length: 40\r\n\r\n"
10746 "first HTTP/1.1 response from alternative1"),
10747 };
10748 StaticSocketDataProvider http_data(http_reads, arraysize(http_reads),
10749 http_writes, arraysize(http_writes));
10750 session_deps_.socket_factory->AddSocketDataProvider(&http_data);
10751
10752 StaticSocketDataProvider data_refused;
10753 data_refused.set_connect_data(MockConnect(ASYNC, ERR_CONNECTION_REFUSED));
10754 session_deps_.socket_factory->AddSocketDataProvider(&data_refused);
10755
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();
10759
zhongyi3d4a55e72016-04-22 20:36:4610760 // Set up two QUIC alternative services for server.
zhongyi48704c182015-12-07 07:52:0210761 AlternativeServiceInfoVector alternative_service_info_vector;
10762 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
10763
bnc3472afd2016-11-17 15:27:2110764 AlternativeService alternative_service1(kProtoQUIC, alternative1);
zhongyie537a002017-06-27 16:48:2110765 alternative_service_info_vector.push_back(
10766 AlternativeServiceInfo::CreateQuicAlternativeServiceInfo(
10767 alternative_service1, expiration,
10768 session->params().quic_supported_versions));
bnc3472afd2016-11-17 15:27:2110769 AlternativeService alternative_service2(kProtoQUIC, alternative2);
zhongyie537a002017-06-27 16:48:2110770 alternative_service_info_vector.push_back(
10771 AlternativeServiceInfo::CreateQuicAlternativeServiceInfo(
10772 alternative_service2, expiration,
10773 session->params().quic_supported_versions));
zhongyi48704c182015-12-07 07:52:0210774
10775 http_server_properties->SetAlternativeServices(
zhongyi3d4a55e72016-04-22 20:36:4610776 server, alternative_service_info_vector);
zhongyi48704c182015-12-07 07:52:0210777
10778 // Mark one of the QUIC alternative service as broken.
10779 http_server_properties->MarkAlternativeServiceBroken(alternative_service1);
zhongyic4de03032017-05-19 04:07:3410780 EXPECT_EQ(2u,
10781 http_server_properties->GetAlternativeServiceInfos(server).size());
zhongyi48704c182015-12-07 07:52:0210782
zhongyi48704c182015-12-07 07:52:0210783 HttpRequestInfo request;
krasinc06a72a2016-12-21 03:42:4610784 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
zhongyi48704c182015-12-07 07:52:0210785 request.method = "GET";
10786 request.url = GURL(origin_url);
zhongyi48704c182015-12-07 07:52:0210787 TestCompletionCallback callback;
10788 NetErrorDetails details;
10789 EXPECT_FALSE(details.quic_broken);
10790
tfarina42834112016-09-22 13:38:2010791 trans.Start(&request, callback.callback(), NetLogWithSource());
bnc691fda62016-08-12 00:43:1610792 trans.PopulateNetErrorDetails(&details);
zhongyi48704c182015-12-07 07:52:0210793 EXPECT_FALSE(details.quic_broken);
10794}
10795
bncd16676a2016-07-20 16:23:0110796TEST_F(HttpNetworkTransactionTest, MarkBrokenAlternateProtocolAndFallback) {
[email protected]564b4912010-03-09 16:30:4210797 HttpRequestInfo request;
10798 request.method = "GET";
bncb26024382016-06-29 02:39:4510799 request.url = GURL("https://www.example.org/");
[email protected]564b4912010-03-09 16:30:4210800
[email protected]d973e99a2012-02-17 21:02:3610801 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
[email protected]564b4912010-03-09 16:30:4210802 StaticSocketDataProvider first_data;
10803 first_data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:0710804 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
bncb26024382016-06-29 02:39:4510805 SSLSocketDataProvider ssl_http11(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3610806 ssl_http11.next_proto = kProtoHTTP11;
bncb26024382016-06-29 02:39:4510807 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_http11);
[email protected]564b4912010-03-09 16:30:4210808
10809 MockRead data_reads[] = {
10810 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
10811 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:0610812 MockRead(ASYNC, OK),
[email protected]564b4912010-03-09 16:30:4210813 };
10814 StaticSocketDataProvider second_data(
10815 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0710816 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
[email protected]564b4912010-03-09 16:30:4210817
danakj1fd259a02016-04-16 03:17:0910818 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]564b4912010-03-09 16:30:4210819
bnc525e175a2016-06-20 12:36:4010820 HttpServerProperties* http_server_properties =
[email protected]17291a022011-10-10 07:32:5310821 session->http_server_properties();
zhongyi3d4a55e72016-04-22 20:36:4610822 const url::SchemeHostPort server(request.url);
[email protected]3912662a32011-10-04 00:51:1110823 // Port must be < 1024, or the header will be ignored (since initial port was
10824 // port 80 (another restricted port).
zhongyie537a002017-06-27 16:48:2110825 // Port is ignored by MockConnect anyway.
10826 const AlternativeService alternative_service(kProtoHTTP2, "www.example.org",
10827 666);
bnc7dc7e1b42015-07-28 14:43:1210828 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:2110829 http_server_properties->SetHttp2AlternativeService(
10830 server, alternative_service, expiration);
[email protected]564b4912010-03-09 16:30:4210831
bnc691fda62016-08-12 00:43:1610832 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]49639fa2011-12-20 23:22:4110833 TestCompletionCallback callback;
[email protected]564b4912010-03-09 16:30:4210834
tfarina42834112016-09-22 13:38:2010835 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110836 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
10837 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]564b4912010-03-09 16:30:4210838
bnc691fda62016-08-12 00:43:1610839 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5210840 ASSERT_TRUE(response);
10841 ASSERT_TRUE(response->headers);
[email protected]564b4912010-03-09 16:30:4210842 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
10843
10844 std::string response_data;
bnc691fda62016-08-12 00:43:1610845 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
[email protected]564b4912010-03-09 16:30:4210846 EXPECT_EQ("hello world", response_data);
10847
zhongyic4de03032017-05-19 04:07:3410848 const AlternativeServiceInfoVector alternative_service_info_vector =
10849 http_server_properties->GetAlternativeServiceInfos(server);
10850 ASSERT_EQ(1u, alternative_service_info_vector.size());
10851 EXPECT_EQ(alternative_service,
zhongyi422ce352017-06-09 23:28:5410852 alternative_service_info_vector[0].alternative_service());
zhongyic4de03032017-05-19 04:07:3410853 EXPECT_TRUE(
10854 http_server_properties->IsAlternativeServiceBroken(alternative_service));
[email protected]564b4912010-03-09 16:30:4210855}
10856
bnc55ff9da2015-08-19 18:42:3510857// Ensure that we are not allowed to redirect traffic via an alternate protocol
10858// to an unrestricted (port >= 1024) when the original traffic was on a
10859// restricted port (port < 1024). Ensure that we can redirect in all other
10860// cases.
bncd16676a2016-07-20 16:23:0110861TEST_F(HttpNetworkTransactionTest, AlternateProtocolPortRestrictedBlocked) {
[email protected]3912662a32011-10-04 00:51:1110862 HttpRequestInfo restricted_port_request;
10863 restricted_port_request.method = "GET";
bncb26024382016-06-29 02:39:4510864 restricted_port_request.url = GURL("https://www.example.org:1023/");
[email protected]3912662a32011-10-04 00:51:1110865 restricted_port_request.load_flags = 0;
10866
[email protected]d973e99a2012-02-17 21:02:3610867 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
[email protected]3912662a32011-10-04 00:51:1110868 StaticSocketDataProvider first_data;
10869 first_data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:0710870 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
[email protected]3912662a32011-10-04 00:51:1110871
10872 MockRead data_reads[] = {
10873 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
10874 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:0610875 MockRead(ASYNC, OK),
[email protected]3912662a32011-10-04 00:51:1110876 };
10877 StaticSocketDataProvider second_data(
10878 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0710879 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
bncb26024382016-06-29 02:39:4510880 SSLSocketDataProvider ssl_http11(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3610881 ssl_http11.next_proto = kProtoHTTP11;
bncb26024382016-06-29 02:39:4510882 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_http11);
[email protected]3912662a32011-10-04 00:51:1110883
danakj1fd259a02016-04-16 03:17:0910884 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]3912662a32011-10-04 00:51:1110885
bnc525e175a2016-06-20 12:36:4010886 HttpServerProperties* http_server_properties =
[email protected]17291a022011-10-10 07:32:5310887 session->http_server_properties();
[email protected]3912662a32011-10-04 00:51:1110888 const int kUnrestrictedAlternatePort = 1024;
bnc3472afd2016-11-17 15:27:2110889 AlternativeService alternative_service(kProtoHTTP2, "www.example.org",
10890 kUnrestrictedAlternatePort);
bnc7dc7e1b42015-07-28 14:43:1210891 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:2110892 http_server_properties->SetHttp2AlternativeService(
zhongyi3d4a55e72016-04-22 20:36:4610893 url::SchemeHostPort(restricted_port_request.url), alternative_service,
rchdc7b9052016-03-17 20:51:5010894 expiration);
[email protected]3912662a32011-10-04 00:51:1110895
bnc691fda62016-08-12 00:43:1610896 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]49639fa2011-12-20 23:22:4110897 TestCompletionCallback callback;
[email protected]3912662a32011-10-04 00:51:1110898
tfarina42834112016-09-22 13:38:2010899 int rv = trans.Start(&restricted_port_request, callback.callback(),
10900 NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110901 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]3912662a32011-10-04 00:51:1110902 // Invalid change to unrestricted port should fail.
robpercival214763f2016-07-01 23:27:0110903 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_CONNECTION_REFUSED));
[email protected]c54c6962013-02-01 04:53:1910904}
[email protected]3912662a32011-10-04 00:51:1110905
bnc55ff9da2015-08-19 18:42:3510906// Ensure that we are allowed to redirect traffic via an alternate protocol to
10907// an unrestricted (port >= 1024) when the original traffic was on a restricted
10908// port (port < 1024) if we set |enable_user_alternate_protocol_ports|.
bncd16676a2016-07-20 16:23:0110909TEST_F(HttpNetworkTransactionTest, AlternateProtocolPortRestrictedPermitted) {
[email protected]bb88e1d32013-05-03 23:11:0710910 session_deps_.enable_user_alternate_protocol_ports = true;
[email protected]c54c6962013-02-01 04:53:1910911
10912 HttpRequestInfo restricted_port_request;
10913 restricted_port_request.method = "GET";
bncb26024382016-06-29 02:39:4510914 restricted_port_request.url = GURL("https://www.example.org:1023/");
[email protected]c54c6962013-02-01 04:53:1910915 restricted_port_request.load_flags = 0;
10916
10917 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
10918 StaticSocketDataProvider first_data;
10919 first_data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:0710920 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
[email protected]c54c6962013-02-01 04:53:1910921
10922 MockRead data_reads[] = {
10923 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
10924 MockRead("hello world"),
10925 MockRead(ASYNC, OK),
10926 };
10927 StaticSocketDataProvider second_data(
10928 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0710929 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
bncb26024382016-06-29 02:39:4510930 SSLSocketDataProvider ssl_http11(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3610931 ssl_http11.next_proto = kProtoHTTP11;
bncb26024382016-06-29 02:39:4510932 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_http11);
[email protected]c54c6962013-02-01 04:53:1910933
danakj1fd259a02016-04-16 03:17:0910934 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]c54c6962013-02-01 04:53:1910935
bnc525e175a2016-06-20 12:36:4010936 HttpServerProperties* http_server_properties =
[email protected]c54c6962013-02-01 04:53:1910937 session->http_server_properties();
10938 const int kUnrestrictedAlternatePort = 1024;
bnc3472afd2016-11-17 15:27:2110939 AlternativeService alternative_service(kProtoHTTP2, "www.example.org",
10940 kUnrestrictedAlternatePort);
bnc7dc7e1b42015-07-28 14:43:1210941 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:2110942 http_server_properties->SetHttp2AlternativeService(
zhongyi3d4a55e72016-04-22 20:36:4610943 url::SchemeHostPort(restricted_port_request.url), alternative_service,
rchdc7b9052016-03-17 20:51:5010944 expiration);
[email protected]c54c6962013-02-01 04:53:1910945
bnc691fda62016-08-12 00:43:1610946 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]c54c6962013-02-01 04:53:1910947 TestCompletionCallback callback;
10948
tfarina42834112016-09-22 13:38:2010949 EXPECT_EQ(ERR_IO_PENDING,
10950 trans.Start(&restricted_port_request, callback.callback(),
10951 NetLogWithSource()));
[email protected]c54c6962013-02-01 04:53:1910952 // Change to unrestricted port should succeed.
robpercival214763f2016-07-01 23:27:0110953 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]3912662a32011-10-04 00:51:1110954}
10955
bnc55ff9da2015-08-19 18:42:3510956// Ensure that we are not allowed to redirect traffic via an alternate protocol
10957// to an unrestricted (port >= 1024) when the original traffic was on a
10958// restricted port (port < 1024). Ensure that we can redirect in all other
10959// cases.
bncd16676a2016-07-20 16:23:0110960TEST_F(HttpNetworkTransactionTest, AlternateProtocolPortRestrictedAllowed) {
[email protected]3912662a32011-10-04 00:51:1110961 HttpRequestInfo restricted_port_request;
10962 restricted_port_request.method = "GET";
bncb26024382016-06-29 02:39:4510963 restricted_port_request.url = GURL("https://www.example.org:1023/");
[email protected]3912662a32011-10-04 00:51:1110964 restricted_port_request.load_flags = 0;
10965
[email protected]d973e99a2012-02-17 21:02:3610966 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
[email protected]3912662a32011-10-04 00:51:1110967 StaticSocketDataProvider first_data;
10968 first_data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:0710969 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
[email protected]3912662a32011-10-04 00:51:1110970
10971 MockRead data_reads[] = {
10972 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
10973 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:0610974 MockRead(ASYNC, OK),
[email protected]3912662a32011-10-04 00:51:1110975 };
10976 StaticSocketDataProvider second_data(
10977 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0710978 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
[email protected]3912662a32011-10-04 00:51:1110979
bncb26024382016-06-29 02:39:4510980 SSLSocketDataProvider ssl(ASYNC, OK);
10981 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
10982
danakj1fd259a02016-04-16 03:17:0910983 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]3912662a32011-10-04 00:51:1110984
bnc525e175a2016-06-20 12:36:4010985 HttpServerProperties* http_server_properties =
[email protected]17291a022011-10-10 07:32:5310986 session->http_server_properties();
[email protected]3912662a32011-10-04 00:51:1110987 const int kRestrictedAlternatePort = 80;
bnc3472afd2016-11-17 15:27:2110988 AlternativeService alternative_service(kProtoHTTP2, "www.example.org",
10989 kRestrictedAlternatePort);
bnc7dc7e1b42015-07-28 14:43:1210990 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:2110991 http_server_properties->SetHttp2AlternativeService(
zhongyi3d4a55e72016-04-22 20:36:4610992 url::SchemeHostPort(restricted_port_request.url), alternative_service,
rchdc7b9052016-03-17 20:51:5010993 expiration);
[email protected]3912662a32011-10-04 00:51:1110994
bnc691fda62016-08-12 00:43:1610995 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]49639fa2011-12-20 23:22:4110996 TestCompletionCallback callback;
[email protected]3912662a32011-10-04 00:51:1110997
tfarina42834112016-09-22 13:38:2010998 int rv = trans.Start(&restricted_port_request, callback.callback(),
10999 NetLogWithSource());
robpercival214763f2016-07-01 23:27:0111000 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]3912662a32011-10-04 00:51:1111001 // Valid change to restricted port should pass.
robpercival214763f2016-07-01 23:27:0111002 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]3912662a32011-10-04 00:51:1111003}
11004
bnc55ff9da2015-08-19 18:42:3511005// Ensure that we are not allowed to redirect traffic via an alternate protocol
11006// to an unrestricted (port >= 1024) when the original traffic was on a
11007// restricted port (port < 1024). Ensure that we can redirect in all other
11008// cases.
bncd16676a2016-07-20 16:23:0111009TEST_F(HttpNetworkTransactionTest, AlternateProtocolPortUnrestrictedAllowed1) {
[email protected]3912662a32011-10-04 00:51:1111010 HttpRequestInfo unrestricted_port_request;
11011 unrestricted_port_request.method = "GET";
bncb26024382016-06-29 02:39:4511012 unrestricted_port_request.url = GURL("https://www.example.org:1024/");
[email protected]3912662a32011-10-04 00:51:1111013 unrestricted_port_request.load_flags = 0;
11014
[email protected]d973e99a2012-02-17 21:02:3611015 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
[email protected]3912662a32011-10-04 00:51:1111016 StaticSocketDataProvider first_data;
11017 first_data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:0711018 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
[email protected]3912662a32011-10-04 00:51:1111019
11020 MockRead data_reads[] = {
11021 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
11022 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:0611023 MockRead(ASYNC, OK),
[email protected]3912662a32011-10-04 00:51:1111024 };
11025 StaticSocketDataProvider second_data(
11026 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0711027 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
bncb26024382016-06-29 02:39:4511028 SSLSocketDataProvider ssl_http11(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3611029 ssl_http11.next_proto = kProtoHTTP11;
bncb26024382016-06-29 02:39:4511030 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_http11);
[email protected]3912662a32011-10-04 00:51:1111031
danakj1fd259a02016-04-16 03:17:0911032 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]3912662a32011-10-04 00:51:1111033
bnc525e175a2016-06-20 12:36:4011034 HttpServerProperties* http_server_properties =
[email protected]17291a022011-10-10 07:32:5311035 session->http_server_properties();
[email protected]3912662a32011-10-04 00:51:1111036 const int kRestrictedAlternatePort = 80;
bnc3472afd2016-11-17 15:27:2111037 AlternativeService alternative_service(kProtoHTTP2, "www.example.org",
11038 kRestrictedAlternatePort);
bnc7dc7e1b42015-07-28 14:43:1211039 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:2111040 http_server_properties->SetHttp2AlternativeService(
zhongyi3d4a55e72016-04-22 20:36:4611041 url::SchemeHostPort(unrestricted_port_request.url), alternative_service,
rchdc7b9052016-03-17 20:51:5011042 expiration);
[email protected]3912662a32011-10-04 00:51:1111043
bnc691fda62016-08-12 00:43:1611044 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]49639fa2011-12-20 23:22:4111045 TestCompletionCallback callback;
[email protected]3912662a32011-10-04 00:51:1111046
bnc691fda62016-08-12 00:43:1611047 int rv = trans.Start(&unrestricted_port_request, callback.callback(),
tfarina42834112016-09-22 13:38:2011048 NetLogWithSource());
robpercival214763f2016-07-01 23:27:0111049 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]3912662a32011-10-04 00:51:1111050 // Valid change to restricted port should pass.
robpercival214763f2016-07-01 23:27:0111051 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]3912662a32011-10-04 00:51:1111052}
11053
bnc55ff9da2015-08-19 18:42:3511054// Ensure that we are not allowed to redirect traffic via an alternate protocol
11055// to an unrestricted (port >= 1024) when the original traffic was on a
11056// restricted port (port < 1024). Ensure that we can redirect in all other
11057// cases.
bncd16676a2016-07-20 16:23:0111058TEST_F(HttpNetworkTransactionTest, AlternateProtocolPortUnrestrictedAllowed2) {
[email protected]3912662a32011-10-04 00:51:1111059 HttpRequestInfo unrestricted_port_request;
11060 unrestricted_port_request.method = "GET";
bncb26024382016-06-29 02:39:4511061 unrestricted_port_request.url = GURL("https://www.example.org:1024/");
[email protected]3912662a32011-10-04 00:51:1111062 unrestricted_port_request.load_flags = 0;
11063
[email protected]d973e99a2012-02-17 21:02:3611064 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
[email protected]3912662a32011-10-04 00:51:1111065 StaticSocketDataProvider first_data;
11066 first_data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:0711067 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
[email protected]3912662a32011-10-04 00:51:1111068
11069 MockRead data_reads[] = {
11070 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
11071 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:0611072 MockRead(ASYNC, OK),
[email protected]3912662a32011-10-04 00:51:1111073 };
11074 StaticSocketDataProvider second_data(
11075 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0711076 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
[email protected]3912662a32011-10-04 00:51:1111077
bncb26024382016-06-29 02:39:4511078 SSLSocketDataProvider ssl(ASYNC, OK);
11079 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
11080
danakj1fd259a02016-04-16 03:17:0911081 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]3912662a32011-10-04 00:51:1111082
bnc525e175a2016-06-20 12:36:4011083 HttpServerProperties* http_server_properties =
[email protected]17291a022011-10-10 07:32:5311084 session->http_server_properties();
bnc0bbb02622015-07-23 10:06:2211085 const int kUnrestrictedAlternatePort = 1025;
bnc3472afd2016-11-17 15:27:2111086 AlternativeService alternative_service(kProtoHTTP2, "www.example.org",
11087 kUnrestrictedAlternatePort);
bnc7dc7e1b42015-07-28 14:43:1211088 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:2111089 http_server_properties->SetHttp2AlternativeService(
zhongyi3d4a55e72016-04-22 20:36:4611090 url::SchemeHostPort(unrestricted_port_request.url), alternative_service,
rchdc7b9052016-03-17 20:51:5011091 expiration);
[email protected]3912662a32011-10-04 00:51:1111092
bnc691fda62016-08-12 00:43:1611093 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]49639fa2011-12-20 23:22:4111094 TestCompletionCallback callback;
[email protected]3912662a32011-10-04 00:51:1111095
bnc691fda62016-08-12 00:43:1611096 int rv = trans.Start(&unrestricted_port_request, callback.callback(),
tfarina42834112016-09-22 13:38:2011097 NetLogWithSource());
robpercival214763f2016-07-01 23:27:0111098 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]3912662a32011-10-04 00:51:1111099 // Valid change to an unrestricted port should pass.
robpercival214763f2016-07-01 23:27:0111100 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]3912662a32011-10-04 00:51:1111101}
11102
bnc55ff9da2015-08-19 18:42:3511103// Ensure that we are not allowed to redirect traffic via an alternate protocol
11104// to an unsafe port, and that we resume the second HttpStreamFactoryImpl::Job
11105// once the alternate protocol request fails.
bncd16676a2016-07-20 16:23:0111106TEST_F(HttpNetworkTransactionTest, AlternateProtocolUnsafeBlocked) {
[email protected]eb6234e2012-01-19 01:50:0211107 HttpRequestInfo request;
11108 request.method = "GET";
bncce36dca22015-04-21 22:11:2311109 request.url = GURL("http://www.example.org/");
[email protected]eb6234e2012-01-19 01:50:0211110
11111 // The alternate protocol request will error out before we attempt to connect,
11112 // so only the standard HTTP request will try to connect.
11113 MockRead data_reads[] = {
11114 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
11115 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:0611116 MockRead(ASYNC, OK),
[email protected]eb6234e2012-01-19 01:50:0211117 };
11118 StaticSocketDataProvider data(
11119 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0711120 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]eb6234e2012-01-19 01:50:0211121
danakj1fd259a02016-04-16 03:17:0911122 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]eb6234e2012-01-19 01:50:0211123
bnc525e175a2016-06-20 12:36:4011124 HttpServerProperties* http_server_properties =
[email protected]eb6234e2012-01-19 01:50:0211125 session->http_server_properties();
11126 const int kUnsafePort = 7;
bnc3472afd2016-11-17 15:27:2111127 AlternativeService alternative_service(kProtoHTTP2, "www.example.org",
11128 kUnsafePort);
bnc7dc7e1b42015-07-28 14:43:1211129 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:2111130 http_server_properties->SetHttp2AlternativeService(
zhongyi3d4a55e72016-04-22 20:36:4611131 url::SchemeHostPort(request.url), alternative_service, expiration);
[email protected]eb6234e2012-01-19 01:50:0211132
bnc691fda62016-08-12 00:43:1611133 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]eb6234e2012-01-19 01:50:0211134 TestCompletionCallback callback;
11135
tfarina42834112016-09-22 13:38:2011136 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0111137 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]eb6234e2012-01-19 01:50:0211138 // The HTTP request should succeed.
robpercival214763f2016-07-01 23:27:0111139 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]eb6234e2012-01-19 01:50:0211140
bnc691fda62016-08-12 00:43:1611141 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5211142 ASSERT_TRUE(response);
11143 ASSERT_TRUE(response->headers);
[email protected]eb6234e2012-01-19 01:50:0211144 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
11145
11146 std::string response_data;
bnc691fda62016-08-12 00:43:1611147 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
[email protected]eb6234e2012-01-19 01:50:0211148 EXPECT_EQ("hello world", response_data);
11149}
11150
bncd16676a2016-07-20 16:23:0111151TEST_F(HttpNetworkTransactionTest, UseAlternateProtocolForNpnSpdy) {
[email protected]2ff8b312010-04-26 22:20:5411152 HttpRequestInfo request;
11153 request.method = "GET";
bncb26024382016-06-29 02:39:4511154 request.url = GURL("https://www.example.org/");
[email protected]2ff8b312010-04-26 22:20:5411155
11156 MockRead data_reads[] = {
bncc958faa2015-07-31 18:14:5211157 MockRead("HTTP/1.1 200 OK\r\n"),
bnc2df4b522016-07-08 18:17:4311158 MockRead(kAlternativeServiceHttpHeader),
bncc958faa2015-07-31 18:14:5211159 MockRead("\r\n"),
11160 MockRead("hello world"),
11161 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
11162 MockRead(ASYNC, OK)};
[email protected]2ff8b312010-04-26 22:20:5411163
11164 StaticSocketDataProvider first_transaction(
11165 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0711166 session_deps_.socket_factory->AddSocketDataProvider(&first_transaction);
bncb26024382016-06-29 02:39:4511167 SSLSocketDataProvider ssl_http11(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3611168 ssl_http11.next_proto = kProtoHTTP11;
bncb26024382016-06-29 02:39:4511169 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_http11);
[email protected]2ff8b312010-04-26 22:20:5411170
bnc032658ba2016-09-26 18:17:1511171 AddSSLSocketData();
[email protected]2ff8b312010-04-26 22:20:5411172
bncdf80d44fd2016-07-15 20:27:4111173 SpdySerializedFrame req(
bncb26024382016-06-29 02:39:4511174 spdy_util_.ConstructSpdyGet("https://www.example.org/", 1, LOWEST));
bncdf80d44fd2016-07-15 20:27:4111175 MockWrite spdy_writes[] = {CreateMockWrite(req, 0)};
[email protected]2ff8b312010-04-26 22:20:5411176
bnc42331402016-07-25 13:36:1511177 SpdySerializedFrame resp(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
bncdf80d44fd2016-07-15 20:27:4111178 SpdySerializedFrame data(spdy_util_.ConstructSpdyDataFrame(1, true));
[email protected]2ff8b312010-04-26 22:20:5411179 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:4111180 CreateMockRead(resp, 1), CreateMockRead(data, 2), MockRead(ASYNC, 0, 3),
[email protected]2ff8b312010-04-26 22:20:5411181 };
11182
rch8e6c6c42015-05-01 14:05:1311183 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
11184 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:0711185 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]2ff8b312010-04-26 22:20:5411186
[email protected]d973e99a2012-02-17 21:02:3611187 MockConnect never_finishing_connect(SYNCHRONOUS, ERR_IO_PENDING);
[email protected]2d6728692011-03-12 01:39:5511188 StaticSocketDataProvider hanging_non_alternate_protocol_socket(
11189 NULL, 0, NULL, 0);
11190 hanging_non_alternate_protocol_socket.set_connect_data(
11191 never_finishing_connect);
[email protected]bb88e1d32013-05-03 23:11:0711192 session_deps_.socket_factory->AddSocketDataProvider(
[email protected]2d6728692011-03-12 01:39:5511193 &hanging_non_alternate_protocol_socket);
11194
[email protected]49639fa2011-12-20 23:22:4111195 TestCompletionCallback callback;
[email protected]2ff8b312010-04-26 22:20:5411196
danakj1fd259a02016-04-16 03:17:0911197 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc87dcefc2017-05-25 12:47:5811198 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:1911199 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]2ff8b312010-04-26 22:20:5411200
tfarina42834112016-09-22 13:38:2011201 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0111202 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
11203 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]2ff8b312010-04-26 22:20:5411204
11205 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5211206 ASSERT_TRUE(response);
11207 ASSERT_TRUE(response->headers);
[email protected]2ff8b312010-04-26 22:20:5411208 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
11209
11210 std::string response_data;
robpercival214763f2016-07-01 23:27:0111211 ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
[email protected]2ff8b312010-04-26 22:20:5411212 EXPECT_EQ("hello world", response_data);
11213
bnc87dcefc2017-05-25 12:47:5811214 trans =
Jeremy Roman0579ed62017-08-29 15:56:1911215 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]2ff8b312010-04-26 22:20:5411216
tfarina42834112016-09-22 13:38:2011217 rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0111218 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
11219 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]2ff8b312010-04-26 22:20:5411220
11221 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5211222 ASSERT_TRUE(response);
11223 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0211224 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]65041fa2010-05-21 06:56:5311225 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5211226 EXPECT_TRUE(response->was_alpn_negotiated);
[email protected]2ff8b312010-04-26 22:20:5411227
robpercival214763f2016-07-01 23:27:0111228 ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
[email protected]2ff8b312010-04-26 22:20:5411229 EXPECT_EQ("hello!", response_data);
[email protected]2ff8b312010-04-26 22:20:5411230}
11231
bncd16676a2016-07-20 16:23:0111232TEST_F(HttpNetworkTransactionTest, AlternateProtocolWithSpdyLateBinding) {
[email protected]2d6728692011-03-12 01:39:5511233 HttpRequestInfo request;
11234 request.method = "GET";
bncb26024382016-06-29 02:39:4511235 request.url = GURL("https://www.example.org/");
[email protected]2d6728692011-03-12 01:39:5511236
bncb26024382016-06-29 02:39:4511237 // First transaction receives Alt-Svc header over HTTP/1.1.
[email protected]2d6728692011-03-12 01:39:5511238 MockRead data_reads[] = {
bncc958faa2015-07-31 18:14:5211239 MockRead("HTTP/1.1 200 OK\r\n"),
bnc2df4b522016-07-08 18:17:4311240 MockRead(kAlternativeServiceHttpHeader),
bncc958faa2015-07-31 18:14:5211241 MockRead("\r\n"),
11242 MockRead("hello world"),
11243 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
11244 MockRead(ASYNC, OK),
[email protected]2d6728692011-03-12 01:39:5511245 };
11246
bncb26024382016-06-29 02:39:4511247 StaticSocketDataProvider http11_data(data_reads, arraysize(data_reads), NULL,
11248 0);
11249 session_deps_.socket_factory->AddSocketDataProvider(&http11_data);
[email protected]2d6728692011-03-12 01:39:5511250
bncb26024382016-06-29 02:39:4511251 SSLSocketDataProvider ssl_http11(ASYNC, OK);
Bence Béky230ac612017-08-30 19:17:0811252 ssl_http11.cert = ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem");
11253 ASSERT_TRUE(ssl_http11.cert);
bncb26024382016-06-29 02:39:4511254 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_http11);
11255
11256 // Second transaction starts an alternative and a non-alternative Job.
11257 // Both sockets hang.
[email protected]d973e99a2012-02-17 21:02:3611258 MockConnect never_finishing_connect(SYNCHRONOUS, ERR_IO_PENDING);
mmenkecc2298e2015-12-07 18:20:1811259 StaticSocketDataProvider hanging_socket1(NULL, 0, NULL, 0);
11260 hanging_socket1.set_connect_data(never_finishing_connect);
mmenkecc2298e2015-12-07 18:20:1811261 session_deps_.socket_factory->AddSocketDataProvider(&hanging_socket1);
11262
11263 StaticSocketDataProvider hanging_socket2(NULL, 0, NULL, 0);
11264 hanging_socket2.set_connect_data(never_finishing_connect);
11265 session_deps_.socket_factory->AddSocketDataProvider(&hanging_socket2);
[email protected]2d6728692011-03-12 01:39:5511266
bncb26024382016-06-29 02:39:4511267 // Third transaction starts an alternative and a non-alternative job.
11268 // The non-alternative job hangs, but the alternative one succeeds.
11269 // The second transaction, still pending, binds to this socket.
bncdf80d44fd2016-07-15 20:27:4111270 SpdySerializedFrame req1(
bncb26024382016-06-29 02:39:4511271 spdy_util_.ConstructSpdyGet("https://www.example.org/", 1, LOWEST));
bncdf80d44fd2016-07-15 20:27:4111272 SpdySerializedFrame req2(
bncb26024382016-06-29 02:39:4511273 spdy_util_.ConstructSpdyGet("https://www.example.org/", 3, LOWEST));
[email protected]2d6728692011-03-12 01:39:5511274 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:4111275 CreateMockWrite(req1, 0), CreateMockWrite(req2, 1),
[email protected]2d6728692011-03-12 01:39:5511276 };
bnc42331402016-07-25 13:36:1511277 SpdySerializedFrame resp1(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
bncdf80d44fd2016-07-15 20:27:4111278 SpdySerializedFrame data1(spdy_util_.ConstructSpdyDataFrame(1, true));
bnc42331402016-07-25 13:36:1511279 SpdySerializedFrame resp2(spdy_util_.ConstructSpdyGetReply(NULL, 0, 3));
bncdf80d44fd2016-07-15 20:27:4111280 SpdySerializedFrame data2(spdy_util_.ConstructSpdyDataFrame(3, true));
[email protected]2d6728692011-03-12 01:39:5511281 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:4111282 CreateMockRead(resp1, 2), CreateMockRead(data1, 3),
11283 CreateMockRead(resp2, 4), CreateMockRead(data2, 5),
rch8e6c6c42015-05-01 14:05:1311284 MockRead(ASYNC, 0, 6),
[email protected]2d6728692011-03-12 01:39:5511285 };
11286
rch8e6c6c42015-05-01 14:05:1311287 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
11288 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:0711289 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]2d6728692011-03-12 01:39:5511290
bnc032658ba2016-09-26 18:17:1511291 AddSSLSocketData();
bncb26024382016-06-29 02:39:4511292
mmenkecc2298e2015-12-07 18:20:1811293 StaticSocketDataProvider hanging_socket3(NULL, 0, NULL, 0);
11294 hanging_socket3.set_connect_data(never_finishing_connect);
11295 session_deps_.socket_factory->AddSocketDataProvider(&hanging_socket3);
[email protected]2d6728692011-03-12 01:39:5511296
danakj1fd259a02016-04-16 03:17:0911297 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]49639fa2011-12-20 23:22:4111298 TestCompletionCallback callback1;
[email protected]90499482013-06-01 00:39:5011299 HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
[email protected]2d6728692011-03-12 01:39:5511300
tfarina42834112016-09-22 13:38:2011301 int rv = trans1.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0111302 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
11303 EXPECT_THAT(callback1.WaitForResult(), IsOk());
[email protected]2d6728692011-03-12 01:39:5511304
11305 const HttpResponseInfo* response = trans1.GetResponseInfo();
wezca1070932016-05-26 20:30:5211306 ASSERT_TRUE(response);
11307 ASSERT_TRUE(response->headers);
[email protected]2d6728692011-03-12 01:39:5511308 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
11309
11310 std::string response_data;
robpercival214763f2016-07-01 23:27:0111311 ASSERT_THAT(ReadTransaction(&trans1, &response_data), IsOk());
[email protected]2d6728692011-03-12 01:39:5511312 EXPECT_EQ("hello world", response_data);
11313
[email protected]49639fa2011-12-20 23:22:4111314 TestCompletionCallback callback2;
[email protected]90499482013-06-01 00:39:5011315 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:2011316 rv = trans2.Start(&request, callback2.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0111317 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2d6728692011-03-12 01:39:5511318
[email protected]49639fa2011-12-20 23:22:4111319 TestCompletionCallback callback3;
[email protected]90499482013-06-01 00:39:5011320 HttpNetworkTransaction trans3(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:2011321 rv = trans3.Start(&request, callback3.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0111322 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2d6728692011-03-12 01:39:5511323
robpercival214763f2016-07-01 23:27:0111324 EXPECT_THAT(callback2.WaitForResult(), IsOk());
11325 EXPECT_THAT(callback3.WaitForResult(), IsOk());
[email protected]2d6728692011-03-12 01:39:5511326
11327 response = trans2.GetResponseInfo();
wezca1070932016-05-26 20:30:5211328 ASSERT_TRUE(response);
11329 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0211330 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]2d6728692011-03-12 01:39:5511331 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5211332 EXPECT_TRUE(response->was_alpn_negotiated);
robpercival214763f2016-07-01 23:27:0111333 ASSERT_THAT(ReadTransaction(&trans2, &response_data), IsOk());
[email protected]2d6728692011-03-12 01:39:5511334 EXPECT_EQ("hello!", response_data);
11335
11336 response = trans3.GetResponseInfo();
wezca1070932016-05-26 20:30:5211337 ASSERT_TRUE(response);
11338 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0211339 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]2d6728692011-03-12 01:39:5511340 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5211341 EXPECT_TRUE(response->was_alpn_negotiated);
robpercival214763f2016-07-01 23:27:0111342 ASSERT_THAT(ReadTransaction(&trans3, &response_data), IsOk());
[email protected]2d6728692011-03-12 01:39:5511343 EXPECT_EQ("hello!", response_data);
[email protected]2d6728692011-03-12 01:39:5511344}
11345
bncd16676a2016-07-20 16:23:0111346TEST_F(HttpNetworkTransactionTest, StallAlternativeServiceForNpnSpdy) {
[email protected]2d6728692011-03-12 01:39:5511347 HttpRequestInfo request;
11348 request.method = "GET";
bncb26024382016-06-29 02:39:4511349 request.url = GURL("https://www.example.org/");
[email protected]2d6728692011-03-12 01:39:5511350
11351 MockRead data_reads[] = {
bncc958faa2015-07-31 18:14:5211352 MockRead("HTTP/1.1 200 OK\r\n"),
bnc2df4b522016-07-08 18:17:4311353 MockRead(kAlternativeServiceHttpHeader),
bncc958faa2015-07-31 18:14:5211354 MockRead("\r\n"),
11355 MockRead("hello world"),
11356 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
11357 MockRead(ASYNC, OK),
[email protected]2d6728692011-03-12 01:39:5511358 };
11359
11360 StaticSocketDataProvider first_transaction(
11361 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0711362 session_deps_.socket_factory->AddSocketDataProvider(&first_transaction);
[email protected]2d6728692011-03-12 01:39:5511363
[email protected]8ddf8322012-02-23 18:08:0611364 SSLSocketDataProvider ssl(ASYNC, OK);
Bence Béky230ac612017-08-30 19:17:0811365 ssl.cert = ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem");
11366 ASSERT_TRUE(ssl.cert);
[email protected]bb88e1d32013-05-03 23:11:0711367 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]2d6728692011-03-12 01:39:5511368
[email protected]d973e99a2012-02-17 21:02:3611369 MockConnect never_finishing_connect(SYNCHRONOUS, ERR_IO_PENDING);
[email protected]2d6728692011-03-12 01:39:5511370 StaticSocketDataProvider hanging_alternate_protocol_socket(
11371 NULL, 0, NULL, 0);
11372 hanging_alternate_protocol_socket.set_connect_data(
11373 never_finishing_connect);
[email protected]bb88e1d32013-05-03 23:11:0711374 session_deps_.socket_factory->AddSocketDataProvider(
[email protected]2d6728692011-03-12 01:39:5511375 &hanging_alternate_protocol_socket);
11376
bncb26024382016-06-29 02:39:4511377 // 2nd request is just a copy of the first one, over HTTP/1.1 again.
mmenkecc2298e2015-12-07 18:20:1811378 StaticSocketDataProvider second_transaction(data_reads, arraysize(data_reads),
11379 NULL, 0);
11380 session_deps_.socket_factory->AddSocketDataProvider(&second_transaction);
bncb26024382016-06-29 02:39:4511381 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]2d6728692011-03-12 01:39:5511382
[email protected]49639fa2011-12-20 23:22:4111383 TestCompletionCallback callback;
[email protected]2d6728692011-03-12 01:39:5511384
danakj1fd259a02016-04-16 03:17:0911385 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc87dcefc2017-05-25 12:47:5811386 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:1911387 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]2d6728692011-03-12 01:39:5511388
tfarina42834112016-09-22 13:38:2011389 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0111390 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
11391 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]2d6728692011-03-12 01:39:5511392
11393 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5211394 ASSERT_TRUE(response);
11395 ASSERT_TRUE(response->headers);
[email protected]2d6728692011-03-12 01:39:5511396 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
11397
11398 std::string response_data;
robpercival214763f2016-07-01 23:27:0111399 ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
[email protected]2d6728692011-03-12 01:39:5511400 EXPECT_EQ("hello world", response_data);
11401
bnc87dcefc2017-05-25 12:47:5811402 trans =
Jeremy Roman0579ed62017-08-29 15:56:1911403 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]2d6728692011-03-12 01:39:5511404
tfarina42834112016-09-22 13:38:2011405 rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0111406 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
11407 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]2d6728692011-03-12 01:39:5511408
11409 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5211410 ASSERT_TRUE(response);
11411 ASSERT_TRUE(response->headers);
[email protected]2d6728692011-03-12 01:39:5511412 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
11413 EXPECT_FALSE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5211414 EXPECT_FALSE(response->was_alpn_negotiated);
[email protected]2d6728692011-03-12 01:39:5511415
robpercival214763f2016-07-01 23:27:0111416 ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
[email protected]2d6728692011-03-12 01:39:5511417 EXPECT_EQ("hello world", response_data);
[email protected]2d6728692011-03-12 01:39:5511418}
11419
[email protected]631f1322010-04-30 17:59:1111420class CapturingProxyResolver : public ProxyResolver {
11421 public:
sammce90c9212015-05-27 23:43:3511422 CapturingProxyResolver() {}
dchengb03027d2014-10-21 12:00:2011423 ~CapturingProxyResolver() override {}
[email protected]631f1322010-04-30 17:59:1111424
dchengb03027d2014-10-21 12:00:2011425 int GetProxyForURL(const GURL& url,
11426 ProxyInfo* results,
11427 const CompletionCallback& callback,
maksim.sisov7e157262016-10-20 11:19:5511428 std::unique_ptr<Request>* request,
tfarina42834112016-09-22 13:38:2011429 const NetLogWithSource& net_log) override {
[email protected]fae7669f2010-08-02 21:49:4011430 ProxyServer proxy_server(ProxyServer::SCHEME_HTTP,
11431 HostPortPair("myproxy", 80));
[email protected]d911f1b2010-05-05 22:39:4211432 results->UseProxyServer(proxy_server);
[email protected]631f1322010-04-30 17:59:1111433 resolved_.push_back(url);
[email protected]d911f1b2010-05-05 22:39:4211434 return OK;
[email protected]631f1322010-04-30 17:59:1111435 }
11436
[email protected]24476402010-07-20 20:55:1711437 const std::vector<GURL>& resolved() const { return resolved_; }
11438
11439 private:
[email protected]631f1322010-04-30 17:59:1111440 std::vector<GURL> resolved_;
11441
11442 DISALLOW_COPY_AND_ASSIGN(CapturingProxyResolver);
11443};
11444
sammce64b2362015-04-29 03:50:2311445class CapturingProxyResolverFactory : public ProxyResolverFactory {
11446 public:
11447 explicit CapturingProxyResolverFactory(CapturingProxyResolver* resolver)
11448 : ProxyResolverFactory(false), resolver_(resolver) {}
11449
11450 int CreateProxyResolver(
11451 const scoped_refptr<ProxyResolverScriptData>& pac_script,
danakj1fd259a02016-04-16 03:17:0911452 std::unique_ptr<ProxyResolver>* resolver,
sammce64b2362015-04-29 03:50:2311453 const net::CompletionCallback& callback,
danakj1fd259a02016-04-16 03:17:0911454 std::unique_ptr<Request>* request) override {
Jeremy Roman0579ed62017-08-29 15:56:1911455 *resolver = std::make_unique<ForwardingProxyResolver>(resolver_);
sammce64b2362015-04-29 03:50:2311456 return OK;
11457 }
11458
11459 private:
11460 ProxyResolver* resolver_;
11461};
11462
bnc2e884782016-08-11 19:45:1911463// Test that proxy is resolved using the origin url,
11464// regardless of the alternative server.
11465TEST_F(HttpNetworkTransactionTest, UseOriginNotAlternativeForProxy) {
11466 // Configure proxy to bypass www.example.org, which is the origin URL.
11467 ProxyConfig proxy_config;
11468 proxy_config.proxy_rules().ParseFromString("myproxy:70");
11469 proxy_config.proxy_rules().bypass_rules.AddRuleFromString("www.example.org");
11470 auto proxy_config_service =
Jeremy Roman0579ed62017-08-29 15:56:1911471 std::make_unique<ProxyConfigServiceFixed>(proxy_config);
bnc2e884782016-08-11 19:45:1911472
11473 CapturingProxyResolver capturing_proxy_resolver;
Jeremy Roman0579ed62017-08-29 15:56:1911474 auto proxy_resolver_factory = std::make_unique<CapturingProxyResolverFactory>(
bnc2e884782016-08-11 19:45:1911475 &capturing_proxy_resolver);
11476
11477 TestNetLog net_log;
11478
Jeremy Roman0579ed62017-08-29 15:56:1911479 session_deps_.proxy_service = std::make_unique<ProxyService>(
bnc2e884782016-08-11 19:45:1911480 std::move(proxy_config_service), std::move(proxy_resolver_factory),
11481 &net_log);
11482
11483 session_deps_.net_log = &net_log;
11484
11485 // Configure alternative service with a hostname that is not bypassed by the
11486 // proxy.
11487 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
11488 HttpServerProperties* http_server_properties =
11489 session->http_server_properties();
11490 url::SchemeHostPort server("https", "www.example.org", 443);
11491 HostPortPair alternative("www.example.com", 443);
bnc3472afd2016-11-17 15:27:2111492 AlternativeService alternative_service(kProtoHTTP2, alternative);
bnc2e884782016-08-11 19:45:1911493 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:2111494 http_server_properties->SetHttp2AlternativeService(
11495 server, alternative_service, expiration);
bnc2e884782016-08-11 19:45:1911496
11497 // Non-alternative job should hang.
11498 MockConnect never_finishing_connect(SYNCHRONOUS, ERR_IO_PENDING);
11499 StaticSocketDataProvider hanging_alternate_protocol_socket(nullptr, 0,
11500 nullptr, 0);
11501 hanging_alternate_protocol_socket.set_connect_data(never_finishing_connect);
11502 session_deps_.socket_factory->AddSocketDataProvider(
11503 &hanging_alternate_protocol_socket);
11504
bnc032658ba2016-09-26 18:17:1511505 AddSSLSocketData();
bnc2e884782016-08-11 19:45:1911506
11507 HttpRequestInfo request;
11508 request.method = "GET";
11509 request.url = GURL("https://www.example.org/");
11510 request.load_flags = 0;
11511
11512 SpdySerializedFrame req(
11513 spdy_util_.ConstructSpdyGet("https://www.example.org/", 1, LOWEST));
11514
11515 MockWrite spdy_writes[] = {CreateMockWrite(req, 0)};
11516
11517 SpdySerializedFrame resp(spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
11518 SpdySerializedFrame data(spdy_util_.ConstructSpdyDataFrame(1, true));
11519 MockRead spdy_reads[] = {
11520 CreateMockRead(resp, 1), CreateMockRead(data, 2), MockRead(ASYNC, 0, 3),
11521 };
11522
11523 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
11524 arraysize(spdy_writes));
11525 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
11526
11527 TestCompletionCallback callback;
11528
11529 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
11530
tfarina42834112016-09-22 13:38:2011531 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
bnc2e884782016-08-11 19:45:1911532 EXPECT_THAT(callback.GetResult(rv), IsOk());
11533
11534 const HttpResponseInfo* response = trans.GetResponseInfo();
11535 ASSERT_TRUE(response);
11536 ASSERT_TRUE(response->headers);
11537 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
11538 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5211539 EXPECT_TRUE(response->was_alpn_negotiated);
bnc2e884782016-08-11 19:45:1911540
11541 std::string response_data;
11542 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
11543 EXPECT_EQ("hello!", response_data);
11544
11545 // Origin host bypasses proxy, no resolution should have happened.
11546 ASSERT_TRUE(capturing_proxy_resolver.resolved().empty());
11547}
11548
bncd16676a2016-07-20 16:23:0111549TEST_F(HttpNetworkTransactionTest, UseAlternativeServiceForTunneledNpnSpdy) {
[email protected]631f1322010-04-30 17:59:1111550 ProxyConfig proxy_config;
[email protected]d911f1b2010-05-05 22:39:4211551 proxy_config.set_auto_detect(true);
11552 proxy_config.set_pac_url(GURL("http://fooproxyurl"));
[email protected]2227c692010-05-04 15:36:1111553
sammc5dd160c2015-04-02 02:43:1311554 CapturingProxyResolver capturing_proxy_resolver;
Jeremy Roman0579ed62017-08-29 15:56:1911555 session_deps_.proxy_service = std::make_unique<ProxyService>(
11556 std::make_unique<ProxyConfigServiceFixed>(proxy_config),
11557 std::make_unique<CapturingProxyResolverFactory>(
bnc87dcefc2017-05-25 12:47:5811558 &capturing_proxy_resolver),
11559 nullptr);
vishal.b62985ca92015-04-17 08:45:5111560 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:0711561 session_deps_.net_log = &net_log;
[email protected]631f1322010-04-30 17:59:1111562
11563 HttpRequestInfo request;
11564 request.method = "GET";
bncb26024382016-06-29 02:39:4511565 request.url = GURL("https://www.example.org/");
[email protected]631f1322010-04-30 17:59:1111566
11567 MockRead data_reads[] = {
bncc958faa2015-07-31 18:14:5211568 MockRead("HTTP/1.1 200 OK\r\n"),
bnc2df4b522016-07-08 18:17:4311569 MockRead(kAlternativeServiceHttpHeader),
bncc958faa2015-07-31 18:14:5211570 MockRead("\r\n"),
11571 MockRead("hello world"),
11572 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
11573 MockRead(ASYNC, OK),
[email protected]631f1322010-04-30 17:59:1111574 };
11575
11576 StaticSocketDataProvider first_transaction(
11577 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0711578 session_deps_.socket_factory->AddSocketDataProvider(&first_transaction);
bncb26024382016-06-29 02:39:4511579 SSLSocketDataProvider ssl_http11(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3611580 ssl_http11.next_proto = kProtoHTTP11;
bncb26024382016-06-29 02:39:4511581 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_http11);
[email protected]631f1322010-04-30 17:59:1111582
bnc032658ba2016-09-26 18:17:1511583 AddSSLSocketData();
[email protected]631f1322010-04-30 17:59:1111584
bncdf80d44fd2016-07-15 20:27:4111585 SpdySerializedFrame req(
bncb26024382016-06-29 02:39:4511586 spdy_util_.ConstructSpdyGet("https://www.example.org/", 1, LOWEST));
[email protected]631f1322010-04-30 17:59:1111587 MockWrite spdy_writes[] = {
rch8e6c6c42015-05-01 14:05:1311588 MockWrite(ASYNC, 0,
bnc8bef8da22016-05-30 01:28:2511589 "CONNECT www.example.org:443 HTTP/1.1\r\n"
11590 "Host: www.example.org:443\r\n"
rch8e6c6c42015-05-01 14:05:1311591 "Proxy-Connection: keep-alive\r\n\r\n"),
bncdf80d44fd2016-07-15 20:27:4111592 CreateMockWrite(req, 2),
[email protected]631f1322010-04-30 17:59:1111593 };
11594
[email protected]d911f1b2010-05-05 22:39:4211595 const char kCONNECTResponse[] = "HTTP/1.1 200 Connected\r\n\r\n";
11596
bnc42331402016-07-25 13:36:1511597 SpdySerializedFrame resp(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
bncdf80d44fd2016-07-15 20:27:4111598 SpdySerializedFrame data(spdy_util_.ConstructSpdyDataFrame(1, true));
[email protected]631f1322010-04-30 17:59:1111599 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:4111600 MockRead(ASYNC, 1, kCONNECTResponse), CreateMockRead(resp, 3),
11601 CreateMockRead(data, 4), MockRead(SYNCHRONOUS, ERR_IO_PENDING, 5),
[email protected]631f1322010-04-30 17:59:1111602 };
11603
rch8e6c6c42015-05-01 14:05:1311604 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
11605 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:0711606 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]631f1322010-04-30 17:59:1111607
[email protected]d973e99a2012-02-17 21:02:3611608 MockConnect never_finishing_connect(SYNCHRONOUS, ERR_IO_PENDING);
[email protected]2d6728692011-03-12 01:39:5511609 StaticSocketDataProvider hanging_non_alternate_protocol_socket(
11610 NULL, 0, NULL, 0);
11611 hanging_non_alternate_protocol_socket.set_connect_data(
11612 never_finishing_connect);
[email protected]bb88e1d32013-05-03 23:11:0711613 session_deps_.socket_factory->AddSocketDataProvider(
[email protected]2d6728692011-03-12 01:39:5511614 &hanging_non_alternate_protocol_socket);
11615
[email protected]49639fa2011-12-20 23:22:4111616 TestCompletionCallback callback;
[email protected]631f1322010-04-30 17:59:1111617
danakj1fd259a02016-04-16 03:17:0911618 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc87dcefc2017-05-25 12:47:5811619 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:1911620 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]631f1322010-04-30 17:59:1111621
tfarina42834112016-09-22 13:38:2011622 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
mmenkea2dcd3bf2016-08-16 21:49:4111623 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
11624 EXPECT_THAT(callback.WaitForResult(), IsOk());
11625
11626 const HttpResponseInfo* response = trans->GetResponseInfo();
11627 ASSERT_TRUE(response);
11628 ASSERT_TRUE(response->headers);
11629 EXPECT_EQ("HTTP/0.9 200 OK", response->headers->GetStatusLine());
11630 EXPECT_FALSE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5211631 EXPECT_TRUE(response->was_alpn_negotiated);
mmenkea2dcd3bf2016-08-16 21:49:4111632
11633 std::string response_data;
11634 ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
11635 EXPECT_EQ("hello world", response_data);
[email protected]631f1322010-04-30 17:59:1111636
bnc87dcefc2017-05-25 12:47:5811637 trans =
Jeremy Roman0579ed62017-08-29 15:56:1911638 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]631f1322010-04-30 17:59:1111639
tfarina42834112016-09-22 13:38:2011640 rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0111641 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
11642 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]631f1322010-04-30 17:59:1111643
mmenkea2dcd3bf2016-08-16 21:49:4111644 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5211645 ASSERT_TRUE(response);
11646 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0211647 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]65041fa2010-05-21 06:56:5311648 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5211649 EXPECT_TRUE(response->was_alpn_negotiated);
[email protected]631f1322010-04-30 17:59:1111650
robpercival214763f2016-07-01 23:27:0111651 ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
[email protected]631f1322010-04-30 17:59:1111652 EXPECT_EQ("hello!", response_data);
bncb26024382016-06-29 02:39:4511653 ASSERT_EQ(2u, capturing_proxy_resolver.resolved().size());
11654 EXPECT_EQ("https://www.example.org/",
sammc5dd160c2015-04-02 02:43:1311655 capturing_proxy_resolver.resolved()[0].spec());
bncce36dca22015-04-21 22:11:2311656 EXPECT_EQ("https://www.example.org/",
sammc5dd160c2015-04-02 02:43:1311657 capturing_proxy_resolver.resolved()[1].spec());
[email protected]631f1322010-04-30 17:59:1111658
[email protected]029c83b62013-01-24 05:28:2011659 LoadTimingInfo load_timing_info;
11660 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
11661 TestLoadTimingNotReusedWithPac(load_timing_info,
11662 CONNECT_TIMING_HAS_SSL_TIMES);
[email protected]631f1322010-04-30 17:59:1111663}
[email protected]631f1322010-04-30 17:59:1111664
bncd16676a2016-07-20 16:23:0111665TEST_F(HttpNetworkTransactionTest,
bnc1c196c6e2016-05-28 13:51:4811666 UseAlternativeServiceForNpnSpdyWithExistingSpdySession) {
[email protected]2ff8b312010-04-26 22:20:5411667 HttpRequestInfo request;
11668 request.method = "GET";
bncb26024382016-06-29 02:39:4511669 request.url = GURL("https://www.example.org/");
[email protected]2ff8b312010-04-26 22:20:5411670
11671 MockRead data_reads[] = {
bncc958faa2015-07-31 18:14:5211672 MockRead("HTTP/1.1 200 OK\r\n"),
bnc2df4b522016-07-08 18:17:4311673 MockRead(kAlternativeServiceHttpHeader),
bncc958faa2015-07-31 18:14:5211674 MockRead("\r\n"),
11675 MockRead("hello world"),
11676 MockRead(ASYNC, OK),
[email protected]2ff8b312010-04-26 22:20:5411677 };
11678
11679 StaticSocketDataProvider first_transaction(
11680 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0711681 session_deps_.socket_factory->AddSocketDataProvider(&first_transaction);
bncb26024382016-06-29 02:39:4511682 SSLSocketDataProvider ssl_http11(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3611683 ssl_http11.next_proto = kProtoHTTP11;
bncb26024382016-06-29 02:39:4511684 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_http11);
[email protected]2ff8b312010-04-26 22:20:5411685
bnc032658ba2016-09-26 18:17:1511686 AddSSLSocketData();
[email protected]2ff8b312010-04-26 22:20:5411687
bncdf80d44fd2016-07-15 20:27:4111688 SpdySerializedFrame req(
bncb26024382016-06-29 02:39:4511689 spdy_util_.ConstructSpdyGet("https://www.example.org/", 1, LOWEST));
bncdf80d44fd2016-07-15 20:27:4111690 MockWrite spdy_writes[] = {CreateMockWrite(req, 0)};
[email protected]2ff8b312010-04-26 22:20:5411691
bnc42331402016-07-25 13:36:1511692 SpdySerializedFrame resp(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
bncdf80d44fd2016-07-15 20:27:4111693 SpdySerializedFrame data(spdy_util_.ConstructSpdyDataFrame(1, true));
[email protected]2ff8b312010-04-26 22:20:5411694 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:4111695 CreateMockRead(resp, 1), CreateMockRead(data, 2), MockRead(ASYNC, 0, 3),
[email protected]2ff8b312010-04-26 22:20:5411696 };
11697
rch8e6c6c42015-05-01 14:05:1311698 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
11699 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:0711700 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]2ff8b312010-04-26 22:20:5411701
[email protected]83039bb2011-12-09 18:43:5511702 TestCompletionCallback callback;
[email protected]2ff8b312010-04-26 22:20:5411703
danakj1fd259a02016-04-16 03:17:0911704 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]2ff8b312010-04-26 22:20:5411705
bnc87dcefc2017-05-25 12:47:5811706 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:1911707 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]2ff8b312010-04-26 22:20:5411708
tfarina42834112016-09-22 13:38:2011709 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0111710 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
11711 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]2ff8b312010-04-26 22:20:5411712
11713 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5211714 ASSERT_TRUE(response);
11715 ASSERT_TRUE(response->headers);
[email protected]2ff8b312010-04-26 22:20:5411716 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
11717
11718 std::string response_data;
robpercival214763f2016-07-01 23:27:0111719 ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
[email protected]2ff8b312010-04-26 22:20:5411720 EXPECT_EQ("hello world", response_data);
11721
11722 // Set up an initial SpdySession in the pool to reuse.
bnc8bef8da22016-05-30 01:28:2511723 HostPortPair host_port_pair("www.example.org", 443);
[email protected]e6d017652013-05-17 18:01:4011724 SpdySessionKey key(host_port_pair, ProxyServer::Direct(),
[email protected]314b03992014-04-01 01:28:5311725 PRIVACY_MODE_DISABLED);
[email protected]795cbf82013-07-22 09:37:2711726 base::WeakPtr<SpdySession> spdy_session =
Bence Béky0ef1556e2017-06-30 19:52:5211727 CreateSpdySession(session.get(), key, NetLogWithSource());
[email protected]02b0c342010-09-25 21:09:3811728
bnc87dcefc2017-05-25 12:47:5811729 trans =
Jeremy Roman0579ed62017-08-29 15:56:1911730 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]2ff8b312010-04-26 22:20:5411731
tfarina42834112016-09-22 13:38:2011732 rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0111733 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
11734 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]2ff8b312010-04-26 22:20:5411735
11736 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5211737 ASSERT_TRUE(response);
11738 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0211739 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]65041fa2010-05-21 06:56:5311740 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5211741 EXPECT_TRUE(response->was_alpn_negotiated);
[email protected]2ff8b312010-04-26 22:20:5411742
robpercival214763f2016-07-01 23:27:0111743 ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
[email protected]2ff8b312010-04-26 22:20:5411744 EXPECT_EQ("hello!", response_data);
[email protected]564b4912010-03-09 16:30:4211745}
11746
[email protected]044de0642010-06-17 10:42:1511747// GenerateAuthToken is a mighty big test.
11748// It tests all permutation of GenerateAuthToken behavior:
11749// - Synchronous and Asynchronous completion.
11750// - OK or error on completion.
11751// - Direct connection, non-authenticating proxy, and authenticating proxy.
11752// - HTTP or HTTPS backend (to include proxy tunneling).
11753// - Non-authenticating and authenticating backend.
11754//
[email protected]fe3b7dc2012-02-03 19:52:0911755// In all, there are 44 reasonable permuations (for example, if there are
[email protected]044de0642010-06-17 10:42:1511756// problems generating an auth token for an authenticating proxy, we don't
11757// need to test all permutations of the backend server).
11758//
11759// The test proceeds by going over each of the configuration cases, and
11760// potentially running up to three rounds in each of the tests. The TestConfig
11761// specifies both the configuration for the test as well as the expectations
11762// for the results.
bncd16676a2016-07-20 16:23:0111763TEST_F(HttpNetworkTransactionTest, GenerateAuthToken) {
[email protected]0b0bf032010-09-21 18:08:5011764 static const char kServer[] = "http://www.example.com";
11765 static const char kSecureServer[] = "https://www.example.com";
11766 static const char kProxy[] = "myproxy:70";
[email protected]044de0642010-06-17 10:42:1511767
11768 enum AuthTiming {
11769 AUTH_NONE,
11770 AUTH_SYNC,
11771 AUTH_ASYNC,
11772 };
11773
11774 const MockWrite kGet(
11775 "GET / HTTP/1.1\r\n"
11776 "Host: www.example.com\r\n"
11777 "Connection: keep-alive\r\n\r\n");
11778 const MockWrite kGetProxy(
11779 "GET http://www.example.com/ HTTP/1.1\r\n"
11780 "Host: www.example.com\r\n"
11781 "Proxy-Connection: keep-alive\r\n\r\n");
11782 const MockWrite kGetAuth(
11783 "GET / HTTP/1.1\r\n"
11784 "Host: www.example.com\r\n"
11785 "Connection: keep-alive\r\n"
11786 "Authorization: auth_token\r\n\r\n");
11787 const MockWrite kGetProxyAuth(
11788 "GET http://www.example.com/ HTTP/1.1\r\n"
11789 "Host: www.example.com\r\n"
11790 "Proxy-Connection: keep-alive\r\n"
11791 "Proxy-Authorization: auth_token\r\n\r\n");
11792 const MockWrite kGetAuthThroughProxy(
11793 "GET http://www.example.com/ HTTP/1.1\r\n"
11794 "Host: www.example.com\r\n"
11795 "Proxy-Connection: keep-alive\r\n"
11796 "Authorization: auth_token\r\n\r\n");
11797 const MockWrite kGetAuthWithProxyAuth(
11798 "GET http://www.example.com/ HTTP/1.1\r\n"
11799 "Host: www.example.com\r\n"
11800 "Proxy-Connection: keep-alive\r\n"
11801 "Proxy-Authorization: auth_token\r\n"
11802 "Authorization: auth_token\r\n\r\n");
11803 const MockWrite kConnect(
11804 "CONNECT www.example.com:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:1711805 "Host: www.example.com:443\r\n"
[email protected]044de0642010-06-17 10:42:1511806 "Proxy-Connection: keep-alive\r\n\r\n");
11807 const MockWrite kConnectProxyAuth(
11808 "CONNECT www.example.com:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:1711809 "Host: www.example.com:443\r\n"
[email protected]044de0642010-06-17 10:42:1511810 "Proxy-Connection: keep-alive\r\n"
11811 "Proxy-Authorization: auth_token\r\n\r\n");
11812
11813 const MockRead kSuccess(
11814 "HTTP/1.1 200 OK\r\n"
11815 "Content-Type: text/html; charset=iso-8859-1\r\n"
11816 "Content-Length: 3\r\n\r\n"
11817 "Yes");
11818 const MockRead kFailure(
11819 "Should not be called.");
11820 const MockRead kServerChallenge(
11821 "HTTP/1.1 401 Unauthorized\r\n"
11822 "WWW-Authenticate: Mock realm=server\r\n"
11823 "Content-Type: text/html; charset=iso-8859-1\r\n"
11824 "Content-Length: 14\r\n\r\n"
11825 "Unauthorized\r\n");
11826 const MockRead kProxyChallenge(
11827 "HTTP/1.1 407 Unauthorized\r\n"
11828 "Proxy-Authenticate: Mock realm=proxy\r\n"
11829 "Proxy-Connection: close\r\n"
11830 "Content-Type: text/html; charset=iso-8859-1\r\n"
11831 "Content-Length: 14\r\n\r\n"
11832 "Unauthorized\r\n");
11833 const MockRead kProxyConnected(
11834 "HTTP/1.1 200 Connection Established\r\n\r\n");
11835
11836 // NOTE(cbentzel): I wanted TestReadWriteRound to be a simple struct with
11837 // no constructors, but the C++ compiler on Windows warns about
11838 // unspecified data in compound literals. So, moved to using constructors,
11839 // and TestRound's created with the default constructor should not be used.
11840 struct TestRound {
11841 TestRound()
11842 : expected_rv(ERR_UNEXPECTED),
11843 extra_write(NULL),
11844 extra_read(NULL) {
11845 }
11846 TestRound(const MockWrite& write_arg, const MockRead& read_arg,
11847 int expected_rv_arg)
11848 : write(write_arg),
11849 read(read_arg),
11850 expected_rv(expected_rv_arg),
11851 extra_write(NULL),
11852 extra_read(NULL) {
11853 }
11854 TestRound(const MockWrite& write_arg, const MockRead& read_arg,
11855 int expected_rv_arg, const MockWrite* extra_write_arg,
[email protected]f871ee152012-07-27 19:02:0111856 const MockRead* extra_read_arg)
[email protected]044de0642010-06-17 10:42:1511857 : write(write_arg),
11858 read(read_arg),
11859 expected_rv(expected_rv_arg),
11860 extra_write(extra_write_arg),
11861 extra_read(extra_read_arg) {
11862 }
11863 MockWrite write;
11864 MockRead read;
11865 int expected_rv;
11866 const MockWrite* extra_write;
11867 const MockRead* extra_read;
11868 };
11869
11870 static const int kNoSSL = 500;
11871
11872 struct TestConfig {
asanka463ca4262016-11-16 02:34:3111873 int line_number;
thestig9d3bb0c2015-01-24 00:49:5111874 const char* const proxy_url;
[email protected]044de0642010-06-17 10:42:1511875 AuthTiming proxy_auth_timing;
asanka463ca4262016-11-16 02:34:3111876 int first_generate_proxy_token_rv;
thestig9d3bb0c2015-01-24 00:49:5111877 const char* const server_url;
[email protected]044de0642010-06-17 10:42:1511878 AuthTiming server_auth_timing;
asanka463ca4262016-11-16 02:34:3111879 int first_generate_server_token_rv;
[email protected]044de0642010-06-17 10:42:1511880 int num_auth_rounds;
11881 int first_ssl_round;
asankae2257db2016-10-11 22:03:1611882 TestRound rounds[4];
[email protected]044de0642010-06-17 10:42:1511883 } test_configs[] = {
asankac93076192016-10-03 15:46:0211884 // Non-authenticating HTTP server with a direct connection.
asanka463ca4262016-11-16 02:34:3111885 {__LINE__,
11886 nullptr,
asankac93076192016-10-03 15:46:0211887 AUTH_NONE,
11888 OK,
11889 kServer,
11890 AUTH_NONE,
11891 OK,
11892 1,
11893 kNoSSL,
11894 {TestRound(kGet, kSuccess, OK)}},
11895 // Authenticating HTTP server with a direct connection.
asanka463ca4262016-11-16 02:34:3111896 {__LINE__,
11897 nullptr,
asankac93076192016-10-03 15:46:0211898 AUTH_NONE,
11899 OK,
11900 kServer,
11901 AUTH_SYNC,
11902 OK,
11903 2,
11904 kNoSSL,
11905 {TestRound(kGet, kServerChallenge, OK),
[email protected]044de0642010-06-17 10:42:1511906 TestRound(kGetAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3111907 {__LINE__,
11908 nullptr,
asankac93076192016-10-03 15:46:0211909 AUTH_NONE,
11910 OK,
11911 kServer,
11912 AUTH_SYNC,
11913 ERR_INVALID_AUTH_CREDENTIALS,
asankae2257db2016-10-11 22:03:1611914 3,
11915 kNoSSL,
11916 {TestRound(kGet, kServerChallenge, OK),
11917 TestRound(kGet, kServerChallenge, OK),
11918 TestRound(kGetAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3111919 {__LINE__,
11920 nullptr,
asankae2257db2016-10-11 22:03:1611921 AUTH_NONE,
11922 OK,
11923 kServer,
11924 AUTH_SYNC,
11925 ERR_UNSUPPORTED_AUTH_SCHEME,
11926 2,
11927 kNoSSL,
11928 {TestRound(kGet, kServerChallenge, OK), TestRound(kGet, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3111929 {__LINE__,
11930 nullptr,
asankae2257db2016-10-11 22:03:1611931 AUTH_NONE,
11932 OK,
11933 kServer,
11934 AUTH_SYNC,
11935 ERR_UNDOCUMENTED_SECURITY_LIBRARY_STATUS,
11936 2,
11937 kNoSSL,
11938 {TestRound(kGet, kServerChallenge, OK), TestRound(kGet, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3111939 {__LINE__,
11940 kProxy,
asankae2257db2016-10-11 22:03:1611941 AUTH_SYNC,
11942 ERR_FAILED,
11943 kServer,
11944 AUTH_NONE,
11945 OK,
11946 2,
11947 kNoSSL,
11948 {TestRound(kGetProxy, kProxyChallenge, OK),
11949 TestRound(kGetProxy, kFailure, ERR_FAILED)}},
asanka463ca4262016-11-16 02:34:3111950 {__LINE__,
11951 kProxy,
asankae2257db2016-10-11 22:03:1611952 AUTH_ASYNC,
11953 ERR_FAILED,
11954 kServer,
11955 AUTH_NONE,
11956 OK,
11957 2,
11958 kNoSSL,
11959 {TestRound(kGetProxy, kProxyChallenge, OK),
11960 TestRound(kGetProxy, kFailure, ERR_FAILED)}},
asanka463ca4262016-11-16 02:34:3111961 {__LINE__,
11962 nullptr,
asankae2257db2016-10-11 22:03:1611963 AUTH_NONE,
11964 OK,
11965 kServer,
11966 AUTH_SYNC,
11967 ERR_FAILED,
asankac93076192016-10-03 15:46:0211968 2,
11969 kNoSSL,
11970 {TestRound(kGet, kServerChallenge, OK),
asankae2257db2016-10-11 22:03:1611971 TestRound(kGet, kFailure, ERR_FAILED)}},
asanka463ca4262016-11-16 02:34:3111972 {__LINE__,
11973 nullptr,
asankae2257db2016-10-11 22:03:1611974 AUTH_NONE,
11975 OK,
11976 kServer,
11977 AUTH_ASYNC,
11978 ERR_FAILED,
11979 2,
11980 kNoSSL,
11981 {TestRound(kGet, kServerChallenge, OK),
11982 TestRound(kGet, kFailure, ERR_FAILED)}},
asanka463ca4262016-11-16 02:34:3111983 {__LINE__,
11984 nullptr,
asankac93076192016-10-03 15:46:0211985 AUTH_NONE,
11986 OK,
11987 kServer,
11988 AUTH_ASYNC,
11989 OK,
11990 2,
11991 kNoSSL,
11992 {TestRound(kGet, kServerChallenge, OK),
[email protected]044de0642010-06-17 10:42:1511993 TestRound(kGetAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3111994 {__LINE__,
11995 nullptr,
asankac93076192016-10-03 15:46:0211996 AUTH_NONE,
11997 OK,
11998 kServer,
11999 AUTH_ASYNC,
12000 ERR_INVALID_AUTH_CREDENTIALS,
asankae2257db2016-10-11 22:03:1612001 3,
asankac93076192016-10-03 15:46:0212002 kNoSSL,
12003 {TestRound(kGet, kServerChallenge, OK),
asankae2257db2016-10-11 22:03:1612004 // The second round uses a HttpAuthHandlerMock that always succeeds.
12005 TestRound(kGet, kServerChallenge, OK),
12006 TestRound(kGetAuth, kSuccess, OK)}},
asankac93076192016-10-03 15:46:0212007 // Non-authenticating HTTP server through a non-authenticating proxy.
asanka463ca4262016-11-16 02:34:3112008 {__LINE__,
12009 kProxy,
asankac93076192016-10-03 15:46:0212010 AUTH_NONE,
12011 OK,
12012 kServer,
12013 AUTH_NONE,
12014 OK,
12015 1,
12016 kNoSSL,
12017 {TestRound(kGetProxy, kSuccess, OK)}},
12018 // Authenticating HTTP server through a non-authenticating proxy.
asanka463ca4262016-11-16 02:34:3112019 {__LINE__,
12020 kProxy,
asankac93076192016-10-03 15:46:0212021 AUTH_NONE,
12022 OK,
12023 kServer,
12024 AUTH_SYNC,
12025 OK,
12026 2,
12027 kNoSSL,
12028 {TestRound(kGetProxy, kServerChallenge, OK),
[email protected]044de0642010-06-17 10:42:1512029 TestRound(kGetAuthThroughProxy, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112030 {__LINE__,
12031 kProxy,
asankac93076192016-10-03 15:46:0212032 AUTH_NONE,
12033 OK,
12034 kServer,
12035 AUTH_SYNC,
12036 ERR_INVALID_AUTH_CREDENTIALS,
asankae2257db2016-10-11 22:03:1612037 3,
asankac93076192016-10-03 15:46:0212038 kNoSSL,
12039 {TestRound(kGetProxy, kServerChallenge, OK),
asankae2257db2016-10-11 22:03:1612040 TestRound(kGetProxy, kServerChallenge, OK),
12041 TestRound(kGetAuthThroughProxy, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112042 {__LINE__,
12043 kProxy,
asankac93076192016-10-03 15:46:0212044 AUTH_NONE,
12045 OK,
12046 kServer,
12047 AUTH_ASYNC,
12048 OK,
12049 2,
12050 kNoSSL,
12051 {TestRound(kGetProxy, kServerChallenge, OK),
[email protected]044de0642010-06-17 10:42:1512052 TestRound(kGetAuthThroughProxy, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112053 {__LINE__,
12054 kProxy,
asankac93076192016-10-03 15:46:0212055 AUTH_NONE,
12056 OK,
12057 kServer,
12058 AUTH_ASYNC,
12059 ERR_INVALID_AUTH_CREDENTIALS,
12060 2,
12061 kNoSSL,
12062 {TestRound(kGetProxy, kServerChallenge, OK),
asankae2257db2016-10-11 22:03:1612063 TestRound(kGetProxy, kSuccess, OK)}},
asankac93076192016-10-03 15:46:0212064 // Non-authenticating HTTP server through an authenticating proxy.
asanka463ca4262016-11-16 02:34:3112065 {__LINE__,
12066 kProxy,
asankac93076192016-10-03 15:46:0212067 AUTH_SYNC,
12068 OK,
12069 kServer,
12070 AUTH_NONE,
12071 OK,
12072 2,
12073 kNoSSL,
12074 {TestRound(kGetProxy, kProxyChallenge, OK),
[email protected]044de0642010-06-17 10:42:1512075 TestRound(kGetProxyAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112076 {__LINE__,
12077 kProxy,
asankac93076192016-10-03 15:46:0212078 AUTH_SYNC,
12079 ERR_INVALID_AUTH_CREDENTIALS,
12080 kServer,
12081 AUTH_NONE,
12082 OK,
12083 2,
12084 kNoSSL,
12085 {TestRound(kGetProxy, kProxyChallenge, OK),
asankae2257db2016-10-11 22:03:1612086 TestRound(kGetProxy, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112087 {__LINE__,
12088 kProxy,
asankac93076192016-10-03 15:46:0212089 AUTH_ASYNC,
12090 OK,
12091 kServer,
12092 AUTH_NONE,
12093 OK,
12094 2,
12095 kNoSSL,
12096 {TestRound(kGetProxy, kProxyChallenge, OK),
[email protected]044de0642010-06-17 10:42:1512097 TestRound(kGetProxyAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112098 {__LINE__,
12099 kProxy,
asankac93076192016-10-03 15:46:0212100 AUTH_ASYNC,
12101 ERR_INVALID_AUTH_CREDENTIALS,
12102 kServer,
12103 AUTH_NONE,
12104 OK,
12105 2,
12106 kNoSSL,
12107 {TestRound(kGetProxy, kProxyChallenge, OK),
asankae2257db2016-10-11 22:03:1612108 TestRound(kGetProxy, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112109 {__LINE__,
12110 kProxy,
12111 AUTH_ASYNC,
12112 ERR_INVALID_AUTH_CREDENTIALS,
12113 kServer,
12114 AUTH_NONE,
12115 OK,
12116 3,
12117 kNoSSL,
12118 {TestRound(kGetProxy, kProxyChallenge, OK),
12119 TestRound(kGetProxy, kProxyChallenge, OK),
12120 TestRound(kGetProxyAuth, kSuccess, OK)}},
asankac93076192016-10-03 15:46:0212121 // Authenticating HTTP server through an authenticating proxy.
asanka463ca4262016-11-16 02:34:3112122 {__LINE__,
12123 kProxy,
asankac93076192016-10-03 15:46:0212124 AUTH_SYNC,
12125 OK,
12126 kServer,
12127 AUTH_SYNC,
12128 OK,
12129 3,
12130 kNoSSL,
12131 {TestRound(kGetProxy, kProxyChallenge, OK),
[email protected]044de0642010-06-17 10:42:1512132 TestRound(kGetProxyAuth, kServerChallenge, OK),
12133 TestRound(kGetAuthWithProxyAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112134 {__LINE__,
12135 kProxy,
asankac93076192016-10-03 15:46:0212136 AUTH_SYNC,
12137 OK,
12138 kServer,
12139 AUTH_SYNC,
12140 ERR_INVALID_AUTH_CREDENTIALS,
12141 3,
12142 kNoSSL,
12143 {TestRound(kGetProxy, kProxyChallenge, OK),
[email protected]044de0642010-06-17 10:42:1512144 TestRound(kGetProxyAuth, kServerChallenge, OK),
asankae2257db2016-10-11 22:03:1612145 TestRound(kGetProxyAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112146 {__LINE__,
12147 kProxy,
asankac93076192016-10-03 15:46:0212148 AUTH_ASYNC,
12149 OK,
12150 kServer,
12151 AUTH_SYNC,
12152 OK,
12153 3,
12154 kNoSSL,
12155 {TestRound(kGetProxy, kProxyChallenge, OK),
[email protected]044de0642010-06-17 10:42:1512156 TestRound(kGetProxyAuth, kServerChallenge, OK),
12157 TestRound(kGetAuthWithProxyAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112158 {__LINE__,
12159 kProxy,
asankac93076192016-10-03 15:46:0212160 AUTH_ASYNC,
12161 OK,
12162 kServer,
12163 AUTH_SYNC,
12164 ERR_INVALID_AUTH_CREDENTIALS,
12165 3,
12166 kNoSSL,
12167 {TestRound(kGetProxy, kProxyChallenge, OK),
[email protected]044de0642010-06-17 10:42:1512168 TestRound(kGetProxyAuth, kServerChallenge, OK),
asankae2257db2016-10-11 22:03:1612169 TestRound(kGetProxyAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112170 {__LINE__,
12171 kProxy,
asankac93076192016-10-03 15:46:0212172 AUTH_SYNC,
12173 OK,
12174 kServer,
12175 AUTH_ASYNC,
12176 OK,
12177 3,
12178 kNoSSL,
12179 {TestRound(kGetProxy, kProxyChallenge, OK),
[email protected]044de0642010-06-17 10:42:1512180 TestRound(kGetProxyAuth, kServerChallenge, OK),
12181 TestRound(kGetAuthWithProxyAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112182 {__LINE__,
12183 kProxy,
12184 AUTH_SYNC,
12185 ERR_INVALID_AUTH_CREDENTIALS,
12186 kServer,
12187 AUTH_ASYNC,
12188 OK,
12189 4,
12190 kNoSSL,
12191 {TestRound(kGetProxy, kProxyChallenge, OK),
12192 TestRound(kGetProxy, kProxyChallenge, OK),
12193 TestRound(kGetProxyAuth, kServerChallenge, OK),
12194 TestRound(kGetAuthWithProxyAuth, kSuccess, OK)}},
12195 {__LINE__,
12196 kProxy,
asankac93076192016-10-03 15:46:0212197 AUTH_SYNC,
12198 OK,
12199 kServer,
12200 AUTH_ASYNC,
12201 ERR_INVALID_AUTH_CREDENTIALS,
12202 3,
12203 kNoSSL,
12204 {TestRound(kGetProxy, kProxyChallenge, OK),
[email protected]044de0642010-06-17 10:42:1512205 TestRound(kGetProxyAuth, kServerChallenge, OK),
asankae2257db2016-10-11 22:03:1612206 TestRound(kGetProxyAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112207 {__LINE__,
12208 kProxy,
asankac93076192016-10-03 15:46:0212209 AUTH_ASYNC,
12210 OK,
12211 kServer,
12212 AUTH_ASYNC,
12213 OK,
12214 3,
12215 kNoSSL,
12216 {TestRound(kGetProxy, kProxyChallenge, OK),
[email protected]044de0642010-06-17 10:42:1512217 TestRound(kGetProxyAuth, kServerChallenge, OK),
12218 TestRound(kGetAuthWithProxyAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112219 {__LINE__,
12220 kProxy,
asankac93076192016-10-03 15:46:0212221 AUTH_ASYNC,
12222 OK,
12223 kServer,
12224 AUTH_ASYNC,
12225 ERR_INVALID_AUTH_CREDENTIALS,
12226 3,
12227 kNoSSL,
12228 {TestRound(kGetProxy, kProxyChallenge, OK),
[email protected]044de0642010-06-17 10:42:1512229 TestRound(kGetProxyAuth, kServerChallenge, OK),
asankae2257db2016-10-11 22:03:1612230 TestRound(kGetProxyAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112231 {__LINE__,
12232 kProxy,
12233 AUTH_ASYNC,
12234 ERR_INVALID_AUTH_CREDENTIALS,
12235 kServer,
12236 AUTH_ASYNC,
12237 ERR_INVALID_AUTH_CREDENTIALS,
12238 4,
12239 kNoSSL,
12240 {TestRound(kGetProxy, kProxyChallenge, OK),
12241 TestRound(kGetProxy, kProxyChallenge, OK),
12242 TestRound(kGetProxyAuth, kServerChallenge, OK),
12243 TestRound(kGetProxyAuth, kSuccess, OK)}},
asankac93076192016-10-03 15:46:0212244 // Non-authenticating HTTPS server with a direct connection.
asanka463ca4262016-11-16 02:34:3112245 {__LINE__,
12246 nullptr,
asankac93076192016-10-03 15:46:0212247 AUTH_NONE,
12248 OK,
12249 kSecureServer,
12250 AUTH_NONE,
12251 OK,
12252 1,
12253 0,
12254 {TestRound(kGet, kSuccess, OK)}},
12255 // Authenticating HTTPS server with a direct connection.
asanka463ca4262016-11-16 02:34:3112256 {__LINE__,
12257 nullptr,
asankac93076192016-10-03 15:46:0212258 AUTH_NONE,
12259 OK,
12260 kSecureServer,
12261 AUTH_SYNC,
12262 OK,
12263 2,
12264 0,
12265 {TestRound(kGet, kServerChallenge, OK),
[email protected]044de0642010-06-17 10:42:1512266 TestRound(kGetAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112267 {__LINE__,
12268 nullptr,
asankac93076192016-10-03 15:46:0212269 AUTH_NONE,
12270 OK,
12271 kSecureServer,
12272 AUTH_SYNC,
12273 ERR_INVALID_AUTH_CREDENTIALS,
12274 2,
12275 0,
asankae2257db2016-10-11 22:03:1612276 {TestRound(kGet, kServerChallenge, OK), TestRound(kGet, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112277 {__LINE__,
12278 nullptr,
asankac93076192016-10-03 15:46:0212279 AUTH_NONE,
12280 OK,
12281 kSecureServer,
12282 AUTH_ASYNC,
12283 OK,
12284 2,
12285 0,
12286 {TestRound(kGet, kServerChallenge, OK),
[email protected]044de0642010-06-17 10:42:1512287 TestRound(kGetAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112288 {__LINE__,
12289 nullptr,
asankac93076192016-10-03 15:46:0212290 AUTH_NONE,
12291 OK,
12292 kSecureServer,
12293 AUTH_ASYNC,
12294 ERR_INVALID_AUTH_CREDENTIALS,
12295 2,
12296 0,
asankae2257db2016-10-11 22:03:1612297 {TestRound(kGet, kServerChallenge, OK), TestRound(kGet, kSuccess, OK)}},
asankac93076192016-10-03 15:46:0212298 // Non-authenticating HTTPS server with a non-authenticating proxy.
asanka463ca4262016-11-16 02:34:3112299 {__LINE__,
12300 kProxy,
asankac93076192016-10-03 15:46:0212301 AUTH_NONE,
12302 OK,
12303 kSecureServer,
12304 AUTH_NONE,
12305 OK,
12306 1,
12307 0,
12308 {TestRound(kConnect, kProxyConnected, OK, &kGet, &kSuccess)}},
12309 // Authenticating HTTPS server through a non-authenticating proxy.
asanka463ca4262016-11-16 02:34:3112310 {__LINE__,
12311 kProxy,
asankac93076192016-10-03 15:46:0212312 AUTH_NONE,
12313 OK,
12314 kSecureServer,
12315 AUTH_SYNC,
12316 OK,
12317 2,
12318 0,
12319 {TestRound(kConnect, kProxyConnected, OK, &kGet, &kServerChallenge),
[email protected]044de0642010-06-17 10:42:1512320 TestRound(kGetAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112321 {__LINE__,
12322 kProxy,
asankac93076192016-10-03 15:46:0212323 AUTH_NONE,
12324 OK,
12325 kSecureServer,
12326 AUTH_SYNC,
12327 ERR_INVALID_AUTH_CREDENTIALS,
12328 2,
12329 0,
12330 {TestRound(kConnect, kProxyConnected, OK, &kGet, &kServerChallenge),
asankae2257db2016-10-11 22:03:1612331 TestRound(kGet, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112332 {__LINE__,
12333 kProxy,
asankac93076192016-10-03 15:46:0212334 AUTH_NONE,
12335 OK,
12336 kSecureServer,
12337 AUTH_ASYNC,
12338 OK,
12339 2,
12340 0,
12341 {TestRound(kConnect, kProxyConnected, OK, &kGet, &kServerChallenge),
[email protected]044de0642010-06-17 10:42:1512342 TestRound(kGetAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112343 {__LINE__,
12344 kProxy,
asankac93076192016-10-03 15:46:0212345 AUTH_NONE,
12346 OK,
12347 kSecureServer,
12348 AUTH_ASYNC,
12349 ERR_INVALID_AUTH_CREDENTIALS,
12350 2,
12351 0,
12352 {TestRound(kConnect, kProxyConnected, OK, &kGet, &kServerChallenge),
asankae2257db2016-10-11 22:03:1612353 TestRound(kGet, kSuccess, OK)}},
asankac93076192016-10-03 15:46:0212354 // Non-Authenticating HTTPS server through an authenticating proxy.
asanka463ca4262016-11-16 02:34:3112355 {__LINE__,
12356 kProxy,
asankac93076192016-10-03 15:46:0212357 AUTH_SYNC,
12358 OK,
12359 kSecureServer,
12360 AUTH_NONE,
12361 OK,
12362 2,
12363 1,
12364 {TestRound(kConnect, kProxyChallenge, OK),
[email protected]044de0642010-06-17 10:42:1512365 TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet, &kSuccess)}},
asanka463ca4262016-11-16 02:34:3112366 {__LINE__,
12367 kProxy,
asankac93076192016-10-03 15:46:0212368 AUTH_SYNC,
12369 ERR_INVALID_AUTH_CREDENTIALS,
12370 kSecureServer,
12371 AUTH_NONE,
12372 OK,
12373 2,
12374 kNoSSL,
12375 {TestRound(kConnect, kProxyChallenge, OK),
asankae2257db2016-10-11 22:03:1612376 TestRound(kConnect, kProxyConnected, OK, &kGet, &kSuccess)}},
asanka463ca4262016-11-16 02:34:3112377 {__LINE__,
12378 kProxy,
asankae2257db2016-10-11 22:03:1612379 AUTH_SYNC,
12380 ERR_UNSUPPORTED_AUTH_SCHEME,
12381 kSecureServer,
12382 AUTH_NONE,
12383 OK,
12384 2,
12385 kNoSSL,
12386 {TestRound(kConnect, kProxyChallenge, OK),
12387 TestRound(kConnect, kProxyConnected, OK, &kGet, &kSuccess)}},
asanka463ca4262016-11-16 02:34:3112388 {__LINE__,
12389 kProxy,
asankae2257db2016-10-11 22:03:1612390 AUTH_SYNC,
12391 ERR_UNEXPECTED,
12392 kSecureServer,
12393 AUTH_NONE,
12394 OK,
12395 2,
12396 kNoSSL,
12397 {TestRound(kConnect, kProxyChallenge, OK),
12398 TestRound(kConnect, kProxyConnected, ERR_UNEXPECTED)}},
asanka463ca4262016-11-16 02:34:3112399 {__LINE__,
12400 kProxy,
asankac93076192016-10-03 15:46:0212401 AUTH_ASYNC,
12402 OK,
12403 kSecureServer,
12404 AUTH_NONE,
12405 OK,
12406 2,
12407 1,
12408 {TestRound(kConnect, kProxyChallenge, OK),
[email protected]044de0642010-06-17 10:42:1512409 TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet, &kSuccess)}},
asanka463ca4262016-11-16 02:34:3112410 {__LINE__,
12411 kProxy,
asankac93076192016-10-03 15:46:0212412 AUTH_ASYNC,
12413 ERR_INVALID_AUTH_CREDENTIALS,
12414 kSecureServer,
12415 AUTH_NONE,
12416 OK,
12417 2,
12418 kNoSSL,
12419 {TestRound(kConnect, kProxyChallenge, OK),
asankae2257db2016-10-11 22:03:1612420 TestRound(kConnect, kProxyConnected, OK, &kGet, &kSuccess)}},
asankac93076192016-10-03 15:46:0212421 // Authenticating HTTPS server through an authenticating proxy.
asanka463ca4262016-11-16 02:34:3112422 {__LINE__,
12423 kProxy,
asankac93076192016-10-03 15:46:0212424 AUTH_SYNC,
12425 OK,
12426 kSecureServer,
12427 AUTH_SYNC,
12428 OK,
12429 3,
12430 1,
12431 {TestRound(kConnect, kProxyChallenge, OK),
12432 TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet,
12433 &kServerChallenge),
[email protected]044de0642010-06-17 10:42:1512434 TestRound(kGetAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112435 {__LINE__,
12436 kProxy,
asankac93076192016-10-03 15:46:0212437 AUTH_SYNC,
12438 OK,
12439 kSecureServer,
12440 AUTH_SYNC,
12441 ERR_INVALID_AUTH_CREDENTIALS,
12442 3,
12443 1,
12444 {TestRound(kConnect, kProxyChallenge, OK),
12445 TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet,
12446 &kServerChallenge),
asankae2257db2016-10-11 22:03:1612447 TestRound(kGet, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112448 {__LINE__,
12449 kProxy,
asankac93076192016-10-03 15:46:0212450 AUTH_ASYNC,
12451 OK,
12452 kSecureServer,
12453 AUTH_SYNC,
12454 OK,
12455 3,
12456 1,
12457 {TestRound(kConnect, kProxyChallenge, OK),
12458 TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet,
12459 &kServerChallenge),
[email protected]044de0642010-06-17 10:42:1512460 TestRound(kGetAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112461 {__LINE__,
12462 kProxy,
asankac93076192016-10-03 15:46:0212463 AUTH_ASYNC,
12464 OK,
12465 kSecureServer,
12466 AUTH_SYNC,
12467 ERR_INVALID_AUTH_CREDENTIALS,
12468 3,
12469 1,
12470 {TestRound(kConnect, kProxyChallenge, OK),
12471 TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet,
12472 &kServerChallenge),
asankae2257db2016-10-11 22:03:1612473 TestRound(kGet, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112474 {__LINE__,
12475 kProxy,
asankac93076192016-10-03 15:46:0212476 AUTH_SYNC,
12477 OK,
12478 kSecureServer,
12479 AUTH_ASYNC,
12480 OK,
12481 3,
12482 1,
12483 {TestRound(kConnect, kProxyChallenge, OK),
12484 TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet,
12485 &kServerChallenge),
[email protected]044de0642010-06-17 10:42:1512486 TestRound(kGetAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112487 {__LINE__,
12488 kProxy,
asankac93076192016-10-03 15:46:0212489 AUTH_SYNC,
12490 OK,
12491 kSecureServer,
12492 AUTH_ASYNC,
12493 ERR_INVALID_AUTH_CREDENTIALS,
12494 3,
12495 1,
12496 {TestRound(kConnect, kProxyChallenge, OK),
12497 TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet,
12498 &kServerChallenge),
asankae2257db2016-10-11 22:03:1612499 TestRound(kGet, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112500 {__LINE__,
12501 kProxy,
asankac93076192016-10-03 15:46:0212502 AUTH_ASYNC,
12503 OK,
12504 kSecureServer,
12505 AUTH_ASYNC,
12506 OK,
12507 3,
12508 1,
12509 {TestRound(kConnect, kProxyChallenge, OK),
12510 TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet,
12511 &kServerChallenge),
[email protected]044de0642010-06-17 10:42:1512512 TestRound(kGetAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112513 {__LINE__,
12514 kProxy,
asankac93076192016-10-03 15:46:0212515 AUTH_ASYNC,
12516 OK,
12517 kSecureServer,
12518 AUTH_ASYNC,
12519 ERR_INVALID_AUTH_CREDENTIALS,
12520 3,
12521 1,
12522 {TestRound(kConnect, kProxyChallenge, OK),
12523 TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet,
12524 &kServerChallenge),
asankae2257db2016-10-11 22:03:1612525 TestRound(kGet, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112526 {__LINE__,
12527 kProxy,
12528 AUTH_ASYNC,
12529 ERR_INVALID_AUTH_CREDENTIALS,
12530 kSecureServer,
12531 AUTH_ASYNC,
12532 ERR_INVALID_AUTH_CREDENTIALS,
12533 4,
12534 2,
12535 {TestRound(kConnect, kProxyChallenge, OK),
12536 TestRound(kConnect, kProxyChallenge, OK),
12537 TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet,
12538 &kServerChallenge),
12539 TestRound(kGet, kSuccess, OK)}},
[email protected]044de0642010-06-17 10:42:1512540 };
12541
asanka463ca4262016-11-16 02:34:3112542 for (const auto& test_config : test_configs) {
12543 SCOPED_TRACE(::testing::Message() << "Test config at "
12544 << test_config.line_number);
[email protected]2d01c262011-08-11 23:07:0812545 HttpAuthHandlerMock::Factory* auth_factory(
12546 new HttpAuthHandlerMock::Factory());
[email protected]bb88e1d32013-05-03 23:11:0712547 session_deps_.http_auth_handler_factory.reset(auth_factory);
asanka5ffd5d72016-03-23 16:20:4912548 SSLInfo empty_ssl_info;
[email protected]65d34382010-07-01 18:12:2612549
12550 // Set up authentication handlers as necessary.
[email protected]044de0642010-06-17 10:42:1512551 if (test_config.proxy_auth_timing != AUTH_NONE) {
asanka463ca4262016-11-16 02:34:3112552 for (int n = 0; n < 3; n++) {
[email protected]2d01c262011-08-11 23:07:0812553 HttpAuthHandlerMock* auth_handler(new HttpAuthHandlerMock());
12554 std::string auth_challenge = "Mock realm=proxy";
12555 GURL origin(test_config.proxy_url);
[email protected]df41d0d82014-03-13 00:43:2412556 HttpAuthChallengeTokenizer tokenizer(auth_challenge.begin(),
12557 auth_challenge.end());
[email protected]2d01c262011-08-11 23:07:0812558 auth_handler->InitFromChallenge(&tokenizer, HttpAuth::AUTH_PROXY,
tfarina42834112016-09-22 13:38:2012559 empty_ssl_info, origin,
12560 NetLogWithSource());
[email protected]2d01c262011-08-11 23:07:0812561 auth_handler->SetGenerateExpectation(
12562 test_config.proxy_auth_timing == AUTH_ASYNC,
asanka463ca4262016-11-16 02:34:3112563 n == 0 ? test_config.first_generate_proxy_token_rv : OK);
[email protected]2d01c262011-08-11 23:07:0812564 auth_factory->AddMockHandler(auth_handler, HttpAuth::AUTH_PROXY);
12565 }
[email protected]044de0642010-06-17 10:42:1512566 }
12567 if (test_config.server_auth_timing != AUTH_NONE) {
[email protected]3fd9dae2010-06-21 11:39:0012568 HttpAuthHandlerMock* auth_handler(new HttpAuthHandlerMock());
[email protected]044de0642010-06-17 10:42:1512569 std::string auth_challenge = "Mock realm=server";
12570 GURL origin(test_config.server_url);
[email protected]df41d0d82014-03-13 00:43:2412571 HttpAuthChallengeTokenizer tokenizer(auth_challenge.begin(),
12572 auth_challenge.end());
[email protected]044de0642010-06-17 10:42:1512573 auth_handler->InitFromChallenge(&tokenizer, HttpAuth::AUTH_SERVER,
tfarina42834112016-09-22 13:38:2012574 empty_ssl_info, origin,
12575 NetLogWithSource());
[email protected]044de0642010-06-17 10:42:1512576 auth_handler->SetGenerateExpectation(
12577 test_config.server_auth_timing == AUTH_ASYNC,
asanka463ca4262016-11-16 02:34:3112578 test_config.first_generate_server_token_rv);
[email protected]2d01c262011-08-11 23:07:0812579 auth_factory->AddMockHandler(auth_handler, HttpAuth::AUTH_SERVER);
asankae2257db2016-10-11 22:03:1612580
12581 // The second handler always succeeds. It should only be used where there
12582 // are multiple auth sessions for server auth in the same network
12583 // transaction using the same auth scheme.
12584 std::unique_ptr<HttpAuthHandlerMock> second_handler =
Jeremy Roman0579ed62017-08-29 15:56:1912585 std::make_unique<HttpAuthHandlerMock>();
asankae2257db2016-10-11 22:03:1612586 second_handler->InitFromChallenge(&tokenizer, HttpAuth::AUTH_SERVER,
12587 empty_ssl_info, origin,
12588 NetLogWithSource());
12589 second_handler->SetGenerateExpectation(true, OK);
12590 auth_factory->AddMockHandler(second_handler.release(),
12591 HttpAuth::AUTH_SERVER);
[email protected]044de0642010-06-17 10:42:1512592 }
12593 if (test_config.proxy_url) {
rdsmith82957ad2015-09-16 19:42:0312594 session_deps_.proxy_service =
12595 ProxyService::CreateFixed(test_config.proxy_url);
[email protected]044de0642010-06-17 10:42:1512596 } else {
rdsmith82957ad2015-09-16 19:42:0312597 session_deps_.proxy_service = ProxyService::CreateDirect();
[email protected]044de0642010-06-17 10:42:1512598 }
12599
12600 HttpRequestInfo request;
12601 request.method = "GET";
12602 request.url = GURL(test_config.server_url);
[email protected]044de0642010-06-17 10:42:1512603
danakj1fd259a02016-04-16 03:17:0912604 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]044de0642010-06-17 10:42:1512605
rchcb68dc62015-05-21 04:45:3612606 SSLSocketDataProvider ssl_socket_data_provider(SYNCHRONOUS, OK);
12607
12608 std::vector<std::vector<MockRead>> mock_reads(1);
12609 std::vector<std::vector<MockWrite>> mock_writes(1);
[email protected]044de0642010-06-17 10:42:1512610 for (int round = 0; round < test_config.num_auth_rounds; ++round) {
davidben8c7089a2017-04-17 20:38:2212611 SCOPED_TRACE(round);
[email protected]044de0642010-06-17 10:42:1512612 const TestRound& read_write_round = test_config.rounds[round];
12613
12614 // Set up expected reads and writes.
rchcb68dc62015-05-21 04:45:3612615 mock_reads.back().push_back(read_write_round.read);
12616 mock_writes.back().push_back(read_write_round.write);
12617
12618 // kProxyChallenge uses Proxy-Connection: close which means that the
12619 // socket is closed and a new one will be created for the next request.
mmenkee71e15332015-10-07 16:39:5412620 if (read_write_round.read.data == kProxyChallenge.data) {
rchcb68dc62015-05-21 04:45:3612621 mock_reads.push_back(std::vector<MockRead>());
12622 mock_writes.push_back(std::vector<MockWrite>());
[email protected]044de0642010-06-17 10:42:1512623 }
12624
rchcb68dc62015-05-21 04:45:3612625 if (read_write_round.extra_read) {
12626 mock_reads.back().push_back(*read_write_round.extra_read);
[email protected]044de0642010-06-17 10:42:1512627 }
rchcb68dc62015-05-21 04:45:3612628 if (read_write_round.extra_write) {
12629 mock_writes.back().push_back(*read_write_round.extra_write);
12630 }
[email protected]044de0642010-06-17 10:42:1512631
12632 // Add an SSL sequence if necessary.
[email protected]044de0642010-06-17 10:42:1512633 if (round >= test_config.first_ssl_round)
[email protected]bb88e1d32013-05-03 23:11:0712634 session_deps_.socket_factory->AddSSLSocketDataProvider(
[email protected]044de0642010-06-17 10:42:1512635 &ssl_socket_data_provider);
rchcb68dc62015-05-21 04:45:3612636 }
[email protected]044de0642010-06-17 10:42:1512637
danakj1fd259a02016-04-16 03:17:0912638 std::vector<std::unique_ptr<StaticSocketDataProvider>> data_providers;
rchcb68dc62015-05-21 04:45:3612639 for (size_t i = 0; i < mock_reads.size(); ++i) {
Jeremy Roman0579ed62017-08-29 15:56:1912640 data_providers.push_back(std::make_unique<StaticSocketDataProvider>(
davidben5f8b6bc2015-11-25 03:19:5412641 mock_reads[i].data(), mock_reads[i].size(), mock_writes[i].data(),
bnc87dcefc2017-05-25 12:47:5812642 mock_writes[i].size()));
rchcb68dc62015-05-21 04:45:3612643 session_deps_.socket_factory->AddSocketDataProvider(
olli.raula525048c2015-12-10 07:38:3212644 data_providers.back().get());
rchcb68dc62015-05-21 04:45:3612645 }
12646
mmenkecc2298e2015-12-07 18:20:1812647 // Transaction must be created after DataProviders, so it's destroyed before
12648 // they are as well.
12649 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
12650
rchcb68dc62015-05-21 04:45:3612651 for (int round = 0; round < test_config.num_auth_rounds; ++round) {
davidben8c7089a2017-04-17 20:38:2212652 SCOPED_TRACE(round);
rchcb68dc62015-05-21 04:45:3612653 const TestRound& read_write_round = test_config.rounds[round];
[email protected]044de0642010-06-17 10:42:1512654 // Start or restart the transaction.
[email protected]49639fa2011-12-20 23:22:4112655 TestCompletionCallback callback;
[email protected]044de0642010-06-17 10:42:1512656 int rv;
12657 if (round == 0) {
tfarina42834112016-09-22 13:38:2012658 rv = trans.Start(&request, callback.callback(), NetLogWithSource());
[email protected]044de0642010-06-17 10:42:1512659 } else {
[email protected]49639fa2011-12-20 23:22:4112660 rv = trans.RestartWithAuth(
12661 AuthCredentials(kFoo, kBar), callback.callback());
[email protected]044de0642010-06-17 10:42:1512662 }
12663 if (rv == ERR_IO_PENDING)
12664 rv = callback.WaitForResult();
12665
12666 // Compare results with expected data.
asankae2257db2016-10-11 22:03:1612667 EXPECT_THAT(rv, IsError(read_write_round.expected_rv));
[email protected]0b0bf032010-09-21 18:08:5012668 const HttpResponseInfo* response = trans.GetResponseInfo();
ttuttlec0c828492015-05-15 01:25:5512669 if (read_write_round.expected_rv != OK) {
[email protected]044de0642010-06-17 10:42:1512670 EXPECT_EQ(round + 1, test_config.num_auth_rounds);
12671 continue;
12672 }
12673 if (round + 1 < test_config.num_auth_rounds) {
wezca1070932016-05-26 20:30:5212674 EXPECT_TRUE(response->auth_challenge);
[email protected]044de0642010-06-17 10:42:1512675 } else {
wezca1070932016-05-26 20:30:5212676 EXPECT_FALSE(response->auth_challenge);
asankae2257db2016-10-11 22:03:1612677 EXPECT_FALSE(trans.IsReadyToRestartForAuth());
[email protected]044de0642010-06-17 10:42:1512678 }
12679 }
[email protected]e5ae96a2010-04-14 20:12:4512680 }
12681}
12682
bncd16676a2016-07-20 16:23:0112683TEST_F(HttpNetworkTransactionTest, MultiRoundAuth) {
[email protected]c871bce92010-07-15 21:51:1412684 // Do multi-round authentication and make sure it works correctly.
[email protected]c871bce92010-07-15 21:51:1412685 HttpAuthHandlerMock::Factory* auth_factory(
12686 new HttpAuthHandlerMock::Factory());
[email protected]bb88e1d32013-05-03 23:11:0712687 session_deps_.http_auth_handler_factory.reset(auth_factory);
rdsmith82957ad2015-09-16 19:42:0312688 session_deps_.proxy_service = ProxyService::CreateDirect();
[email protected]bb88e1d32013-05-03 23:11:0712689 session_deps_.host_resolver->rules()->AddRule("www.example.com", "10.0.0.1");
12690 session_deps_.host_resolver->set_synchronous_mode(true);
[email protected]c871bce92010-07-15 21:51:1412691
12692 HttpAuthHandlerMock* auth_handler(new HttpAuthHandlerMock());
12693 auth_handler->set_connection_based(true);
12694 std::string auth_challenge = "Mock realm=server";
12695 GURL origin("http://www.example.com");
[email protected]df41d0d82014-03-13 00:43:2412696 HttpAuthChallengeTokenizer tokenizer(auth_challenge.begin(),
12697 auth_challenge.end());
asanka5ffd5d72016-03-23 16:20:4912698 SSLInfo empty_ssl_info;
[email protected]c871bce92010-07-15 21:51:1412699 auth_handler->InitFromChallenge(&tokenizer, HttpAuth::AUTH_SERVER,
tfarina42834112016-09-22 13:38:2012700 empty_ssl_info, origin, NetLogWithSource());
[email protected]2d01c262011-08-11 23:07:0812701 auth_factory->AddMockHandler(auth_handler, HttpAuth::AUTH_SERVER);
[email protected]c871bce92010-07-15 21:51:1412702
[email protected]c871bce92010-07-15 21:51:1412703 int rv = OK;
12704 const HttpResponseInfo* response = NULL;
12705 HttpRequestInfo request;
12706 request.method = "GET";
12707 request.url = origin;
[email protected]cb9bf6ca2011-01-28 13:15:2712708
danakj1fd259a02016-04-16 03:17:0912709 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]7ef4cbbb2011-02-06 11:19:1012710
12711 // Use a TCP Socket Pool with only one connection per group. This is used
12712 // to validate that the TCP socket is not released to the pool between
12713 // each round of multi-round authentication.
mmenkee65e7af2015-10-13 17:16:4212714 HttpNetworkSessionPeer session_peer(session.get());
[email protected]ab739042011-04-07 15:22:2812715 TransportClientSocketPool* transport_pool = new TransportClientSocketPool(
[email protected]7ef4cbbb2011-02-06 11:19:1012716 50, // Max sockets for pool
12717 1, // Max sockets per group
tbansal7b403bcc2016-04-13 22:33:2112718 session_deps_.host_resolver.get(), session_deps_.socket_factory.get(),
12719 NULL, session_deps_.net_log);
Jeremy Roman0579ed62017-08-29 15:56:1912720 auto mock_pool_manager = std::make_unique<MockClientSocketPoolManager>();
[email protected]a42dbd142011-11-17 16:42:0212721 mock_pool_manager->SetTransportSocketPool(transport_pool);
dchengc7eeda422015-12-26 03:56:4812722 session_peer.SetClientSocketPoolManager(std::move(mock_pool_manager));
[email protected]7ef4cbbb2011-02-06 11:19:1012723
bnc691fda62016-08-12 00:43:1612724 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]49639fa2011-12-20 23:22:4112725 TestCompletionCallback callback;
[email protected]c871bce92010-07-15 21:51:1412726
12727 const MockWrite kGet(
12728 "GET / HTTP/1.1\r\n"
12729 "Host: www.example.com\r\n"
12730 "Connection: keep-alive\r\n\r\n");
12731 const MockWrite kGetAuth(
12732 "GET / HTTP/1.1\r\n"
12733 "Host: www.example.com\r\n"
12734 "Connection: keep-alive\r\n"
12735 "Authorization: auth_token\r\n\r\n");
12736
12737 const MockRead kServerChallenge(
12738 "HTTP/1.1 401 Unauthorized\r\n"
12739 "WWW-Authenticate: Mock realm=server\r\n"
12740 "Content-Type: text/html; charset=iso-8859-1\r\n"
12741 "Content-Length: 14\r\n\r\n"
12742 "Unauthorized\r\n");
12743 const MockRead kSuccess(
12744 "HTTP/1.1 200 OK\r\n"
12745 "Content-Type: text/html; charset=iso-8859-1\r\n"
12746 "Content-Length: 3\r\n\r\n"
12747 "Yes");
12748
12749 MockWrite writes[] = {
12750 // First round
12751 kGet,
12752 // Second round
12753 kGetAuth,
12754 // Third round
12755 kGetAuth,
[email protected]eca50e122010-09-11 14:03:3012756 // Fourth round
[email protected]7ef4cbbb2011-02-06 11:19:1012757 kGetAuth,
12758 // Competing request
12759 kGet,
[email protected]c871bce92010-07-15 21:51:1412760 };
12761 MockRead reads[] = {
12762 // First round
12763 kServerChallenge,
12764 // Second round
12765 kServerChallenge,
12766 // Third round
[email protected]eca50e122010-09-11 14:03:3012767 kServerChallenge,
12768 // Fourth round
[email protected]c871bce92010-07-15 21:51:1412769 kSuccess,
[email protected]7ef4cbbb2011-02-06 11:19:1012770 // Competing response
12771 kSuccess,
[email protected]c871bce92010-07-15 21:51:1412772 };
12773 StaticSocketDataProvider data_provider(reads, arraysize(reads),
12774 writes, arraysize(writes));
[email protected]bb88e1d32013-05-03 23:11:0712775 session_deps_.socket_factory->AddSocketDataProvider(&data_provider);
[email protected]c871bce92010-07-15 21:51:1412776
thestig9d3bb0c2015-01-24 00:49:5112777 const char kSocketGroup[] = "www.example.com:80";
[email protected]7ef4cbbb2011-02-06 11:19:1012778
12779 // First round of authentication.
[email protected]c871bce92010-07-15 21:51:1412780 auth_handler->SetGenerateExpectation(false, OK);
tfarina42834112016-09-22 13:38:2012781 rv = trans.Start(&request, callback.callback(), NetLogWithSource());
[email protected]c871bce92010-07-15 21:51:1412782 if (rv == ERR_IO_PENDING)
12783 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0112784 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:1612785 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5212786 ASSERT_TRUE(response);
12787 EXPECT_TRUE(response->auth_challenge);
[email protected]ab739042011-04-07 15:22:2812788 EXPECT_EQ(0, transport_pool->IdleSocketCountInGroup(kSocketGroup));
asanka463ca4262016-11-16 02:34:3112789 EXPECT_EQ(HttpAuthHandlerMock::State::WAIT_FOR_GENERATE_AUTH_TOKEN,
12790 auth_handler->state());
[email protected]c871bce92010-07-15 21:51:1412791
[email protected]7ef4cbbb2011-02-06 11:19:1012792 // In between rounds, another request comes in for the same domain.
12793 // It should not be able to grab the TCP socket that trans has already
12794 // claimed.
bnc691fda62016-08-12 00:43:1612795 HttpNetworkTransaction trans_compete(DEFAULT_PRIORITY, session.get());
[email protected]49639fa2011-12-20 23:22:4112796 TestCompletionCallback callback_compete;
tfarina42834112016-09-22 13:38:2012797 rv = trans_compete.Start(&request, callback_compete.callback(),
12798 NetLogWithSource());
robpercival214763f2016-07-01 23:27:0112799 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]7ef4cbbb2011-02-06 11:19:1012800 // callback_compete.WaitForResult at this point would stall forever,
12801 // since the HttpNetworkTransaction does not release the request back to
12802 // the pool until after authentication completes.
12803
12804 // Second round of authentication.
[email protected]c871bce92010-07-15 21:51:1412805 auth_handler->SetGenerateExpectation(false, OK);
bnc691fda62016-08-12 00:43:1612806 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar), callback.callback());
[email protected]c871bce92010-07-15 21:51:1412807 if (rv == ERR_IO_PENDING)
12808 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0112809 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:1612810 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5212811 ASSERT_TRUE(response);
12812 EXPECT_FALSE(response->auth_challenge);
[email protected]ab739042011-04-07 15:22:2812813 EXPECT_EQ(0, transport_pool->IdleSocketCountInGroup(kSocketGroup));
asanka463ca4262016-11-16 02:34:3112814 EXPECT_EQ(HttpAuthHandlerMock::State::WAIT_FOR_GENERATE_AUTH_TOKEN,
12815 auth_handler->state());
[email protected]c871bce92010-07-15 21:51:1412816
[email protected]7ef4cbbb2011-02-06 11:19:1012817 // Third round of authentication.
[email protected]c871bce92010-07-15 21:51:1412818 auth_handler->SetGenerateExpectation(false, OK);
bnc691fda62016-08-12 00:43:1612819 rv = trans.RestartWithAuth(AuthCredentials(), callback.callback());
[email protected]c871bce92010-07-15 21:51:1412820 if (rv == ERR_IO_PENDING)
12821 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0112822 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:1612823 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5212824 ASSERT_TRUE(response);
12825 EXPECT_FALSE(response->auth_challenge);
[email protected]ab739042011-04-07 15:22:2812826 EXPECT_EQ(0, transport_pool->IdleSocketCountInGroup(kSocketGroup));
asanka463ca4262016-11-16 02:34:3112827 EXPECT_EQ(HttpAuthHandlerMock::State::WAIT_FOR_GENERATE_AUTH_TOKEN,
12828 auth_handler->state());
[email protected]eca50e122010-09-11 14:03:3012829
[email protected]7ef4cbbb2011-02-06 11:19:1012830 // Fourth round of authentication, which completes successfully.
[email protected]eca50e122010-09-11 14:03:3012831 auth_handler->SetGenerateExpectation(false, OK);
bnc691fda62016-08-12 00:43:1612832 rv = trans.RestartWithAuth(AuthCredentials(), callback.callback());
[email protected]eca50e122010-09-11 14:03:3012833 if (rv == ERR_IO_PENDING)
12834 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0112835 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:1612836 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5212837 ASSERT_TRUE(response);
12838 EXPECT_FALSE(response->auth_challenge);
[email protected]ab739042011-04-07 15:22:2812839 EXPECT_EQ(0, transport_pool->IdleSocketCountInGroup(kSocketGroup));
[email protected]7ef4cbbb2011-02-06 11:19:1012840
asanka463ca4262016-11-16 02:34:3112841 // In WAIT_FOR_CHALLENGE, although in reality the auth handler is done. A real
12842 // auth handler should transition to a DONE state in concert with the remote
12843 // server. But that's not something we can test here with a mock handler.
12844 EXPECT_EQ(HttpAuthHandlerMock::State::WAIT_FOR_CHALLENGE,
12845 auth_handler->state());
12846
[email protected]7ef4cbbb2011-02-06 11:19:1012847 // Read the body since the fourth round was successful. This will also
12848 // release the socket back to the pool.
12849 scoped_refptr<IOBufferWithSize> io_buf(new IOBufferWithSize(50));
bnc691fda62016-08-12 00:43:1612850 rv = trans.Read(io_buf.get(), io_buf->size(), callback.callback());
[email protected]7ef4cbbb2011-02-06 11:19:1012851 if (rv == ERR_IO_PENDING)
12852 rv = callback.WaitForResult();
12853 EXPECT_EQ(3, rv);
bnc691fda62016-08-12 00:43:1612854 rv = trans.Read(io_buf.get(), io_buf->size(), callback.callback());
[email protected]7ef4cbbb2011-02-06 11:19:1012855 EXPECT_EQ(0, rv);
12856 // There are still 0 idle sockets, since the trans_compete transaction
12857 // will be handed it immediately after trans releases it to the group.
[email protected]ab739042011-04-07 15:22:2812858 EXPECT_EQ(0, transport_pool->IdleSocketCountInGroup(kSocketGroup));
[email protected]7ef4cbbb2011-02-06 11:19:1012859
12860 // The competing request can now finish. Wait for the headers and then
12861 // read the body.
12862 rv = callback_compete.WaitForResult();
robpercival214763f2016-07-01 23:27:0112863 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:1612864 rv = trans_compete.Read(io_buf.get(), io_buf->size(), callback.callback());
[email protected]7ef4cbbb2011-02-06 11:19:1012865 if (rv == ERR_IO_PENDING)
12866 rv = callback.WaitForResult();
12867 EXPECT_EQ(3, rv);
bnc691fda62016-08-12 00:43:1612868 rv = trans_compete.Read(io_buf.get(), io_buf->size(), callback.callback());
[email protected]7ef4cbbb2011-02-06 11:19:1012869 EXPECT_EQ(0, rv);
12870
12871 // Finally, the socket is released to the group.
[email protected]ab739042011-04-07 15:22:2812872 EXPECT_EQ(1, transport_pool->IdleSocketCountInGroup(kSocketGroup));
[email protected]c871bce92010-07-15 21:51:1412873}
12874
[email protected]65041fa2010-05-21 06:56:5312875// This tests the case that a request is issued via http instead of spdy after
12876// npn is negotiated.
bncd16676a2016-07-20 16:23:0112877TEST_F(HttpNetworkTransactionTest, NpnWithHttpOverSSL) {
[email protected]65041fa2010-05-21 06:56:5312878 HttpRequestInfo request;
12879 request.method = "GET";
bncce36dca22015-04-21 22:11:2312880 request.url = GURL("https://www.example.org/");
[email protected]65041fa2010-05-21 06:56:5312881
12882 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:2312883 MockWrite(
12884 "GET / HTTP/1.1\r\n"
12885 "Host: www.example.org\r\n"
12886 "Connection: keep-alive\r\n\r\n"),
[email protected]65041fa2010-05-21 06:56:5312887 };
12888
12889 MockRead data_reads[] = {
bncc958faa2015-07-31 18:14:5212890 MockRead("HTTP/1.1 200 OK\r\n"),
bnc2df4b522016-07-08 18:17:4312891 MockRead(kAlternativeServiceHttpHeader),
bncc958faa2015-07-31 18:14:5212892 MockRead("\r\n"),
12893 MockRead("hello world"),
12894 MockRead(SYNCHRONOUS, OK),
[email protected]65041fa2010-05-21 06:56:5312895 };
12896
[email protected]8ddf8322012-02-23 18:08:0612897 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3612898 ssl.next_proto = kProtoHTTP11;
[email protected]65041fa2010-05-21 06:56:5312899
[email protected]bb88e1d32013-05-03 23:11:0712900 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]65041fa2010-05-21 06:56:5312901
12902 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
12903 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:0712904 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]65041fa2010-05-21 06:56:5312905
[email protected]49639fa2011-12-20 23:22:4112906 TestCompletionCallback callback;
[email protected]65041fa2010-05-21 06:56:5312907
danakj1fd259a02016-04-16 03:17:0912908 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1612909 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]65041fa2010-05-21 06:56:5312910
tfarina42834112016-09-22 13:38:2012911 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
[email protected]65041fa2010-05-21 06:56:5312912
robpercival214763f2016-07-01 23:27:0112913 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
12914 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]65041fa2010-05-21 06:56:5312915
bnc691fda62016-08-12 00:43:1612916 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5212917 ASSERT_TRUE(response);
12918 ASSERT_TRUE(response->headers);
[email protected]65041fa2010-05-21 06:56:5312919 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
12920
12921 std::string response_data;
bnc691fda62016-08-12 00:43:1612922 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
[email protected]65041fa2010-05-21 06:56:5312923 EXPECT_EQ("hello world", response_data);
12924
12925 EXPECT_FALSE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5212926 EXPECT_TRUE(response->was_alpn_negotiated);
[email protected]65041fa2010-05-21 06:56:5312927}
[email protected]26ef6582010-06-24 02:30:4712928
bnc55ff9da2015-08-19 18:42:3512929// Simulate the SSL handshake completing with an NPN negotiation followed by an
12930// immediate server closing of the socket.
12931// Regression test for https://crbug.com/46369.
bncd16676a2016-07-20 16:23:0112932TEST_F(HttpNetworkTransactionTest, SpdyPostNPNServerHangup) {
[email protected]26ef6582010-06-24 02:30:4712933 HttpRequestInfo request;
12934 request.method = "GET";
bncce36dca22015-04-21 22:11:2312935 request.url = GURL("https://www.example.org/");
[email protected]26ef6582010-06-24 02:30:4712936
[email protected]8ddf8322012-02-23 18:08:0612937 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3612938 ssl.next_proto = kProtoHTTP2;
[email protected]bb88e1d32013-05-03 23:11:0712939 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]26ef6582010-06-24 02:30:4712940
bncdf80d44fd2016-07-15 20:27:4112941 SpdySerializedFrame req(
bnc38dcd392016-02-09 23:19:4912942 spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST, true));
bncdf80d44fd2016-07-15 20:27:4112943 MockWrite spdy_writes[] = {CreateMockWrite(req, 1)};
[email protected]26ef6582010-06-24 02:30:4712944
12945 MockRead spdy_reads[] = {
[email protected]8ddf8322012-02-23 18:08:0612946 MockRead(SYNCHRONOUS, 0, 0) // Not async - return 0 immediately.
[email protected]26ef6582010-06-24 02:30:4712947 };
12948
rch8e6c6c42015-05-01 14:05:1312949 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
12950 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:0712951 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]26ef6582010-06-24 02:30:4712952
[email protected]49639fa2011-12-20 23:22:4112953 TestCompletionCallback callback;
[email protected]26ef6582010-06-24 02:30:4712954
danakj1fd259a02016-04-16 03:17:0912955 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1612956 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]26ef6582010-06-24 02:30:4712957
tfarina42834112016-09-22 13:38:2012958 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0112959 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
12960 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_CONNECTION_CLOSED));
[email protected]26ef6582010-06-24 02:30:4712961}
[email protected]65d34382010-07-01 18:12:2612962
[email protected]795cbf82013-07-22 09:37:2712963// A subclass of HttpAuthHandlerMock that records the request URL when
12964// it gets it. This is needed since the auth handler may get destroyed
12965// before we get a chance to query it.
12966class UrlRecordingHttpAuthHandlerMock : public HttpAuthHandlerMock {
12967 public:
12968 explicit UrlRecordingHttpAuthHandlerMock(GURL* url) : url_(url) {}
12969
dchengb03027d2014-10-21 12:00:2012970 ~UrlRecordingHttpAuthHandlerMock() override {}
[email protected]795cbf82013-07-22 09:37:2712971
12972 protected:
dchengb03027d2014-10-21 12:00:2012973 int GenerateAuthTokenImpl(const AuthCredentials* credentials,
12974 const HttpRequestInfo* request,
12975 const CompletionCallback& callback,
12976 std::string* auth_token) override {
[email protected]795cbf82013-07-22 09:37:2712977 *url_ = request->url;
12978 return HttpAuthHandlerMock::GenerateAuthTokenImpl(
12979 credentials, request, callback, auth_token);
12980 }
12981
12982 private:
12983 GURL* url_;
12984};
12985
[email protected]8e6441ca2010-08-19 05:56:3812986// Test that if we cancel the transaction as the connection is completing, that
12987// everything tears down correctly.
bncd16676a2016-07-20 16:23:0112988TEST_F(HttpNetworkTransactionTest, SimpleCancel) {
[email protected]8e6441ca2010-08-19 05:56:3812989 // Setup everything about the connection to complete synchronously, so that
12990 // after calling HttpNetworkTransaction::Start, the only thing we're waiting
12991 // for is the callback from the HttpStreamRequest.
12992 // Then cancel the transaction.
12993 // Verify that we don't crash.
[email protected]d973e99a2012-02-17 21:02:3612994 MockConnect mock_connect(SYNCHRONOUS, OK);
[email protected]8e6441ca2010-08-19 05:56:3812995 MockRead data_reads[] = {
[email protected]8ddf8322012-02-23 18:08:0612996 MockRead(SYNCHRONOUS, "HTTP/1.0 200 OK\r\n\r\n"),
12997 MockRead(SYNCHRONOUS, "hello world"),
12998 MockRead(SYNCHRONOUS, OK),
[email protected]8e6441ca2010-08-19 05:56:3812999 };
13000
[email protected]8e6441ca2010-08-19 05:56:3813001 HttpRequestInfo request;
13002 request.method = "GET";
bncce36dca22015-04-21 22:11:2313003 request.url = GURL("http://www.example.org/");
[email protected]8e6441ca2010-08-19 05:56:3813004
[email protected]bb88e1d32013-05-03 23:11:0713005 session_deps_.host_resolver->set_synchronous_mode(true);
danakj1fd259a02016-04-16 03:17:0913006 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc87dcefc2017-05-25 12:47:5813007 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:1913008 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:2713009
[email protected]8e6441ca2010-08-19 05:56:3813010 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
13011 data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:0713012 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]8e6441ca2010-08-19 05:56:3813013
[email protected]49639fa2011-12-20 23:22:4113014 TestCompletionCallback callback;
[email protected]8e6441ca2010-08-19 05:56:3813015
vishal.b62985ca92015-04-17 08:45:5113016 BoundTestNetLog log;
[email protected]49639fa2011-12-20 23:22:4113017 int rv = trans->Start(&request, callback.callback(), log.bound());
robpercival214763f2016-07-01 23:27:0113018 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]8e6441ca2010-08-19 05:56:3813019 trans.reset(); // Cancel the transaction here.
13020
fdoray92e35a72016-06-10 15:54:5513021 base::RunLoop().RunUntilIdle();
[email protected]f45c1ee2010-08-03 00:54:3013022}
13023
[email protected]ecab6e052014-05-16 14:58:1213024// Test that if a transaction is cancelled after receiving the headers, the
13025// stream is drained properly and added back to the socket pool. The main
13026// purpose of this test is to make sure that an HttpStreamParser can be read
13027// from after the HttpNetworkTransaction and the objects it owns have been
13028// deleted.
13029// See http://crbug.com/368418
bncd16676a2016-07-20 16:23:0113030TEST_F(HttpNetworkTransactionTest, CancelAfterHeaders) {
[email protected]ecab6e052014-05-16 14:58:1213031 MockRead data_reads[] = {
13032 MockRead(ASYNC, "HTTP/1.1 200 OK\r\n"),
13033 MockRead(ASYNC, "Content-Length: 2\r\n"),
13034 MockRead(ASYNC, "Connection: Keep-Alive\r\n\r\n"),
13035 MockRead(ASYNC, "1"),
13036 // 2 async reads are necessary to trigger a ReadResponseBody call after the
13037 // HttpNetworkTransaction has been deleted.
13038 MockRead(ASYNC, "2"),
13039 MockRead(SYNCHRONOUS, ERR_IO_PENDING), // Should never read this.
13040 };
13041 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
13042 session_deps_.socket_factory->AddSocketDataProvider(&data);
13043
danakj1fd259a02016-04-16 03:17:0913044 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]ecab6e052014-05-16 14:58:1213045
13046 {
13047 HttpRequestInfo request;
13048 request.method = "GET";
bncce36dca22015-04-21 22:11:2313049 request.url = GURL("http://www.example.org/");
[email protected]ecab6e052014-05-16 14:58:1213050
dcheng48459ac22014-08-26 00:46:4113051 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]ecab6e052014-05-16 14:58:1213052 TestCompletionCallback callback;
13053
tfarina42834112016-09-22 13:38:2013054 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0113055 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]ecab6e052014-05-16 14:58:1213056 callback.WaitForResult();
13057
13058 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5213059 ASSERT_TRUE(response);
13060 EXPECT_TRUE(response->headers);
[email protected]ecab6e052014-05-16 14:58:1213061 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
13062
13063 // The transaction and HttpRequestInfo are deleted.
13064 }
13065
13066 // Let the HttpResponseBodyDrainer drain the socket.
fdoray92e35a72016-06-10 15:54:5513067 base::RunLoop().RunUntilIdle();
[email protected]ecab6e052014-05-16 14:58:1213068
13069 // Socket should now be idle, waiting to be reused.
dcheng48459ac22014-08-26 00:46:4113070 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]ecab6e052014-05-16 14:58:1213071}
13072
[email protected]76a505b2010-08-25 06:23:0013073// Test a basic GET request through a proxy.
bncd16676a2016-07-20 16:23:0113074TEST_F(HttpNetworkTransactionTest, ProxyGet) {
rdsmith82957ad2015-09-16 19:42:0313075 session_deps_.proxy_service =
13076 ProxyService::CreateFixedFromPacResult("PROXY myproxy:70");
vishal.b62985ca92015-04-17 08:45:5113077 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:0713078 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:0913079 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]76a505b2010-08-25 06:23:0013080
[email protected]76a505b2010-08-25 06:23:0013081 HttpRequestInfo request;
13082 request.method = "GET";
bncce36dca22015-04-21 22:11:2313083 request.url = GURL("http://www.example.org/");
[email protected]76a505b2010-08-25 06:23:0013084
13085 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:2313086 MockWrite(
13087 "GET http://www.example.org/ HTTP/1.1\r\n"
13088 "Host: www.example.org\r\n"
13089 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]76a505b2010-08-25 06:23:0013090 };
13091
13092 MockRead data_reads1[] = {
13093 MockRead("HTTP/1.1 200 OK\r\n"),
13094 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
13095 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:0613096 MockRead(SYNCHRONOUS, OK),
[email protected]76a505b2010-08-25 06:23:0013097 };
13098
13099 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
13100 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:0713101 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]76a505b2010-08-25 06:23:0013102
[email protected]49639fa2011-12-20 23:22:4113103 TestCompletionCallback callback1;
[email protected]76a505b2010-08-25 06:23:0013104
bnc691fda62016-08-12 00:43:1613105 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
ryansturm49a8cb12016-06-15 16:51:0913106 BeforeHeadersSentHandler headers_handler;
bnc691fda62016-08-12 00:43:1613107 trans.SetBeforeHeadersSentCallback(
ryansturm49a8cb12016-06-15 16:51:0913108 base::Bind(&BeforeHeadersSentHandler::OnBeforeHeadersSent,
13109 base::Unretained(&headers_handler)));
[email protected]0b0bf032010-09-21 18:08:5013110
bnc691fda62016-08-12 00:43:1613111 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:0113112 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]76a505b2010-08-25 06:23:0013113
13114 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:0113115 EXPECT_THAT(rv, IsOk());
[email protected]76a505b2010-08-25 06:23:0013116
bnc691fda62016-08-12 00:43:1613117 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5213118 ASSERT_TRUE(response);
[email protected]76a505b2010-08-25 06:23:0013119
13120 EXPECT_TRUE(response->headers->IsKeepAlive());
13121 EXPECT_EQ(200, response->headers->response_code());
13122 EXPECT_EQ(100, response->headers->GetContentLength());
13123 EXPECT_TRUE(response->was_fetched_via_proxy);
tbansal2ecbbc72016-10-06 17:15:4713124 EXPECT_EQ(ProxyServer(ProxyServer::SCHEME_HTTP,
13125 HostPortPair::FromString("myproxy:70")),
13126 response->proxy_server);
ryansturm49a8cb12016-06-15 16:51:0913127 EXPECT_TRUE(headers_handler.observed_before_headers_sent());
13128 EXPECT_TRUE(headers_handler.observed_before_headers_sent_with_proxy());
13129 EXPECT_EQ("myproxy:70", headers_handler.observed_proxy_server_uri());
[email protected]76a505b2010-08-25 06:23:0013130 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
[email protected]029c83b62013-01-24 05:28:2013131
13132 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:1613133 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]029c83b62013-01-24 05:28:2013134 TestLoadTimingNotReusedWithPac(load_timing_info,
13135 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
[email protected]76a505b2010-08-25 06:23:0013136}
13137
13138// Test a basic HTTPS GET request through a proxy.
bncd16676a2016-07-20 16:23:0113139TEST_F(HttpNetworkTransactionTest, ProxyTunnelGet) {
rdsmith82957ad2015-09-16 19:42:0313140 session_deps_.proxy_service =
13141 ProxyService::CreateFixedFromPacResult("PROXY myproxy:70");
vishal.b62985ca92015-04-17 08:45:5113142 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:0713143 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:0913144 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]76a505b2010-08-25 06:23:0013145
[email protected]76a505b2010-08-25 06:23:0013146 HttpRequestInfo request;
13147 request.method = "GET";
bncce36dca22015-04-21 22:11:2313148 request.url = GURL("https://www.example.org/");
[email protected]76a505b2010-08-25 06:23:0013149
13150 // Since we have proxy, should try to establish tunnel.
13151 MockWrite data_writes1[] = {
rsleevidb16bb02015-11-12 23:47:1713152 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
13153 "Host: www.example.org:443\r\n"
13154 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]76a505b2010-08-25 06:23:0013155
rsleevidb16bb02015-11-12 23:47:1713156 MockWrite("GET / HTTP/1.1\r\n"
13157 "Host: www.example.org\r\n"
13158 "Connection: keep-alive\r\n\r\n"),
[email protected]76a505b2010-08-25 06:23:0013159 };
13160
13161 MockRead data_reads1[] = {
13162 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
13163
13164 MockRead("HTTP/1.1 200 OK\r\n"),
13165 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
13166 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:0613167 MockRead(SYNCHRONOUS, OK),
[email protected]76a505b2010-08-25 06:23:0013168 };
13169
13170 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
13171 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:0713172 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8ddf8322012-02-23 18:08:0613173 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:0713174 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]76a505b2010-08-25 06:23:0013175
[email protected]49639fa2011-12-20 23:22:4113176 TestCompletionCallback callback1;
[email protected]76a505b2010-08-25 06:23:0013177
bnc691fda62016-08-12 00:43:1613178 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
ryansturm49a8cb12016-06-15 16:51:0913179 BeforeHeadersSentHandler headers_handler;
bnc691fda62016-08-12 00:43:1613180 trans.SetBeforeHeadersSentCallback(
ryansturm49a8cb12016-06-15 16:51:0913181 base::Bind(&BeforeHeadersSentHandler::OnBeforeHeadersSent,
13182 base::Unretained(&headers_handler)));
[email protected]0b0bf032010-09-21 18:08:5013183
bnc691fda62016-08-12 00:43:1613184 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:0113185 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]76a505b2010-08-25 06:23:0013186
13187 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:0113188 EXPECT_THAT(rv, IsOk());
mmenke43758e62015-05-04 21:09:4613189 TestNetLogEntry::List entries;
[email protected]b2fcd0e2010-12-01 15:19:4013190 log.GetEntries(&entries);
[email protected]76a505b2010-08-25 06:23:0013191 size_t pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:0013192 entries, 0, NetLogEventType::HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
13193 NetLogEventPhase::NONE);
[email protected]76a505b2010-08-25 06:23:0013194 ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:4013195 entries, pos,
mikecirone8b85c432016-09-08 19:11:0013196 NetLogEventType::HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
13197 NetLogEventPhase::NONE);
[email protected]76a505b2010-08-25 06:23:0013198
bnc691fda62016-08-12 00:43:1613199 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5213200 ASSERT_TRUE(response);
[email protected]76a505b2010-08-25 06:23:0013201
13202 EXPECT_TRUE(response->headers->IsKeepAlive());
13203 EXPECT_EQ(200, response->headers->response_code());
13204 EXPECT_EQ(100, response->headers->GetContentLength());
13205 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
13206 EXPECT_TRUE(response->was_fetched_via_proxy);
tbansal2ecbbc72016-10-06 17:15:4713207 EXPECT_EQ(ProxyServer(ProxyServer::SCHEME_HTTP,
13208 HostPortPair::FromString("myproxy:70")),
13209 response->proxy_server);
ryansturm49a8cb12016-06-15 16:51:0913210 EXPECT_TRUE(headers_handler.observed_before_headers_sent());
13211 EXPECT_TRUE(headers_handler.observed_before_headers_sent_with_proxy());
13212 EXPECT_EQ("myproxy:70", headers_handler.observed_proxy_server_uri());
[email protected]029c83b62013-01-24 05:28:2013213
13214 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:1613215 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]029c83b62013-01-24 05:28:2013216 TestLoadTimingNotReusedWithPac(load_timing_info,
13217 CONNECT_TIMING_HAS_SSL_TIMES);
[email protected]76a505b2010-08-25 06:23:0013218}
13219
rsleevidb16bb02015-11-12 23:47:1713220// Test a basic HTTPS GET request through a proxy, connecting to an IPv6
13221// literal host.
bncd16676a2016-07-20 16:23:0113222TEST_F(HttpNetworkTransactionTest, ProxyTunnelGetIPv6) {
rsleevidb16bb02015-11-12 23:47:1713223 session_deps_.proxy_service =
13224 ProxyService::CreateFixedFromPacResult("PROXY myproxy:70");
13225 BoundTestNetLog log;
13226 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:0913227 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
rsleevidb16bb02015-11-12 23:47:1713228
13229 HttpRequestInfo request;
13230 request.method = "GET";
13231 request.url = GURL("https://[::1]:443/");
13232
13233 // Since we have proxy, should try to establish tunnel.
13234 MockWrite data_writes1[] = {
13235 MockWrite("CONNECT [::1]:443 HTTP/1.1\r\n"
13236 "Host: [::1]:443\r\n"
13237 "Proxy-Connection: keep-alive\r\n\r\n"),
13238
13239 MockWrite("GET / HTTP/1.1\r\n"
13240 "Host: [::1]\r\n"
13241 "Connection: keep-alive\r\n\r\n"),
13242 };
13243
13244 MockRead data_reads1[] = {
13245 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
13246
13247 MockRead("HTTP/1.1 200 OK\r\n"),
13248 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
13249 MockRead("Content-Length: 100\r\n\r\n"),
13250 MockRead(SYNCHRONOUS, OK),
13251 };
13252
13253 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
13254 data_writes1, arraysize(data_writes1));
13255 session_deps_.socket_factory->AddSocketDataProvider(&data1);
13256 SSLSocketDataProvider ssl(ASYNC, OK);
13257 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
13258
13259 TestCompletionCallback callback1;
13260
bnc691fda62016-08-12 00:43:1613261 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
rsleevidb16bb02015-11-12 23:47:1713262
bnc691fda62016-08-12 00:43:1613263 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:0113264 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
rsleevidb16bb02015-11-12 23:47:1713265
13266 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:0113267 EXPECT_THAT(rv, IsOk());
rsleevidb16bb02015-11-12 23:47:1713268 TestNetLogEntry::List entries;
13269 log.GetEntries(&entries);
13270 size_t pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:0013271 entries, 0, NetLogEventType::HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
13272 NetLogEventPhase::NONE);
rsleevidb16bb02015-11-12 23:47:1713273 ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:0013274 entries, pos,
13275 NetLogEventType::HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
13276 NetLogEventPhase::NONE);
rsleevidb16bb02015-11-12 23:47:1713277
bnc691fda62016-08-12 00:43:1613278 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5213279 ASSERT_TRUE(response);
rsleevidb16bb02015-11-12 23:47:1713280
13281 EXPECT_TRUE(response->headers->IsKeepAlive());
13282 EXPECT_EQ(200, response->headers->response_code());
13283 EXPECT_EQ(100, response->headers->GetContentLength());
13284 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
13285 EXPECT_TRUE(response->was_fetched_via_proxy);
tbansal2ecbbc72016-10-06 17:15:4713286 EXPECT_EQ(ProxyServer(ProxyServer::SCHEME_HTTP,
13287 HostPortPair::FromString("myproxy:70")),
13288 response->proxy_server);
rsleevidb16bb02015-11-12 23:47:1713289
13290 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:1613291 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
rsleevidb16bb02015-11-12 23:47:1713292 TestLoadTimingNotReusedWithPac(load_timing_info,
13293 CONNECT_TIMING_HAS_SSL_TIMES);
13294}
13295
[email protected]76a505b2010-08-25 06:23:0013296// Test a basic HTTPS GET request through a proxy, but the server hangs up
13297// while establishing the tunnel.
bncd16676a2016-07-20 16:23:0113298TEST_F(HttpNetworkTransactionTest, ProxyTunnelGetHangup) {
rdsmith82957ad2015-09-16 19:42:0313299 session_deps_.proxy_service = ProxyService::CreateFixed("myproxy:70");
vishal.b62985ca92015-04-17 08:45:5113300 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:0713301 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:0913302 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]76a505b2010-08-25 06:23:0013303
[email protected]76a505b2010-08-25 06:23:0013304 HttpRequestInfo request;
13305 request.method = "GET";
bncce36dca22015-04-21 22:11:2313306 request.url = GURL("https://www.example.org/");
[email protected]76a505b2010-08-25 06:23:0013307
13308 // Since we have proxy, should try to establish tunnel.
13309 MockWrite data_writes1[] = {
rsleevidb16bb02015-11-12 23:47:1713310 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
13311 "Host: www.example.org:443\r\n"
13312 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]76a505b2010-08-25 06:23:0013313
rsleevidb16bb02015-11-12 23:47:1713314 MockWrite("GET / HTTP/1.1\r\n"
13315 "Host: www.example.org\r\n"
13316 "Connection: keep-alive\r\n\r\n"),
[email protected]76a505b2010-08-25 06:23:0013317 };
13318
13319 MockRead data_reads1[] = {
[email protected]8ddf8322012-02-23 18:08:0613320 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
[email protected]76a505b2010-08-25 06:23:0013321 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:0613322 MockRead(ASYNC, 0, 0), // EOF
[email protected]76a505b2010-08-25 06:23:0013323 };
13324
13325 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
13326 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:0713327 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8ddf8322012-02-23 18:08:0613328 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:0713329 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]76a505b2010-08-25 06:23:0013330
[email protected]49639fa2011-12-20 23:22:4113331 TestCompletionCallback callback1;
[email protected]76a505b2010-08-25 06:23:0013332
bnc691fda62016-08-12 00:43:1613333 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]0b0bf032010-09-21 18:08:5013334
bnc691fda62016-08-12 00:43:1613335 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:0113336 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]76a505b2010-08-25 06:23:0013337
13338 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:0113339 EXPECT_THAT(rv, IsError(ERR_EMPTY_RESPONSE));
mmenke43758e62015-05-04 21:09:4613340 TestNetLogEntry::List entries;
[email protected]b2fcd0e2010-12-01 15:19:4013341 log.GetEntries(&entries);
[email protected]76a505b2010-08-25 06:23:0013342 size_t pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:0013343 entries, 0, NetLogEventType::HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
13344 NetLogEventPhase::NONE);
[email protected]76a505b2010-08-25 06:23:0013345 ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:4013346 entries, pos,
mikecirone8b85c432016-09-08 19:11:0013347 NetLogEventType::HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
13348 NetLogEventPhase::NONE);
[email protected]76a505b2010-08-25 06:23:0013349}
13350
[email protected]749eefa82010-09-13 22:14:0313351// Test for crbug.com/55424.
bncd16676a2016-07-20 16:23:0113352TEST_F(HttpNetworkTransactionTest, PreconnectWithExistingSpdySession) {
bncdf80d44fd2016-07-15 20:27:4113353 SpdySerializedFrame req(
bnc38dcd392016-02-09 23:19:4913354 spdy_util_.ConstructSpdyGet("https://www.example.org", 1, LOWEST));
bncdf80d44fd2016-07-15 20:27:4113355 MockWrite spdy_writes[] = {CreateMockWrite(req, 0)};
[email protected]749eefa82010-09-13 22:14:0313356
bnc42331402016-07-25 13:36:1513357 SpdySerializedFrame resp(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
bncdf80d44fd2016-07-15 20:27:4113358 SpdySerializedFrame data(spdy_util_.ConstructSpdyDataFrame(1, true));
[email protected]749eefa82010-09-13 22:14:0313359 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:4113360 CreateMockRead(resp, 1), CreateMockRead(data, 2), MockRead(ASYNC, 0, 3),
[email protected]749eefa82010-09-13 22:14:0313361 };
13362
rch8e6c6c42015-05-01 14:05:1313363 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
13364 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:0713365 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]749eefa82010-09-13 22:14:0313366
[email protected]8ddf8322012-02-23 18:08:0613367 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3613368 ssl.next_proto = kProtoHTTP2;
[email protected]bb88e1d32013-05-03 23:11:0713369 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]749eefa82010-09-13 22:14:0313370
danakj1fd259a02016-04-16 03:17:0913371 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]749eefa82010-09-13 22:14:0313372
13373 // Set up an initial SpdySession in the pool to reuse.
bncce36dca22015-04-21 22:11:2313374 HostPortPair host_port_pair("www.example.org", 443);
[email protected]e6d017652013-05-17 18:01:4013375 SpdySessionKey key(host_port_pair, ProxyServer::Direct(),
[email protected]314b03992014-04-01 01:28:5313376 PRIVACY_MODE_DISABLED);
[email protected]795cbf82013-07-22 09:37:2713377 base::WeakPtr<SpdySession> spdy_session =
Bence Béky0ef1556e2017-06-30 19:52:5213378 CreateSpdySession(session.get(), key, NetLogWithSource());
[email protected]749eefa82010-09-13 22:14:0313379
13380 HttpRequestInfo request;
13381 request.method = "GET";
bncce36dca22015-04-21 22:11:2313382 request.url = GURL("https://www.example.org/");
[email protected]749eefa82010-09-13 22:14:0313383
13384 // This is the important line that marks this as a preconnect.
13385 request.motivation = HttpRequestInfo::PRECONNECT_MOTIVATED;
13386
bnc691fda62016-08-12 00:43:1613387 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]749eefa82010-09-13 22:14:0313388
[email protected]41d64e82013-07-03 22:44:2613389 TestCompletionCallback callback;
tfarina42834112016-09-22 13:38:2013390 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0113391 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
13392 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]749eefa82010-09-13 22:14:0313393}
13394
[email protected]73b8dd222010-11-11 19:55:2413395// Given a net error, cause that error to be returned from the first Write()
bnc691fda62016-08-12 00:43:1613396// call and verify that the HttpNetworkTransaction fails with that error.
[email protected]23e482282013-06-14 16:08:0213397void HttpNetworkTransactionTest::CheckErrorIsPassedBack(
[email protected]bb88e1d32013-05-03 23:11:0713398 int error, IoMode mode) {
ttuttle859dc7a2015-04-23 19:42:2913399 HttpRequestInfo request_info;
[email protected]cb9bf6ca2011-01-28 13:15:2713400 request_info.url = GURL("https://www.example.com/");
13401 request_info.method = "GET";
ttuttle859dc7a2015-04-23 19:42:2913402 request_info.load_flags = LOAD_NORMAL;
[email protected]cb9bf6ca2011-01-28 13:15:2713403
[email protected]8ddf8322012-02-23 18:08:0613404 SSLSocketDataProvider ssl_data(mode, OK);
ttuttle859dc7a2015-04-23 19:42:2913405 MockWrite data_writes[] = {
13406 MockWrite(mode, error),
[email protected]73b8dd222010-11-11 19:55:2413407 };
ttuttle859dc7a2015-04-23 19:42:2913408 StaticSocketDataProvider data(NULL, 0, data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:0713409 session_deps_.socket_factory->AddSocketDataProvider(&data);
13410 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data);
[email protected]73b8dd222010-11-11 19:55:2413411
danakj1fd259a02016-04-16 03:17:0913412 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1613413 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]73b8dd222010-11-11 19:55:2413414
[email protected]49639fa2011-12-20 23:22:4113415 TestCompletionCallback callback;
tfarina42834112016-09-22 13:38:2013416 int rv = trans.Start(&request_info, callback.callback(), NetLogWithSource());
ttuttle859dc7a2015-04-23 19:42:2913417 if (rv == ERR_IO_PENDING)
[email protected]73b8dd222010-11-11 19:55:2413418 rv = callback.WaitForResult();
13419 ASSERT_EQ(error, rv);
13420}
13421
bncd16676a2016-07-20 16:23:0113422TEST_F(HttpNetworkTransactionTest, SSLWriteCertError) {
[email protected]73b8dd222010-11-11 19:55:2413423 // Just check a grab bag of cert errors.
13424 static const int kErrors[] = {
13425 ERR_CERT_COMMON_NAME_INVALID,
13426 ERR_CERT_AUTHORITY_INVALID,
13427 ERR_CERT_DATE_INVALID,
13428 };
13429 for (size_t i = 0; i < arraysize(kErrors); i++) {
[email protected]8ddf8322012-02-23 18:08:0613430 CheckErrorIsPassedBack(kErrors[i], ASYNC);
13431 CheckErrorIsPassedBack(kErrors[i], SYNCHRONOUS);
[email protected]73b8dd222010-11-11 19:55:2413432 }
13433}
13434
[email protected]bd0b6772011-01-11 19:59:3013435// Ensure that a client certificate is removed from the SSL client auth
13436// cache when:
13437// 1) No proxy is involved.
13438// 2) TLS False Start is disabled.
13439// 3) The initial TLS handshake requests a client certificate.
13440// 4) The client supplies an invalid/unacceptable certificate.
bncd16676a2016-07-20 16:23:0113441TEST_F(HttpNetworkTransactionTest, ClientAuthCertCache_Direct_NoFalseStart) {
ttuttle859dc7a2015-04-23 19:42:2913442 HttpRequestInfo request_info;
[email protected]cb9bf6ca2011-01-28 13:15:2713443 request_info.url = GURL("https://www.example.com/");
13444 request_info.method = "GET";
ttuttle859dc7a2015-04-23 19:42:2913445 request_info.load_flags = LOAD_NORMAL;
[email protected]cb9bf6ca2011-01-28 13:15:2713446
[email protected]bd0b6772011-01-11 19:59:3013447 scoped_refptr<SSLCertRequestInfo> cert_request(new SSLCertRequestInfo());
[email protected]791879c2013-12-17 07:22:4113448 cert_request->host_and_port = HostPortPair("www.example.com", 443);
[email protected]bd0b6772011-01-11 19:59:3013449
13450 // [ssl_]data1 contains the data for the first SSL handshake. When a
13451 // CertificateRequest is received for the first time, the handshake will
13452 // be aborted to allow the caller to provide a certificate.
ttuttle859dc7a2015-04-23 19:42:2913453 SSLSocketDataProvider ssl_data1(ASYNC, ERR_SSL_CLIENT_AUTH_CERT_NEEDED);
[email protected]bd0b6772011-01-11 19:59:3013454 ssl_data1.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0713455 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data1);
ttuttle859dc7a2015-04-23 19:42:2913456 StaticSocketDataProvider data1(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0713457 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]bd0b6772011-01-11 19:59:3013458
13459 // [ssl_]data2 contains the data for the second SSL handshake. When TLS
13460 // False Start is not being used, the result of the SSL handshake will be
13461 // returned as part of the SSLClientSocket::Connect() call. This test
13462 // matches the result of a server sending a handshake_failure alert,
13463 // rather than a Finished message, because it requires a client
13464 // certificate and none was supplied.
ttuttle859dc7a2015-04-23 19:42:2913465 SSLSocketDataProvider ssl_data2(ASYNC, ERR_SSL_PROTOCOL_ERROR);
[email protected]bd0b6772011-01-11 19:59:3013466 ssl_data2.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0713467 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data2);
ttuttle859dc7a2015-04-23 19:42:2913468 StaticSocketDataProvider data2(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0713469 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]bd0b6772011-01-11 19:59:3013470
13471 // [ssl_]data3 contains the data for the third SSL handshake. When a
13472 // connection to a server fails during an SSL handshake,
davidbenb937d6c2015-05-14 04:53:4213473 // HttpNetworkTransaction will attempt to fallback to TLSv1.1 if the previous
13474 // connection was attempted with TLSv1.2. This is transparent to the caller
[email protected]bd0b6772011-01-11 19:59:3013475 // of the HttpNetworkTransaction. Because this test failure is due to
13476 // requiring a client certificate, this fallback handshake should also
13477 // fail.
ttuttle859dc7a2015-04-23 19:42:2913478 SSLSocketDataProvider ssl_data3(ASYNC, ERR_SSL_PROTOCOL_ERROR);
[email protected]bd0b6772011-01-11 19:59:3013479 ssl_data3.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0713480 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data3);
ttuttle859dc7a2015-04-23 19:42:2913481 StaticSocketDataProvider data3(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0713482 session_deps_.socket_factory->AddSocketDataProvider(&data3);
[email protected]bd0b6772011-01-11 19:59:3013483
[email protected]80c75f682012-05-26 16:22:1713484 // [ssl_]data4 contains the data for the fourth SSL handshake. When a
13485 // connection to a server fails during an SSL handshake,
davidbenb937d6c2015-05-14 04:53:4213486 // HttpNetworkTransaction will attempt to fallback to TLSv1 if the previous
13487 // connection was attempted with TLSv1.1. This is transparent to the caller
[email protected]80c75f682012-05-26 16:22:1713488 // of the HttpNetworkTransaction. Because this test failure is due to
13489 // requiring a client certificate, this fallback handshake should also
13490 // fail.
ttuttle859dc7a2015-04-23 19:42:2913491 SSLSocketDataProvider ssl_data4(ASYNC, ERR_SSL_PROTOCOL_ERROR);
[email protected]80c75f682012-05-26 16:22:1713492 ssl_data4.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0713493 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data4);
ttuttle859dc7a2015-04-23 19:42:2913494 StaticSocketDataProvider data4(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0713495 session_deps_.socket_factory->AddSocketDataProvider(&data4);
[email protected]80c75f682012-05-26 16:22:1713496
danakj1fd259a02016-04-16 03:17:0913497 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1613498 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]bd0b6772011-01-11 19:59:3013499
[email protected]bd0b6772011-01-11 19:59:3013500 // Begin the SSL handshake with the peer. This consumes ssl_data1.
[email protected]49639fa2011-12-20 23:22:4113501 TestCompletionCallback callback;
tfarina42834112016-09-22 13:38:2013502 int rv = trans.Start(&request_info, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0113503 ASSERT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]bd0b6772011-01-11 19:59:3013504
13505 // Complete the SSL handshake, which should abort due to requiring a
13506 // client certificate.
13507 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0113508 ASSERT_THAT(rv, IsError(ERR_SSL_CLIENT_AUTH_CERT_NEEDED));
[email protected]bd0b6772011-01-11 19:59:3013509
13510 // Indicate that no certificate should be supplied. From the perspective
13511 // of SSLClientCertCache, NULL is just as meaningful as a real
13512 // certificate, so this is the same as supply a
13513 // legitimate-but-unacceptable certificate.
bnc691fda62016-08-12 00:43:1613514 rv = trans.RestartWithCertificate(NULL, NULL, callback.callback());
robpercival214763f2016-07-01 23:27:0113515 ASSERT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]bd0b6772011-01-11 19:59:3013516
13517 // Ensure the certificate was added to the client auth cache before
13518 // allowing the connection to continue restarting.
13519 scoped_refptr<X509Certificate> client_cert;
svaldez7872fd02015-11-19 21:10:5413520 scoped_refptr<SSLPrivateKey> client_private_key;
[email protected]791879c2013-12-17 07:22:4113521 ASSERT_TRUE(session->ssl_client_auth_cache()->Lookup(
svaldez7872fd02015-11-19 21:10:5413522 HostPortPair("www.example.com", 443), &client_cert, &client_private_key));
wezca1070932016-05-26 20:30:5213523 ASSERT_FALSE(client_cert);
[email protected]bd0b6772011-01-11 19:59:3013524
13525 // Restart the handshake. This will consume ssl_data2, which fails, and
[email protected]80c75f682012-05-26 16:22:1713526 // then consume ssl_data3 and ssl_data4, both of which should also fail.
13527 // The result code is checked against what ssl_data4 should return.
[email protected]bd0b6772011-01-11 19:59:3013528 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0113529 ASSERT_THAT(rv, IsError(ERR_SSL_PROTOCOL_ERROR));
[email protected]bd0b6772011-01-11 19:59:3013530
13531 // Ensure that the client certificate is removed from the cache on a
13532 // handshake failure.
[email protected]791879c2013-12-17 07:22:4113533 ASSERT_FALSE(session->ssl_client_auth_cache()->Lookup(
svaldez7872fd02015-11-19 21:10:5413534 HostPortPair("www.example.com", 443), &client_cert, &client_private_key));
[email protected]bd0b6772011-01-11 19:59:3013535}
13536
13537// Ensure that a client certificate is removed from the SSL client auth
13538// cache when:
13539// 1) No proxy is involved.
13540// 2) TLS False Start is enabled.
13541// 3) The initial TLS handshake requests a client certificate.
13542// 4) The client supplies an invalid/unacceptable certificate.
bncd16676a2016-07-20 16:23:0113543TEST_F(HttpNetworkTransactionTest, ClientAuthCertCache_Direct_FalseStart) {
ttuttle859dc7a2015-04-23 19:42:2913544 HttpRequestInfo request_info;
[email protected]cb9bf6ca2011-01-28 13:15:2713545 request_info.url = GURL("https://www.example.com/");
13546 request_info.method = "GET";
ttuttle859dc7a2015-04-23 19:42:2913547 request_info.load_flags = LOAD_NORMAL;
[email protected]cb9bf6ca2011-01-28 13:15:2713548
[email protected]bd0b6772011-01-11 19:59:3013549 scoped_refptr<SSLCertRequestInfo> cert_request(new SSLCertRequestInfo());
[email protected]791879c2013-12-17 07:22:4113550 cert_request->host_and_port = HostPortPair("www.example.com", 443);
[email protected]bd0b6772011-01-11 19:59:3013551
13552 // When TLS False Start is used, SSLClientSocket::Connect() calls will
13553 // return successfully after reading up to the peer's Certificate message.
13554 // This is to allow the caller to call SSLClientSocket::Write(), which can
13555 // enqueue application data to be sent in the same packet as the
13556 // ChangeCipherSpec and Finished messages.
13557 // The actual handshake will be finished when SSLClientSocket::Read() is
13558 // called, which expects to process the peer's ChangeCipherSpec and
13559 // Finished messages. If there was an error negotiating with the peer,
13560 // such as due to the peer requiring a client certificate when none was
13561 // supplied, the alert sent by the peer won't be processed until Read() is
13562 // called.
13563
13564 // Like the non-False Start case, when a client certificate is requested by
13565 // the peer, the handshake is aborted during the Connect() call.
13566 // [ssl_]data1 represents the initial SSL handshake with the peer.
ttuttle859dc7a2015-04-23 19:42:2913567 SSLSocketDataProvider ssl_data1(ASYNC, ERR_SSL_CLIENT_AUTH_CERT_NEEDED);
[email protected]bd0b6772011-01-11 19:59:3013568 ssl_data1.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0713569 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data1);
ttuttle859dc7a2015-04-23 19:42:2913570 StaticSocketDataProvider data1(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0713571 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]bd0b6772011-01-11 19:59:3013572
13573 // When a client certificate is supplied, Connect() will not be aborted
13574 // when the peer requests the certificate. Instead, the handshake will
13575 // artificially succeed, allowing the caller to write the HTTP request to
13576 // the socket. The handshake messages are not processed until Read() is
13577 // called, which then detects that the handshake was aborted, due to the
13578 // peer sending a handshake_failure because it requires a client
13579 // certificate.
ttuttle859dc7a2015-04-23 19:42:2913580 SSLSocketDataProvider ssl_data2(ASYNC, OK);
[email protected]bd0b6772011-01-11 19:59:3013581 ssl_data2.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0713582 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data2);
ttuttle859dc7a2015-04-23 19:42:2913583 MockRead data2_reads[] = {
13584 MockRead(ASYNC /* async */, ERR_SSL_PROTOCOL_ERROR),
[email protected]bd0b6772011-01-11 19:59:3013585 };
ttuttle859dc7a2015-04-23 19:42:2913586 StaticSocketDataProvider data2(data2_reads, arraysize(data2_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0713587 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]bd0b6772011-01-11 19:59:3013588
13589 // As described in ClientAuthCertCache_Direct_NoFalseStart, [ssl_]data3 is
[email protected]80c75f682012-05-26 16:22:1713590 // the data for the SSL handshake once the TLSv1.1 connection falls back to
13591 // TLSv1. It has the same behaviour as [ssl_]data2.
ttuttle859dc7a2015-04-23 19:42:2913592 SSLSocketDataProvider ssl_data3(ASYNC, OK);
[email protected]bd0b6772011-01-11 19:59:3013593 ssl_data3.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0713594 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data3);
ttuttle859dc7a2015-04-23 19:42:2913595 StaticSocketDataProvider data3(data2_reads, arraysize(data2_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0713596 session_deps_.socket_factory->AddSocketDataProvider(&data3);
[email protected]bd0b6772011-01-11 19:59:3013597
[email protected]80c75f682012-05-26 16:22:1713598 // [ssl_]data4 is the data for the SSL handshake once the TLSv1 connection
13599 // falls back to SSLv3. It has the same behaviour as [ssl_]data2.
ttuttle859dc7a2015-04-23 19:42:2913600 SSLSocketDataProvider ssl_data4(ASYNC, OK);
[email protected]80c75f682012-05-26 16:22:1713601 ssl_data4.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0713602 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data4);
ttuttle859dc7a2015-04-23 19:42:2913603 StaticSocketDataProvider data4(data2_reads, arraysize(data2_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0713604 session_deps_.socket_factory->AddSocketDataProvider(&data4);
[email protected]80c75f682012-05-26 16:22:1713605
[email protected]7799de12013-05-30 05:52:5113606 // Need one more if TLSv1.2 is enabled.
ttuttle859dc7a2015-04-23 19:42:2913607 SSLSocketDataProvider ssl_data5(ASYNC, OK);
[email protected]7799de12013-05-30 05:52:5113608 ssl_data5.cert_request_info = cert_request.get();
13609 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data5);
ttuttle859dc7a2015-04-23 19:42:2913610 StaticSocketDataProvider data5(data2_reads, arraysize(data2_reads), NULL, 0);
[email protected]7799de12013-05-30 05:52:5113611 session_deps_.socket_factory->AddSocketDataProvider(&data5);
13612
danakj1fd259a02016-04-16 03:17:0913613 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1613614 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]bd0b6772011-01-11 19:59:3013615
[email protected]bd0b6772011-01-11 19:59:3013616 // Begin the initial SSL handshake.
[email protected]49639fa2011-12-20 23:22:4113617 TestCompletionCallback callback;
tfarina42834112016-09-22 13:38:2013618 int rv = trans.Start(&request_info, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0113619 ASSERT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]bd0b6772011-01-11 19:59:3013620
13621 // Complete the SSL handshake, which should abort due to requiring a
13622 // client certificate.
13623 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0113624 ASSERT_THAT(rv, IsError(ERR_SSL_CLIENT_AUTH_CERT_NEEDED));
[email protected]bd0b6772011-01-11 19:59:3013625
13626 // Indicate that no certificate should be supplied. From the perspective
13627 // of SSLClientCertCache, NULL is just as meaningful as a real
13628 // certificate, so this is the same as supply a
13629 // legitimate-but-unacceptable certificate.
bnc691fda62016-08-12 00:43:1613630 rv = trans.RestartWithCertificate(NULL, NULL, callback.callback());
robpercival214763f2016-07-01 23:27:0113631 ASSERT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]bd0b6772011-01-11 19:59:3013632
13633 // Ensure the certificate was added to the client auth cache before
13634 // allowing the connection to continue restarting.
13635 scoped_refptr<X509Certificate> client_cert;
svaldez7872fd02015-11-19 21:10:5413636 scoped_refptr<SSLPrivateKey> client_private_key;
[email protected]791879c2013-12-17 07:22:4113637 ASSERT_TRUE(session->ssl_client_auth_cache()->Lookup(
svaldez7872fd02015-11-19 21:10:5413638 HostPortPair("www.example.com", 443), &client_cert, &client_private_key));
wezca1070932016-05-26 20:30:5213639 ASSERT_FALSE(client_cert);
[email protected]bd0b6772011-01-11 19:59:3013640
[email protected]bd0b6772011-01-11 19:59:3013641 // Restart the handshake. This will consume ssl_data2, which fails, and
[email protected]80c75f682012-05-26 16:22:1713642 // then consume ssl_data3 and ssl_data4, both of which should also fail.
13643 // The result code is checked against what ssl_data4 should return.
[email protected]bd0b6772011-01-11 19:59:3013644 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0113645 ASSERT_THAT(rv, IsError(ERR_SSL_PROTOCOL_ERROR));
[email protected]bd0b6772011-01-11 19:59:3013646
13647 // Ensure that the client certificate is removed from the cache on a
13648 // handshake failure.
[email protected]791879c2013-12-17 07:22:4113649 ASSERT_FALSE(session->ssl_client_auth_cache()->Lookup(
svaldez7872fd02015-11-19 21:10:5413650 HostPortPair("www.example.com", 443), &client_cert, &client_private_key));
[email protected]bd0b6772011-01-11 19:59:3013651}
13652
[email protected]8c405132011-01-11 22:03:1813653// Ensure that a client certificate is removed from the SSL client auth
13654// cache when:
13655// 1) An HTTPS proxy is involved.
13656// 3) The HTTPS proxy requests a client certificate.
13657// 4) The client supplies an invalid/unacceptable certificate for the
13658// proxy.
13659// The test is repeated twice, first for connecting to an HTTPS endpoint,
13660// then for connecting to an HTTP endpoint.
bncd16676a2016-07-20 16:23:0113661TEST_F(HttpNetworkTransactionTest, ClientAuthCertCache_Proxy_Fail) {
rdsmith82957ad2015-09-16 19:42:0313662 session_deps_.proxy_service = ProxyService::CreateFixed("https://proxy:70");
vishal.b62985ca92015-04-17 08:45:5113663 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:0713664 session_deps_.net_log = log.bound().net_log();
[email protected]8c405132011-01-11 22:03:1813665
13666 scoped_refptr<SSLCertRequestInfo> cert_request(new SSLCertRequestInfo());
[email protected]791879c2013-12-17 07:22:4113667 cert_request->host_and_port = HostPortPair("proxy", 70);
[email protected]8c405132011-01-11 22:03:1813668
13669 // See ClientAuthCertCache_Direct_NoFalseStart for the explanation of
13670 // [ssl_]data[1-3]. Rather than represending the endpoint
13671 // (www.example.com:443), they represent failures with the HTTPS proxy
13672 // (proxy:70).
ttuttle859dc7a2015-04-23 19:42:2913673 SSLSocketDataProvider ssl_data1(ASYNC, ERR_SSL_CLIENT_AUTH_CERT_NEEDED);
[email protected]8c405132011-01-11 22:03:1813674 ssl_data1.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0713675 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data1);
ttuttle859dc7a2015-04-23 19:42:2913676 StaticSocketDataProvider data1(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0713677 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8c405132011-01-11 22:03:1813678
ttuttle859dc7a2015-04-23 19:42:2913679 SSLSocketDataProvider ssl_data2(ASYNC, ERR_SSL_PROTOCOL_ERROR);
[email protected]8c405132011-01-11 22:03:1813680 ssl_data2.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0713681 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data2);
ttuttle859dc7a2015-04-23 19:42:2913682 StaticSocketDataProvider data2(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0713683 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]8c405132011-01-11 22:03:1813684
[email protected]80c75f682012-05-26 16:22:1713685 // TODO(wtc): find out why this unit test doesn't need [ssl_]data3.
13686#if 0
ttuttle859dc7a2015-04-23 19:42:2913687 SSLSocketDataProvider ssl_data3(ASYNC, ERR_SSL_PROTOCOL_ERROR);
[email protected]8c405132011-01-11 22:03:1813688 ssl_data3.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0713689 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data3);
ttuttle859dc7a2015-04-23 19:42:2913690 StaticSocketDataProvider data3(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0713691 session_deps_.socket_factory->AddSocketDataProvider(&data3);
[email protected]80c75f682012-05-26 16:22:1713692#endif
[email protected]8c405132011-01-11 22:03:1813693
ttuttle859dc7a2015-04-23 19:42:2913694 HttpRequestInfo requests[2];
[email protected]8c405132011-01-11 22:03:1813695 requests[0].url = GURL("https://www.example.com/");
13696 requests[0].method = "GET";
ttuttle859dc7a2015-04-23 19:42:2913697 requests[0].load_flags = LOAD_NORMAL;
[email protected]8c405132011-01-11 22:03:1813698
13699 requests[1].url = GURL("http://www.example.com/");
13700 requests[1].method = "GET";
ttuttle859dc7a2015-04-23 19:42:2913701 requests[1].load_flags = LOAD_NORMAL;
[email protected]8c405132011-01-11 22:03:1813702
13703 for (size_t i = 0; i < arraysize(requests); ++i) {
[email protected]bb88e1d32013-05-03 23:11:0713704 session_deps_.socket_factory->ResetNextMockIndexes();
danakj1fd259a02016-04-16 03:17:0913705 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1613706 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]8c405132011-01-11 22:03:1813707
13708 // Begin the SSL handshake with the proxy.
[email protected]49639fa2011-12-20 23:22:4113709 TestCompletionCallback callback;
tfarina42834112016-09-22 13:38:2013710 int rv = trans.Start(&requests[i], callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0113711 ASSERT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]8c405132011-01-11 22:03:1813712
13713 // Complete the SSL handshake, which should abort due to requiring a
13714 // client certificate.
13715 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0113716 ASSERT_THAT(rv, IsError(ERR_SSL_CLIENT_AUTH_CERT_NEEDED));
[email protected]8c405132011-01-11 22:03:1813717
13718 // Indicate that no certificate should be supplied. From the perspective
13719 // of SSLClientCertCache, NULL is just as meaningful as a real
13720 // certificate, so this is the same as supply a
13721 // legitimate-but-unacceptable certificate.
bnc691fda62016-08-12 00:43:1613722 rv = trans.RestartWithCertificate(NULL, NULL, callback.callback());
robpercival214763f2016-07-01 23:27:0113723 ASSERT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]8c405132011-01-11 22:03:1813724
13725 // Ensure the certificate was added to the client auth cache before
13726 // allowing the connection to continue restarting.
13727 scoped_refptr<X509Certificate> client_cert;
svaldez7872fd02015-11-19 21:10:5413728 scoped_refptr<SSLPrivateKey> client_private_key;
[email protected]791879c2013-12-17 07:22:4113729 ASSERT_TRUE(session->ssl_client_auth_cache()->Lookup(
svaldez7872fd02015-11-19 21:10:5413730 HostPortPair("proxy", 70), &client_cert, &client_private_key));
wezca1070932016-05-26 20:30:5213731 ASSERT_FALSE(client_cert);
[email protected]8c405132011-01-11 22:03:1813732 // Ensure the certificate was NOT cached for the endpoint. This only
13733 // applies to HTTPS requests, but is fine to check for HTTP requests.
[email protected]791879c2013-12-17 07:22:4113734 ASSERT_FALSE(session->ssl_client_auth_cache()->Lookup(
svaldez7872fd02015-11-19 21:10:5413735 HostPortPair("www.example.com", 443), &client_cert,
13736 &client_private_key));
[email protected]8c405132011-01-11 22:03:1813737
13738 // Restart the handshake. This will consume ssl_data2, which fails, and
13739 // then consume ssl_data3, which should also fail. The result code is
13740 // checked against what ssl_data3 should return.
13741 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0113742 ASSERT_THAT(rv, IsError(ERR_PROXY_CONNECTION_FAILED));
[email protected]8c405132011-01-11 22:03:1813743
13744 // Now that the new handshake has failed, ensure that the client
13745 // certificate was removed from the client auth cache.
[email protected]791879c2013-12-17 07:22:4113746 ASSERT_FALSE(session->ssl_client_auth_cache()->Lookup(
svaldez7872fd02015-11-19 21:10:5413747 HostPortPair("proxy", 70), &client_cert, &client_private_key));
[email protected]791879c2013-12-17 07:22:4113748 ASSERT_FALSE(session->ssl_client_auth_cache()->Lookup(
svaldez7872fd02015-11-19 21:10:5413749 HostPortPair("www.example.com", 443), &client_cert,
13750 &client_private_key));
[email protected]8c405132011-01-11 22:03:1813751 }
13752}
13753
bncd16676a2016-07-20 16:23:0113754TEST_F(HttpNetworkTransactionTest, UseIPConnectionPooling) {
[email protected]e3ceb682011-06-28 23:55:4613755 // Set up a special HttpNetworkSession with a MockCachingHostResolver.
Jeremy Roman0579ed62017-08-29 15:56:1913756 session_deps_.host_resolver = std::make_unique<MockCachingHostResolver>();
danakj1fd259a02016-04-16 03:17:0913757 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]e3ceb682011-06-28 23:55:4613758
bnc032658ba2016-09-26 18:17:1513759 AddSSLSocketData();
[email protected]e3ceb682011-06-28 23:55:4613760
bncdf80d44fd2016-07-15 20:27:4113761 SpdySerializedFrame host1_req(
bnc38dcd392016-02-09 23:19:4913762 spdy_util_.ConstructSpdyGet("https://www.example.org", 1, LOWEST));
rdsmithebb50aa2015-11-12 03:44:3813763 spdy_util_.UpdateWithStreamDestruction(1);
bncdf80d44fd2016-07-15 20:27:4113764 SpdySerializedFrame host2_req(
bnca4d611d2016-09-22 19:55:3713765 spdy_util_.ConstructSpdyGet("https://mail.example.com", 3, LOWEST));
[email protected]e3ceb682011-06-28 23:55:4613766 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:4113767 CreateMockWrite(host1_req, 0), CreateMockWrite(host2_req, 3),
[email protected]e3ceb682011-06-28 23:55:4613768 };
bnc42331402016-07-25 13:36:1513769 SpdySerializedFrame host1_resp(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
bncdf80d44fd2016-07-15 20:27:4113770 SpdySerializedFrame host1_resp_body(
13771 spdy_util_.ConstructSpdyDataFrame(1, true));
bnc42331402016-07-25 13:36:1513772 SpdySerializedFrame host2_resp(spdy_util_.ConstructSpdyGetReply(NULL, 0, 3));
bncdf80d44fd2016-07-15 20:27:4113773 SpdySerializedFrame host2_resp_body(
13774 spdy_util_.ConstructSpdyDataFrame(3, true));
[email protected]e3ceb682011-06-28 23:55:4613775 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:4113776 CreateMockRead(host1_resp, 1), CreateMockRead(host1_resp_body, 2),
13777 CreateMockRead(host2_resp, 4), CreateMockRead(host2_resp_body, 5),
rch8e6c6c42015-05-01 14:05:1313778 MockRead(ASYNC, 0, 6),
[email protected]e3ceb682011-06-28 23:55:4613779 };
13780
eroman36d84e54432016-03-17 03:23:0213781 IPEndPoint peer_addr(IPAddress::IPv4Localhost(), 443);
[email protected]d2b5f092012-06-08 23:55:0213782 MockConnect connect(ASYNC, OK, peer_addr);
rch8e6c6c42015-05-01 14:05:1313783 SequencedSocketData spdy_data(connect, spdy_reads, arraysize(spdy_reads),
13784 spdy_writes, arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:0713785 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]e3ceb682011-06-28 23:55:4613786
[email protected]aa22b242011-11-16 18:58:2913787 TestCompletionCallback callback;
[email protected]e3ceb682011-06-28 23:55:4613788 HttpRequestInfo request1;
13789 request1.method = "GET";
bncce36dca22015-04-21 22:11:2313790 request1.url = GURL("https://www.example.org/");
[email protected]e3ceb682011-06-28 23:55:4613791 request1.load_flags = 0;
[email protected]90499482013-06-01 00:39:5013792 HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
[email protected]e3ceb682011-06-28 23:55:4613793
tfarina42834112016-09-22 13:38:2013794 int rv = trans1.Start(&request1, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0113795 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
13796 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]e3ceb682011-06-28 23:55:4613797
13798 const HttpResponseInfo* response = trans1.GetResponseInfo();
wezca1070932016-05-26 20:30:5213799 ASSERT_TRUE(response);
13800 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0213801 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]e3ceb682011-06-28 23:55:4613802
13803 std::string response_data;
robpercival214763f2016-07-01 23:27:0113804 ASSERT_THAT(ReadTransaction(&trans1, &response_data), IsOk());
[email protected]e3ceb682011-06-28 23:55:4613805 EXPECT_EQ("hello!", response_data);
13806
bnca4d611d2016-09-22 19:55:3713807 // Preload mail.example.com into HostCache.
13808 HostPortPair host_port("mail.example.com", 443);
[email protected]5109c1952013-08-20 18:44:1013809 HostResolver::RequestInfo resolve_info(host_port);
[email protected]e3ceb682011-06-28 23:55:4613810 AddressList ignored;
maksim.sisov31452af2016-07-27 06:38:1013811 std::unique_ptr<HostResolver::Request> request;
13812 rv = session_deps_.host_resolver->Resolve(resolve_info, DEFAULT_PRIORITY,
13813 &ignored, callback.callback(),
tfarina42834112016-09-22 13:38:2013814 &request, NetLogWithSource());
robpercival214763f2016-07-01 23:27:0113815 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]6e78dfb2011-07-28 21:34:4713816 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0113817 EXPECT_THAT(rv, IsOk());
[email protected]e3ceb682011-06-28 23:55:4613818
13819 HttpRequestInfo request2;
13820 request2.method = "GET";
bnca4d611d2016-09-22 19:55:3713821 request2.url = GURL("https://mail.example.com/");
[email protected]e3ceb682011-06-28 23:55:4613822 request2.load_flags = 0;
[email protected]90499482013-06-01 00:39:5013823 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
[email protected]e3ceb682011-06-28 23:55:4613824
tfarina42834112016-09-22 13:38:2013825 rv = trans2.Start(&request2, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0113826 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
13827 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]e3ceb682011-06-28 23:55:4613828
13829 response = trans2.GetResponseInfo();
wezca1070932016-05-26 20:30:5213830 ASSERT_TRUE(response);
13831 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0213832 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]e3ceb682011-06-28 23:55:4613833 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5213834 EXPECT_TRUE(response->was_alpn_negotiated);
robpercival214763f2016-07-01 23:27:0113835 ASSERT_THAT(ReadTransaction(&trans2, &response_data), IsOk());
[email protected]e3ceb682011-06-28 23:55:4613836 EXPECT_EQ("hello!", response_data);
[email protected]e3ceb682011-06-28 23:55:4613837}
13838
bncd16676a2016-07-20 16:23:0113839TEST_F(HttpNetworkTransactionTest, UseIPConnectionPoolingAfterResolution) {
[email protected]d2b5f092012-06-08 23:55:0213840 // Set up a special HttpNetworkSession with a MockCachingHostResolver.
Jeremy Roman0579ed62017-08-29 15:56:1913841 session_deps_.host_resolver = std::make_unique<MockCachingHostResolver>();
danakj1fd259a02016-04-16 03:17:0913842 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]d2b5f092012-06-08 23:55:0213843
bnc032658ba2016-09-26 18:17:1513844 AddSSLSocketData();
[email protected]d2b5f092012-06-08 23:55:0213845
bncdf80d44fd2016-07-15 20:27:4113846 SpdySerializedFrame host1_req(
bnc38dcd392016-02-09 23:19:4913847 spdy_util_.ConstructSpdyGet("https://www.example.org", 1, LOWEST));
rdsmithebb50aa2015-11-12 03:44:3813848 spdy_util_.UpdateWithStreamDestruction(1);
bncdf80d44fd2016-07-15 20:27:4113849 SpdySerializedFrame host2_req(
bnca4d611d2016-09-22 19:55:3713850 spdy_util_.ConstructSpdyGet("https://mail.example.com", 3, LOWEST));
[email protected]d2b5f092012-06-08 23:55:0213851 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:4113852 CreateMockWrite(host1_req, 0), CreateMockWrite(host2_req, 3),
[email protected]d2b5f092012-06-08 23:55:0213853 };
bnc42331402016-07-25 13:36:1513854 SpdySerializedFrame host1_resp(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
bncdf80d44fd2016-07-15 20:27:4113855 SpdySerializedFrame host1_resp_body(
13856 spdy_util_.ConstructSpdyDataFrame(1, true));
bnc42331402016-07-25 13:36:1513857 SpdySerializedFrame host2_resp(spdy_util_.ConstructSpdyGetReply(NULL, 0, 3));
bncdf80d44fd2016-07-15 20:27:4113858 SpdySerializedFrame host2_resp_body(
13859 spdy_util_.ConstructSpdyDataFrame(3, true));
[email protected]d2b5f092012-06-08 23:55:0213860 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:4113861 CreateMockRead(host1_resp, 1), CreateMockRead(host1_resp_body, 2),
13862 CreateMockRead(host2_resp, 4), CreateMockRead(host2_resp_body, 5),
rch8e6c6c42015-05-01 14:05:1313863 MockRead(ASYNC, 0, 6),
[email protected]d2b5f092012-06-08 23:55:0213864 };
13865
eroman36d84e54432016-03-17 03:23:0213866 IPEndPoint peer_addr(IPAddress::IPv4Localhost(), 443);
[email protected]d2b5f092012-06-08 23:55:0213867 MockConnect connect(ASYNC, OK, peer_addr);
rch8e6c6c42015-05-01 14:05:1313868 SequencedSocketData spdy_data(connect, spdy_reads, arraysize(spdy_reads),
13869 spdy_writes, arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:0713870 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]d2b5f092012-06-08 23:55:0213871
13872 TestCompletionCallback callback;
13873 HttpRequestInfo request1;
13874 request1.method = "GET";
bncce36dca22015-04-21 22:11:2313875 request1.url = GURL("https://www.example.org/");
[email protected]d2b5f092012-06-08 23:55:0213876 request1.load_flags = 0;
[email protected]90499482013-06-01 00:39:5013877 HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
[email protected]d2b5f092012-06-08 23:55:0213878
tfarina42834112016-09-22 13:38:2013879 int rv = trans1.Start(&request1, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0113880 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
13881 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]d2b5f092012-06-08 23:55:0213882
13883 const HttpResponseInfo* response = trans1.GetResponseInfo();
wezca1070932016-05-26 20:30:5213884 ASSERT_TRUE(response);
13885 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0213886 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]d2b5f092012-06-08 23:55:0213887
13888 std::string response_data;
robpercival214763f2016-07-01 23:27:0113889 ASSERT_THAT(ReadTransaction(&trans1, &response_data), IsOk());
[email protected]d2b5f092012-06-08 23:55:0213890 EXPECT_EQ("hello!", response_data);
13891
13892 HttpRequestInfo request2;
13893 request2.method = "GET";
bnca4d611d2016-09-22 19:55:3713894 request2.url = GURL("https://mail.example.com/");
[email protected]d2b5f092012-06-08 23:55:0213895 request2.load_flags = 0;
[email protected]90499482013-06-01 00:39:5013896 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
[email protected]d2b5f092012-06-08 23:55:0213897
tfarina42834112016-09-22 13:38:2013898 rv = trans2.Start(&request2, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0113899 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
13900 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]d2b5f092012-06-08 23:55:0213901
13902 response = trans2.GetResponseInfo();
wezca1070932016-05-26 20:30:5213903 ASSERT_TRUE(response);
13904 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0213905 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]d2b5f092012-06-08 23:55:0213906 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5213907 EXPECT_TRUE(response->was_alpn_negotiated);
robpercival214763f2016-07-01 23:27:0113908 ASSERT_THAT(ReadTransaction(&trans2, &response_data), IsOk());
[email protected]d2b5f092012-06-08 23:55:0213909 EXPECT_EQ("hello!", response_data);
[email protected]d2b5f092012-06-08 23:55:0213910}
13911
bnc8016c1f2017-03-31 02:11:2913912// Regression test for https://crbug.com/546991.
13913// The server might not be able to serve an IP pooled request, and might send a
13914// 421 Misdirected Request response status to indicate this.
13915// HttpNetworkTransaction should reset the request and retry without IP pooling.
13916TEST_F(HttpNetworkTransactionTest, RetryWithoutConnectionPooling) {
13917 // Two hosts resolve to the same IP address.
13918 const std::string ip_addr = "1.2.3.4";
13919 IPAddress ip;
13920 ASSERT_TRUE(ip.AssignFromIPLiteral(ip_addr));
13921 IPEndPoint peer_addr = IPEndPoint(ip, 443);
13922
Jeremy Roman0579ed62017-08-29 15:56:1913923 session_deps_.host_resolver = std::make_unique<MockCachingHostResolver>();
bnc8016c1f2017-03-31 02:11:2913924 session_deps_.host_resolver->rules()->AddRule("www.example.org", ip_addr);
13925 session_deps_.host_resolver->rules()->AddRule("mail.example.org", ip_addr);
13926
13927 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
13928
13929 // Two requests on the first connection.
13930 SpdySerializedFrame req1(
13931 spdy_util_.ConstructSpdyGet("https://www.example.org", 1, LOWEST));
13932 spdy_util_.UpdateWithStreamDestruction(1);
13933 SpdySerializedFrame req2(
13934 spdy_util_.ConstructSpdyGet("https://mail.example.org", 3, LOWEST));
13935 SpdySerializedFrame rst(
13936 spdy_util_.ConstructSpdyRstStream(3, ERROR_CODE_CANCEL));
13937 MockWrite writes1[] = {
13938 CreateMockWrite(req1, 0), CreateMockWrite(req2, 3),
13939 CreateMockWrite(rst, 6),
13940 };
13941
13942 // The first one succeeds, the second gets error 421 Misdirected Request.
13943 SpdySerializedFrame resp1(spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
13944 SpdySerializedFrame body1(spdy_util_.ConstructSpdyDataFrame(1, true));
13945 SpdyHeaderBlock response_headers;
13946 response_headers[SpdyTestUtil::GetStatusKey()] = "421";
13947 SpdySerializedFrame resp2(
13948 spdy_util_.ConstructSpdyReply(3, std::move(response_headers)));
13949 MockRead reads1[] = {CreateMockRead(resp1, 1), CreateMockRead(body1, 2),
13950 CreateMockRead(resp2, 4), MockRead(ASYNC, 0, 5)};
13951
13952 MockConnect connect1(ASYNC, OK, peer_addr);
13953 SequencedSocketData data1(connect1, reads1, arraysize(reads1), writes1,
13954 arraysize(writes1));
13955 session_deps_.socket_factory->AddSocketDataProvider(&data1);
13956
13957 AddSSLSocketData();
13958
13959 // Retry the second request on a second connection.
13960 SpdyTestUtil spdy_util2;
13961 SpdySerializedFrame req3(
13962 spdy_util2.ConstructSpdyGet("https://mail.example.org", 1, LOWEST));
13963 MockWrite writes2[] = {
13964 CreateMockWrite(req3, 0),
13965 };
13966
13967 SpdySerializedFrame resp3(spdy_util2.ConstructSpdyGetReply(nullptr, 0, 1));
13968 SpdySerializedFrame body3(spdy_util2.ConstructSpdyDataFrame(1, true));
13969 MockRead reads2[] = {CreateMockRead(resp3, 1), CreateMockRead(body3, 2),
13970 MockRead(ASYNC, 0, 3)};
13971
13972 MockConnect connect2(ASYNC, OK, peer_addr);
13973 SequencedSocketData data2(connect2, reads2, arraysize(reads2), writes2,
13974 arraysize(writes2));
13975 session_deps_.socket_factory->AddSocketDataProvider(&data2);
13976
13977 AddSSLSocketData();
13978
13979 // Preload mail.example.org into HostCache.
13980 HostPortPair host_port("mail.example.org", 443);
13981 HostResolver::RequestInfo resolve_info(host_port);
13982 AddressList ignored;
13983 std::unique_ptr<HostResolver::Request> request;
13984 TestCompletionCallback callback;
13985 int rv = session_deps_.host_resolver->Resolve(resolve_info, DEFAULT_PRIORITY,
13986 &ignored, callback.callback(),
13987 &request, NetLogWithSource());
13988 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
13989 rv = callback.WaitForResult();
13990 EXPECT_THAT(rv, IsOk());
13991
13992 HttpRequestInfo request1;
13993 request1.method = "GET";
13994 request1.url = GURL("https://www.example.org/");
13995 request1.load_flags = 0;
13996 HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
13997
13998 rv = trans1.Start(&request1, callback.callback(), NetLogWithSource());
13999 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
14000 rv = callback.WaitForResult();
14001 EXPECT_THAT(rv, IsOk());
14002
14003 const HttpResponseInfo* response = trans1.GetResponseInfo();
14004 ASSERT_TRUE(response);
14005 ASSERT_TRUE(response->headers);
14006 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
14007 EXPECT_TRUE(response->was_fetched_via_spdy);
14008 EXPECT_TRUE(response->was_alpn_negotiated);
14009 std::string response_data;
14010 ASSERT_THAT(ReadTransaction(&trans1, &response_data), IsOk());
14011 EXPECT_EQ("hello!", response_data);
14012
14013 HttpRequestInfo request2;
14014 request2.method = "GET";
14015 request2.url = GURL("https://mail.example.org/");
14016 request2.load_flags = 0;
14017 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
14018
14019 BoundTestNetLog log;
14020 rv = trans2.Start(&request2, callback.callback(), log.bound());
14021 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
14022 rv = callback.WaitForResult();
14023 EXPECT_THAT(rv, IsOk());
14024
14025 response = trans2.GetResponseInfo();
14026 ASSERT_TRUE(response);
14027 ASSERT_TRUE(response->headers);
14028 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
14029 EXPECT_TRUE(response->was_fetched_via_spdy);
14030 EXPECT_TRUE(response->was_alpn_negotiated);
14031 ASSERT_THAT(ReadTransaction(&trans2, &response_data), IsOk());
14032 EXPECT_EQ("hello!", response_data);
14033
14034 TestNetLogEntry::List entries;
14035 log.GetEntries(&entries);
davidbence688ae2017-05-04 15:12:5914036 ExpectLogContainsSomewhere(
14037 entries, 0, NetLogEventType::HTTP_TRANSACTION_RESTART_MISDIRECTED_REQUEST,
bnc8016c1f2017-03-31 02:11:2914038 NetLogEventPhase::NONE);
davidbence688ae2017-05-04 15:12:5914039}
14040
14041// Test that HTTP 421 responses are properly returned to the caller if received
14042// on the retry as well. HttpNetworkTransaction should not infinite loop or lose
14043// portions of the response.
14044TEST_F(HttpNetworkTransactionTest, ReturnHTTP421OnRetry) {
14045 // Two hosts resolve to the same IP address.
14046 const std::string ip_addr = "1.2.3.4";
14047 IPAddress ip;
14048 ASSERT_TRUE(ip.AssignFromIPLiteral(ip_addr));
14049 IPEndPoint peer_addr = IPEndPoint(ip, 443);
14050
Jeremy Roman0579ed62017-08-29 15:56:1914051 session_deps_.host_resolver = std::make_unique<MockCachingHostResolver>();
davidbence688ae2017-05-04 15:12:5914052 session_deps_.host_resolver->rules()->AddRule("www.example.org", ip_addr);
14053 session_deps_.host_resolver->rules()->AddRule("mail.example.org", ip_addr);
14054
14055 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
14056
14057 // Two requests on the first connection.
14058 SpdySerializedFrame req1(
14059 spdy_util_.ConstructSpdyGet("https://www.example.org", 1, LOWEST));
14060 spdy_util_.UpdateWithStreamDestruction(1);
14061 SpdySerializedFrame req2(
14062 spdy_util_.ConstructSpdyGet("https://mail.example.org", 3, LOWEST));
14063 SpdySerializedFrame rst(
14064 spdy_util_.ConstructSpdyRstStream(3, ERROR_CODE_CANCEL));
14065 MockWrite writes1[] = {
14066 CreateMockWrite(req1, 0), CreateMockWrite(req2, 3),
14067 CreateMockWrite(rst, 6),
14068 };
14069
14070 // The first one succeeds, the second gets error 421 Misdirected Request.
14071 SpdySerializedFrame resp1(spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
14072 SpdySerializedFrame body1(spdy_util_.ConstructSpdyDataFrame(1, true));
14073 SpdyHeaderBlock response_headers;
14074 response_headers[SpdyTestUtil::GetStatusKey()] = "421";
14075 SpdySerializedFrame resp2(
14076 spdy_util_.ConstructSpdyReply(3, response_headers.Clone()));
14077 MockRead reads1[] = {CreateMockRead(resp1, 1), CreateMockRead(body1, 2),
14078 CreateMockRead(resp2, 4), MockRead(ASYNC, 0, 5)};
14079
14080 MockConnect connect1(ASYNC, OK, peer_addr);
14081 SequencedSocketData data1(connect1, reads1, arraysize(reads1), writes1,
14082 arraysize(writes1));
14083 session_deps_.socket_factory->AddSocketDataProvider(&data1);
14084
14085 AddSSLSocketData();
14086
14087 // Retry the second request on a second connection. It returns 421 Misdirected
14088 // Retry again.
14089 SpdyTestUtil spdy_util2;
14090 SpdySerializedFrame req3(
14091 spdy_util2.ConstructSpdyGet("https://mail.example.org", 1, LOWEST));
14092 MockWrite writes2[] = {
14093 CreateMockWrite(req3, 0),
14094 };
14095
14096 SpdySerializedFrame resp3(
14097 spdy_util2.ConstructSpdyReply(1, std::move(response_headers)));
14098 SpdySerializedFrame body3(spdy_util2.ConstructSpdyDataFrame(1, true));
14099 MockRead reads2[] = {CreateMockRead(resp3, 1), CreateMockRead(body3, 2),
14100 MockRead(ASYNC, 0, 3)};
14101
14102 MockConnect connect2(ASYNC, OK, peer_addr);
14103 SequencedSocketData data2(connect2, reads2, arraysize(reads2), writes2,
14104 arraysize(writes2));
14105 session_deps_.socket_factory->AddSocketDataProvider(&data2);
14106
14107 AddSSLSocketData();
14108
14109 // Preload mail.example.org into HostCache.
14110 HostPortPair host_port("mail.example.org", 443);
14111 HostResolver::RequestInfo resolve_info(host_port);
14112 AddressList ignored;
14113 std::unique_ptr<HostResolver::Request> request;
14114 TestCompletionCallback callback;
14115 int rv = session_deps_.host_resolver->Resolve(resolve_info, DEFAULT_PRIORITY,
14116 &ignored, callback.callback(),
14117 &request, NetLogWithSource());
14118 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
14119 rv = callback.WaitForResult();
14120 EXPECT_THAT(rv, IsOk());
14121
14122 HttpRequestInfo request1;
14123 request1.method = "GET";
14124 request1.url = GURL("https://www.example.org/");
14125 request1.load_flags = 0;
14126 HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
14127
14128 rv = trans1.Start(&request1, callback.callback(), NetLogWithSource());
14129 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
14130 rv = callback.WaitForResult();
14131 EXPECT_THAT(rv, IsOk());
14132
14133 const HttpResponseInfo* response = trans1.GetResponseInfo();
14134 ASSERT_TRUE(response);
14135 ASSERT_TRUE(response->headers);
14136 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
14137 EXPECT_TRUE(response->was_fetched_via_spdy);
14138 EXPECT_TRUE(response->was_alpn_negotiated);
14139 std::string response_data;
14140 ASSERT_THAT(ReadTransaction(&trans1, &response_data), IsOk());
14141 EXPECT_EQ("hello!", response_data);
14142
14143 HttpRequestInfo request2;
14144 request2.method = "GET";
14145 request2.url = GURL("https://mail.example.org/");
14146 request2.load_flags = 0;
14147 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
14148
14149 BoundTestNetLog log;
14150 rv = trans2.Start(&request2, callback.callback(), log.bound());
14151 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
14152 rv = callback.WaitForResult();
14153 EXPECT_THAT(rv, IsOk());
14154
14155 // After a retry, the 421 Misdirected Request is reported back up to the
14156 // caller.
14157 response = trans2.GetResponseInfo();
14158 ASSERT_TRUE(response);
14159 ASSERT_TRUE(response->headers);
14160 EXPECT_EQ("HTTP/1.1 421", response->headers->GetStatusLine());
14161 EXPECT_TRUE(response->was_fetched_via_spdy);
14162 EXPECT_TRUE(response->was_alpn_negotiated);
14163 EXPECT_TRUE(response->ssl_info.cert);
14164 ASSERT_THAT(ReadTransaction(&trans2, &response_data), IsOk());
14165 EXPECT_EQ("hello!", response_data);
bnc8016c1f2017-03-31 02:11:2914166}
14167
bnc6dcd8192017-05-25 20:11:5014168class OneTimeCachingHostResolver : public MockHostResolverBase {
[email protected]e3ceb682011-06-28 23:55:4614169 public:
14170 explicit OneTimeCachingHostResolver(const HostPortPair& host_port)
bnc6dcd8192017-05-25 20:11:5014171 : MockHostResolverBase(/* use_caching = */ true), host_port_(host_port) {}
dchengb03027d2014-10-21 12:00:2014172 ~OneTimeCachingHostResolver() override {}
[email protected]e3ceb682011-06-28 23:55:4614173
dchengb03027d2014-10-21 12:00:2014174 int ResolveFromCache(const RequestInfo& info,
14175 AddressList* addresses,
tfarina42834112016-09-22 13:38:2014176 const NetLogWithSource& net_log) override {
bnc6dcd8192017-05-25 20:11:5014177 int rv = MockHostResolverBase::ResolveFromCache(info, addresses, net_log);
[email protected]95a214c2011-08-04 21:50:4014178 if (rv == OK && info.host_port_pair().Equals(host_port_))
bnc6dcd8192017-05-25 20:11:5014179 GetHostCache()->clear();
[email protected]e3ceb682011-06-28 23:55:4614180 return rv;
14181 }
14182
[email protected]e3ceb682011-06-28 23:55:4614183 private:
[email protected]e3ceb682011-06-28 23:55:4614184 const HostPortPair host_port_;
14185};
14186
bncd16676a2016-07-20 16:23:0114187TEST_F(HttpNetworkTransactionTest,
mmenke5c642132015-06-02 16:05:1314188 UseIPConnectionPoolingWithHostCacheExpiration) {
[email protected]e3ceb682011-06-28 23:55:4614189 // Set up a special HttpNetworkSession with a OneTimeCachingHostResolver.
Jeremy Roman0579ed62017-08-29 15:56:1914190 session_deps_.host_resolver = std::make_unique<OneTimeCachingHostResolver>(
bnca4d611d2016-09-22 19:55:3714191 HostPortPair("mail.example.com", 443));
danakj1fd259a02016-04-16 03:17:0914192 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]e3ceb682011-06-28 23:55:4614193
bnc032658ba2016-09-26 18:17:1514194 AddSSLSocketData();
[email protected]e3ceb682011-06-28 23:55:4614195
bncdf80d44fd2016-07-15 20:27:4114196 SpdySerializedFrame host1_req(
bnc38dcd392016-02-09 23:19:4914197 spdy_util_.ConstructSpdyGet("https://www.example.org", 1, LOWEST));
rdsmithebb50aa2015-11-12 03:44:3814198 spdy_util_.UpdateWithStreamDestruction(1);
bncdf80d44fd2016-07-15 20:27:4114199 SpdySerializedFrame host2_req(
bnca4d611d2016-09-22 19:55:3714200 spdy_util_.ConstructSpdyGet("https://mail.example.com", 3, LOWEST));
[email protected]e3ceb682011-06-28 23:55:4614201 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:4114202 CreateMockWrite(host1_req, 0), CreateMockWrite(host2_req, 3),
[email protected]e3ceb682011-06-28 23:55:4614203 };
bnc42331402016-07-25 13:36:1514204 SpdySerializedFrame host1_resp(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
bncdf80d44fd2016-07-15 20:27:4114205 SpdySerializedFrame host1_resp_body(
14206 spdy_util_.ConstructSpdyDataFrame(1, true));
bnc42331402016-07-25 13:36:1514207 SpdySerializedFrame host2_resp(spdy_util_.ConstructSpdyGetReply(NULL, 0, 3));
bncdf80d44fd2016-07-15 20:27:4114208 SpdySerializedFrame host2_resp_body(
14209 spdy_util_.ConstructSpdyDataFrame(3, true));
[email protected]e3ceb682011-06-28 23:55:4614210 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:4114211 CreateMockRead(host1_resp, 1), CreateMockRead(host1_resp_body, 2),
14212 CreateMockRead(host2_resp, 4), CreateMockRead(host2_resp_body, 5),
rch8e6c6c42015-05-01 14:05:1314213 MockRead(ASYNC, 0, 6),
[email protected]e3ceb682011-06-28 23:55:4614214 };
14215
eroman36d84e54432016-03-17 03:23:0214216 IPEndPoint peer_addr(IPAddress::IPv4Localhost(), 443);
[email protected]d2b5f092012-06-08 23:55:0214217 MockConnect connect(ASYNC, OK, peer_addr);
rch8e6c6c42015-05-01 14:05:1314218 SequencedSocketData spdy_data(connect, spdy_reads, arraysize(spdy_reads),
14219 spdy_writes, arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:0714220 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]e3ceb682011-06-28 23:55:4614221
[email protected]aa22b242011-11-16 18:58:2914222 TestCompletionCallback callback;
[email protected]e3ceb682011-06-28 23:55:4614223 HttpRequestInfo request1;
14224 request1.method = "GET";
bncce36dca22015-04-21 22:11:2314225 request1.url = GURL("https://www.example.org/");
[email protected]e3ceb682011-06-28 23:55:4614226 request1.load_flags = 0;
[email protected]90499482013-06-01 00:39:5014227 HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
[email protected]e3ceb682011-06-28 23:55:4614228
tfarina42834112016-09-22 13:38:2014229 int rv = trans1.Start(&request1, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0114230 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
14231 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]e3ceb682011-06-28 23:55:4614232
14233 const HttpResponseInfo* response = trans1.GetResponseInfo();
wezca1070932016-05-26 20:30:5214234 ASSERT_TRUE(response);
14235 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0214236 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]e3ceb682011-06-28 23:55:4614237
14238 std::string response_data;
robpercival214763f2016-07-01 23:27:0114239 ASSERT_THAT(ReadTransaction(&trans1, &response_data), IsOk());
[email protected]e3ceb682011-06-28 23:55:4614240 EXPECT_EQ("hello!", response_data);
14241
14242 // Preload cache entries into HostCache.
bnca4d611d2016-09-22 19:55:3714243 HostResolver::RequestInfo resolve_info(HostPortPair("mail.example.com", 443));
[email protected]e3ceb682011-06-28 23:55:4614244 AddressList ignored;
maksim.sisov31452af2016-07-27 06:38:1014245 std::unique_ptr<HostResolver::Request> request;
bnc6dcd8192017-05-25 20:11:5014246 rv = session_deps_.host_resolver->Resolve(resolve_info, DEFAULT_PRIORITY,
14247 &ignored, callback.callback(),
14248 &request, NetLogWithSource());
robpercival214763f2016-07-01 23:27:0114249 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]6e78dfb2011-07-28 21:34:4714250 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0114251 EXPECT_THAT(rv, IsOk());
[email protected]e3ceb682011-06-28 23:55:4614252
14253 HttpRequestInfo request2;
14254 request2.method = "GET";
bnca4d611d2016-09-22 19:55:3714255 request2.url = GURL("https://mail.example.com/");
[email protected]e3ceb682011-06-28 23:55:4614256 request2.load_flags = 0;
[email protected]90499482013-06-01 00:39:5014257 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
[email protected]e3ceb682011-06-28 23:55:4614258
tfarina42834112016-09-22 13:38:2014259 rv = trans2.Start(&request2, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0114260 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
14261 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]e3ceb682011-06-28 23:55:4614262
14263 response = trans2.GetResponseInfo();
wezca1070932016-05-26 20:30:5214264 ASSERT_TRUE(response);
14265 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0214266 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]e3ceb682011-06-28 23:55:4614267 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5214268 EXPECT_TRUE(response->was_alpn_negotiated);
robpercival214763f2016-07-01 23:27:0114269 ASSERT_THAT(ReadTransaction(&trans2, &response_data), IsOk());
[email protected]e3ceb682011-06-28 23:55:4614270 EXPECT_EQ("hello!", response_data);
[email protected]e3ceb682011-06-28 23:55:4614271}
14272
bncd16676a2016-07-20 16:23:0114273TEST_F(HttpNetworkTransactionTest, DoNotUseSpdySessionForHttp) {
bncce36dca22015-04-21 22:11:2314274 const std::string https_url = "https://www.example.org:8080/";
14275 const std::string http_url = "http://www.example.org:8080/";
[email protected]8450d722012-07-02 19:14:0414276
14277 // SPDY GET for HTTPS URL
bncdf80d44fd2016-07-15 20:27:4114278 SpdySerializedFrame req1(
bnc38dcd392016-02-09 23:19:4914279 spdy_util_.ConstructSpdyGet(https_url.c_str(), 1, LOWEST));
[email protected]8450d722012-07-02 19:14:0414280
14281 MockWrite writes1[] = {
bncdf80d44fd2016-07-15 20:27:4114282 CreateMockWrite(req1, 0),
[email protected]8450d722012-07-02 19:14:0414283 };
14284
bnc42331402016-07-25 13:36:1514285 SpdySerializedFrame resp1(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
bncdf80d44fd2016-07-15 20:27:4114286 SpdySerializedFrame body1(spdy_util_.ConstructSpdyDataFrame(1, true));
14287 MockRead reads1[] = {CreateMockRead(resp1, 1), CreateMockRead(body1, 2),
mmenkee24011922015-12-17 22:12:5914288 MockRead(SYNCHRONOUS, ERR_IO_PENDING, 3)};
[email protected]8450d722012-07-02 19:14:0414289
rch8e6c6c42015-05-01 14:05:1314290 SequencedSocketData data1(reads1, arraysize(reads1), writes1,
14291 arraysize(writes1));
[email protected]8450d722012-07-02 19:14:0414292 MockConnect connect_data1(ASYNC, OK);
[email protected]dd54bd82012-07-19 23:44:5714293 data1.set_connect_data(connect_data1);
[email protected]8450d722012-07-02 19:14:0414294
14295 // HTTP GET for the HTTP URL
14296 MockWrite writes2[] = {
rch8e6c6c42015-05-01 14:05:1314297 MockWrite(ASYNC, 0,
lgarrona91df87f2014-12-05 00:51:3414298 "GET / HTTP/1.1\r\n"
bncce36dca22015-04-21 22:11:2314299 "Host: www.example.org:8080\r\n"
lgarrona91df87f2014-12-05 00:51:3414300 "Connection: keep-alive\r\n\r\n"),
[email protected]8450d722012-07-02 19:14:0414301 };
14302
14303 MockRead reads2[] = {
rch8e6c6c42015-05-01 14:05:1314304 MockRead(ASYNC, 1, "HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
14305 MockRead(ASYNC, 2, "hello"),
14306 MockRead(ASYNC, OK, 3),
[email protected]8450d722012-07-02 19:14:0414307 };
14308
rch8e6c6c42015-05-01 14:05:1314309 SequencedSocketData data2(reads2, arraysize(reads2), writes2,
14310 arraysize(writes2));
[email protected]8450d722012-07-02 19:14:0414311
[email protected]8450d722012-07-02 19:14:0414312 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3614313 ssl.next_proto = kProtoHTTP2;
[email protected]bb88e1d32013-05-03 23:11:0714314 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
14315 session_deps_.socket_factory->AddSocketDataProvider(&data1);
14316 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]8450d722012-07-02 19:14:0414317
danakj1fd259a02016-04-16 03:17:0914318 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]8450d722012-07-02 19:14:0414319
14320 // Start the first transaction to set up the SpdySession
14321 HttpRequestInfo request1;
14322 request1.method = "GET";
14323 request1.url = GURL(https_url);
[email protected]8450d722012-07-02 19:14:0414324 request1.load_flags = 0;
[email protected]90499482013-06-01 00:39:5014325 HttpNetworkTransaction trans1(LOWEST, session.get());
[email protected]8450d722012-07-02 19:14:0414326 TestCompletionCallback callback1;
14327 EXPECT_EQ(ERR_IO_PENDING,
tfarina42834112016-09-22 13:38:2014328 trans1.Start(&request1, callback1.callback(), NetLogWithSource()));
fdoray92e35a72016-06-10 15:54:5514329 base::RunLoop().RunUntilIdle();
[email protected]8450d722012-07-02 19:14:0414330
robpercival214763f2016-07-01 23:27:0114331 EXPECT_THAT(callback1.WaitForResult(), IsOk());
[email protected]8450d722012-07-02 19:14:0414332 EXPECT_TRUE(trans1.GetResponseInfo()->was_fetched_via_spdy);
14333
14334 // Now, start the HTTP request
14335 HttpRequestInfo request2;
14336 request2.method = "GET";
14337 request2.url = GURL(http_url);
[email protected]8450d722012-07-02 19:14:0414338 request2.load_flags = 0;
[email protected]90499482013-06-01 00:39:5014339 HttpNetworkTransaction trans2(MEDIUM, session.get());
[email protected]8450d722012-07-02 19:14:0414340 TestCompletionCallback callback2;
14341 EXPECT_EQ(ERR_IO_PENDING,
tfarina42834112016-09-22 13:38:2014342 trans2.Start(&request2, callback2.callback(), NetLogWithSource()));
fdoray92e35a72016-06-10 15:54:5514343 base::RunLoop().RunUntilIdle();
[email protected]8450d722012-07-02 19:14:0414344
robpercival214763f2016-07-01 23:27:0114345 EXPECT_THAT(callback2.WaitForResult(), IsOk());
[email protected]8450d722012-07-02 19:14:0414346 EXPECT_FALSE(trans2.GetResponseInfo()->was_fetched_via_spdy);
14347}
14348
bnc5452e2a2015-05-08 16:27:4214349// Alternative service requires HTTP/2 (or SPDY), but HTTP/1.1 is negotiated
14350// with the alternative server. That connection should not be used.
bncd16676a2016-07-20 16:23:0114351TEST_F(HttpNetworkTransactionTest, AlternativeServiceNotOnHttp11) {
bnc8bef8da22016-05-30 01:28:2514352 url::SchemeHostPort server("https", "www.example.org", 443);
14353 HostPortPair alternative("www.example.org", 444);
bnc5452e2a2015-05-08 16:27:4214354
bnc8bef8da22016-05-30 01:28:2514355 // Negotiate HTTP/1.1 with alternative.
bnc5452e2a2015-05-08 16:27:4214356 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3614357 ssl.next_proto = kProtoHTTP11;
bnc5452e2a2015-05-08 16:27:4214358 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
14359
14360 // No data should be read from the alternative, because HTTP/1.1 is
14361 // negotiated.
14362 StaticSocketDataProvider data;
14363 session_deps_.socket_factory->AddSocketDataProvider(&data);
14364
14365 // This test documents that an alternate Job should not be used if HTTP/1.1 is
zhongyi3d4a55e72016-04-22 20:36:4614366 // negotiated. In order to test this, a failed connection to the server is
bnc5452e2a2015-05-08 16:27:4214367 // mocked. This way the request relies on the alternate Job.
14368 StaticSocketDataProvider data_refused;
14369 data_refused.set_connect_data(MockConnect(ASYNC, ERR_CONNECTION_REFUSED));
14370 session_deps_.socket_factory->AddSocketDataProvider(&data_refused);
14371
zhongyi3d4a55e72016-04-22 20:36:4614372 // Set up alternative service for server.
danakj1fd259a02016-04-16 03:17:0914373 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc525e175a2016-06-20 12:36:4014374 HttpServerProperties* http_server_properties =
bnc5452e2a2015-05-08 16:27:4214375 session->http_server_properties();
bnc3472afd2016-11-17 15:27:2114376 AlternativeService alternative_service(kProtoHTTP2, alternative);
bnc7dc7e1b42015-07-28 14:43:1214377 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:2114378 http_server_properties->SetHttp2AlternativeService(
14379 server, alternative_service, expiration);
bnc5452e2a2015-05-08 16:27:4214380
bnc5452e2a2015-05-08 16:27:4214381 HttpRequestInfo request;
krasinc06a72a2016-12-21 03:42:4614382 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
bnc5452e2a2015-05-08 16:27:4214383 request.method = "GET";
bnc8bef8da22016-05-30 01:28:2514384 request.url = GURL("https://www.example.org:443");
bnc5452e2a2015-05-08 16:27:4214385 TestCompletionCallback callback;
14386
14387 // HTTP/2 (or SPDY) is required for alternative service, if HTTP/1.1 is
bnc94c92842016-09-21 15:22:5214388 // negotiated, the alternate Job should fail with ERR_ALPN_NEGOTIATION_FAILED.
tfarina42834112016-09-22 13:38:2014389 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
bnc94c92842016-09-21 15:22:5214390 EXPECT_THAT(callback.GetResult(rv), IsError(ERR_ALPN_NEGOTIATION_FAILED));
bnc5452e2a2015-05-08 16:27:4214391}
14392
bnc40448a532015-05-11 19:13:1414393// A request to a server with an alternative service fires two Jobs: one to the
zhongyi3d4a55e72016-04-22 20:36:4614394// server, and an alternate one to the alternative server. If the former
bnc40448a532015-05-11 19:13:1414395// succeeds, the request should succeed, even if the latter fails because
14396// HTTP/1.1 is negotiated which is insufficient for alternative service.
bncd16676a2016-07-20 16:23:0114397TEST_F(HttpNetworkTransactionTest, FailedAlternativeServiceIsNotUserVisible) {
bnc8bef8da22016-05-30 01:28:2514398 url::SchemeHostPort server("https", "www.example.org", 443);
14399 HostPortPair alternative("www.example.org", 444);
bnc40448a532015-05-11 19:13:1414400
14401 // Negotiate HTTP/1.1 with alternative.
14402 SSLSocketDataProvider alternative_ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3614403 alternative_ssl.next_proto = kProtoHTTP11;
bnc40448a532015-05-11 19:13:1414404 session_deps_.socket_factory->AddSSLSocketDataProvider(&alternative_ssl);
14405
14406 // No data should be read from the alternative, because HTTP/1.1 is
14407 // negotiated.
14408 StaticSocketDataProvider data;
14409 session_deps_.socket_factory->AddSocketDataProvider(&data);
14410
zhongyi3d4a55e72016-04-22 20:36:4614411 // Negotiate HTTP/1.1 with server.
bnc40448a532015-05-11 19:13:1414412 SSLSocketDataProvider origin_ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3614413 origin_ssl.next_proto = kProtoHTTP11;
bnc40448a532015-05-11 19:13:1414414 session_deps_.socket_factory->AddSSLSocketDataProvider(&origin_ssl);
14415
14416 MockWrite http_writes[] = {
bnc8bef8da22016-05-30 01:28:2514417 MockWrite("GET / HTTP/1.1\r\n"
14418 "Host: www.example.org\r\n"
14419 "Connection: keep-alive\r\n\r\n"),
14420 MockWrite("GET /second HTTP/1.1\r\n"
14421 "Host: www.example.org\r\n"
14422 "Connection: keep-alive\r\n\r\n"),
bnc40448a532015-05-11 19:13:1414423 };
14424
14425 MockRead http_reads[] = {
14426 MockRead("HTTP/1.1 200 OK\r\n"),
14427 MockRead("Content-Type: text/html\r\n"),
14428 MockRead("Content-Length: 6\r\n\r\n"),
14429 MockRead("foobar"),
14430 MockRead("HTTP/1.1 200 OK\r\n"),
14431 MockRead("Content-Type: text/html\r\n"),
14432 MockRead("Content-Length: 7\r\n\r\n"),
14433 MockRead("another"),
14434 };
14435 StaticSocketDataProvider http_data(http_reads, arraysize(http_reads),
14436 http_writes, arraysize(http_writes));
14437 session_deps_.socket_factory->AddSocketDataProvider(&http_data);
14438
zhongyi3d4a55e72016-04-22 20:36:4614439 // Set up alternative service for server.
danakj1fd259a02016-04-16 03:17:0914440 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc525e175a2016-06-20 12:36:4014441 HttpServerProperties* http_server_properties =
bnc40448a532015-05-11 19:13:1414442 session->http_server_properties();
bnc3472afd2016-11-17 15:27:2114443 AlternativeService alternative_service(kProtoHTTP2, alternative);
bnc7dc7e1b42015-07-28 14:43:1214444 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:2114445 http_server_properties->SetHttp2AlternativeService(
14446 server, alternative_service, expiration);
bnc40448a532015-05-11 19:13:1414447
14448 HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
14449 HttpRequestInfo request1;
14450 request1.method = "GET";
bnc8bef8da22016-05-30 01:28:2514451 request1.url = GURL("https://www.example.org:443");
bnc40448a532015-05-11 19:13:1414452 request1.load_flags = 0;
14453 TestCompletionCallback callback1;
14454
tfarina42834112016-09-22 13:38:2014455 int rv = trans1.Start(&request1, callback1.callback(), NetLogWithSource());
bnc40448a532015-05-11 19:13:1414456 rv = callback1.GetResult(rv);
robpercival214763f2016-07-01 23:27:0114457 EXPECT_THAT(rv, IsOk());
bnc40448a532015-05-11 19:13:1414458
14459 const HttpResponseInfo* response1 = trans1.GetResponseInfo();
wezca1070932016-05-26 20:30:5214460 ASSERT_TRUE(response1);
14461 ASSERT_TRUE(response1->headers);
bnc40448a532015-05-11 19:13:1414462 EXPECT_EQ("HTTP/1.1 200 OK", response1->headers->GetStatusLine());
14463
14464 std::string response_data1;
robpercival214763f2016-07-01 23:27:0114465 ASSERT_THAT(ReadTransaction(&trans1, &response_data1), IsOk());
bnc40448a532015-05-11 19:13:1414466 EXPECT_EQ("foobar", response_data1);
14467
14468 // Alternative should be marked as broken, because HTTP/1.1 is not sufficient
14469 // for alternative service.
14470 EXPECT_TRUE(
14471 http_server_properties->IsAlternativeServiceBroken(alternative_service));
14472
zhongyi3d4a55e72016-04-22 20:36:4614473 // Since |alternative_service| is broken, a second transaction to server
bnc40448a532015-05-11 19:13:1414474 // should not start an alternate Job. It should pool to existing connection
zhongyi3d4a55e72016-04-22 20:36:4614475 // to server.
bnc40448a532015-05-11 19:13:1414476 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
14477 HttpRequestInfo request2;
14478 request2.method = "GET";
bnc8bef8da22016-05-30 01:28:2514479 request2.url = GURL("https://www.example.org:443/second");
bnc40448a532015-05-11 19:13:1414480 request2.load_flags = 0;
14481 TestCompletionCallback callback2;
14482
tfarina42834112016-09-22 13:38:2014483 rv = trans2.Start(&request2, callback2.callback(), NetLogWithSource());
bnc40448a532015-05-11 19:13:1414484 rv = callback2.GetResult(rv);
robpercival214763f2016-07-01 23:27:0114485 EXPECT_THAT(rv, IsOk());
bnc40448a532015-05-11 19:13:1414486
14487 const HttpResponseInfo* response2 = trans2.GetResponseInfo();
wezca1070932016-05-26 20:30:5214488 ASSERT_TRUE(response2);
14489 ASSERT_TRUE(response2->headers);
bnc40448a532015-05-11 19:13:1414490 EXPECT_EQ("HTTP/1.1 200 OK", response2->headers->GetStatusLine());
14491
14492 std::string response_data2;
robpercival214763f2016-07-01 23:27:0114493 ASSERT_THAT(ReadTransaction(&trans2, &response_data2), IsOk());
bnc40448a532015-05-11 19:13:1414494 EXPECT_EQ("another", response_data2);
14495}
14496
bnc5452e2a2015-05-08 16:27:4214497// Alternative service requires HTTP/2 (or SPDY), but there is already a
14498// HTTP/1.1 socket open to the alternative server. That socket should not be
14499// used.
bncd16676a2016-07-20 16:23:0114500TEST_F(HttpNetworkTransactionTest, AlternativeServiceShouldNotPoolToHttp11) {
zhongyi3d4a55e72016-04-22 20:36:4614501 url::SchemeHostPort server("https", "origin.example.org", 443);
bnc5452e2a2015-05-08 16:27:4214502 HostPortPair alternative("alternative.example.org", 443);
14503 std::string origin_url = "https://origin.example.org:443";
14504 std::string alternative_url = "https://alternative.example.org:443";
14505
14506 // Negotiate HTTP/1.1 with alternative.example.org.
14507 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3614508 ssl.next_proto = kProtoHTTP11;
bnc5452e2a2015-05-08 16:27:4214509 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
14510
14511 // HTTP/1.1 data for |request1| and |request2|.
14512 MockWrite http_writes[] = {
14513 MockWrite(
14514 "GET / HTTP/1.1\r\n"
14515 "Host: alternative.example.org\r\n"
14516 "Connection: keep-alive\r\n\r\n"),
14517 MockWrite(
14518 "GET / HTTP/1.1\r\n"
14519 "Host: alternative.example.org\r\n"
14520 "Connection: keep-alive\r\n\r\n"),
14521 };
14522
14523 MockRead http_reads[] = {
14524 MockRead(
14525 "HTTP/1.1 200 OK\r\n"
14526 "Content-Type: text/html; charset=iso-8859-1\r\n"
14527 "Content-Length: 40\r\n\r\n"
14528 "first HTTP/1.1 response from alternative"),
14529 MockRead(
14530 "HTTP/1.1 200 OK\r\n"
14531 "Content-Type: text/html; charset=iso-8859-1\r\n"
14532 "Content-Length: 41\r\n\r\n"
14533 "second HTTP/1.1 response from alternative"),
14534 };
14535 StaticSocketDataProvider http_data(http_reads, arraysize(http_reads),
14536 http_writes, arraysize(http_writes));
14537 session_deps_.socket_factory->AddSocketDataProvider(&http_data);
14538
14539 // This test documents that an alternate Job should not pool to an already
14540 // existing HTTP/1.1 connection. In order to test this, a failed connection
zhongyi3d4a55e72016-04-22 20:36:4614541 // to the server is mocked. This way |request2| relies on the alternate Job.
bnc5452e2a2015-05-08 16:27:4214542 StaticSocketDataProvider data_refused;
14543 data_refused.set_connect_data(MockConnect(ASYNC, ERR_CONNECTION_REFUSED));
14544 session_deps_.socket_factory->AddSocketDataProvider(&data_refused);
14545
zhongyi3d4a55e72016-04-22 20:36:4614546 // Set up alternative service for server.
danakj1fd259a02016-04-16 03:17:0914547 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc525e175a2016-06-20 12:36:4014548 HttpServerProperties* http_server_properties =
bnc5452e2a2015-05-08 16:27:4214549 session->http_server_properties();
bnc3472afd2016-11-17 15:27:2114550 AlternativeService alternative_service(kProtoHTTP2, alternative);
bnc7dc7e1b42015-07-28 14:43:1214551 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:2114552 http_server_properties->SetHttp2AlternativeService(
14553 server, alternative_service, expiration);
bnc5452e2a2015-05-08 16:27:4214554
14555 // First transaction to alternative to open an HTTP/1.1 socket.
bnc5452e2a2015-05-08 16:27:4214556 HttpRequestInfo request1;
krasinc06a72a2016-12-21 03:42:4614557 HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
bnc5452e2a2015-05-08 16:27:4214558 request1.method = "GET";
14559 request1.url = GURL(alternative_url);
14560 request1.load_flags = 0;
14561 TestCompletionCallback callback1;
14562
tfarina42834112016-09-22 13:38:2014563 int rv = trans1.Start(&request1, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0114564 EXPECT_THAT(callback1.GetResult(rv), IsOk());
bnc691fda62016-08-12 00:43:1614565 const HttpResponseInfo* response1 = trans1.GetResponseInfo();
bnc5452e2a2015-05-08 16:27:4214566 ASSERT_TRUE(response1);
wezca1070932016-05-26 20:30:5214567 ASSERT_TRUE(response1->headers);
bnc5452e2a2015-05-08 16:27:4214568 EXPECT_EQ("HTTP/1.1 200 OK", response1->headers->GetStatusLine());
bnc94c92842016-09-21 15:22:5214569 EXPECT_TRUE(response1->was_alpn_negotiated);
bnc5452e2a2015-05-08 16:27:4214570 EXPECT_FALSE(response1->was_fetched_via_spdy);
14571 std::string response_data1;
bnc691fda62016-08-12 00:43:1614572 ASSERT_THAT(ReadTransaction(&trans1, &response_data1), IsOk());
bnc5452e2a2015-05-08 16:27:4214573 EXPECT_EQ("first HTTP/1.1 response from alternative", response_data1);
14574
14575 // Request for origin.example.org, which has an alternative service. This
14576 // will start two Jobs: the alternative looks for connections to pool to,
14577 // finds one which is HTTP/1.1, and should ignore it, and should not try to
zhongyi3d4a55e72016-04-22 20:36:4614578 // open other connections to alternative server. The Job to server fails, so
bnc5452e2a2015-05-08 16:27:4214579 // this request fails.
bnc5452e2a2015-05-08 16:27:4214580 HttpRequestInfo request2;
krasinc06a72a2016-12-21 03:42:4614581 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
bnc5452e2a2015-05-08 16:27:4214582 request2.method = "GET";
14583 request2.url = GURL(origin_url);
14584 request2.load_flags = 0;
14585 TestCompletionCallback callback2;
14586
tfarina42834112016-09-22 13:38:2014587 rv = trans2.Start(&request2, callback2.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0114588 EXPECT_THAT(callback2.GetResult(rv), IsError(ERR_CONNECTION_REFUSED));
bnc5452e2a2015-05-08 16:27:4214589
14590 // Another transaction to alternative. This is to test that the HTTP/1.1
14591 // socket is still open and in the pool.
bnc5452e2a2015-05-08 16:27:4214592 HttpRequestInfo request3;
krasinc06a72a2016-12-21 03:42:4614593 HttpNetworkTransaction trans3(DEFAULT_PRIORITY, session.get());
bnc5452e2a2015-05-08 16:27:4214594 request3.method = "GET";
14595 request3.url = GURL(alternative_url);
14596 request3.load_flags = 0;
14597 TestCompletionCallback callback3;
14598
tfarina42834112016-09-22 13:38:2014599 rv = trans3.Start(&request3, callback3.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0114600 EXPECT_THAT(callback3.GetResult(rv), IsOk());
bnc691fda62016-08-12 00:43:1614601 const HttpResponseInfo* response3 = trans3.GetResponseInfo();
bnc5452e2a2015-05-08 16:27:4214602 ASSERT_TRUE(response3);
wezca1070932016-05-26 20:30:5214603 ASSERT_TRUE(response3->headers);
bnc5452e2a2015-05-08 16:27:4214604 EXPECT_EQ("HTTP/1.1 200 OK", response3->headers->GetStatusLine());
bnc94c92842016-09-21 15:22:5214605 EXPECT_TRUE(response3->was_alpn_negotiated);
bnc5452e2a2015-05-08 16:27:4214606 EXPECT_FALSE(response3->was_fetched_via_spdy);
14607 std::string response_data3;
bnc691fda62016-08-12 00:43:1614608 ASSERT_THAT(ReadTransaction(&trans3, &response_data3), IsOk());
bnc5452e2a2015-05-08 16:27:4214609 EXPECT_EQ("second HTTP/1.1 response from alternative", response_data3);
14610}
14611
bncd16676a2016-07-20 16:23:0114612TEST_F(HttpNetworkTransactionTest, DoNotUseSpdySessionForHttpOverTunnel) {
bncce36dca22015-04-21 22:11:2314613 const std::string https_url = "https://www.example.org:8080/";
14614 const std::string http_url = "http://www.example.org:8080/";
[email protected]8450d722012-07-02 19:14:0414615
rdsmithebb50aa2015-11-12 03:44:3814616 // Separate SPDY util instance for naked and wrapped requests.
bncd16676a2016-07-20 16:23:0114617 SpdyTestUtil spdy_util_wrapped;
rdsmithebb50aa2015-11-12 03:44:3814618
[email protected]8450d722012-07-02 19:14:0414619 // SPDY GET for HTTPS URL (through CONNECT tunnel)
bncce36dca22015-04-21 22:11:2314620 const HostPortPair host_port_pair("www.example.org", 8080);
bncdf80d44fd2016-07-15 20:27:4114621 SpdySerializedFrame connect(
lgarrona91df87f2014-12-05 00:51:3414622 spdy_util_.ConstructSpdyConnect(NULL, 0, 1, LOWEST, host_port_pair));
bncdf80d44fd2016-07-15 20:27:4114623 SpdySerializedFrame req1(
bnc38dcd392016-02-09 23:19:4914624 spdy_util_wrapped.ConstructSpdyGet(https_url.c_str(), 1, LOWEST));
bncdf80d44fd2016-07-15 20:27:4114625 SpdySerializedFrame wrapped_req1(
[email protected]23e482282013-06-14 16:08:0214626 spdy_util_.ConstructWrappedSpdyFrame(req1, 1));
[email protected]601e03f12014-04-06 16:26:3914627
14628 // SPDY GET for HTTP URL (through the proxy, but not the tunnel).
[email protected]745aa9c2014-06-27 02:21:2914629 SpdyHeaderBlock req2_block;
14630 req2_block[spdy_util_.GetMethodKey()] = "GET";
bncce36dca22015-04-21 22:11:2314631 req2_block[spdy_util_.GetHostKey()] = "www.example.org:8080";
[email protected]745aa9c2014-06-27 02:21:2914632 req2_block[spdy_util_.GetSchemeKey()] = "http";
bnc7ecc1122015-09-28 13:22:4914633 req2_block[spdy_util_.GetPathKey()] = "/";
bncdf80d44fd2016-07-15 20:27:4114634 SpdySerializedFrame req2(
bnc42331402016-07-25 13:36:1514635 spdy_util_.ConstructSpdyHeaders(3, std::move(req2_block), MEDIUM, true));
[email protected]8450d722012-07-02 19:14:0414636
14637 MockWrite writes1[] = {
bncdf80d44fd2016-07-15 20:27:4114638 CreateMockWrite(connect, 0), CreateMockWrite(wrapped_req1, 2),
14639 CreateMockWrite(req2, 6),
[email protected]8450d722012-07-02 19:14:0414640 };
14641
bncdf80d44fd2016-07-15 20:27:4114642 SpdySerializedFrame conn_resp(
bnc42331402016-07-25 13:36:1514643 spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
bncdf80d44fd2016-07-15 20:27:4114644 SpdySerializedFrame resp1(
bnc42331402016-07-25 13:36:1514645 spdy_util_wrapped.ConstructSpdyGetReply(nullptr, 0, 1));
bncdf80d44fd2016-07-15 20:27:4114646 SpdySerializedFrame body1(spdy_util_wrapped.ConstructSpdyDataFrame(1, true));
14647 SpdySerializedFrame wrapped_resp1(
rdsmithebb50aa2015-11-12 03:44:3814648 spdy_util_wrapped.ConstructWrappedSpdyFrame(resp1, 1));
bncdf80d44fd2016-07-15 20:27:4114649 SpdySerializedFrame wrapped_body1(
rdsmithebb50aa2015-11-12 03:44:3814650 spdy_util_wrapped.ConstructWrappedSpdyFrame(body1, 1));
bnc42331402016-07-25 13:36:1514651 SpdySerializedFrame resp2(spdy_util_.ConstructSpdyGetReply(NULL, 0, 3));
bncdf80d44fd2016-07-15 20:27:4114652 SpdySerializedFrame body2(spdy_util_.ConstructSpdyDataFrame(3, true));
mmenke666a6fea2015-12-19 04:16:3314653 MockRead reads1[] = {
bncdf80d44fd2016-07-15 20:27:4114654 CreateMockRead(conn_resp, 1),
mmenke666a6fea2015-12-19 04:16:3314655 MockRead(ASYNC, ERR_IO_PENDING, 3),
bncdf80d44fd2016-07-15 20:27:4114656 CreateMockRead(wrapped_resp1, 4),
14657 CreateMockRead(wrapped_body1, 5),
mmenke666a6fea2015-12-19 04:16:3314658 MockRead(ASYNC, ERR_IO_PENDING, 7),
bncdf80d44fd2016-07-15 20:27:4114659 CreateMockRead(resp2, 8),
14660 CreateMockRead(body2, 9),
mmenke666a6fea2015-12-19 04:16:3314661 MockRead(SYNCHRONOUS, ERR_IO_PENDING, 10),
14662 };
[email protected]8450d722012-07-02 19:14:0414663
mmenke666a6fea2015-12-19 04:16:3314664 SequencedSocketData data1(reads1, arraysize(reads1), writes1,
14665 arraysize(writes1));
[email protected]8450d722012-07-02 19:14:0414666 MockConnect connect_data1(ASYNC, OK);
[email protected]dd54bd82012-07-19 23:44:5714667 data1.set_connect_data(connect_data1);
[email protected]8450d722012-07-02 19:14:0414668
rdsmith82957ad2015-09-16 19:42:0314669 session_deps_.proxy_service =
14670 ProxyService::CreateFixedFromPacResult("HTTPS proxy:70");
vishal.b62985ca92015-04-17 08:45:5114671 TestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:0714672 session_deps_.net_log = &log;
[email protected]8450d722012-07-02 19:14:0414673 SSLSocketDataProvider ssl1(ASYNC, OK); // to the proxy
bnc3cf2a592016-08-11 14:48:3614674 ssl1.next_proto = kProtoHTTP2;
mmenke666a6fea2015-12-19 04:16:3314675 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl1);
[email protected]8450d722012-07-02 19:14:0414676 SSLSocketDataProvider ssl2(ASYNC, OK); // to the server
bnc3cf2a592016-08-11 14:48:3614677 ssl2.next_proto = kProtoHTTP2;
mmenke666a6fea2015-12-19 04:16:3314678 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
14679 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8450d722012-07-02 19:14:0414680
danakj1fd259a02016-04-16 03:17:0914681 std::unique_ptr<HttpNetworkSession> session = CreateSession(&session_deps_);
[email protected]8450d722012-07-02 19:14:0414682
14683 // Start the first transaction to set up the SpdySession
14684 HttpRequestInfo request1;
14685 request1.method = "GET";
14686 request1.url = GURL(https_url);
[email protected]8450d722012-07-02 19:14:0414687 request1.load_flags = 0;
[email protected]90499482013-06-01 00:39:5014688 HttpNetworkTransaction trans1(LOWEST, session.get());
[email protected]8450d722012-07-02 19:14:0414689 TestCompletionCallback callback1;
tfarina42834112016-09-22 13:38:2014690 int rv = trans1.Start(&request1, callback1.callback(), NetLogWithSource());
[email protected]8450d722012-07-02 19:14:0414691
mmenke666a6fea2015-12-19 04:16:3314692 // This pause is a hack to avoid running into https://crbug.com/497228.
14693 data1.RunUntilPaused();
14694 base::RunLoop().RunUntilIdle();
14695 data1.Resume();
robpercival214763f2016-07-01 23:27:0114696 EXPECT_THAT(callback1.GetResult(rv), IsOk());
[email protected]8450d722012-07-02 19:14:0414697 EXPECT_TRUE(trans1.GetResponseInfo()->was_fetched_via_spdy);
14698
[email protected]f6c63db52013-02-02 00:35:2214699 LoadTimingInfo load_timing_info1;
14700 EXPECT_TRUE(trans1.GetLoadTimingInfo(&load_timing_info1));
14701 TestLoadTimingNotReusedWithPac(load_timing_info1,
14702 CONNECT_TIMING_HAS_SSL_TIMES);
14703
mmenke666a6fea2015-12-19 04:16:3314704 // Now, start the HTTP request.
[email protected]8450d722012-07-02 19:14:0414705 HttpRequestInfo request2;
14706 request2.method = "GET";
14707 request2.url = GURL(http_url);
[email protected]8450d722012-07-02 19:14:0414708 request2.load_flags = 0;
[email protected]90499482013-06-01 00:39:5014709 HttpNetworkTransaction trans2(MEDIUM, session.get());
[email protected]8450d722012-07-02 19:14:0414710 TestCompletionCallback callback2;
tfarina42834112016-09-22 13:38:2014711 rv = trans2.Start(&request2, callback2.callback(), NetLogWithSource());
[email protected]8450d722012-07-02 19:14:0414712
mmenke666a6fea2015-12-19 04:16:3314713 // This pause is a hack to avoid running into https://crbug.com/497228.
14714 data1.RunUntilPaused();
14715 base::RunLoop().RunUntilIdle();
14716 data1.Resume();
robpercival214763f2016-07-01 23:27:0114717 EXPECT_THAT(callback2.GetResult(rv), IsOk());
mmenke666a6fea2015-12-19 04:16:3314718
[email protected]8450d722012-07-02 19:14:0414719 EXPECT_TRUE(trans2.GetResponseInfo()->was_fetched_via_spdy);
[email protected]f6c63db52013-02-02 00:35:2214720
14721 LoadTimingInfo load_timing_info2;
14722 EXPECT_TRUE(trans2.GetLoadTimingInfo(&load_timing_info2));
14723 // The established SPDY sessions is considered reused by the HTTP request.
14724 TestLoadTimingReusedWithPac(load_timing_info2);
14725 // HTTP requests over a SPDY session should have a different connection
14726 // socket_log_id than requests over a tunnel.
14727 EXPECT_NE(load_timing_info1.socket_log_id, load_timing_info2.socket_log_id);
[email protected]8450d722012-07-02 19:14:0414728}
14729
[email protected]2d88e7d2012-07-19 17:55:1714730// Test that in the case where we have a SPDY session to a SPDY proxy
14731// that we do not pool other origins that resolve to the same IP when
14732// the certificate does not match the new origin.
14733// http://crbug.com/134690
bncd16676a2016-07-20 16:23:0114734TEST_F(HttpNetworkTransactionTest, DoNotUseSpdySessionIfCertDoesNotMatch) {
bncce36dca22015-04-21 22:11:2314735 const std::string url1 = "http://www.example.org/";
14736 const std::string url2 = "https://news.example.org/";
[email protected]2d88e7d2012-07-19 17:55:1714737 const std::string ip_addr = "1.2.3.4";
14738
rdsmithebb50aa2015-11-12 03:44:3814739 // Second SpdyTestUtil instance for the second socket.
bncd16676a2016-07-20 16:23:0114740 SpdyTestUtil spdy_util_secure;
rdsmithebb50aa2015-11-12 03:44:3814741
[email protected]2d88e7d2012-07-19 17:55:1714742 // SPDY GET for HTTP URL (through SPDY proxy)
bnc086b39e12016-06-24 13:05:2614743 SpdyHeaderBlock headers(
bncce36dca22015-04-21 22:11:2314744 spdy_util_.ConstructGetHeaderBlockForProxy("http://www.example.org/"));
bncdf80d44fd2016-07-15 20:27:4114745 SpdySerializedFrame req1(
bnc42331402016-07-25 13:36:1514746 spdy_util_.ConstructSpdyHeaders(1, std::move(headers), LOWEST, true));
[email protected]2d88e7d2012-07-19 17:55:1714747
14748 MockWrite writes1[] = {
bncdf80d44fd2016-07-15 20:27:4114749 CreateMockWrite(req1, 0),
[email protected]2d88e7d2012-07-19 17:55:1714750 };
14751
bnc42331402016-07-25 13:36:1514752 SpdySerializedFrame resp1(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
bncdf80d44fd2016-07-15 20:27:4114753 SpdySerializedFrame body1(spdy_util_.ConstructSpdyDataFrame(1, true));
[email protected]2d88e7d2012-07-19 17:55:1714754 MockRead reads1[] = {
bncdf80d44fd2016-07-15 20:27:4114755 MockRead(ASYNC, ERR_IO_PENDING, 1), CreateMockRead(resp1, 2),
14756 CreateMockRead(body1, 3), MockRead(ASYNC, OK, 4), // EOF
[email protected]2d88e7d2012-07-19 17:55:1714757 };
14758
mmenke666a6fea2015-12-19 04:16:3314759 SequencedSocketData data1(reads1, arraysize(reads1), writes1,
14760 arraysize(writes1));
martijnfe9636e2016-02-06 14:33:3214761 IPAddress ip;
martijn654c8c42016-02-10 22:10:5914762 ASSERT_TRUE(ip.AssignFromIPLiteral(ip_addr));
[email protected]2d88e7d2012-07-19 17:55:1714763 IPEndPoint peer_addr = IPEndPoint(ip, 443);
14764 MockConnect connect_data1(ASYNC, OK, peer_addr);
mmenke666a6fea2015-12-19 04:16:3314765 data1.set_connect_data(connect_data1);
[email protected]2d88e7d2012-07-19 17:55:1714766
14767 // SPDY GET for HTTPS URL (direct)
bncdf80d44fd2016-07-15 20:27:4114768 SpdySerializedFrame req2(
bnc38dcd392016-02-09 23:19:4914769 spdy_util_secure.ConstructSpdyGet(url2.c_str(), 1, MEDIUM));
[email protected]2d88e7d2012-07-19 17:55:1714770
14771 MockWrite writes2[] = {
bncdf80d44fd2016-07-15 20:27:4114772 CreateMockWrite(req2, 0),
[email protected]2d88e7d2012-07-19 17:55:1714773 };
14774
bnc42331402016-07-25 13:36:1514775 SpdySerializedFrame resp2(spdy_util_secure.ConstructSpdyGetReply(NULL, 0, 1));
bncdf80d44fd2016-07-15 20:27:4114776 SpdySerializedFrame body2(spdy_util_secure.ConstructSpdyDataFrame(1, true));
14777 MockRead reads2[] = {CreateMockRead(resp2, 1), CreateMockRead(body2, 2),
mmenke666a6fea2015-12-19 04:16:3314778 MockRead(ASYNC, OK, 3)};
[email protected]2d88e7d2012-07-19 17:55:1714779
mmenke666a6fea2015-12-19 04:16:3314780 SequencedSocketData data2(reads2, arraysize(reads2), writes2,
14781 arraysize(writes2));
[email protected]2d88e7d2012-07-19 17:55:1714782 MockConnect connect_data2(ASYNC, OK);
mmenke666a6fea2015-12-19 04:16:3314783 data2.set_connect_data(connect_data2);
[email protected]2d88e7d2012-07-19 17:55:1714784
14785 // Set up a proxy config that sends HTTP requests to a proxy, and
14786 // all others direct.
14787 ProxyConfig proxy_config;
14788 proxy_config.proxy_rules().ParseFromString("http=https://proxy:443");
Jeremy Roman0579ed62017-08-29 15:56:1914789 session_deps_.proxy_service = std::make_unique<ProxyService>(
14790 std::make_unique<ProxyConfigServiceFixed>(proxy_config), nullptr,
bnc87dcefc2017-05-25 12:47:5814791 nullptr);
[email protected]2d88e7d2012-07-19 17:55:1714792
bncce36dca22015-04-21 22:11:2314793 SSLSocketDataProvider ssl1(ASYNC, OK); // to the proxy
bnc3cf2a592016-08-11 14:48:3614794 ssl1.next_proto = kProtoHTTP2;
[email protected]2d88e7d2012-07-19 17:55:1714795 // Load a valid cert. Note, that this does not need to
14796 // be valid for proxy because the MockSSLClientSocket does
14797 // not actually verify it. But SpdySession will use this
14798 // to see if it is valid for the new origin
bncce36dca22015-04-21 22:11:2314799 ssl1.cert = ImportCertFromFile(GetTestCertsDirectory(), "ok_cert.pem");
wezca1070932016-05-26 20:30:5214800 ASSERT_TRUE(ssl1.cert);
mmenke666a6fea2015-12-19 04:16:3314801 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl1);
14802 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]2d88e7d2012-07-19 17:55:1714803
14804 SSLSocketDataProvider ssl2(ASYNC, OK); // to the server
bnc3cf2a592016-08-11 14:48:3614805 ssl2.next_proto = kProtoHTTP2;
mmenke666a6fea2015-12-19 04:16:3314806 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
14807 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]2d88e7d2012-07-19 17:55:1714808
Jeremy Roman0579ed62017-08-29 15:56:1914809 session_deps_.host_resolver = std::make_unique<MockCachingHostResolver>();
bncce36dca22015-04-21 22:11:2314810 session_deps_.host_resolver->rules()->AddRule("news.example.org", ip_addr);
[email protected]bb88e1d32013-05-03 23:11:0714811 session_deps_.host_resolver->rules()->AddRule("proxy", ip_addr);
[email protected]2d88e7d2012-07-19 17:55:1714812
danakj1fd259a02016-04-16 03:17:0914813 std::unique_ptr<HttpNetworkSession> session = CreateSession(&session_deps_);
[email protected]2d88e7d2012-07-19 17:55:1714814
14815 // Start the first transaction to set up the SpdySession
14816 HttpRequestInfo request1;
14817 request1.method = "GET";
14818 request1.url = GURL(url1);
[email protected]2d88e7d2012-07-19 17:55:1714819 request1.load_flags = 0;
[email protected]90499482013-06-01 00:39:5014820 HttpNetworkTransaction trans1(LOWEST, session.get());
[email protected]2d88e7d2012-07-19 17:55:1714821 TestCompletionCallback callback1;
14822 ASSERT_EQ(ERR_IO_PENDING,
tfarina42834112016-09-22 13:38:2014823 trans1.Start(&request1, callback1.callback(), NetLogWithSource()));
mmenke666a6fea2015-12-19 04:16:3314824 // This pause is a hack to avoid running into https://crbug.com/497228.
14825 data1.RunUntilPaused();
14826 base::RunLoop().RunUntilIdle();
14827 data1.Resume();
[email protected]2d88e7d2012-07-19 17:55:1714828
robpercival214763f2016-07-01 23:27:0114829 EXPECT_THAT(callback1.WaitForResult(), IsOk());
[email protected]2d88e7d2012-07-19 17:55:1714830 EXPECT_TRUE(trans1.GetResponseInfo()->was_fetched_via_spdy);
14831
14832 // Now, start the HTTP request
14833 HttpRequestInfo request2;
14834 request2.method = "GET";
14835 request2.url = GURL(url2);
[email protected]2d88e7d2012-07-19 17:55:1714836 request2.load_flags = 0;
[email protected]90499482013-06-01 00:39:5014837 HttpNetworkTransaction trans2(MEDIUM, session.get());
[email protected]2d88e7d2012-07-19 17:55:1714838 TestCompletionCallback callback2;
14839 EXPECT_EQ(ERR_IO_PENDING,
tfarina42834112016-09-22 13:38:2014840 trans2.Start(&request2, callback2.callback(), NetLogWithSource()));
fdoray92e35a72016-06-10 15:54:5514841 base::RunLoop().RunUntilIdle();
[email protected]2d88e7d2012-07-19 17:55:1714842
14843 ASSERT_TRUE(callback2.have_result());
robpercival214763f2016-07-01 23:27:0114844 EXPECT_THAT(callback2.WaitForResult(), IsOk());
[email protected]2d88e7d2012-07-19 17:55:1714845 EXPECT_TRUE(trans2.GetResponseInfo()->was_fetched_via_spdy);
14846}
14847
[email protected]85f97342013-04-17 06:12:2414848// Test to verify that a failed socket read (due to an ERR_CONNECTION_CLOSED
14849// error) in SPDY session, removes the socket from pool and closes the SPDY
14850// session. Verify that new url's from the same HttpNetworkSession (and a new
14851// SpdySession) do work. http://crbug.com/224701
bncd16676a2016-07-20 16:23:0114852TEST_F(HttpNetworkTransactionTest, ErrorSocketNotConnected) {
bncce36dca22015-04-21 22:11:2314853 const std::string https_url = "https://www.example.org/";
[email protected]85f97342013-04-17 06:12:2414854
14855 MockRead reads1[] = {
14856 MockRead(SYNCHRONOUS, ERR_CONNECTION_CLOSED, 0)
14857 };
14858
mmenke11eb5152015-06-09 14:50:5014859 SequencedSocketData data1(reads1, arraysize(reads1), NULL, 0);
[email protected]85f97342013-04-17 06:12:2414860
bncdf80d44fd2016-07-15 20:27:4114861 SpdySerializedFrame req2(
bnc38dcd392016-02-09 23:19:4914862 spdy_util_.ConstructSpdyGet(https_url.c_str(), 1, MEDIUM));
[email protected]85f97342013-04-17 06:12:2414863 MockWrite writes2[] = {
bncdf80d44fd2016-07-15 20:27:4114864 CreateMockWrite(req2, 0),
[email protected]85f97342013-04-17 06:12:2414865 };
14866
bnc42331402016-07-25 13:36:1514867 SpdySerializedFrame resp2(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
bncdf80d44fd2016-07-15 20:27:4114868 SpdySerializedFrame body2(spdy_util_.ConstructSpdyDataFrame(1, true));
[email protected]85f97342013-04-17 06:12:2414869 MockRead reads2[] = {
bncdf80d44fd2016-07-15 20:27:4114870 CreateMockRead(resp2, 1), CreateMockRead(body2, 2),
14871 MockRead(ASYNC, OK, 3) // EOF
[email protected]85f97342013-04-17 06:12:2414872 };
14873
mmenke11eb5152015-06-09 14:50:5014874 SequencedSocketData data2(reads2, arraysize(reads2), writes2,
14875 arraysize(writes2));
[email protected]85f97342013-04-17 06:12:2414876
[email protected]85f97342013-04-17 06:12:2414877 SSLSocketDataProvider ssl1(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3614878 ssl1.next_proto = kProtoHTTP2;
mmenke11eb5152015-06-09 14:50:5014879 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl1);
14880 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]85f97342013-04-17 06:12:2414881
14882 SSLSocketDataProvider ssl2(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3614883 ssl2.next_proto = kProtoHTTP2;
mmenke11eb5152015-06-09 14:50:5014884 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
14885 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]85f97342013-04-17 06:12:2414886
danakj1fd259a02016-04-16 03:17:0914887 std::unique_ptr<HttpNetworkSession> session(
mmenke11eb5152015-06-09 14:50:5014888 SpdySessionDependencies::SpdyCreateSession(&session_deps_));
[email protected]85f97342013-04-17 06:12:2414889
14890 // Start the first transaction to set up the SpdySession and verify that
14891 // connection was closed.
14892 HttpRequestInfo request1;
14893 request1.method = "GET";
14894 request1.url = GURL(https_url);
14895 request1.load_flags = 0;
[email protected]90499482013-06-01 00:39:5014896 HttpNetworkTransaction trans1(MEDIUM, session.get());
[email protected]85f97342013-04-17 06:12:2414897 TestCompletionCallback callback1;
14898 EXPECT_EQ(ERR_IO_PENDING,
tfarina42834112016-09-22 13:38:2014899 trans1.Start(&request1, callback1.callback(), NetLogWithSource()));
robpercival214763f2016-07-01 23:27:0114900 EXPECT_THAT(callback1.WaitForResult(), IsError(ERR_CONNECTION_CLOSED));
[email protected]85f97342013-04-17 06:12:2414901
14902 // Now, start the second request and make sure it succeeds.
14903 HttpRequestInfo request2;
14904 request2.method = "GET";
14905 request2.url = GURL(https_url);
14906 request2.load_flags = 0;
[email protected]90499482013-06-01 00:39:5014907 HttpNetworkTransaction trans2(MEDIUM, session.get());
[email protected]85f97342013-04-17 06:12:2414908 TestCompletionCallback callback2;
14909 EXPECT_EQ(ERR_IO_PENDING,
tfarina42834112016-09-22 13:38:2014910 trans2.Start(&request2, callback2.callback(), NetLogWithSource()));
[email protected]85f97342013-04-17 06:12:2414911
robpercival214763f2016-07-01 23:27:0114912 ASSERT_THAT(callback2.WaitForResult(), IsOk());
[email protected]85f97342013-04-17 06:12:2414913 EXPECT_TRUE(trans2.GetResponseInfo()->was_fetched_via_spdy);
14914}
14915
bncd16676a2016-07-20 16:23:0114916TEST_F(HttpNetworkTransactionTest, CloseIdleSpdySessionToOpenNewOne) {
[email protected]483fa202013-05-14 01:07:0314917 ClientSocketPoolManager::set_max_sockets_per_group(
14918 HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
14919 ClientSocketPoolManager::set_max_sockets_per_pool(
14920 HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
14921
14922 // Use two different hosts with different IPs so they don't get pooled.
14923 session_deps_.host_resolver->rules()->AddRule("www.a.com", "10.0.0.1");
14924 session_deps_.host_resolver->rules()->AddRule("www.b.com", "10.0.0.2");
danakj1fd259a02016-04-16 03:17:0914925 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]483fa202013-05-14 01:07:0314926
14927 SSLSocketDataProvider ssl1(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3614928 ssl1.next_proto = kProtoHTTP2;
[email protected]483fa202013-05-14 01:07:0314929 SSLSocketDataProvider ssl2(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3614930 ssl2.next_proto = kProtoHTTP2;
[email protected]483fa202013-05-14 01:07:0314931 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl1);
14932 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
14933
bncdf80d44fd2016-07-15 20:27:4114934 SpdySerializedFrame host1_req(
bnc38dcd392016-02-09 23:19:4914935 spdy_util_.ConstructSpdyGet("https://www.a.com", 1, DEFAULT_PRIORITY));
[email protected]483fa202013-05-14 01:07:0314936 MockWrite spdy1_writes[] = {
bncdf80d44fd2016-07-15 20:27:4114937 CreateMockWrite(host1_req, 0),
[email protected]483fa202013-05-14 01:07:0314938 };
bnc42331402016-07-25 13:36:1514939 SpdySerializedFrame host1_resp(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
bncdf80d44fd2016-07-15 20:27:4114940 SpdySerializedFrame host1_resp_body(
14941 spdy_util_.ConstructSpdyDataFrame(1, true));
[email protected]483fa202013-05-14 01:07:0314942 MockRead spdy1_reads[] = {
bncdf80d44fd2016-07-15 20:27:4114943 CreateMockRead(host1_resp, 1), CreateMockRead(host1_resp_body, 2),
mmenkee24011922015-12-17 22:12:5914944 MockRead(SYNCHRONOUS, ERR_IO_PENDING, 3),
[email protected]483fa202013-05-14 01:07:0314945 };
14946
rdsmithebb50aa2015-11-12 03:44:3814947 // Use a separate test instance for the separate SpdySession that will be
14948 // created.
bncd16676a2016-07-20 16:23:0114949 SpdyTestUtil spdy_util_2;
Jeremy Roman0579ed62017-08-29 15:56:1914950 auto spdy1_data = std::make_unique<SequencedSocketData>(
bnc87dcefc2017-05-25 12:47:5814951 spdy1_reads, arraysize(spdy1_reads), spdy1_writes,
14952 arraysize(spdy1_writes));
[email protected]483fa202013-05-14 01:07:0314953 session_deps_.socket_factory->AddSocketDataProvider(spdy1_data.get());
14954
bncdf80d44fd2016-07-15 20:27:4114955 SpdySerializedFrame host2_req(
bnc38dcd392016-02-09 23:19:4914956 spdy_util_2.ConstructSpdyGet("https://www.b.com", 1, DEFAULT_PRIORITY));
[email protected]483fa202013-05-14 01:07:0314957 MockWrite spdy2_writes[] = {
bncdf80d44fd2016-07-15 20:27:4114958 CreateMockWrite(host2_req, 0),
[email protected]483fa202013-05-14 01:07:0314959 };
bnc42331402016-07-25 13:36:1514960 SpdySerializedFrame host2_resp(spdy_util_2.ConstructSpdyGetReply(NULL, 0, 1));
bncdf80d44fd2016-07-15 20:27:4114961 SpdySerializedFrame host2_resp_body(
14962 spdy_util_2.ConstructSpdyDataFrame(1, true));
[email protected]483fa202013-05-14 01:07:0314963 MockRead spdy2_reads[] = {
bncdf80d44fd2016-07-15 20:27:4114964 CreateMockRead(host2_resp, 1), CreateMockRead(host2_resp_body, 2),
mmenkee24011922015-12-17 22:12:5914965 MockRead(SYNCHRONOUS, ERR_IO_PENDING, 3),
[email protected]483fa202013-05-14 01:07:0314966 };
14967
Jeremy Roman0579ed62017-08-29 15:56:1914968 auto spdy2_data = std::make_unique<SequencedSocketData>(
bnc87dcefc2017-05-25 12:47:5814969 spdy2_reads, arraysize(spdy2_reads), spdy2_writes,
14970 arraysize(spdy2_writes));
[email protected]483fa202013-05-14 01:07:0314971 session_deps_.socket_factory->AddSocketDataProvider(spdy2_data.get());
14972
14973 MockWrite http_write[] = {
14974 MockWrite("GET / HTTP/1.1\r\n"
14975 "Host: www.a.com\r\n"
14976 "Connection: keep-alive\r\n\r\n"),
14977 };
14978
14979 MockRead http_read[] = {
14980 MockRead("HTTP/1.1 200 OK\r\n"),
14981 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
14982 MockRead("Content-Length: 6\r\n\r\n"),
14983 MockRead("hello!"),
14984 };
14985 StaticSocketDataProvider http_data(http_read, arraysize(http_read),
14986 http_write, arraysize(http_write));
14987 session_deps_.socket_factory->AddSocketDataProvider(&http_data);
14988
14989 HostPortPair host_port_pair_a("www.a.com", 443);
[email protected]e6d017652013-05-17 18:01:4014990 SpdySessionKey spdy_session_key_a(
[email protected]314b03992014-04-01 01:28:5314991 host_port_pair_a, ProxyServer::Direct(), PRIVACY_MODE_DISABLED);
[email protected]483fa202013-05-14 01:07:0314992 EXPECT_FALSE(
[email protected]41d64e82013-07-03 22:44:2614993 HasSpdySession(session->spdy_session_pool(), spdy_session_key_a));
[email protected]483fa202013-05-14 01:07:0314994
14995 TestCompletionCallback callback;
14996 HttpRequestInfo request1;
14997 request1.method = "GET";
14998 request1.url = GURL("https://www.a.com/");
14999 request1.load_flags = 0;
bnc87dcefc2017-05-25 12:47:5815000 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:1915001 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]483fa202013-05-14 01:07:0315002
tfarina42834112016-09-22 13:38:2015003 int rv = trans->Start(&request1, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0115004 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
15005 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]483fa202013-05-14 01:07:0315006
15007 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5215008 ASSERT_TRUE(response);
15009 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0215010 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]483fa202013-05-14 01:07:0315011 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5215012 EXPECT_TRUE(response->was_alpn_negotiated);
[email protected]483fa202013-05-14 01:07:0315013
15014 std::string response_data;
robpercival214763f2016-07-01 23:27:0115015 ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
[email protected]483fa202013-05-14 01:07:0315016 EXPECT_EQ("hello!", response_data);
15017 trans.reset();
15018 EXPECT_TRUE(
[email protected]41d64e82013-07-03 22:44:2615019 HasSpdySession(session->spdy_session_pool(), spdy_session_key_a));
[email protected]483fa202013-05-14 01:07:0315020
15021 HostPortPair host_port_pair_b("www.b.com", 443);
[email protected]e6d017652013-05-17 18:01:4015022 SpdySessionKey spdy_session_key_b(
[email protected]314b03992014-04-01 01:28:5315023 host_port_pair_b, ProxyServer::Direct(), PRIVACY_MODE_DISABLED);
[email protected]483fa202013-05-14 01:07:0315024 EXPECT_FALSE(
[email protected]41d64e82013-07-03 22:44:2615025 HasSpdySession(session->spdy_session_pool(), spdy_session_key_b));
[email protected]483fa202013-05-14 01:07:0315026 HttpRequestInfo request2;
15027 request2.method = "GET";
15028 request2.url = GURL("https://www.b.com/");
15029 request2.load_flags = 0;
bnc87dcefc2017-05-25 12:47:5815030 trans =
Jeremy Roman0579ed62017-08-29 15:56:1915031 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]483fa202013-05-14 01:07:0315032
tfarina42834112016-09-22 13:38:2015033 rv = trans->Start(&request2, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0115034 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
15035 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]483fa202013-05-14 01:07:0315036
15037 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5215038 ASSERT_TRUE(response);
15039 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0215040 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]483fa202013-05-14 01:07:0315041 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5215042 EXPECT_TRUE(response->was_alpn_negotiated);
robpercival214763f2016-07-01 23:27:0115043 ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
[email protected]483fa202013-05-14 01:07:0315044 EXPECT_EQ("hello!", response_data);
15045 EXPECT_FALSE(
[email protected]41d64e82013-07-03 22:44:2615046 HasSpdySession(session->spdy_session_pool(), spdy_session_key_a));
[email protected]483fa202013-05-14 01:07:0315047 EXPECT_TRUE(
[email protected]41d64e82013-07-03 22:44:2615048 HasSpdySession(session->spdy_session_pool(), spdy_session_key_b));
[email protected]483fa202013-05-14 01:07:0315049
15050 HostPortPair host_port_pair_a1("www.a.com", 80);
[email protected]e6d017652013-05-17 18:01:4015051 SpdySessionKey spdy_session_key_a1(
[email protected]314b03992014-04-01 01:28:5315052 host_port_pair_a1, ProxyServer::Direct(), PRIVACY_MODE_DISABLED);
[email protected]483fa202013-05-14 01:07:0315053 EXPECT_FALSE(
[email protected]41d64e82013-07-03 22:44:2615054 HasSpdySession(session->spdy_session_pool(), spdy_session_key_a1));
[email protected]483fa202013-05-14 01:07:0315055 HttpRequestInfo request3;
15056 request3.method = "GET";
15057 request3.url = GURL("http://www.a.com/");
15058 request3.load_flags = 0;
bnc87dcefc2017-05-25 12:47:5815059 trans =
Jeremy Roman0579ed62017-08-29 15:56:1915060 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]483fa202013-05-14 01:07:0315061
tfarina42834112016-09-22 13:38:2015062 rv = trans->Start(&request3, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0115063 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
15064 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]483fa202013-05-14 01:07:0315065
15066 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5215067 ASSERT_TRUE(response);
15068 ASSERT_TRUE(response->headers);
[email protected]483fa202013-05-14 01:07:0315069 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
15070 EXPECT_FALSE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5215071 EXPECT_FALSE(response->was_alpn_negotiated);
robpercival214763f2016-07-01 23:27:0115072 ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
[email protected]483fa202013-05-14 01:07:0315073 EXPECT_EQ("hello!", response_data);
15074 EXPECT_FALSE(
[email protected]41d64e82013-07-03 22:44:2615075 HasSpdySession(session->spdy_session_pool(), spdy_session_key_a));
[email protected]483fa202013-05-14 01:07:0315076 EXPECT_FALSE(
[email protected]41d64e82013-07-03 22:44:2615077 HasSpdySession(session->spdy_session_pool(), spdy_session_key_b));
[email protected]483fa202013-05-14 01:07:0315078}
15079
bncd16676a2016-07-20 16:23:0115080TEST_F(HttpNetworkTransactionTest, HttpSyncConnectError) {
[email protected]79e1fd62013-06-20 06:50:0415081 HttpRequestInfo request;
15082 request.method = "GET";
bncce36dca22015-04-21 22:11:2315083 request.url = GURL("http://www.example.org/");
[email protected]79e1fd62013-06-20 06:50:0415084
danakj1fd259a02016-04-16 03:17:0915085 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1615086 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]79e1fd62013-06-20 06:50:0415087
ttuttled9dbc652015-09-29 20:00:5915088 MockConnect mock_connect(SYNCHRONOUS, ERR_NAME_NOT_RESOLVED);
[email protected]79e1fd62013-06-20 06:50:0415089 StaticSocketDataProvider data;
15090 data.set_connect_data(mock_connect);
15091 session_deps_.socket_factory->AddSocketDataProvider(&data);
15092
15093 TestCompletionCallback callback;
15094
tfarina42834112016-09-22 13:38:2015095 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0115096 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]79e1fd62013-06-20 06:50:0415097
15098 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0115099 EXPECT_THAT(rv, IsError(ERR_NAME_NOT_RESOLVED));
[email protected]79e1fd62013-06-20 06:50:0415100
[email protected]79e1fd62013-06-20 06:50:0415101 // We don't care whether this succeeds or fails, but it shouldn't crash.
15102 HttpRequestHeaders request_headers;
bnc691fda62016-08-12 00:43:1615103 trans.GetFullRequestHeaders(&request_headers);
ttuttle1f2d7e92015-04-28 16:17:4715104
15105 ConnectionAttempts attempts;
bnc691fda62016-08-12 00:43:1615106 trans.GetConnectionAttempts(&attempts);
ttuttle1f2d7e92015-04-28 16:17:4715107 ASSERT_EQ(1u, attempts.size());
robpercival214763f2016-07-01 23:27:0115108 EXPECT_THAT(attempts[0].result, IsError(ERR_NAME_NOT_RESOLVED));
ttuttled9dbc652015-09-29 20:00:5915109
15110 IPEndPoint endpoint;
bnc691fda62016-08-12 00:43:1615111 EXPECT_FALSE(trans.GetRemoteEndpoint(&endpoint));
ttuttled9dbc652015-09-29 20:00:5915112 EXPECT_TRUE(endpoint.address().empty());
[email protected]79e1fd62013-06-20 06:50:0415113}
15114
bncd16676a2016-07-20 16:23:0115115TEST_F(HttpNetworkTransactionTest, HttpAsyncConnectError) {
[email protected]79e1fd62013-06-20 06:50:0415116 HttpRequestInfo request;
15117 request.method = "GET";
bncce36dca22015-04-21 22:11:2315118 request.url = GURL("http://www.example.org/");
[email protected]79e1fd62013-06-20 06:50:0415119
danakj1fd259a02016-04-16 03:17:0915120 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1615121 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]79e1fd62013-06-20 06:50:0415122
ttuttled9dbc652015-09-29 20:00:5915123 MockConnect mock_connect(ASYNC, ERR_NAME_NOT_RESOLVED);
[email protected]79e1fd62013-06-20 06:50:0415124 StaticSocketDataProvider data;
15125 data.set_connect_data(mock_connect);
15126 session_deps_.socket_factory->AddSocketDataProvider(&data);
15127
15128 TestCompletionCallback callback;
15129
tfarina42834112016-09-22 13:38:2015130 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0115131 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]79e1fd62013-06-20 06:50:0415132
15133 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0115134 EXPECT_THAT(rv, IsError(ERR_NAME_NOT_RESOLVED));
[email protected]79e1fd62013-06-20 06:50:0415135
[email protected]79e1fd62013-06-20 06:50:0415136 // We don't care whether this succeeds or fails, but it shouldn't crash.
15137 HttpRequestHeaders request_headers;
bnc691fda62016-08-12 00:43:1615138 trans.GetFullRequestHeaders(&request_headers);
ttuttle1f2d7e92015-04-28 16:17:4715139
15140 ConnectionAttempts attempts;
bnc691fda62016-08-12 00:43:1615141 trans.GetConnectionAttempts(&attempts);
ttuttle1f2d7e92015-04-28 16:17:4715142 ASSERT_EQ(1u, attempts.size());
robpercival214763f2016-07-01 23:27:0115143 EXPECT_THAT(attempts[0].result, IsError(ERR_NAME_NOT_RESOLVED));
ttuttled9dbc652015-09-29 20:00:5915144
15145 IPEndPoint endpoint;
bnc691fda62016-08-12 00:43:1615146 EXPECT_FALSE(trans.GetRemoteEndpoint(&endpoint));
ttuttled9dbc652015-09-29 20:00:5915147 EXPECT_TRUE(endpoint.address().empty());
[email protected]79e1fd62013-06-20 06:50:0415148}
15149
bncd16676a2016-07-20 16:23:0115150TEST_F(HttpNetworkTransactionTest, HttpSyncWriteError) {
[email protected]79e1fd62013-06-20 06:50:0415151 HttpRequestInfo request;
15152 request.method = "GET";
bncce36dca22015-04-21 22:11:2315153 request.url = GURL("http://www.example.org/");
[email protected]79e1fd62013-06-20 06:50:0415154
danakj1fd259a02016-04-16 03:17:0915155 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1615156 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]79e1fd62013-06-20 06:50:0415157
15158 MockWrite data_writes[] = {
15159 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
15160 };
15161 MockRead data_reads[] = {
15162 MockRead(SYNCHRONOUS, ERR_UNEXPECTED), // Should not be reached.
15163 };
15164
15165 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
15166 data_writes, arraysize(data_writes));
15167 session_deps_.socket_factory->AddSocketDataProvider(&data);
15168
15169 TestCompletionCallback callback;
15170
tfarina42834112016-09-22 13:38:2015171 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0115172 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]79e1fd62013-06-20 06:50:0415173
15174 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0115175 EXPECT_THAT(rv, IsError(ERR_CONNECTION_RESET));
[email protected]79e1fd62013-06-20 06:50:0415176
[email protected]79e1fd62013-06-20 06:50:0415177 HttpRequestHeaders request_headers;
bnc691fda62016-08-12 00:43:1615178 EXPECT_TRUE(trans.GetFullRequestHeaders(&request_headers));
[email protected]79e1fd62013-06-20 06:50:0415179 EXPECT_TRUE(request_headers.HasHeader("Host"));
15180}
15181
bncd16676a2016-07-20 16:23:0115182TEST_F(HttpNetworkTransactionTest, HttpAsyncWriteError) {
[email protected]79e1fd62013-06-20 06:50:0415183 HttpRequestInfo request;
15184 request.method = "GET";
bncce36dca22015-04-21 22:11:2315185 request.url = GURL("http://www.example.org/");
[email protected]79e1fd62013-06-20 06:50:0415186
danakj1fd259a02016-04-16 03:17:0915187 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1615188 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]79e1fd62013-06-20 06:50:0415189
15190 MockWrite data_writes[] = {
15191 MockWrite(ASYNC, ERR_CONNECTION_RESET),
15192 };
15193 MockRead data_reads[] = {
15194 MockRead(SYNCHRONOUS, ERR_UNEXPECTED), // Should not be reached.
15195 };
15196
15197 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
15198 data_writes, arraysize(data_writes));
15199 session_deps_.socket_factory->AddSocketDataProvider(&data);
15200
15201 TestCompletionCallback callback;
15202
tfarina42834112016-09-22 13:38:2015203 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0115204 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]79e1fd62013-06-20 06:50:0415205
15206 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0115207 EXPECT_THAT(rv, IsError(ERR_CONNECTION_RESET));
[email protected]79e1fd62013-06-20 06:50:0415208
[email protected]79e1fd62013-06-20 06:50:0415209 HttpRequestHeaders request_headers;
bnc691fda62016-08-12 00:43:1615210 EXPECT_TRUE(trans.GetFullRequestHeaders(&request_headers));
[email protected]79e1fd62013-06-20 06:50:0415211 EXPECT_TRUE(request_headers.HasHeader("Host"));
15212}
15213
bncd16676a2016-07-20 16:23:0115214TEST_F(HttpNetworkTransactionTest, HttpSyncReadError) {
[email protected]79e1fd62013-06-20 06:50:0415215 HttpRequestInfo request;
15216 request.method = "GET";
bncce36dca22015-04-21 22:11:2315217 request.url = GURL("http://www.example.org/");
[email protected]79e1fd62013-06-20 06:50:0415218
danakj1fd259a02016-04-16 03:17:0915219 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1615220 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]79e1fd62013-06-20 06:50:0415221
15222 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:2315223 MockWrite(
15224 "GET / HTTP/1.1\r\n"
15225 "Host: www.example.org\r\n"
15226 "Connection: keep-alive\r\n\r\n"),
[email protected]79e1fd62013-06-20 06:50:0415227 };
15228 MockRead data_reads[] = {
15229 MockRead(SYNCHRONOUS, ERR_CONNECTION_RESET),
15230 };
15231
15232 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
15233 data_writes, arraysize(data_writes));
15234 session_deps_.socket_factory->AddSocketDataProvider(&data);
15235
15236 TestCompletionCallback callback;
15237
tfarina42834112016-09-22 13:38:2015238 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0115239 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]79e1fd62013-06-20 06:50:0415240
15241 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0115242 EXPECT_THAT(rv, IsError(ERR_CONNECTION_RESET));
[email protected]79e1fd62013-06-20 06:50:0415243
[email protected]79e1fd62013-06-20 06:50:0415244 HttpRequestHeaders request_headers;
bnc691fda62016-08-12 00:43:1615245 EXPECT_TRUE(trans.GetFullRequestHeaders(&request_headers));
[email protected]79e1fd62013-06-20 06:50:0415246 EXPECT_TRUE(request_headers.HasHeader("Host"));
15247}
15248
bncd16676a2016-07-20 16:23:0115249TEST_F(HttpNetworkTransactionTest, HttpAsyncReadError) {
[email protected]79e1fd62013-06-20 06:50:0415250 HttpRequestInfo request;
15251 request.method = "GET";
bncce36dca22015-04-21 22:11:2315252 request.url = GURL("http://www.example.org/");
[email protected]79e1fd62013-06-20 06:50:0415253
danakj1fd259a02016-04-16 03:17:0915254 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1615255 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]79e1fd62013-06-20 06:50:0415256
15257 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:2315258 MockWrite(
15259 "GET / HTTP/1.1\r\n"
15260 "Host: www.example.org\r\n"
15261 "Connection: keep-alive\r\n\r\n"),
[email protected]79e1fd62013-06-20 06:50:0415262 };
15263 MockRead data_reads[] = {
15264 MockRead(ASYNC, ERR_CONNECTION_RESET),
15265 };
15266
15267 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
15268 data_writes, arraysize(data_writes));
15269 session_deps_.socket_factory->AddSocketDataProvider(&data);
15270
15271 TestCompletionCallback callback;
15272
tfarina42834112016-09-22 13:38:2015273 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0115274 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]79e1fd62013-06-20 06:50:0415275
15276 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0115277 EXPECT_THAT(rv, IsError(ERR_CONNECTION_RESET));
[email protected]79e1fd62013-06-20 06:50:0415278
[email protected]79e1fd62013-06-20 06:50:0415279 HttpRequestHeaders request_headers;
bnc691fda62016-08-12 00:43:1615280 EXPECT_TRUE(trans.GetFullRequestHeaders(&request_headers));
[email protected]79e1fd62013-06-20 06:50:0415281 EXPECT_TRUE(request_headers.HasHeader("Host"));
15282}
15283
bncd16676a2016-07-20 16:23:0115284TEST_F(HttpNetworkTransactionTest, GetFullRequestHeadersIncludesExtraHeader) {
[email protected]79e1fd62013-06-20 06:50:0415285 HttpRequestInfo request;
15286 request.method = "GET";
bncce36dca22015-04-21 22:11:2315287 request.url = GURL("http://www.example.org/");
[email protected]79e1fd62013-06-20 06:50:0415288 request.extra_headers.SetHeader("X-Foo", "bar");
15289
danakj1fd259a02016-04-16 03:17:0915290 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1615291 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]79e1fd62013-06-20 06:50:0415292
15293 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:2315294 MockWrite(
15295 "GET / HTTP/1.1\r\n"
15296 "Host: www.example.org\r\n"
15297 "Connection: keep-alive\r\n"
15298 "X-Foo: bar\r\n\r\n"),
[email protected]79e1fd62013-06-20 06:50:0415299 };
15300 MockRead data_reads[] = {
15301 MockRead("HTTP/1.1 200 OK\r\n"
15302 "Content-Length: 5\r\n\r\n"
15303 "hello"),
15304 MockRead(ASYNC, ERR_UNEXPECTED),
15305 };
15306
15307 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
15308 data_writes, arraysize(data_writes));
15309 session_deps_.socket_factory->AddSocketDataProvider(&data);
15310
15311 TestCompletionCallback callback;
15312
tfarina42834112016-09-22 13:38:2015313 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0115314 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]79e1fd62013-06-20 06:50:0415315
15316 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0115317 EXPECT_THAT(rv, IsOk());
[email protected]79e1fd62013-06-20 06:50:0415318
15319 HttpRequestHeaders request_headers;
bnc691fda62016-08-12 00:43:1615320 EXPECT_TRUE(trans.GetFullRequestHeaders(&request_headers));
[email protected]79e1fd62013-06-20 06:50:0415321 std::string foo;
15322 EXPECT_TRUE(request_headers.GetHeader("X-Foo", &foo));
15323 EXPECT_EQ("bar", foo);
15324}
15325
[email protected]bf828982013-08-14 18:01:4715326namespace {
15327
yhiranoa7e05bb2014-11-06 05:40:3915328// Fake HttpStream that simply records calls to SetPriority().
15329class FakeStream : public HttpStream,
[email protected]e86839fd2013-08-14 18:29:0315330 public base::SupportsWeakPtr<FakeStream> {
15331 public:
15332 explicit FakeStream(RequestPriority priority) : priority_(priority) {}
dchengb03027d2014-10-21 12:00:2015333 ~FakeStream() override {}
[email protected]e86839fd2013-08-14 18:29:0315334
15335 RequestPriority priority() const { return priority_; }
15336
dchengb03027d2014-10-21 12:00:2015337 int InitializeStream(const HttpRequestInfo* request_info,
15338 RequestPriority priority,
tfarina42834112016-09-22 13:38:2015339 const NetLogWithSource& net_log,
dchengb03027d2014-10-21 12:00:2015340 const CompletionCallback& callback) override {
[email protected]e86839fd2013-08-14 18:29:0315341 return ERR_IO_PENDING;
15342 }
15343
dchengb03027d2014-10-21 12:00:2015344 int SendRequest(const HttpRequestHeaders& request_headers,
15345 HttpResponseInfo* response,
15346 const CompletionCallback& callback) override {
[email protected]e86839fd2013-08-14 18:29:0315347 ADD_FAILURE();
15348 return ERR_UNEXPECTED;
15349 }
15350
dchengb03027d2014-10-21 12:00:2015351 int ReadResponseHeaders(const CompletionCallback& callback) override {
[email protected]e86839fd2013-08-14 18:29:0315352 ADD_FAILURE();
15353 return ERR_UNEXPECTED;
15354 }
15355
dchengb03027d2014-10-21 12:00:2015356 int ReadResponseBody(IOBuffer* buf,
15357 int buf_len,
15358 const CompletionCallback& callback) override {
[email protected]e86839fd2013-08-14 18:29:0315359 ADD_FAILURE();
15360 return ERR_UNEXPECTED;
15361 }
15362
dchengb03027d2014-10-21 12:00:2015363 void Close(bool not_reusable) override {}
[email protected]e86839fd2013-08-14 18:29:0315364
dchengb03027d2014-10-21 12:00:2015365 bool IsResponseBodyComplete() const override {
[email protected]e86839fd2013-08-14 18:29:0315366 ADD_FAILURE();
15367 return false;
15368 }
15369
dchengb03027d2014-10-21 12:00:2015370 bool IsConnectionReused() const override {
[email protected]e86839fd2013-08-14 18:29:0315371 ADD_FAILURE();
15372 return false;
15373 }
15374
dchengb03027d2014-10-21 12:00:2015375 void SetConnectionReused() override { ADD_FAILURE(); }
[email protected]e86839fd2013-08-14 18:29:0315376
mmenkebd84c392015-09-02 14:12:3415377 bool CanReuseConnection() const override { return false; }
[email protected]e86839fd2013-08-14 18:29:0315378
sclittle4de1bab92015-09-22 21:28:2415379 int64_t GetTotalReceivedBytes() const override {
[email protected]bc92bc972013-12-13 08:32:5915380 ADD_FAILURE();
15381 return 0;
15382 }
15383
sclittlebe1ccf62015-09-02 19:40:3615384 int64_t GetTotalSentBytes() const override {
15385 ADD_FAILURE();
15386 return 0;
15387 }
15388
dchengb03027d2014-10-21 12:00:2015389 bool GetLoadTimingInfo(LoadTimingInfo* load_timing_info) const override {
[email protected]e86839fd2013-08-14 18:29:0315390 ADD_FAILURE();
15391 return false;
15392 }
15393
rchcd379012017-04-12 21:53:3215394 bool GetAlternativeService(
15395 AlternativeService* alternative_service) const override {
15396 ADD_FAILURE();
15397 return false;
15398 }
15399
dchengb03027d2014-10-21 12:00:2015400 void GetSSLInfo(SSLInfo* ssl_info) override { ADD_FAILURE(); }
15401
15402 void GetSSLCertRequestInfo(SSLCertRequestInfo* cert_request_info) override {
[email protected]e86839fd2013-08-14 18:29:0315403 ADD_FAILURE();
15404 }
15405
ttuttled9dbc652015-09-29 20:00:5915406 bool GetRemoteEndpoint(IPEndPoint* endpoint) override { return false; }
15407
nharper78e6d2b2016-09-21 05:42:3515408 Error GetTokenBindingSignature(crypto::ECPrivateKey* key,
15409 TokenBindingType tb_type,
15410 std::vector<uint8_t>* out) override {
nharperb7441ef2016-01-25 23:54:1415411 ADD_FAILURE();
15412 return ERR_NOT_IMPLEMENTED;
15413 }
15414
dchengb03027d2014-10-21 12:00:2015415 void Drain(HttpNetworkSession* session) override { ADD_FAILURE(); }
[email protected]e86839fd2013-08-14 18:29:0315416
zhongyica364fbb2015-12-12 03:39:1215417 void PopulateNetErrorDetails(NetErrorDetails* details) override { return; }
15418
dchengb03027d2014-10-21 12:00:2015419 void SetPriority(RequestPriority priority) override { priority_ = priority; }
[email protected]e86839fd2013-08-14 18:29:0315420
yhiranoa7e05bb2014-11-06 05:40:3915421 HttpStream* RenewStreamForAuth() override { return NULL; }
15422
Andrey Kosyakov83a6eee2017-08-14 19:20:0415423 void SetRequestHeadersCallback(RequestHeadersCallback callback) override {}
15424
[email protected]e86839fd2013-08-14 18:29:0315425 private:
15426 RequestPriority priority_;
15427
15428 DISALLOW_COPY_AND_ASSIGN(FakeStream);
15429};
15430
15431// Fake HttpStreamRequest that simply records calls to SetPriority()
15432// and vends FakeStreams with its current priority.
[email protected]bf828982013-08-14 18:01:4715433class FakeStreamRequest : public HttpStreamRequest,
15434 public base::SupportsWeakPtr<FakeStreamRequest> {
15435 public:
[email protected]e86839fd2013-08-14 18:29:0315436 FakeStreamRequest(RequestPriority priority,
15437 HttpStreamRequest::Delegate* delegate)
15438 : priority_(priority),
[email protected]831e4a32013-11-14 02:14:4415439 delegate_(delegate),
15440 websocket_stream_create_helper_(NULL) {}
15441
15442 FakeStreamRequest(RequestPriority priority,
15443 HttpStreamRequest::Delegate* delegate,
15444 WebSocketHandshakeStreamBase::CreateHelper* create_helper)
15445 : priority_(priority),
15446 delegate_(delegate),
15447 websocket_stream_create_helper_(create_helper) {}
[email protected]e86839fd2013-08-14 18:29:0315448
dchengb03027d2014-10-21 12:00:2015449 ~FakeStreamRequest() override {}
[email protected]bf828982013-08-14 18:01:4715450
15451 RequestPriority priority() const { return priority_; }
15452
[email protected]831e4a32013-11-14 02:14:4415453 const WebSocketHandshakeStreamBase::CreateHelper*
15454 websocket_stream_create_helper() const {
15455 return websocket_stream_create_helper_;
15456 }
15457
[email protected]e86839fd2013-08-14 18:29:0315458 // Create a new FakeStream and pass it to the request's
15459 // delegate. Returns a weak pointer to the FakeStream.
15460 base::WeakPtr<FakeStream> FinishStreamRequest() {
Jeremy Roman0579ed62017-08-29 15:56:1915461 auto fake_stream = std::make_unique<FakeStream>(priority_);
[email protected]e86839fd2013-08-14 18:29:0315462 // Do this before calling OnStreamReady() as OnStreamReady() may
15463 // immediately delete |fake_stream|.
15464 base::WeakPtr<FakeStream> weak_stream = fake_stream->AsWeakPtr();
bnc5029f4632017-06-08 16:19:0015465 delegate_->OnStreamReady(SSLConfig(), ProxyInfo(), std::move(fake_stream));
[email protected]e86839fd2013-08-14 18:29:0315466 return weak_stream;
15467 }
15468
asanka681f02d2017-02-22 17:06:3915469 int RestartTunnelWithProxyAuth() override {
[email protected]bf828982013-08-14 18:01:4715470 ADD_FAILURE();
15471 return ERR_UNEXPECTED;
15472 }
15473
dchengb03027d2014-10-21 12:00:2015474 LoadState GetLoadState() const override {
[email protected]bf828982013-08-14 18:01:4715475 ADD_FAILURE();
15476 return LoadState();
15477 }
15478
dchengb03027d2014-10-21 12:00:2015479 void SetPriority(RequestPriority priority) override { priority_ = priority; }
[email protected]bf828982013-08-14 18:01:4715480
bnc94c92842016-09-21 15:22:5215481 bool was_alpn_negotiated() const override { return false; }
[email protected]bf828982013-08-14 18:01:4715482
bnc6227b26e2016-08-12 02:00:4315483 NextProto negotiated_protocol() const override { return kProtoUnknown; }
[email protected]bf828982013-08-14 18:01:4715484
dchengb03027d2014-10-21 12:00:2015485 bool using_spdy() const override { return false; }
[email protected]bf828982013-08-14 18:01:4715486
ttuttle1f2d7e92015-04-28 16:17:4715487 const ConnectionAttempts& connection_attempts() const override {
15488 static ConnectionAttempts no_attempts;
15489 return no_attempts;
15490 }
15491
[email protected]bf828982013-08-14 18:01:4715492 private:
15493 RequestPriority priority_;
[email protected]e86839fd2013-08-14 18:29:0315494 HttpStreamRequest::Delegate* const delegate_;
[email protected]831e4a32013-11-14 02:14:4415495 WebSocketHandshakeStreamBase::CreateHelper* websocket_stream_create_helper_;
[email protected]bf828982013-08-14 18:01:4715496
15497 DISALLOW_COPY_AND_ASSIGN(FakeStreamRequest);
15498};
15499
15500// Fake HttpStreamFactory that vends FakeStreamRequests.
15501class FakeStreamFactory : public HttpStreamFactory {
15502 public:
15503 FakeStreamFactory() {}
dchengb03027d2014-10-21 12:00:2015504 ~FakeStreamFactory() override {}
[email protected]bf828982013-08-14 18:01:4715505
15506 // Returns a WeakPtr<> to the last HttpStreamRequest returned by
15507 // RequestStream() (which may be NULL if it was destroyed already).
15508 base::WeakPtr<FakeStreamRequest> last_stream_request() {
15509 return last_stream_request_;
15510 }
15511
xunjieli96f2a402017-06-05 17:24:2715512 std::unique_ptr<HttpStreamRequest> RequestStream(
15513 const HttpRequestInfo& info,
15514 RequestPriority priority,
15515 const SSLConfig& server_ssl_config,
15516 const SSLConfig& proxy_ssl_config,
15517 HttpStreamRequest::Delegate* delegate,
15518 bool enable_ip_based_pooling,
15519 bool enable_alternative_services,
15520 const NetLogWithSource& net_log) override {
Jeremy Roman0579ed62017-08-29 15:56:1915521 auto fake_request = std::make_unique<FakeStreamRequest>(priority, delegate);
[email protected]bf828982013-08-14 18:01:4715522 last_stream_request_ = fake_request->AsWeakPtr();
xunjieli96f2a402017-06-05 17:24:2715523 return std::move(fake_request);
[email protected]bf828982013-08-14 18:01:4715524 }
15525
xunjieli96f2a402017-06-05 17:24:2715526 std::unique_ptr<HttpStreamRequest> RequestBidirectionalStreamImpl(
xunjieli11834f02015-12-22 04:27:0815527 const HttpRequestInfo& info,
15528 RequestPriority priority,
15529 const SSLConfig& server_ssl_config,
15530 const SSLConfig& proxy_ssl_config,
15531 HttpStreamRequest::Delegate* delegate,
bnc8016c1f2017-03-31 02:11:2915532 bool enable_ip_based_pooling,
bncaccd4962017-04-06 21:00:2615533 bool enable_alternative_services,
tfarina42834112016-09-22 13:38:2015534 const NetLogWithSource& net_log) override {
xunjieli11834f02015-12-22 04:27:0815535 NOTREACHED();
15536 return nullptr;
15537 }
15538
xunjieli96f2a402017-06-05 17:24:2715539 std::unique_ptr<HttpStreamRequest> RequestWebSocketHandshakeStream(
[email protected]bf828982013-08-14 18:01:4715540 const HttpRequestInfo& info,
15541 RequestPriority priority,
15542 const SSLConfig& server_ssl_config,
15543 const SSLConfig& proxy_ssl_config,
15544 HttpStreamRequest::Delegate* delegate,
[email protected]467086b2013-11-12 08:19:4615545 WebSocketHandshakeStreamBase::CreateHelper* create_helper,
bnc8016c1f2017-03-31 02:11:2915546 bool enable_ip_based_pooling,
bncaccd4962017-04-06 21:00:2615547 bool enable_alternative_services,
tfarina42834112016-09-22 13:38:2015548 const NetLogWithSource& net_log) override {
xunjieli96f2a402017-06-05 17:24:2715549 auto fake_request =
Jeremy Roman0579ed62017-08-29 15:56:1915550 std::make_unique<FakeStreamRequest>(priority, delegate, create_helper);
[email protected]831e4a32013-11-14 02:14:4415551 last_stream_request_ = fake_request->AsWeakPtr();
xunjieli96f2a402017-06-05 17:24:2715552 return std::move(fake_request);
[email protected]bf828982013-08-14 18:01:4715553 }
15554
dchengb03027d2014-10-21 12:00:2015555 void PreconnectStreams(int num_streams,
nharper8cdb0fb2016-04-22 21:34:5915556 const HttpRequestInfo& info) override {
[email protected]bf828982013-08-14 18:01:4715557 ADD_FAILURE();
15558 }
15559
dchengb03027d2014-10-21 12:00:2015560 const HostMappingRules* GetHostMappingRules() const override {
[email protected]bf828982013-08-14 18:01:4715561 ADD_FAILURE();
15562 return NULL;
15563 }
15564
xunjielif5267de2017-01-20 21:18:5715565 void DumpMemoryStats(base::trace_event::ProcessMemoryDump* pmd,
15566 const std::string& parent_absolute_name) const override {
15567 ADD_FAILURE();
15568 }
15569
[email protected]bf828982013-08-14 18:01:4715570 private:
15571 base::WeakPtr<FakeStreamRequest> last_stream_request_;
15572
15573 DISALLOW_COPY_AND_ASSIGN(FakeStreamFactory);
15574};
15575
Adam Rice425cf122015-01-19 06:18:2415576// TODO(ricea): Maybe unify this with the one in
15577// url_request_http_job_unittest.cc ?
15578class FakeWebSocketBasicHandshakeStream : public WebSocketHandshakeStreamBase {
15579 public:
danakj1fd259a02016-04-16 03:17:0915580 FakeWebSocketBasicHandshakeStream(
15581 std::unique_ptr<ClientSocketHandle> connection,
15582 bool using_proxy)
mmenkea7da6da2016-09-01 21:56:5215583 : state_(std::move(connection), using_proxy, false) {}
Adam Rice425cf122015-01-19 06:18:2415584
15585 // Fake implementation of HttpStreamBase methods.
15586 // This ends up being quite "real" because this object has to really send data
15587 // on the mock socket. It might be easier to use the real implementation, but
15588 // the fact that the WebSocket code is not compiled on iOS makes that
15589 // difficult.
15590 int InitializeStream(const HttpRequestInfo* request_info,
15591 RequestPriority priority,
tfarina42834112016-09-22 13:38:2015592 const NetLogWithSource& net_log,
Adam Rice425cf122015-01-19 06:18:2415593 const CompletionCallback& callback) override {
15594 state_.Initialize(request_info, priority, net_log, callback);
15595 return OK;
15596 }
15597
15598 int SendRequest(const HttpRequestHeaders& request_headers,
15599 HttpResponseInfo* response,
15600 const CompletionCallback& callback) override {
15601 return parser()->SendRequest(state_.GenerateRequestLine(), request_headers,
15602 response, callback);
15603 }
15604
15605 int ReadResponseHeaders(const CompletionCallback& callback) override {
15606 return parser()->ReadResponseHeaders(callback);
15607 }
15608
15609 int ReadResponseBody(IOBuffer* buf,
15610 int buf_len,
15611 const CompletionCallback& callback) override {
15612 NOTREACHED();
15613 return ERR_IO_PENDING;
15614 }
15615
15616 void Close(bool not_reusable) override {
15617 if (parser())
15618 parser()->Close(true);
15619 }
15620
15621 bool IsResponseBodyComplete() const override {
15622 NOTREACHED();
15623 return false;
15624 }
15625
Adam Rice425cf122015-01-19 06:18:2415626 bool IsConnectionReused() const override {
15627 NOTREACHED();
15628 return false;
15629 }
15630 void SetConnectionReused() override { NOTREACHED(); }
15631
mmenkebd84c392015-09-02 14:12:3415632 bool CanReuseConnection() const override { return false; }
Adam Rice425cf122015-01-19 06:18:2415633
sclittle4de1bab92015-09-22 21:28:2415634 int64_t GetTotalReceivedBytes() const override {
Adam Rice425cf122015-01-19 06:18:2415635 NOTREACHED();
15636 return 0;
15637 }
15638
sclittlebe1ccf62015-09-02 19:40:3615639 int64_t GetTotalSentBytes() const override {
15640 NOTREACHED();
15641 return 0;
15642 }
15643
Adam Rice425cf122015-01-19 06:18:2415644 bool GetLoadTimingInfo(LoadTimingInfo* load_timing_info) const override {
15645 NOTREACHED();
15646 return false;
15647 }
15648
rchcd379012017-04-12 21:53:3215649 bool GetAlternativeService(
15650 AlternativeService* alternative_service) const override {
15651 ADD_FAILURE();
15652 return false;
15653 }
15654
Adam Ricecb76ac62015-02-20 05:33:2515655 void GetSSLInfo(SSLInfo* ssl_info) override {}
Adam Rice425cf122015-01-19 06:18:2415656
15657 void GetSSLCertRequestInfo(SSLCertRequestInfo* cert_request_info) override {
15658 NOTREACHED();
15659 }
15660
ttuttled9dbc652015-09-29 20:00:5915661 bool GetRemoteEndpoint(IPEndPoint* endpoint) override { return false; }
15662
nharper78e6d2b2016-09-21 05:42:3515663 Error GetTokenBindingSignature(crypto::ECPrivateKey* key,
15664 TokenBindingType tb_type,
15665 std::vector<uint8_t>* out) override {
nharperb7441ef2016-01-25 23:54:1415666 ADD_FAILURE();
15667 return ERR_NOT_IMPLEMENTED;
15668 }
15669
Adam Rice425cf122015-01-19 06:18:2415670 void Drain(HttpNetworkSession* session) override { NOTREACHED(); }
15671
zhongyica364fbb2015-12-12 03:39:1215672 void PopulateNetErrorDetails(NetErrorDetails* details) override { return; }
15673
Adam Rice425cf122015-01-19 06:18:2415674 void SetPriority(RequestPriority priority) override { NOTREACHED(); }
15675
Adam Rice425cf122015-01-19 06:18:2415676 HttpStream* RenewStreamForAuth() override {
15677 NOTREACHED();
15678 return nullptr;
15679 }
15680
15681 // Fake implementation of WebSocketHandshakeStreamBase method(s)
danakj1fd259a02016-04-16 03:17:0915682 std::unique_ptr<WebSocketStream> Upgrade() override {
Adam Rice425cf122015-01-19 06:18:2415683 NOTREACHED();
danakj1fd259a02016-04-16 03:17:0915684 return std::unique_ptr<WebSocketStream>();
Adam Rice425cf122015-01-19 06:18:2415685 }
15686
15687 private:
15688 HttpStreamParser* parser() const { return state_.parser(); }
15689 HttpBasicState state_;
15690
15691 DISALLOW_COPY_AND_ASSIGN(FakeWebSocketBasicHandshakeStream);
15692};
15693
[email protected]831e4a32013-11-14 02:14:4415694// TODO(yhirano): Split this class out into a net/websockets file, if it is
15695// worth doing.
15696class FakeWebSocketStreamCreateHelper :
15697 public WebSocketHandshakeStreamBase::CreateHelper {
15698 public:
bnc615cf2f2017-05-19 18:53:2615699 std::unique_ptr<WebSocketHandshakeStreamBase> CreateBasicStream(
danakj1fd259a02016-04-16 03:17:0915700 std::unique_ptr<ClientSocketHandle> connection,
mostynbba063d6032014-10-09 11:01:1315701 bool using_proxy) override {
Jeremy Roman0579ed62017-08-29 15:56:1915702 return std::make_unique<FakeWebSocketBasicHandshakeStream>(
bnc615cf2f2017-05-19 18:53:2615703 std::move(connection), using_proxy);
[email protected]831e4a32013-11-14 02:14:4415704 }
15705
dchengb03027d2014-10-21 12:00:2015706 ~FakeWebSocketStreamCreateHelper() override {}
[email protected]831e4a32013-11-14 02:14:4415707
danakj1fd259a02016-04-16 03:17:0915708 virtual std::unique_ptr<WebSocketStream> Upgrade() {
[email protected]831e4a32013-11-14 02:14:4415709 NOTREACHED();
danakj1fd259a02016-04-16 03:17:0915710 return std::unique_ptr<WebSocketStream>();
[email protected]831e4a32013-11-14 02:14:4415711 }
15712};
15713
[email protected]bf828982013-08-14 18:01:4715714} // namespace
15715
15716// Make sure that HttpNetworkTransaction passes on its priority to its
15717// stream request on start.
bncd16676a2016-07-20 16:23:0115718TEST_F(HttpNetworkTransactionTest, SetStreamRequestPriorityOnStart) {
danakj1fd259a02016-04-16 03:17:0915719 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
mmenkee65e7af2015-10-13 17:16:4215720 HttpNetworkSessionPeer peer(session.get());
[email protected]bf828982013-08-14 18:01:4715721 FakeStreamFactory* fake_factory = new FakeStreamFactory();
danakj1fd259a02016-04-16 03:17:0915722 peer.SetHttpStreamFactory(std::unique_ptr<HttpStreamFactory>(fake_factory));
[email protected]bf828982013-08-14 18:01:4715723
krasinc06a72a2016-12-21 03:42:4615724 HttpRequestInfo request;
dcheng48459ac22014-08-26 00:46:4115725 HttpNetworkTransaction trans(LOW, session.get());
[email protected]bf828982013-08-14 18:01:4715726
wezca1070932016-05-26 20:30:5215727 ASSERT_FALSE(fake_factory->last_stream_request());
[email protected]bf828982013-08-14 18:01:4715728
[email protected]bf828982013-08-14 18:01:4715729 TestCompletionCallback callback;
15730 EXPECT_EQ(ERR_IO_PENDING,
tfarina42834112016-09-22 13:38:2015731 trans.Start(&request, callback.callback(), NetLogWithSource()));
[email protected]bf828982013-08-14 18:01:4715732
15733 base::WeakPtr<FakeStreamRequest> fake_request =
15734 fake_factory->last_stream_request();
wezca1070932016-05-26 20:30:5215735 ASSERT_TRUE(fake_request);
[email protected]bf828982013-08-14 18:01:4715736 EXPECT_EQ(LOW, fake_request->priority());
15737}
15738
15739// Make sure that HttpNetworkTransaction passes on its priority
15740// updates to its stream request.
bncd16676a2016-07-20 16:23:0115741TEST_F(HttpNetworkTransactionTest, SetStreamRequestPriority) {
danakj1fd259a02016-04-16 03:17:0915742 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
mmenkee65e7af2015-10-13 17:16:4215743 HttpNetworkSessionPeer peer(session.get());
[email protected]bf828982013-08-14 18:01:4715744 FakeStreamFactory* fake_factory = new FakeStreamFactory();
danakj1fd259a02016-04-16 03:17:0915745 peer.SetHttpStreamFactory(std::unique_ptr<HttpStreamFactory>(fake_factory));
[email protected]bf828982013-08-14 18:01:4715746
krasinc06a72a2016-12-21 03:42:4615747 HttpRequestInfo request;
dcheng48459ac22014-08-26 00:46:4115748 HttpNetworkTransaction trans(LOW, session.get());
[email protected]bf828982013-08-14 18:01:4715749
[email protected]bf828982013-08-14 18:01:4715750 TestCompletionCallback callback;
15751 EXPECT_EQ(ERR_IO_PENDING,
tfarina42834112016-09-22 13:38:2015752 trans.Start(&request, callback.callback(), NetLogWithSource()));
[email protected]bf828982013-08-14 18:01:4715753
15754 base::WeakPtr<FakeStreamRequest> fake_request =
15755 fake_factory->last_stream_request();
wezca1070932016-05-26 20:30:5215756 ASSERT_TRUE(fake_request);
[email protected]bf828982013-08-14 18:01:4715757 EXPECT_EQ(LOW, fake_request->priority());
15758
15759 trans.SetPriority(LOWEST);
wezca1070932016-05-26 20:30:5215760 ASSERT_TRUE(fake_request);
[email protected]bf828982013-08-14 18:01:4715761 EXPECT_EQ(LOWEST, fake_request->priority());
15762}
15763
[email protected]e86839fd2013-08-14 18:29:0315764// Make sure that HttpNetworkTransaction passes on its priority
15765// updates to its stream.
bncd16676a2016-07-20 16:23:0115766TEST_F(HttpNetworkTransactionTest, SetStreamPriority) {
danakj1fd259a02016-04-16 03:17:0915767 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
mmenkee65e7af2015-10-13 17:16:4215768 HttpNetworkSessionPeer peer(session.get());
[email protected]e86839fd2013-08-14 18:29:0315769 FakeStreamFactory* fake_factory = new FakeStreamFactory();
danakj1fd259a02016-04-16 03:17:0915770 peer.SetHttpStreamFactory(std::unique_ptr<HttpStreamFactory>(fake_factory));
[email protected]e86839fd2013-08-14 18:29:0315771
krasinc06a72a2016-12-21 03:42:4615772 HttpRequestInfo request;
dcheng48459ac22014-08-26 00:46:4115773 HttpNetworkTransaction trans(LOW, session.get());
[email protected]e86839fd2013-08-14 18:29:0315774
[email protected]e86839fd2013-08-14 18:29:0315775 TestCompletionCallback callback;
15776 EXPECT_EQ(ERR_IO_PENDING,
tfarina42834112016-09-22 13:38:2015777 trans.Start(&request, callback.callback(), NetLogWithSource()));
[email protected]e86839fd2013-08-14 18:29:0315778
15779 base::WeakPtr<FakeStreamRequest> fake_request =
15780 fake_factory->last_stream_request();
wezca1070932016-05-26 20:30:5215781 ASSERT_TRUE(fake_request);
[email protected]e86839fd2013-08-14 18:29:0315782 base::WeakPtr<FakeStream> fake_stream = fake_request->FinishStreamRequest();
wezca1070932016-05-26 20:30:5215783 ASSERT_TRUE(fake_stream);
[email protected]e86839fd2013-08-14 18:29:0315784 EXPECT_EQ(LOW, fake_stream->priority());
15785
15786 trans.SetPriority(LOWEST);
15787 EXPECT_EQ(LOWEST, fake_stream->priority());
15788}
15789
bncd16676a2016-07-20 16:23:0115790TEST_F(HttpNetworkTransactionTest, CreateWebSocketHandshakeStream) {
[email protected]831e4a32013-11-14 02:14:4415791 // The same logic needs to be tested for both ws: and wss: schemes, but this
15792 // test is already parameterised on NextProto, so it uses a loop to verify
15793 // that the different schemes work.
bncce36dca22015-04-21 22:11:2315794 std::string test_cases[] = {"ws://www.example.org/",
15795 "wss://www.example.org/"};
[email protected]831e4a32013-11-14 02:14:4415796 for (size_t i = 0; i < arraysize(test_cases); ++i) {
danakj1fd259a02016-04-16 03:17:0915797 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
mmenkee65e7af2015-10-13 17:16:4215798 HttpNetworkSessionPeer peer(session.get());
[email protected]831e4a32013-11-14 02:14:4415799 FakeStreamFactory* fake_factory = new FakeStreamFactory();
15800 FakeWebSocketStreamCreateHelper websocket_stream_create_helper;
[email protected]0191b51c2013-11-18 10:55:2315801 peer.SetHttpStreamFactoryForWebSocket(
danakj1fd259a02016-04-16 03:17:0915802 std::unique_ptr<HttpStreamFactory>(fake_factory));
[email protected]831e4a32013-11-14 02:14:4415803
krasinc06a72a2016-12-21 03:42:4615804 HttpRequestInfo request;
dcheng48459ac22014-08-26 00:46:4115805 HttpNetworkTransaction trans(LOW, session.get());
[email protected]831e4a32013-11-14 02:14:4415806 trans.SetWebSocketHandshakeStreamCreateHelper(
15807 &websocket_stream_create_helper);
15808
[email protected]831e4a32013-11-14 02:14:4415809 TestCompletionCallback callback;
15810 request.method = "GET";
15811 request.url = GURL(test_cases[i]);
15812
15813 EXPECT_EQ(ERR_IO_PENDING,
tfarina42834112016-09-22 13:38:2015814 trans.Start(&request, callback.callback(), NetLogWithSource()));
[email protected]831e4a32013-11-14 02:14:4415815
15816 base::WeakPtr<FakeStreamRequest> fake_request =
15817 fake_factory->last_stream_request();
wezca1070932016-05-26 20:30:5215818 ASSERT_TRUE(fake_request);
[email protected]831e4a32013-11-14 02:14:4415819 EXPECT_EQ(&websocket_stream_create_helper,
15820 fake_request->websocket_stream_create_helper());
15821 }
15822}
15823
[email protected]043b68c82013-08-22 23:41:5215824// Tests that when a used socket is returned to the SSL socket pool, it's closed
15825// if the transport socket pool is stalled on the global socket limit.
bncd16676a2016-07-20 16:23:0115826TEST_F(HttpNetworkTransactionTest, CloseSSLSocketOnIdleForHttpRequest) {
[email protected]043b68c82013-08-22 23:41:5215827 ClientSocketPoolManager::set_max_sockets_per_group(
15828 HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
15829 ClientSocketPoolManager::set_max_sockets_per_pool(
15830 HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
15831
15832 // Set up SSL request.
15833
15834 HttpRequestInfo ssl_request;
15835 ssl_request.method = "GET";
bncce36dca22015-04-21 22:11:2315836 ssl_request.url = GURL("https://www.example.org/");
[email protected]043b68c82013-08-22 23:41:5215837
15838 MockWrite ssl_writes[] = {
bncce36dca22015-04-21 22:11:2315839 MockWrite(
15840 "GET / HTTP/1.1\r\n"
15841 "Host: www.example.org\r\n"
15842 "Connection: keep-alive\r\n\r\n"),
[email protected]043b68c82013-08-22 23:41:5215843 };
15844 MockRead ssl_reads[] = {
15845 MockRead("HTTP/1.1 200 OK\r\n"),
15846 MockRead("Content-Length: 11\r\n\r\n"),
15847 MockRead("hello world"),
15848 MockRead(SYNCHRONOUS, OK),
15849 };
15850 StaticSocketDataProvider ssl_data(ssl_reads, arraysize(ssl_reads),
15851 ssl_writes, arraysize(ssl_writes));
15852 session_deps_.socket_factory->AddSocketDataProvider(&ssl_data);
15853
15854 SSLSocketDataProvider ssl(ASYNC, OK);
15855 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
15856
15857 // Set up HTTP request.
15858
15859 HttpRequestInfo http_request;
15860 http_request.method = "GET";
bncce36dca22015-04-21 22:11:2315861 http_request.url = GURL("http://www.example.org/");
[email protected]043b68c82013-08-22 23:41:5215862
15863 MockWrite http_writes[] = {
bncce36dca22015-04-21 22:11:2315864 MockWrite(
15865 "GET / HTTP/1.1\r\n"
15866 "Host: www.example.org\r\n"
15867 "Connection: keep-alive\r\n\r\n"),
[email protected]043b68c82013-08-22 23:41:5215868 };
15869 MockRead http_reads[] = {
15870 MockRead("HTTP/1.1 200 OK\r\n"),
15871 MockRead("Content-Length: 7\r\n\r\n"),
15872 MockRead("falafel"),
15873 MockRead(SYNCHRONOUS, OK),
15874 };
15875 StaticSocketDataProvider http_data(http_reads, arraysize(http_reads),
15876 http_writes, arraysize(http_writes));
15877 session_deps_.socket_factory->AddSocketDataProvider(&http_data);
15878
danakj1fd259a02016-04-16 03:17:0915879 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]043b68c82013-08-22 23:41:5215880
15881 // Start the SSL request.
15882 TestCompletionCallback ssl_callback;
bnc691fda62016-08-12 00:43:1615883 HttpNetworkTransaction ssl_trans(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:2015884 ASSERT_EQ(ERR_IO_PENDING,
15885 ssl_trans.Start(&ssl_request, ssl_callback.callback(),
15886 NetLogWithSource()));
[email protected]043b68c82013-08-22 23:41:5215887
15888 // Start the HTTP request. Pool should stall.
15889 TestCompletionCallback http_callback;
bnc691fda62016-08-12 00:43:1615890 HttpNetworkTransaction http_trans(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:2015891 ASSERT_EQ(ERR_IO_PENDING,
15892 http_trans.Start(&http_request, http_callback.callback(),
15893 NetLogWithSource()));
dcheng48459ac22014-08-26 00:46:4115894 EXPECT_TRUE(IsTransportSocketPoolStalled(session.get()));
[email protected]043b68c82013-08-22 23:41:5215895
15896 // Wait for response from SSL request.
robpercival214763f2016-07-01 23:27:0115897 ASSERT_THAT(ssl_callback.WaitForResult(), IsOk());
[email protected]043b68c82013-08-22 23:41:5215898 std::string response_data;
bnc691fda62016-08-12 00:43:1615899 ASSERT_THAT(ReadTransaction(&ssl_trans, &response_data), IsOk());
[email protected]043b68c82013-08-22 23:41:5215900 EXPECT_EQ("hello world", response_data);
15901
15902 // The SSL socket should automatically be closed, so the HTTP request can
15903 // start.
dcheng48459ac22014-08-26 00:46:4115904 EXPECT_EQ(0, GetIdleSocketCountInSSLSocketPool(session.get()));
15905 ASSERT_FALSE(IsTransportSocketPoolStalled(session.get()));
[email protected]043b68c82013-08-22 23:41:5215906
15907 // The HTTP request can now complete.
robpercival214763f2016-07-01 23:27:0115908 ASSERT_THAT(http_callback.WaitForResult(), IsOk());
bnc691fda62016-08-12 00:43:1615909 ASSERT_THAT(ReadTransaction(&http_trans, &response_data), IsOk());
[email protected]043b68c82013-08-22 23:41:5215910 EXPECT_EQ("falafel", response_data);
15911
dcheng48459ac22014-08-26 00:46:4115912 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]043b68c82013-08-22 23:41:5215913}
15914
15915// Tests that when a SSL connection is established but there's no corresponding
15916// request that needs it, the new socket is closed if the transport socket pool
15917// is stalled on the global socket limit.
bncd16676a2016-07-20 16:23:0115918TEST_F(HttpNetworkTransactionTest, CloseSSLSocketOnIdleForHttpRequest2) {
[email protected]043b68c82013-08-22 23:41:5215919 ClientSocketPoolManager::set_max_sockets_per_group(
15920 HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
15921 ClientSocketPoolManager::set_max_sockets_per_pool(
15922 HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
15923
15924 // Set up an ssl request.
15925
15926 HttpRequestInfo ssl_request;
15927 ssl_request.method = "GET";
15928 ssl_request.url = GURL("https://www.foopy.com/");
15929
15930 // No data will be sent on the SSL socket.
15931 StaticSocketDataProvider ssl_data;
15932 session_deps_.socket_factory->AddSocketDataProvider(&ssl_data);
15933
15934 SSLSocketDataProvider ssl(ASYNC, OK);
15935 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
15936
15937 // Set up HTTP request.
15938
15939 HttpRequestInfo http_request;
15940 http_request.method = "GET";
bncce36dca22015-04-21 22:11:2315941 http_request.url = GURL("http://www.example.org/");
[email protected]043b68c82013-08-22 23:41:5215942
15943 MockWrite http_writes[] = {
bncce36dca22015-04-21 22:11:2315944 MockWrite(
15945 "GET / HTTP/1.1\r\n"
15946 "Host: www.example.org\r\n"
15947 "Connection: keep-alive\r\n\r\n"),
[email protected]043b68c82013-08-22 23:41:5215948 };
15949 MockRead http_reads[] = {
15950 MockRead("HTTP/1.1 200 OK\r\n"),
15951 MockRead("Content-Length: 7\r\n\r\n"),
15952 MockRead("falafel"),
15953 MockRead(SYNCHRONOUS, OK),
15954 };
15955 StaticSocketDataProvider http_data(http_reads, arraysize(http_reads),
15956 http_writes, arraysize(http_writes));
15957 session_deps_.socket_factory->AddSocketDataProvider(&http_data);
15958
danakj1fd259a02016-04-16 03:17:0915959 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]043b68c82013-08-22 23:41:5215960
15961 // Preconnect an SSL socket. A preconnect is needed because connect jobs are
15962 // cancelled when a normal transaction is cancelled.
ttuttle859dc7a2015-04-23 19:42:2915963 HttpStreamFactory* http_stream_factory = session->http_stream_factory();
nharper8cdb0fb2016-04-22 21:34:5915964 http_stream_factory->PreconnectStreams(1, ssl_request);
dcheng48459ac22014-08-26 00:46:4115965 EXPECT_EQ(0, GetIdleSocketCountInSSLSocketPool(session.get()));
[email protected]043b68c82013-08-22 23:41:5215966
15967 // Start the HTTP request. Pool should stall.
15968 TestCompletionCallback http_callback;
bnc691fda62016-08-12 00:43:1615969 HttpNetworkTransaction http_trans(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:2015970 ASSERT_EQ(ERR_IO_PENDING,
15971 http_trans.Start(&http_request, http_callback.callback(),
15972 NetLogWithSource()));
dcheng48459ac22014-08-26 00:46:4115973 EXPECT_TRUE(IsTransportSocketPoolStalled(session.get()));
[email protected]043b68c82013-08-22 23:41:5215974
15975 // The SSL connection will automatically be closed once the connection is
15976 // established, to let the HTTP request start.
robpercival214763f2016-07-01 23:27:0115977 ASSERT_THAT(http_callback.WaitForResult(), IsOk());
[email protected]043b68c82013-08-22 23:41:5215978 std::string response_data;
bnc691fda62016-08-12 00:43:1615979 ASSERT_THAT(ReadTransaction(&http_trans, &response_data), IsOk());
[email protected]043b68c82013-08-22 23:41:5215980 EXPECT_EQ("falafel", response_data);
15981
dcheng48459ac22014-08-26 00:46:4115982 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]043b68c82013-08-22 23:41:5215983}
15984
bncd16676a2016-07-20 16:23:0115985TEST_F(HttpNetworkTransactionTest, PostReadsErrorResponseAfterReset) {
danakj1fd259a02016-04-16 03:17:0915986 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:2215987 element_readers.push_back(
Jeremy Roman0579ed62017-08-29 15:56:1915988 std::make_unique<UploadBytesElementReader>("foo", 3));
olli.raula6df48b2a2015-11-26 07:40:2215989 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]02d74a02014-04-23 18:10:5415990
15991 HttpRequestInfo request;
15992 request.method = "POST";
15993 request.url = GURL("http://www.foo.com/");
15994 request.upload_data_stream = &upload_data_stream;
[email protected]02d74a02014-04-23 18:10:5415995
danakj1fd259a02016-04-16 03:17:0915996 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1615997 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]02d74a02014-04-23 18:10:5415998 // Send headers successfully, but get an error while sending the body.
15999 MockWrite data_writes[] = {
16000 MockWrite("POST / HTTP/1.1\r\n"
16001 "Host: www.foo.com\r\n"
16002 "Connection: keep-alive\r\n"
16003 "Content-Length: 3\r\n\r\n"),
16004 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
16005 };
16006
16007 MockRead data_reads[] = {
16008 MockRead("HTTP/1.0 400 Not OK\r\n\r\n"),
16009 MockRead("hello world"),
16010 MockRead(SYNCHRONOUS, OK),
16011 };
16012 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
16013 arraysize(data_writes));
16014 session_deps_.socket_factory->AddSocketDataProvider(&data);
16015
16016 TestCompletionCallback callback;
16017
tfarina42834112016-09-22 13:38:2016018 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0116019 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]02d74a02014-04-23 18:10:5416020
16021 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0116022 EXPECT_THAT(rv, IsOk());
[email protected]02d74a02014-04-23 18:10:5416023
bnc691fda62016-08-12 00:43:1616024 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5216025 ASSERT_TRUE(response);
[email protected]02d74a02014-04-23 18:10:5416026
wezca1070932016-05-26 20:30:5216027 EXPECT_TRUE(response->headers);
[email protected]02d74a02014-04-23 18:10:5416028 EXPECT_EQ("HTTP/1.0 400 Not OK", response->headers->GetStatusLine());
16029
16030 std::string response_data;
bnc691fda62016-08-12 00:43:1616031 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:0116032 EXPECT_THAT(rv, IsOk());
[email protected]02d74a02014-04-23 18:10:5416033 EXPECT_EQ("hello world", response_data);
16034}
16035
16036// This test makes sure the retry logic doesn't trigger when reading an error
16037// response from a server that rejected a POST with a CONNECTION_RESET.
bncd16676a2016-07-20 16:23:0116038TEST_F(HttpNetworkTransactionTest,
[email protected]02d74a02014-04-23 18:10:5416039 PostReadsErrorResponseAfterResetOnReusedSocket) {
danakj1fd259a02016-04-16 03:17:0916040 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]02d74a02014-04-23 18:10:5416041 MockWrite data_writes[] = {
16042 MockWrite("GET / HTTP/1.1\r\n"
16043 "Host: www.foo.com\r\n"
16044 "Connection: keep-alive\r\n\r\n"),
16045 MockWrite("POST / HTTP/1.1\r\n"
16046 "Host: www.foo.com\r\n"
16047 "Connection: keep-alive\r\n"
16048 "Content-Length: 3\r\n\r\n"),
16049 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
16050 };
16051
16052 MockRead data_reads[] = {
16053 MockRead("HTTP/1.1 200 Peachy\r\n"
16054 "Content-Length: 14\r\n\r\n"),
16055 MockRead("first response"),
16056 MockRead("HTTP/1.1 400 Not OK\r\n"
16057 "Content-Length: 15\r\n\r\n"),
16058 MockRead("second response"),
16059 MockRead(SYNCHRONOUS, OK),
16060 };
16061 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
16062 arraysize(data_writes));
16063 session_deps_.socket_factory->AddSocketDataProvider(&data);
16064
16065 TestCompletionCallback callback;
16066 HttpRequestInfo request1;
16067 request1.method = "GET";
16068 request1.url = GURL("http://www.foo.com/");
16069 request1.load_flags = 0;
16070
bnc87dcefc2017-05-25 12:47:5816071 auto trans1 =
Jeremy Roman0579ed62017-08-29 15:56:1916072 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:2016073 int rv = trans1->Start(&request1, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0116074 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]02d74a02014-04-23 18:10:5416075
16076 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0116077 EXPECT_THAT(rv, IsOk());
[email protected]02d74a02014-04-23 18:10:5416078
16079 const HttpResponseInfo* response1 = trans1->GetResponseInfo();
wezca1070932016-05-26 20:30:5216080 ASSERT_TRUE(response1);
[email protected]02d74a02014-04-23 18:10:5416081
wezca1070932016-05-26 20:30:5216082 EXPECT_TRUE(response1->headers);
[email protected]02d74a02014-04-23 18:10:5416083 EXPECT_EQ("HTTP/1.1 200 Peachy", response1->headers->GetStatusLine());
16084
16085 std::string response_data1;
16086 rv = ReadTransaction(trans1.get(), &response_data1);
robpercival214763f2016-07-01 23:27:0116087 EXPECT_THAT(rv, IsOk());
[email protected]02d74a02014-04-23 18:10:5416088 EXPECT_EQ("first response", response_data1);
16089 // Delete the transaction to release the socket back into the socket pool.
16090 trans1.reset();
16091
danakj1fd259a02016-04-16 03:17:0916092 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:2216093 element_readers.push_back(
Jeremy Roman0579ed62017-08-29 15:56:1916094 std::make_unique<UploadBytesElementReader>("foo", 3));
olli.raula6df48b2a2015-11-26 07:40:2216095 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]02d74a02014-04-23 18:10:5416096
16097 HttpRequestInfo request2;
16098 request2.method = "POST";
16099 request2.url = GURL("http://www.foo.com/");
16100 request2.upload_data_stream = &upload_data_stream;
16101 request2.load_flags = 0;
16102
bnc691fda62016-08-12 00:43:1616103 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:2016104 rv = trans2.Start(&request2, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0116105 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]02d74a02014-04-23 18:10:5416106
16107 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0116108 EXPECT_THAT(rv, IsOk());
[email protected]02d74a02014-04-23 18:10:5416109
bnc691fda62016-08-12 00:43:1616110 const HttpResponseInfo* response2 = trans2.GetResponseInfo();
wezca1070932016-05-26 20:30:5216111 ASSERT_TRUE(response2);
[email protected]02d74a02014-04-23 18:10:5416112
wezca1070932016-05-26 20:30:5216113 EXPECT_TRUE(response2->headers);
[email protected]02d74a02014-04-23 18:10:5416114 EXPECT_EQ("HTTP/1.1 400 Not OK", response2->headers->GetStatusLine());
16115
16116 std::string response_data2;
bnc691fda62016-08-12 00:43:1616117 rv = ReadTransaction(&trans2, &response_data2);
robpercival214763f2016-07-01 23:27:0116118 EXPECT_THAT(rv, IsOk());
[email protected]02d74a02014-04-23 18:10:5416119 EXPECT_EQ("second response", response_data2);
16120}
16121
bncd16676a2016-07-20 16:23:0116122TEST_F(HttpNetworkTransactionTest,
[email protected]02d74a02014-04-23 18:10:5416123 PostReadsErrorResponseAfterResetPartialBodySent) {
danakj1fd259a02016-04-16 03:17:0916124 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:2216125 element_readers.push_back(
Jeremy Roman0579ed62017-08-29 15:56:1916126 std::make_unique<UploadBytesElementReader>("foo", 3));
olli.raula6df48b2a2015-11-26 07:40:2216127 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]02d74a02014-04-23 18:10:5416128
16129 HttpRequestInfo request;
16130 request.method = "POST";
16131 request.url = GURL("http://www.foo.com/");
16132 request.upload_data_stream = &upload_data_stream;
[email protected]02d74a02014-04-23 18:10:5416133
danakj1fd259a02016-04-16 03:17:0916134 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1616135 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]02d74a02014-04-23 18:10:5416136 // Send headers successfully, but get an error while sending the body.
16137 MockWrite data_writes[] = {
16138 MockWrite("POST / HTTP/1.1\r\n"
16139 "Host: www.foo.com\r\n"
16140 "Connection: keep-alive\r\n"
16141 "Content-Length: 3\r\n\r\n"
16142 "fo"),
16143 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
16144 };
16145
16146 MockRead data_reads[] = {
16147 MockRead("HTTP/1.0 400 Not OK\r\n\r\n"),
16148 MockRead("hello world"),
16149 MockRead(SYNCHRONOUS, OK),
16150 };
16151 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
16152 arraysize(data_writes));
16153 session_deps_.socket_factory->AddSocketDataProvider(&data);
16154
16155 TestCompletionCallback callback;
16156
tfarina42834112016-09-22 13:38:2016157 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0116158 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]02d74a02014-04-23 18:10:5416159
16160 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0116161 EXPECT_THAT(rv, IsOk());
[email protected]02d74a02014-04-23 18:10:5416162
bnc691fda62016-08-12 00:43:1616163 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5216164 ASSERT_TRUE(response);
[email protected]02d74a02014-04-23 18:10:5416165
wezca1070932016-05-26 20:30:5216166 EXPECT_TRUE(response->headers);
[email protected]02d74a02014-04-23 18:10:5416167 EXPECT_EQ("HTTP/1.0 400 Not OK", response->headers->GetStatusLine());
16168
16169 std::string response_data;
bnc691fda62016-08-12 00:43:1616170 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:0116171 EXPECT_THAT(rv, IsOk());
[email protected]02d74a02014-04-23 18:10:5416172 EXPECT_EQ("hello world", response_data);
16173}
16174
16175// This tests the more common case than the previous test, where headers and
16176// body are not merged into a single request.
bncd16676a2016-07-20 16:23:0116177TEST_F(HttpNetworkTransactionTest, ChunkedPostReadsErrorResponseAfterReset) {
mmenkecbc2b712014-10-09 20:29:0716178 ChunkedUploadDataStream upload_data_stream(0);
[email protected]02d74a02014-04-23 18:10:5416179
16180 HttpRequestInfo request;
16181 request.method = "POST";
16182 request.url = GURL("http://www.foo.com/");
16183 request.upload_data_stream = &upload_data_stream;
[email protected]02d74a02014-04-23 18:10:5416184
danakj1fd259a02016-04-16 03:17:0916185 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1616186 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]02d74a02014-04-23 18:10:5416187 // Send headers successfully, but get an error while sending the body.
16188 MockWrite data_writes[] = {
16189 MockWrite("POST / HTTP/1.1\r\n"
16190 "Host: www.foo.com\r\n"
16191 "Connection: keep-alive\r\n"
16192 "Transfer-Encoding: chunked\r\n\r\n"),
16193 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
16194 };
16195
16196 MockRead data_reads[] = {
16197 MockRead("HTTP/1.0 400 Not OK\r\n\r\n"),
16198 MockRead("hello world"),
16199 MockRead(SYNCHRONOUS, OK),
16200 };
16201 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
16202 arraysize(data_writes));
16203 session_deps_.socket_factory->AddSocketDataProvider(&data);
16204
16205 TestCompletionCallback callback;
16206
tfarina42834112016-09-22 13:38:2016207 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0116208 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]02d74a02014-04-23 18:10:5416209 // Make sure the headers are sent before adding a chunk. This ensures that
16210 // they can't be merged with the body in a single send. Not currently
16211 // necessary since a chunked body is never merged with headers, but this makes
16212 // the test more future proof.
16213 base::RunLoop().RunUntilIdle();
16214
mmenkecbc2b712014-10-09 20:29:0716215 upload_data_stream.AppendData("last chunk", 10, true);
[email protected]02d74a02014-04-23 18:10:5416216
16217 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0116218 EXPECT_THAT(rv, IsOk());
[email protected]02d74a02014-04-23 18:10:5416219
bnc691fda62016-08-12 00:43:1616220 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5216221 ASSERT_TRUE(response);
[email protected]02d74a02014-04-23 18:10:5416222
wezca1070932016-05-26 20:30:5216223 EXPECT_TRUE(response->headers);
[email protected]02d74a02014-04-23 18:10:5416224 EXPECT_EQ("HTTP/1.0 400 Not OK", response->headers->GetStatusLine());
16225
16226 std::string response_data;
bnc691fda62016-08-12 00:43:1616227 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:0116228 EXPECT_THAT(rv, IsOk());
[email protected]02d74a02014-04-23 18:10:5416229 EXPECT_EQ("hello world", response_data);
16230}
16231
bncd16676a2016-07-20 16:23:0116232TEST_F(HttpNetworkTransactionTest, PostReadsErrorResponseAfterResetAnd100) {
danakj1fd259a02016-04-16 03:17:0916233 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:2216234 element_readers.push_back(
Jeremy Roman0579ed62017-08-29 15:56:1916235 std::make_unique<UploadBytesElementReader>("foo", 3));
olli.raula6df48b2a2015-11-26 07:40:2216236 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 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
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 "Content-Length: 3\r\n\r\n"),
16251 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
16252 };
16253
16254 MockRead data_reads[] = {
16255 MockRead("HTTP/1.0 100 Continue\r\n\r\n"),
16256 MockRead("HTTP/1.0 400 Not OK\r\n\r\n"),
16257 MockRead("hello world"),
16258 MockRead(SYNCHRONOUS, OK),
16259 };
16260 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
16261 arraysize(data_writes));
16262 session_deps_.socket_factory->AddSocketDataProvider(&data);
16263
16264 TestCompletionCallback callback;
16265
tfarina42834112016-09-22 13:38:2016266 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0116267 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]02d74a02014-04-23 18:10:5416268
16269 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0116270 EXPECT_THAT(rv, IsOk());
[email protected]02d74a02014-04-23 18:10:5416271
bnc691fda62016-08-12 00:43:1616272 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5216273 ASSERT_TRUE(response);
[email protected]02d74a02014-04-23 18:10:5416274
wezca1070932016-05-26 20:30:5216275 EXPECT_TRUE(response->headers);
[email protected]02d74a02014-04-23 18:10:5416276 EXPECT_EQ("HTTP/1.0 400 Not OK", response->headers->GetStatusLine());
16277
16278 std::string response_data;
bnc691fda62016-08-12 00:43:1616279 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:0116280 EXPECT_THAT(rv, IsOk());
[email protected]02d74a02014-04-23 18:10:5416281 EXPECT_EQ("hello world", response_data);
16282}
16283
bncd16676a2016-07-20 16:23:0116284TEST_F(HttpNetworkTransactionTest, PostIgnoresNonErrorResponseAfterReset) {
danakj1fd259a02016-04-16 03:17:0916285 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:2216286 element_readers.push_back(
Jeremy Roman0579ed62017-08-29 15:56:1916287 std::make_unique<UploadBytesElementReader>("foo", 3));
olli.raula6df48b2a2015-11-26 07:40:2216288 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]02d74a02014-04-23 18:10:5416289
16290 HttpRequestInfo request;
16291 request.method = "POST";
16292 request.url = GURL("http://www.foo.com/");
16293 request.upload_data_stream = &upload_data_stream;
[email protected]02d74a02014-04-23 18:10:5416294
danakj1fd259a02016-04-16 03:17:0916295 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1616296 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]02d74a02014-04-23 18:10:5416297 // Send headers successfully, but get an error while sending the body.
16298 MockWrite data_writes[] = {
16299 MockWrite("POST / HTTP/1.1\r\n"
16300 "Host: www.foo.com\r\n"
16301 "Connection: keep-alive\r\n"
16302 "Content-Length: 3\r\n\r\n"),
16303 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
16304 };
16305
16306 MockRead data_reads[] = {
16307 MockRead("HTTP/1.0 200 Just Dandy\r\n\r\n"),
16308 MockRead("hello world"),
16309 MockRead(SYNCHRONOUS, OK),
16310 };
16311 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
16312 arraysize(data_writes));
16313 session_deps_.socket_factory->AddSocketDataProvider(&data);
16314
16315 TestCompletionCallback callback;
16316
tfarina42834112016-09-22 13:38:2016317 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0116318 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]02d74a02014-04-23 18:10:5416319
16320 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0116321 EXPECT_THAT(rv, IsError(ERR_CONNECTION_RESET));
[email protected]02d74a02014-04-23 18:10:5416322}
16323
bncd16676a2016-07-20 16:23:0116324TEST_F(HttpNetworkTransactionTest,
[email protected]02d74a02014-04-23 18:10:5416325 PostIgnoresNonErrorResponseAfterResetAnd100) {
danakj1fd259a02016-04-16 03:17:0916326 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:2216327 element_readers.push_back(
Jeremy Roman0579ed62017-08-29 15:56:1916328 std::make_unique<UploadBytesElementReader>("foo", 3));
olli.raula6df48b2a2015-11-26 07:40:2216329 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]02d74a02014-04-23 18:10:5416330
16331 HttpRequestInfo request;
16332 request.method = "POST";
16333 request.url = GURL("http://www.foo.com/");
16334 request.upload_data_stream = &upload_data_stream;
[email protected]02d74a02014-04-23 18:10:5416335
danakj1fd259a02016-04-16 03:17:0916336 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1616337 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]02d74a02014-04-23 18:10:5416338 // Send headers successfully, but get an error while sending the body.
16339 MockWrite data_writes[] = {
16340 MockWrite("POST / HTTP/1.1\r\n"
16341 "Host: www.foo.com\r\n"
16342 "Connection: keep-alive\r\n"
16343 "Content-Length: 3\r\n\r\n"),
16344 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
16345 };
16346
16347 MockRead data_reads[] = {
16348 MockRead("HTTP/1.0 100 Continue\r\n\r\n"),
16349 MockRead("HTTP/1.0 302 Redirect\r\n"),
16350 MockRead("Location: http://somewhere-else.com/\r\n"),
16351 MockRead("Content-Length: 0\r\n\r\n"),
16352 MockRead(SYNCHRONOUS, OK),
16353 };
16354 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
16355 arraysize(data_writes));
16356 session_deps_.socket_factory->AddSocketDataProvider(&data);
16357
16358 TestCompletionCallback callback;
16359
tfarina42834112016-09-22 13:38:2016360 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0116361 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]02d74a02014-04-23 18:10:5416362
16363 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0116364 EXPECT_THAT(rv, IsError(ERR_CONNECTION_RESET));
[email protected]02d74a02014-04-23 18:10:5416365}
16366
bncd16676a2016-07-20 16:23:0116367TEST_F(HttpNetworkTransactionTest, PostIgnoresHttp09ResponseAfterReset) {
danakj1fd259a02016-04-16 03:17:0916368 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:2216369 element_readers.push_back(
Jeremy Roman0579ed62017-08-29 15:56:1916370 std::make_unique<UploadBytesElementReader>("foo", 3));
olli.raula6df48b2a2015-11-26 07:40:2216371 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]02d74a02014-04-23 18:10:5416372
16373 HttpRequestInfo request;
16374 request.method = "POST";
16375 request.url = GURL("http://www.foo.com/");
16376 request.upload_data_stream = &upload_data_stream;
[email protected]02d74a02014-04-23 18:10:5416377
danakj1fd259a02016-04-16 03:17:0916378 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1616379 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]02d74a02014-04-23 18:10:5416380 // Send headers successfully, but get an error while sending the body.
16381 MockWrite data_writes[] = {
16382 MockWrite("POST / HTTP/1.1\r\n"
16383 "Host: www.foo.com\r\n"
16384 "Connection: keep-alive\r\n"
16385 "Content-Length: 3\r\n\r\n"),
16386 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
16387 };
16388
16389 MockRead data_reads[] = {
16390 MockRead("HTTP 0.9 rocks!"),
16391 MockRead(SYNCHRONOUS, OK),
16392 };
16393 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
16394 arraysize(data_writes));
16395 session_deps_.socket_factory->AddSocketDataProvider(&data);
16396
16397 TestCompletionCallback callback;
16398
tfarina42834112016-09-22 13:38:2016399 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0116400 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]02d74a02014-04-23 18:10:5416401
16402 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0116403 EXPECT_THAT(rv, IsError(ERR_CONNECTION_RESET));
[email protected]02d74a02014-04-23 18:10:5416404}
16405
bncd16676a2016-07-20 16:23:0116406TEST_F(HttpNetworkTransactionTest, PostIgnoresPartial400HeadersAfterReset) {
danakj1fd259a02016-04-16 03:17:0916407 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:2216408 element_readers.push_back(
Jeremy Roman0579ed62017-08-29 15:56:1916409 std::make_unique<UploadBytesElementReader>("foo", 3));
olli.raula6df48b2a2015-11-26 07:40:2216410 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]02d74a02014-04-23 18:10:5416411
16412 HttpRequestInfo request;
16413 request.method = "POST";
16414 request.url = GURL("http://www.foo.com/");
16415 request.upload_data_stream = &upload_data_stream;
[email protected]02d74a02014-04-23 18:10:5416416
danakj1fd259a02016-04-16 03:17:0916417 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1616418 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]02d74a02014-04-23 18:10:5416419 // Send headers successfully, but get an error while sending the body.
16420 MockWrite data_writes[] = {
16421 MockWrite("POST / HTTP/1.1\r\n"
16422 "Host: www.foo.com\r\n"
16423 "Connection: keep-alive\r\n"
16424 "Content-Length: 3\r\n\r\n"),
16425 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
16426 };
16427
16428 MockRead data_reads[] = {
16429 MockRead("HTTP/1.0 400 Not a Full Response\r\n"),
16430 MockRead(SYNCHRONOUS, OK),
16431 };
16432 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
16433 arraysize(data_writes));
16434 session_deps_.socket_factory->AddSocketDataProvider(&data);
16435
16436 TestCompletionCallback callback;
16437
tfarina42834112016-09-22 13:38:2016438 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0116439 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]02d74a02014-04-23 18:10:5416440
16441 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0116442 EXPECT_THAT(rv, IsError(ERR_CONNECTION_RESET));
[email protected]02d74a02014-04-23 18:10:5416443}
16444
Adam Rice425cf122015-01-19 06:18:2416445// Verify that proxy headers are not sent to the destination server when
16446// establishing a tunnel for a secure WebSocket connection.
bncd16676a2016-07-20 16:23:0116447TEST_F(HttpNetworkTransactionTest, ProxyHeadersNotSentOverWssTunnel) {
Adam Rice425cf122015-01-19 06:18:2416448 HttpRequestInfo request;
16449 request.method = "GET";
bncce36dca22015-04-21 22:11:2316450 request.url = GURL("wss://www.example.org/");
Adam Rice425cf122015-01-19 06:18:2416451 AddWebSocketHeaders(&request.extra_headers);
16452
16453 // Configure against proxy server "myproxy:70".
rdsmith82957ad2015-09-16 19:42:0316454 session_deps_.proxy_service =
16455 ProxyService::CreateFixedFromPacResult("PROXY myproxy:70");
Adam Rice425cf122015-01-19 06:18:2416456
danakj1fd259a02016-04-16 03:17:0916457 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
Adam Rice425cf122015-01-19 06:18:2416458
16459 // Since a proxy is configured, try to establish a tunnel.
16460 MockWrite data_writes[] = {
rsleevidb16bb02015-11-12 23:47:1716461 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
16462 "Host: www.example.org:443\r\n"
16463 "Proxy-Connection: keep-alive\r\n\r\n"),
Adam Rice425cf122015-01-19 06:18:2416464
16465 // After calling trans->RestartWithAuth(), this is the request we should
16466 // be issuing -- the final header line contains the credentials.
rsleevidb16bb02015-11-12 23:47:1716467 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
16468 "Host: www.example.org:443\r\n"
16469 "Proxy-Connection: keep-alive\r\n"
16470 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
Adam Rice425cf122015-01-19 06:18:2416471
rsleevidb16bb02015-11-12 23:47:1716472 MockWrite("GET / HTTP/1.1\r\n"
16473 "Host: www.example.org\r\n"
16474 "Connection: Upgrade\r\n"
16475 "Upgrade: websocket\r\n"
16476 "Origin: http://www.example.org\r\n"
16477 "Sec-WebSocket-Version: 13\r\n"
16478 "Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==\r\n\r\n"),
Adam Rice425cf122015-01-19 06:18:2416479 };
16480
16481 // The proxy responds to the connect with a 407, using a persistent
16482 // connection.
16483 MockRead data_reads[] = {
16484 // No credentials.
16485 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
16486 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
mmenkee71e15332015-10-07 16:39:5416487 MockRead("Content-Length: 0\r\n"),
16488 MockRead("Proxy-Connection: keep-alive\r\n\r\n"),
Adam Rice425cf122015-01-19 06:18:2416489
16490 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
16491
16492 MockRead("HTTP/1.1 101 Switching Protocols\r\n"),
16493 MockRead("Upgrade: websocket\r\n"),
16494 MockRead("Connection: Upgrade\r\n"),
16495 MockRead("Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=\r\n\r\n"),
16496 };
16497
16498 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
16499 arraysize(data_writes));
16500 session_deps_.socket_factory->AddSocketDataProvider(&data);
16501 SSLSocketDataProvider ssl(ASYNC, OK);
16502 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
16503
bnc87dcefc2017-05-25 12:47:5816504 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:1916505 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
Adam Rice425cf122015-01-19 06:18:2416506 FakeWebSocketStreamCreateHelper websocket_stream_create_helper;
16507 trans->SetWebSocketHandshakeStreamCreateHelper(
16508 &websocket_stream_create_helper);
16509
16510 {
16511 TestCompletionCallback callback;
16512
tfarina42834112016-09-22 13:38:2016513 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0116514 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
Adam Rice425cf122015-01-19 06:18:2416515
16516 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0116517 EXPECT_THAT(rv, IsOk());
Adam Rice425cf122015-01-19 06:18:2416518 }
16519
16520 const HttpResponseInfo* response = trans->GetResponseInfo();
16521 ASSERT_TRUE(response);
wezca1070932016-05-26 20:30:5216522 ASSERT_TRUE(response->headers);
Adam Rice425cf122015-01-19 06:18:2416523 EXPECT_EQ(407, response->headers->response_code());
16524
16525 {
16526 TestCompletionCallback callback;
16527
16528 int rv = trans->RestartWithAuth(AuthCredentials(kFoo, kBar),
16529 callback.callback());
robpercival214763f2016-07-01 23:27:0116530 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
Adam Rice425cf122015-01-19 06:18:2416531
16532 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0116533 EXPECT_THAT(rv, IsOk());
Adam Rice425cf122015-01-19 06:18:2416534 }
16535
16536 response = trans->GetResponseInfo();
16537 ASSERT_TRUE(response);
wezca1070932016-05-26 20:30:5216538 ASSERT_TRUE(response->headers);
Adam Rice425cf122015-01-19 06:18:2416539
16540 EXPECT_EQ(101, response->headers->response_code());
16541
16542 trans.reset();
16543 session->CloseAllConnections();
16544}
16545
16546// Verify that proxy headers are not sent to the destination server when
16547// establishing a tunnel for an insecure WebSocket connection.
16548// This requires the authentication info to be injected into the auth cache
16549// due to crbug.com/395064
16550// TODO(ricea): Change to use a 407 response once issue 395064 is fixed.
bncd16676a2016-07-20 16:23:0116551TEST_F(HttpNetworkTransactionTest, ProxyHeadersNotSentOverWsTunnel) {
Adam Rice425cf122015-01-19 06:18:2416552 HttpRequestInfo request;
16553 request.method = "GET";
bncce36dca22015-04-21 22:11:2316554 request.url = GURL("ws://www.example.org/");
Adam Rice425cf122015-01-19 06:18:2416555 AddWebSocketHeaders(&request.extra_headers);
16556
16557 // Configure against proxy server "myproxy:70".
rdsmith82957ad2015-09-16 19:42:0316558 session_deps_.proxy_service =
16559 ProxyService::CreateFixedFromPacResult("PROXY myproxy:70");
Adam Rice425cf122015-01-19 06:18:2416560
danakj1fd259a02016-04-16 03:17:0916561 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
Adam Rice425cf122015-01-19 06:18:2416562
16563 MockWrite data_writes[] = {
16564 // Try to establish a tunnel for the WebSocket connection, with
16565 // credentials. Because WebSockets have a separate set of socket pools,
16566 // they cannot and will not use the same TCP/IP connection as the
16567 // preflight HTTP request.
16568 MockWrite(
bncce36dca22015-04-21 22:11:2316569 "CONNECT www.example.org:80 HTTP/1.1\r\n"
16570 "Host: www.example.org:80\r\n"
Adam Rice425cf122015-01-19 06:18:2416571 "Proxy-Connection: keep-alive\r\n"
16572 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
16573
16574 MockWrite(
16575 "GET / HTTP/1.1\r\n"
bncce36dca22015-04-21 22:11:2316576 "Host: www.example.org\r\n"
Adam Rice425cf122015-01-19 06:18:2416577 "Connection: Upgrade\r\n"
16578 "Upgrade: websocket\r\n"
bncce36dca22015-04-21 22:11:2316579 "Origin: http://www.example.org\r\n"
Adam Rice425cf122015-01-19 06:18:2416580 "Sec-WebSocket-Version: 13\r\n"
16581 "Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==\r\n\r\n"),
16582 };
16583
16584 MockRead data_reads[] = {
16585 // HTTP CONNECT with credentials.
16586 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
16587
16588 // WebSocket connection established inside tunnel.
16589 MockRead("HTTP/1.1 101 Switching Protocols\r\n"),
16590 MockRead("Upgrade: websocket\r\n"),
16591 MockRead("Connection: Upgrade\r\n"),
16592 MockRead("Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=\r\n\r\n"),
16593 };
16594
16595 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
16596 arraysize(data_writes));
16597 session_deps_.socket_factory->AddSocketDataProvider(&data);
16598
16599 session->http_auth_cache()->Add(
16600 GURL("http://myproxy:70/"), "MyRealm1", HttpAuth::AUTH_SCHEME_BASIC,
16601 "Basic realm=MyRealm1", AuthCredentials(kFoo, kBar), "/");
16602
bnc87dcefc2017-05-25 12:47:5816603 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:1916604 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
Adam Rice425cf122015-01-19 06:18:2416605 FakeWebSocketStreamCreateHelper websocket_stream_create_helper;
16606 trans->SetWebSocketHandshakeStreamCreateHelper(
16607 &websocket_stream_create_helper);
16608
16609 TestCompletionCallback callback;
16610
tfarina42834112016-09-22 13:38:2016611 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0116612 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
Adam Rice425cf122015-01-19 06:18:2416613
16614 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0116615 EXPECT_THAT(rv, IsOk());
Adam Rice425cf122015-01-19 06:18:2416616
16617 const HttpResponseInfo* response = trans->GetResponseInfo();
16618 ASSERT_TRUE(response);
wezca1070932016-05-26 20:30:5216619 ASSERT_TRUE(response->headers);
Adam Rice425cf122015-01-19 06:18:2416620
16621 EXPECT_EQ(101, response->headers->response_code());
16622
16623 trans.reset();
16624 session->CloseAllConnections();
16625}
16626
bncd16676a2016-07-20 16:23:0116627TEST_F(HttpNetworkTransactionTest, TotalNetworkBytesPost) {
danakj1fd259a02016-04-16 03:17:0916628 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:2216629 element_readers.push_back(
Jeremy Roman0579ed62017-08-29 15:56:1916630 std::make_unique<UploadBytesElementReader>("foo", 3));
olli.raula6df48b2a2015-11-26 07:40:2216631 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
sclittlefb249892015-09-10 21:33:2216632
16633 HttpRequestInfo request;
16634 request.method = "POST";
16635 request.url = GURL("http://www.foo.com/");
16636 request.upload_data_stream = &upload_data_stream;
16637
danakj1fd259a02016-04-16 03:17:0916638 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1616639 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
sclittlefb249892015-09-10 21:33:2216640 MockWrite data_writes[] = {
16641 MockWrite("POST / HTTP/1.1\r\n"
16642 "Host: www.foo.com\r\n"
16643 "Connection: keep-alive\r\n"
16644 "Content-Length: 3\r\n\r\n"),
16645 MockWrite("foo"),
16646 };
16647
16648 MockRead data_reads[] = {
16649 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello world"),
16650 MockRead(SYNCHRONOUS, OK),
16651 };
16652 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
16653 arraysize(data_writes));
16654 session_deps_.socket_factory->AddSocketDataProvider(&data);
16655
16656 TestCompletionCallback callback;
16657
16658 EXPECT_EQ(ERR_IO_PENDING,
tfarina42834112016-09-22 13:38:2016659 trans.Start(&request, callback.callback(), NetLogWithSource()));
robpercival214763f2016-07-01 23:27:0116660 EXPECT_THAT(callback.WaitForResult(), IsOk());
sclittlefb249892015-09-10 21:33:2216661
16662 std::string response_data;
bnc691fda62016-08-12 00:43:1616663 EXPECT_THAT(ReadTransaction(&trans, &response_data), IsOk());
sclittlefb249892015-09-10 21:33:2216664
16665 EXPECT_EQ(CountWriteBytes(data_writes, arraysize(data_writes)),
bnc691fda62016-08-12 00:43:1616666 trans.GetTotalSentBytes());
sclittlefb249892015-09-10 21:33:2216667 EXPECT_EQ(CountReadBytes(data_reads, arraysize(data_reads)),
bnc691fda62016-08-12 00:43:1616668 trans.GetTotalReceivedBytes());
sclittlefb249892015-09-10 21:33:2216669}
16670
bncd16676a2016-07-20 16:23:0116671TEST_F(HttpNetworkTransactionTest, TotalNetworkBytesPost100Continue) {
danakj1fd259a02016-04-16 03:17:0916672 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:2216673 element_readers.push_back(
Jeremy Roman0579ed62017-08-29 15:56:1916674 std::make_unique<UploadBytesElementReader>("foo", 3));
olli.raula6df48b2a2015-11-26 07:40:2216675 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
sclittlefb249892015-09-10 21:33:2216676
16677 HttpRequestInfo request;
16678 request.method = "POST";
16679 request.url = GURL("http://www.foo.com/");
16680 request.upload_data_stream = &upload_data_stream;
16681
danakj1fd259a02016-04-16 03:17:0916682 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1616683 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
sclittlefb249892015-09-10 21:33:2216684 MockWrite data_writes[] = {
16685 MockWrite("POST / HTTP/1.1\r\n"
16686 "Host: www.foo.com\r\n"
16687 "Connection: keep-alive\r\n"
16688 "Content-Length: 3\r\n\r\n"),
16689 MockWrite("foo"),
16690 };
16691
16692 MockRead data_reads[] = {
16693 MockRead("HTTP/1.1 100 Continue\r\n\r\n"),
16694 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello world"),
16695 MockRead(SYNCHRONOUS, OK),
16696 };
16697 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
16698 arraysize(data_writes));
16699 session_deps_.socket_factory->AddSocketDataProvider(&data);
16700
16701 TestCompletionCallback callback;
16702
16703 EXPECT_EQ(ERR_IO_PENDING,
tfarina42834112016-09-22 13:38:2016704 trans.Start(&request, callback.callback(), NetLogWithSource()));
robpercival214763f2016-07-01 23:27:0116705 EXPECT_THAT(callback.WaitForResult(), IsOk());
sclittlefb249892015-09-10 21:33:2216706
16707 std::string response_data;
bnc691fda62016-08-12 00:43:1616708 EXPECT_THAT(ReadTransaction(&trans, &response_data), IsOk());
sclittlefb249892015-09-10 21:33:2216709
16710 EXPECT_EQ(CountWriteBytes(data_writes, arraysize(data_writes)),
bnc691fda62016-08-12 00:43:1616711 trans.GetTotalSentBytes());
sclittlefb249892015-09-10 21:33:2216712 EXPECT_EQ(CountReadBytes(data_reads, arraysize(data_reads)),
bnc691fda62016-08-12 00:43:1616713 trans.GetTotalReceivedBytes());
sclittlefb249892015-09-10 21:33:2216714}
16715
bncd16676a2016-07-20 16:23:0116716TEST_F(HttpNetworkTransactionTest, TotalNetworkBytesChunkedPost) {
sclittlefb249892015-09-10 21:33:2216717 ChunkedUploadDataStream upload_data_stream(0);
16718
16719 HttpRequestInfo request;
16720 request.method = "POST";
16721 request.url = GURL("http://www.foo.com/");
16722 request.upload_data_stream = &upload_data_stream;
16723
danakj1fd259a02016-04-16 03:17:0916724 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1616725 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
sclittlefb249892015-09-10 21:33:2216726 // Send headers successfully, but get an error while sending the body.
16727 MockWrite data_writes[] = {
16728 MockWrite("POST / HTTP/1.1\r\n"
16729 "Host: www.foo.com\r\n"
16730 "Connection: keep-alive\r\n"
16731 "Transfer-Encoding: chunked\r\n\r\n"),
16732 MockWrite("1\r\nf\r\n"), MockWrite("2\r\noo\r\n"), MockWrite("0\r\n\r\n"),
16733 };
16734
16735 MockRead data_reads[] = {
16736 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello world"),
16737 MockRead(SYNCHRONOUS, OK),
16738 };
16739 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
16740 arraysize(data_writes));
16741 session_deps_.socket_factory->AddSocketDataProvider(&data);
16742
16743 TestCompletionCallback callback;
16744
16745 EXPECT_EQ(ERR_IO_PENDING,
tfarina42834112016-09-22 13:38:2016746 trans.Start(&request, callback.callback(), NetLogWithSource()));
sclittlefb249892015-09-10 21:33:2216747
16748 base::RunLoop().RunUntilIdle();
16749 upload_data_stream.AppendData("f", 1, false);
16750
16751 base::RunLoop().RunUntilIdle();
16752 upload_data_stream.AppendData("oo", 2, true);
16753
robpercival214763f2016-07-01 23:27:0116754 EXPECT_THAT(callback.WaitForResult(), IsOk());
sclittlefb249892015-09-10 21:33:2216755
16756 std::string response_data;
bnc691fda62016-08-12 00:43:1616757 EXPECT_THAT(ReadTransaction(&trans, &response_data), IsOk());
sclittlefb249892015-09-10 21:33:2216758
16759 EXPECT_EQ(CountWriteBytes(data_writes, arraysize(data_writes)),
bnc691fda62016-08-12 00:43:1616760 trans.GetTotalSentBytes());
sclittlefb249892015-09-10 21:33:2216761 EXPECT_EQ(CountReadBytes(data_reads, arraysize(data_reads)),
bnc691fda62016-08-12 00:43:1616762 trans.GetTotalReceivedBytes());
sclittlefb249892015-09-10 21:33:2216763}
16764
rdsmith1d343be52016-10-21 20:37:5016765// Confirm that transactions whose throttle is created in (and stays in)
16766// the unthrottled state are not blocked.
16767TEST_F(HttpNetworkTransactionTest, ThrottlingUnthrottled) {
16768 TestNetworkStreamThrottler* throttler(nullptr);
16769 std::unique_ptr<HttpNetworkSession> session(
16770 CreateSessionWithThrottler(&session_deps_, &throttler));
16771
16772 // Send a simple request and make sure it goes through.
16773 HttpRequestInfo request;
16774 request.method = "GET";
16775 request.url = GURL("http://www.example.org/");
16776
bnc87dcefc2017-05-25 12:47:5816777 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:1916778 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
rdsmith1d343be52016-10-21 20:37:5016779
16780 MockWrite data_writes[] = {
16781 MockWrite("GET / HTTP/1.1\r\n"
16782 "Host: www.example.org\r\n"
16783 "Connection: keep-alive\r\n\r\n"),
16784 };
16785 MockRead data_reads[] = {
16786 MockRead("HTTP/1.0 200 OK\r\n\r\n"), MockRead("hello world"),
16787 MockRead(SYNCHRONOUS, OK),
16788 };
16789 StaticSocketDataProvider reads(data_reads, arraysize(data_reads), data_writes,
16790 arraysize(data_writes));
16791 session_deps_.socket_factory->AddSocketDataProvider(&reads);
16792
16793 TestCompletionCallback callback;
16794 trans->Start(&request, callback.callback(), NetLogWithSource());
16795 EXPECT_EQ(OK, callback.WaitForResult());
16796}
16797
16798// Confirm requests can be blocked by a throttler, and are resumed
16799// when the throttle is unblocked.
16800TEST_F(HttpNetworkTransactionTest, ThrottlingBasic) {
16801 TestNetworkStreamThrottler* throttler(nullptr);
16802 std::unique_ptr<HttpNetworkSession> session(
16803 CreateSessionWithThrottler(&session_deps_, &throttler));
16804
16805 // Send a simple request and make sure it goes through.
16806 HttpRequestInfo request;
16807 request.method = "GET";
16808 request.url = GURL("http://www.example.org/");
16809
16810 MockWrite data_writes[] = {
16811 MockWrite("GET / HTTP/1.1\r\n"
16812 "Host: www.example.org\r\n"
16813 "Connection: keep-alive\r\n\r\n"),
16814 };
16815 MockRead data_reads[] = {
16816 MockRead("HTTP/1.0 200 OK\r\n\r\n"), MockRead("hello world"),
16817 MockRead(SYNCHRONOUS, OK),
16818 };
16819 StaticSocketDataProvider reads(data_reads, arraysize(data_reads), data_writes,
16820 arraysize(data_writes));
16821 session_deps_.socket_factory->AddSocketDataProvider(&reads);
16822
16823 // Start a request that will be throttled at start; confirm it
16824 // doesn't complete.
16825 throttler->set_throttle_new_requests(true);
bnc87dcefc2017-05-25 12:47:5816826 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:1916827 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
rdsmith1d343be52016-10-21 20:37:5016828
16829 TestCompletionCallback callback;
16830 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
16831 EXPECT_EQ(ERR_IO_PENDING, rv);
16832
16833 base::RunLoop().RunUntilIdle();
16834 EXPECT_EQ(LOAD_STATE_THROTTLED, trans->GetLoadState());
16835 EXPECT_FALSE(callback.have_result());
16836
16837 // Confirm the request goes on to complete when unthrottled.
16838 throttler->UnthrottleAllRequests();
16839 base::RunLoop().RunUntilIdle();
16840 ASSERT_TRUE(callback.have_result());
16841 EXPECT_EQ(OK, callback.WaitForResult());
16842}
16843
16844// Destroy a request while it's throttled.
16845TEST_F(HttpNetworkTransactionTest, ThrottlingDestruction) {
16846 TestNetworkStreamThrottler* throttler(nullptr);
16847 std::unique_ptr<HttpNetworkSession> session(
16848 CreateSessionWithThrottler(&session_deps_, &throttler));
16849
16850 // Send a simple request and make sure it goes through.
16851 HttpRequestInfo request;
16852 request.method = "GET";
16853 request.url = GURL("http://www.example.org/");
16854
16855 MockWrite data_writes[] = {
16856 MockWrite("GET / HTTP/1.1\r\n"
16857 "Host: www.example.org\r\n"
16858 "Connection: keep-alive\r\n\r\n"),
16859 };
16860 MockRead data_reads[] = {
16861 MockRead("HTTP/1.0 200 OK\r\n\r\n"), MockRead("hello world"),
16862 MockRead(SYNCHRONOUS, OK),
16863 };
16864 StaticSocketDataProvider reads(data_reads, arraysize(data_reads), data_writes,
16865 arraysize(data_writes));
16866 session_deps_.socket_factory->AddSocketDataProvider(&reads);
16867
16868 // Start a request that will be throttled at start; confirm it
16869 // doesn't complete.
16870 throttler->set_throttle_new_requests(true);
bnc87dcefc2017-05-25 12:47:5816871 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:1916872 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
rdsmith1d343be52016-10-21 20:37:5016873
16874 TestCompletionCallback callback;
16875 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
16876 EXPECT_EQ(ERR_IO_PENDING, rv);
16877
16878 base::RunLoop().RunUntilIdle();
16879 EXPECT_EQ(LOAD_STATE_THROTTLED, trans->GetLoadState());
16880 EXPECT_FALSE(callback.have_result());
16881
16882 EXPECT_EQ(1u, throttler->num_outstanding_requests());
16883 trans.reset();
16884 EXPECT_EQ(0u, throttler->num_outstanding_requests());
16885}
16886
16887// Confirm the throttler receives SetPriority calls.
16888TEST_F(HttpNetworkTransactionTest, ThrottlingPrioritySet) {
16889 TestNetworkStreamThrottler* throttler(nullptr);
16890 std::unique_ptr<HttpNetworkSession> session(
16891 CreateSessionWithThrottler(&session_deps_, &throttler));
16892
16893 // Send a simple request and make sure it goes through.
16894 HttpRequestInfo request;
16895 request.method = "GET";
16896 request.url = GURL("http://www.example.org/");
16897
16898 MockWrite data_writes[] = {
16899 MockWrite("GET / HTTP/1.1\r\n"
16900 "Host: www.example.org\r\n"
16901 "Connection: keep-alive\r\n\r\n"),
16902 };
16903 MockRead data_reads[] = {
16904 MockRead("HTTP/1.0 200 OK\r\n\r\n"), MockRead("hello world"),
16905 MockRead(SYNCHRONOUS, OK),
16906 };
16907 StaticSocketDataProvider reads(data_reads, arraysize(data_reads), data_writes,
16908 arraysize(data_writes));
16909 session_deps_.socket_factory->AddSocketDataProvider(&reads);
16910
16911 throttler->set_throttle_new_requests(true);
Jeremy Roman0579ed62017-08-29 15:56:1916912 auto trans = std::make_unique<HttpNetworkTransaction>(IDLE, session.get());
rdsmith1d343be52016-10-21 20:37:5016913 // Start the transaction to associate a throttle with it.
16914 TestCompletionCallback callback;
16915 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
16916 EXPECT_EQ(ERR_IO_PENDING, rv);
16917
16918 EXPECT_EQ(0, throttler->num_set_priority_calls());
16919 trans->SetPriority(LOW);
16920 EXPECT_EQ(1, throttler->num_set_priority_calls());
16921 EXPECT_EQ(LOW, throttler->last_priority_set());
16922
16923 throttler->UnthrottleAllRequests();
16924 base::RunLoop().RunUntilIdle();
16925 ASSERT_TRUE(callback.have_result());
16926 EXPECT_EQ(OK, callback.WaitForResult());
16927}
16928
16929// Confirm that unthrottling from a SetPriority call by the
16930// throttler works properly.
16931TEST_F(HttpNetworkTransactionTest, ThrottlingPrioritySetUnthrottle) {
16932 TestNetworkStreamThrottler* throttler(nullptr);
16933 std::unique_ptr<HttpNetworkSession> session(
16934 CreateSessionWithThrottler(&session_deps_, &throttler));
16935
16936 // Send a simple request and make sure it goes through.
16937 HttpRequestInfo request;
16938 request.method = "GET";
16939 request.url = GURL("http://www.example.org/");
16940
16941 MockWrite data_writes[] = {
16942 MockWrite("GET / HTTP/1.1\r\n"
16943 "Host: www.example.org\r\n"
16944 "Connection: keep-alive\r\n\r\n"),
16945 };
16946 MockRead data_reads[] = {
16947 MockRead("HTTP/1.0 200 OK\r\n\r\n"), MockRead("hello world"),
16948 MockRead(SYNCHRONOUS, OK),
16949 };
16950 StaticSocketDataProvider reads(data_reads, arraysize(data_reads), data_writes,
16951 arraysize(data_writes));
16952 session_deps_.socket_factory->AddSocketDataProvider(&reads);
16953
16954 StaticSocketDataProvider reads1(data_reads, arraysize(data_reads),
16955 data_writes, arraysize(data_writes));
16956 session_deps_.socket_factory->AddSocketDataProvider(&reads1);
16957
16958 // Start a request that will be throttled at start; confirm it
16959 // doesn't complete.
16960 throttler->set_throttle_new_requests(true);
bnc87dcefc2017-05-25 12:47:5816961 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:1916962 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
rdsmith1d343be52016-10-21 20:37:5016963
16964 TestCompletionCallback callback;
16965 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
16966 EXPECT_EQ(ERR_IO_PENDING, rv);
16967
16968 base::RunLoop().RunUntilIdle();
16969 EXPECT_EQ(LOAD_STATE_THROTTLED, trans->GetLoadState());
16970 EXPECT_FALSE(callback.have_result());
16971
16972 // Create a new request, call SetPriority on it to unthrottle,
16973 // and make sure that allows the original request to complete.
Jeremy Roman0579ed62017-08-29 15:56:1916974 auto trans1 = std::make_unique<HttpNetworkTransaction>(LOW, session.get());
rdsmith1d343be52016-10-21 20:37:5016975 throttler->set_priority_change_closure(
16976 base::Bind(&TestNetworkStreamThrottler::UnthrottleAllRequests,
16977 base::Unretained(throttler)));
16978
16979 // Start the transaction to associate a throttle with it.
16980 TestCompletionCallback callback1;
16981 rv = trans1->Start(&request, callback1.callback(), NetLogWithSource());
16982 EXPECT_EQ(ERR_IO_PENDING, rv);
16983
16984 trans1->SetPriority(IDLE);
16985
16986 base::RunLoop().RunUntilIdle();
16987 ASSERT_TRUE(callback.have_result());
16988 EXPECT_EQ(OK, callback.WaitForResult());
16989 ASSERT_TRUE(callback1.have_result());
16990 EXPECT_EQ(OK, callback1.WaitForResult());
16991}
16992
16993// Transaction will be destroyed when the unique_ptr goes out of scope.
bnc87dcefc2017-05-25 12:47:5816994void DestroyTransaction(std::unique_ptr<HttpNetworkTransaction> transaction) {}
rdsmith1d343be52016-10-21 20:37:5016995
16996// Confirm that destroying a transaction from a SetPriority call by the
16997// throttler works properly.
16998TEST_F(HttpNetworkTransactionTest, ThrottlingPrioritySetDestroy) {
16999 TestNetworkStreamThrottler* throttler(nullptr);
17000 std::unique_ptr<HttpNetworkSession> session(
17001 CreateSessionWithThrottler(&session_deps_, &throttler));
17002
17003 // Send a simple request and make sure it goes through.
17004 HttpRequestInfo request;
17005 request.method = "GET";
17006 request.url = GURL("http://www.example.org/");
17007
17008 MockWrite data_writes[] = {
17009 MockWrite("GET / HTTP/1.1\r\n"
17010 "Host: www.example.org\r\n"
17011 "Connection: keep-alive\r\n\r\n"),
17012 };
17013 MockRead data_reads[] = {
17014 MockRead("HTTP/1.0 200 OK\r\n\r\n"), MockRead("hello world"),
17015 MockRead(SYNCHRONOUS, OK),
17016 };
17017 StaticSocketDataProvider reads(data_reads, arraysize(data_reads), data_writes,
17018 arraysize(data_writes));
17019 session_deps_.socket_factory->AddSocketDataProvider(&reads);
17020
17021 StaticSocketDataProvider reads1(data_reads, arraysize(data_reads),
17022 data_writes, arraysize(data_writes));
17023 session_deps_.socket_factory->AddSocketDataProvider(&reads1);
17024
17025 // Start a request that will be throttled at start; confirm it
17026 // doesn't complete.
17027 throttler->set_throttle_new_requests(true);
bnc87dcefc2017-05-25 12:47:5817028 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:1917029 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
rdsmith1d343be52016-10-21 20:37:5017030
17031 TestCompletionCallback callback;
17032 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
17033 EXPECT_EQ(ERR_IO_PENDING, rv);
17034
17035 base::RunLoop().RunUntilIdle();
17036 EXPECT_EQ(LOAD_STATE_THROTTLED, trans->GetLoadState());
17037 EXPECT_FALSE(callback.have_result());
17038
17039 // Arrange for the set priority call on the above transaction to delete
17040 // the transaction.
bnc87dcefc2017-05-25 12:47:5817041 HttpNetworkTransaction* trans_ptr(trans.get());
rdsmith1d343be52016-10-21 20:37:5017042 throttler->set_priority_change_closure(
17043 base::Bind(&DestroyTransaction, base::Passed(&trans)));
17044
17045 // Call it and check results (partially a "doesn't crash" test).
17046 trans_ptr->SetPriority(IDLE);
17047 trans_ptr = nullptr; // No longer a valid pointer.
17048
17049 base::RunLoop().RunUntilIdle();
17050 ASSERT_FALSE(callback.have_result());
17051}
17052
nharperb7441ef2016-01-25 23:54:1417053#if !defined(OS_IOS)
bncd16676a2016-07-20 16:23:0117054TEST_F(HttpNetworkTransactionTest, TokenBindingSpdy) {
nharperb7441ef2016-01-25 23:54:1417055 const std::string https_url = "https://www.example.com";
17056 HttpRequestInfo request;
17057 request.url = GURL(https_url);
17058 request.method = "GET";
17059
17060 SSLSocketDataProvider ssl(ASYNC, OK);
17061 ssl.token_binding_negotiated = true;
17062 ssl.token_binding_key_param = TB_PARAM_ECDSAP256;
bnc3cf2a592016-08-11 14:48:3617063 ssl.next_proto = kProtoHTTP2;
nharperb7441ef2016-01-25 23:54:1417064 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
17065
bnc42331402016-07-25 13:36:1517066 SpdySerializedFrame resp(spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
bncdf80d44fd2016-07-15 20:27:4117067 SpdySerializedFrame body(spdy_util_.ConstructSpdyDataFrame(1, true));
17068 MockRead reads[] = {CreateMockRead(resp), CreateMockRead(body),
nharperb7441ef2016-01-25 23:54:1417069 MockRead(ASYNC, ERR_IO_PENDING)};
17070 StaticSocketDataProvider data(reads, arraysize(reads), nullptr, 0);
17071 session_deps_.socket_factory->AddSocketDataProvider(&data);
bnc87dcefc2017-05-25 12:47:5817072 session_deps_.channel_id_service =
Jeremy Roman0579ed62017-08-29 15:56:1917073 std::make_unique<ChannelIDService>(new DefaultChannelIDStore(nullptr));
danakj1fd259a02016-04-16 03:17:0917074 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
nharperb7441ef2016-01-25 23:54:1417075
17076 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
17077 TestCompletionCallback callback;
17078 EXPECT_EQ(ERR_IO_PENDING,
tfarina42834112016-09-22 13:38:2017079 trans.Start(&request, callback.callback(), NetLogWithSource()));
fdorayf33fede2017-05-11 21:18:1017080
17081 NetTestSuite::GetScopedTaskEnvironment()->RunUntilIdle();
nharperb7441ef2016-01-25 23:54:1417082
17083 EXPECT_TRUE(trans.GetResponseInfo()->was_fetched_via_spdy);
17084 HttpRequestHeaders headers;
17085 ASSERT_TRUE(trans.GetFullRequestHeaders(&headers));
17086 EXPECT_TRUE(headers.HasHeader(HttpRequestHeaders::kTokenBinding));
17087}
17088#endif // !defined(OS_IOS)
17089
eustasc7d27da2017-04-06 10:33:2017090void CheckContentEncodingMatching(SpdySessionDependencies* session_deps,
17091 const std::string& accept_encoding,
17092 const std::string& content_encoding,
sky50576f32017-05-01 19:28:0317093 const std::string& location,
eustasc7d27da2017-04-06 10:33:2017094 bool should_match) {
17095 HttpRequestInfo request;
17096 request.method = "GET";
17097 request.url = GURL("http://www.foo.com/");
17098 request.extra_headers.SetHeader(HttpRequestHeaders::kAcceptEncoding,
17099 accept_encoding);
17100
17101 std::unique_ptr<HttpNetworkSession> session(CreateSession(session_deps));
17102 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
17103 // Send headers successfully, but get an error while sending the body.
17104 MockWrite data_writes[] = {
17105 MockWrite("GET / HTTP/1.1\r\n"
17106 "Host: www.foo.com\r\n"
17107 "Connection: keep-alive\r\n"
17108 "Accept-Encoding: "),
17109 MockWrite(accept_encoding.data()), MockWrite("\r\n\r\n"),
17110 };
17111
sky50576f32017-05-01 19:28:0317112 std::string response_code = "200 OK";
17113 std::string extra;
17114 if (!location.empty()) {
17115 response_code = "301 Redirect\r\nLocation: ";
17116 response_code.append(location);
17117 }
17118
eustasc7d27da2017-04-06 10:33:2017119 MockRead data_reads[] = {
sky50576f32017-05-01 19:28:0317120 MockRead("HTTP/1.0 "),
17121 MockRead(response_code.data()),
17122 MockRead("\r\nContent-Encoding: "),
17123 MockRead(content_encoding.data()),
17124 MockRead("\r\n\r\n"),
eustasc7d27da2017-04-06 10:33:2017125 MockRead(SYNCHRONOUS, OK),
17126 };
17127 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
17128 arraysize(data_writes));
17129 session_deps->socket_factory->AddSocketDataProvider(&data);
17130
17131 TestCompletionCallback callback;
17132
17133 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
17134 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
17135
17136 rv = callback.WaitForResult();
17137 if (should_match) {
17138 EXPECT_THAT(rv, IsOk());
17139 } else {
17140 EXPECT_THAT(rv, IsError(ERR_CONTENT_DECODING_FAILED));
17141 }
17142}
17143
17144TEST_F(HttpNetworkTransactionTest, MatchContentEncoding1) {
sky50576f32017-05-01 19:28:0317145 CheckContentEncodingMatching(&session_deps_, "gzip,sdch", "br", "", false);
eustasc7d27da2017-04-06 10:33:2017146}
17147
17148TEST_F(HttpNetworkTransactionTest, MatchContentEncoding2) {
sky50576f32017-05-01 19:28:0317149 CheckContentEncodingMatching(&session_deps_, "identity;q=1, *;q=0", "", "",
17150 true);
eustasc7d27da2017-04-06 10:33:2017151}
17152
17153TEST_F(HttpNetworkTransactionTest, MatchContentEncoding3) {
17154 CheckContentEncodingMatching(&session_deps_, "identity;q=1, *;q=0", "gzip",
sky50576f32017-05-01 19:28:0317155 "", false);
17156}
17157
17158TEST_F(HttpNetworkTransactionTest, MatchContentEncoding4) {
17159 CheckContentEncodingMatching(&session_deps_, "identity;q=1, *;q=0", "gzip",
17160 "www.foo.com/other", true);
eustasc7d27da2017-04-06 10:33:2017161}
17162
xunjieli96f2a402017-06-05 17:24:2717163TEST_F(HttpNetworkTransactionTest, ProxyResolutionFailsSync) {
17164 ProxyConfig proxy_config;
17165 proxy_config.set_pac_url(GURL("http://fooproxyurl"));
17166 proxy_config.set_pac_mandatory(true);
17167 MockAsyncProxyResolver resolver;
17168 session_deps_.proxy_service.reset(new ProxyService(
Jeremy Roman0579ed62017-08-29 15:56:1917169 std::make_unique<ProxyConfigServiceFixed>(proxy_config),
xunjieli96f2a402017-06-05 17:24:2717170 base::WrapUnique(new FailingProxyResolverFactory), nullptr));
17171
17172 HttpRequestInfo request;
17173 request.method = "GET";
17174 request.url = GURL("http://www.example.org/");
17175
17176 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
17177 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
17178
17179 TestCompletionCallback callback;
17180
17181 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
17182 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
17183 EXPECT_THAT(callback.WaitForResult(),
17184 IsError(ERR_MANDATORY_PROXY_CONFIGURATION_FAILED));
17185}
17186
17187TEST_F(HttpNetworkTransactionTest, ProxyResolutionFailsAsync) {
17188 ProxyConfig proxy_config;
17189 proxy_config.set_pac_url(GURL("http://fooproxyurl"));
17190 proxy_config.set_pac_mandatory(true);
17191 MockAsyncProxyResolverFactory* proxy_resolver_factory =
17192 new MockAsyncProxyResolverFactory(false);
17193 MockAsyncProxyResolver resolver;
17194 session_deps_.proxy_service.reset(
Jeremy Roman0579ed62017-08-29 15:56:1917195 new ProxyService(std::make_unique<ProxyConfigServiceFixed>(proxy_config),
xunjieli96f2a402017-06-05 17:24:2717196 base::WrapUnique(proxy_resolver_factory), nullptr));
17197 HttpRequestInfo request;
17198 request.method = "GET";
17199 request.url = GURL("http://www.example.org/");
17200
17201 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
17202 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
17203
17204 TestCompletionCallback callback;
17205 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
17206 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
17207
17208 proxy_resolver_factory->pending_requests()[0]->CompleteNowWithForwarder(
17209 ERR_FAILED, &resolver);
17210 EXPECT_THAT(callback.WaitForResult(),
17211 IsError(ERR_MANDATORY_PROXY_CONFIGURATION_FAILED));
17212}
17213
17214TEST_F(HttpNetworkTransactionTest, NoSupportedProxies) {
17215 session_deps_.proxy_service =
17216 ProxyService::CreateFixedFromPacResult("QUIC myproxy.org:443");
17217 session_deps_.enable_quic = false;
17218 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
17219
17220 HttpRequestInfo request;
17221 request.method = "GET";
17222 request.url = GURL("http://www.example.org/");
17223
17224 TestCompletionCallback callback;
17225 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
17226 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
17227 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
17228
17229 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_NO_SUPPORTED_PROXIES));
17230}
17231
[email protected]89ceba9a2009-03-21 03:46:0617232} // namespace net