blob: 0f1f7ffb358bdb19d9c183c2830cc8e7dca66384 [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);
asanka098c0092016-06-16 20:18:43808 EXPECT_EQ("http://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";
5953 request.url = GURL("http://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
[email protected]49639fa2011-12-20 23:22:416035 TestCompletionCallback callback1;
[email protected]3f918782009-02-28 01:29:246036
bnc691fda62016-08-12 00:43:166037 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]0b0bf032010-09-21 18:08:506038
tfarina42834112016-09-22 13:38:206039 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:016040 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]3f918782009-02-28 01:29:246041
6042 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:016043 EXPECT_THAT(rv, IsOk());
[email protected]3f918782009-02-28 01:29:246044
bnc691fda62016-08-12 00:43:166045 EXPECT_FALSE(trans.IsReadyToRestartForAuth());
[email protected]0757e7702009-03-27 04:00:226046
bnc691fda62016-08-12 00:43:166047 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:526048 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:046049 EXPECT_TRUE(CheckNTLMServerAuth(response->auth_challenge.get()));
[email protected]3f918782009-02-28 01:29:246050
[email protected]49639fa2011-12-20 23:22:416051 TestCompletionCallback callback2;
[email protected]10af5fe72011-01-31 16:17:256052
bnc691fda62016-08-12 00:43:166053 rv = trans.RestartWithAuth(AuthCredentials(kTestingNTLM, kTestingNTLM),
6054 callback2.callback());
robpercival214763f2016-07-01 23:27:016055 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]10af5fe72011-01-31 16:17:256056
6057 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:016058 EXPECT_THAT(rv, IsOk());
[email protected]10af5fe72011-01-31 16:17:256059
bnc691fda62016-08-12 00:43:166060 EXPECT_TRUE(trans.IsReadyToRestartForAuth());
[email protected]10af5fe72011-01-31 16:17:256061
bnc691fda62016-08-12 00:43:166062 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:526063 ASSERT_TRUE(response);
6064 EXPECT_FALSE(response->auth_challenge);
[email protected]10af5fe72011-01-31 16:17:256065
[email protected]49639fa2011-12-20 23:22:416066 TestCompletionCallback callback3;
[email protected]3f918782009-02-28 01:29:246067
bnc691fda62016-08-12 00:43:166068 rv = trans.RestartWithAuth(AuthCredentials(), callback3.callback());
robpercival214763f2016-07-01 23:27:016069 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]3f918782009-02-28 01:29:246070
[email protected]0757e7702009-03-27 04:00:226071 rv = callback3.WaitForResult();
robpercival214763f2016-07-01 23:27:016072 EXPECT_THAT(rv, IsOk());
[email protected]3f918782009-02-28 01:29:246073
bnc691fda62016-08-12 00:43:166074 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:526075 ASSERT_TRUE(response);
6076 EXPECT_FALSE(response->auth_challenge);
[email protected]3f918782009-02-28 01:29:246077 EXPECT_EQ(13, response->headers->GetContentLength());
6078}
6079
[email protected]385a4672009-03-11 22:21:296080// Enter a wrong password, and then the correct one.
bncd16676a2016-07-20 16:23:016081TEST_F(HttpNetworkTransactionTest, NTLMAuth2) {
[email protected]1c773ea12009-04-28 19:58:426082 HttpRequestInfo request;
[email protected]385a4672009-03-11 22:21:296083 request.method = "GET";
6084 request.url = GURL("http://172.22.68.17/kids/login.aspx");
[email protected]385a4672009-03-11 22:21:296085
[email protected]cb9bf6ca2011-01-28 13:15:276086 HttpAuthHandlerNTLM::ScopedProcSetter proc_setter(MockGenerateRandom2,
6087 MockGetHostName);
danakj1fd259a02016-04-16 03:17:096088 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:276089
[email protected]385a4672009-03-11 22:21:296090 MockWrite data_writes1[] = {
6091 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
6092 "Host: 172.22.68.17\r\n"
6093 "Connection: keep-alive\r\n\r\n"),
6094 };
6095
6096 MockRead data_reads1[] = {
6097 MockRead("HTTP/1.1 401 Access Denied\r\n"),
[email protected]aef04272010-06-28 18:03:046098 // Negotiate and NTLM are often requested together. However, we only want
6099 // to test NTLM. Since Negotiate is preferred over NTLM, we have to skip
6100 // the header that requests Negotiate for this test.
[email protected]385a4672009-03-11 22:21:296101 MockRead("WWW-Authenticate: NTLM\r\n"),
6102 MockRead("Connection: close\r\n"),
6103 MockRead("Content-Length: 42\r\n"),
[email protected]076c85082009-04-10 23:21:366104 MockRead("Content-Type: text/html\r\n\r\n"),
[email protected]385a4672009-03-11 22:21:296105 // Missing content -- won't matter, as connection will be reset.
[email protected]8ddf8322012-02-23 18:08:066106 MockRead(SYNCHRONOUS, ERR_UNEXPECTED),
[email protected]385a4672009-03-11 22:21:296107 };
6108
6109 MockWrite data_writes2[] = {
bnc691fda62016-08-12 00:43:166110 // After restarting with a null identity, this is the
6111 // request we should be issuing -- the final header line contains a Type
6112 // 1 message.
6113 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
6114 "Host: 172.22.68.17\r\n"
6115 "Connection: keep-alive\r\n"
6116 "Authorization: NTLM "
6117 "TlRMTVNTUAABAAAAB4IIAAAAAAAAAAAAAAAAAAAAAAA=\r\n\r\n"),
[email protected]385a4672009-03-11 22:21:296118
bnc691fda62016-08-12 00:43:166119 // After calling trans.RestartWithAuth(), we should send a Type 3 message
6120 // (the credentials for the origin server). The second request continues
6121 // on the same connection.
6122 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
6123 "Host: 172.22.68.17\r\n"
6124 "Connection: keep-alive\r\n"
6125 "Authorization: NTLM TlRMTVNTUAADAAAAGAAYAGgAAAAYABgAgA"
6126 "AAAAAAAABAAAAAGAAYAEAAAAAQABAAWAAAAAAAAAAAAAAABYIIAHQA"
6127 "ZQBzAHQAaQBuAGcALQBuAHQAbABtAFcAVABDAC0AVwBJAE4ANwCWeY"
6128 "XnSZNwoQAAAAAAAAAAAAAAAAAAAADLa34/phTTKzNTWdub+uyFleOj"
6129 "4Ww7b7E=\r\n\r\n"),
[email protected]385a4672009-03-11 22:21:296130 };
6131
6132 MockRead data_reads2[] = {
6133 // The origin server responds with a Type 2 message.
6134 MockRead("HTTP/1.1 401 Access Denied\r\n"),
6135 MockRead("WWW-Authenticate: NTLM "
6136 "TlRMTVNTUAACAAAADAAMADgAAAAFgokCbVWUZezVGpAAAAAAAAAAALo"
6137 "AugBEAAAABQEoCgAAAA9HAE8ATwBHAEwARQACAAwARwBPAE8ARwBMAE"
6138 "UAAQAaAEEASwBFAEUAUwBBAFIAQQAtAEMATwBSAFAABAAeAGMAbwByA"
6139 "HAALgBnAG8AbwBnAGwAZQAuAGMAbwBtAAMAQABhAGsAZQBlAHMAYQBy"
6140 "AGEALQBjAG8AcgBwAC4AYQBkAC4AYwBvAHIAcAAuAGcAbwBvAGcAbAB"
6141 "lAC4AYwBvAG0ABQAeAGMAbwByAHAALgBnAG8AbwBnAGwAZQAuAGMAbw"
6142 "BtAAAAAAA=\r\n"),
6143 MockRead("Content-Length: 42\r\n"),
[email protected]076c85082009-04-10 23:21:366144 MockRead("Content-Type: text/html\r\n\r\n"),
[email protected]385a4672009-03-11 22:21:296145 MockRead("You are not authorized to view this page\r\n"),
6146
6147 // Wrong password.
6148 MockRead("HTTP/1.1 401 Access Denied\r\n"),
[email protected]385a4672009-03-11 22:21:296149 MockRead("WWW-Authenticate: NTLM\r\n"),
6150 MockRead("Connection: close\r\n"),
6151 MockRead("Content-Length: 42\r\n"),
[email protected]076c85082009-04-10 23:21:366152 MockRead("Content-Type: text/html\r\n\r\n"),
[email protected]385a4672009-03-11 22:21:296153 // Missing content -- won't matter, as connection will be reset.
[email protected]8ddf8322012-02-23 18:08:066154 MockRead(SYNCHRONOUS, ERR_UNEXPECTED),
[email protected]385a4672009-03-11 22:21:296155 };
6156
6157 MockWrite data_writes3[] = {
bnc691fda62016-08-12 00:43:166158 // After restarting with a null identity, this is the
6159 // request we should be issuing -- the final header line contains a Type
6160 // 1 message.
6161 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
6162 "Host: 172.22.68.17\r\n"
6163 "Connection: keep-alive\r\n"
6164 "Authorization: NTLM "
6165 "TlRMTVNTUAABAAAAB4IIAAAAAAAAAAAAAAAAAAAAAAA=\r\n\r\n"),
[email protected]385a4672009-03-11 22:21:296166
bnc691fda62016-08-12 00:43:166167 // After calling trans.RestartWithAuth(), we should send a Type 3 message
6168 // (the credentials for the origin server). The second request continues
6169 // on the same connection.
6170 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
6171 "Host: 172.22.68.17\r\n"
6172 "Connection: keep-alive\r\n"
6173 "Authorization: NTLM TlRMTVNTUAADAAAAGAAYAGgAAAAYABgAgA"
6174 "AAAAAAAABAAAAAGAAYAEAAAAAQABAAWAAAAAAAAAAAAAAABYIIAHQA"
6175 "ZQBzAHQAaQBuAGcALQBuAHQAbABtAFcAVABDAC0AVwBJAE4ANwBO54"
6176 "dFMVvTHwAAAAAAAAAAAAAAAAAAAACS7sT6Uzw7L0L//WUqlIaVWpbI"
6177 "+4MUm7c=\r\n\r\n"),
[email protected]385a4672009-03-11 22:21:296178 };
6179
6180 MockRead data_reads3[] = {
6181 // The origin server responds with a Type 2 message.
6182 MockRead("HTTP/1.1 401 Access Denied\r\n"),
6183 MockRead("WWW-Authenticate: NTLM "
6184 "TlRMTVNTUAACAAAADAAMADgAAAAFgokCL24VN8dgOR8AAAAAAAAAALo"
6185 "AugBEAAAABQEoCgAAAA9HAE8ATwBHAEwARQACAAwARwBPAE8ARwBMAE"
6186 "UAAQAaAEEASwBFAEUAUwBBAFIAQQAtAEMATwBSAFAABAAeAGMAbwByA"
6187 "HAALgBnAG8AbwBnAGwAZQAuAGMAbwBtAAMAQABhAGsAZQBlAHMAYQBy"
6188 "AGEALQBjAG8AcgBwAC4AYQBkAC4AYwBvAHIAcAAuAGcAbwBvAGcAbAB"
6189 "lAC4AYwBvAG0ABQAeAGMAbwByAHAALgBnAG8AbwBnAGwAZQAuAGMAbw"
6190 "BtAAAAAAA=\r\n"),
6191 MockRead("Content-Length: 42\r\n"),
[email protected]076c85082009-04-10 23:21:366192 MockRead("Content-Type: text/html\r\n\r\n"),
[email protected]385a4672009-03-11 22:21:296193 MockRead("You are not authorized to view this page\r\n"),
6194
6195 // Lastly we get the desired content.
6196 MockRead("HTTP/1.1 200 OK\r\n"),
6197 MockRead("Content-Type: text/html; charset=utf-8\r\n"),
6198 MockRead("Content-Length: 13\r\n\r\n"),
6199 MockRead("Please Login\r\n"),
[email protected]8ddf8322012-02-23 18:08:066200 MockRead(SYNCHRONOUS, OK),
[email protected]385a4672009-03-11 22:21:296201 };
6202
[email protected]31a2bfe2010-02-09 08:03:396203 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
6204 data_writes1, arraysize(data_writes1));
6205 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
6206 data_writes2, arraysize(data_writes2));
6207 StaticSocketDataProvider data3(data_reads3, arraysize(data_reads3),
6208 data_writes3, arraysize(data_writes3));
[email protected]bb88e1d32013-05-03 23:11:076209 session_deps_.socket_factory->AddSocketDataProvider(&data1);
6210 session_deps_.socket_factory->AddSocketDataProvider(&data2);
6211 session_deps_.socket_factory->AddSocketDataProvider(&data3);
[email protected]385a4672009-03-11 22:21:296212
[email protected]49639fa2011-12-20 23:22:416213 TestCompletionCallback callback1;
[email protected]385a4672009-03-11 22:21:296214
bnc691fda62016-08-12 00:43:166215 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]0b0bf032010-09-21 18:08:506216
tfarina42834112016-09-22 13:38:206217 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:016218 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]385a4672009-03-11 22:21:296219
6220 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:016221 EXPECT_THAT(rv, IsOk());
[email protected]385a4672009-03-11 22:21:296222
bnc691fda62016-08-12 00:43:166223 EXPECT_FALSE(trans.IsReadyToRestartForAuth());
[email protected]385a4672009-03-11 22:21:296224
bnc691fda62016-08-12 00:43:166225 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:526226 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:046227 EXPECT_TRUE(CheckNTLMServerAuth(response->auth_challenge.get()));
[email protected]385a4672009-03-11 22:21:296228
[email protected]49639fa2011-12-20 23:22:416229 TestCompletionCallback callback2;
[email protected]385a4672009-03-11 22:21:296230
[email protected]0757e7702009-03-27 04:00:226231 // Enter the wrong password.
bnc691fda62016-08-12 00:43:166232 rv = trans.RestartWithAuth(AuthCredentials(kTestingNTLM, kWrongPassword),
6233 callback2.callback());
robpercival214763f2016-07-01 23:27:016234 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]385a4672009-03-11 22:21:296235
[email protected]10af5fe72011-01-31 16:17:256236 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:016237 EXPECT_THAT(rv, IsOk());
[email protected]385a4672009-03-11 22:21:296238
bnc691fda62016-08-12 00:43:166239 EXPECT_TRUE(trans.IsReadyToRestartForAuth());
[email protected]49639fa2011-12-20 23:22:416240 TestCompletionCallback callback3;
bnc691fda62016-08-12 00:43:166241 rv = trans.RestartWithAuth(AuthCredentials(), callback3.callback());
robpercival214763f2016-07-01 23:27:016242 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]10af5fe72011-01-31 16:17:256243 rv = callback3.WaitForResult();
robpercival214763f2016-07-01 23:27:016244 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:166245 EXPECT_FALSE(trans.IsReadyToRestartForAuth());
[email protected]0757e7702009-03-27 04:00:226246
bnc691fda62016-08-12 00:43:166247 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:526248 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:046249 EXPECT_TRUE(CheckNTLMServerAuth(response->auth_challenge.get()));
[email protected]0757e7702009-03-27 04:00:226250
[email protected]49639fa2011-12-20 23:22:416251 TestCompletionCallback callback4;
[email protected]0757e7702009-03-27 04:00:226252
6253 // Now enter the right password.
bnc691fda62016-08-12 00:43:166254 rv = trans.RestartWithAuth(AuthCredentials(kTestingNTLM, kTestingNTLM),
6255 callback4.callback());
robpercival214763f2016-07-01 23:27:016256 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]10af5fe72011-01-31 16:17:256257
6258 rv = callback4.WaitForResult();
robpercival214763f2016-07-01 23:27:016259 EXPECT_THAT(rv, IsOk());
[email protected]10af5fe72011-01-31 16:17:256260
bnc691fda62016-08-12 00:43:166261 EXPECT_TRUE(trans.IsReadyToRestartForAuth());
[email protected]10af5fe72011-01-31 16:17:256262
[email protected]49639fa2011-12-20 23:22:416263 TestCompletionCallback callback5;
[email protected]10af5fe72011-01-31 16:17:256264
6265 // One more roundtrip
bnc691fda62016-08-12 00:43:166266 rv = trans.RestartWithAuth(AuthCredentials(), callback5.callback());
robpercival214763f2016-07-01 23:27:016267 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]0757e7702009-03-27 04:00:226268
6269 rv = callback5.WaitForResult();
robpercival214763f2016-07-01 23:27:016270 EXPECT_THAT(rv, IsOk());
[email protected]0757e7702009-03-27 04:00:226271
bnc691fda62016-08-12 00:43:166272 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:526273 EXPECT_FALSE(response->auth_challenge);
[email protected]385a4672009-03-11 22:21:296274 EXPECT_EQ(13, response->headers->GetContentLength());
6275}
[email protected]ea9dc9a2009-09-05 00:43:326276#endif // NTLM_PORTABLE
[email protected]385a4672009-03-11 22:21:296277
[email protected]4ddaf2502008-10-23 18:26:196278// Test reading a server response which has only headers, and no body.
6279// After some maximum number of bytes is consumed, the transaction should
6280// fail with ERR_RESPONSE_HEADERS_TOO_BIG.
bncd16676a2016-07-20 16:23:016281TEST_F(HttpNetworkTransactionTest, LargeHeadersNoBody) {
[email protected]1c773ea12009-04-28 19:58:426282 HttpRequestInfo request;
[email protected]4ddaf2502008-10-23 18:26:196283 request.method = "GET";
bncce36dca22015-04-21 22:11:236284 request.url = GURL("http://www.example.org/");
[email protected]4ddaf2502008-10-23 18:26:196285
danakj1fd259a02016-04-16 03:17:096286 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:166287 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:276288
[email protected]b75b7b2f2009-10-06 00:54:536289 // Respond with 300 kb of headers (we should fail after 256 kb).
[email protected]15a5ccf82008-10-23 19:57:436290 std::string large_headers_string;
[email protected]b75b7b2f2009-10-06 00:54:536291 FillLargeHeadersString(&large_headers_string, 300 * 1024);
[email protected]4ddaf2502008-10-23 18:26:196292
6293 MockRead data_reads[] = {
6294 MockRead("HTTP/1.0 200 OK\r\n"),
[email protected]8ddf8322012-02-23 18:08:066295 MockRead(ASYNC, large_headers_string.data(), large_headers_string.size()),
[email protected]4ddaf2502008-10-23 18:26:196296 MockRead("\r\nBODY"),
[email protected]8ddf8322012-02-23 18:08:066297 MockRead(SYNCHRONOUS, OK),
[email protected]4ddaf2502008-10-23 18:26:196298 };
[email protected]31a2bfe2010-02-09 08:03:396299 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:076300 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]4ddaf2502008-10-23 18:26:196301
[email protected]49639fa2011-12-20 23:22:416302 TestCompletionCallback callback;
[email protected]4ddaf2502008-10-23 18:26:196303
tfarina42834112016-09-22 13:38:206304 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:016305 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]4ddaf2502008-10-23 18:26:196306
6307 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:016308 EXPECT_THAT(rv, IsError(ERR_RESPONSE_HEADERS_TOO_BIG));
[email protected]4ddaf2502008-10-23 18:26:196309}
[email protected]f4e426b2008-11-05 00:24:496310
6311// Make sure that we don't try to reuse a TCPClientSocket when failing to
6312// establish tunnel.
6313// http://code.google.com/p/chromium/issues/detail?id=3772
bncd16676a2016-07-20 16:23:016314TEST_F(HttpNetworkTransactionTest, DontRecycleTransportSocketForSSLTunnel) {
[email protected]cb9bf6ca2011-01-28 13:15:276315 HttpRequestInfo request;
6316 request.method = "GET";
bncce36dca22015-04-21 22:11:236317 request.url = GURL("https://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:276318
[email protected]f4e426b2008-11-05 00:24:496319 // Configure against proxy server "myproxy:70".
rdsmith82957ad2015-09-16 19:42:036320 session_deps_.proxy_service = ProxyService::CreateFixed("myproxy:70");
[email protected]db8f44c2008-12-13 04:52:016321
danakj1fd259a02016-04-16 03:17:096322 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]f4e426b2008-11-05 00:24:496323
bnc87dcefc2017-05-25 12:47:586324 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:196325 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]f4e426b2008-11-05 00:24:496326
[email protected]f4e426b2008-11-05 00:24:496327 // Since we have proxy, should try to establish tunnel.
6328 MockWrite data_writes1[] = {
rsleevidb16bb02015-11-12 23:47:176329 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
6330 "Host: www.example.org:443\r\n"
6331 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]f4e426b2008-11-05 00:24:496332 };
6333
[email protected]77848d12008-11-14 00:00:226334 // The proxy responds to the connect with a 404, using a persistent
[email protected]f4e426b2008-11-05 00:24:496335 // connection. Usually a proxy would return 501 (not implemented),
6336 // or 200 (tunnel established).
6337 MockRead data_reads1[] = {
mmenked39192ee2015-12-09 00:57:236338 MockRead("HTTP/1.1 404 Not Found\r\n"),
6339 MockRead("Content-Length: 10\r\n\r\n"),
6340 MockRead(SYNCHRONOUS, ERR_UNEXPECTED),
[email protected]f4e426b2008-11-05 00:24:496341 };
6342
[email protected]31a2bfe2010-02-09 08:03:396343 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
6344 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:076345 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]f4e426b2008-11-05 00:24:496346
[email protected]49639fa2011-12-20 23:22:416347 TestCompletionCallback callback1;
[email protected]f4e426b2008-11-05 00:24:496348
tfarina42834112016-09-22 13:38:206349 int rv = trans->Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:016350 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]f4e426b2008-11-05 00:24:496351
6352 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:016353 EXPECT_THAT(rv, IsError(ERR_TUNNEL_CONNECTION_FAILED));
[email protected]f4e426b2008-11-05 00:24:496354
[email protected]b4404c02009-04-10 16:38:526355 // Empty the current queue. This is necessary because idle sockets are
6356 // added to the connection pool asynchronously with a PostTask.
fdoray92e35a72016-06-10 15:54:556357 base::RunLoop().RunUntilIdle();
[email protected]b4404c02009-04-10 16:38:526358
[email protected]f4e426b2008-11-05 00:24:496359 // We now check to make sure the TCPClientSocket was not added back to
6360 // the pool.
[email protected]90499482013-06-01 00:39:506361 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]f4e426b2008-11-05 00:24:496362 trans.reset();
fdoray92e35a72016-06-10 15:54:556363 base::RunLoop().RunUntilIdle();
[email protected]f4e426b2008-11-05 00:24:496364 // Make sure that the socket didn't get recycled after calling the destructor.
[email protected]90499482013-06-01 00:39:506365 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]f4e426b2008-11-05 00:24:496366}
[email protected]372d34a2008-11-05 21:30:516367
[email protected]1b157c02009-04-21 01:55:406368// Make sure that we recycle a socket after reading all of the response body.
bncd16676a2016-07-20 16:23:016369TEST_F(HttpNetworkTransactionTest, RecycleSocket) {
[email protected]1c773ea12009-04-28 19:58:426370 HttpRequestInfo request;
[email protected]1b157c02009-04-21 01:55:406371 request.method = "GET";
bncce36dca22015-04-21 22:11:236372 request.url = GURL("http://www.example.org/");
[email protected]1b157c02009-04-21 01:55:406373
danakj1fd259a02016-04-16 03:17:096374 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:276375
bnc691fda62016-08-12 00:43:166376 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:276377
[email protected]1b157c02009-04-21 01:55:406378 MockRead data_reads[] = {
6379 // A part of the response body is received with the response headers.
6380 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 11\r\n\r\nhel"),
6381 // The rest of the response body is received in two parts.
6382 MockRead("lo"),
6383 MockRead(" world"),
6384 MockRead("junk"), // Should not be read!!
[email protected]8ddf8322012-02-23 18:08:066385 MockRead(SYNCHRONOUS, OK),
[email protected]1b157c02009-04-21 01:55:406386 };
6387
[email protected]31a2bfe2010-02-09 08:03:396388 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:076389 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1b157c02009-04-21 01:55:406390
[email protected]49639fa2011-12-20 23:22:416391 TestCompletionCallback callback;
[email protected]1b157c02009-04-21 01:55:406392
tfarina42834112016-09-22 13:38:206393 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:016394 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]1b157c02009-04-21 01:55:406395
6396 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:016397 EXPECT_THAT(rv, IsOk());
[email protected]1b157c02009-04-21 01:55:406398
bnc691fda62016-08-12 00:43:166399 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:526400 ASSERT_TRUE(response);
[email protected]1b157c02009-04-21 01:55:406401
wezca1070932016-05-26 20:30:526402 EXPECT_TRUE(response->headers);
[email protected]1b157c02009-04-21 01:55:406403 std::string status_line = response->headers->GetStatusLine();
6404 EXPECT_EQ("HTTP/1.1 200 OK", status_line);
6405
[email protected]90499482013-06-01 00:39:506406 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]1b157c02009-04-21 01:55:406407
6408 std::string response_data;
bnc691fda62016-08-12 00:43:166409 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:016410 EXPECT_THAT(rv, IsOk());
[email protected]1b157c02009-04-21 01:55:406411 EXPECT_EQ("hello world", response_data);
6412
6413 // Empty the current queue. This is necessary because idle sockets are
6414 // added to the connection pool asynchronously with a PostTask.
fdoray92e35a72016-06-10 15:54:556415 base::RunLoop().RunUntilIdle();
[email protected]1b157c02009-04-21 01:55:406416
6417 // We now check to make sure the socket was added back to the pool.
[email protected]90499482013-06-01 00:39:506418 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]1b157c02009-04-21 01:55:406419}
6420
[email protected]76a505b2010-08-25 06:23:006421// Make sure that we recycle a SSL socket after reading all of the response
6422// body.
bncd16676a2016-07-20 16:23:016423TEST_F(HttpNetworkTransactionTest, RecycleSSLSocket) {
[email protected]76a505b2010-08-25 06:23:006424 HttpRequestInfo request;
6425 request.method = "GET";
bncce36dca22015-04-21 22:11:236426 request.url = GURL("https://www.example.org/");
[email protected]76a505b2010-08-25 06:23:006427
6428 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:236429 MockWrite(
6430 "GET / HTTP/1.1\r\n"
6431 "Host: www.example.org\r\n"
6432 "Connection: keep-alive\r\n\r\n"),
[email protected]76a505b2010-08-25 06:23:006433 };
6434
6435 MockRead data_reads[] = {
6436 MockRead("HTTP/1.1 200 OK\r\n"),
6437 MockRead("Content-Length: 11\r\n\r\n"),
6438 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:066439 MockRead(SYNCHRONOUS, OK),
[email protected]76a505b2010-08-25 06:23:006440 };
6441
[email protected]8ddf8322012-02-23 18:08:066442 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:076443 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]76a505b2010-08-25 06:23:006444
6445 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
6446 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:076447 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]76a505b2010-08-25 06:23:006448
[email protected]49639fa2011-12-20 23:22:416449 TestCompletionCallback callback;
[email protected]76a505b2010-08-25 06:23:006450
danakj1fd259a02016-04-16 03:17:096451 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:166452 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]76a505b2010-08-25 06:23:006453
tfarina42834112016-09-22 13:38:206454 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
[email protected]76a505b2010-08-25 06:23:006455
robpercival214763f2016-07-01 23:27:016456 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
6457 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]76a505b2010-08-25 06:23:006458
bnc691fda62016-08-12 00:43:166459 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:526460 ASSERT_TRUE(response);
6461 ASSERT_TRUE(response->headers);
[email protected]76a505b2010-08-25 06:23:006462 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
6463
[email protected]90499482013-06-01 00:39:506464 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]76a505b2010-08-25 06:23:006465
6466 std::string response_data;
bnc691fda62016-08-12 00:43:166467 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:016468 EXPECT_THAT(rv, IsOk());
[email protected]76a505b2010-08-25 06:23:006469 EXPECT_EQ("hello world", response_data);
6470
6471 // Empty the current queue. This is necessary because idle sockets are
6472 // added to the connection pool asynchronously with a PostTask.
fdoray92e35a72016-06-10 15:54:556473 base::RunLoop().RunUntilIdle();
[email protected]76a505b2010-08-25 06:23:006474
6475 // We now check to make sure the socket was added back to the pool.
[email protected]90499482013-06-01 00:39:506476 EXPECT_EQ(1, GetIdleSocketCountInSSLSocketPool(session.get()));
[email protected]76a505b2010-08-25 06:23:006477}
6478
6479// Grab a SSL socket, use it, and put it back into the pool. Then, reuse it
6480// from the pool and make sure that we recover okay.
bncd16676a2016-07-20 16:23:016481TEST_F(HttpNetworkTransactionTest, RecycleDeadSSLSocket) {
[email protected]76a505b2010-08-25 06:23:006482 HttpRequestInfo request;
6483 request.method = "GET";
bncce36dca22015-04-21 22:11:236484 request.url = GURL("https://www.example.org/");
[email protected]76a505b2010-08-25 06:23:006485
6486 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:236487 MockWrite(
6488 "GET / HTTP/1.1\r\n"
6489 "Host: www.example.org\r\n"
6490 "Connection: keep-alive\r\n\r\n"),
6491 MockWrite(
6492 "GET / HTTP/1.1\r\n"
6493 "Host: www.example.org\r\n"
6494 "Connection: keep-alive\r\n\r\n"),
[email protected]76a505b2010-08-25 06:23:006495 };
6496
6497 MockRead data_reads[] = {
mmenke911ee0222015-12-04 03:58:426498 MockRead("HTTP/1.1 200 OK\r\n"), MockRead("Content-Length: 11\r\n\r\n"),
6499 MockRead("hello world"), MockRead(ASYNC, ERR_CONNECTION_CLOSED)};
[email protected]76a505b2010-08-25 06:23:006500
[email protected]8ddf8322012-02-23 18:08:066501 SSLSocketDataProvider ssl(ASYNC, OK);
6502 SSLSocketDataProvider ssl2(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:076503 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
6504 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
[email protected]76a505b2010-08-25 06:23:006505
6506 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
6507 data_writes, arraysize(data_writes));
6508 StaticSocketDataProvider data2(data_reads, arraysize(data_reads),
6509 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:076510 session_deps_.socket_factory->AddSocketDataProvider(&data);
6511 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]76a505b2010-08-25 06:23:006512
[email protected]49639fa2011-12-20 23:22:416513 TestCompletionCallback callback;
[email protected]76a505b2010-08-25 06:23:006514
danakj1fd259a02016-04-16 03:17:096515 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc87dcefc2017-05-25 12:47:586516 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:196517 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]76a505b2010-08-25 06:23:006518
tfarina42834112016-09-22 13:38:206519 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
[email protected]76a505b2010-08-25 06:23:006520
robpercival214763f2016-07-01 23:27:016521 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
6522 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]76a505b2010-08-25 06:23:006523
6524 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:526525 ASSERT_TRUE(response);
6526 ASSERT_TRUE(response->headers);
[email protected]76a505b2010-08-25 06:23:006527 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
6528
[email protected]90499482013-06-01 00:39:506529 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]76a505b2010-08-25 06:23:006530
6531 std::string response_data;
6532 rv = ReadTransaction(trans.get(), &response_data);
robpercival214763f2016-07-01 23:27:016533 EXPECT_THAT(rv, IsOk());
[email protected]76a505b2010-08-25 06:23:006534 EXPECT_EQ("hello world", response_data);
6535
6536 // Empty the current queue. This is necessary because idle sockets are
6537 // added to the connection pool asynchronously with a PostTask.
fdoray92e35a72016-06-10 15:54:556538 base::RunLoop().RunUntilIdle();
[email protected]76a505b2010-08-25 06:23:006539
6540 // We now check to make sure the socket was added back to the pool.
[email protected]90499482013-06-01 00:39:506541 EXPECT_EQ(1, GetIdleSocketCountInSSLSocketPool(session.get()));
[email protected]76a505b2010-08-25 06:23:006542
6543 // Now start the second transaction, which should reuse the previous socket.
6544
bnc87dcefc2017-05-25 12:47:586545 trans =
Jeremy Roman0579ed62017-08-29 15:56:196546 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]76a505b2010-08-25 06:23:006547
tfarina42834112016-09-22 13:38:206548 rv = trans->Start(&request, callback.callback(), NetLogWithSource());
[email protected]76a505b2010-08-25 06:23:006549
robpercival214763f2016-07-01 23:27:016550 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
6551 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]76a505b2010-08-25 06:23:006552
6553 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:526554 ASSERT_TRUE(response);
6555 ASSERT_TRUE(response->headers);
[email protected]76a505b2010-08-25 06:23:006556 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
6557
[email protected]90499482013-06-01 00:39:506558 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]76a505b2010-08-25 06:23:006559
6560 rv = ReadTransaction(trans.get(), &response_data);
robpercival214763f2016-07-01 23:27:016561 EXPECT_THAT(rv, IsOk());
[email protected]76a505b2010-08-25 06:23:006562 EXPECT_EQ("hello world", response_data);
6563
6564 // Empty the current queue. This is necessary because idle sockets are
6565 // added to the connection pool asynchronously with a PostTask.
fdoray92e35a72016-06-10 15:54:556566 base::RunLoop().RunUntilIdle();
[email protected]76a505b2010-08-25 06:23:006567
6568 // We now check to make sure the socket was added back to the pool.
[email protected]90499482013-06-01 00:39:506569 EXPECT_EQ(1, GetIdleSocketCountInSSLSocketPool(session.get()));
[email protected]76a505b2010-08-25 06:23:006570}
6571
maksim.sisov0adf8592016-07-15 06:25:566572// Grab a socket, use it, and put it back into the pool. Then, make
6573// low memory notification and ensure the socket pool is flushed.
bncd16676a2016-07-20 16:23:016574TEST_F(HttpNetworkTransactionTest, FlushSocketPoolOnLowMemoryNotifications) {
maksim.sisov0adf8592016-07-15 06:25:566575 HttpRequestInfo request;
6576 request.method = "GET";
6577 request.url = GURL("http://www.example.org/");
6578 request.load_flags = 0;
6579
6580 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
6581
bnc691fda62016-08-12 00:43:166582 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
maksim.sisov0adf8592016-07-15 06:25:566583
6584 MockRead data_reads[] = {
6585 // A part of the response body is received with the response headers.
6586 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 11\r\n\r\nhel"),
6587 // The rest of the response body is received in two parts.
6588 MockRead("lo"), MockRead(" world"),
6589 MockRead("junk"), // Should not be read!!
6590 MockRead(SYNCHRONOUS, OK),
6591 };
6592
6593 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
6594 session_deps_.socket_factory->AddSocketDataProvider(&data);
6595
6596 TestCompletionCallback callback;
6597
tfarina42834112016-09-22 13:38:206598 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
maksim.sisov0adf8592016-07-15 06:25:566599 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
6600
6601 EXPECT_THAT(callback.GetResult(rv), IsOk());
6602
bnc691fda62016-08-12 00:43:166603 const HttpResponseInfo* response = trans.GetResponseInfo();
maksim.sisov0adf8592016-07-15 06:25:566604 ASSERT_TRUE(response);
6605 EXPECT_TRUE(response->headers);
6606 std::string status_line = response->headers->GetStatusLine();
6607 EXPECT_EQ("HTTP/1.1 200 OK", status_line);
6608
6609 // Make memory critical notification and ensure the transaction still has been
6610 // operating right.
6611 base::MemoryPressureListener::NotifyMemoryPressure(
6612 base::MemoryPressureListener::MEMORY_PRESSURE_LEVEL_CRITICAL);
6613 base::RunLoop().RunUntilIdle();
6614
6615 // Socket should not be flushed as long as it is not idle.
6616 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
6617
6618 std::string response_data;
bnc691fda62016-08-12 00:43:166619 rv = ReadTransaction(&trans, &response_data);
maksim.sisov0adf8592016-07-15 06:25:566620 EXPECT_THAT(rv, IsOk());
6621 EXPECT_EQ("hello world", response_data);
6622
6623 // Empty the current queue. This is necessary because idle sockets are
6624 // added to the connection pool asynchronously with a PostTask.
6625 base::RunLoop().RunUntilIdle();
6626
6627 // We now check to make sure the socket was added back to the pool.
6628 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
6629
6630 // Idle sockets should be flushed now.
6631 base::MemoryPressureListener::NotifyMemoryPressure(
6632 base::MemoryPressureListener::MEMORY_PRESSURE_LEVEL_CRITICAL);
6633 base::RunLoop().RunUntilIdle();
6634
6635 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
6636}
6637
6638// Grab an SSL socket, use it, and put it back into the pool. Then, make
6639// low memory notification and ensure the socket pool is flushed.
bncd16676a2016-07-20 16:23:016640TEST_F(HttpNetworkTransactionTest, FlushSSLSocketPoolOnLowMemoryNotifications) {
maksim.sisov0adf8592016-07-15 06:25:566641 HttpRequestInfo request;
6642 request.method = "GET";
6643 request.url = GURL("https://www.example.org/");
6644 request.load_flags = 0;
6645
6646 MockWrite data_writes[] = {
6647 MockWrite("GET / HTTP/1.1\r\n"
6648 "Host: www.example.org\r\n"
6649 "Connection: keep-alive\r\n\r\n"),
6650 };
6651
6652 MockRead data_reads[] = {
6653 MockRead("HTTP/1.1 200 OK\r\n"), MockRead("Content-Length: 11\r\n\r\n"),
6654 MockRead("hello world"), MockRead(ASYNC, ERR_CONNECTION_CLOSED)};
6655
6656 SSLSocketDataProvider ssl(ASYNC, OK);
6657 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
6658
6659 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
6660 arraysize(data_writes));
6661 session_deps_.socket_factory->AddSocketDataProvider(&data);
6662
6663 TestCompletionCallback callback;
6664
6665 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:166666 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
maksim.sisov0adf8592016-07-15 06:25:566667
6668 EXPECT_EQ(0, GetIdleSocketCountInSSLSocketPool(session.get()));
tfarina42834112016-09-22 13:38:206669 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
maksim.sisov0adf8592016-07-15 06:25:566670
6671 EXPECT_THAT(callback.GetResult(rv), IsOk());
6672
bnc691fda62016-08-12 00:43:166673 const HttpResponseInfo* response = trans.GetResponseInfo();
maksim.sisov0adf8592016-07-15 06:25:566674 ASSERT_TRUE(response);
6675 ASSERT_TRUE(response->headers);
6676 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
6677
6678 // Make memory critical notification and ensure the transaction still has been
6679 // operating right.
6680 base::MemoryPressureListener::NotifyMemoryPressure(
6681 base::MemoryPressureListener::MEMORY_PRESSURE_LEVEL_CRITICAL);
6682 base::RunLoop().RunUntilIdle();
6683
6684 EXPECT_EQ(0, GetIdleSocketCountInSSLSocketPool(session.get()));
6685
6686 std::string response_data;
bnc691fda62016-08-12 00:43:166687 rv = ReadTransaction(&trans, &response_data);
maksim.sisov0adf8592016-07-15 06:25:566688 EXPECT_THAT(rv, IsOk());
6689 EXPECT_EQ("hello world", response_data);
6690
6691 // Empty the current queue. This is necessary because idle sockets are
6692 // added to the connection pool asynchronously with a PostTask.
6693 base::RunLoop().RunUntilIdle();
6694
6695 // We now check to make sure the socket was added back to the pool.
6696 EXPECT_EQ(1, GetIdleSocketCountInSSLSocketPool(session.get()));
6697
6698 // Make memory notification once again and ensure idle socket is closed.
6699 base::MemoryPressureListener::NotifyMemoryPressure(
6700 base::MemoryPressureListener::MEMORY_PRESSURE_LEVEL_CRITICAL);
6701 base::RunLoop().RunUntilIdle();
6702
6703 EXPECT_EQ(0, GetIdleSocketCountInSSLSocketPool(session.get()));
6704}
6705
[email protected]b4404c02009-04-10 16:38:526706// Make sure that we recycle a socket after a zero-length response.
6707// http://crbug.com/9880
bncd16676a2016-07-20 16:23:016708TEST_F(HttpNetworkTransactionTest, RecycleSocketAfterZeroContentLength) {
[email protected]1c773ea12009-04-28 19:58:426709 HttpRequestInfo request;
[email protected]b4404c02009-04-10 16:38:526710 request.method = "GET";
bncce36dca22015-04-21 22:11:236711 request.url = GURL(
6712 "http://www.example.org/csi?v=3&s=web&action=&"
6713 "tran=undefined&ei=mAXcSeegAo-SMurloeUN&"
6714 "e=17259,18167,19592,19773,19981,20133,20173,20233&"
6715 "rt=prt.2642,ol.2649,xjs.2951");
[email protected]b4404c02009-04-10 16:38:526716
danakj1fd259a02016-04-16 03:17:096717 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:276718
[email protected]b4404c02009-04-10 16:38:526719 MockRead data_reads[] = {
6720 MockRead("HTTP/1.1 204 No Content\r\n"
6721 "Content-Length: 0\r\n"
6722 "Content-Type: text/html\r\n\r\n"),
6723 MockRead("junk"), // Should not be read!!
[email protected]8ddf8322012-02-23 18:08:066724 MockRead(SYNCHRONOUS, OK),
[email protected]b4404c02009-04-10 16:38:526725 };
6726
[email protected]31a2bfe2010-02-09 08:03:396727 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:076728 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]b4404c02009-04-10 16:38:526729
mmenkecc2298e2015-12-07 18:20:186730 // Transaction must be created after the MockReads, so it's destroyed before
6731 // them.
bnc691fda62016-08-12 00:43:166732 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
mmenkecc2298e2015-12-07 18:20:186733
[email protected]49639fa2011-12-20 23:22:416734 TestCompletionCallback callback;
[email protected]b4404c02009-04-10 16:38:526735
tfarina42834112016-09-22 13:38:206736 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:016737 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]b4404c02009-04-10 16:38:526738
6739 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:016740 EXPECT_THAT(rv, IsOk());
[email protected]b4404c02009-04-10 16:38:526741
bnc691fda62016-08-12 00:43:166742 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:526743 ASSERT_TRUE(response);
[email protected]b4404c02009-04-10 16:38:526744
wezca1070932016-05-26 20:30:526745 EXPECT_TRUE(response->headers);
[email protected]b4404c02009-04-10 16:38:526746 std::string status_line = response->headers->GetStatusLine();
6747 EXPECT_EQ("HTTP/1.1 204 No Content", status_line);
6748
[email protected]90499482013-06-01 00:39:506749 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]b4404c02009-04-10 16:38:526750
6751 std::string response_data;
bnc691fda62016-08-12 00:43:166752 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:016753 EXPECT_THAT(rv, IsOk());
[email protected]b4404c02009-04-10 16:38:526754 EXPECT_EQ("", response_data);
6755
6756 // Empty the current queue. This is necessary because idle sockets are
6757 // added to the connection pool asynchronously with a PostTask.
fdoray92e35a72016-06-10 15:54:556758 base::RunLoop().RunUntilIdle();
[email protected]b4404c02009-04-10 16:38:526759
6760 // We now check to make sure the socket was added back to the pool.
[email protected]90499482013-06-01 00:39:506761 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]b4404c02009-04-10 16:38:526762}
6763
bncd16676a2016-07-20 16:23:016764TEST_F(HttpNetworkTransactionTest, ResendRequestOnWriteBodyError) {
danakj1fd259a02016-04-16 03:17:096765 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:226766 element_readers.push_back(
Jeremy Roman0579ed62017-08-29 15:56:196767 std::make_unique<UploadBytesElementReader>("foo", 3));
olli.raula6df48b2a2015-11-26 07:40:226768 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]329b68b2012-11-14 17:54:276769
[email protected]1c773ea12009-04-28 19:58:426770 HttpRequestInfo request[2];
[email protected]372d34a2008-11-05 21:30:516771 // Transaction 1: a GET request that succeeds. The socket is recycled
6772 // after use.
6773 request[0].method = "GET";
6774 request[0].url = GURL("http://www.google.com/");
6775 request[0].load_flags = 0;
6776 // Transaction 2: a POST request. Reuses the socket kept alive from
6777 // transaction 1. The first attempts fails when writing the POST data.
6778 // This causes the transaction to retry with a new socket. The second
6779 // attempt succeeds.
6780 request[1].method = "POST";
6781 request[1].url = GURL("http://www.google.com/login.cgi");
[email protected]329b68b2012-11-14 17:54:276782 request[1].upload_data_stream = &upload_data_stream;
[email protected]372d34a2008-11-05 21:30:516783 request[1].load_flags = 0;
6784
danakj1fd259a02016-04-16 03:17:096785 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]372d34a2008-11-05 21:30:516786
6787 // The first socket is used for transaction 1 and the first attempt of
6788 // transaction 2.
6789
6790 // The response of transaction 1.
6791 MockRead data_reads1[] = {
6792 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 11\r\n\r\n"),
6793 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:066794 MockRead(SYNCHRONOUS, OK),
[email protected]372d34a2008-11-05 21:30:516795 };
6796 // The mock write results of transaction 1 and the first attempt of
6797 // transaction 2.
6798 MockWrite data_writes1[] = {
[email protected]8ddf8322012-02-23 18:08:066799 MockWrite(SYNCHRONOUS, 64), // GET
6800 MockWrite(SYNCHRONOUS, 93), // POST
6801 MockWrite(SYNCHRONOUS, ERR_CONNECTION_ABORTED), // POST data
[email protected]372d34a2008-11-05 21:30:516802 };
[email protected]31a2bfe2010-02-09 08:03:396803 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
6804 data_writes1, arraysize(data_writes1));
[email protected]372d34a2008-11-05 21:30:516805
6806 // The second socket is used for the second attempt of transaction 2.
6807
6808 // The response of transaction 2.
6809 MockRead data_reads2[] = {
6810 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 7\r\n\r\n"),
6811 MockRead("welcome"),
[email protected]8ddf8322012-02-23 18:08:066812 MockRead(SYNCHRONOUS, OK),
[email protected]372d34a2008-11-05 21:30:516813 };
6814 // The mock write results of the second attempt of transaction 2.
6815 MockWrite data_writes2[] = {
[email protected]8ddf8322012-02-23 18:08:066816 MockWrite(SYNCHRONOUS, 93), // POST
6817 MockWrite(SYNCHRONOUS, 3), // POST data
[email protected]372d34a2008-11-05 21:30:516818 };
[email protected]31a2bfe2010-02-09 08:03:396819 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
6820 data_writes2, arraysize(data_writes2));
[email protected]372d34a2008-11-05 21:30:516821
[email protected]bb88e1d32013-05-03 23:11:076822 session_deps_.socket_factory->AddSocketDataProvider(&data1);
6823 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]372d34a2008-11-05 21:30:516824
thestig9d3bb0c2015-01-24 00:49:516825 const char* const kExpectedResponseData[] = {
[email protected]372d34a2008-11-05 21:30:516826 "hello world", "welcome"
6827 };
6828
6829 for (int i = 0; i < 2; ++i) {
bnc691fda62016-08-12 00:43:166830 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]372d34a2008-11-05 21:30:516831
[email protected]49639fa2011-12-20 23:22:416832 TestCompletionCallback callback;
[email protected]372d34a2008-11-05 21:30:516833
tfarina42834112016-09-22 13:38:206834 int rv = trans.Start(&request[i], callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:016835 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]372d34a2008-11-05 21:30:516836
6837 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:016838 EXPECT_THAT(rv, IsOk());
[email protected]372d34a2008-11-05 21:30:516839
bnc691fda62016-08-12 00:43:166840 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:526841 ASSERT_TRUE(response);
[email protected]372d34a2008-11-05 21:30:516842
wezca1070932016-05-26 20:30:526843 EXPECT_TRUE(response->headers);
[email protected]372d34a2008-11-05 21:30:516844 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
6845
6846 std::string response_data;
bnc691fda62016-08-12 00:43:166847 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:016848 EXPECT_THAT(rv, IsOk());
[email protected]372d34a2008-11-05 21:30:516849 EXPECT_EQ(kExpectedResponseData[i], response_data);
6850 }
6851}
[email protected]f9ee6b52008-11-08 06:46:236852
6853// Test the request-challenge-retry sequence for basic auth when there is
6854// an identity in the URL. The request should be sent as normal, but when
[email protected]2262e3a2012-05-22 16:08:166855// it fails the identity from the URL is used to answer the challenge.
bncd16676a2016-07-20 16:23:016856TEST_F(HttpNetworkTransactionTest, AuthIdentityInURL) {
[email protected]1c773ea12009-04-28 19:58:426857 HttpRequestInfo request;
[email protected]f9ee6b52008-11-08 06:46:236858 request.method = "GET";
bncce36dca22015-04-21 22:11:236859 request.url = GURL("http://foo:b@[email protected]/");
[email protected]7b08ba62012-02-10 20:19:416860 request.load_flags = LOAD_NORMAL;
[email protected]a97cca42009-08-14 01:00:296861
danakj1fd259a02016-04-16 03:17:096862 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:166863 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:276864
[email protected]a97cca42009-08-14 01:00:296865 // The password contains an escaped character -- for this test to pass it
6866 // will need to be unescaped by HttpNetworkTransaction.
6867 EXPECT_EQ("b%40r", request.url.password());
6868
[email protected]f9ee6b52008-11-08 06:46:236869 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:236870 MockWrite(
6871 "GET / HTTP/1.1\r\n"
6872 "Host: www.example.org\r\n"
6873 "Connection: keep-alive\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:236874 };
6875
6876 MockRead data_reads1[] = {
6877 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
6878 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
6879 MockRead("Content-Length: 10\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:066880 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]f9ee6b52008-11-08 06:46:236881 };
6882
[email protected]2262e3a2012-05-22 16:08:166883 // After the challenge above, the transaction will be restarted using the
6884 // identity from the url (foo, b@r) to answer the challenge.
6885 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:236886 MockWrite(
6887 "GET / HTTP/1.1\r\n"
6888 "Host: www.example.org\r\n"
6889 "Connection: keep-alive\r\n"
6890 "Authorization: Basic Zm9vOmJAcg==\r\n\r\n"),
[email protected]2262e3a2012-05-22 16:08:166891 };
6892
6893 MockRead data_reads2[] = {
6894 MockRead("HTTP/1.0 200 OK\r\n"),
6895 MockRead("Content-Length: 100\r\n\r\n"),
6896 MockRead(SYNCHRONOUS, OK),
6897 };
6898
[email protected]31a2bfe2010-02-09 08:03:396899 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
6900 data_writes1, arraysize(data_writes1));
[email protected]2262e3a2012-05-22 16:08:166901 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
6902 data_writes2, arraysize(data_writes2));
[email protected]bb88e1d32013-05-03 23:11:076903 session_deps_.socket_factory->AddSocketDataProvider(&data1);
6904 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]f9ee6b52008-11-08 06:46:236905
[email protected]49639fa2011-12-20 23:22:416906 TestCompletionCallback callback1;
tfarina42834112016-09-22 13:38:206907 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:016908 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]f9ee6b52008-11-08 06:46:236909 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:016910 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:166911 EXPECT_TRUE(trans.IsReadyToRestartForAuth());
[email protected]2262e3a2012-05-22 16:08:166912
6913 TestCompletionCallback callback2;
bnc691fda62016-08-12 00:43:166914 rv = trans.RestartWithAuth(AuthCredentials(), callback2.callback());
robpercival214763f2016-07-01 23:27:016915 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2262e3a2012-05-22 16:08:166916 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:016917 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:166918 EXPECT_FALSE(trans.IsReadyToRestartForAuth());
[email protected]0757e7702009-03-27 04:00:226919
bnc691fda62016-08-12 00:43:166920 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:526921 ASSERT_TRUE(response);
[email protected]2262e3a2012-05-22 16:08:166922
6923 // There is no challenge info, since the identity in URL worked.
wezca1070932016-05-26 20:30:526924 EXPECT_FALSE(response->auth_challenge);
[email protected]2262e3a2012-05-22 16:08:166925
6926 EXPECT_EQ(100, response->headers->GetContentLength());
6927
6928 // Empty the current queue.
fdoray92e35a72016-06-10 15:54:556929 base::RunLoop().RunUntilIdle();
[email protected]2262e3a2012-05-22 16:08:166930}
6931
6932// Test the request-challenge-retry sequence for basic auth when there is an
6933// incorrect identity in the URL. The identity from the URL should be used only
6934// once.
bncd16676a2016-07-20 16:23:016935TEST_F(HttpNetworkTransactionTest, WrongAuthIdentityInURL) {
[email protected]2262e3a2012-05-22 16:08:166936 HttpRequestInfo request;
6937 request.method = "GET";
6938 // Note: the URL has a username:password in it. The password "baz" is
6939 // wrong (should be "bar").
bncce36dca22015-04-21 22:11:236940 request.url = GURL("http://foo:[email protected]/");
[email protected]2262e3a2012-05-22 16:08:166941
6942 request.load_flags = LOAD_NORMAL;
6943
danakj1fd259a02016-04-16 03:17:096944 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:166945 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]2262e3a2012-05-22 16:08:166946
6947 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:236948 MockWrite(
6949 "GET / HTTP/1.1\r\n"
6950 "Host: www.example.org\r\n"
6951 "Connection: keep-alive\r\n\r\n"),
[email protected]2262e3a2012-05-22 16:08:166952 };
6953
6954 MockRead data_reads1[] = {
6955 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
6956 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
6957 MockRead("Content-Length: 10\r\n\r\n"),
6958 MockRead(SYNCHRONOUS, ERR_FAILED),
6959 };
6960
6961 // After the challenge above, the transaction will be restarted using the
6962 // identity from the url (foo, baz) to answer the challenge.
6963 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:236964 MockWrite(
6965 "GET / HTTP/1.1\r\n"
6966 "Host: www.example.org\r\n"
6967 "Connection: keep-alive\r\n"
6968 "Authorization: Basic Zm9vOmJheg==\r\n\r\n"),
[email protected]2262e3a2012-05-22 16:08:166969 };
6970
6971 MockRead data_reads2[] = {
6972 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
6973 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
6974 MockRead("Content-Length: 10\r\n\r\n"),
6975 MockRead(SYNCHRONOUS, ERR_FAILED),
6976 };
6977
6978 // After the challenge above, the transaction will be restarted using the
6979 // identity supplied by the user (foo, bar) to answer the challenge.
6980 MockWrite data_writes3[] = {
bncce36dca22015-04-21 22:11:236981 MockWrite(
6982 "GET / HTTP/1.1\r\n"
6983 "Host: www.example.org\r\n"
6984 "Connection: keep-alive\r\n"
6985 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]2262e3a2012-05-22 16:08:166986 };
6987
6988 MockRead data_reads3[] = {
6989 MockRead("HTTP/1.0 200 OK\r\n"),
6990 MockRead("Content-Length: 100\r\n\r\n"),
6991 MockRead(SYNCHRONOUS, OK),
6992 };
6993
6994 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
6995 data_writes1, arraysize(data_writes1));
6996 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
6997 data_writes2, arraysize(data_writes2));
6998 StaticSocketDataProvider data3(data_reads3, arraysize(data_reads3),
6999 data_writes3, arraysize(data_writes3));
[email protected]bb88e1d32013-05-03 23:11:077000 session_deps_.socket_factory->AddSocketDataProvider(&data1);
7001 session_deps_.socket_factory->AddSocketDataProvider(&data2);
7002 session_deps_.socket_factory->AddSocketDataProvider(&data3);
[email protected]2262e3a2012-05-22 16:08:167003
7004 TestCompletionCallback callback1;
7005
tfarina42834112016-09-22 13:38:207006 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:017007 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2262e3a2012-05-22 16:08:167008
7009 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:017010 EXPECT_THAT(rv, IsOk());
[email protected]2262e3a2012-05-22 16:08:167011
bnc691fda62016-08-12 00:43:167012 EXPECT_TRUE(trans.IsReadyToRestartForAuth());
[email protected]2262e3a2012-05-22 16:08:167013 TestCompletionCallback callback2;
bnc691fda62016-08-12 00:43:167014 rv = trans.RestartWithAuth(AuthCredentials(), callback2.callback());
robpercival214763f2016-07-01 23:27:017015 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2262e3a2012-05-22 16:08:167016 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:017017 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:167018 EXPECT_FALSE(trans.IsReadyToRestartForAuth());
[email protected]2262e3a2012-05-22 16:08:167019
bnc691fda62016-08-12 00:43:167020 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:527021 ASSERT_TRUE(response);
[email protected]2262e3a2012-05-22 16:08:167022 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
7023
7024 TestCompletionCallback callback3;
bnc691fda62016-08-12 00:43:167025 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar), callback3.callback());
robpercival214763f2016-07-01 23:27:017026 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2262e3a2012-05-22 16:08:167027 rv = callback3.WaitForResult();
robpercival214763f2016-07-01 23:27:017028 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:167029 EXPECT_FALSE(trans.IsReadyToRestartForAuth());
[email protected]2262e3a2012-05-22 16:08:167030
bnc691fda62016-08-12 00:43:167031 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:527032 ASSERT_TRUE(response);
[email protected]2262e3a2012-05-22 16:08:167033
7034 // There is no challenge info, since the identity worked.
wezca1070932016-05-26 20:30:527035 EXPECT_FALSE(response->auth_challenge);
[email protected]2262e3a2012-05-22 16:08:167036
7037 EXPECT_EQ(100, response->headers->GetContentLength());
7038
[email protected]ea9dc9a2009-09-05 00:43:327039 // Empty the current queue.
fdoray92e35a72016-06-10 15:54:557040 base::RunLoop().RunUntilIdle();
[email protected]ea9dc9a2009-09-05 00:43:327041}
7042
[email protected]2217aa22013-10-11 03:03:547043
7044// Test the request-challenge-retry sequence for basic auth when there is a
7045// correct identity in the URL, but its use is being suppressed. The identity
7046// from the URL should never be used.
bncd16676a2016-07-20 16:23:017047TEST_F(HttpNetworkTransactionTest, AuthIdentityInURLSuppressed) {
[email protected]2217aa22013-10-11 03:03:547048 HttpRequestInfo request;
7049 request.method = "GET";
bncce36dca22015-04-21 22:11:237050 request.url = GURL("http://foo:[email protected]/");
[email protected]2217aa22013-10-11 03:03:547051 request.load_flags = LOAD_DO_NOT_USE_EMBEDDED_IDENTITY;
7052
danakj1fd259a02016-04-16 03:17:097053 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:167054 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]2217aa22013-10-11 03:03:547055
7056 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:237057 MockWrite(
7058 "GET / HTTP/1.1\r\n"
7059 "Host: www.example.org\r\n"
7060 "Connection: keep-alive\r\n\r\n"),
[email protected]2217aa22013-10-11 03:03:547061 };
7062
7063 MockRead data_reads1[] = {
7064 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
7065 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
7066 MockRead("Content-Length: 10\r\n\r\n"),
7067 MockRead(SYNCHRONOUS, ERR_FAILED),
7068 };
7069
7070 // After the challenge above, the transaction will be restarted using the
7071 // identity supplied by the user, not the one in the URL, to answer the
7072 // challenge.
7073 MockWrite data_writes3[] = {
bncce36dca22015-04-21 22:11:237074 MockWrite(
7075 "GET / HTTP/1.1\r\n"
7076 "Host: www.example.org\r\n"
7077 "Connection: keep-alive\r\n"
7078 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]2217aa22013-10-11 03:03:547079 };
7080
7081 MockRead data_reads3[] = {
7082 MockRead("HTTP/1.0 200 OK\r\n"),
7083 MockRead("Content-Length: 100\r\n\r\n"),
7084 MockRead(SYNCHRONOUS, OK),
7085 };
7086
7087 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
7088 data_writes1, arraysize(data_writes1));
7089 StaticSocketDataProvider data3(data_reads3, arraysize(data_reads3),
7090 data_writes3, arraysize(data_writes3));
7091 session_deps_.socket_factory->AddSocketDataProvider(&data1);
7092 session_deps_.socket_factory->AddSocketDataProvider(&data3);
7093
7094 TestCompletionCallback callback1;
tfarina42834112016-09-22 13:38:207095 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:017096 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2217aa22013-10-11 03:03:547097 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:017098 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:167099 EXPECT_FALSE(trans.IsReadyToRestartForAuth());
[email protected]2217aa22013-10-11 03:03:547100
bnc691fda62016-08-12 00:43:167101 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:527102 ASSERT_TRUE(response);
[email protected]2217aa22013-10-11 03:03:547103 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
7104
7105 TestCompletionCallback callback3;
bnc691fda62016-08-12 00:43:167106 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar), callback3.callback());
robpercival214763f2016-07-01 23:27:017107 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2217aa22013-10-11 03:03:547108 rv = callback3.WaitForResult();
robpercival214763f2016-07-01 23:27:017109 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:167110 EXPECT_FALSE(trans.IsReadyToRestartForAuth());
[email protected]2217aa22013-10-11 03:03:547111
bnc691fda62016-08-12 00:43:167112 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:527113 ASSERT_TRUE(response);
[email protected]2217aa22013-10-11 03:03:547114
7115 // There is no challenge info, since the identity worked.
wezca1070932016-05-26 20:30:527116 EXPECT_FALSE(response->auth_challenge);
[email protected]2217aa22013-10-11 03:03:547117 EXPECT_EQ(100, response->headers->GetContentLength());
7118
7119 // Empty the current queue.
fdoray92e35a72016-06-10 15:54:557120 base::RunLoop().RunUntilIdle();
[email protected]2217aa22013-10-11 03:03:547121}
7122
[email protected]f9ee6b52008-11-08 06:46:237123// Test that previously tried username/passwords for a realm get re-used.
bncd16676a2016-07-20 16:23:017124TEST_F(HttpNetworkTransactionTest, BasicAuthCacheAndPreauth) {
danakj1fd259a02016-04-16 03:17:097125 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]f9ee6b52008-11-08 06:46:237126
7127 // Transaction 1: authenticate (foo, bar) on MyRealm1
7128 {
[email protected]1c773ea12009-04-28 19:58:427129 HttpRequestInfo request;
[email protected]f9ee6b52008-11-08 06:46:237130 request.method = "GET";
bncce36dca22015-04-21 22:11:237131 request.url = GURL("http://www.example.org/x/y/z");
[email protected]f9ee6b52008-11-08 06:46:237132
bnc691fda62016-08-12 00:43:167133 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:277134
[email protected]f9ee6b52008-11-08 06:46:237135 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:237136 MockWrite(
7137 "GET /x/y/z HTTP/1.1\r\n"
7138 "Host: www.example.org\r\n"
7139 "Connection: keep-alive\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:237140 };
7141
7142 MockRead data_reads1[] = {
7143 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
7144 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
7145 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067146 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]f9ee6b52008-11-08 06:46:237147 };
7148
7149 // Resend with authorization (username=foo, password=bar)
7150 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:237151 MockWrite(
7152 "GET /x/y/z HTTP/1.1\r\n"
7153 "Host: www.example.org\r\n"
7154 "Connection: keep-alive\r\n"
7155 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:237156 };
7157
7158 // Sever accepts the authorization.
7159 MockRead data_reads2[] = {
7160 MockRead("HTTP/1.0 200 OK\r\n"),
7161 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067162 MockRead(SYNCHRONOUS, OK),
[email protected]f9ee6b52008-11-08 06:46:237163 };
7164
[email protected]31a2bfe2010-02-09 08:03:397165 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
7166 data_writes1, arraysize(data_writes1));
7167 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
7168 data_writes2, arraysize(data_writes2));
[email protected]bb88e1d32013-05-03 23:11:077169 session_deps_.socket_factory->AddSocketDataProvider(&data1);
7170 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]f9ee6b52008-11-08 06:46:237171
[email protected]49639fa2011-12-20 23:22:417172 TestCompletionCallback callback1;
[email protected]f9ee6b52008-11-08 06:46:237173
tfarina42834112016-09-22 13:38:207174 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:017175 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]f9ee6b52008-11-08 06:46:237176
7177 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:017178 EXPECT_THAT(rv, IsOk());
[email protected]f9ee6b52008-11-08 06:46:237179
bnc691fda62016-08-12 00:43:167180 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:527181 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:047182 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]f9ee6b52008-11-08 06:46:237183
[email protected]49639fa2011-12-20 23:22:417184 TestCompletionCallback callback2;
[email protected]f9ee6b52008-11-08 06:46:237185
bnc691fda62016-08-12 00:43:167186 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar),
7187 callback2.callback());
robpercival214763f2016-07-01 23:27:017188 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]f9ee6b52008-11-08 06:46:237189
7190 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:017191 EXPECT_THAT(rv, IsOk());
[email protected]f9ee6b52008-11-08 06:46:237192
bnc691fda62016-08-12 00:43:167193 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:527194 ASSERT_TRUE(response);
7195 EXPECT_FALSE(response->auth_challenge);
[email protected]f9ee6b52008-11-08 06:46:237196 EXPECT_EQ(100, response->headers->GetContentLength());
7197 }
7198
7199 // ------------------------------------------------------------------------
7200
7201 // Transaction 2: authenticate (foo2, bar2) on MyRealm2
7202 {
[email protected]1c773ea12009-04-28 19:58:427203 HttpRequestInfo request;
[email protected]f9ee6b52008-11-08 06:46:237204 request.method = "GET";
7205 // Note that Transaction 1 was at /x/y/z, so this is in the same
7206 // protection space as MyRealm1.
bncce36dca22015-04-21 22:11:237207 request.url = GURL("http://www.example.org/x/y/a/b");
[email protected]f9ee6b52008-11-08 06:46:237208
bnc691fda62016-08-12 00:43:167209 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:277210
[email protected]f9ee6b52008-11-08 06:46:237211 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:237212 MockWrite(
7213 "GET /x/y/a/b HTTP/1.1\r\n"
7214 "Host: www.example.org\r\n"
7215 "Connection: keep-alive\r\n"
7216 // Send preemptive authorization for MyRealm1
7217 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:237218 };
7219
7220 // The server didn't like the preemptive authorization, and
7221 // challenges us for a different realm (MyRealm2).
7222 MockRead data_reads1[] = {
7223 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
7224 MockRead("WWW-Authenticate: Basic realm=\"MyRealm2\"\r\n"),
7225 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067226 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]f9ee6b52008-11-08 06:46:237227 };
7228
7229 // Resend with authorization for MyRealm2 (username=foo2, password=bar2)
7230 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:237231 MockWrite(
7232 "GET /x/y/a/b HTTP/1.1\r\n"
7233 "Host: www.example.org\r\n"
7234 "Connection: keep-alive\r\n"
7235 "Authorization: Basic Zm9vMjpiYXIy\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:237236 };
7237
7238 // Sever accepts the authorization.
7239 MockRead data_reads2[] = {
7240 MockRead("HTTP/1.0 200 OK\r\n"),
7241 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067242 MockRead(SYNCHRONOUS, OK),
[email protected]f9ee6b52008-11-08 06:46:237243 };
7244
[email protected]31a2bfe2010-02-09 08:03:397245 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
7246 data_writes1, arraysize(data_writes1));
7247 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
7248 data_writes2, arraysize(data_writes2));
[email protected]bb88e1d32013-05-03 23:11:077249 session_deps_.socket_factory->AddSocketDataProvider(&data1);
7250 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]f9ee6b52008-11-08 06:46:237251
[email protected]49639fa2011-12-20 23:22:417252 TestCompletionCallback callback1;
[email protected]f9ee6b52008-11-08 06:46:237253
tfarina42834112016-09-22 13:38:207254 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:017255 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]f9ee6b52008-11-08 06:46:237256
7257 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:017258 EXPECT_THAT(rv, IsOk());
[email protected]f9ee6b52008-11-08 06:46:237259
bnc691fda62016-08-12 00:43:167260 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:527261 ASSERT_TRUE(response);
7262 ASSERT_TRUE(response->auth_challenge);
[email protected]79cb5c12011-09-12 13:12:047263 EXPECT_FALSE(response->auth_challenge->is_proxy);
asanka098c0092016-06-16 20:18:437264 EXPECT_EQ("http://www.example.org",
7265 response->auth_challenge->challenger.Serialize());
[email protected]79cb5c12011-09-12 13:12:047266 EXPECT_EQ("MyRealm2", response->auth_challenge->realm);
aberentbba302d2015-12-03 10:20:197267 EXPECT_EQ(kBasicAuthScheme, response->auth_challenge->scheme);
[email protected]f9ee6b52008-11-08 06:46:237268
[email protected]49639fa2011-12-20 23:22:417269 TestCompletionCallback callback2;
[email protected]f9ee6b52008-11-08 06:46:237270
bnc691fda62016-08-12 00:43:167271 rv = trans.RestartWithAuth(AuthCredentials(kFoo2, kBar2),
7272 callback2.callback());
robpercival214763f2016-07-01 23:27:017273 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]f9ee6b52008-11-08 06:46:237274
7275 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:017276 EXPECT_THAT(rv, IsOk());
[email protected]f9ee6b52008-11-08 06:46:237277
bnc691fda62016-08-12 00:43:167278 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:527279 ASSERT_TRUE(response);
7280 EXPECT_FALSE(response->auth_challenge);
[email protected]f9ee6b52008-11-08 06:46:237281 EXPECT_EQ(100, response->headers->GetContentLength());
7282 }
7283
7284 // ------------------------------------------------------------------------
7285
7286 // Transaction 3: Resend a request in MyRealm's protection space --
7287 // succeed with preemptive authorization.
7288 {
[email protected]1c773ea12009-04-28 19:58:427289 HttpRequestInfo request;
[email protected]f9ee6b52008-11-08 06:46:237290 request.method = "GET";
bncce36dca22015-04-21 22:11:237291 request.url = GURL("http://www.example.org/x/y/z2");
[email protected]f9ee6b52008-11-08 06:46:237292
bnc691fda62016-08-12 00:43:167293 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:277294
[email protected]f9ee6b52008-11-08 06:46:237295 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:237296 MockWrite(
7297 "GET /x/y/z2 HTTP/1.1\r\n"
7298 "Host: www.example.org\r\n"
7299 "Connection: keep-alive\r\n"
7300 // The authorization for MyRealm1 gets sent preemptively
7301 // (since the url is in the same protection space)
7302 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:237303 };
7304
7305 // Sever accepts the preemptive authorization
7306 MockRead data_reads1[] = {
7307 MockRead("HTTP/1.0 200 OK\r\n"),
7308 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067309 MockRead(SYNCHRONOUS, OK),
[email protected]f9ee6b52008-11-08 06:46:237310 };
7311
[email protected]31a2bfe2010-02-09 08:03:397312 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
7313 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:077314 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]f9ee6b52008-11-08 06:46:237315
[email protected]49639fa2011-12-20 23:22:417316 TestCompletionCallback callback1;
[email protected]f9ee6b52008-11-08 06:46:237317
tfarina42834112016-09-22 13:38:207318 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:017319 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]f9ee6b52008-11-08 06:46:237320
7321 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:017322 EXPECT_THAT(rv, IsOk());
[email protected]f9ee6b52008-11-08 06:46:237323
bnc691fda62016-08-12 00:43:167324 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:527325 ASSERT_TRUE(response);
[email protected]f9ee6b52008-11-08 06:46:237326
wezca1070932016-05-26 20:30:527327 EXPECT_FALSE(response->auth_challenge);
[email protected]f9ee6b52008-11-08 06:46:237328 EXPECT_EQ(100, response->headers->GetContentLength());
7329 }
7330
7331 // ------------------------------------------------------------------------
7332
7333 // Transaction 4: request another URL in MyRealm (however the
7334 // url is not known to belong to the protection space, so no pre-auth).
7335 {
[email protected]1c773ea12009-04-28 19:58:427336 HttpRequestInfo request;
[email protected]f9ee6b52008-11-08 06:46:237337 request.method = "GET";
bncce36dca22015-04-21 22:11:237338 request.url = GURL("http://www.example.org/x/1");
[email protected]f9ee6b52008-11-08 06:46:237339
bnc691fda62016-08-12 00:43:167340 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:277341
[email protected]f9ee6b52008-11-08 06:46:237342 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:237343 MockWrite(
7344 "GET /x/1 HTTP/1.1\r\n"
7345 "Host: www.example.org\r\n"
7346 "Connection: keep-alive\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:237347 };
7348
7349 MockRead data_reads1[] = {
7350 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
7351 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
7352 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067353 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]f9ee6b52008-11-08 06:46:237354 };
7355
7356 // Resend with authorization from MyRealm's cache.
7357 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:237358 MockWrite(
7359 "GET /x/1 HTTP/1.1\r\n"
7360 "Host: www.example.org\r\n"
7361 "Connection: keep-alive\r\n"
7362 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:237363 };
7364
7365 // Sever accepts the authorization.
7366 MockRead data_reads2[] = {
7367 MockRead("HTTP/1.0 200 OK\r\n"),
7368 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067369 MockRead(SYNCHRONOUS, OK),
[email protected]f9ee6b52008-11-08 06:46:237370 };
7371
[email protected]31a2bfe2010-02-09 08:03:397372 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
7373 data_writes1, arraysize(data_writes1));
7374 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
7375 data_writes2, arraysize(data_writes2));
[email protected]bb88e1d32013-05-03 23:11:077376 session_deps_.socket_factory->AddSocketDataProvider(&data1);
7377 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]f9ee6b52008-11-08 06:46:237378
[email protected]49639fa2011-12-20 23:22:417379 TestCompletionCallback callback1;
[email protected]f9ee6b52008-11-08 06:46:237380
tfarina42834112016-09-22 13:38:207381 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:017382 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]f9ee6b52008-11-08 06:46:237383
7384 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:017385 EXPECT_THAT(rv, IsOk());
[email protected]f9ee6b52008-11-08 06:46:237386
bnc691fda62016-08-12 00:43:167387 EXPECT_TRUE(trans.IsReadyToRestartForAuth());
[email protected]49639fa2011-12-20 23:22:417388 TestCompletionCallback callback2;
bnc691fda62016-08-12 00:43:167389 rv = trans.RestartWithAuth(AuthCredentials(), callback2.callback());
robpercival214763f2016-07-01 23:27:017390 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]0757e7702009-03-27 04:00:227391 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:017392 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:167393 EXPECT_FALSE(trans.IsReadyToRestartForAuth());
[email protected]0757e7702009-03-27 04:00:227394
bnc691fda62016-08-12 00:43:167395 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:527396 ASSERT_TRUE(response);
7397 EXPECT_FALSE(response->auth_challenge);
[email protected]f9ee6b52008-11-08 06:46:237398 EXPECT_EQ(100, response->headers->GetContentLength());
7399 }
7400
7401 // ------------------------------------------------------------------------
7402
7403 // Transaction 5: request a URL in MyRealm, but the server rejects the
7404 // cached identity. Should invalidate and re-prompt.
7405 {
[email protected]1c773ea12009-04-28 19:58:427406 HttpRequestInfo request;
[email protected]f9ee6b52008-11-08 06:46:237407 request.method = "GET";
bncce36dca22015-04-21 22:11:237408 request.url = GURL("http://www.example.org/p/q/t");
[email protected]f9ee6b52008-11-08 06:46:237409
bnc691fda62016-08-12 00:43:167410 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:277411
[email protected]f9ee6b52008-11-08 06:46:237412 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:237413 MockWrite(
7414 "GET /p/q/t HTTP/1.1\r\n"
7415 "Host: www.example.org\r\n"
7416 "Connection: keep-alive\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:237417 };
7418
7419 MockRead data_reads1[] = {
7420 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
7421 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
7422 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067423 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]f9ee6b52008-11-08 06:46:237424 };
7425
7426 // Resend with authorization from cache for MyRealm.
7427 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:237428 MockWrite(
7429 "GET /p/q/t HTTP/1.1\r\n"
7430 "Host: www.example.org\r\n"
7431 "Connection: keep-alive\r\n"
7432 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:237433 };
7434
7435 // Sever rejects the authorization.
7436 MockRead data_reads2[] = {
7437 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
7438 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
7439 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067440 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]f9ee6b52008-11-08 06:46:237441 };
7442
7443 // At this point we should prompt for new credentials for MyRealm.
7444 // Restart with username=foo3, password=foo4.
7445 MockWrite data_writes3[] = {
bncce36dca22015-04-21 22:11:237446 MockWrite(
7447 "GET /p/q/t HTTP/1.1\r\n"
7448 "Host: www.example.org\r\n"
7449 "Connection: keep-alive\r\n"
7450 "Authorization: Basic Zm9vMzpiYXIz\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:237451 };
7452
7453 // Sever accepts the authorization.
7454 MockRead data_reads3[] = {
7455 MockRead("HTTP/1.0 200 OK\r\n"),
7456 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067457 MockRead(SYNCHRONOUS, OK),
[email protected]f9ee6b52008-11-08 06:46:237458 };
7459
[email protected]31a2bfe2010-02-09 08:03:397460 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
7461 data_writes1, arraysize(data_writes1));
7462 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
7463 data_writes2, arraysize(data_writes2));
7464 StaticSocketDataProvider data3(data_reads3, arraysize(data_reads3),
7465 data_writes3, arraysize(data_writes3));
[email protected]bb88e1d32013-05-03 23:11:077466 session_deps_.socket_factory->AddSocketDataProvider(&data1);
7467 session_deps_.socket_factory->AddSocketDataProvider(&data2);
7468 session_deps_.socket_factory->AddSocketDataProvider(&data3);
[email protected]f9ee6b52008-11-08 06:46:237469
[email protected]49639fa2011-12-20 23:22:417470 TestCompletionCallback callback1;
[email protected]f9ee6b52008-11-08 06:46:237471
tfarina42834112016-09-22 13:38:207472 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:017473 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]f9ee6b52008-11-08 06:46:237474
7475 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:017476 EXPECT_THAT(rv, IsOk());
[email protected]f9ee6b52008-11-08 06:46:237477
bnc691fda62016-08-12 00:43:167478 EXPECT_TRUE(trans.IsReadyToRestartForAuth());
[email protected]49639fa2011-12-20 23:22:417479 TestCompletionCallback callback2;
bnc691fda62016-08-12 00:43:167480 rv = trans.RestartWithAuth(AuthCredentials(), callback2.callback());
robpercival214763f2016-07-01 23:27:017481 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]0757e7702009-03-27 04:00:227482 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:017483 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:167484 EXPECT_FALSE(trans.IsReadyToRestartForAuth());
[email protected]0757e7702009-03-27 04:00:227485
bnc691fda62016-08-12 00:43:167486 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:527487 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:047488 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]f9ee6b52008-11-08 06:46:237489
[email protected]49639fa2011-12-20 23:22:417490 TestCompletionCallback callback3;
[email protected]f9ee6b52008-11-08 06:46:237491
bnc691fda62016-08-12 00:43:167492 rv = trans.RestartWithAuth(AuthCredentials(kFoo3, kBar3),
7493 callback3.callback());
robpercival214763f2016-07-01 23:27:017494 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]f9ee6b52008-11-08 06:46:237495
[email protected]0757e7702009-03-27 04:00:227496 rv = callback3.WaitForResult();
robpercival214763f2016-07-01 23:27:017497 EXPECT_THAT(rv, IsOk());
[email protected]f9ee6b52008-11-08 06:46:237498
bnc691fda62016-08-12 00:43:167499 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:527500 ASSERT_TRUE(response);
7501 EXPECT_FALSE(response->auth_challenge);
[email protected]f9ee6b52008-11-08 06:46:237502 EXPECT_EQ(100, response->headers->GetContentLength());
7503 }
7504}
[email protected]89ceba9a2009-03-21 03:46:067505
[email protected]3c32c5f2010-05-18 15:18:127506// Tests that nonce count increments when multiple auth attempts
7507// are started with the same nonce.
bncd16676a2016-07-20 16:23:017508TEST_F(HttpNetworkTransactionTest, DigestPreAuthNonceCount) {
[email protected]54fea2562010-11-17 14:40:447509 HttpAuthHandlerDigest::Factory* digest_factory =
7510 new HttpAuthHandlerDigest::Factory();
7511 HttpAuthHandlerDigest::FixedNonceGenerator* nonce_generator =
7512 new HttpAuthHandlerDigest::FixedNonceGenerator("0123456789abcdef");
7513 digest_factory->set_nonce_generator(nonce_generator);
[email protected]bb88e1d32013-05-03 23:11:077514 session_deps_.http_auth_handler_factory.reset(digest_factory);
danakj1fd259a02016-04-16 03:17:097515 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]3c32c5f2010-05-18 15:18:127516
7517 // Transaction 1: authenticate (foo, bar) on MyRealm1
7518 {
[email protected]3c32c5f2010-05-18 15:18:127519 HttpRequestInfo request;
7520 request.method = "GET";
bncce36dca22015-04-21 22:11:237521 request.url = GURL("http://www.example.org/x/y/z");
[email protected]3c32c5f2010-05-18 15:18:127522
bnc691fda62016-08-12 00:43:167523 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:277524
[email protected]3c32c5f2010-05-18 15:18:127525 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:237526 MockWrite(
7527 "GET /x/y/z HTTP/1.1\r\n"
7528 "Host: www.example.org\r\n"
7529 "Connection: keep-alive\r\n\r\n"),
[email protected]3c32c5f2010-05-18 15:18:127530 };
7531
7532 MockRead data_reads1[] = {
7533 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
7534 MockRead("WWW-Authenticate: Digest realm=\"digestive\", nonce=\"OU812\", "
7535 "algorithm=MD5, qop=\"auth\"\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067536 MockRead(SYNCHRONOUS, OK),
[email protected]3c32c5f2010-05-18 15:18:127537 };
7538
7539 // Resend with authorization (username=foo, password=bar)
7540 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:237541 MockWrite(
7542 "GET /x/y/z HTTP/1.1\r\n"
7543 "Host: www.example.org\r\n"
7544 "Connection: keep-alive\r\n"
7545 "Authorization: Digest username=\"foo\", realm=\"digestive\", "
7546 "nonce=\"OU812\", uri=\"/x/y/z\", algorithm=MD5, "
7547 "response=\"03ffbcd30add722589c1de345d7a927f\", qop=auth, "
7548 "nc=00000001, cnonce=\"0123456789abcdef\"\r\n\r\n"),
[email protected]3c32c5f2010-05-18 15:18:127549 };
7550
7551 // Sever accepts the authorization.
7552 MockRead data_reads2[] = {
zmo9528c9f42015-08-04 22:12:087553 MockRead("HTTP/1.0 200 OK\r\n"),
7554 MockRead(SYNCHRONOUS, OK),
[email protected]3c32c5f2010-05-18 15:18:127555 };
7556
7557 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
7558 data_writes1, arraysize(data_writes1));
7559 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
7560 data_writes2, arraysize(data_writes2));
[email protected]bb88e1d32013-05-03 23:11:077561 session_deps_.socket_factory->AddSocketDataProvider(&data1);
7562 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]3c32c5f2010-05-18 15:18:127563
[email protected]49639fa2011-12-20 23:22:417564 TestCompletionCallback callback1;
[email protected]3c32c5f2010-05-18 15:18:127565
tfarina42834112016-09-22 13:38:207566 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:017567 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]3c32c5f2010-05-18 15:18:127568
7569 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:017570 EXPECT_THAT(rv, IsOk());
[email protected]3c32c5f2010-05-18 15:18:127571
bnc691fda62016-08-12 00:43:167572 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:527573 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:047574 EXPECT_TRUE(CheckDigestServerAuth(response->auth_challenge.get()));
[email protected]3c32c5f2010-05-18 15:18:127575
[email protected]49639fa2011-12-20 23:22:417576 TestCompletionCallback callback2;
[email protected]3c32c5f2010-05-18 15:18:127577
bnc691fda62016-08-12 00:43:167578 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar),
7579 callback2.callback());
robpercival214763f2016-07-01 23:27:017580 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]3c32c5f2010-05-18 15:18:127581
7582 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:017583 EXPECT_THAT(rv, IsOk());
[email protected]3c32c5f2010-05-18 15:18:127584
bnc691fda62016-08-12 00:43:167585 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:527586 ASSERT_TRUE(response);
7587 EXPECT_FALSE(response->auth_challenge);
[email protected]3c32c5f2010-05-18 15:18:127588 }
7589
7590 // ------------------------------------------------------------------------
7591
7592 // Transaction 2: Request another resource in digestive's protection space.
7593 // This will preemptively add an Authorization header which should have an
7594 // "nc" value of 2 (as compared to 1 in the first use.
7595 {
[email protected]3c32c5f2010-05-18 15:18:127596 HttpRequestInfo request;
7597 request.method = "GET";
7598 // Note that Transaction 1 was at /x/y/z, so this is in the same
7599 // protection space as digest.
bncce36dca22015-04-21 22:11:237600 request.url = GURL("http://www.example.org/x/y/a/b");
[email protected]3c32c5f2010-05-18 15:18:127601
bnc691fda62016-08-12 00:43:167602 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:277603
[email protected]3c32c5f2010-05-18 15:18:127604 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:237605 MockWrite(
7606 "GET /x/y/a/b HTTP/1.1\r\n"
7607 "Host: www.example.org\r\n"
7608 "Connection: keep-alive\r\n"
7609 "Authorization: Digest username=\"foo\", realm=\"digestive\", "
7610 "nonce=\"OU812\", uri=\"/x/y/a/b\", algorithm=MD5, "
7611 "response=\"d6f9a2c07d1c5df7b89379dca1269b35\", qop=auth, "
7612 "nc=00000002, cnonce=\"0123456789abcdef\"\r\n\r\n"),
[email protected]3c32c5f2010-05-18 15:18:127613 };
7614
7615 // Sever accepts the authorization.
7616 MockRead data_reads1[] = {
7617 MockRead("HTTP/1.0 200 OK\r\n"),
7618 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067619 MockRead(SYNCHRONOUS, OK),
[email protected]3c32c5f2010-05-18 15:18:127620 };
7621
7622 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
7623 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:077624 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]3c32c5f2010-05-18 15:18:127625
[email protected]49639fa2011-12-20 23:22:417626 TestCompletionCallback callback1;
[email protected]3c32c5f2010-05-18 15:18:127627
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]3c32c5f2010-05-18 15:18:127630
7631 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:017632 EXPECT_THAT(rv, IsOk());
[email protected]3c32c5f2010-05-18 15:18:127633
bnc691fda62016-08-12 00:43:167634 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:527635 ASSERT_TRUE(response);
7636 EXPECT_FALSE(response->auth_challenge);
[email protected]3c32c5f2010-05-18 15:18:127637 }
7638}
7639
[email protected]89ceba9a2009-03-21 03:46:067640// Test the ResetStateForRestart() private method.
bncd16676a2016-07-20 16:23:017641TEST_F(HttpNetworkTransactionTest, ResetStateForRestart) {
[email protected]89ceba9a2009-03-21 03:46:067642 // Create a transaction (the dependencies aren't important).
danakj1fd259a02016-04-16 03:17:097643 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:167644 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]89ceba9a2009-03-21 03:46:067645
7646 // Setup some state (which we expect ResetStateForRestart() will clear).
bnc691fda62016-08-12 00:43:167647 trans.read_buf_ = new IOBuffer(15);
7648 trans.read_buf_len_ = 15;
7649 trans.request_headers_.SetHeader("Authorization", "NTLM");
[email protected]89ceba9a2009-03-21 03:46:067650
7651 // Setup state in response_
bnc691fda62016-08-12 00:43:167652 HttpResponseInfo* response = &trans.response_;
[email protected]0877e3d2009-10-17 22:29:577653 response->auth_challenge = new AuthChallengeInfo();
[email protected]70d66502011-09-23 00:55:087654 response->ssl_info.cert_status = static_cast<CertStatus>(-1); // Nonsensical.
[email protected]0877e3d2009-10-17 22:29:577655 response->response_time = base::Time::Now();
7656 response->was_cached = true; // (Wouldn't ever actually be true...)
[email protected]89ceba9a2009-03-21 03:46:067657
7658 { // Setup state for response_.vary_data
7659 HttpRequestInfo request;
7660 std::string temp("HTTP/1.1 200 OK\nVary: foo, bar\n\n");
7661 std::replace(temp.begin(), temp.end(), '\n', '\0');
[email protected]ad8e04a2010-11-01 04:16:277662 scoped_refptr<HttpResponseHeaders> headers(new HttpResponseHeaders(temp));
[email protected]8c76ae22010-04-20 22:15:437663 request.extra_headers.SetHeader("Foo", "1");
7664 request.extra_headers.SetHeader("bar", "23");
[email protected]90499482013-06-01 00:39:507665 EXPECT_TRUE(response->vary_data.Init(request, *headers.get()));
[email protected]89ceba9a2009-03-21 03:46:067666 }
7667
7668 // Cause the above state to be reset.
bnc691fda62016-08-12 00:43:167669 trans.ResetStateForRestart();
[email protected]89ceba9a2009-03-21 03:46:067670
7671 // Verify that the state that needed to be reset, has been reset.
bnc691fda62016-08-12 00:43:167672 EXPECT_FALSE(trans.read_buf_);
7673 EXPECT_EQ(0, trans.read_buf_len_);
7674 EXPECT_TRUE(trans.request_headers_.IsEmpty());
wezca1070932016-05-26 20:30:527675 EXPECT_FALSE(response->auth_challenge);
7676 EXPECT_FALSE(response->headers);
[email protected]34f40942010-10-04 00:34:047677 EXPECT_FALSE(response->was_cached);
[email protected]70d66502011-09-23 00:55:087678 EXPECT_EQ(0U, response->ssl_info.cert_status);
[email protected]0877e3d2009-10-17 22:29:577679 EXPECT_FALSE(response->vary_data.is_valid());
[email protected]89ceba9a2009-03-21 03:46:067680}
7681
[email protected]bacff652009-03-31 17:50:337682// Test HTTPS connections to a site with a bad certificate
bncd16676a2016-07-20 16:23:017683TEST_F(HttpNetworkTransactionTest, HTTPSBadCertificate) {
[email protected]bacff652009-03-31 17:50:337684 HttpRequestInfo request;
7685 request.method = "GET";
bncce36dca22015-04-21 22:11:237686 request.url = GURL("https://www.example.org/");
[email protected]bacff652009-03-31 17:50:337687
danakj1fd259a02016-04-16 03:17:097688 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:167689 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:277690
[email protected]bacff652009-03-31 17:50:337691 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:237692 MockWrite(
7693 "GET / HTTP/1.1\r\n"
7694 "Host: www.example.org\r\n"
7695 "Connection: keep-alive\r\n\r\n"),
[email protected]bacff652009-03-31 17:50:337696 };
7697
7698 MockRead data_reads[] = {
7699 MockRead("HTTP/1.0 200 OK\r\n"),
7700 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
7701 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067702 MockRead(SYNCHRONOUS, OK),
[email protected]bacff652009-03-31 17:50:337703 };
7704
[email protected]5ecc992a42009-11-11 01:41:597705 StaticSocketDataProvider ssl_bad_certificate;
[email protected]31a2bfe2010-02-09 08:03:397706 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
7707 data_writes, arraysize(data_writes));
[email protected]8ddf8322012-02-23 18:08:067708 SSLSocketDataProvider ssl_bad(ASYNC, ERR_CERT_AUTHORITY_INVALID);
7709 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bacff652009-03-31 17:50:337710
[email protected]bb88e1d32013-05-03 23:11:077711 session_deps_.socket_factory->AddSocketDataProvider(&ssl_bad_certificate);
7712 session_deps_.socket_factory->AddSocketDataProvider(&data);
7713 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_bad);
7714 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]bacff652009-03-31 17:50:337715
[email protected]49639fa2011-12-20 23:22:417716 TestCompletionCallback callback;
[email protected]bacff652009-03-31 17:50:337717
tfarina42834112016-09-22 13:38:207718 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:017719 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]bacff652009-03-31 17:50:337720
7721 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:017722 EXPECT_THAT(rv, IsError(ERR_CERT_AUTHORITY_INVALID));
[email protected]bacff652009-03-31 17:50:337723
bnc691fda62016-08-12 00:43:167724 rv = trans.RestartIgnoringLastError(callback.callback());
robpercival214763f2016-07-01 23:27:017725 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]bacff652009-03-31 17:50:337726
7727 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:017728 EXPECT_THAT(rv, IsOk());
[email protected]bacff652009-03-31 17:50:337729
bnc691fda62016-08-12 00:43:167730 const HttpResponseInfo* response = trans.GetResponseInfo();
[email protected]bacff652009-03-31 17:50:337731
wezca1070932016-05-26 20:30:527732 ASSERT_TRUE(response);
[email protected]bacff652009-03-31 17:50:337733 EXPECT_EQ(100, response->headers->GetContentLength());
7734}
7735
7736// Test HTTPS connections to a site with a bad certificate, going through a
7737// proxy
bncd16676a2016-07-20 16:23:017738TEST_F(HttpNetworkTransactionTest, HTTPSBadCertificateViaProxy) {
rdsmith82957ad2015-09-16 19:42:037739 session_deps_.proxy_service = ProxyService::CreateFixed("myproxy:70");
[email protected]bacff652009-03-31 17:50:337740
7741 HttpRequestInfo request;
7742 request.method = "GET";
bncce36dca22015-04-21 22:11:237743 request.url = GURL("https://www.example.org/");
[email protected]bacff652009-03-31 17:50:337744
7745 MockWrite proxy_writes[] = {
rsleevidb16bb02015-11-12 23:47:177746 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
7747 "Host: www.example.org:443\r\n"
7748 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]bacff652009-03-31 17:50:337749 };
7750
7751 MockRead proxy_reads[] = {
7752 MockRead("HTTP/1.0 200 Connected\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067753 MockRead(SYNCHRONOUS, OK)
[email protected]bacff652009-03-31 17:50:337754 };
7755
7756 MockWrite data_writes[] = {
rsleevidb16bb02015-11-12 23:47:177757 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
7758 "Host: www.example.org:443\r\n"
7759 "Proxy-Connection: keep-alive\r\n\r\n"),
7760 MockWrite("GET / HTTP/1.1\r\n"
7761 "Host: www.example.org\r\n"
7762 "Connection: keep-alive\r\n\r\n"),
[email protected]bacff652009-03-31 17:50:337763 };
7764
7765 MockRead data_reads[] = {
7766 MockRead("HTTP/1.0 200 Connected\r\n\r\n"),
7767 MockRead("HTTP/1.0 200 OK\r\n"),
7768 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
7769 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067770 MockRead(SYNCHRONOUS, OK),
[email protected]bacff652009-03-31 17:50:337771 };
7772
[email protected]31a2bfe2010-02-09 08:03:397773 StaticSocketDataProvider ssl_bad_certificate(
7774 proxy_reads, arraysize(proxy_reads),
7775 proxy_writes, arraysize(proxy_writes));
7776 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
7777 data_writes, arraysize(data_writes));
[email protected]8ddf8322012-02-23 18:08:067778 SSLSocketDataProvider ssl_bad(ASYNC, ERR_CERT_AUTHORITY_INVALID);
7779 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bacff652009-03-31 17:50:337780
[email protected]bb88e1d32013-05-03 23:11:077781 session_deps_.socket_factory->AddSocketDataProvider(&ssl_bad_certificate);
7782 session_deps_.socket_factory->AddSocketDataProvider(&data);
7783 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_bad);
7784 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]bacff652009-03-31 17:50:337785
[email protected]49639fa2011-12-20 23:22:417786 TestCompletionCallback callback;
[email protected]bacff652009-03-31 17:50:337787
7788 for (int i = 0; i < 2; i++) {
[email protected]bb88e1d32013-05-03 23:11:077789 session_deps_.socket_factory->ResetNextMockIndexes();
[email protected]bacff652009-03-31 17:50:337790
danakj1fd259a02016-04-16 03:17:097791 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:167792 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]bacff652009-03-31 17:50:337793
tfarina42834112016-09-22 13:38:207794 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:017795 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]bacff652009-03-31 17:50:337796
7797 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:017798 EXPECT_THAT(rv, IsError(ERR_CERT_AUTHORITY_INVALID));
[email protected]bacff652009-03-31 17:50:337799
bnc691fda62016-08-12 00:43:167800 rv = trans.RestartIgnoringLastError(callback.callback());
robpercival214763f2016-07-01 23:27:017801 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]bacff652009-03-31 17:50:337802
7803 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:017804 EXPECT_THAT(rv, IsOk());
[email protected]bacff652009-03-31 17:50:337805
bnc691fda62016-08-12 00:43:167806 const HttpResponseInfo* response = trans.GetResponseInfo();
[email protected]bacff652009-03-31 17:50:337807
wezca1070932016-05-26 20:30:527808 ASSERT_TRUE(response);
[email protected]bacff652009-03-31 17:50:337809 EXPECT_EQ(100, response->headers->GetContentLength());
7810 }
7811}
7812
[email protected]2df19bb2010-08-25 20:13:467813
7814// Test HTTPS connections to a site, going through an HTTPS proxy
bncd16676a2016-07-20 16:23:017815TEST_F(HttpNetworkTransactionTest, HTTPSViaHttpsProxy) {
rdsmith82957ad2015-09-16 19:42:037816 session_deps_.proxy_service =
7817 ProxyService::CreateFixedFromPacResult("HTTPS proxy:70");
vishal.b62985ca92015-04-17 08:45:517818 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:077819 session_deps_.net_log = &net_log;
[email protected]2df19bb2010-08-25 20:13:467820
7821 HttpRequestInfo request;
7822 request.method = "GET";
bncce36dca22015-04-21 22:11:237823 request.url = GURL("https://www.example.org/");
[email protected]2df19bb2010-08-25 20:13:467824
7825 MockWrite data_writes[] = {
rsleevidb16bb02015-11-12 23:47:177826 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
7827 "Host: www.example.org:443\r\n"
7828 "Proxy-Connection: keep-alive\r\n\r\n"),
7829 MockWrite("GET / HTTP/1.1\r\n"
7830 "Host: www.example.org\r\n"
7831 "Connection: keep-alive\r\n\r\n"),
[email protected]2df19bb2010-08-25 20:13:467832 };
7833
7834 MockRead data_reads[] = {
7835 MockRead("HTTP/1.0 200 Connected\r\n\r\n"),
7836 MockRead("HTTP/1.1 200 OK\r\n"),
7837 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
7838 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067839 MockRead(SYNCHRONOUS, OK),
[email protected]2df19bb2010-08-25 20:13:467840 };
7841
7842 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
7843 data_writes, arraysize(data_writes));
[email protected]8ddf8322012-02-23 18:08:067844 SSLSocketDataProvider proxy_ssl(ASYNC, OK); // SSL to the proxy
7845 SSLSocketDataProvider tunnel_ssl(ASYNC, OK); // SSL through the tunnel
[email protected]2df19bb2010-08-25 20:13:467846
[email protected]bb88e1d32013-05-03 23:11:077847 session_deps_.socket_factory->AddSocketDataProvider(&data);
7848 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy_ssl);
7849 session_deps_.socket_factory->AddSSLSocketDataProvider(&tunnel_ssl);
[email protected]2df19bb2010-08-25 20:13:467850
[email protected]49639fa2011-12-20 23:22:417851 TestCompletionCallback callback;
[email protected]2df19bb2010-08-25 20:13:467852
danakj1fd259a02016-04-16 03:17:097853 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:167854 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]2df19bb2010-08-25 20:13:467855
tfarina42834112016-09-22 13:38:207856 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:017857 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2df19bb2010-08-25 20:13:467858
7859 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:017860 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:167861 const HttpResponseInfo* response = trans.GetResponseInfo();
[email protected]2df19bb2010-08-25 20:13:467862
wezca1070932016-05-26 20:30:527863 ASSERT_TRUE(response);
[email protected]2df19bb2010-08-25 20:13:467864
tbansal2ecbbc72016-10-06 17:15:477865 EXPECT_TRUE(response->proxy_server.is_https());
[email protected]2df19bb2010-08-25 20:13:467866 EXPECT_TRUE(response->headers->IsKeepAlive());
7867 EXPECT_EQ(200, response->headers->response_code());
7868 EXPECT_EQ(100, response->headers->GetContentLength());
7869 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
[email protected]029c83b62013-01-24 05:28:207870
7871 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:167872 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]029c83b62013-01-24 05:28:207873 TestLoadTimingNotReusedWithPac(load_timing_info,
7874 CONNECT_TIMING_HAS_SSL_TIMES);
[email protected]2df19bb2010-08-25 20:13:467875}
7876
[email protected]511f6f52010-12-17 03:58:297877// Test an HTTPS Proxy's ability to redirect a CONNECT request
bncd16676a2016-07-20 16:23:017878TEST_F(HttpNetworkTransactionTest, RedirectOfHttpsConnectViaHttpsProxy) {
rdsmith82957ad2015-09-16 19:42:037879 session_deps_.proxy_service =
7880 ProxyService::CreateFixedFromPacResult("HTTPS proxy:70");
vishal.b62985ca92015-04-17 08:45:517881 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:077882 session_deps_.net_log = &net_log;
[email protected]511f6f52010-12-17 03:58:297883
7884 HttpRequestInfo request;
7885 request.method = "GET";
bncce36dca22015-04-21 22:11:237886 request.url = GURL("https://www.example.org/");
[email protected]511f6f52010-12-17 03:58:297887
7888 MockWrite data_writes[] = {
rsleevidb16bb02015-11-12 23:47:177889 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
7890 "Host: www.example.org:443\r\n"
7891 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]511f6f52010-12-17 03:58:297892 };
7893
7894 MockRead data_reads[] = {
7895 MockRead("HTTP/1.1 302 Redirect\r\n"),
7896 MockRead("Location: http://login.example.com/\r\n"),
7897 MockRead("Content-Length: 0\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067898 MockRead(SYNCHRONOUS, OK),
[email protected]511f6f52010-12-17 03:58:297899 };
7900
7901 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
7902 data_writes, arraysize(data_writes));
[email protected]8ddf8322012-02-23 18:08:067903 SSLSocketDataProvider proxy_ssl(ASYNC, OK); // SSL to the proxy
[email protected]511f6f52010-12-17 03:58:297904
[email protected]bb88e1d32013-05-03 23:11:077905 session_deps_.socket_factory->AddSocketDataProvider(&data);
7906 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy_ssl);
[email protected]511f6f52010-12-17 03:58:297907
[email protected]49639fa2011-12-20 23:22:417908 TestCompletionCallback callback;
[email protected]511f6f52010-12-17 03:58:297909
danakj1fd259a02016-04-16 03:17:097910 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:167911 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]511f6f52010-12-17 03:58:297912
tfarina42834112016-09-22 13:38:207913 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:017914 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]511f6f52010-12-17 03:58:297915
7916 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:017917 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:167918 const HttpResponseInfo* response = trans.GetResponseInfo();
[email protected]511f6f52010-12-17 03:58:297919
wezca1070932016-05-26 20:30:527920 ASSERT_TRUE(response);
[email protected]511f6f52010-12-17 03:58:297921
7922 EXPECT_EQ(302, response->headers->response_code());
7923 std::string url;
7924 EXPECT_TRUE(response->headers->IsRedirect(&url));
7925 EXPECT_EQ("http://login.example.com/", url);
[email protected]029c83b62013-01-24 05:28:207926
7927 // In the case of redirects from proxies, HttpNetworkTransaction returns
7928 // timing for the proxy connection instead of the connection to the host,
7929 // and no send / receive times.
7930 // See HttpNetworkTransaction::OnHttpsProxyTunnelResponse.
7931 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:167932 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]029c83b62013-01-24 05:28:207933
7934 EXPECT_FALSE(load_timing_info.socket_reused);
mikecironef22f9812016-10-04 03:40:197935 EXPECT_NE(NetLogSource::kInvalidId, load_timing_info.socket_log_id);
[email protected]029c83b62013-01-24 05:28:207936
7937 EXPECT_FALSE(load_timing_info.proxy_resolve_start.is_null());
7938 EXPECT_LE(load_timing_info.proxy_resolve_start,
7939 load_timing_info.proxy_resolve_end);
7940 EXPECT_LE(load_timing_info.proxy_resolve_end,
7941 load_timing_info.connect_timing.connect_start);
7942 ExpectConnectTimingHasTimes(
7943 load_timing_info.connect_timing,
7944 CONNECT_TIMING_HAS_DNS_TIMES | CONNECT_TIMING_HAS_SSL_TIMES);
7945
7946 EXPECT_TRUE(load_timing_info.send_start.is_null());
7947 EXPECT_TRUE(load_timing_info.send_end.is_null());
7948 EXPECT_TRUE(load_timing_info.receive_headers_end.is_null());
[email protected]511f6f52010-12-17 03:58:297949}
7950
7951// Test an HTTPS (SPDY) Proxy's ability to redirect a CONNECT request
bncd16676a2016-07-20 16:23:017952TEST_F(HttpNetworkTransactionTest, RedirectOfHttpsConnectViaSpdyProxy) {
rdsmith82957ad2015-09-16 19:42:037953 session_deps_.proxy_service = ProxyService::CreateFixed("https://proxy:70");
[email protected]511f6f52010-12-17 03:58:297954
7955 HttpRequestInfo request;
7956 request.method = "GET";
bncce36dca22015-04-21 22:11:237957 request.url = GURL("https://www.example.org/");
[email protected]511f6f52010-12-17 03:58:297958
bncdf80d44fd2016-07-15 20:27:417959 SpdySerializedFrame conn(spdy_util_.ConstructSpdyConnect(
bncce36dca22015-04-21 22:11:237960 NULL, 0, 1, LOWEST, HostPortPair("www.example.org", 443)));
bncdf80d44fd2016-07-15 20:27:417961 SpdySerializedFrame goaway(
diannahu9904e272017-02-03 14:40:087962 spdy_util_.ConstructSpdyRstStream(1, ERROR_CODE_CANCEL));
[email protected]511f6f52010-12-17 03:58:297963 MockWrite data_writes[] = {
bncdf80d44fd2016-07-15 20:27:417964 CreateMockWrite(conn, 0, SYNCHRONOUS),
7965 CreateMockWrite(goaway, 2, SYNCHRONOUS),
[email protected]511f6f52010-12-17 03:58:297966 };
7967
7968 static const char* const kExtraHeaders[] = {
7969 "location",
7970 "http://login.example.com/",
7971 };
bnc42331402016-07-25 13:36:157972 SpdySerializedFrame resp(spdy_util_.ConstructSpdyReplyError(
bncc9f762a2016-12-06 20:38:237973 "302", kExtraHeaders, arraysize(kExtraHeaders) / 2, 1));
[email protected]511f6f52010-12-17 03:58:297974 MockRead data_reads[] = {
bncdf80d44fd2016-07-15 20:27:417975 CreateMockRead(resp, 1), MockRead(ASYNC, 0, 3), // EOF
[email protected]511f6f52010-12-17 03:58:297976 };
7977
rch8e6c6c42015-05-01 14:05:137978 SequencedSocketData data(data_reads, arraysize(data_reads), data_writes,
7979 arraysize(data_writes));
[email protected]8ddf8322012-02-23 18:08:067980 SSLSocketDataProvider proxy_ssl(ASYNC, OK); // SSL to the proxy
bnc3cf2a592016-08-11 14:48:367981 proxy_ssl.next_proto = kProtoHTTP2;
[email protected]511f6f52010-12-17 03:58:297982
[email protected]bb88e1d32013-05-03 23:11:077983 session_deps_.socket_factory->AddSocketDataProvider(&data);
7984 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy_ssl);
[email protected]511f6f52010-12-17 03:58:297985
[email protected]49639fa2011-12-20 23:22:417986 TestCompletionCallback callback;
[email protected]511f6f52010-12-17 03:58:297987
danakj1fd259a02016-04-16 03:17:097988 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:167989 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]511f6f52010-12-17 03:58:297990
tfarina42834112016-09-22 13:38:207991 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:017992 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]511f6f52010-12-17 03:58:297993
7994 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:017995 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:167996 const HttpResponseInfo* response = trans.GetResponseInfo();
[email protected]511f6f52010-12-17 03:58:297997
wezca1070932016-05-26 20:30:527998 ASSERT_TRUE(response);
[email protected]511f6f52010-12-17 03:58:297999
8000 EXPECT_EQ(302, response->headers->response_code());
8001 std::string url;
8002 EXPECT_TRUE(response->headers->IsRedirect(&url));
8003 EXPECT_EQ("http://login.example.com/", url);
8004}
8005
[email protected]4eddbc732012-08-09 05:40:178006// Test that an HTTPS proxy's response to a CONNECT request is filtered.
bncd16676a2016-07-20 16:23:018007TEST_F(HttpNetworkTransactionTest, ErrorResponseToHttpsConnectViaHttpsProxy) {
rdsmith82957ad2015-09-16 19:42:038008 session_deps_.proxy_service = ProxyService::CreateFixed("https://proxy:70");
[email protected]511f6f52010-12-17 03:58:298009
8010 HttpRequestInfo request;
8011 request.method = "GET";
bncce36dca22015-04-21 22:11:238012 request.url = GURL("https://www.example.org/");
[email protected]511f6f52010-12-17 03:58:298013
8014 MockWrite data_writes[] = {
rsleevidb16bb02015-11-12 23:47:178015 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
8016 "Host: www.example.org:443\r\n"
8017 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]511f6f52010-12-17 03:58:298018 };
8019
8020 MockRead data_reads[] = {
8021 MockRead("HTTP/1.1 404 Not Found\r\n"),
8022 MockRead("Content-Length: 23\r\n\r\n"),
8023 MockRead("The host does not exist"),
[email protected]8ddf8322012-02-23 18:08:068024 MockRead(SYNCHRONOUS, OK),
[email protected]511f6f52010-12-17 03:58:298025 };
8026
8027 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
8028 data_writes, arraysize(data_writes));
[email protected]8ddf8322012-02-23 18:08:068029 SSLSocketDataProvider proxy_ssl(ASYNC, OK); // SSL to the proxy
[email protected]511f6f52010-12-17 03:58:298030
[email protected]bb88e1d32013-05-03 23:11:078031 session_deps_.socket_factory->AddSocketDataProvider(&data);
8032 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy_ssl);
[email protected]511f6f52010-12-17 03:58:298033
[email protected]49639fa2011-12-20 23:22:418034 TestCompletionCallback callback;
[email protected]511f6f52010-12-17 03:58:298035
danakj1fd259a02016-04-16 03:17:098036 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:168037 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]511f6f52010-12-17 03:58:298038
tfarina42834112016-09-22 13:38:208039 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:018040 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]511f6f52010-12-17 03:58:298041
8042 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:018043 EXPECT_THAT(rv, IsError(ERR_TUNNEL_CONNECTION_FAILED));
[email protected]511f6f52010-12-17 03:58:298044
ttuttle960fcbf2016-04-19 13:26:328045 // TODO(juliatuttle): Anything else to check here?
[email protected]511f6f52010-12-17 03:58:298046}
8047
[email protected]4eddbc732012-08-09 05:40:178048// Test that a SPDY proxy's response to a CONNECT request is filtered.
bncd16676a2016-07-20 16:23:018049TEST_F(HttpNetworkTransactionTest, ErrorResponseToHttpsConnectViaSpdyProxy) {
rdsmith82957ad2015-09-16 19:42:038050 session_deps_.proxy_service = ProxyService::CreateFixed("https://proxy:70");
[email protected]511f6f52010-12-17 03:58:298051
8052 HttpRequestInfo request;
8053 request.method = "GET";
bncce36dca22015-04-21 22:11:238054 request.url = GURL("https://www.example.org/");
[email protected]511f6f52010-12-17 03:58:298055
bncdf80d44fd2016-07-15 20:27:418056 SpdySerializedFrame conn(spdy_util_.ConstructSpdyConnect(
bncce36dca22015-04-21 22:11:238057 NULL, 0, 1, LOWEST, HostPortPair("www.example.org", 443)));
bncdf80d44fd2016-07-15 20:27:418058 SpdySerializedFrame rst(
diannahu9904e272017-02-03 14:40:088059 spdy_util_.ConstructSpdyRstStream(1, ERROR_CODE_CANCEL));
[email protected]511f6f52010-12-17 03:58:298060 MockWrite data_writes[] = {
bncdf80d44fd2016-07-15 20:27:418061 CreateMockWrite(conn, 0), CreateMockWrite(rst, 3),
[email protected]511f6f52010-12-17 03:58:298062 };
8063
8064 static const char* const kExtraHeaders[] = {
8065 "location",
8066 "http://login.example.com/",
8067 };
bnc42331402016-07-25 13:36:158068 SpdySerializedFrame resp(spdy_util_.ConstructSpdyReplyError(
bncc9f762a2016-12-06 20:38:238069 "404", kExtraHeaders, arraysize(kExtraHeaders) / 2, 1));
bncdf80d44fd2016-07-15 20:27:418070 SpdySerializedFrame body(spdy_util_.ConstructSpdyDataFrame(
bncb03b1092016-04-06 11:19:558071 1, "The host does not exist", 23, true));
[email protected]511f6f52010-12-17 03:58:298072 MockRead data_reads[] = {
bncdf80d44fd2016-07-15 20:27:418073 CreateMockRead(resp, 1), CreateMockRead(body, 2),
rch8e6c6c42015-05-01 14:05:138074 MockRead(ASYNC, 0, 4), // EOF
[email protected]511f6f52010-12-17 03:58:298075 };
8076
rch8e6c6c42015-05-01 14:05:138077 SequencedSocketData data(data_reads, arraysize(data_reads), data_writes,
8078 arraysize(data_writes));
[email protected]8ddf8322012-02-23 18:08:068079 SSLSocketDataProvider proxy_ssl(ASYNC, OK); // SSL to the proxy
bnc3cf2a592016-08-11 14:48:368080 proxy_ssl.next_proto = kProtoHTTP2;
[email protected]511f6f52010-12-17 03:58:298081
[email protected]bb88e1d32013-05-03 23:11:078082 session_deps_.socket_factory->AddSocketDataProvider(&data);
8083 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy_ssl);
[email protected]511f6f52010-12-17 03:58:298084
[email protected]49639fa2011-12-20 23:22:418085 TestCompletionCallback callback;
[email protected]511f6f52010-12-17 03:58:298086
danakj1fd259a02016-04-16 03:17:098087 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:168088 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]511f6f52010-12-17 03:58:298089
tfarina42834112016-09-22 13:38:208090 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:018091 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]511f6f52010-12-17 03:58:298092
8093 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:018094 EXPECT_THAT(rv, IsError(ERR_TUNNEL_CONNECTION_FAILED));
[email protected]511f6f52010-12-17 03:58:298095
ttuttle960fcbf2016-04-19 13:26:328096 // TODO(juliatuttle): Anything else to check here?
[email protected]511f6f52010-12-17 03:58:298097}
8098
[email protected]0c5fb722012-02-28 11:50:358099// Test the request-challenge-retry sequence for basic auth, through
8100// a SPDY proxy over a single SPDY session.
bncd16676a2016-07-20 16:23:018101TEST_F(HttpNetworkTransactionTest, BasicAuthSpdyProxy) {
[email protected]0c5fb722012-02-28 11:50:358102 HttpRequestInfo request;
8103 request.method = "GET";
bncce36dca22015-04-21 22:11:238104 request.url = GURL("https://www.example.org/");
[email protected]0c5fb722012-02-28 11:50:358105 // when the no authentication data flag is set.
ttuttle859dc7a2015-04-23 19:42:298106 request.load_flags = LOAD_DO_NOT_SEND_AUTH_DATA;
[email protected]0c5fb722012-02-28 11:50:358107
8108 // Configure against https proxy server "myproxy:70".
rdsmith82957ad2015-09-16 19:42:038109 session_deps_.proxy_service =
8110 ProxyService::CreateFixedFromPacResult("HTTPS myproxy:70");
vishal.b62985ca92015-04-17 08:45:518111 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:078112 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:098113 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]0c5fb722012-02-28 11:50:358114
8115 // Since we have proxy, should try to establish tunnel.
bncdf80d44fd2016-07-15 20:27:418116 SpdySerializedFrame req(spdy_util_.ConstructSpdyConnect(
bncce36dca22015-04-21 22:11:238117 NULL, 0, 1, LOWEST, HostPortPair("www.example.org", 443)));
bncdf80d44fd2016-07-15 20:27:418118 SpdySerializedFrame rst(
diannahu9904e272017-02-03 14:40:088119 spdy_util_.ConstructSpdyRstStream(1, ERROR_CODE_CANCEL));
rdsmithebb50aa2015-11-12 03:44:388120 spdy_util_.UpdateWithStreamDestruction(1);
[email protected]0c5fb722012-02-28 11:50:358121
bnc691fda62016-08-12 00:43:168122 // After calling trans.RestartWithAuth(), this is the request we should
[email protected]0c5fb722012-02-28 11:50:358123 // be issuing -- the final header line contains the credentials.
8124 const char* const kAuthCredentials[] = {
8125 "proxy-authorization", "Basic Zm9vOmJhcg==",
8126 };
bncdf80d44fd2016-07-15 20:27:418127 SpdySerializedFrame connect2(spdy_util_.ConstructSpdyConnect(
lgarrona91df87f2014-12-05 00:51:348128 kAuthCredentials, arraysize(kAuthCredentials) / 2, 3, LOWEST,
bncce36dca22015-04-21 22:11:238129 HostPortPair("www.example.org", 443)));
8130 // fetch https://www.example.org/ via HTTP
8131 const char get[] =
8132 "GET / HTTP/1.1\r\n"
8133 "Host: www.example.org\r\n"
8134 "Connection: keep-alive\r\n\r\n";
bncdf80d44fd2016-07-15 20:27:418135 SpdySerializedFrame wrapped_get(
8136 spdy_util_.ConstructSpdyDataFrame(3, get, strlen(get), false));
[email protected]0c5fb722012-02-28 11:50:358137
8138 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:418139 CreateMockWrite(req, 0, ASYNC), CreateMockWrite(rst, 2, ASYNC),
8140 CreateMockWrite(connect2, 3), CreateMockWrite(wrapped_get, 5),
[email protected]0c5fb722012-02-28 11:50:358141 };
8142
8143 // The proxy responds to the connect with a 407, using a persistent
8144 // connection.
thestig9d3bb0c2015-01-24 00:49:518145 const char kAuthStatus[] = "407";
[email protected]0c5fb722012-02-28 11:50:358146 const char* const kAuthChallenge[] = {
[email protected]0c5fb722012-02-28 11:50:358147 "proxy-authenticate", "Basic realm=\"MyRealm1\"",
8148 };
bnc42331402016-07-25 13:36:158149 SpdySerializedFrame conn_auth_resp(spdy_util_.ConstructSpdyReplyError(
bncdf80d44fd2016-07-15 20:27:418150 kAuthStatus, kAuthChallenge, arraysize(kAuthChallenge) / 2, 1));
[email protected]0c5fb722012-02-28 11:50:358151
bnc42331402016-07-25 13:36:158152 SpdySerializedFrame conn_resp(spdy_util_.ConstructSpdyGetReply(NULL, 0, 3));
[email protected]0c5fb722012-02-28 11:50:358153 const char resp[] = "HTTP/1.1 200 OK\r\n"
8154 "Content-Length: 5\r\n\r\n";
8155
bncdf80d44fd2016-07-15 20:27:418156 SpdySerializedFrame wrapped_get_resp(
8157 spdy_util_.ConstructSpdyDataFrame(3, resp, strlen(resp), false));
8158 SpdySerializedFrame wrapped_body(
8159 spdy_util_.ConstructSpdyDataFrame(3, "hello", 5, false));
[email protected]0c5fb722012-02-28 11:50:358160 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:418161 CreateMockRead(conn_auth_resp, 1, ASYNC),
8162 CreateMockRead(conn_resp, 4, ASYNC),
8163 CreateMockRead(wrapped_get_resp, 6, ASYNC),
8164 CreateMockRead(wrapped_body, 7, ASYNC),
rch8e6c6c42015-05-01 14:05:138165 MockRead(ASYNC, OK, 8), // EOF. May or may not be read.
[email protected]0c5fb722012-02-28 11:50:358166 };
8167
rch8e6c6c42015-05-01 14:05:138168 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
8169 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:078170 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]0c5fb722012-02-28 11:50:358171 // Negotiate SPDY to the proxy
8172 SSLSocketDataProvider proxy(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:368173 proxy.next_proto = kProtoHTTP2;
[email protected]bb88e1d32013-05-03 23:11:078174 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy);
[email protected]0c5fb722012-02-28 11:50:358175 // Vanilla SSL to the server
8176 SSLSocketDataProvider server(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:078177 session_deps_.socket_factory->AddSSLSocketDataProvider(&server);
[email protected]0c5fb722012-02-28 11:50:358178
8179 TestCompletionCallback callback1;
8180
bnc87dcefc2017-05-25 12:47:588181 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:198182 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]0c5fb722012-02-28 11:50:358183
8184 int rv = trans->Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:018185 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]0c5fb722012-02-28 11:50:358186
8187 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:018188 EXPECT_THAT(rv, IsOk());
mmenke43758e62015-05-04 21:09:468189 TestNetLogEntry::List entries;
[email protected]0c5fb722012-02-28 11:50:358190 log.GetEntries(&entries);
8191 size_t pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:008192 entries, 0, NetLogEventType::HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
8193 NetLogEventPhase::NONE);
[email protected]0c5fb722012-02-28 11:50:358194 ExpectLogContainsSomewhere(
8195 entries, pos,
mikecirone8b85c432016-09-08 19:11:008196 NetLogEventType::HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
8197 NetLogEventPhase::NONE);
[email protected]0c5fb722012-02-28 11:50:358198
8199 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:528200 ASSERT_TRUE(response);
8201 ASSERT_TRUE(response->headers);
[email protected]0c5fb722012-02-28 11:50:358202 EXPECT_EQ(407, response->headers->response_code());
8203 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
wezca1070932016-05-26 20:30:528204 EXPECT_TRUE(response->auth_challenge);
asanka098c0092016-06-16 20:18:438205 EXPECT_TRUE(CheckBasicSecureProxyAuth(response->auth_challenge.get()));
[email protected]0c5fb722012-02-28 11:50:358206
8207 TestCompletionCallback callback2;
8208
8209 rv = trans->RestartWithAuth(AuthCredentials(kFoo, kBar),
8210 callback2.callback());
robpercival214763f2016-07-01 23:27:018211 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]0c5fb722012-02-28 11:50:358212
8213 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:018214 EXPECT_THAT(rv, IsOk());
[email protected]0c5fb722012-02-28 11:50:358215
8216 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:528217 ASSERT_TRUE(response);
[email protected]0c5fb722012-02-28 11:50:358218
8219 EXPECT_TRUE(response->headers->IsKeepAlive());
8220 EXPECT_EQ(200, response->headers->response_code());
8221 EXPECT_EQ(5, response->headers->GetContentLength());
8222 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
8223
8224 // The password prompt info should not be set.
wezca1070932016-05-26 20:30:528225 EXPECT_FALSE(response->auth_challenge);
[email protected]0c5fb722012-02-28 11:50:358226
[email protected]029c83b62013-01-24 05:28:208227 LoadTimingInfo load_timing_info;
8228 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
8229 TestLoadTimingNotReusedWithPac(load_timing_info,
8230 CONNECT_TIMING_HAS_SSL_TIMES);
8231
[email protected]0c5fb722012-02-28 11:50:358232 trans.reset();
8233 session->CloseAllConnections();
8234}
8235
[email protected]7c6f7ba2012-04-03 04:09:298236// Test that an explicitly trusted SPDY proxy can push a resource from an
8237// origin that is different from that of its associated resource.
bncd16676a2016-07-20 16:23:018238TEST_F(HttpNetworkTransactionTest, CrossOriginSPDYProxyPush) {
tbansal28e68f82016-02-04 02:56:158239 // Configure the proxy delegate to allow cross-origin SPDY pushes.
Jeremy Roman0579ed62017-08-29 15:56:198240 auto proxy_delegate = std::make_unique<TestProxyDelegate>();
tbansal28e68f82016-02-04 02:56:158241 proxy_delegate->set_trusted_spdy_proxy(net::ProxyServer::FromURI(
8242 "https://myproxy:443", net::ProxyServer::SCHEME_HTTP));
[email protected]7c6f7ba2012-04-03 04:09:298243 HttpRequestInfo request;
8244 HttpRequestInfo push_request;
8245
[email protected]7c6f7ba2012-04-03 04:09:298246 request.method = "GET";
bncce36dca22015-04-21 22:11:238247 request.url = GURL("http://www.example.org/");
[email protected]7c6f7ba2012-04-03 04:09:298248 push_request.method = "GET";
8249 push_request.url = GURL("http://www.another-origin.com/foo.dat");
8250
tbansal28e68f82016-02-04 02:56:158251 // Configure against https proxy server "myproxy:443".
rdsmith82957ad2015-09-16 19:42:038252 session_deps_.proxy_service =
tbansal28e68f82016-02-04 02:56:158253 ProxyService::CreateFixedFromPacResult("HTTPS myproxy:443");
vishal.b62985ca92015-04-17 08:45:518254 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:078255 session_deps_.net_log = log.bound().net_log();
[email protected]61b4efc2012-04-27 18:12:508256
inlinechan894515af2016-12-09 02:40:108257 session_deps_.proxy_delegate = std::move(proxy_delegate);
[email protected]61b4efc2012-04-27 18:12:508258
danakj1fd259a02016-04-16 03:17:098259 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]7c6f7ba2012-04-03 04:09:298260
bncdf80d44fd2016-07-15 20:27:418261 SpdySerializedFrame stream1_syn(
bncb26024382016-06-29 02:39:458262 spdy_util_.ConstructSpdyGet("http://www.example.org/", 1, LOWEST));
tombergan5d22c182017-01-11 02:05:358263 SpdySerializedFrame stream2_priority(
8264 spdy_util_.ConstructSpdyPriority(2, 1, IDLE, true));
[email protected]7c6f7ba2012-04-03 04:09:298265
8266 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:418267 CreateMockWrite(stream1_syn, 0, ASYNC),
tombergan5d22c182017-01-11 02:05:358268 CreateMockWrite(stream2_priority, 3, ASYNC),
[email protected]7c6f7ba2012-04-03 04:09:298269 };
8270
bncdf80d44fd2016-07-15 20:27:418271 SpdySerializedFrame stream1_reply(
bnc42331402016-07-25 13:36:158272 spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
[email protected]7c6f7ba2012-04-03 04:09:298273
bncdf80d44fd2016-07-15 20:27:418274 SpdySerializedFrame stream1_body(spdy_util_.ConstructSpdyDataFrame(1, true));
[email protected]7c6f7ba2012-04-03 04:09:298275
bncdf80d44fd2016-07-15 20:27:418276 SpdySerializedFrame stream2_syn(spdy_util_.ConstructSpdyPush(
bncb03b1092016-04-06 11:19:558277 NULL, 0, 2, 1, "http://www.another-origin.com/foo.dat"));
[email protected]8a0fc822013-06-27 20:52:438278 const char kPushedData[] = "pushed";
bncdf80d44fd2016-07-15 20:27:418279 SpdySerializedFrame stream2_body(spdy_util_.ConstructSpdyDataFrame(
8280 2, kPushedData, strlen(kPushedData), true));
[email protected]7c6f7ba2012-04-03 04:09:298281
8282 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:418283 CreateMockRead(stream1_reply, 1, ASYNC),
8284 CreateMockRead(stream2_syn, 2, ASYNC),
tombergan5d22c182017-01-11 02:05:358285 CreateMockRead(stream1_body, 4, ASYNC),
8286 CreateMockRead(stream2_body, 5, ASYNC),
8287 MockRead(SYNCHRONOUS, ERR_IO_PENDING, 6), // Force a hang
[email protected]7c6f7ba2012-04-03 04:09:298288 };
8289
rch8e6c6c42015-05-01 14:05:138290 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
8291 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:078292 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]7c6f7ba2012-04-03 04:09:298293 // Negotiate SPDY to the proxy
8294 SSLSocketDataProvider proxy(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:368295 proxy.next_proto = kProtoHTTP2;
[email protected]bb88e1d32013-05-03 23:11:078296 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy);
[email protected]7c6f7ba2012-04-03 04:09:298297
bnc87dcefc2017-05-25 12:47:588298 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:198299 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]7c6f7ba2012-04-03 04:09:298300 TestCompletionCallback callback;
8301 int rv = trans->Start(&request, callback.callback(), log.bound());
robpercival214763f2016-07-01 23:27:018302 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]7c6f7ba2012-04-03 04:09:298303
8304 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:018305 EXPECT_THAT(rv, IsOk());
[email protected]7c6f7ba2012-04-03 04:09:298306 const HttpResponseInfo* response = trans->GetResponseInfo();
8307
bnc87dcefc2017-05-25 12:47:588308 auto push_trans =
Jeremy Roman0579ed62017-08-29 15:56:198309 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]90499482013-06-01 00:39:508310 rv = push_trans->Start(&push_request, callback.callback(), log.bound());
robpercival214763f2016-07-01 23:27:018311 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]7c6f7ba2012-04-03 04:09:298312
8313 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:018314 EXPECT_THAT(rv, IsOk());
[email protected]7c6f7ba2012-04-03 04:09:298315 const HttpResponseInfo* push_response = push_trans->GetResponseInfo();
8316
wezca1070932016-05-26 20:30:528317 ASSERT_TRUE(response);
[email protected]7c6f7ba2012-04-03 04:09:298318 EXPECT_TRUE(response->headers->IsKeepAlive());
8319
8320 EXPECT_EQ(200, response->headers->response_code());
8321 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
8322
8323 std::string response_data;
8324 rv = ReadTransaction(trans.get(), &response_data);
robpercival214763f2016-07-01 23:27:018325 EXPECT_THAT(rv, IsOk());
[email protected]7c6f7ba2012-04-03 04:09:298326 EXPECT_EQ("hello!", response_data);
8327
[email protected]029c83b62013-01-24 05:28:208328 LoadTimingInfo load_timing_info;
8329 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
8330 TestLoadTimingNotReusedWithPac(load_timing_info,
8331 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
8332
[email protected]7c6f7ba2012-04-03 04:09:298333 // Verify the pushed stream.
wezca1070932016-05-26 20:30:528334 EXPECT_TRUE(push_response->headers);
[email protected]7c6f7ba2012-04-03 04:09:298335 EXPECT_EQ(200, push_response->headers->response_code());
8336
8337 rv = ReadTransaction(push_trans.get(), &response_data);
robpercival214763f2016-07-01 23:27:018338 EXPECT_THAT(rv, IsOk());
[email protected]7c6f7ba2012-04-03 04:09:298339 EXPECT_EQ("pushed", response_data);
8340
[email protected]029c83b62013-01-24 05:28:208341 LoadTimingInfo push_load_timing_info;
8342 EXPECT_TRUE(push_trans->GetLoadTimingInfo(&push_load_timing_info));
8343 TestLoadTimingReusedWithPac(push_load_timing_info);
8344 // The transactions should share a socket ID, despite being for different
8345 // origins.
8346 EXPECT_EQ(load_timing_info.socket_log_id,
8347 push_load_timing_info.socket_log_id);
8348
[email protected]7c6f7ba2012-04-03 04:09:298349 trans.reset();
8350 push_trans.reset();
8351 session->CloseAllConnections();
8352}
8353
[email protected]8c843192012-04-05 07:15:008354// Test that an explicitly trusted SPDY proxy cannot push HTTPS content.
bncd16676a2016-07-20 16:23:018355TEST_F(HttpNetworkTransactionTest, CrossOriginProxyPushCorrectness) {
tbansal28e68f82016-02-04 02:56:158356 // Configure the proxy delegate to allow cross-origin SPDY pushes.
Jeremy Roman0579ed62017-08-29 15:56:198357 auto proxy_delegate = std::make_unique<TestProxyDelegate>();
tbansal28e68f82016-02-04 02:56:158358 proxy_delegate->set_trusted_spdy_proxy(net::ProxyServer::FromURI(
8359 "https://myproxy:443", net::ProxyServer::SCHEME_HTTP));
[email protected]8c843192012-04-05 07:15:008360 HttpRequestInfo request;
8361
8362 request.method = "GET";
bncce36dca22015-04-21 22:11:238363 request.url = GURL("http://www.example.org/");
[email protected]8c843192012-04-05 07:15:008364
tbansal28e68f82016-02-04 02:56:158365 session_deps_.proxy_service =
8366 ProxyService::CreateFixed("https://myproxy:443");
vishal.b62985ca92015-04-17 08:45:518367 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:078368 session_deps_.net_log = log.bound().net_log();
[email protected]61b4efc2012-04-27 18:12:508369
8370 // Enable cross-origin push.
inlinechan894515af2016-12-09 02:40:108371 session_deps_.proxy_delegate = std::move(proxy_delegate);
[email protected]61b4efc2012-04-27 18:12:508372
danakj1fd259a02016-04-16 03:17:098373 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]8c843192012-04-05 07:15:008374
bncdf80d44fd2016-07-15 20:27:418375 SpdySerializedFrame stream1_syn(
bncb26024382016-06-29 02:39:458376 spdy_util_.ConstructSpdyGet("http://www.example.org/", 1, LOWEST));
[email protected]8c843192012-04-05 07:15:008377
bncdf80d44fd2016-07-15 20:27:418378 SpdySerializedFrame push_rst(
diannahu9904e272017-02-03 14:40:088379 spdy_util_.ConstructSpdyRstStream(2, ERROR_CODE_REFUSED_STREAM));
[email protected]8c843192012-04-05 07:15:008380
8381 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:418382 CreateMockWrite(stream1_syn, 0, ASYNC), CreateMockWrite(push_rst, 3),
[email protected]8c843192012-04-05 07:15:008383 };
8384
bncdf80d44fd2016-07-15 20:27:418385 SpdySerializedFrame stream1_reply(
bnc42331402016-07-25 13:36:158386 spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
[email protected]8c843192012-04-05 07:15:008387
bncdf80d44fd2016-07-15 20:27:418388 SpdySerializedFrame stream1_body(spdy_util_.ConstructSpdyDataFrame(1, true));
[email protected]8c843192012-04-05 07:15:008389
bncdf80d44fd2016-07-15 20:27:418390 SpdySerializedFrame stream2_syn(spdy_util_.ConstructSpdyPush(
bncb03b1092016-04-06 11:19:558391 NULL, 0, 2, 1, "https://www.another-origin.com/foo.dat"));
[email protected]8c843192012-04-05 07:15:008392
8393 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:418394 CreateMockRead(stream1_reply, 1, ASYNC),
8395 CreateMockRead(stream2_syn, 2, ASYNC),
8396 CreateMockRead(stream1_body, 4, ASYNC),
mmenkee24011922015-12-17 22:12:598397 MockRead(SYNCHRONOUS, ERR_IO_PENDING, 5), // Force a hang
[email protected]8c843192012-04-05 07:15:008398 };
8399
rch8e6c6c42015-05-01 14:05:138400 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
8401 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:078402 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]8c843192012-04-05 07:15:008403 // Negotiate SPDY to the proxy
8404 SSLSocketDataProvider proxy(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:368405 proxy.next_proto = kProtoHTTP2;
[email protected]bb88e1d32013-05-03 23:11:078406 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy);
[email protected]8c843192012-04-05 07:15:008407
bnc87dcefc2017-05-25 12:47:588408 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:198409 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]8c843192012-04-05 07:15:008410 TestCompletionCallback callback;
8411 int rv = trans->Start(&request, callback.callback(), log.bound());
robpercival214763f2016-07-01 23:27:018412 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]8c843192012-04-05 07:15:008413
8414 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:018415 EXPECT_THAT(rv, IsOk());
[email protected]8c843192012-04-05 07:15:008416 const HttpResponseInfo* response = trans->GetResponseInfo();
8417
wezca1070932016-05-26 20:30:528418 ASSERT_TRUE(response);
[email protected]8c843192012-04-05 07:15:008419 EXPECT_TRUE(response->headers->IsKeepAlive());
8420
8421 EXPECT_EQ(200, response->headers->response_code());
8422 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
8423
8424 std::string response_data;
8425 rv = ReadTransaction(trans.get(), &response_data);
robpercival214763f2016-07-01 23:27:018426 EXPECT_THAT(rv, IsOk());
[email protected]8c843192012-04-05 07:15:008427 EXPECT_EQ("hello!", response_data);
8428
8429 trans.reset();
8430 session->CloseAllConnections();
8431}
8432
tbansal8ef1d3e2016-02-03 04:05:428433// Test that an explicitly trusted SPDY proxy can push same-origin HTTPS
8434// resources.
bncd16676a2016-07-20 16:23:018435TEST_F(HttpNetworkTransactionTest, SameOriginProxyPushCorrectness) {
tbansal28e68f82016-02-04 02:56:158436 // Configure the proxy delegate to allow cross-origin SPDY pushes.
Jeremy Roman0579ed62017-08-29 15:56:198437 auto proxy_delegate = std::make_unique<TestProxyDelegate>();
tbansal28e68f82016-02-04 02:56:158438 proxy_delegate->set_trusted_spdy_proxy(
8439 net::ProxyServer::FromURI("myproxy:70", net::ProxyServer::SCHEME_HTTP));
8440
tbansal8ef1d3e2016-02-03 04:05:428441 HttpRequestInfo request;
8442
8443 request.method = "GET";
8444 request.url = GURL("http://www.example.org/");
8445
8446 // Configure against https proxy server "myproxy:70".
8447 session_deps_.proxy_service = ProxyService::CreateFixed("https://myproxy:70");
8448 BoundTestNetLog log;
8449 session_deps_.net_log = log.bound().net_log();
8450
8451 // Enable cross-origin push.
inlinechan894515af2016-12-09 02:40:108452 session_deps_.proxy_delegate = std::move(proxy_delegate);
tbansal8ef1d3e2016-02-03 04:05:428453
danakj1fd259a02016-04-16 03:17:098454 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
tbansal8ef1d3e2016-02-03 04:05:428455
bncdf80d44fd2016-07-15 20:27:418456 SpdySerializedFrame stream1_syn(
bncb26024382016-06-29 02:39:458457 spdy_util_.ConstructSpdyGet("http://www.example.org/", 1, LOWEST));
tombergan5d22c182017-01-11 02:05:358458 SpdySerializedFrame stream2_priority(
8459 spdy_util_.ConstructSpdyPriority(2, 1, IDLE, true));
tbansal8ef1d3e2016-02-03 04:05:428460
8461 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:418462 CreateMockWrite(stream1_syn, 0, ASYNC),
tombergan5d22c182017-01-11 02:05:358463 CreateMockWrite(stream2_priority, 3, ASYNC),
tbansal8ef1d3e2016-02-03 04:05:428464 };
8465
bncdf80d44fd2016-07-15 20:27:418466 SpdySerializedFrame stream1_reply(
bnc42331402016-07-25 13:36:158467 spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
tbansal8ef1d3e2016-02-03 04:05:428468
bncdf80d44fd2016-07-15 20:27:418469 SpdySerializedFrame stream2_syn(spdy_util_.ConstructSpdyPush(
Bence Béky096cf052017-08-08 23:55:338470 nullptr, 0, 2, 1, "http://www.example.org/foo.dat"));
bnc38dcd392016-02-09 23:19:498471
bncdf80d44fd2016-07-15 20:27:418472 SpdySerializedFrame stream1_body(spdy_util_.ConstructSpdyDataFrame(1, true));
tbansal8ef1d3e2016-02-03 04:05:428473
bncdf80d44fd2016-07-15 20:27:418474 SpdySerializedFrame stream2_reply(
bnc42331402016-07-25 13:36:158475 spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
tbansal8ef1d3e2016-02-03 04:05:428476
bncdf80d44fd2016-07-15 20:27:418477 SpdySerializedFrame stream2_body(spdy_util_.ConstructSpdyDataFrame(1, true));
tbansal8ef1d3e2016-02-03 04:05:428478
8479 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:418480 CreateMockRead(stream1_reply, 1, ASYNC),
8481 CreateMockRead(stream2_syn, 2, ASYNC),
tombergan5d22c182017-01-11 02:05:358482 CreateMockRead(stream1_body, 4, ASYNC),
8483 CreateMockRead(stream2_body, 5, ASYNC),
8484 MockRead(SYNCHRONOUS, ERR_IO_PENDING, 6), // Force a hang
tbansal8ef1d3e2016-02-03 04:05:428485 };
8486
8487 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
8488 arraysize(spdy_writes));
8489 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
8490 // Negotiate SPDY to the proxy
8491 SSLSocketDataProvider proxy(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:368492 proxy.next_proto = kProtoHTTP2;
tbansal8ef1d3e2016-02-03 04:05:428493 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy);
8494
bnc87dcefc2017-05-25 12:47:588495 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:198496 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
tbansal8ef1d3e2016-02-03 04:05:428497 TestCompletionCallback callback;
8498 int rv = trans->Start(&request, callback.callback(), log.bound());
robpercival214763f2016-07-01 23:27:018499 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
tbansal8ef1d3e2016-02-03 04:05:428500
8501 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:018502 EXPECT_THAT(rv, IsOk());
tbansal8ef1d3e2016-02-03 04:05:428503 const HttpResponseInfo* response = trans->GetResponseInfo();
8504
wezca1070932016-05-26 20:30:528505 ASSERT_TRUE(response);
tbansal8ef1d3e2016-02-03 04:05:428506 EXPECT_TRUE(response->headers->IsKeepAlive());
8507
8508 EXPECT_EQ(200, response->headers->response_code());
8509 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
8510
8511 std::string response_data;
8512 rv = ReadTransaction(trans.get(), &response_data);
robpercival214763f2016-07-01 23:27:018513 EXPECT_THAT(rv, IsOk());
tbansal8ef1d3e2016-02-03 04:05:428514 EXPECT_EQ("hello!", response_data);
8515
8516 trans.reset();
8517 session->CloseAllConnections();
8518}
8519
[email protected]2df19bb2010-08-25 20:13:468520// Test HTTPS connections to a site with a bad certificate, going through an
8521// HTTPS proxy
bncd16676a2016-07-20 16:23:018522TEST_F(HttpNetworkTransactionTest, HTTPSBadCertificateViaHttpsProxy) {
rdsmith82957ad2015-09-16 19:42:038523 session_deps_.proxy_service = ProxyService::CreateFixed("https://proxy:70");
[email protected]2df19bb2010-08-25 20:13:468524
8525 HttpRequestInfo request;
8526 request.method = "GET";
bncce36dca22015-04-21 22:11:238527 request.url = GURL("https://www.example.org/");
[email protected]2df19bb2010-08-25 20:13:468528
8529 // Attempt to fetch the URL from a server with a bad cert
8530 MockWrite bad_cert_writes[] = {
rsleevidb16bb02015-11-12 23:47:178531 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
8532 "Host: www.example.org:443\r\n"
8533 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]2df19bb2010-08-25 20:13:468534 };
8535
8536 MockRead bad_cert_reads[] = {
8537 MockRead("HTTP/1.0 200 Connected\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:068538 MockRead(SYNCHRONOUS, OK)
[email protected]2df19bb2010-08-25 20:13:468539 };
8540
8541 // Attempt to fetch the URL with a good cert
8542 MockWrite good_data_writes[] = {
rsleevidb16bb02015-11-12 23:47:178543 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
8544 "Host: www.example.org:443\r\n"
8545 "Proxy-Connection: keep-alive\r\n\r\n"),
8546 MockWrite("GET / HTTP/1.1\r\n"
8547 "Host: www.example.org\r\n"
8548 "Connection: keep-alive\r\n\r\n"),
[email protected]2df19bb2010-08-25 20:13:468549 };
8550
8551 MockRead good_cert_reads[] = {
8552 MockRead("HTTP/1.0 200 Connected\r\n\r\n"),
8553 MockRead("HTTP/1.0 200 OK\r\n"),
8554 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
8555 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:068556 MockRead(SYNCHRONOUS, OK),
[email protected]2df19bb2010-08-25 20:13:468557 };
8558
8559 StaticSocketDataProvider ssl_bad_certificate(
8560 bad_cert_reads, arraysize(bad_cert_reads),
8561 bad_cert_writes, arraysize(bad_cert_writes));
8562 StaticSocketDataProvider data(good_cert_reads, arraysize(good_cert_reads),
8563 good_data_writes, arraysize(good_data_writes));
[email protected]8ddf8322012-02-23 18:08:068564 SSLSocketDataProvider ssl_bad(ASYNC, ERR_CERT_AUTHORITY_INVALID);
8565 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]2df19bb2010-08-25 20:13:468566
8567 // SSL to the proxy, then CONNECT request, then SSL with bad certificate
[email protected]bb88e1d32013-05-03 23:11:078568 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
8569 session_deps_.socket_factory->AddSocketDataProvider(&ssl_bad_certificate);
8570 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_bad);
[email protected]2df19bb2010-08-25 20:13:468571
8572 // SSL to the proxy, then CONNECT request, then valid SSL certificate
[email protected]bb88e1d32013-05-03 23:11:078573 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
8574 session_deps_.socket_factory->AddSocketDataProvider(&data);
8575 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]2df19bb2010-08-25 20:13:468576
[email protected]49639fa2011-12-20 23:22:418577 TestCompletionCallback callback;
[email protected]2df19bb2010-08-25 20:13:468578
danakj1fd259a02016-04-16 03:17:098579 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:168580 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]2df19bb2010-08-25 20:13:468581
tfarina42834112016-09-22 13:38:208582 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:018583 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2df19bb2010-08-25 20:13:468584
8585 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:018586 EXPECT_THAT(rv, IsError(ERR_CERT_AUTHORITY_INVALID));
[email protected]2df19bb2010-08-25 20:13:468587
bnc691fda62016-08-12 00:43:168588 rv = trans.RestartIgnoringLastError(callback.callback());
robpercival214763f2016-07-01 23:27:018589 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2df19bb2010-08-25 20:13:468590
8591 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:018592 EXPECT_THAT(rv, IsOk());
[email protected]2df19bb2010-08-25 20:13:468593
bnc691fda62016-08-12 00:43:168594 const HttpResponseInfo* response = trans.GetResponseInfo();
[email protected]2df19bb2010-08-25 20:13:468595
wezca1070932016-05-26 20:30:528596 ASSERT_TRUE(response);
[email protected]2df19bb2010-08-25 20:13:468597 EXPECT_EQ(100, response->headers->GetContentLength());
8598}
8599
bncd16676a2016-07-20 16:23:018600TEST_F(HttpNetworkTransactionTest, BuildRequest_UserAgent) {
[email protected]1c773ea12009-04-28 19:58:428601 HttpRequestInfo request;
8602 request.method = "GET";
bncce36dca22015-04-21 22:11:238603 request.url = GURL("http://www.example.org/");
[email protected]8c76ae22010-04-20 22:15:438604 request.extra_headers.SetHeader(HttpRequestHeaders::kUserAgent,
8605 "Chromium Ultra Awesome X Edition");
[email protected]1c773ea12009-04-28 19:58:428606
danakj1fd259a02016-04-16 03:17:098607 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:168608 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:278609
[email protected]1c773ea12009-04-28 19:58:428610 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:238611 MockWrite(
8612 "GET / HTTP/1.1\r\n"
8613 "Host: www.example.org\r\n"
8614 "Connection: keep-alive\r\n"
8615 "User-Agent: Chromium Ultra Awesome X Edition\r\n\r\n"),
[email protected]1c773ea12009-04-28 19:58:428616 };
8617
8618 // Lastly, the server responds with the actual content.
8619 MockRead data_reads[] = {
8620 MockRead("HTTP/1.0 200 OK\r\n"),
8621 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
8622 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:068623 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:428624 };
8625
[email protected]31a2bfe2010-02-09 08:03:398626 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
8627 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:078628 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:428629
[email protected]49639fa2011-12-20 23:22:418630 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:428631
tfarina42834112016-09-22 13:38:208632 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:018633 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]1c773ea12009-04-28 19:58:428634
8635 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:018636 EXPECT_THAT(rv, IsOk());
[email protected]1c773ea12009-04-28 19:58:428637}
8638
bncd16676a2016-07-20 16:23:018639TEST_F(HttpNetworkTransactionTest, BuildRequest_UserAgentOverTunnel) {
[email protected]da81f132010-08-18 23:39:298640 HttpRequestInfo request;
8641 request.method = "GET";
bncce36dca22015-04-21 22:11:238642 request.url = GURL("https://www.example.org/");
[email protected]da81f132010-08-18 23:39:298643 request.extra_headers.SetHeader(HttpRequestHeaders::kUserAgent,
8644 "Chromium Ultra Awesome X Edition");
8645
rdsmith82957ad2015-09-16 19:42:038646 session_deps_.proxy_service = ProxyService::CreateFixed("myproxy:70");
danakj1fd259a02016-04-16 03:17:098647 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:168648 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:278649
[email protected]da81f132010-08-18 23:39:298650 MockWrite data_writes[] = {
rsleevidb16bb02015-11-12 23:47:178651 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
8652 "Host: www.example.org:443\r\n"
8653 "Proxy-Connection: keep-alive\r\n"
8654 "User-Agent: Chromium Ultra Awesome X Edition\r\n\r\n"),
[email protected]da81f132010-08-18 23:39:298655 };
8656 MockRead data_reads[] = {
8657 // Return an error, so the transaction stops here (this test isn't
8658 // interested in the rest).
8659 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
8660 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
8661 MockRead("Proxy-Connection: close\r\n\r\n"),
8662 };
8663
8664 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
8665 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:078666 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]da81f132010-08-18 23:39:298667
[email protected]49639fa2011-12-20 23:22:418668 TestCompletionCallback callback;
[email protected]da81f132010-08-18 23:39:298669
tfarina42834112016-09-22 13:38:208670 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:018671 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]da81f132010-08-18 23:39:298672
8673 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:018674 EXPECT_THAT(rv, IsOk());
[email protected]da81f132010-08-18 23:39:298675}
8676
bncd16676a2016-07-20 16:23:018677TEST_F(HttpNetworkTransactionTest, BuildRequest_Referer) {
[email protected]1c773ea12009-04-28 19:58:428678 HttpRequestInfo request;
8679 request.method = "GET";
bncce36dca22015-04-21 22:11:238680 request.url = GURL("http://www.example.org/");
[email protected]c10450102011-06-27 09:06:168681 request.extra_headers.SetHeader(HttpRequestHeaders::kReferer,
8682 "http://the.previous.site.com/");
[email protected]1c773ea12009-04-28 19:58:428683
danakj1fd259a02016-04-16 03:17:098684 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:168685 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:278686
[email protected]1c773ea12009-04-28 19:58:428687 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:238688 MockWrite(
8689 "GET / HTTP/1.1\r\n"
8690 "Host: www.example.org\r\n"
8691 "Connection: keep-alive\r\n"
8692 "Referer: http://the.previous.site.com/\r\n\r\n"),
[email protected]1c773ea12009-04-28 19:58:428693 };
8694
8695 // Lastly, the server responds with the actual content.
8696 MockRead data_reads[] = {
8697 MockRead("HTTP/1.0 200 OK\r\n"),
8698 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
8699 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:068700 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:428701 };
8702
[email protected]31a2bfe2010-02-09 08:03:398703 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
8704 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:078705 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:428706
[email protected]49639fa2011-12-20 23:22:418707 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:428708
tfarina42834112016-09-22 13:38:208709 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:018710 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]1c773ea12009-04-28 19:58:428711
8712 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:018713 EXPECT_THAT(rv, IsOk());
[email protected]1c773ea12009-04-28 19:58:428714}
8715
bncd16676a2016-07-20 16:23:018716TEST_F(HttpNetworkTransactionTest, BuildRequest_PostContentLengthZero) {
[email protected]1c773ea12009-04-28 19:58:428717 HttpRequestInfo request;
8718 request.method = "POST";
bncce36dca22015-04-21 22:11:238719 request.url = GURL("http://www.example.org/");
[email protected]1c773ea12009-04-28 19:58:428720
danakj1fd259a02016-04-16 03:17:098721 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:168722 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:278723
[email protected]1c773ea12009-04-28 19:58:428724 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:238725 MockWrite(
8726 "POST / HTTP/1.1\r\n"
8727 "Host: www.example.org\r\n"
8728 "Connection: keep-alive\r\n"
8729 "Content-Length: 0\r\n\r\n"),
[email protected]1c773ea12009-04-28 19:58:428730 };
8731
8732 // Lastly, the server responds with the actual content.
8733 MockRead data_reads[] = {
8734 MockRead("HTTP/1.0 200 OK\r\n"),
8735 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
8736 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:068737 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:428738 };
8739
[email protected]31a2bfe2010-02-09 08:03:398740 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
8741 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:078742 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:428743
[email protected]49639fa2011-12-20 23:22:418744 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:428745
tfarina42834112016-09-22 13:38:208746 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:018747 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]1c773ea12009-04-28 19:58:428748
8749 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:018750 EXPECT_THAT(rv, IsOk());
[email protected]1c773ea12009-04-28 19:58:428751}
8752
bncd16676a2016-07-20 16:23:018753TEST_F(HttpNetworkTransactionTest, BuildRequest_PutContentLengthZero) {
[email protected]1c773ea12009-04-28 19:58:428754 HttpRequestInfo request;
8755 request.method = "PUT";
bncce36dca22015-04-21 22:11:238756 request.url = GURL("http://www.example.org/");
[email protected]1c773ea12009-04-28 19:58:428757
danakj1fd259a02016-04-16 03:17:098758 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:168759 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:278760
[email protected]1c773ea12009-04-28 19:58:428761 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:238762 MockWrite(
8763 "PUT / HTTP/1.1\r\n"
8764 "Host: www.example.org\r\n"
8765 "Connection: keep-alive\r\n"
8766 "Content-Length: 0\r\n\r\n"),
[email protected]1c773ea12009-04-28 19:58:428767 };
8768
8769 // Lastly, the server responds with the actual content.
8770 MockRead data_reads[] = {
8771 MockRead("HTTP/1.0 200 OK\r\n"),
8772 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
8773 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:068774 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:428775 };
8776
[email protected]31a2bfe2010-02-09 08:03:398777 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
8778 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:078779 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:428780
[email protected]49639fa2011-12-20 23:22:418781 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:428782
tfarina42834112016-09-22 13:38:208783 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:018784 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]1c773ea12009-04-28 19:58:428785
8786 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:018787 EXPECT_THAT(rv, IsOk());
[email protected]1c773ea12009-04-28 19:58:428788}
8789
bncd16676a2016-07-20 16:23:018790TEST_F(HttpNetworkTransactionTest, BuildRequest_HeadContentLengthZero) {
[email protected]1c773ea12009-04-28 19:58:428791 HttpRequestInfo request;
8792 request.method = "HEAD";
bncce36dca22015-04-21 22:11:238793 request.url = GURL("http://www.example.org/");
[email protected]1c773ea12009-04-28 19:58:428794
danakj1fd259a02016-04-16 03:17:098795 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:168796 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:278797
[email protected]1c773ea12009-04-28 19:58:428798 MockWrite data_writes[] = {
csharrisonf473dd192015-08-18 13:54:138799 MockWrite("HEAD / HTTP/1.1\r\n"
8800 "Host: www.example.org\r\n"
8801 "Connection: keep-alive\r\n\r\n"),
[email protected]1c773ea12009-04-28 19:58:428802 };
8803
8804 // Lastly, the server responds with the actual content.
8805 MockRead data_reads[] = {
8806 MockRead("HTTP/1.0 200 OK\r\n"),
8807 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
8808 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:068809 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:428810 };
8811
[email protected]31a2bfe2010-02-09 08:03:398812 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
8813 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:078814 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:428815
[email protected]49639fa2011-12-20 23:22:418816 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:428817
tfarina42834112016-09-22 13:38:208818 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:018819 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]1c773ea12009-04-28 19:58:428820
8821 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:018822 EXPECT_THAT(rv, IsOk());
[email protected]1c773ea12009-04-28 19:58:428823}
8824
bncd16676a2016-07-20 16:23:018825TEST_F(HttpNetworkTransactionTest, BuildRequest_CacheControlNoCache) {
[email protected]1c773ea12009-04-28 19:58:428826 HttpRequestInfo request;
8827 request.method = "GET";
bncce36dca22015-04-21 22:11:238828 request.url = GURL("http://www.example.org/");
[email protected]1c773ea12009-04-28 19:58:428829 request.load_flags = LOAD_BYPASS_CACHE;
8830
danakj1fd259a02016-04-16 03:17:098831 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:168832 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:278833
[email protected]1c773ea12009-04-28 19:58:428834 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:238835 MockWrite(
8836 "GET / HTTP/1.1\r\n"
8837 "Host: www.example.org\r\n"
8838 "Connection: keep-alive\r\n"
8839 "Pragma: no-cache\r\n"
8840 "Cache-Control: no-cache\r\n\r\n"),
[email protected]1c773ea12009-04-28 19:58:428841 };
8842
8843 // Lastly, the server responds with the actual content.
8844 MockRead data_reads[] = {
8845 MockRead("HTTP/1.0 200 OK\r\n"),
8846 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
8847 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:068848 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:428849 };
8850
[email protected]31a2bfe2010-02-09 08:03:398851 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
8852 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:078853 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:428854
[email protected]49639fa2011-12-20 23:22:418855 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:428856
tfarina42834112016-09-22 13:38:208857 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:018858 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]1c773ea12009-04-28 19:58:428859
8860 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:018861 EXPECT_THAT(rv, IsOk());
[email protected]1c773ea12009-04-28 19:58:428862}
8863
bncd16676a2016-07-20 16:23:018864TEST_F(HttpNetworkTransactionTest, BuildRequest_CacheControlValidateCache) {
[email protected]1c773ea12009-04-28 19:58:428865 HttpRequestInfo request;
8866 request.method = "GET";
bncce36dca22015-04-21 22:11:238867 request.url = GURL("http://www.example.org/");
[email protected]1c773ea12009-04-28 19:58:428868 request.load_flags = LOAD_VALIDATE_CACHE;
8869
danakj1fd259a02016-04-16 03:17:098870 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:168871 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:278872
[email protected]1c773ea12009-04-28 19:58:428873 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:238874 MockWrite(
8875 "GET / HTTP/1.1\r\n"
8876 "Host: www.example.org\r\n"
8877 "Connection: keep-alive\r\n"
8878 "Cache-Control: max-age=0\r\n\r\n"),
[email protected]1c773ea12009-04-28 19:58:428879 };
8880
8881 // Lastly, the server responds with the actual content.
8882 MockRead data_reads[] = {
8883 MockRead("HTTP/1.0 200 OK\r\n"),
8884 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
8885 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:068886 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:428887 };
8888
[email protected]31a2bfe2010-02-09 08:03:398889 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
8890 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:078891 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:428892
[email protected]49639fa2011-12-20 23:22:418893 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:428894
tfarina42834112016-09-22 13:38:208895 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:018896 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]1c773ea12009-04-28 19:58:428897
8898 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:018899 EXPECT_THAT(rv, IsOk());
[email protected]1c773ea12009-04-28 19:58:428900}
8901
bncd16676a2016-07-20 16:23:018902TEST_F(HttpNetworkTransactionTest, BuildRequest_ExtraHeaders) {
[email protected]1c773ea12009-04-28 19:58:428903 HttpRequestInfo request;
8904 request.method = "GET";
bncce36dca22015-04-21 22:11:238905 request.url = GURL("http://www.example.org/");
[email protected]8c76ae22010-04-20 22:15:438906 request.extra_headers.SetHeader("FooHeader", "Bar");
[email protected]1c773ea12009-04-28 19:58:428907
danakj1fd259a02016-04-16 03:17:098908 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:168909 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:278910
[email protected]1c773ea12009-04-28 19:58:428911 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:238912 MockWrite(
8913 "GET / HTTP/1.1\r\n"
8914 "Host: www.example.org\r\n"
8915 "Connection: keep-alive\r\n"
8916 "FooHeader: Bar\r\n\r\n"),
[email protected]1c773ea12009-04-28 19:58:428917 };
8918
8919 // Lastly, the server responds with the actual content.
8920 MockRead data_reads[] = {
8921 MockRead("HTTP/1.0 200 OK\r\n"),
8922 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
8923 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:068924 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:428925 };
8926
[email protected]31a2bfe2010-02-09 08:03:398927 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
8928 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:078929 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:428930
[email protected]49639fa2011-12-20 23:22:418931 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:428932
tfarina42834112016-09-22 13:38:208933 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:018934 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]1c773ea12009-04-28 19:58:428935
8936 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:018937 EXPECT_THAT(rv, IsOk());
[email protected]1c773ea12009-04-28 19:58:428938}
8939
bncd16676a2016-07-20 16:23:018940TEST_F(HttpNetworkTransactionTest, BuildRequest_ExtraHeadersStripped) {
[email protected]270c6412010-03-29 22:02:478941 HttpRequestInfo request;
8942 request.method = "GET";
bncce36dca22015-04-21 22:11:238943 request.url = GURL("http://www.example.org/");
[email protected]8c76ae22010-04-20 22:15:438944 request.extra_headers.SetHeader("referer", "www.foo.com");
8945 request.extra_headers.SetHeader("hEllo", "Kitty");
8946 request.extra_headers.SetHeader("FoO", "bar");
[email protected]270c6412010-03-29 22:02:478947
danakj1fd259a02016-04-16 03:17:098948 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:168949 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:278950
[email protected]270c6412010-03-29 22:02:478951 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:238952 MockWrite(
8953 "GET / HTTP/1.1\r\n"
8954 "Host: www.example.org\r\n"
8955 "Connection: keep-alive\r\n"
8956 "referer: www.foo.com\r\n"
8957 "hEllo: Kitty\r\n"
8958 "FoO: bar\r\n\r\n"),
[email protected]270c6412010-03-29 22:02:478959 };
8960
8961 // Lastly, the server responds with the actual content.
8962 MockRead data_reads[] = {
8963 MockRead("HTTP/1.0 200 OK\r\n"),
8964 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
8965 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:068966 MockRead(SYNCHRONOUS, OK),
[email protected]270c6412010-03-29 22:02:478967 };
8968
8969 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
8970 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:078971 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]270c6412010-03-29 22:02:478972
[email protected]49639fa2011-12-20 23:22:418973 TestCompletionCallback callback;
[email protected]270c6412010-03-29 22:02:478974
tfarina42834112016-09-22 13:38:208975 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:018976 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]270c6412010-03-29 22:02:478977
8978 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:018979 EXPECT_THAT(rv, IsOk());
[email protected]270c6412010-03-29 22:02:478980}
8981
bncd16676a2016-07-20 16:23:018982TEST_F(HttpNetworkTransactionTest, SOCKS4_HTTP_GET) {
[email protected]cb9bf6ca2011-01-28 13:15:278983 HttpRequestInfo request;
8984 request.method = "GET";
bncce36dca22015-04-21 22:11:238985 request.url = GURL("http://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:278986
rdsmith82957ad2015-09-16 19:42:038987 session_deps_.proxy_service =
8988 ProxyService::CreateFixedFromPacResult("SOCKS myproxy:1080");
vishal.b62985ca92015-04-17 08:45:518989 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:078990 session_deps_.net_log = &net_log;
[email protected]3cd17242009-06-23 02:59:028991
danakj1fd259a02016-04-16 03:17:098992 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:168993 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]3cd17242009-06-23 02:59:028994
[email protected]3cd17242009-06-23 02:59:028995 char write_buffer[] = { 0x04, 0x01, 0x00, 0x50, 127, 0, 0, 1, 0 };
8996 char read_buffer[] = { 0x00, 0x5A, 0x00, 0x00, 0, 0, 0, 0 };
8997
8998 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:238999 MockWrite(ASYNC, write_buffer, arraysize(write_buffer)),
9000 MockWrite(
9001 "GET / HTTP/1.1\r\n"
9002 "Host: www.example.org\r\n"
9003 "Connection: keep-alive\r\n\r\n")};
[email protected]3cd17242009-06-23 02:59:029004
9005 MockRead data_reads[] = {
[email protected]8ddf8322012-02-23 18:08:069006 MockRead(ASYNC, read_buffer, arraysize(read_buffer)),
[email protected]3cd17242009-06-23 02:59:029007 MockRead("HTTP/1.0 200 OK\r\n"),
9008 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n\r\n"),
9009 MockRead("Payload"),
[email protected]8ddf8322012-02-23 18:08:069010 MockRead(SYNCHRONOUS, OK)
[email protected]3cd17242009-06-23 02:59:029011 };
9012
[email protected]31a2bfe2010-02-09 08:03:399013 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
9014 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:079015 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]3cd17242009-06-23 02:59:029016
[email protected]49639fa2011-12-20 23:22:419017 TestCompletionCallback callback;
[email protected]3cd17242009-06-23 02:59:029018
tfarina42834112016-09-22 13:38:209019 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:019020 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]3cd17242009-06-23 02:59:029021
9022 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:019023 EXPECT_THAT(rv, IsOk());
[email protected]3cd17242009-06-23 02:59:029024
bnc691fda62016-08-12 00:43:169025 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:529026 ASSERT_TRUE(response);
[email protected]3cd17242009-06-23 02:59:029027
tbansal2ecbbc72016-10-06 17:15:479028 EXPECT_EQ(ProxyServer::SCHEME_SOCKS4, response->proxy_server.scheme());
[email protected]029c83b62013-01-24 05:28:209029 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:169030 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]029c83b62013-01-24 05:28:209031 TestLoadTimingNotReusedWithPac(load_timing_info,
9032 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
9033
[email protected]3cd17242009-06-23 02:59:029034 std::string response_text;
bnc691fda62016-08-12 00:43:169035 rv = ReadTransaction(&trans, &response_text);
robpercival214763f2016-07-01 23:27:019036 EXPECT_THAT(rv, IsOk());
[email protected]3cd17242009-06-23 02:59:029037 EXPECT_EQ("Payload", response_text);
9038}
9039
bncd16676a2016-07-20 16:23:019040TEST_F(HttpNetworkTransactionTest, SOCKS4_SSL_GET) {
[email protected]cb9bf6ca2011-01-28 13:15:279041 HttpRequestInfo request;
9042 request.method = "GET";
bncce36dca22015-04-21 22:11:239043 request.url = GURL("https://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:279044
rdsmith82957ad2015-09-16 19:42:039045 session_deps_.proxy_service =
9046 ProxyService::CreateFixedFromPacResult("SOCKS myproxy:1080");
vishal.b62985ca92015-04-17 08:45:519047 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:079048 session_deps_.net_log = &net_log;
[email protected]3cd17242009-06-23 02:59:029049
danakj1fd259a02016-04-16 03:17:099050 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:169051 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]3cd17242009-06-23 02:59:029052
[email protected]3cd17242009-06-23 02:59:029053 unsigned char write_buffer[] = { 0x04, 0x01, 0x01, 0xBB, 127, 0, 0, 1, 0 };
9054 unsigned char read_buffer[] = { 0x00, 0x5A, 0x00, 0x00, 0, 0, 0, 0 };
9055
9056 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:239057 MockWrite(ASYNC, reinterpret_cast<char*>(write_buffer),
9058 arraysize(write_buffer)),
9059 MockWrite(
9060 "GET / HTTP/1.1\r\n"
9061 "Host: www.example.org\r\n"
9062 "Connection: keep-alive\r\n\r\n")};
[email protected]3cd17242009-06-23 02:59:029063
9064 MockRead data_reads[] = {
[email protected]f871ee152012-07-27 19:02:019065 MockRead(ASYNC, reinterpret_cast<char*>(read_buffer),
9066 arraysize(read_buffer)),
[email protected]e0c27be2009-07-15 13:09:359067 MockRead("HTTP/1.0 200 OK\r\n"),
9068 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n\r\n"),
9069 MockRead("Payload"),
[email protected]8ddf8322012-02-23 18:08:069070 MockRead(SYNCHRONOUS, OK)
[email protected]e0c27be2009-07-15 13:09:359071 };
9072
[email protected]31a2bfe2010-02-09 08:03:399073 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
9074 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:079075 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]e0c27be2009-07-15 13:09:359076
[email protected]8ddf8322012-02-23 18:08:069077 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:079078 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]e0c27be2009-07-15 13:09:359079
[email protected]49639fa2011-12-20 23:22:419080 TestCompletionCallback callback;
[email protected]e0c27be2009-07-15 13:09:359081
tfarina42834112016-09-22 13:38:209082 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:019083 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]e0c27be2009-07-15 13:09:359084
9085 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:019086 EXPECT_THAT(rv, IsOk());
[email protected]e0c27be2009-07-15 13:09:359087
[email protected]029c83b62013-01-24 05:28:209088 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:169089 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]029c83b62013-01-24 05:28:209090 TestLoadTimingNotReusedWithPac(load_timing_info,
9091 CONNECT_TIMING_HAS_SSL_TIMES);
9092
bnc691fda62016-08-12 00:43:169093 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:529094 ASSERT_TRUE(response);
tbansal2ecbbc72016-10-06 17:15:479095 EXPECT_EQ(ProxyServer::SCHEME_SOCKS4, response->proxy_server.scheme());
[email protected]e0c27be2009-07-15 13:09:359096
9097 std::string response_text;
bnc691fda62016-08-12 00:43:169098 rv = ReadTransaction(&trans, &response_text);
robpercival214763f2016-07-01 23:27:019099 EXPECT_THAT(rv, IsOk());
[email protected]e0c27be2009-07-15 13:09:359100 EXPECT_EQ("Payload", response_text);
9101}
9102
bncd16676a2016-07-20 16:23:019103TEST_F(HttpNetworkTransactionTest, SOCKS4_HTTP_GET_no_PAC) {
[email protected]029c83b62013-01-24 05:28:209104 HttpRequestInfo request;
9105 request.method = "GET";
bncce36dca22015-04-21 22:11:239106 request.url = GURL("http://www.example.org/");
[email protected]029c83b62013-01-24 05:28:209107
rdsmith82957ad2015-09-16 19:42:039108 session_deps_.proxy_service =
9109 ProxyService::CreateFixed("socks4://myproxy:1080");
vishal.b62985ca92015-04-17 08:45:519110 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:079111 session_deps_.net_log = &net_log;
[email protected]029c83b62013-01-24 05:28:209112
danakj1fd259a02016-04-16 03:17:099113 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:169114 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]029c83b62013-01-24 05:28:209115
9116 char write_buffer[] = { 0x04, 0x01, 0x00, 0x50, 127, 0, 0, 1, 0 };
9117 char read_buffer[] = { 0x00, 0x5A, 0x00, 0x00, 0, 0, 0, 0 };
9118
9119 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:239120 MockWrite(ASYNC, write_buffer, arraysize(write_buffer)),
9121 MockWrite(
9122 "GET / HTTP/1.1\r\n"
9123 "Host: www.example.org\r\n"
9124 "Connection: keep-alive\r\n\r\n")};
[email protected]029c83b62013-01-24 05:28:209125
9126 MockRead data_reads[] = {
9127 MockRead(ASYNC, read_buffer, arraysize(read_buffer)),
9128 MockRead("HTTP/1.0 200 OK\r\n"),
9129 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n\r\n"),
9130 MockRead("Payload"),
9131 MockRead(SYNCHRONOUS, OK)
9132 };
9133
9134 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
9135 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:079136 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]029c83b62013-01-24 05:28:209137
9138 TestCompletionCallback callback;
9139
tfarina42834112016-09-22 13:38:209140 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:019141 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]029c83b62013-01-24 05:28:209142
9143 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:019144 EXPECT_THAT(rv, IsOk());
[email protected]029c83b62013-01-24 05:28:209145
bnc691fda62016-08-12 00:43:169146 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:529147 ASSERT_TRUE(response);
[email protected]029c83b62013-01-24 05:28:209148
9149 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:169150 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]029c83b62013-01-24 05:28:209151 TestLoadTimingNotReused(load_timing_info,
9152 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
9153
9154 std::string response_text;
bnc691fda62016-08-12 00:43:169155 rv = ReadTransaction(&trans, &response_text);
robpercival214763f2016-07-01 23:27:019156 EXPECT_THAT(rv, IsOk());
[email protected]029c83b62013-01-24 05:28:209157 EXPECT_EQ("Payload", response_text);
9158}
9159
bncd16676a2016-07-20 16:23:019160TEST_F(HttpNetworkTransactionTest, SOCKS5_HTTP_GET) {
[email protected]cb9bf6ca2011-01-28 13:15:279161 HttpRequestInfo request;
9162 request.method = "GET";
bncce36dca22015-04-21 22:11:239163 request.url = GURL("http://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:279164
rdsmith82957ad2015-09-16 19:42:039165 session_deps_.proxy_service =
9166 ProxyService::CreateFixedFromPacResult("SOCKS5 myproxy:1080");
vishal.b62985ca92015-04-17 08:45:519167 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:079168 session_deps_.net_log = &net_log;
[email protected]e0c27be2009-07-15 13:09:359169
danakj1fd259a02016-04-16 03:17:099170 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:169171 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]e0c27be2009-07-15 13:09:359172
[email protected]e0c27be2009-07-15 13:09:359173 const char kSOCKS5GreetRequest[] = { 0x05, 0x01, 0x00 };
9174 const char kSOCKS5GreetResponse[] = { 0x05, 0x00 };
[email protected]f209dba2009-12-18 00:24:379175 const char kSOCKS5OkRequest[] = {
bncce36dca22015-04-21 22:11:239176 0x05, // Version
9177 0x01, // Command (CONNECT)
9178 0x00, // Reserved.
9179 0x03, // Address type (DOMAINNAME).
9180 0x0F, // Length of domain (15)
9181 'w', 'w', 'w', '.', 'e', 'x', 'a', 'm', 'p', 'l', 'e', // Domain string
9182 '.', 'o', 'r', 'g', 0x00, 0x50, // 16-bit port (80)
[email protected]f209dba2009-12-18 00:24:379183 };
[email protected]e0c27be2009-07-15 13:09:359184 const char kSOCKS5OkResponse[] =
9185 { 0x05, 0x00, 0x00, 0x01, 127, 0, 0, 1, 0x00, 0x50 };
9186
9187 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:239188 MockWrite(ASYNC, kSOCKS5GreetRequest, arraysize(kSOCKS5GreetRequest)),
9189 MockWrite(ASYNC, kSOCKS5OkRequest, arraysize(kSOCKS5OkRequest)),
9190 MockWrite(
9191 "GET / HTTP/1.1\r\n"
9192 "Host: www.example.org\r\n"
9193 "Connection: keep-alive\r\n\r\n")};
[email protected]e0c27be2009-07-15 13:09:359194
9195 MockRead data_reads[] = {
[email protected]f871ee152012-07-27 19:02:019196 MockRead(ASYNC, kSOCKS5GreetResponse, arraysize(kSOCKS5GreetResponse)),
9197 MockRead(ASYNC, kSOCKS5OkResponse, arraysize(kSOCKS5OkResponse)),
[email protected]e0c27be2009-07-15 13:09:359198 MockRead("HTTP/1.0 200 OK\r\n"),
9199 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n\r\n"),
9200 MockRead("Payload"),
[email protected]8ddf8322012-02-23 18:08:069201 MockRead(SYNCHRONOUS, OK)
[email protected]e0c27be2009-07-15 13:09:359202 };
9203
[email protected]31a2bfe2010-02-09 08:03:399204 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
9205 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:079206 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]e0c27be2009-07-15 13:09:359207
[email protected]49639fa2011-12-20 23:22:419208 TestCompletionCallback callback;
[email protected]e0c27be2009-07-15 13:09:359209
tfarina42834112016-09-22 13:38:209210 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:019211 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]e0c27be2009-07-15 13:09:359212
9213 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:019214 EXPECT_THAT(rv, IsOk());
[email protected]e0c27be2009-07-15 13:09:359215
bnc691fda62016-08-12 00:43:169216 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:529217 ASSERT_TRUE(response);
tbansal2ecbbc72016-10-06 17:15:479218 EXPECT_EQ(ProxyServer::SCHEME_SOCKS5, response->proxy_server.scheme());
[email protected]e0c27be2009-07-15 13:09:359219
[email protected]029c83b62013-01-24 05:28:209220 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:169221 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]029c83b62013-01-24 05:28:209222 TestLoadTimingNotReusedWithPac(load_timing_info,
9223 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
9224
[email protected]e0c27be2009-07-15 13:09:359225 std::string response_text;
bnc691fda62016-08-12 00:43:169226 rv = ReadTransaction(&trans, &response_text);
robpercival214763f2016-07-01 23:27:019227 EXPECT_THAT(rv, IsOk());
[email protected]e0c27be2009-07-15 13:09:359228 EXPECT_EQ("Payload", response_text);
9229}
9230
bncd16676a2016-07-20 16:23:019231TEST_F(HttpNetworkTransactionTest, SOCKS5_SSL_GET) {
[email protected]cb9bf6ca2011-01-28 13:15:279232 HttpRequestInfo request;
9233 request.method = "GET";
bncce36dca22015-04-21 22:11:239234 request.url = GURL("https://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:279235
rdsmith82957ad2015-09-16 19:42:039236 session_deps_.proxy_service =
9237 ProxyService::CreateFixedFromPacResult("SOCKS5 myproxy:1080");
vishal.b62985ca92015-04-17 08:45:519238 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:079239 session_deps_.net_log = &net_log;
[email protected]e0c27be2009-07-15 13:09:359240
danakj1fd259a02016-04-16 03:17:099241 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:169242 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]e0c27be2009-07-15 13:09:359243
[email protected]e0c27be2009-07-15 13:09:359244 const char kSOCKS5GreetRequest[] = { 0x05, 0x01, 0x00 };
9245 const char kSOCKS5GreetResponse[] = { 0x05, 0x00 };
[email protected]f209dba2009-12-18 00:24:379246 const unsigned char kSOCKS5OkRequest[] = {
bncce36dca22015-04-21 22:11:239247 0x05, // Version
9248 0x01, // Command (CONNECT)
9249 0x00, // Reserved.
9250 0x03, // Address type (DOMAINNAME).
9251 0x0F, // Length of domain (15)
9252 'w', 'w', 'w', '.', 'e', 'x', 'a', 'm', 'p', 'l', 'e', // Domain string
9253 '.', 'o', 'r', 'g', 0x01, 0xBB, // 16-bit port (443)
[email protected]f209dba2009-12-18 00:24:379254 };
9255
[email protected]e0c27be2009-07-15 13:09:359256 const char kSOCKS5OkResponse[] =
9257 { 0x05, 0x00, 0x00, 0x01, 0, 0, 0, 0, 0x00, 0x00 };
9258
9259 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:239260 MockWrite(ASYNC, kSOCKS5GreetRequest, arraysize(kSOCKS5GreetRequest)),
9261 MockWrite(ASYNC, reinterpret_cast<const char*>(kSOCKS5OkRequest),
9262 arraysize(kSOCKS5OkRequest)),
9263 MockWrite(
9264 "GET / HTTP/1.1\r\n"
9265 "Host: www.example.org\r\n"
9266 "Connection: keep-alive\r\n\r\n")};
[email protected]e0c27be2009-07-15 13:09:359267
9268 MockRead data_reads[] = {
[email protected]f871ee152012-07-27 19:02:019269 MockRead(ASYNC, kSOCKS5GreetResponse, arraysize(kSOCKS5GreetResponse)),
9270 MockRead(ASYNC, kSOCKS5OkResponse, arraysize(kSOCKS5OkResponse)),
[email protected]3cd17242009-06-23 02:59:029271 MockRead("HTTP/1.0 200 OK\r\n"),
9272 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n\r\n"),
9273 MockRead("Payload"),
[email protected]8ddf8322012-02-23 18:08:069274 MockRead(SYNCHRONOUS, OK)
[email protected]3cd17242009-06-23 02:59:029275 };
9276
[email protected]31a2bfe2010-02-09 08:03:399277 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
9278 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:079279 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]3cd17242009-06-23 02:59:029280
[email protected]8ddf8322012-02-23 18:08:069281 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:079282 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]3cd17242009-06-23 02:59:029283
[email protected]49639fa2011-12-20 23:22:419284 TestCompletionCallback callback;
[email protected]3cd17242009-06-23 02:59:029285
tfarina42834112016-09-22 13:38:209286 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:019287 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]3cd17242009-06-23 02:59:029288
9289 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:019290 EXPECT_THAT(rv, IsOk());
[email protected]3cd17242009-06-23 02:59:029291
bnc691fda62016-08-12 00:43:169292 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:529293 ASSERT_TRUE(response);
tbansal2ecbbc72016-10-06 17:15:479294 EXPECT_EQ(ProxyServer::SCHEME_SOCKS5, response->proxy_server.scheme());
[email protected]3cd17242009-06-23 02:59:029295
[email protected]029c83b62013-01-24 05:28:209296 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:169297 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]029c83b62013-01-24 05:28:209298 TestLoadTimingNotReusedWithPac(load_timing_info,
9299 CONNECT_TIMING_HAS_SSL_TIMES);
9300
[email protected]3cd17242009-06-23 02:59:029301 std::string response_text;
bnc691fda62016-08-12 00:43:169302 rv = ReadTransaction(&trans, &response_text);
robpercival214763f2016-07-01 23:27:019303 EXPECT_THAT(rv, IsOk());
[email protected]3cd17242009-06-23 02:59:029304 EXPECT_EQ("Payload", response_text);
9305}
9306
[email protected]448d4ca52012-03-04 04:12:239307namespace {
9308
[email protected]04e5be32009-06-26 20:00:319309// Tests that for connection endpoints the group names are correctly set.
[email protected]2d731a32010-04-29 01:04:069310
9311struct GroupNameTest {
9312 std::string proxy_server;
9313 std::string url;
9314 std::string expected_group_name;
[email protected]e60e47a2010-07-14 03:37:189315 bool ssl;
[email protected]2d731a32010-04-29 01:04:069316};
9317
danakj1fd259a02016-04-16 03:17:099318std::unique_ptr<HttpNetworkSession> SetupSessionForGroupNameTests(
[email protected]bb88e1d32013-05-03 23:11:079319 SpdySessionDependencies* session_deps_) {
danakj1fd259a02016-04-16 03:17:099320 std::unique_ptr<HttpNetworkSession> session(CreateSession(session_deps_));
[email protected]2d731a32010-04-29 01:04:069321
bnc525e175a2016-06-20 12:36:409322 HttpServerProperties* http_server_properties =
[email protected]17291a022011-10-10 07:32:539323 session->http_server_properties();
bnc3472afd2016-11-17 15:27:219324 AlternativeService alternative_service(kProtoHTTP2, "", 444);
bnc7dc7e1b42015-07-28 14:43:129325 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:219326 http_server_properties->SetHttp2AlternativeService(
bncaa60ff402016-06-22 19:12:429327 url::SchemeHostPort("https", "host.with.alternate", 443),
zhongyi3d4a55e72016-04-22 20:36:469328 alternative_service, expiration);
[email protected]2d731a32010-04-29 01:04:069329
9330 return session;
9331}
9332
mmenkee65e7af2015-10-13 17:16:429333int GroupNameTransactionHelper(const std::string& url,
9334 HttpNetworkSession* session) {
[email protected]2d731a32010-04-29 01:04:069335 HttpRequestInfo request;
9336 request.method = "GET";
9337 request.url = GURL(url);
[email protected]2d731a32010-04-29 01:04:069338
bnc691fda62016-08-12 00:43:169339 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session);
[email protected]cb9bf6ca2011-01-28 13:15:279340
[email protected]49639fa2011-12-20 23:22:419341 TestCompletionCallback callback;
[email protected]2d731a32010-04-29 01:04:069342
9343 // We do not complete this request, the dtor will clean the transaction up.
tfarina42834112016-09-22 13:38:209344 return trans.Start(&request, callback.callback(), NetLogWithSource());
[email protected]2d731a32010-04-29 01:04:069345}
9346
[email protected]448d4ca52012-03-04 04:12:239347} // namespace
9348
bncd16676a2016-07-20 16:23:019349TEST_F(HttpNetworkTransactionTest, GroupNameForDirectConnections) {
[email protected]2d731a32010-04-29 01:04:069350 const GroupNameTest tests[] = {
bncce36dca22015-04-21 22:11:239351 {
9352 "", // unused
9353 "http://www.example.org/direct",
9354 "www.example.org:80",
9355 false,
9356 },
9357 {
9358 "", // unused
9359 "http://[2001:1418:13:1::25]/direct",
9360 "[2001:1418:13:1::25]:80",
9361 false,
9362 },
[email protected]04e5be32009-06-26 20:00:319363
bncce36dca22015-04-21 22:11:239364 // SSL Tests
9365 {
9366 "", // unused
9367 "https://www.example.org/direct_ssl",
9368 "ssl/www.example.org:443",
9369 true,
9370 },
9371 {
9372 "", // unused
9373 "https://[2001:1418:13:1::25]/direct",
9374 "ssl/[2001:1418:13:1::25]:443",
9375 true,
9376 },
9377 {
9378 "", // unused
bncaa60ff402016-06-22 19:12:429379 "https://host.with.alternate/direct",
bncce36dca22015-04-21 22:11:239380 "ssl/host.with.alternate:443",
9381 true,
9382 },
[email protected]2d731a32010-04-29 01:04:069383 };
[email protected]2ff8b312010-04-26 22:20:549384
viettrungluue4a8b882014-10-16 06:17:389385 for (size_t i = 0; i < arraysize(tests); ++i) {
rdsmith82957ad2015-09-16 19:42:039386 session_deps_.proxy_service =
9387 ProxyService::CreateFixed(tests[i].proxy_server);
danakj1fd259a02016-04-16 03:17:099388 std::unique_ptr<HttpNetworkSession> session(
bnca9b9e222016-07-11 20:10:409389 SetupSessionForGroupNameTests(&session_deps_));
[email protected]2d731a32010-04-29 01:04:069390
mmenkee65e7af2015-10-13 17:16:429391 HttpNetworkSessionPeer peer(session.get());
[email protected]ab739042011-04-07 15:22:289392 CaptureGroupNameTransportSocketPool* transport_conn_pool =
bnc87dcefc2017-05-25 12:47:589393 new CaptureGroupNameTransportSocketPool(nullptr, nullptr);
[email protected]2431756e2010-09-29 20:26:139394 CaptureGroupNameSSLSocketPool* ssl_conn_pool =
bnc87dcefc2017-05-25 12:47:589395 new CaptureGroupNameSSLSocketPool(nullptr, nullptr);
Jeremy Roman0579ed62017-08-29 15:56:199396 auto mock_pool_manager = std::make_unique<MockClientSocketPoolManager>();
[email protected]a42dbd142011-11-17 16:42:029397 mock_pool_manager->SetTransportSocketPool(transport_conn_pool);
9398 mock_pool_manager->SetSSLSocketPool(ssl_conn_pool);
dchengc7eeda422015-12-26 03:56:489399 peer.SetClientSocketPoolManager(std::move(mock_pool_manager));
[email protected]2d731a32010-04-29 01:04:069400
9401 EXPECT_EQ(ERR_IO_PENDING,
mmenkee65e7af2015-10-13 17:16:429402 GroupNameTransactionHelper(tests[i].url, session.get()));
[email protected]e60e47a2010-07-14 03:37:189403 if (tests[i].ssl)
9404 EXPECT_EQ(tests[i].expected_group_name,
9405 ssl_conn_pool->last_group_name_received());
9406 else
9407 EXPECT_EQ(tests[i].expected_group_name,
[email protected]ab739042011-04-07 15:22:289408 transport_conn_pool->last_group_name_received());
[email protected]2d731a32010-04-29 01:04:069409 }
[email protected]2d731a32010-04-29 01:04:069410}
9411
bncd16676a2016-07-20 16:23:019412TEST_F(HttpNetworkTransactionTest, GroupNameForHTTPProxyConnections) {
[email protected]2d731a32010-04-29 01:04:069413 const GroupNameTest tests[] = {
bncce36dca22015-04-21 22:11:239414 {
9415 "http_proxy",
9416 "http://www.example.org/http_proxy_normal",
9417 "www.example.org:80",
9418 false,
9419 },
[email protected]2d731a32010-04-29 01:04:069420
bncce36dca22015-04-21 22:11:239421 // SSL Tests
9422 {
9423 "http_proxy",
9424 "https://www.example.org/http_connect_ssl",
9425 "ssl/www.example.org:443",
9426 true,
9427 },
[email protected]af3490e2010-10-16 21:02:299428
bncce36dca22015-04-21 22:11:239429 {
9430 "http_proxy",
bncaa60ff402016-06-22 19:12:429431 "https://host.with.alternate/direct",
bncce36dca22015-04-21 22:11:239432 "ssl/host.with.alternate:443",
9433 true,
9434 },
[email protected]45499252013-01-23 17:12:569435
bncce36dca22015-04-21 22:11:239436 {
9437 "http_proxy",
9438 "ftp://ftp.google.com/http_proxy_normal",
9439 "ftp/ftp.google.com:21",
9440 false,
9441 },
[email protected]2d731a32010-04-29 01:04:069442 };
9443
viettrungluue4a8b882014-10-16 06:17:389444 for (size_t i = 0; i < arraysize(tests); ++i) {
rdsmith82957ad2015-09-16 19:42:039445 session_deps_.proxy_service =
9446 ProxyService::CreateFixed(tests[i].proxy_server);
danakj1fd259a02016-04-16 03:17:099447 std::unique_ptr<HttpNetworkSession> session(
bnca9b9e222016-07-11 20:10:409448 SetupSessionForGroupNameTests(&session_deps_));
[email protected]2d731a32010-04-29 01:04:069449
mmenkee65e7af2015-10-13 17:16:429450 HttpNetworkSessionPeer peer(session.get());
[email protected]2d731a32010-04-29 01:04:069451
[email protected]e60e47a2010-07-14 03:37:189452 HostPortPair proxy_host("http_proxy", 80);
[email protected]2431756e2010-09-29 20:26:139453 CaptureGroupNameHttpProxySocketPool* http_proxy_pool =
[email protected]9e1bdd32011-02-03 21:48:349454 new CaptureGroupNameHttpProxySocketPool(NULL, NULL);
[email protected]2431756e2010-09-29 20:26:139455 CaptureGroupNameSSLSocketPool* ssl_conn_pool =
[email protected]9e1bdd32011-02-03 21:48:349456 new CaptureGroupNameSSLSocketPool(NULL, NULL);
Jeremy Roman0579ed62017-08-29 15:56:199457 auto mock_pool_manager = std::make_unique<MockClientSocketPoolManager>();
aviadef3442016-10-03 18:50:399458 mock_pool_manager->SetSocketPoolForHTTPProxy(
9459 proxy_host, base::WrapUnique(http_proxy_pool));
9460 mock_pool_manager->SetSocketPoolForSSLWithProxy(
9461 proxy_host, base::WrapUnique(ssl_conn_pool));
dchengc7eeda422015-12-26 03:56:489462 peer.SetClientSocketPoolManager(std::move(mock_pool_manager));
[email protected]2d731a32010-04-29 01:04:069463
9464 EXPECT_EQ(ERR_IO_PENDING,
mmenkee65e7af2015-10-13 17:16:429465 GroupNameTransactionHelper(tests[i].url, session.get()));
[email protected]e60e47a2010-07-14 03:37:189466 if (tests[i].ssl)
9467 EXPECT_EQ(tests[i].expected_group_name,
9468 ssl_conn_pool->last_group_name_received());
9469 else
9470 EXPECT_EQ(tests[i].expected_group_name,
9471 http_proxy_pool->last_group_name_received());
[email protected]2d731a32010-04-29 01:04:069472 }
[email protected]2d731a32010-04-29 01:04:069473}
9474
bncd16676a2016-07-20 16:23:019475TEST_F(HttpNetworkTransactionTest, GroupNameForSOCKSConnections) {
[email protected]2d731a32010-04-29 01:04:069476 const GroupNameTest tests[] = {
bncce36dca22015-04-21 22:11:239477 {
9478 "socks4://socks_proxy:1080",
9479 "http://www.example.org/socks4_direct",
9480 "socks4/www.example.org:80",
9481 false,
9482 },
9483 {
9484 "socks5://socks_proxy:1080",
9485 "http://www.example.org/socks5_direct",
9486 "socks5/www.example.org:80",
9487 false,
9488 },
[email protected]2d731a32010-04-29 01:04:069489
bncce36dca22015-04-21 22:11:239490 // SSL Tests
9491 {
9492 "socks4://socks_proxy:1080",
9493 "https://www.example.org/socks4_ssl",
9494 "socks4/ssl/www.example.org:443",
9495 true,
9496 },
9497 {
9498 "socks5://socks_proxy:1080",
9499 "https://www.example.org/socks5_ssl",
9500 "socks5/ssl/www.example.org:443",
9501 true,
9502 },
[email protected]af3490e2010-10-16 21:02:299503
bncce36dca22015-04-21 22:11:239504 {
9505 "socks4://socks_proxy:1080",
bncaa60ff402016-06-22 19:12:429506 "https://host.with.alternate/direct",
bncce36dca22015-04-21 22:11:239507 "socks4/ssl/host.with.alternate:443",
9508 true,
9509 },
[email protected]04e5be32009-06-26 20:00:319510 };
9511
viettrungluue4a8b882014-10-16 06:17:389512 for (size_t i = 0; i < arraysize(tests); ++i) {
rdsmith82957ad2015-09-16 19:42:039513 session_deps_.proxy_service =
9514 ProxyService::CreateFixed(tests[i].proxy_server);
danakj1fd259a02016-04-16 03:17:099515 std::unique_ptr<HttpNetworkSession> session(
bnca9b9e222016-07-11 20:10:409516 SetupSessionForGroupNameTests(&session_deps_));
[email protected]8b114dd72011-03-25 05:33:029517
mmenkee65e7af2015-10-13 17:16:429518 HttpNetworkSessionPeer peer(session.get());
[email protected]04e5be32009-06-26 20:00:319519
[email protected]e60e47a2010-07-14 03:37:189520 HostPortPair proxy_host("socks_proxy", 1080);
[email protected]2431756e2010-09-29 20:26:139521 CaptureGroupNameSOCKSSocketPool* socks_conn_pool =
[email protected]9e1bdd32011-02-03 21:48:349522 new CaptureGroupNameSOCKSSocketPool(NULL, NULL);
[email protected]2431756e2010-09-29 20:26:139523 CaptureGroupNameSSLSocketPool* ssl_conn_pool =
[email protected]9e1bdd32011-02-03 21:48:349524 new CaptureGroupNameSSLSocketPool(NULL, NULL);
Jeremy Roman0579ed62017-08-29 15:56:199525 auto mock_pool_manager = std::make_unique<MockClientSocketPoolManager>();
aviadef3442016-10-03 18:50:399526 mock_pool_manager->SetSocketPoolForSOCKSProxy(
9527 proxy_host, base::WrapUnique(socks_conn_pool));
9528 mock_pool_manager->SetSocketPoolForSSLWithProxy(
9529 proxy_host, base::WrapUnique(ssl_conn_pool));
dchengc7eeda422015-12-26 03:56:489530 peer.SetClientSocketPoolManager(std::move(mock_pool_manager));
[email protected]04e5be32009-06-26 20:00:319531
bnc691fda62016-08-12 00:43:169532 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]04e5be32009-06-26 20:00:319533
[email protected]2d731a32010-04-29 01:04:069534 EXPECT_EQ(ERR_IO_PENDING,
mmenkee65e7af2015-10-13 17:16:429535 GroupNameTransactionHelper(tests[i].url, session.get()));
[email protected]e60e47a2010-07-14 03:37:189536 if (tests[i].ssl)
9537 EXPECT_EQ(tests[i].expected_group_name,
9538 ssl_conn_pool->last_group_name_received());
9539 else
9540 EXPECT_EQ(tests[i].expected_group_name,
9541 socks_conn_pool->last_group_name_received());
[email protected]04e5be32009-06-26 20:00:319542 }
9543}
9544
bncd16676a2016-07-20 16:23:019545TEST_F(HttpNetworkTransactionTest, ReconsiderProxyAfterFailedConnection) {
[email protected]cb9bf6ca2011-01-28 13:15:279546 HttpRequestInfo request;
9547 request.method = "GET";
bncce36dca22015-04-21 22:11:239548 request.url = GURL("http://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:279549
rdsmith82957ad2015-09-16 19:42:039550 session_deps_.proxy_service =
9551 ProxyService::CreateFixed("myproxy:70;foobar:80");
[email protected]b59ff372009-07-15 22:04:329552
[email protected]69719062010-01-05 20:09:219553 // This simulates failure resolving all hostnames; that means we will fail
9554 // connecting to both proxies (myproxy:70 and foobar:80).
[email protected]bb88e1d32013-05-03 23:11:079555 session_deps_.host_resolver->rules()->AddSimulatedFailure("*");
[email protected]b59ff372009-07-15 22:04:329556
danakj1fd259a02016-04-16 03:17:099557 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:169558 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]9172a982009-06-06 00:30:259559
[email protected]49639fa2011-12-20 23:22:419560 TestCompletionCallback callback;
[email protected]9172a982009-06-06 00:30:259561
tfarina42834112016-09-22 13:38:209562 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:019563 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]9172a982009-06-06 00:30:259564
[email protected]9172a982009-06-06 00:30:259565 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:019566 EXPECT_THAT(rv, IsError(ERR_PROXY_CONNECTION_FAILED));
[email protected]9172a982009-06-06 00:30:259567}
9568
[email protected]685af592010-05-11 19:31:249569// Base test to make sure that when the load flags for a request specify to
9570// bypass the cache, the DNS cache is not used.
[email protected]23e482282013-06-14 16:08:029571void HttpNetworkTransactionTest::BypassHostCacheOnRefreshHelper(
[email protected]bb88e1d32013-05-03 23:11:079572 int load_flags) {
[email protected]cb9bf6ca2011-01-28 13:15:279573 // Issue a request, asking to bypass the cache(s).
maksim.sisov31452af2016-07-27 06:38:109574 HttpRequestInfo request_info;
9575 request_info.method = "GET";
9576 request_info.load_flags = load_flags;
9577 request_info.url = GURL("http://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:279578
[email protected]a2c2fb92009-07-18 07:31:049579 // Select a host resolver that does caching.
Jeremy Roman0579ed62017-08-29 15:56:199580 session_deps_.host_resolver = std::make_unique<MockCachingHostResolver>();
[email protected]b59ff372009-07-15 22:04:329581
danakj1fd259a02016-04-16 03:17:099582 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:169583 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]3b9cca42009-06-16 01:08:289584
bncce36dca22015-04-21 22:11:239585 // Warm up the host cache so it has an entry for "www.example.org".
[email protected]3b9cca42009-06-16 01:08:289586 AddressList addrlist;
[email protected]aa22b242011-11-16 18:58:299587 TestCompletionCallback callback;
maksim.sisov31452af2016-07-27 06:38:109588 std::unique_ptr<HostResolver::Request> request1;
[email protected]bb88e1d32013-05-03 23:11:079589 int rv = session_deps_.host_resolver->Resolve(
bncce36dca22015-04-21 22:11:239590 HostResolver::RequestInfo(HostPortPair("www.example.org", 80)),
maksim.sisov31452af2016-07-27 06:38:109591 DEFAULT_PRIORITY, &addrlist, callback.callback(), &request1,
tfarina42834112016-09-22 13:38:209592 NetLogWithSource());
robpercival214763f2016-07-01 23:27:019593 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]6e78dfb2011-07-28 21:34:479594 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:019595 EXPECT_THAT(rv, IsOk());
[email protected]3b9cca42009-06-16 01:08:289596
9597 // Verify that it was added to host cache, by doing a subsequent async lookup
9598 // and confirming it completes synchronously.
maksim.sisov31452af2016-07-27 06:38:109599 std::unique_ptr<HostResolver::Request> request2;
[email protected]bb88e1d32013-05-03 23:11:079600 rv = session_deps_.host_resolver->Resolve(
bncce36dca22015-04-21 22:11:239601 HostResolver::RequestInfo(HostPortPair("www.example.org", 80)),
maksim.sisov31452af2016-07-27 06:38:109602 DEFAULT_PRIORITY, &addrlist, callback.callback(), &request2,
tfarina42834112016-09-22 13:38:209603 NetLogWithSource());
robpercival214763f2016-07-01 23:27:019604 ASSERT_THAT(rv, IsOk());
[email protected]3b9cca42009-06-16 01:08:289605
bncce36dca22015-04-21 22:11:239606 // Inject a failure the next time that "www.example.org" is resolved. This way
[email protected]3b9cca42009-06-16 01:08:289607 // we can tell if the next lookup hit the cache, or the "network".
9608 // (cache --> success, "network" --> failure).
bncce36dca22015-04-21 22:11:239609 session_deps_.host_resolver->rules()->AddSimulatedFailure("www.example.org");
[email protected]3b9cca42009-06-16 01:08:289610
9611 // Connect up a mock socket which will fail with ERR_UNEXPECTED during the
9612 // first read -- this won't be reached as the host resolution will fail first.
[email protected]8ddf8322012-02-23 18:08:069613 MockRead data_reads[] = { MockRead(SYNCHRONOUS, ERR_UNEXPECTED) };
[email protected]31a2bfe2010-02-09 08:03:399614 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:079615 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]3b9cca42009-06-16 01:08:289616
[email protected]3b9cca42009-06-16 01:08:289617 // Run the request.
tfarina42834112016-09-22 13:38:209618 rv = trans.Start(&request_info, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:019619 ASSERT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]49639fa2011-12-20 23:22:419620 rv = callback.WaitForResult();
[email protected]3b9cca42009-06-16 01:08:289621
9622 // If we bypassed the cache, we would have gotten a failure while resolving
bncce36dca22015-04-21 22:11:239623 // "www.example.org".
robpercival214763f2016-07-01 23:27:019624 EXPECT_THAT(rv, IsError(ERR_NAME_NOT_RESOLVED));
[email protected]3b9cca42009-06-16 01:08:289625}
9626
[email protected]685af592010-05-11 19:31:249627// There are multiple load flags that should trigger the host cache bypass.
9628// Test each in isolation:
bncd16676a2016-07-20 16:23:019629TEST_F(HttpNetworkTransactionTest, BypassHostCacheOnRefresh1) {
[email protected]685af592010-05-11 19:31:249630 BypassHostCacheOnRefreshHelper(LOAD_BYPASS_CACHE);
9631}
9632
bncd16676a2016-07-20 16:23:019633TEST_F(HttpNetworkTransactionTest, BypassHostCacheOnRefresh2) {
[email protected]685af592010-05-11 19:31:249634 BypassHostCacheOnRefreshHelper(LOAD_VALIDATE_CACHE);
9635}
9636
bncd16676a2016-07-20 16:23:019637TEST_F(HttpNetworkTransactionTest, BypassHostCacheOnRefresh3) {
[email protected]685af592010-05-11 19:31:249638 BypassHostCacheOnRefreshHelper(LOAD_DISABLE_CACHE);
9639}
9640
[email protected]0877e3d2009-10-17 22:29:579641// Make sure we can handle an error when writing the request.
bncd16676a2016-07-20 16:23:019642TEST_F(HttpNetworkTransactionTest, RequestWriteError) {
[email protected]0877e3d2009-10-17 22:29:579643 HttpRequestInfo request;
9644 request.method = "GET";
9645 request.url = GURL("http://www.foo.com/");
[email protected]0877e3d2009-10-17 22:29:579646
9647 MockWrite write_failure[] = {
[email protected]8ddf8322012-02-23 18:08:069648 MockWrite(ASYNC, ERR_CONNECTION_RESET),
[email protected]0877e3d2009-10-17 22:29:579649 };
[email protected]31a2bfe2010-02-09 08:03:399650 StaticSocketDataProvider data(NULL, 0,
9651 write_failure, arraysize(write_failure));
[email protected]bb88e1d32013-05-03 23:11:079652 session_deps_.socket_factory->AddSocketDataProvider(&data);
danakj1fd259a02016-04-16 03:17:099653 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]0877e3d2009-10-17 22:29:579654
[email protected]49639fa2011-12-20 23:22:419655 TestCompletionCallback callback;
[email protected]0877e3d2009-10-17 22:29:579656
bnc691fda62016-08-12 00:43:169657 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]0877e3d2009-10-17 22:29:579658
tfarina42834112016-09-22 13:38:209659 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:019660 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]0877e3d2009-10-17 22:29:579661
9662 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:019663 EXPECT_THAT(rv, IsError(ERR_CONNECTION_RESET));
ttuttled9dbc652015-09-29 20:00:599664
9665 IPEndPoint endpoint;
bnc691fda62016-08-12 00:43:169666 EXPECT_TRUE(trans.GetRemoteEndpoint(&endpoint));
ttuttled9dbc652015-09-29 20:00:599667 EXPECT_LT(0u, endpoint.address().size());
[email protected]0877e3d2009-10-17 22:29:579668}
9669
zmo9528c9f42015-08-04 22:12:089670// Check that a connection closed after the start of the headers finishes ok.
bncd16676a2016-07-20 16:23:019671TEST_F(HttpNetworkTransactionTest, ConnectionClosedAfterStartOfHeaders) {
[email protected]0877e3d2009-10-17 22:29:579672 HttpRequestInfo request;
9673 request.method = "GET";
9674 request.url = GURL("http://www.foo.com/");
[email protected]0877e3d2009-10-17 22:29:579675
9676 MockRead data_reads[] = {
9677 MockRead("HTTP/1."),
[email protected]8ddf8322012-02-23 18:08:069678 MockRead(SYNCHRONOUS, OK),
[email protected]0877e3d2009-10-17 22:29:579679 };
9680
[email protected]31a2bfe2010-02-09 08:03:399681 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:079682 session_deps_.socket_factory->AddSocketDataProvider(&data);
danakj1fd259a02016-04-16 03:17:099683 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]0877e3d2009-10-17 22:29:579684
[email protected]49639fa2011-12-20 23:22:419685 TestCompletionCallback callback;
[email protected]0877e3d2009-10-17 22:29:579686
bnc691fda62016-08-12 00:43:169687 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]0877e3d2009-10-17 22:29:579688
tfarina42834112016-09-22 13:38:209689 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:019690 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]0877e3d2009-10-17 22:29:579691
9692 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:019693 EXPECT_THAT(rv, IsOk());
zmo9528c9f42015-08-04 22:12:089694
bnc691fda62016-08-12 00:43:169695 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:529696 ASSERT_TRUE(response);
zmo9528c9f42015-08-04 22:12:089697
wezca1070932016-05-26 20:30:529698 EXPECT_TRUE(response->headers);
zmo9528c9f42015-08-04 22:12:089699 EXPECT_EQ("HTTP/1.0 200 OK", response->headers->GetStatusLine());
9700
9701 std::string response_data;
bnc691fda62016-08-12 00:43:169702 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:019703 EXPECT_THAT(rv, IsOk());
zmo9528c9f42015-08-04 22:12:089704 EXPECT_EQ("", response_data);
ttuttled9dbc652015-09-29 20:00:599705
9706 IPEndPoint endpoint;
bnc691fda62016-08-12 00:43:169707 EXPECT_TRUE(trans.GetRemoteEndpoint(&endpoint));
ttuttled9dbc652015-09-29 20:00:599708 EXPECT_LT(0u, endpoint.address().size());
[email protected]0877e3d2009-10-17 22:29:579709}
9710
9711// Make sure that a dropped connection while draining the body for auth
9712// restart does the right thing.
bncd16676a2016-07-20 16:23:019713TEST_F(HttpNetworkTransactionTest, DrainResetOK) {
[email protected]0877e3d2009-10-17 22:29:579714 HttpRequestInfo request;
9715 request.method = "GET";
bncce36dca22015-04-21 22:11:239716 request.url = GURL("http://www.example.org/");
[email protected]0877e3d2009-10-17 22:29:579717
9718 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:239719 MockWrite(
9720 "GET / HTTP/1.1\r\n"
9721 "Host: www.example.org\r\n"
9722 "Connection: keep-alive\r\n\r\n"),
[email protected]0877e3d2009-10-17 22:29:579723 };
9724
9725 MockRead data_reads1[] = {
9726 MockRead("HTTP/1.1 401 Unauthorized\r\n"),
9727 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
9728 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
9729 MockRead("Content-Length: 14\r\n\r\n"),
9730 MockRead("Unauth"),
[email protected]8ddf8322012-02-23 18:08:069731 MockRead(ASYNC, ERR_CONNECTION_RESET),
[email protected]0877e3d2009-10-17 22:29:579732 };
9733
[email protected]31a2bfe2010-02-09 08:03:399734 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
9735 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:079736 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]0877e3d2009-10-17 22:29:579737
bnc691fda62016-08-12 00:43:169738 // After calling trans.RestartWithAuth(), this is the request we should
[email protected]0877e3d2009-10-17 22:29:579739 // be issuing -- the final header line contains the credentials.
9740 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:239741 MockWrite(
9742 "GET / HTTP/1.1\r\n"
9743 "Host: www.example.org\r\n"
9744 "Connection: keep-alive\r\n"
9745 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]0877e3d2009-10-17 22:29:579746 };
9747
9748 // Lastly, the server responds with the actual content.
9749 MockRead data_reads2[] = {
9750 MockRead("HTTP/1.1 200 OK\r\n"),
9751 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
9752 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:069753 MockRead(SYNCHRONOUS, OK),
[email protected]0877e3d2009-10-17 22:29:579754 };
9755
[email protected]31a2bfe2010-02-09 08:03:399756 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
9757 data_writes2, arraysize(data_writes2));
[email protected]bb88e1d32013-05-03 23:11:079758 session_deps_.socket_factory->AddSocketDataProvider(&data2);
danakj1fd259a02016-04-16 03:17:099759 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]0877e3d2009-10-17 22:29:579760
[email protected]49639fa2011-12-20 23:22:419761 TestCompletionCallback callback1;
[email protected]0877e3d2009-10-17 22:29:579762
bnc691fda62016-08-12 00:43:169763 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]0b0bf032010-09-21 18:08:509764
tfarina42834112016-09-22 13:38:209765 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:019766 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]0877e3d2009-10-17 22:29:579767
9768 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:019769 EXPECT_THAT(rv, IsOk());
[email protected]0877e3d2009-10-17 22:29:579770
bnc691fda62016-08-12 00:43:169771 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:529772 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:049773 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]0877e3d2009-10-17 22:29:579774
[email protected]49639fa2011-12-20 23:22:419775 TestCompletionCallback callback2;
[email protected]0877e3d2009-10-17 22:29:579776
bnc691fda62016-08-12 00:43:169777 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar), callback2.callback());
robpercival214763f2016-07-01 23:27:019778 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]0877e3d2009-10-17 22:29:579779
9780 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:019781 EXPECT_THAT(rv, IsOk());
[email protected]0877e3d2009-10-17 22:29:579782
bnc691fda62016-08-12 00:43:169783 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:529784 ASSERT_TRUE(response);
9785 EXPECT_FALSE(response->auth_challenge);
[email protected]0877e3d2009-10-17 22:29:579786 EXPECT_EQ(100, response->headers->GetContentLength());
9787}
9788
9789// Test HTTPS connections going through a proxy that sends extra data.
bncd16676a2016-07-20 16:23:019790TEST_F(HttpNetworkTransactionTest, HTTPSViaProxyWithExtraData) {
rdsmith82957ad2015-09-16 19:42:039791 session_deps_.proxy_service = ProxyService::CreateFixed("myproxy:70");
[email protected]0877e3d2009-10-17 22:29:579792
9793 HttpRequestInfo request;
9794 request.method = "GET";
bncce36dca22015-04-21 22:11:239795 request.url = GURL("https://www.example.org/");
[email protected]0877e3d2009-10-17 22:29:579796
9797 MockRead proxy_reads[] = {
9798 MockRead("HTTP/1.0 200 Connected\r\n\r\nExtra data"),
[email protected]8ddf8322012-02-23 18:08:069799 MockRead(SYNCHRONOUS, OK)
[email protected]0877e3d2009-10-17 22:29:579800 };
9801
[email protected]31a2bfe2010-02-09 08:03:399802 StaticSocketDataProvider data(proxy_reads, arraysize(proxy_reads), NULL, 0);
[email protected]8ddf8322012-02-23 18:08:069803 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]0877e3d2009-10-17 22:29:579804
[email protected]bb88e1d32013-05-03 23:11:079805 session_deps_.socket_factory->AddSocketDataProvider(&data);
9806 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]0877e3d2009-10-17 22:29:579807
[email protected]49639fa2011-12-20 23:22:419808 TestCompletionCallback callback;
[email protected]0877e3d2009-10-17 22:29:579809
[email protected]bb88e1d32013-05-03 23:11:079810 session_deps_.socket_factory->ResetNextMockIndexes();
[email protected]0877e3d2009-10-17 22:29:579811
danakj1fd259a02016-04-16 03:17:099812 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
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_TUNNEL_CONNECTION_FAILED));
[email protected]0877e3d2009-10-17 22:29:579820}
9821
bncd16676a2016-07-20 16:23:019822TEST_F(HttpNetworkTransactionTest, LargeContentLengthThenClose) {
[email protected]9492e4a2010-02-24 00:58:469823 HttpRequestInfo request;
9824 request.method = "GET";
bncce36dca22015-04-21 22:11:239825 request.url = GURL("http://www.example.org/");
[email protected]9492e4a2010-02-24 00:58:469826
danakj1fd259a02016-04-16 03:17:099827 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:169828 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:279829
[email protected]e22e1362009-11-23 21:31:129830 MockRead data_reads[] = {
9831 MockRead("HTTP/1.0 200 OK\r\nContent-Length:6719476739\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:069832 MockRead(SYNCHRONOUS, OK),
[email protected]e22e1362009-11-23 21:31:129833 };
[email protected]9492e4a2010-02-24 00:58:469834
9835 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:079836 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]9492e4a2010-02-24 00:58:469837
[email protected]49639fa2011-12-20 23:22:419838 TestCompletionCallback callback;
[email protected]9492e4a2010-02-24 00:58:469839
tfarina42834112016-09-22 13:38:209840 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:019841 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]9492e4a2010-02-24 00:58:469842
robpercival214763f2016-07-01 23:27:019843 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]9492e4a2010-02-24 00:58:469844
bnc691fda62016-08-12 00:43:169845 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:529846 ASSERT_TRUE(response);
[email protected]9492e4a2010-02-24 00:58:469847
wezca1070932016-05-26 20:30:529848 EXPECT_TRUE(response->headers);
[email protected]9492e4a2010-02-24 00:58:469849 EXPECT_EQ("HTTP/1.0 200 OK", response->headers->GetStatusLine());
9850
9851 std::string response_data;
bnc691fda62016-08-12 00:43:169852 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:019853 EXPECT_THAT(rv, IsError(ERR_CONTENT_LENGTH_MISMATCH));
[email protected]e22e1362009-11-23 21:31:129854}
9855
bncd16676a2016-07-20 16:23:019856TEST_F(HttpNetworkTransactionTest, UploadFileSmallerThanLength) {
[email protected]6cdfd7f2013-02-08 20:40:159857 base::FilePath temp_file_path;
[email protected]03d9afc02013-12-03 17:55:529858 ASSERT_TRUE(base::CreateTemporaryFile(&temp_file_path));
avibf0746c2015-12-09 19:53:149859 const uint64_t kFakeSize = 100000; // file is actually blank
[email protected]d98961652012-09-11 20:27:219860 UploadFileElementReader::ScopedOverridingContentLengthForTests
9861 overriding_content_length(kFakeSize);
[email protected]95d88ffe2010-02-04 21:25:339862
danakj1fd259a02016-04-16 03:17:099863 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
Jeremy Roman0579ed62017-08-29 15:56:199864 element_readers.push_back(std::make_unique<UploadFileElementReader>(
avibf0746c2015-12-09 19:53:149865 base::ThreadTaskRunnerHandle::Get().get(), temp_file_path, 0,
ricea2deef682016-09-09 08:04:079866 std::numeric_limits<uint64_t>::max(), base::Time()));
olli.raula6df48b2a2015-11-26 07:40:229867 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]329b68b2012-11-14 17:54:279868
9869 HttpRequestInfo request;
9870 request.method = "POST";
bncce36dca22015-04-21 22:11:239871 request.url = GURL("http://www.example.org/upload");
[email protected]329b68b2012-11-14 17:54:279872 request.upload_data_stream = &upload_data_stream;
[email protected]329b68b2012-11-14 17:54:279873
danakj1fd259a02016-04-16 03:17:099874 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:169875 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]95d88ffe2010-02-04 21:25:339876
9877 MockRead data_reads[] = {
9878 MockRead("HTTP/1.0 200 OK\r\n\r\n"),
9879 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:069880 MockRead(SYNCHRONOUS, OK),
[email protected]95d88ffe2010-02-04 21:25:339881 };
[email protected]31a2bfe2010-02-09 08:03:399882 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:079883 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]95d88ffe2010-02-04 21:25:339884
[email protected]49639fa2011-12-20 23:22:419885 TestCompletionCallback callback;
[email protected]95d88ffe2010-02-04 21:25:339886
tfarina42834112016-09-22 13:38:209887 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:019888 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]95d88ffe2010-02-04 21:25:339889
9890 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:019891 EXPECT_THAT(rv, IsError(ERR_UPLOAD_FILE_CHANGED));
[email protected]95d88ffe2010-02-04 21:25:339892
bnc691fda62016-08-12 00:43:169893 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:529894 ASSERT_TRUE(response);
[email protected]95d88ffe2010-02-04 21:25:339895
maksim.sisove869bf52016-06-23 17:11:529896 EXPECT_FALSE(response->headers);
[email protected]95d88ffe2010-02-04 21:25:339897
[email protected]dd3aa792013-07-16 19:10:239898 base::DeleteFile(temp_file_path, false);
[email protected]95d88ffe2010-02-04 21:25:339899}
9900
bncd16676a2016-07-20 16:23:019901TEST_F(HttpNetworkTransactionTest, UploadUnreadableFile) {
[email protected]6cdfd7f2013-02-08 20:40:159902 base::FilePath temp_file;
[email protected]03d9afc02013-12-03 17:55:529903 ASSERT_TRUE(base::CreateTemporaryFile(&temp_file));
[email protected]6624b4622010-03-29 19:58:369904 std::string temp_file_content("Unreadable file.");
lazyboy8df84fc2017-04-12 02:12:489905 ASSERT_EQ(static_cast<int>(temp_file_content.length()),
9906 base::WriteFile(temp_file, temp_file_content.c_str(),
9907 temp_file_content.length()));
[email protected]92be8eb2014-08-07 22:57:119908 ASSERT_TRUE(base::MakeFileUnreadable(temp_file));
[email protected]6624b4622010-03-29 19:58:369909
danakj1fd259a02016-04-16 03:17:099910 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
Jeremy Roman0579ed62017-08-29 15:56:199911 element_readers.push_back(std::make_unique<UploadFileElementReader>(
avibf0746c2015-12-09 19:53:149912 base::ThreadTaskRunnerHandle::Get().get(), temp_file, 0,
ricea2deef682016-09-09 08:04:079913 std::numeric_limits<uint64_t>::max(), base::Time()));
olli.raula6df48b2a2015-11-26 07:40:229914 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]329b68b2012-11-14 17:54:279915
9916 HttpRequestInfo request;
9917 request.method = "POST";
bncce36dca22015-04-21 22:11:239918 request.url = GURL("http://www.example.org/upload");
[email protected]329b68b2012-11-14 17:54:279919 request.upload_data_stream = &upload_data_stream;
[email protected]329b68b2012-11-14 17:54:279920
[email protected]999dd8c2013-11-12 06:45:549921 // If we try to upload an unreadable file, the transaction should fail.
danakj1fd259a02016-04-16 03:17:099922 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:169923 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]6624b4622010-03-29 19:58:369924
[email protected]999dd8c2013-11-12 06:45:549925 StaticSocketDataProvider data(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:079926 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]6624b4622010-03-29 19:58:369927
[email protected]49639fa2011-12-20 23:22:419928 TestCompletionCallback callback;
[email protected]6624b4622010-03-29 19:58:369929
tfarina42834112016-09-22 13:38:209930 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:019931 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]6624b4622010-03-29 19:58:369932
9933 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:019934 EXPECT_THAT(rv, IsError(ERR_ACCESS_DENIED));
[email protected]6624b4622010-03-29 19:58:369935
[email protected]dd3aa792013-07-16 19:10:239936 base::DeleteFile(temp_file, false);
[email protected]6624b4622010-03-29 19:58:369937}
9938
bncd16676a2016-07-20 16:23:019939TEST_F(HttpNetworkTransactionTest, CancelDuringInitRequestBody) {
[email protected]02cad5d2013-10-02 08:14:039940 class FakeUploadElementReader : public UploadElementReader {
9941 public:
9942 FakeUploadElementReader() {}
dchengb03027d2014-10-21 12:00:209943 ~FakeUploadElementReader() override {}
[email protected]02cad5d2013-10-02 08:14:039944
9945 const CompletionCallback& callback() const { return callback_; }
9946
9947 // UploadElementReader overrides:
dchengb03027d2014-10-21 12:00:209948 int Init(const CompletionCallback& callback) override {
[email protected]02cad5d2013-10-02 08:14:039949 callback_ = callback;
9950 return ERR_IO_PENDING;
9951 }
avibf0746c2015-12-09 19:53:149952 uint64_t GetContentLength() const override { return 0; }
9953 uint64_t BytesRemaining() const override { return 0; }
dchengb03027d2014-10-21 12:00:209954 int Read(IOBuffer* buf,
9955 int buf_length,
9956 const CompletionCallback& callback) override {
[email protected]02cad5d2013-10-02 08:14:039957 return ERR_FAILED;
9958 }
9959
9960 private:
9961 CompletionCallback callback_;
9962 };
9963
9964 FakeUploadElementReader* fake_reader = new FakeUploadElementReader;
danakj1fd259a02016-04-16 03:17:099965 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
9966 element_readers.push_back(base::WrapUnique(fake_reader));
olli.raula6df48b2a2015-11-26 07:40:229967 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]02cad5d2013-10-02 08:14:039968
9969 HttpRequestInfo request;
9970 request.method = "POST";
bncce36dca22015-04-21 22:11:239971 request.url = GURL("http://www.example.org/upload");
[email protected]02cad5d2013-10-02 08:14:039972 request.upload_data_stream = &upload_data_stream;
[email protected]02cad5d2013-10-02 08:14:039973
danakj1fd259a02016-04-16 03:17:099974 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc87dcefc2017-05-25 12:47:589975 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:199976 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]02cad5d2013-10-02 08:14:039977
9978 StaticSocketDataProvider data;
9979 session_deps_.socket_factory->AddSocketDataProvider(&data);
9980
9981 TestCompletionCallback callback;
tfarina42834112016-09-22 13:38:209982 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:019983 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
fdoray92e35a72016-06-10 15:54:559984 base::RunLoop().RunUntilIdle();
[email protected]02cad5d2013-10-02 08:14:039985
9986 // Transaction is pending on request body initialization.
9987 ASSERT_FALSE(fake_reader->callback().is_null());
9988
9989 // Return Init()'s result after the transaction gets destroyed.
9990 trans.reset();
9991 fake_reader->callback().Run(OK); // Should not crash.
9992}
9993
[email protected]aeefc9e82010-02-19 16:18:279994// Tests that changes to Auth realms are treated like auth rejections.
bncd16676a2016-07-20 16:23:019995TEST_F(HttpNetworkTransactionTest, ChangeAuthRealms) {
[email protected]aeefc9e82010-02-19 16:18:279996 HttpRequestInfo request;
9997 request.method = "GET";
bncce36dca22015-04-21 22:11:239998 request.url = GURL("http://www.example.org/");
[email protected]aeefc9e82010-02-19 16:18:279999
10000 // First transaction will request a resource and receive a Basic challenge
10001 // with realm="first_realm".
10002 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:2310003 MockWrite(
10004 "GET / HTTP/1.1\r\n"
10005 "Host: www.example.org\r\n"
10006 "Connection: keep-alive\r\n"
10007 "\r\n"),
[email protected]aeefc9e82010-02-19 16:18:2710008 };
10009 MockRead data_reads1[] = {
10010 MockRead("HTTP/1.1 401 Unauthorized\r\n"
10011 "WWW-Authenticate: Basic realm=\"first_realm\"\r\n"
10012 "\r\n"),
10013 };
10014
bnc691fda62016-08-12 00:43:1610015 // After calling trans.RestartWithAuth(), provide an Authentication header
[email protected]aeefc9e82010-02-19 16:18:2710016 // for first_realm. The server will reject and provide a challenge with
10017 // second_realm.
10018 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:2310019 MockWrite(
10020 "GET / HTTP/1.1\r\n"
10021 "Host: www.example.org\r\n"
10022 "Connection: keep-alive\r\n"
10023 "Authorization: Basic Zmlyc3Q6YmF6\r\n"
10024 "\r\n"),
[email protected]aeefc9e82010-02-19 16:18:2710025 };
10026 MockRead data_reads2[] = {
10027 MockRead("HTTP/1.1 401 Unauthorized\r\n"
10028 "WWW-Authenticate: Basic realm=\"second_realm\"\r\n"
10029 "\r\n"),
10030 };
10031
10032 // This again fails, and goes back to first_realm. Make sure that the
10033 // entry is removed from cache.
10034 MockWrite data_writes3[] = {
bncce36dca22015-04-21 22:11:2310035 MockWrite(
10036 "GET / HTTP/1.1\r\n"
10037 "Host: www.example.org\r\n"
10038 "Connection: keep-alive\r\n"
10039 "Authorization: Basic c2Vjb25kOmZvdQ==\r\n"
10040 "\r\n"),
[email protected]aeefc9e82010-02-19 16:18:2710041 };
10042 MockRead data_reads3[] = {
10043 MockRead("HTTP/1.1 401 Unauthorized\r\n"
10044 "WWW-Authenticate: Basic realm=\"first_realm\"\r\n"
10045 "\r\n"),
10046 };
10047
10048 // Try one last time (with the correct password) and get the resource.
10049 MockWrite data_writes4[] = {
bncce36dca22015-04-21 22:11:2310050 MockWrite(
10051 "GET / HTTP/1.1\r\n"
10052 "Host: www.example.org\r\n"
10053 "Connection: keep-alive\r\n"
10054 "Authorization: Basic Zmlyc3Q6YmFy\r\n"
10055 "\r\n"),
[email protected]aeefc9e82010-02-19 16:18:2710056 };
10057 MockRead data_reads4[] = {
10058 MockRead("HTTP/1.1 200 OK\r\n"
10059 "Content-Type: text/html; charset=iso-8859-1\r\n"
[email protected]0b0bf032010-09-21 18:08:5010060 "Content-Length: 5\r\n"
10061 "\r\n"
10062 "hello"),
[email protected]aeefc9e82010-02-19 16:18:2710063 };
10064
10065 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
10066 data_writes1, arraysize(data_writes1));
10067 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
10068 data_writes2, arraysize(data_writes2));
10069 StaticSocketDataProvider data3(data_reads3, arraysize(data_reads3),
10070 data_writes3, arraysize(data_writes3));
10071 StaticSocketDataProvider data4(data_reads4, arraysize(data_reads4),
10072 data_writes4, arraysize(data_writes4));
[email protected]bb88e1d32013-05-03 23:11:0710073 session_deps_.socket_factory->AddSocketDataProvider(&data1);
10074 session_deps_.socket_factory->AddSocketDataProvider(&data2);
10075 session_deps_.socket_factory->AddSocketDataProvider(&data3);
10076 session_deps_.socket_factory->AddSocketDataProvider(&data4);
[email protected]aeefc9e82010-02-19 16:18:2710077
[email protected]49639fa2011-12-20 23:22:4110078 TestCompletionCallback callback1;
[email protected]aeefc9e82010-02-19 16:18:2710079
danakj1fd259a02016-04-16 03:17:0910080 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1610081 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]0b0bf032010-09-21 18:08:5010082
[email protected]aeefc9e82010-02-19 16:18:2710083 // Issue the first request with Authorize headers. There should be a
10084 // password prompt for first_realm waiting to be filled in after the
10085 // transaction completes.
tfarina42834112016-09-22 13:38:2010086 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110087 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]aeefc9e82010-02-19 16:18:2710088 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:0110089 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:1610090 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5210091 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:0410092 const AuthChallengeInfo* challenge = response->auth_challenge.get();
wezca1070932016-05-26 20:30:5210093 ASSERT_TRUE(challenge);
[email protected]79cb5c12011-09-12 13:12:0410094 EXPECT_FALSE(challenge->is_proxy);
asanka098c0092016-06-16 20:18:4310095 EXPECT_EQ("http://www.example.org", challenge->challenger.Serialize());
[email protected]79cb5c12011-09-12 13:12:0410096 EXPECT_EQ("first_realm", challenge->realm);
aberentbba302d2015-12-03 10:20:1910097 EXPECT_EQ(kBasicAuthScheme, challenge->scheme);
[email protected]aeefc9e82010-02-19 16:18:2710098
10099 // Issue the second request with an incorrect password. There should be a
10100 // password prompt for second_realm waiting to be filled in after the
10101 // transaction completes.
[email protected]49639fa2011-12-20 23:22:4110102 TestCompletionCallback callback2;
bnc691fda62016-08-12 00:43:1610103 rv = trans.RestartWithAuth(AuthCredentials(kFirst, kBaz),
10104 callback2.callback());
robpercival214763f2016-07-01 23:27:0110105 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]aeefc9e82010-02-19 16:18:2710106 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:0110107 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:1610108 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5210109 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:0410110 challenge = response->auth_challenge.get();
wezca1070932016-05-26 20:30:5210111 ASSERT_TRUE(challenge);
[email protected]79cb5c12011-09-12 13:12:0410112 EXPECT_FALSE(challenge->is_proxy);
asanka098c0092016-06-16 20:18:4310113 EXPECT_EQ("http://www.example.org", challenge->challenger.Serialize());
[email protected]79cb5c12011-09-12 13:12:0410114 EXPECT_EQ("second_realm", challenge->realm);
aberentbba302d2015-12-03 10:20:1910115 EXPECT_EQ(kBasicAuthScheme, challenge->scheme);
[email protected]aeefc9e82010-02-19 16:18:2710116
10117 // Issue the third request with another incorrect password. There should be
10118 // a password prompt for first_realm waiting to be filled in. If the password
10119 // prompt is not present, it indicates that the HttpAuthCacheEntry for
10120 // first_realm was not correctly removed.
[email protected]49639fa2011-12-20 23:22:4110121 TestCompletionCallback callback3;
bnc691fda62016-08-12 00:43:1610122 rv = trans.RestartWithAuth(AuthCredentials(kSecond, kFou),
10123 callback3.callback());
robpercival214763f2016-07-01 23:27:0110124 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]aeefc9e82010-02-19 16:18:2710125 rv = callback3.WaitForResult();
robpercival214763f2016-07-01 23:27:0110126 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:1610127 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5210128 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:0410129 challenge = response->auth_challenge.get();
wezca1070932016-05-26 20:30:5210130 ASSERT_TRUE(challenge);
[email protected]79cb5c12011-09-12 13:12:0410131 EXPECT_FALSE(challenge->is_proxy);
asanka098c0092016-06-16 20:18:4310132 EXPECT_EQ("http://www.example.org", challenge->challenger.Serialize());
[email protected]79cb5c12011-09-12 13:12:0410133 EXPECT_EQ("first_realm", challenge->realm);
aberentbba302d2015-12-03 10:20:1910134 EXPECT_EQ(kBasicAuthScheme, challenge->scheme);
[email protected]aeefc9e82010-02-19 16:18:2710135
10136 // Issue the fourth request with the correct password and username.
[email protected]49639fa2011-12-20 23:22:4110137 TestCompletionCallback callback4;
bnc691fda62016-08-12 00:43:1610138 rv = trans.RestartWithAuth(AuthCredentials(kFirst, kBar),
10139 callback4.callback());
robpercival214763f2016-07-01 23:27:0110140 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]aeefc9e82010-02-19 16:18:2710141 rv = callback4.WaitForResult();
robpercival214763f2016-07-01 23:27:0110142 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:1610143 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5210144 ASSERT_TRUE(response);
10145 EXPECT_FALSE(response->auth_challenge);
[email protected]aeefc9e82010-02-19 16:18:2710146}
10147
Bence Béky230ac612017-08-30 19:17:0810148// Regression test for https://crbug.com/754395.
10149TEST_F(HttpNetworkTransactionTest, IgnoreAltSvcWithInvalidCert) {
10150 MockRead data_reads[] = {
10151 MockRead("HTTP/1.1 200 OK\r\n"),
10152 MockRead(kAlternativeServiceHttpHeader),
10153 MockRead("\r\n"),
10154 MockRead("hello world"),
10155 MockRead(SYNCHRONOUS, OK),
10156 };
10157
10158 HttpRequestInfo request;
10159 request.method = "GET";
10160 request.url = GURL("https://www.example.org/");
10161
10162 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
10163 session_deps_.socket_factory->AddSocketDataProvider(&data);
10164
10165 SSLSocketDataProvider ssl(ASYNC, OK);
10166 ssl.cert = ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem");
10167 ASSERT_TRUE(ssl.cert);
10168 ssl.cert_status = CERT_STATUS_COMMON_NAME_INVALID;
10169 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
10170
10171 TestCompletionCallback callback;
10172
10173 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
10174 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
10175
10176 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
10177 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
10178
10179 url::SchemeHostPort test_server(request.url);
10180 HttpServerProperties* http_server_properties =
10181 session->http_server_properties();
10182 EXPECT_TRUE(
10183 http_server_properties->GetAlternativeServiceInfos(test_server).empty());
10184
10185 EXPECT_THAT(callback.WaitForResult(), IsOk());
10186
10187 const HttpResponseInfo* response = trans.GetResponseInfo();
10188 ASSERT_TRUE(response);
10189 ASSERT_TRUE(response->headers);
10190 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
10191 EXPECT_FALSE(response->was_fetched_via_spdy);
10192 EXPECT_FALSE(response->was_alpn_negotiated);
10193
10194 std::string response_data;
10195 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
10196 EXPECT_EQ("hello world", response_data);
10197
10198 EXPECT_TRUE(
10199 http_server_properties->GetAlternativeServiceInfos(test_server).empty());
10200}
10201
bncd16676a2016-07-20 16:23:0110202TEST_F(HttpNetworkTransactionTest, HonorAlternativeServiceHeader) {
bncc958faa2015-07-31 18:14:5210203 MockRead data_reads[] = {
10204 MockRead("HTTP/1.1 200 OK\r\n"),
bnc2df4b522016-07-08 18:17:4310205 MockRead(kAlternativeServiceHttpHeader),
bncc958faa2015-07-31 18:14:5210206 MockRead("\r\n"),
10207 MockRead("hello world"),
10208 MockRead(SYNCHRONOUS, OK),
10209 };
10210
10211 HttpRequestInfo request;
10212 request.method = "GET";
bncb26024382016-06-29 02:39:4510213 request.url = GURL("https://www.example.org/");
bncc958faa2015-07-31 18:14:5210214
10215 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
bncc958faa2015-07-31 18:14:5210216 session_deps_.socket_factory->AddSocketDataProvider(&data);
10217
bncb26024382016-06-29 02:39:4510218 SSLSocketDataProvider ssl(ASYNC, OK);
Bence Béky230ac612017-08-30 19:17:0810219 ssl.cert = ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem");
10220 ASSERT_TRUE(ssl.cert);
bncb26024382016-06-29 02:39:4510221 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
10222
bncc958faa2015-07-31 18:14:5210223 TestCompletionCallback callback;
10224
danakj1fd259a02016-04-16 03:17:0910225 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1610226 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
bncc958faa2015-07-31 18:14:5210227
tfarina42834112016-09-22 13:38:2010228 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110229 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
bncc958faa2015-07-31 18:14:5210230
bncb26024382016-06-29 02:39:4510231 url::SchemeHostPort test_server(request.url);
bnc525e175a2016-06-20 12:36:4010232 HttpServerProperties* http_server_properties =
10233 session->http_server_properties();
zhongyic4de03032017-05-19 04:07:3410234 EXPECT_TRUE(
10235 http_server_properties->GetAlternativeServiceInfos(test_server).empty());
bncc958faa2015-07-31 18:14:5210236
robpercival214763f2016-07-01 23:27:0110237 EXPECT_THAT(callback.WaitForResult(), IsOk());
bncc958faa2015-07-31 18:14:5210238
bnc691fda62016-08-12 00:43:1610239 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5210240 ASSERT_TRUE(response);
10241 ASSERT_TRUE(response->headers);
bncc958faa2015-07-31 18:14:5210242 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
10243 EXPECT_FALSE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5210244 EXPECT_FALSE(response->was_alpn_negotiated);
bncc958faa2015-07-31 18:14:5210245
10246 std::string response_data;
bnc691fda62016-08-12 00:43:1610247 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
bncc958faa2015-07-31 18:14:5210248 EXPECT_EQ("hello world", response_data);
10249
zhongyic4de03032017-05-19 04:07:3410250 AlternativeServiceInfoVector alternative_service_info_vector =
10251 http_server_properties->GetAlternativeServiceInfos(test_server);
10252 ASSERT_EQ(1u, alternative_service_info_vector.size());
10253 AlternativeService alternative_service(kProtoHTTP2, "mail.example.org", 443);
10254 EXPECT_EQ(alternative_service,
zhongyi422ce352017-06-09 23:28:5410255 alternative_service_info_vector[0].alternative_service());
bncc958faa2015-07-31 18:14:5210256}
10257
bnce3dd56f2016-06-01 10:37:1110258// Regression test for https://crbug.com/615497.
bncd16676a2016-07-20 16:23:0110259TEST_F(HttpNetworkTransactionTest,
bnce3dd56f2016-06-01 10:37:1110260 DoNotParseAlternativeServiceHeaderOnInsecureRequest) {
bnce3dd56f2016-06-01 10:37:1110261 MockRead data_reads[] = {
10262 MockRead("HTTP/1.1 200 OK\r\n"),
bnc2df4b522016-07-08 18:17:4310263 MockRead(kAlternativeServiceHttpHeader),
bnce3dd56f2016-06-01 10:37:1110264 MockRead("\r\n"),
10265 MockRead("hello world"),
10266 MockRead(SYNCHRONOUS, OK),
10267 };
10268
10269 HttpRequestInfo request;
10270 request.method = "GET";
10271 request.url = GURL("http://www.example.org/");
10272 request.load_flags = 0;
10273
10274 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
10275 session_deps_.socket_factory->AddSocketDataProvider(&data);
10276
10277 TestCompletionCallback callback;
10278
10279 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1610280 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
bnce3dd56f2016-06-01 10:37:1110281
10282 url::SchemeHostPort test_server(request.url);
bnc525e175a2016-06-20 12:36:4010283 HttpServerProperties* http_server_properties =
10284 session->http_server_properties();
zhongyic4de03032017-05-19 04:07:3410285 EXPECT_TRUE(
10286 http_server_properties->GetAlternativeServiceInfos(test_server).empty());
bnce3dd56f2016-06-01 10:37:1110287
tfarina42834112016-09-22 13:38:2010288 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110289 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
10290 EXPECT_THAT(callback.WaitForResult(), IsOk());
bnce3dd56f2016-06-01 10:37:1110291
bnc691fda62016-08-12 00:43:1610292 const HttpResponseInfo* response = trans.GetResponseInfo();
bnce3dd56f2016-06-01 10:37:1110293 ASSERT_TRUE(response);
10294 ASSERT_TRUE(response->headers);
10295 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
10296 EXPECT_FALSE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5210297 EXPECT_FALSE(response->was_alpn_negotiated);
bnce3dd56f2016-06-01 10:37:1110298
10299 std::string response_data;
bnc691fda62016-08-12 00:43:1610300 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
bnce3dd56f2016-06-01 10:37:1110301 EXPECT_EQ("hello world", response_data);
10302
zhongyic4de03032017-05-19 04:07:3410303 EXPECT_TRUE(
10304 http_server_properties->GetAlternativeServiceInfos(test_server).empty());
bnce3dd56f2016-06-01 10:37:1110305}
10306
bnca86731e2017-04-17 12:31:2810307// HTTP/2 Alternative Services should be disabled by default.
bnc8bef8da22016-05-30 01:28:2510308// TODO(bnc): Remove when https://crbug.com/615413 is fixed.
bncd16676a2016-07-20 16:23:0110309TEST_F(HttpNetworkTransactionTest,
bnc8bef8da22016-05-30 01:28:2510310 DisableHTTP2AlternativeServicesWithDifferentHost) {
bnca86731e2017-04-17 12:31:2810311 session_deps_.enable_http2_alternative_service = false;
bncb26024382016-06-29 02:39:4510312
bnc8bef8da22016-05-30 01:28:2510313 HttpRequestInfo request;
10314 request.method = "GET";
bncb26024382016-06-29 02:39:4510315 request.url = GURL("https://www.example.org/");
bnc8bef8da22016-05-30 01:28:2510316 request.load_flags = 0;
10317
10318 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
10319 StaticSocketDataProvider first_data;
10320 first_data.set_connect_data(mock_connect);
10321 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
bncb26024382016-06-29 02:39:4510322 SSLSocketDataProvider ssl_http11(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3610323 ssl_http11.next_proto = kProtoHTTP11;
bncb26024382016-06-29 02:39:4510324 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_http11);
bnc8bef8da22016-05-30 01:28:2510325
10326 MockRead data_reads[] = {
10327 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello world"),
10328 MockRead(ASYNC, OK),
10329 };
10330 StaticSocketDataProvider second_data(data_reads, arraysize(data_reads), NULL,
10331 0);
10332 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
10333
10334 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
10335
bnc525e175a2016-06-20 12:36:4010336 HttpServerProperties* http_server_properties =
bnc8bef8da22016-05-30 01:28:2510337 session->http_server_properties();
bnc3472afd2016-11-17 15:27:2110338 AlternativeService alternative_service(kProtoHTTP2, "different.example.org",
10339 444);
bnc8bef8da22016-05-30 01:28:2510340 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:2110341 http_server_properties->SetHttp2AlternativeService(
bnc8bef8da22016-05-30 01:28:2510342 url::SchemeHostPort(request.url), alternative_service, expiration);
10343
bnc691fda62016-08-12 00:43:1610344 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
bnc8bef8da22016-05-30 01:28:2510345 TestCompletionCallback callback;
10346
tfarina42834112016-09-22 13:38:2010347 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
bnc8bef8da22016-05-30 01:28:2510348 // Alternative service is not used, request fails.
robpercival214763f2016-07-01 23:27:0110349 EXPECT_THAT(callback.GetResult(rv), IsError(ERR_CONNECTION_REFUSED));
bnc8bef8da22016-05-30 01:28:2510350}
10351
bnce3dd56f2016-06-01 10:37:1110352// Regression test for https://crbug.com/615497:
10353// Alternative Services should be disabled for http origin.
bncd16676a2016-07-20 16:23:0110354TEST_F(HttpNetworkTransactionTest,
bnce3dd56f2016-06-01 10:37:1110355 DisableAlternativeServicesForInsecureOrigin) {
bnce3dd56f2016-06-01 10:37:1110356 HttpRequestInfo request;
10357 request.method = "GET";
10358 request.url = GURL("http://www.example.org/");
10359 request.load_flags = 0;
10360
10361 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
10362 StaticSocketDataProvider first_data;
10363 first_data.set_connect_data(mock_connect);
10364 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
10365
10366 MockRead data_reads[] = {
10367 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello world"),
10368 MockRead(ASYNC, OK),
10369 };
10370 StaticSocketDataProvider second_data(data_reads, arraysize(data_reads), NULL,
10371 0);
10372 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
10373
10374 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
10375
bnc525e175a2016-06-20 12:36:4010376 HttpServerProperties* http_server_properties =
bnce3dd56f2016-06-01 10:37:1110377 session->http_server_properties();
bnc3472afd2016-11-17 15:27:2110378 AlternativeService alternative_service(kProtoHTTP2, "", 444);
bnce3dd56f2016-06-01 10:37:1110379 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:2110380 http_server_properties->SetHttp2AlternativeService(
bnce3dd56f2016-06-01 10:37:1110381 url::SchemeHostPort(request.url), alternative_service, expiration);
10382
bnc691fda62016-08-12 00:43:1610383 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
bnce3dd56f2016-06-01 10:37:1110384 TestCompletionCallback callback;
10385
tfarina42834112016-09-22 13:38:2010386 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
bnce3dd56f2016-06-01 10:37:1110387 // Alternative service is not used, request fails.
robpercival214763f2016-07-01 23:27:0110388 EXPECT_THAT(callback.GetResult(rv), IsError(ERR_CONNECTION_REFUSED));
bnce3dd56f2016-06-01 10:37:1110389}
10390
bncd16676a2016-07-20 16:23:0110391TEST_F(HttpNetworkTransactionTest, ClearAlternativeServices) {
bnc4f575852015-10-14 18:35:0810392 // Set an alternative service for origin.
danakj1fd259a02016-04-16 03:17:0910393 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc525e175a2016-06-20 12:36:4010394 HttpServerProperties* http_server_properties =
10395 session->http_server_properties();
bncb26024382016-06-29 02:39:4510396 url::SchemeHostPort test_server("https", "www.example.org", 443);
bnc3472afd2016-11-17 15:27:2110397 AlternativeService alternative_service(kProtoQUIC, "", 80);
bnc4f575852015-10-14 18:35:0810398 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:2110399 http_server_properties->SetQuicAlternativeService(
10400 test_server, alternative_service, expiration,
10401 session->params().quic_supported_versions);
zhongyic4de03032017-05-19 04:07:3410402 EXPECT_EQ(
10403 1u,
10404 http_server_properties->GetAlternativeServiceInfos(test_server).size());
bnc4f575852015-10-14 18:35:0810405
10406 // Send a clear header.
10407 MockRead data_reads[] = {
10408 MockRead("HTTP/1.1 200 OK\r\n"),
10409 MockRead("Alt-Svc: clear\r\n"),
10410 MockRead("\r\n"),
10411 MockRead("hello world"),
10412 MockRead(SYNCHRONOUS, OK),
10413 };
10414 StaticSocketDataProvider data(data_reads, arraysize(data_reads), nullptr, 0);
10415 session_deps_.socket_factory->AddSocketDataProvider(&data);
10416
bncb26024382016-06-29 02:39:4510417 SSLSocketDataProvider ssl(ASYNC, OK);
Bence Béky230ac612017-08-30 19:17:0810418 ssl.cert = ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem");
10419 ASSERT_TRUE(ssl.cert);
bncb26024382016-06-29 02:39:4510420 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
10421
bnc4f575852015-10-14 18:35:0810422 HttpRequestInfo request;
10423 request.method = "GET";
bncb26024382016-06-29 02:39:4510424 request.url = GURL("https://www.example.org/");
bnc4f575852015-10-14 18:35:0810425
10426 TestCompletionCallback callback;
10427
bnc691fda62016-08-12 00:43:1610428 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
bnc4f575852015-10-14 18:35:0810429
tfarina42834112016-09-22 13:38:2010430 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110431 EXPECT_THAT(callback.GetResult(rv), IsOk());
bnc4f575852015-10-14 18:35:0810432
bnc691fda62016-08-12 00:43:1610433 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5210434 ASSERT_TRUE(response);
10435 ASSERT_TRUE(response->headers);
bnc4f575852015-10-14 18:35:0810436 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
10437 EXPECT_FALSE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5210438 EXPECT_FALSE(response->was_alpn_negotiated);
bnc4f575852015-10-14 18:35:0810439
10440 std::string response_data;
bnc691fda62016-08-12 00:43:1610441 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
bnc4f575852015-10-14 18:35:0810442 EXPECT_EQ("hello world", response_data);
10443
zhongyic4de03032017-05-19 04:07:3410444 EXPECT_TRUE(
10445 http_server_properties->GetAlternativeServiceInfos(test_server).empty());
bnc4f575852015-10-14 18:35:0810446}
10447
bncd16676a2016-07-20 16:23:0110448TEST_F(HttpNetworkTransactionTest, HonorMultipleAlternativeServiceHeaders) {
bncc958faa2015-07-31 18:14:5210449 MockRead data_reads[] = {
10450 MockRead("HTTP/1.1 200 OK\r\n"),
bnc2df4b522016-07-08 18:17:4310451 MockRead("Alt-Svc: h2=\"www.example.com:443\","),
10452 MockRead("h2=\":1234\"\r\n\r\n"),
bncc958faa2015-07-31 18:14:5210453 MockRead("hello world"),
10454 MockRead(SYNCHRONOUS, OK),
10455 };
10456
10457 HttpRequestInfo request;
10458 request.method = "GET";
bncb26024382016-06-29 02:39:4510459 request.url = GURL("https://www.example.org/");
bncc958faa2015-07-31 18:14:5210460
10461 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
bncc958faa2015-07-31 18:14:5210462 session_deps_.socket_factory->AddSocketDataProvider(&data);
10463
bncb26024382016-06-29 02:39:4510464 SSLSocketDataProvider ssl(ASYNC, OK);
Bence Béky230ac612017-08-30 19:17:0810465 ssl.cert = ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem");
10466 ASSERT_TRUE(ssl.cert);
bncb26024382016-06-29 02:39:4510467 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
10468
bncc958faa2015-07-31 18:14:5210469 TestCompletionCallback callback;
10470
danakj1fd259a02016-04-16 03:17:0910471 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1610472 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
bncc958faa2015-07-31 18:14:5210473
tfarina42834112016-09-22 13:38:2010474 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110475 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
bncc958faa2015-07-31 18:14:5210476
bncb26024382016-06-29 02:39:4510477 url::SchemeHostPort test_server("https", "www.example.org", 443);
bnc525e175a2016-06-20 12:36:4010478 HttpServerProperties* http_server_properties =
10479 session->http_server_properties();
zhongyic4de03032017-05-19 04:07:3410480 EXPECT_TRUE(
10481 http_server_properties->GetAlternativeServiceInfos(test_server).empty());
bncc958faa2015-07-31 18:14:5210482
robpercival214763f2016-07-01 23:27:0110483 EXPECT_THAT(callback.WaitForResult(), IsOk());
bncc958faa2015-07-31 18:14:5210484
bnc691fda62016-08-12 00:43:1610485 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5210486 ASSERT_TRUE(response);
10487 ASSERT_TRUE(response->headers);
bncc958faa2015-07-31 18:14:5210488 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
10489 EXPECT_FALSE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5210490 EXPECT_FALSE(response->was_alpn_negotiated);
bncc958faa2015-07-31 18:14:5210491
10492 std::string response_data;
bnc691fda62016-08-12 00:43:1610493 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
bncc958faa2015-07-31 18:14:5210494 EXPECT_EQ("hello world", response_data);
10495
zhongyic4de03032017-05-19 04:07:3410496 AlternativeServiceInfoVector alternative_service_info_vector =
10497 http_server_properties->GetAlternativeServiceInfos(test_server);
10498 ASSERT_EQ(2u, alternative_service_info_vector.size());
10499
10500 AlternativeService alternative_service(kProtoHTTP2, "www.example.com", 443);
10501 EXPECT_EQ(alternative_service,
zhongyi422ce352017-06-09 23:28:5410502 alternative_service_info_vector[0].alternative_service());
zhongyic4de03032017-05-19 04:07:3410503 AlternativeService alternative_service_2(kProtoHTTP2, "www.example.org",
10504 1234);
10505 EXPECT_EQ(alternative_service_2,
zhongyi422ce352017-06-09 23:28:5410506 alternative_service_info_vector[1].alternative_service());
bncc958faa2015-07-31 18:14:5210507}
10508
bncd16676a2016-07-20 16:23:0110509TEST_F(HttpNetworkTransactionTest, IdentifyQuicBroken) {
zhongyi3d4a55e72016-04-22 20:36:4610510 url::SchemeHostPort server("https", "origin.example.org", 443);
zhongyi48704c182015-12-07 07:52:0210511 HostPortPair alternative("alternative.example.org", 443);
10512 std::string origin_url = "https://origin.example.org:443";
10513 std::string alternative_url = "https://alternative.example.org:443";
10514
10515 // Negotiate HTTP/1.1 with alternative.example.org.
10516 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3610517 ssl.next_proto = kProtoHTTP11;
zhongyi48704c182015-12-07 07:52:0210518 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
10519
10520 // HTTP/1.1 data for request.
10521 MockWrite http_writes[] = {
10522 MockWrite("GET / HTTP/1.1\r\n"
10523 "Host: alternative.example.org\r\n"
10524 "Connection: keep-alive\r\n\r\n"),
10525 };
10526
10527 MockRead http_reads[] = {
10528 MockRead("HTTP/1.1 200 OK\r\n"
10529 "Content-Type: text/html; charset=iso-8859-1\r\n"
10530 "Content-Length: 40\r\n\r\n"
10531 "first HTTP/1.1 response from alternative"),
10532 };
10533 StaticSocketDataProvider http_data(http_reads, arraysize(http_reads),
10534 http_writes, arraysize(http_writes));
10535 session_deps_.socket_factory->AddSocketDataProvider(&http_data);
10536
10537 StaticSocketDataProvider data_refused;
10538 data_refused.set_connect_data(MockConnect(ASYNC, ERR_CONNECTION_REFUSED));
10539 session_deps_.socket_factory->AddSocketDataProvider(&data_refused);
10540
zhongyi3d4a55e72016-04-22 20:36:4610541 // Set up a QUIC alternative service for server.
danakj1fd259a02016-04-16 03:17:0910542 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc525e175a2016-06-20 12:36:4010543 HttpServerProperties* http_server_properties =
zhongyi48704c182015-12-07 07:52:0210544 session->http_server_properties();
bnc3472afd2016-11-17 15:27:2110545 AlternativeService alternative_service(kProtoQUIC, alternative);
zhongyi48704c182015-12-07 07:52:0210546 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:2110547 http_server_properties->SetQuicAlternativeService(
10548 server, alternative_service, expiration,
10549 HttpNetworkSession::Params().quic_supported_versions);
zhongyi48704c182015-12-07 07:52:0210550 // Mark the QUIC alternative service as broken.
10551 http_server_properties->MarkAlternativeServiceBroken(alternative_service);
10552
zhongyi48704c182015-12-07 07:52:0210553 HttpRequestInfo request;
krasinc06a72a2016-12-21 03:42:4610554 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
zhongyi48704c182015-12-07 07:52:0210555 request.method = "GET";
10556 request.url = GURL(origin_url);
zhongyi48704c182015-12-07 07:52:0210557 TestCompletionCallback callback;
10558 NetErrorDetails details;
10559 EXPECT_FALSE(details.quic_broken);
10560
tfarina42834112016-09-22 13:38:2010561 trans.Start(&request, callback.callback(), NetLogWithSource());
bnc691fda62016-08-12 00:43:1610562 trans.PopulateNetErrorDetails(&details);
zhongyi48704c182015-12-07 07:52:0210563 EXPECT_TRUE(details.quic_broken);
10564}
10565
bncd16676a2016-07-20 16:23:0110566TEST_F(HttpNetworkTransactionTest, IdentifyQuicNotBroken) {
zhongyi3d4a55e72016-04-22 20:36:4610567 url::SchemeHostPort server("https", "origin.example.org", 443);
zhongyi48704c182015-12-07 07:52:0210568 HostPortPair alternative1("alternative1.example.org", 443);
10569 HostPortPair alternative2("alternative2.example.org", 443);
10570 std::string origin_url = "https://origin.example.org:443";
10571 std::string alternative_url1 = "https://alternative1.example.org:443";
10572 std::string alternative_url2 = "https://alternative2.example.org:443";
10573
10574 // Negotiate HTTP/1.1 with alternative1.example.org.
10575 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3610576 ssl.next_proto = kProtoHTTP11;
zhongyi48704c182015-12-07 07:52:0210577 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
10578
10579 // HTTP/1.1 data for request.
10580 MockWrite http_writes[] = {
10581 MockWrite("GET / HTTP/1.1\r\n"
10582 "Host: alternative1.example.org\r\n"
10583 "Connection: keep-alive\r\n\r\n"),
10584 };
10585
10586 MockRead http_reads[] = {
10587 MockRead("HTTP/1.1 200 OK\r\n"
10588 "Content-Type: text/html; charset=iso-8859-1\r\n"
10589 "Content-Length: 40\r\n\r\n"
10590 "first HTTP/1.1 response from alternative1"),
10591 };
10592 StaticSocketDataProvider http_data(http_reads, arraysize(http_reads),
10593 http_writes, arraysize(http_writes));
10594 session_deps_.socket_factory->AddSocketDataProvider(&http_data);
10595
10596 StaticSocketDataProvider data_refused;
10597 data_refused.set_connect_data(MockConnect(ASYNC, ERR_CONNECTION_REFUSED));
10598 session_deps_.socket_factory->AddSocketDataProvider(&data_refused);
10599
danakj1fd259a02016-04-16 03:17:0910600 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc525e175a2016-06-20 12:36:4010601 HttpServerProperties* http_server_properties =
zhongyi48704c182015-12-07 07:52:0210602 session->http_server_properties();
10603
zhongyi3d4a55e72016-04-22 20:36:4610604 // Set up two QUIC alternative services for server.
zhongyi48704c182015-12-07 07:52:0210605 AlternativeServiceInfoVector alternative_service_info_vector;
10606 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
10607
bnc3472afd2016-11-17 15:27:2110608 AlternativeService alternative_service1(kProtoQUIC, alternative1);
zhongyie537a002017-06-27 16:48:2110609 alternative_service_info_vector.push_back(
10610 AlternativeServiceInfo::CreateQuicAlternativeServiceInfo(
10611 alternative_service1, expiration,
10612 session->params().quic_supported_versions));
bnc3472afd2016-11-17 15:27:2110613 AlternativeService alternative_service2(kProtoQUIC, alternative2);
zhongyie537a002017-06-27 16:48:2110614 alternative_service_info_vector.push_back(
10615 AlternativeServiceInfo::CreateQuicAlternativeServiceInfo(
10616 alternative_service2, expiration,
10617 session->params().quic_supported_versions));
zhongyi48704c182015-12-07 07:52:0210618
10619 http_server_properties->SetAlternativeServices(
zhongyi3d4a55e72016-04-22 20:36:4610620 server, alternative_service_info_vector);
zhongyi48704c182015-12-07 07:52:0210621
10622 // Mark one of the QUIC alternative service as broken.
10623 http_server_properties->MarkAlternativeServiceBroken(alternative_service1);
zhongyic4de03032017-05-19 04:07:3410624 EXPECT_EQ(2u,
10625 http_server_properties->GetAlternativeServiceInfos(server).size());
zhongyi48704c182015-12-07 07:52:0210626
zhongyi48704c182015-12-07 07:52:0210627 HttpRequestInfo request;
krasinc06a72a2016-12-21 03:42:4610628 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
zhongyi48704c182015-12-07 07:52:0210629 request.method = "GET";
10630 request.url = GURL(origin_url);
zhongyi48704c182015-12-07 07:52:0210631 TestCompletionCallback callback;
10632 NetErrorDetails details;
10633 EXPECT_FALSE(details.quic_broken);
10634
tfarina42834112016-09-22 13:38:2010635 trans.Start(&request, callback.callback(), NetLogWithSource());
bnc691fda62016-08-12 00:43:1610636 trans.PopulateNetErrorDetails(&details);
zhongyi48704c182015-12-07 07:52:0210637 EXPECT_FALSE(details.quic_broken);
10638}
10639
bncd16676a2016-07-20 16:23:0110640TEST_F(HttpNetworkTransactionTest, MarkBrokenAlternateProtocolAndFallback) {
[email protected]564b4912010-03-09 16:30:4210641 HttpRequestInfo request;
10642 request.method = "GET";
bncb26024382016-06-29 02:39:4510643 request.url = GURL("https://www.example.org/");
[email protected]564b4912010-03-09 16:30:4210644
[email protected]d973e99a2012-02-17 21:02:3610645 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
[email protected]564b4912010-03-09 16:30:4210646 StaticSocketDataProvider first_data;
10647 first_data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:0710648 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
bncb26024382016-06-29 02:39:4510649 SSLSocketDataProvider ssl_http11(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3610650 ssl_http11.next_proto = kProtoHTTP11;
bncb26024382016-06-29 02:39:4510651 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_http11);
[email protected]564b4912010-03-09 16:30:4210652
10653 MockRead data_reads[] = {
10654 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
10655 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:0610656 MockRead(ASYNC, OK),
[email protected]564b4912010-03-09 16:30:4210657 };
10658 StaticSocketDataProvider second_data(
10659 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0710660 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
[email protected]564b4912010-03-09 16:30:4210661
danakj1fd259a02016-04-16 03:17:0910662 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]564b4912010-03-09 16:30:4210663
bnc525e175a2016-06-20 12:36:4010664 HttpServerProperties* http_server_properties =
[email protected]17291a022011-10-10 07:32:5310665 session->http_server_properties();
zhongyi3d4a55e72016-04-22 20:36:4610666 const url::SchemeHostPort server(request.url);
[email protected]3912662a32011-10-04 00:51:1110667 // Port must be < 1024, or the header will be ignored (since initial port was
10668 // port 80 (another restricted port).
zhongyie537a002017-06-27 16:48:2110669 // Port is ignored by MockConnect anyway.
10670 const AlternativeService alternative_service(kProtoHTTP2, "www.example.org",
10671 666);
bnc7dc7e1b42015-07-28 14:43:1210672 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:2110673 http_server_properties->SetHttp2AlternativeService(
10674 server, alternative_service, expiration);
[email protected]564b4912010-03-09 16:30:4210675
bnc691fda62016-08-12 00:43:1610676 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]49639fa2011-12-20 23:22:4110677 TestCompletionCallback callback;
[email protected]564b4912010-03-09 16:30:4210678
tfarina42834112016-09-22 13:38:2010679 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110680 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
10681 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]564b4912010-03-09 16:30:4210682
bnc691fda62016-08-12 00:43:1610683 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5210684 ASSERT_TRUE(response);
10685 ASSERT_TRUE(response->headers);
[email protected]564b4912010-03-09 16:30:4210686 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
10687
10688 std::string response_data;
bnc691fda62016-08-12 00:43:1610689 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
[email protected]564b4912010-03-09 16:30:4210690 EXPECT_EQ("hello world", response_data);
10691
zhongyic4de03032017-05-19 04:07:3410692 const AlternativeServiceInfoVector alternative_service_info_vector =
10693 http_server_properties->GetAlternativeServiceInfos(server);
10694 ASSERT_EQ(1u, alternative_service_info_vector.size());
10695 EXPECT_EQ(alternative_service,
zhongyi422ce352017-06-09 23:28:5410696 alternative_service_info_vector[0].alternative_service());
zhongyic4de03032017-05-19 04:07:3410697 EXPECT_TRUE(
10698 http_server_properties->IsAlternativeServiceBroken(alternative_service));
[email protected]564b4912010-03-09 16:30:4210699}
10700
bnc55ff9da2015-08-19 18:42:3510701// Ensure that we are not allowed to redirect traffic via an alternate protocol
10702// to an unrestricted (port >= 1024) when the original traffic was on a
10703// restricted port (port < 1024). Ensure that we can redirect in all other
10704// cases.
bncd16676a2016-07-20 16:23:0110705TEST_F(HttpNetworkTransactionTest, AlternateProtocolPortRestrictedBlocked) {
[email protected]3912662a32011-10-04 00:51:1110706 HttpRequestInfo restricted_port_request;
10707 restricted_port_request.method = "GET";
bncb26024382016-06-29 02:39:4510708 restricted_port_request.url = GURL("https://www.example.org:1023/");
[email protected]3912662a32011-10-04 00:51:1110709 restricted_port_request.load_flags = 0;
10710
[email protected]d973e99a2012-02-17 21:02:3610711 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
[email protected]3912662a32011-10-04 00:51:1110712 StaticSocketDataProvider first_data;
10713 first_data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:0710714 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
[email protected]3912662a32011-10-04 00:51:1110715
10716 MockRead data_reads[] = {
10717 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
10718 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:0610719 MockRead(ASYNC, OK),
[email protected]3912662a32011-10-04 00:51:1110720 };
10721 StaticSocketDataProvider second_data(
10722 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0710723 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
bncb26024382016-06-29 02:39:4510724 SSLSocketDataProvider ssl_http11(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3610725 ssl_http11.next_proto = kProtoHTTP11;
bncb26024382016-06-29 02:39:4510726 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_http11);
[email protected]3912662a32011-10-04 00:51:1110727
danakj1fd259a02016-04-16 03:17:0910728 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]3912662a32011-10-04 00:51:1110729
bnc525e175a2016-06-20 12:36:4010730 HttpServerProperties* http_server_properties =
[email protected]17291a022011-10-10 07:32:5310731 session->http_server_properties();
[email protected]3912662a32011-10-04 00:51:1110732 const int kUnrestrictedAlternatePort = 1024;
bnc3472afd2016-11-17 15:27:2110733 AlternativeService alternative_service(kProtoHTTP2, "www.example.org",
10734 kUnrestrictedAlternatePort);
bnc7dc7e1b42015-07-28 14:43:1210735 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:2110736 http_server_properties->SetHttp2AlternativeService(
zhongyi3d4a55e72016-04-22 20:36:4610737 url::SchemeHostPort(restricted_port_request.url), alternative_service,
rchdc7b9052016-03-17 20:51:5010738 expiration);
[email protected]3912662a32011-10-04 00:51:1110739
bnc691fda62016-08-12 00:43:1610740 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]49639fa2011-12-20 23:22:4110741 TestCompletionCallback callback;
[email protected]3912662a32011-10-04 00:51:1110742
tfarina42834112016-09-22 13:38:2010743 int rv = trans.Start(&restricted_port_request, callback.callback(),
10744 NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110745 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]3912662a32011-10-04 00:51:1110746 // Invalid change to unrestricted port should fail.
robpercival214763f2016-07-01 23:27:0110747 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_CONNECTION_REFUSED));
[email protected]c54c6962013-02-01 04:53:1910748}
[email protected]3912662a32011-10-04 00:51:1110749
bnc55ff9da2015-08-19 18:42:3510750// Ensure that we are allowed to redirect traffic via an alternate protocol to
10751// an unrestricted (port >= 1024) when the original traffic was on a restricted
10752// port (port < 1024) if we set |enable_user_alternate_protocol_ports|.
bncd16676a2016-07-20 16:23:0110753TEST_F(HttpNetworkTransactionTest, AlternateProtocolPortRestrictedPermitted) {
[email protected]bb88e1d32013-05-03 23:11:0710754 session_deps_.enable_user_alternate_protocol_ports = true;
[email protected]c54c6962013-02-01 04:53:1910755
10756 HttpRequestInfo restricted_port_request;
10757 restricted_port_request.method = "GET";
bncb26024382016-06-29 02:39:4510758 restricted_port_request.url = GURL("https://www.example.org:1023/");
[email protected]c54c6962013-02-01 04:53:1910759 restricted_port_request.load_flags = 0;
10760
10761 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
10762 StaticSocketDataProvider first_data;
10763 first_data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:0710764 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
[email protected]c54c6962013-02-01 04:53:1910765
10766 MockRead data_reads[] = {
10767 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
10768 MockRead("hello world"),
10769 MockRead(ASYNC, OK),
10770 };
10771 StaticSocketDataProvider second_data(
10772 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0710773 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
bncb26024382016-06-29 02:39:4510774 SSLSocketDataProvider ssl_http11(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3610775 ssl_http11.next_proto = kProtoHTTP11;
bncb26024382016-06-29 02:39:4510776 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_http11);
[email protected]c54c6962013-02-01 04:53:1910777
danakj1fd259a02016-04-16 03:17:0910778 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]c54c6962013-02-01 04:53:1910779
bnc525e175a2016-06-20 12:36:4010780 HttpServerProperties* http_server_properties =
[email protected]c54c6962013-02-01 04:53:1910781 session->http_server_properties();
10782 const int kUnrestrictedAlternatePort = 1024;
bnc3472afd2016-11-17 15:27:2110783 AlternativeService alternative_service(kProtoHTTP2, "www.example.org",
10784 kUnrestrictedAlternatePort);
bnc7dc7e1b42015-07-28 14:43:1210785 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:2110786 http_server_properties->SetHttp2AlternativeService(
zhongyi3d4a55e72016-04-22 20:36:4610787 url::SchemeHostPort(restricted_port_request.url), alternative_service,
rchdc7b9052016-03-17 20:51:5010788 expiration);
[email protected]c54c6962013-02-01 04:53:1910789
bnc691fda62016-08-12 00:43:1610790 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]c54c6962013-02-01 04:53:1910791 TestCompletionCallback callback;
10792
tfarina42834112016-09-22 13:38:2010793 EXPECT_EQ(ERR_IO_PENDING,
10794 trans.Start(&restricted_port_request, callback.callback(),
10795 NetLogWithSource()));
[email protected]c54c6962013-02-01 04:53:1910796 // Change to unrestricted port should succeed.
robpercival214763f2016-07-01 23:27:0110797 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]3912662a32011-10-04 00:51:1110798}
10799
bnc55ff9da2015-08-19 18:42:3510800// Ensure that we are not allowed to redirect traffic via an alternate protocol
10801// to an unrestricted (port >= 1024) when the original traffic was on a
10802// restricted port (port < 1024). Ensure that we can redirect in all other
10803// cases.
bncd16676a2016-07-20 16:23:0110804TEST_F(HttpNetworkTransactionTest, AlternateProtocolPortRestrictedAllowed) {
[email protected]3912662a32011-10-04 00:51:1110805 HttpRequestInfo restricted_port_request;
10806 restricted_port_request.method = "GET";
bncb26024382016-06-29 02:39:4510807 restricted_port_request.url = GURL("https://www.example.org:1023/");
[email protected]3912662a32011-10-04 00:51:1110808 restricted_port_request.load_flags = 0;
10809
[email protected]d973e99a2012-02-17 21:02:3610810 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
[email protected]3912662a32011-10-04 00:51:1110811 StaticSocketDataProvider first_data;
10812 first_data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:0710813 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
[email protected]3912662a32011-10-04 00:51:1110814
10815 MockRead data_reads[] = {
10816 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
10817 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:0610818 MockRead(ASYNC, OK),
[email protected]3912662a32011-10-04 00:51:1110819 };
10820 StaticSocketDataProvider second_data(
10821 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0710822 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
[email protected]3912662a32011-10-04 00:51:1110823
bncb26024382016-06-29 02:39:4510824 SSLSocketDataProvider ssl(ASYNC, OK);
10825 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
10826
danakj1fd259a02016-04-16 03:17:0910827 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]3912662a32011-10-04 00:51:1110828
bnc525e175a2016-06-20 12:36:4010829 HttpServerProperties* http_server_properties =
[email protected]17291a022011-10-10 07:32:5310830 session->http_server_properties();
[email protected]3912662a32011-10-04 00:51:1110831 const int kRestrictedAlternatePort = 80;
bnc3472afd2016-11-17 15:27:2110832 AlternativeService alternative_service(kProtoHTTP2, "www.example.org",
10833 kRestrictedAlternatePort);
bnc7dc7e1b42015-07-28 14:43:1210834 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:2110835 http_server_properties->SetHttp2AlternativeService(
zhongyi3d4a55e72016-04-22 20:36:4610836 url::SchemeHostPort(restricted_port_request.url), alternative_service,
rchdc7b9052016-03-17 20:51:5010837 expiration);
[email protected]3912662a32011-10-04 00:51:1110838
bnc691fda62016-08-12 00:43:1610839 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]49639fa2011-12-20 23:22:4110840 TestCompletionCallback callback;
[email protected]3912662a32011-10-04 00:51:1110841
tfarina42834112016-09-22 13:38:2010842 int rv = trans.Start(&restricted_port_request, callback.callback(),
10843 NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110844 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]3912662a32011-10-04 00:51:1110845 // Valid change to restricted port should pass.
robpercival214763f2016-07-01 23:27:0110846 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]3912662a32011-10-04 00:51:1110847}
10848
bnc55ff9da2015-08-19 18:42:3510849// Ensure that we are not allowed to redirect traffic via an alternate protocol
10850// to an unrestricted (port >= 1024) when the original traffic was on a
10851// restricted port (port < 1024). Ensure that we can redirect in all other
10852// cases.
bncd16676a2016-07-20 16:23:0110853TEST_F(HttpNetworkTransactionTest, AlternateProtocolPortUnrestrictedAllowed1) {
[email protected]3912662a32011-10-04 00:51:1110854 HttpRequestInfo unrestricted_port_request;
10855 unrestricted_port_request.method = "GET";
bncb26024382016-06-29 02:39:4510856 unrestricted_port_request.url = GURL("https://www.example.org:1024/");
[email protected]3912662a32011-10-04 00:51:1110857 unrestricted_port_request.load_flags = 0;
10858
[email protected]d973e99a2012-02-17 21:02:3610859 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
[email protected]3912662a32011-10-04 00:51:1110860 StaticSocketDataProvider first_data;
10861 first_data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:0710862 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
[email protected]3912662a32011-10-04 00:51:1110863
10864 MockRead data_reads[] = {
10865 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
10866 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:0610867 MockRead(ASYNC, OK),
[email protected]3912662a32011-10-04 00:51:1110868 };
10869 StaticSocketDataProvider second_data(
10870 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0710871 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
bncb26024382016-06-29 02:39:4510872 SSLSocketDataProvider ssl_http11(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3610873 ssl_http11.next_proto = kProtoHTTP11;
bncb26024382016-06-29 02:39:4510874 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_http11);
[email protected]3912662a32011-10-04 00:51:1110875
danakj1fd259a02016-04-16 03:17:0910876 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]3912662a32011-10-04 00:51:1110877
bnc525e175a2016-06-20 12:36:4010878 HttpServerProperties* http_server_properties =
[email protected]17291a022011-10-10 07:32:5310879 session->http_server_properties();
[email protected]3912662a32011-10-04 00:51:1110880 const int kRestrictedAlternatePort = 80;
bnc3472afd2016-11-17 15:27:2110881 AlternativeService alternative_service(kProtoHTTP2, "www.example.org",
10882 kRestrictedAlternatePort);
bnc7dc7e1b42015-07-28 14:43:1210883 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:2110884 http_server_properties->SetHttp2AlternativeService(
zhongyi3d4a55e72016-04-22 20:36:4610885 url::SchemeHostPort(unrestricted_port_request.url), alternative_service,
rchdc7b9052016-03-17 20:51:5010886 expiration);
[email protected]3912662a32011-10-04 00:51:1110887
bnc691fda62016-08-12 00:43:1610888 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]49639fa2011-12-20 23:22:4110889 TestCompletionCallback callback;
[email protected]3912662a32011-10-04 00:51:1110890
bnc691fda62016-08-12 00:43:1610891 int rv = trans.Start(&unrestricted_port_request, callback.callback(),
tfarina42834112016-09-22 13:38:2010892 NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110893 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]3912662a32011-10-04 00:51:1110894 // Valid change to restricted port should pass.
robpercival214763f2016-07-01 23:27:0110895 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]3912662a32011-10-04 00:51:1110896}
10897
bnc55ff9da2015-08-19 18:42:3510898// Ensure that we are not allowed to redirect traffic via an alternate protocol
10899// to an unrestricted (port >= 1024) when the original traffic was on a
10900// restricted port (port < 1024). Ensure that we can redirect in all other
10901// cases.
bncd16676a2016-07-20 16:23:0110902TEST_F(HttpNetworkTransactionTest, AlternateProtocolPortUnrestrictedAllowed2) {
[email protected]3912662a32011-10-04 00:51:1110903 HttpRequestInfo unrestricted_port_request;
10904 unrestricted_port_request.method = "GET";
bncb26024382016-06-29 02:39:4510905 unrestricted_port_request.url = GURL("https://www.example.org:1024/");
[email protected]3912662a32011-10-04 00:51:1110906 unrestricted_port_request.load_flags = 0;
10907
[email protected]d973e99a2012-02-17 21:02:3610908 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
[email protected]3912662a32011-10-04 00:51:1110909 StaticSocketDataProvider first_data;
10910 first_data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:0710911 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
[email protected]3912662a32011-10-04 00:51:1110912
10913 MockRead data_reads[] = {
10914 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
10915 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:0610916 MockRead(ASYNC, OK),
[email protected]3912662a32011-10-04 00:51:1110917 };
10918 StaticSocketDataProvider second_data(
10919 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0710920 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
[email protected]3912662a32011-10-04 00:51:1110921
bncb26024382016-06-29 02:39:4510922 SSLSocketDataProvider ssl(ASYNC, OK);
10923 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
10924
danakj1fd259a02016-04-16 03:17:0910925 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]3912662a32011-10-04 00:51:1110926
bnc525e175a2016-06-20 12:36:4010927 HttpServerProperties* http_server_properties =
[email protected]17291a022011-10-10 07:32:5310928 session->http_server_properties();
bnc0bbb02622015-07-23 10:06:2210929 const int kUnrestrictedAlternatePort = 1025;
bnc3472afd2016-11-17 15:27:2110930 AlternativeService alternative_service(kProtoHTTP2, "www.example.org",
10931 kUnrestrictedAlternatePort);
bnc7dc7e1b42015-07-28 14:43:1210932 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:2110933 http_server_properties->SetHttp2AlternativeService(
zhongyi3d4a55e72016-04-22 20:36:4610934 url::SchemeHostPort(unrestricted_port_request.url), alternative_service,
rchdc7b9052016-03-17 20:51:5010935 expiration);
[email protected]3912662a32011-10-04 00:51:1110936
bnc691fda62016-08-12 00:43:1610937 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]49639fa2011-12-20 23:22:4110938 TestCompletionCallback callback;
[email protected]3912662a32011-10-04 00:51:1110939
bnc691fda62016-08-12 00:43:1610940 int rv = trans.Start(&unrestricted_port_request, callback.callback(),
tfarina42834112016-09-22 13:38:2010941 NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110942 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]3912662a32011-10-04 00:51:1110943 // Valid change to an unrestricted port should pass.
robpercival214763f2016-07-01 23:27:0110944 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]3912662a32011-10-04 00:51:1110945}
10946
bnc55ff9da2015-08-19 18:42:3510947// Ensure that we are not allowed to redirect traffic via an alternate protocol
10948// to an unsafe port, and that we resume the second HttpStreamFactoryImpl::Job
10949// once the alternate protocol request fails.
bncd16676a2016-07-20 16:23:0110950TEST_F(HttpNetworkTransactionTest, AlternateProtocolUnsafeBlocked) {
[email protected]eb6234e2012-01-19 01:50:0210951 HttpRequestInfo request;
10952 request.method = "GET";
bncce36dca22015-04-21 22:11:2310953 request.url = GURL("http://www.example.org/");
[email protected]eb6234e2012-01-19 01:50:0210954
10955 // The alternate protocol request will error out before we attempt to connect,
10956 // so only the standard HTTP request will try to connect.
10957 MockRead data_reads[] = {
10958 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
10959 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:0610960 MockRead(ASYNC, OK),
[email protected]eb6234e2012-01-19 01:50:0210961 };
10962 StaticSocketDataProvider data(
10963 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0710964 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]eb6234e2012-01-19 01:50:0210965
danakj1fd259a02016-04-16 03:17:0910966 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]eb6234e2012-01-19 01:50:0210967
bnc525e175a2016-06-20 12:36:4010968 HttpServerProperties* http_server_properties =
[email protected]eb6234e2012-01-19 01:50:0210969 session->http_server_properties();
10970 const int kUnsafePort = 7;
bnc3472afd2016-11-17 15:27:2110971 AlternativeService alternative_service(kProtoHTTP2, "www.example.org",
10972 kUnsafePort);
bnc7dc7e1b42015-07-28 14:43:1210973 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:2110974 http_server_properties->SetHttp2AlternativeService(
zhongyi3d4a55e72016-04-22 20:36:4610975 url::SchemeHostPort(request.url), alternative_service, expiration);
[email protected]eb6234e2012-01-19 01:50:0210976
bnc691fda62016-08-12 00:43:1610977 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]eb6234e2012-01-19 01:50:0210978 TestCompletionCallback callback;
10979
tfarina42834112016-09-22 13:38:2010980 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110981 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]eb6234e2012-01-19 01:50:0210982 // The HTTP request should succeed.
robpercival214763f2016-07-01 23:27:0110983 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]eb6234e2012-01-19 01:50:0210984
bnc691fda62016-08-12 00:43:1610985 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5210986 ASSERT_TRUE(response);
10987 ASSERT_TRUE(response->headers);
[email protected]eb6234e2012-01-19 01:50:0210988 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
10989
10990 std::string response_data;
bnc691fda62016-08-12 00:43:1610991 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
[email protected]eb6234e2012-01-19 01:50:0210992 EXPECT_EQ("hello world", response_data);
10993}
10994
bncd16676a2016-07-20 16:23:0110995TEST_F(HttpNetworkTransactionTest, UseAlternateProtocolForNpnSpdy) {
[email protected]2ff8b312010-04-26 22:20:5410996 HttpRequestInfo request;
10997 request.method = "GET";
bncb26024382016-06-29 02:39:4510998 request.url = GURL("https://www.example.org/");
[email protected]2ff8b312010-04-26 22:20:5410999
11000 MockRead data_reads[] = {
bncc958faa2015-07-31 18:14:5211001 MockRead("HTTP/1.1 200 OK\r\n"),
bnc2df4b522016-07-08 18:17:4311002 MockRead(kAlternativeServiceHttpHeader),
bncc958faa2015-07-31 18:14:5211003 MockRead("\r\n"),
11004 MockRead("hello world"),
11005 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
11006 MockRead(ASYNC, OK)};
[email protected]2ff8b312010-04-26 22:20:5411007
11008 StaticSocketDataProvider first_transaction(
11009 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0711010 session_deps_.socket_factory->AddSocketDataProvider(&first_transaction);
bncb26024382016-06-29 02:39:4511011 SSLSocketDataProvider ssl_http11(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3611012 ssl_http11.next_proto = kProtoHTTP11;
bncb26024382016-06-29 02:39:4511013 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_http11);
[email protected]2ff8b312010-04-26 22:20:5411014
bnc032658ba2016-09-26 18:17:1511015 AddSSLSocketData();
[email protected]2ff8b312010-04-26 22:20:5411016
bncdf80d44fd2016-07-15 20:27:4111017 SpdySerializedFrame req(
bncb26024382016-06-29 02:39:4511018 spdy_util_.ConstructSpdyGet("https://www.example.org/", 1, LOWEST));
bncdf80d44fd2016-07-15 20:27:4111019 MockWrite spdy_writes[] = {CreateMockWrite(req, 0)};
[email protected]2ff8b312010-04-26 22:20:5411020
bnc42331402016-07-25 13:36:1511021 SpdySerializedFrame resp(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
bncdf80d44fd2016-07-15 20:27:4111022 SpdySerializedFrame data(spdy_util_.ConstructSpdyDataFrame(1, true));
[email protected]2ff8b312010-04-26 22:20:5411023 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:4111024 CreateMockRead(resp, 1), CreateMockRead(data, 2), MockRead(ASYNC, 0, 3),
[email protected]2ff8b312010-04-26 22:20:5411025 };
11026
rch8e6c6c42015-05-01 14:05:1311027 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
11028 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:0711029 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]2ff8b312010-04-26 22:20:5411030
[email protected]d973e99a2012-02-17 21:02:3611031 MockConnect never_finishing_connect(SYNCHRONOUS, ERR_IO_PENDING);
[email protected]2d6728692011-03-12 01:39:5511032 StaticSocketDataProvider hanging_non_alternate_protocol_socket(
11033 NULL, 0, NULL, 0);
11034 hanging_non_alternate_protocol_socket.set_connect_data(
11035 never_finishing_connect);
[email protected]bb88e1d32013-05-03 23:11:0711036 session_deps_.socket_factory->AddSocketDataProvider(
[email protected]2d6728692011-03-12 01:39:5511037 &hanging_non_alternate_protocol_socket);
11038
[email protected]49639fa2011-12-20 23:22:4111039 TestCompletionCallback callback;
[email protected]2ff8b312010-04-26 22:20:5411040
danakj1fd259a02016-04-16 03:17:0911041 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc87dcefc2017-05-25 12:47:5811042 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:1911043 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]2ff8b312010-04-26 22:20:5411044
tfarina42834112016-09-22 13:38:2011045 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0111046 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
11047 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]2ff8b312010-04-26 22:20:5411048
11049 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5211050 ASSERT_TRUE(response);
11051 ASSERT_TRUE(response->headers);
[email protected]2ff8b312010-04-26 22:20:5411052 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
11053
11054 std::string response_data;
robpercival214763f2016-07-01 23:27:0111055 ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
[email protected]2ff8b312010-04-26 22:20:5411056 EXPECT_EQ("hello world", response_data);
11057
bnc87dcefc2017-05-25 12:47:5811058 trans =
Jeremy Roman0579ed62017-08-29 15:56:1911059 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]2ff8b312010-04-26 22:20:5411060
tfarina42834112016-09-22 13:38:2011061 rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0111062 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
11063 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]2ff8b312010-04-26 22:20:5411064
11065 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5211066 ASSERT_TRUE(response);
11067 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0211068 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]65041fa2010-05-21 06:56:5311069 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5211070 EXPECT_TRUE(response->was_alpn_negotiated);
[email protected]2ff8b312010-04-26 22:20:5411071
robpercival214763f2016-07-01 23:27:0111072 ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
[email protected]2ff8b312010-04-26 22:20:5411073 EXPECT_EQ("hello!", response_data);
[email protected]2ff8b312010-04-26 22:20:5411074}
11075
bncd16676a2016-07-20 16:23:0111076TEST_F(HttpNetworkTransactionTest, AlternateProtocolWithSpdyLateBinding) {
[email protected]2d6728692011-03-12 01:39:5511077 HttpRequestInfo request;
11078 request.method = "GET";
bncb26024382016-06-29 02:39:4511079 request.url = GURL("https://www.example.org/");
[email protected]2d6728692011-03-12 01:39:5511080
bncb26024382016-06-29 02:39:4511081 // First transaction receives Alt-Svc header over HTTP/1.1.
[email protected]2d6728692011-03-12 01:39:5511082 MockRead data_reads[] = {
bncc958faa2015-07-31 18:14:5211083 MockRead("HTTP/1.1 200 OK\r\n"),
bnc2df4b522016-07-08 18:17:4311084 MockRead(kAlternativeServiceHttpHeader),
bncc958faa2015-07-31 18:14:5211085 MockRead("\r\n"),
11086 MockRead("hello world"),
11087 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
11088 MockRead(ASYNC, OK),
[email protected]2d6728692011-03-12 01:39:5511089 };
11090
bncb26024382016-06-29 02:39:4511091 StaticSocketDataProvider http11_data(data_reads, arraysize(data_reads), NULL,
11092 0);
11093 session_deps_.socket_factory->AddSocketDataProvider(&http11_data);
[email protected]2d6728692011-03-12 01:39:5511094
bncb26024382016-06-29 02:39:4511095 SSLSocketDataProvider ssl_http11(ASYNC, OK);
Bence Béky230ac612017-08-30 19:17:0811096 ssl_http11.cert = ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem");
11097 ASSERT_TRUE(ssl_http11.cert);
bncb26024382016-06-29 02:39:4511098 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_http11);
11099
11100 // Second transaction starts an alternative and a non-alternative Job.
11101 // Both sockets hang.
[email protected]d973e99a2012-02-17 21:02:3611102 MockConnect never_finishing_connect(SYNCHRONOUS, ERR_IO_PENDING);
mmenkecc2298e2015-12-07 18:20:1811103 StaticSocketDataProvider hanging_socket1(NULL, 0, NULL, 0);
11104 hanging_socket1.set_connect_data(never_finishing_connect);
mmenkecc2298e2015-12-07 18:20:1811105 session_deps_.socket_factory->AddSocketDataProvider(&hanging_socket1);
11106
11107 StaticSocketDataProvider hanging_socket2(NULL, 0, NULL, 0);
11108 hanging_socket2.set_connect_data(never_finishing_connect);
11109 session_deps_.socket_factory->AddSocketDataProvider(&hanging_socket2);
[email protected]2d6728692011-03-12 01:39:5511110
bncb26024382016-06-29 02:39:4511111 // Third transaction starts an alternative and a non-alternative job.
11112 // The non-alternative job hangs, but the alternative one succeeds.
11113 // The second transaction, still pending, binds to this socket.
bncdf80d44fd2016-07-15 20:27:4111114 SpdySerializedFrame req1(
bncb26024382016-06-29 02:39:4511115 spdy_util_.ConstructSpdyGet("https://www.example.org/", 1, LOWEST));
bncdf80d44fd2016-07-15 20:27:4111116 SpdySerializedFrame req2(
bncb26024382016-06-29 02:39:4511117 spdy_util_.ConstructSpdyGet("https://www.example.org/", 3, LOWEST));
[email protected]2d6728692011-03-12 01:39:5511118 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:4111119 CreateMockWrite(req1, 0), CreateMockWrite(req2, 1),
[email protected]2d6728692011-03-12 01:39:5511120 };
bnc42331402016-07-25 13:36:1511121 SpdySerializedFrame resp1(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
bncdf80d44fd2016-07-15 20:27:4111122 SpdySerializedFrame data1(spdy_util_.ConstructSpdyDataFrame(1, true));
bnc42331402016-07-25 13:36:1511123 SpdySerializedFrame resp2(spdy_util_.ConstructSpdyGetReply(NULL, 0, 3));
bncdf80d44fd2016-07-15 20:27:4111124 SpdySerializedFrame data2(spdy_util_.ConstructSpdyDataFrame(3, true));
[email protected]2d6728692011-03-12 01:39:5511125 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:4111126 CreateMockRead(resp1, 2), CreateMockRead(data1, 3),
11127 CreateMockRead(resp2, 4), CreateMockRead(data2, 5),
rch8e6c6c42015-05-01 14:05:1311128 MockRead(ASYNC, 0, 6),
[email protected]2d6728692011-03-12 01:39:5511129 };
11130
rch8e6c6c42015-05-01 14:05:1311131 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
11132 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:0711133 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]2d6728692011-03-12 01:39:5511134
bnc032658ba2016-09-26 18:17:1511135 AddSSLSocketData();
bncb26024382016-06-29 02:39:4511136
mmenkecc2298e2015-12-07 18:20:1811137 StaticSocketDataProvider hanging_socket3(NULL, 0, NULL, 0);
11138 hanging_socket3.set_connect_data(never_finishing_connect);
11139 session_deps_.socket_factory->AddSocketDataProvider(&hanging_socket3);
[email protected]2d6728692011-03-12 01:39:5511140
danakj1fd259a02016-04-16 03:17:0911141 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]49639fa2011-12-20 23:22:4111142 TestCompletionCallback callback1;
[email protected]90499482013-06-01 00:39:5011143 HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
[email protected]2d6728692011-03-12 01:39:5511144
tfarina42834112016-09-22 13:38:2011145 int rv = trans1.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0111146 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
11147 EXPECT_THAT(callback1.WaitForResult(), IsOk());
[email protected]2d6728692011-03-12 01:39:5511148
11149 const HttpResponseInfo* response = trans1.GetResponseInfo();
wezca1070932016-05-26 20:30:5211150 ASSERT_TRUE(response);
11151 ASSERT_TRUE(response->headers);
[email protected]2d6728692011-03-12 01:39:5511152 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
11153
11154 std::string response_data;
robpercival214763f2016-07-01 23:27:0111155 ASSERT_THAT(ReadTransaction(&trans1, &response_data), IsOk());
[email protected]2d6728692011-03-12 01:39:5511156 EXPECT_EQ("hello world", response_data);
11157
[email protected]49639fa2011-12-20 23:22:4111158 TestCompletionCallback callback2;
[email protected]90499482013-06-01 00:39:5011159 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:2011160 rv = trans2.Start(&request, callback2.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0111161 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2d6728692011-03-12 01:39:5511162
[email protected]49639fa2011-12-20 23:22:4111163 TestCompletionCallback callback3;
[email protected]90499482013-06-01 00:39:5011164 HttpNetworkTransaction trans3(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:2011165 rv = trans3.Start(&request, callback3.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0111166 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2d6728692011-03-12 01:39:5511167
robpercival214763f2016-07-01 23:27:0111168 EXPECT_THAT(callback2.WaitForResult(), IsOk());
11169 EXPECT_THAT(callback3.WaitForResult(), IsOk());
[email protected]2d6728692011-03-12 01:39:5511170
11171 response = trans2.GetResponseInfo();
wezca1070932016-05-26 20:30:5211172 ASSERT_TRUE(response);
11173 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0211174 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]2d6728692011-03-12 01:39:5511175 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5211176 EXPECT_TRUE(response->was_alpn_negotiated);
robpercival214763f2016-07-01 23:27:0111177 ASSERT_THAT(ReadTransaction(&trans2, &response_data), IsOk());
[email protected]2d6728692011-03-12 01:39:5511178 EXPECT_EQ("hello!", response_data);
11179
11180 response = trans3.GetResponseInfo();
wezca1070932016-05-26 20:30:5211181 ASSERT_TRUE(response);
11182 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0211183 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]2d6728692011-03-12 01:39:5511184 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5211185 EXPECT_TRUE(response->was_alpn_negotiated);
robpercival214763f2016-07-01 23:27:0111186 ASSERT_THAT(ReadTransaction(&trans3, &response_data), IsOk());
[email protected]2d6728692011-03-12 01:39:5511187 EXPECT_EQ("hello!", response_data);
[email protected]2d6728692011-03-12 01:39:5511188}
11189
bncd16676a2016-07-20 16:23:0111190TEST_F(HttpNetworkTransactionTest, StallAlternativeServiceForNpnSpdy) {
[email protected]2d6728692011-03-12 01:39:5511191 HttpRequestInfo request;
11192 request.method = "GET";
bncb26024382016-06-29 02:39:4511193 request.url = GURL("https://www.example.org/");
[email protected]2d6728692011-03-12 01:39:5511194
11195 MockRead data_reads[] = {
bncc958faa2015-07-31 18:14:5211196 MockRead("HTTP/1.1 200 OK\r\n"),
bnc2df4b522016-07-08 18:17:4311197 MockRead(kAlternativeServiceHttpHeader),
bncc958faa2015-07-31 18:14:5211198 MockRead("\r\n"),
11199 MockRead("hello world"),
11200 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
11201 MockRead(ASYNC, OK),
[email protected]2d6728692011-03-12 01:39:5511202 };
11203
11204 StaticSocketDataProvider first_transaction(
11205 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0711206 session_deps_.socket_factory->AddSocketDataProvider(&first_transaction);
[email protected]2d6728692011-03-12 01:39:5511207
[email protected]8ddf8322012-02-23 18:08:0611208 SSLSocketDataProvider ssl(ASYNC, OK);
Bence Béky230ac612017-08-30 19:17:0811209 ssl.cert = ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem");
11210 ASSERT_TRUE(ssl.cert);
[email protected]bb88e1d32013-05-03 23:11:0711211 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]2d6728692011-03-12 01:39:5511212
[email protected]d973e99a2012-02-17 21:02:3611213 MockConnect never_finishing_connect(SYNCHRONOUS, ERR_IO_PENDING);
[email protected]2d6728692011-03-12 01:39:5511214 StaticSocketDataProvider hanging_alternate_protocol_socket(
11215 NULL, 0, NULL, 0);
11216 hanging_alternate_protocol_socket.set_connect_data(
11217 never_finishing_connect);
[email protected]bb88e1d32013-05-03 23:11:0711218 session_deps_.socket_factory->AddSocketDataProvider(
[email protected]2d6728692011-03-12 01:39:5511219 &hanging_alternate_protocol_socket);
11220
bncb26024382016-06-29 02:39:4511221 // 2nd request is just a copy of the first one, over HTTP/1.1 again.
mmenkecc2298e2015-12-07 18:20:1811222 StaticSocketDataProvider second_transaction(data_reads, arraysize(data_reads),
11223 NULL, 0);
11224 session_deps_.socket_factory->AddSocketDataProvider(&second_transaction);
bncb26024382016-06-29 02:39:4511225 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]2d6728692011-03-12 01:39:5511226
[email protected]49639fa2011-12-20 23:22:4111227 TestCompletionCallback callback;
[email protected]2d6728692011-03-12 01:39:5511228
danakj1fd259a02016-04-16 03:17:0911229 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc87dcefc2017-05-25 12:47:5811230 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:1911231 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]2d6728692011-03-12 01:39:5511232
tfarina42834112016-09-22 13:38:2011233 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0111234 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
11235 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]2d6728692011-03-12 01:39:5511236
11237 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5211238 ASSERT_TRUE(response);
11239 ASSERT_TRUE(response->headers);
[email protected]2d6728692011-03-12 01:39:5511240 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
11241
11242 std::string response_data;
robpercival214763f2016-07-01 23:27:0111243 ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
[email protected]2d6728692011-03-12 01:39:5511244 EXPECT_EQ("hello world", response_data);
11245
bnc87dcefc2017-05-25 12:47:5811246 trans =
Jeremy Roman0579ed62017-08-29 15:56:1911247 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]2d6728692011-03-12 01:39:5511248
tfarina42834112016-09-22 13:38:2011249 rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0111250 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
11251 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]2d6728692011-03-12 01:39:5511252
11253 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5211254 ASSERT_TRUE(response);
11255 ASSERT_TRUE(response->headers);
[email protected]2d6728692011-03-12 01:39:5511256 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
11257 EXPECT_FALSE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5211258 EXPECT_FALSE(response->was_alpn_negotiated);
[email protected]2d6728692011-03-12 01:39:5511259
robpercival214763f2016-07-01 23:27:0111260 ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
[email protected]2d6728692011-03-12 01:39:5511261 EXPECT_EQ("hello world", response_data);
[email protected]2d6728692011-03-12 01:39:5511262}
11263
[email protected]631f1322010-04-30 17:59:1111264class CapturingProxyResolver : public ProxyResolver {
11265 public:
sammce90c9212015-05-27 23:43:3511266 CapturingProxyResolver() {}
dchengb03027d2014-10-21 12:00:2011267 ~CapturingProxyResolver() override {}
[email protected]631f1322010-04-30 17:59:1111268
dchengb03027d2014-10-21 12:00:2011269 int GetProxyForURL(const GURL& url,
11270 ProxyInfo* results,
11271 const CompletionCallback& callback,
maksim.sisov7e157262016-10-20 11:19:5511272 std::unique_ptr<Request>* request,
tfarina42834112016-09-22 13:38:2011273 const NetLogWithSource& net_log) override {
[email protected]fae7669f2010-08-02 21:49:4011274 ProxyServer proxy_server(ProxyServer::SCHEME_HTTP,
11275 HostPortPair("myproxy", 80));
[email protected]d911f1b2010-05-05 22:39:4211276 results->UseProxyServer(proxy_server);
[email protected]631f1322010-04-30 17:59:1111277 resolved_.push_back(url);
[email protected]d911f1b2010-05-05 22:39:4211278 return OK;
[email protected]631f1322010-04-30 17:59:1111279 }
11280
[email protected]24476402010-07-20 20:55:1711281 const std::vector<GURL>& resolved() const { return resolved_; }
11282
11283 private:
[email protected]631f1322010-04-30 17:59:1111284 std::vector<GURL> resolved_;
11285
11286 DISALLOW_COPY_AND_ASSIGN(CapturingProxyResolver);
11287};
11288
sammce64b2362015-04-29 03:50:2311289class CapturingProxyResolverFactory : public ProxyResolverFactory {
11290 public:
11291 explicit CapturingProxyResolverFactory(CapturingProxyResolver* resolver)
11292 : ProxyResolverFactory(false), resolver_(resolver) {}
11293
11294 int CreateProxyResolver(
11295 const scoped_refptr<ProxyResolverScriptData>& pac_script,
danakj1fd259a02016-04-16 03:17:0911296 std::unique_ptr<ProxyResolver>* resolver,
sammce64b2362015-04-29 03:50:2311297 const net::CompletionCallback& callback,
danakj1fd259a02016-04-16 03:17:0911298 std::unique_ptr<Request>* request) override {
Jeremy Roman0579ed62017-08-29 15:56:1911299 *resolver = std::make_unique<ForwardingProxyResolver>(resolver_);
sammce64b2362015-04-29 03:50:2311300 return OK;
11301 }
11302
11303 private:
11304 ProxyResolver* resolver_;
11305};
11306
bnc2e884782016-08-11 19:45:1911307// Test that proxy is resolved using the origin url,
11308// regardless of the alternative server.
11309TEST_F(HttpNetworkTransactionTest, UseOriginNotAlternativeForProxy) {
11310 // Configure proxy to bypass www.example.org, which is the origin URL.
11311 ProxyConfig proxy_config;
11312 proxy_config.proxy_rules().ParseFromString("myproxy:70");
11313 proxy_config.proxy_rules().bypass_rules.AddRuleFromString("www.example.org");
11314 auto proxy_config_service =
Jeremy Roman0579ed62017-08-29 15:56:1911315 std::make_unique<ProxyConfigServiceFixed>(proxy_config);
bnc2e884782016-08-11 19:45:1911316
11317 CapturingProxyResolver capturing_proxy_resolver;
Jeremy Roman0579ed62017-08-29 15:56:1911318 auto proxy_resolver_factory = std::make_unique<CapturingProxyResolverFactory>(
bnc2e884782016-08-11 19:45:1911319 &capturing_proxy_resolver);
11320
11321 TestNetLog net_log;
11322
Jeremy Roman0579ed62017-08-29 15:56:1911323 session_deps_.proxy_service = std::make_unique<ProxyService>(
bnc2e884782016-08-11 19:45:1911324 std::move(proxy_config_service), std::move(proxy_resolver_factory),
11325 &net_log);
11326
11327 session_deps_.net_log = &net_log;
11328
11329 // Configure alternative service with a hostname that is not bypassed by the
11330 // proxy.
11331 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
11332 HttpServerProperties* http_server_properties =
11333 session->http_server_properties();
11334 url::SchemeHostPort server("https", "www.example.org", 443);
11335 HostPortPair alternative("www.example.com", 443);
bnc3472afd2016-11-17 15:27:2111336 AlternativeService alternative_service(kProtoHTTP2, alternative);
bnc2e884782016-08-11 19:45:1911337 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:2111338 http_server_properties->SetHttp2AlternativeService(
11339 server, alternative_service, expiration);
bnc2e884782016-08-11 19:45:1911340
11341 // Non-alternative job should hang.
11342 MockConnect never_finishing_connect(SYNCHRONOUS, ERR_IO_PENDING);
11343 StaticSocketDataProvider hanging_alternate_protocol_socket(nullptr, 0,
11344 nullptr, 0);
11345 hanging_alternate_protocol_socket.set_connect_data(never_finishing_connect);
11346 session_deps_.socket_factory->AddSocketDataProvider(
11347 &hanging_alternate_protocol_socket);
11348
bnc032658ba2016-09-26 18:17:1511349 AddSSLSocketData();
bnc2e884782016-08-11 19:45:1911350
11351 HttpRequestInfo request;
11352 request.method = "GET";
11353 request.url = GURL("https://www.example.org/");
11354 request.load_flags = 0;
11355
11356 SpdySerializedFrame req(
11357 spdy_util_.ConstructSpdyGet("https://www.example.org/", 1, LOWEST));
11358
11359 MockWrite spdy_writes[] = {CreateMockWrite(req, 0)};
11360
11361 SpdySerializedFrame resp(spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
11362 SpdySerializedFrame data(spdy_util_.ConstructSpdyDataFrame(1, true));
11363 MockRead spdy_reads[] = {
11364 CreateMockRead(resp, 1), CreateMockRead(data, 2), MockRead(ASYNC, 0, 3),
11365 };
11366
11367 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
11368 arraysize(spdy_writes));
11369 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
11370
11371 TestCompletionCallback callback;
11372
11373 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
11374
tfarina42834112016-09-22 13:38:2011375 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
bnc2e884782016-08-11 19:45:1911376 EXPECT_THAT(callback.GetResult(rv), IsOk());
11377
11378 const HttpResponseInfo* response = trans.GetResponseInfo();
11379 ASSERT_TRUE(response);
11380 ASSERT_TRUE(response->headers);
11381 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
11382 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5211383 EXPECT_TRUE(response->was_alpn_negotiated);
bnc2e884782016-08-11 19:45:1911384
11385 std::string response_data;
11386 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
11387 EXPECT_EQ("hello!", response_data);
11388
11389 // Origin host bypasses proxy, no resolution should have happened.
11390 ASSERT_TRUE(capturing_proxy_resolver.resolved().empty());
11391}
11392
bncd16676a2016-07-20 16:23:0111393TEST_F(HttpNetworkTransactionTest, UseAlternativeServiceForTunneledNpnSpdy) {
[email protected]631f1322010-04-30 17:59:1111394 ProxyConfig proxy_config;
[email protected]d911f1b2010-05-05 22:39:4211395 proxy_config.set_auto_detect(true);
11396 proxy_config.set_pac_url(GURL("http://fooproxyurl"));
[email protected]2227c692010-05-04 15:36:1111397
sammc5dd160c2015-04-02 02:43:1311398 CapturingProxyResolver capturing_proxy_resolver;
Jeremy Roman0579ed62017-08-29 15:56:1911399 session_deps_.proxy_service = std::make_unique<ProxyService>(
11400 std::make_unique<ProxyConfigServiceFixed>(proxy_config),
11401 std::make_unique<CapturingProxyResolverFactory>(
bnc87dcefc2017-05-25 12:47:5811402 &capturing_proxy_resolver),
11403 nullptr);
vishal.b62985ca92015-04-17 08:45:5111404 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:0711405 session_deps_.net_log = &net_log;
[email protected]631f1322010-04-30 17:59:1111406
11407 HttpRequestInfo request;
11408 request.method = "GET";
bncb26024382016-06-29 02:39:4511409 request.url = GURL("https://www.example.org/");
[email protected]631f1322010-04-30 17:59:1111410
11411 MockRead data_reads[] = {
bncc958faa2015-07-31 18:14:5211412 MockRead("HTTP/1.1 200 OK\r\n"),
bnc2df4b522016-07-08 18:17:4311413 MockRead(kAlternativeServiceHttpHeader),
bncc958faa2015-07-31 18:14:5211414 MockRead("\r\n"),
11415 MockRead("hello world"),
11416 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
11417 MockRead(ASYNC, OK),
[email protected]631f1322010-04-30 17:59:1111418 };
11419
11420 StaticSocketDataProvider first_transaction(
11421 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0711422 session_deps_.socket_factory->AddSocketDataProvider(&first_transaction);
bncb26024382016-06-29 02:39:4511423 SSLSocketDataProvider ssl_http11(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3611424 ssl_http11.next_proto = kProtoHTTP11;
bncb26024382016-06-29 02:39:4511425 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_http11);
[email protected]631f1322010-04-30 17:59:1111426
bnc032658ba2016-09-26 18:17:1511427 AddSSLSocketData();
[email protected]631f1322010-04-30 17:59:1111428
bncdf80d44fd2016-07-15 20:27:4111429 SpdySerializedFrame req(
bncb26024382016-06-29 02:39:4511430 spdy_util_.ConstructSpdyGet("https://www.example.org/", 1, LOWEST));
[email protected]631f1322010-04-30 17:59:1111431 MockWrite spdy_writes[] = {
rch8e6c6c42015-05-01 14:05:1311432 MockWrite(ASYNC, 0,
bnc8bef8da22016-05-30 01:28:2511433 "CONNECT www.example.org:443 HTTP/1.1\r\n"
11434 "Host: www.example.org:443\r\n"
rch8e6c6c42015-05-01 14:05:1311435 "Proxy-Connection: keep-alive\r\n\r\n"),
bncdf80d44fd2016-07-15 20:27:4111436 CreateMockWrite(req, 2),
[email protected]631f1322010-04-30 17:59:1111437 };
11438
[email protected]d911f1b2010-05-05 22:39:4211439 const char kCONNECTResponse[] = "HTTP/1.1 200 Connected\r\n\r\n";
11440
bnc42331402016-07-25 13:36:1511441 SpdySerializedFrame resp(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
bncdf80d44fd2016-07-15 20:27:4111442 SpdySerializedFrame data(spdy_util_.ConstructSpdyDataFrame(1, true));
[email protected]631f1322010-04-30 17:59:1111443 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:4111444 MockRead(ASYNC, 1, kCONNECTResponse), CreateMockRead(resp, 3),
11445 CreateMockRead(data, 4), MockRead(SYNCHRONOUS, ERR_IO_PENDING, 5),
[email protected]631f1322010-04-30 17:59:1111446 };
11447
rch8e6c6c42015-05-01 14:05:1311448 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
11449 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:0711450 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]631f1322010-04-30 17:59:1111451
[email protected]d973e99a2012-02-17 21:02:3611452 MockConnect never_finishing_connect(SYNCHRONOUS, ERR_IO_PENDING);
[email protected]2d6728692011-03-12 01:39:5511453 StaticSocketDataProvider hanging_non_alternate_protocol_socket(
11454 NULL, 0, NULL, 0);
11455 hanging_non_alternate_protocol_socket.set_connect_data(
11456 never_finishing_connect);
[email protected]bb88e1d32013-05-03 23:11:0711457 session_deps_.socket_factory->AddSocketDataProvider(
[email protected]2d6728692011-03-12 01:39:5511458 &hanging_non_alternate_protocol_socket);
11459
[email protected]49639fa2011-12-20 23:22:4111460 TestCompletionCallback callback;
[email protected]631f1322010-04-30 17:59:1111461
danakj1fd259a02016-04-16 03:17:0911462 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc87dcefc2017-05-25 12:47:5811463 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:1911464 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]631f1322010-04-30 17:59:1111465
tfarina42834112016-09-22 13:38:2011466 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
mmenkea2dcd3bf2016-08-16 21:49:4111467 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
11468 EXPECT_THAT(callback.WaitForResult(), IsOk());
11469
11470 const HttpResponseInfo* response = trans->GetResponseInfo();
11471 ASSERT_TRUE(response);
11472 ASSERT_TRUE(response->headers);
11473 EXPECT_EQ("HTTP/0.9 200 OK", response->headers->GetStatusLine());
11474 EXPECT_FALSE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5211475 EXPECT_TRUE(response->was_alpn_negotiated);
mmenkea2dcd3bf2016-08-16 21:49:4111476
11477 std::string response_data;
11478 ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
11479 EXPECT_EQ("hello world", response_data);
[email protected]631f1322010-04-30 17:59:1111480
bnc87dcefc2017-05-25 12:47:5811481 trans =
Jeremy Roman0579ed62017-08-29 15:56:1911482 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]631f1322010-04-30 17:59:1111483
tfarina42834112016-09-22 13:38:2011484 rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0111485 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
11486 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]631f1322010-04-30 17:59:1111487
mmenkea2dcd3bf2016-08-16 21:49:4111488 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5211489 ASSERT_TRUE(response);
11490 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0211491 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]65041fa2010-05-21 06:56:5311492 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5211493 EXPECT_TRUE(response->was_alpn_negotiated);
[email protected]631f1322010-04-30 17:59:1111494
robpercival214763f2016-07-01 23:27:0111495 ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
[email protected]631f1322010-04-30 17:59:1111496 EXPECT_EQ("hello!", response_data);
bncb26024382016-06-29 02:39:4511497 ASSERT_EQ(2u, capturing_proxy_resolver.resolved().size());
11498 EXPECT_EQ("https://www.example.org/",
sammc5dd160c2015-04-02 02:43:1311499 capturing_proxy_resolver.resolved()[0].spec());
bncce36dca22015-04-21 22:11:2311500 EXPECT_EQ("https://www.example.org/",
sammc5dd160c2015-04-02 02:43:1311501 capturing_proxy_resolver.resolved()[1].spec());
[email protected]631f1322010-04-30 17:59:1111502
[email protected]029c83b62013-01-24 05:28:2011503 LoadTimingInfo load_timing_info;
11504 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
11505 TestLoadTimingNotReusedWithPac(load_timing_info,
11506 CONNECT_TIMING_HAS_SSL_TIMES);
[email protected]631f1322010-04-30 17:59:1111507}
[email protected]631f1322010-04-30 17:59:1111508
bncd16676a2016-07-20 16:23:0111509TEST_F(HttpNetworkTransactionTest,
bnc1c196c6e2016-05-28 13:51:4811510 UseAlternativeServiceForNpnSpdyWithExistingSpdySession) {
[email protected]2ff8b312010-04-26 22:20:5411511 HttpRequestInfo request;
11512 request.method = "GET";
bncb26024382016-06-29 02:39:4511513 request.url = GURL("https://www.example.org/");
[email protected]2ff8b312010-04-26 22:20:5411514
11515 MockRead data_reads[] = {
bncc958faa2015-07-31 18:14:5211516 MockRead("HTTP/1.1 200 OK\r\n"),
bnc2df4b522016-07-08 18:17:4311517 MockRead(kAlternativeServiceHttpHeader),
bncc958faa2015-07-31 18:14:5211518 MockRead("\r\n"),
11519 MockRead("hello world"),
11520 MockRead(ASYNC, OK),
[email protected]2ff8b312010-04-26 22:20:5411521 };
11522
11523 StaticSocketDataProvider first_transaction(
11524 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0711525 session_deps_.socket_factory->AddSocketDataProvider(&first_transaction);
bncb26024382016-06-29 02:39:4511526 SSLSocketDataProvider ssl_http11(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3611527 ssl_http11.next_proto = kProtoHTTP11;
bncb26024382016-06-29 02:39:4511528 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_http11);
[email protected]2ff8b312010-04-26 22:20:5411529
bnc032658ba2016-09-26 18:17:1511530 AddSSLSocketData();
[email protected]2ff8b312010-04-26 22:20:5411531
bncdf80d44fd2016-07-15 20:27:4111532 SpdySerializedFrame req(
bncb26024382016-06-29 02:39:4511533 spdy_util_.ConstructSpdyGet("https://www.example.org/", 1, LOWEST));
bncdf80d44fd2016-07-15 20:27:4111534 MockWrite spdy_writes[] = {CreateMockWrite(req, 0)};
[email protected]2ff8b312010-04-26 22:20:5411535
bnc42331402016-07-25 13:36:1511536 SpdySerializedFrame resp(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
bncdf80d44fd2016-07-15 20:27:4111537 SpdySerializedFrame data(spdy_util_.ConstructSpdyDataFrame(1, true));
[email protected]2ff8b312010-04-26 22:20:5411538 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:4111539 CreateMockRead(resp, 1), CreateMockRead(data, 2), MockRead(ASYNC, 0, 3),
[email protected]2ff8b312010-04-26 22:20:5411540 };
11541
rch8e6c6c42015-05-01 14:05:1311542 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
11543 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:0711544 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]2ff8b312010-04-26 22:20:5411545
[email protected]83039bb2011-12-09 18:43:5511546 TestCompletionCallback callback;
[email protected]2ff8b312010-04-26 22:20:5411547
danakj1fd259a02016-04-16 03:17:0911548 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]2ff8b312010-04-26 22:20:5411549
bnc87dcefc2017-05-25 12:47:5811550 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:1911551 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]2ff8b312010-04-26 22:20:5411552
tfarina42834112016-09-22 13:38:2011553 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0111554 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
11555 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]2ff8b312010-04-26 22:20:5411556
11557 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5211558 ASSERT_TRUE(response);
11559 ASSERT_TRUE(response->headers);
[email protected]2ff8b312010-04-26 22:20:5411560 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
11561
11562 std::string response_data;
robpercival214763f2016-07-01 23:27:0111563 ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
[email protected]2ff8b312010-04-26 22:20:5411564 EXPECT_EQ("hello world", response_data);
11565
11566 // Set up an initial SpdySession in the pool to reuse.
bnc8bef8da22016-05-30 01:28:2511567 HostPortPair host_port_pair("www.example.org", 443);
[email protected]e6d017652013-05-17 18:01:4011568 SpdySessionKey key(host_port_pair, ProxyServer::Direct(),
[email protected]314b03992014-04-01 01:28:5311569 PRIVACY_MODE_DISABLED);
[email protected]795cbf82013-07-22 09:37:2711570 base::WeakPtr<SpdySession> spdy_session =
Bence Béky0ef1556e2017-06-30 19:52:5211571 CreateSpdySession(session.get(), key, NetLogWithSource());
[email protected]02b0c342010-09-25 21:09:3811572
bnc87dcefc2017-05-25 12:47:5811573 trans =
Jeremy Roman0579ed62017-08-29 15:56:1911574 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]2ff8b312010-04-26 22:20:5411575
tfarina42834112016-09-22 13:38:2011576 rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0111577 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
11578 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]2ff8b312010-04-26 22:20:5411579
11580 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5211581 ASSERT_TRUE(response);
11582 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0211583 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]65041fa2010-05-21 06:56:5311584 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5211585 EXPECT_TRUE(response->was_alpn_negotiated);
[email protected]2ff8b312010-04-26 22:20:5411586
robpercival214763f2016-07-01 23:27:0111587 ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
[email protected]2ff8b312010-04-26 22:20:5411588 EXPECT_EQ("hello!", response_data);
[email protected]564b4912010-03-09 16:30:4211589}
11590
[email protected]044de0642010-06-17 10:42:1511591// GenerateAuthToken is a mighty big test.
11592// It tests all permutation of GenerateAuthToken behavior:
11593// - Synchronous and Asynchronous completion.
11594// - OK or error on completion.
11595// - Direct connection, non-authenticating proxy, and authenticating proxy.
11596// - HTTP or HTTPS backend (to include proxy tunneling).
11597// - Non-authenticating and authenticating backend.
11598//
[email protected]fe3b7dc2012-02-03 19:52:0911599// In all, there are 44 reasonable permuations (for example, if there are
[email protected]044de0642010-06-17 10:42:1511600// problems generating an auth token for an authenticating proxy, we don't
11601// need to test all permutations of the backend server).
11602//
11603// The test proceeds by going over each of the configuration cases, and
11604// potentially running up to three rounds in each of the tests. The TestConfig
11605// specifies both the configuration for the test as well as the expectations
11606// for the results.
bncd16676a2016-07-20 16:23:0111607TEST_F(HttpNetworkTransactionTest, GenerateAuthToken) {
[email protected]0b0bf032010-09-21 18:08:5011608 static const char kServer[] = "http://www.example.com";
11609 static const char kSecureServer[] = "https://www.example.com";
11610 static const char kProxy[] = "myproxy:70";
[email protected]044de0642010-06-17 10:42:1511611
11612 enum AuthTiming {
11613 AUTH_NONE,
11614 AUTH_SYNC,
11615 AUTH_ASYNC,
11616 };
11617
11618 const MockWrite kGet(
11619 "GET / HTTP/1.1\r\n"
11620 "Host: www.example.com\r\n"
11621 "Connection: keep-alive\r\n\r\n");
11622 const MockWrite kGetProxy(
11623 "GET http://www.example.com/ HTTP/1.1\r\n"
11624 "Host: www.example.com\r\n"
11625 "Proxy-Connection: keep-alive\r\n\r\n");
11626 const MockWrite kGetAuth(
11627 "GET / HTTP/1.1\r\n"
11628 "Host: www.example.com\r\n"
11629 "Connection: keep-alive\r\n"
11630 "Authorization: auth_token\r\n\r\n");
11631 const MockWrite kGetProxyAuth(
11632 "GET http://www.example.com/ HTTP/1.1\r\n"
11633 "Host: www.example.com\r\n"
11634 "Proxy-Connection: keep-alive\r\n"
11635 "Proxy-Authorization: auth_token\r\n\r\n");
11636 const MockWrite kGetAuthThroughProxy(
11637 "GET http://www.example.com/ HTTP/1.1\r\n"
11638 "Host: www.example.com\r\n"
11639 "Proxy-Connection: keep-alive\r\n"
11640 "Authorization: auth_token\r\n\r\n");
11641 const MockWrite kGetAuthWithProxyAuth(
11642 "GET http://www.example.com/ HTTP/1.1\r\n"
11643 "Host: www.example.com\r\n"
11644 "Proxy-Connection: keep-alive\r\n"
11645 "Proxy-Authorization: auth_token\r\n"
11646 "Authorization: auth_token\r\n\r\n");
11647 const MockWrite kConnect(
11648 "CONNECT www.example.com:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:1711649 "Host: www.example.com:443\r\n"
[email protected]044de0642010-06-17 10:42:1511650 "Proxy-Connection: keep-alive\r\n\r\n");
11651 const MockWrite kConnectProxyAuth(
11652 "CONNECT www.example.com:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:1711653 "Host: www.example.com:443\r\n"
[email protected]044de0642010-06-17 10:42:1511654 "Proxy-Connection: keep-alive\r\n"
11655 "Proxy-Authorization: auth_token\r\n\r\n");
11656
11657 const MockRead kSuccess(
11658 "HTTP/1.1 200 OK\r\n"
11659 "Content-Type: text/html; charset=iso-8859-1\r\n"
11660 "Content-Length: 3\r\n\r\n"
11661 "Yes");
11662 const MockRead kFailure(
11663 "Should not be called.");
11664 const MockRead kServerChallenge(
11665 "HTTP/1.1 401 Unauthorized\r\n"
11666 "WWW-Authenticate: Mock realm=server\r\n"
11667 "Content-Type: text/html; charset=iso-8859-1\r\n"
11668 "Content-Length: 14\r\n\r\n"
11669 "Unauthorized\r\n");
11670 const MockRead kProxyChallenge(
11671 "HTTP/1.1 407 Unauthorized\r\n"
11672 "Proxy-Authenticate: Mock realm=proxy\r\n"
11673 "Proxy-Connection: close\r\n"
11674 "Content-Type: text/html; charset=iso-8859-1\r\n"
11675 "Content-Length: 14\r\n\r\n"
11676 "Unauthorized\r\n");
11677 const MockRead kProxyConnected(
11678 "HTTP/1.1 200 Connection Established\r\n\r\n");
11679
11680 // NOTE(cbentzel): I wanted TestReadWriteRound to be a simple struct with
11681 // no constructors, but the C++ compiler on Windows warns about
11682 // unspecified data in compound literals. So, moved to using constructors,
11683 // and TestRound's created with the default constructor should not be used.
11684 struct TestRound {
11685 TestRound()
11686 : expected_rv(ERR_UNEXPECTED),
11687 extra_write(NULL),
11688 extra_read(NULL) {
11689 }
11690 TestRound(const MockWrite& write_arg, const MockRead& read_arg,
11691 int expected_rv_arg)
11692 : write(write_arg),
11693 read(read_arg),
11694 expected_rv(expected_rv_arg),
11695 extra_write(NULL),
11696 extra_read(NULL) {
11697 }
11698 TestRound(const MockWrite& write_arg, const MockRead& read_arg,
11699 int expected_rv_arg, const MockWrite* extra_write_arg,
[email protected]f871ee152012-07-27 19:02:0111700 const MockRead* extra_read_arg)
[email protected]044de0642010-06-17 10:42:1511701 : write(write_arg),
11702 read(read_arg),
11703 expected_rv(expected_rv_arg),
11704 extra_write(extra_write_arg),
11705 extra_read(extra_read_arg) {
11706 }
11707 MockWrite write;
11708 MockRead read;
11709 int expected_rv;
11710 const MockWrite* extra_write;
11711 const MockRead* extra_read;
11712 };
11713
11714 static const int kNoSSL = 500;
11715
11716 struct TestConfig {
asanka463ca4262016-11-16 02:34:3111717 int line_number;
thestig9d3bb0c2015-01-24 00:49:5111718 const char* const proxy_url;
[email protected]044de0642010-06-17 10:42:1511719 AuthTiming proxy_auth_timing;
asanka463ca4262016-11-16 02:34:3111720 int first_generate_proxy_token_rv;
thestig9d3bb0c2015-01-24 00:49:5111721 const char* const server_url;
[email protected]044de0642010-06-17 10:42:1511722 AuthTiming server_auth_timing;
asanka463ca4262016-11-16 02:34:3111723 int first_generate_server_token_rv;
[email protected]044de0642010-06-17 10:42:1511724 int num_auth_rounds;
11725 int first_ssl_round;
asankae2257db2016-10-11 22:03:1611726 TestRound rounds[4];
[email protected]044de0642010-06-17 10:42:1511727 } test_configs[] = {
asankac93076192016-10-03 15:46:0211728 // Non-authenticating HTTP server with a direct connection.
asanka463ca4262016-11-16 02:34:3111729 {__LINE__,
11730 nullptr,
asankac93076192016-10-03 15:46:0211731 AUTH_NONE,
11732 OK,
11733 kServer,
11734 AUTH_NONE,
11735 OK,
11736 1,
11737 kNoSSL,
11738 {TestRound(kGet, kSuccess, OK)}},
11739 // Authenticating HTTP server with a direct connection.
asanka463ca4262016-11-16 02:34:3111740 {__LINE__,
11741 nullptr,
asankac93076192016-10-03 15:46:0211742 AUTH_NONE,
11743 OK,
11744 kServer,
11745 AUTH_SYNC,
11746 OK,
11747 2,
11748 kNoSSL,
11749 {TestRound(kGet, kServerChallenge, OK),
[email protected]044de0642010-06-17 10:42:1511750 TestRound(kGetAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3111751 {__LINE__,
11752 nullptr,
asankac93076192016-10-03 15:46:0211753 AUTH_NONE,
11754 OK,
11755 kServer,
11756 AUTH_SYNC,
11757 ERR_INVALID_AUTH_CREDENTIALS,
asankae2257db2016-10-11 22:03:1611758 3,
11759 kNoSSL,
11760 {TestRound(kGet, kServerChallenge, OK),
11761 TestRound(kGet, kServerChallenge, OK),
11762 TestRound(kGetAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3111763 {__LINE__,
11764 nullptr,
asankae2257db2016-10-11 22:03:1611765 AUTH_NONE,
11766 OK,
11767 kServer,
11768 AUTH_SYNC,
11769 ERR_UNSUPPORTED_AUTH_SCHEME,
11770 2,
11771 kNoSSL,
11772 {TestRound(kGet, kServerChallenge, OK), TestRound(kGet, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3111773 {__LINE__,
11774 nullptr,
asankae2257db2016-10-11 22:03:1611775 AUTH_NONE,
11776 OK,
11777 kServer,
11778 AUTH_SYNC,
11779 ERR_UNDOCUMENTED_SECURITY_LIBRARY_STATUS,
11780 2,
11781 kNoSSL,
11782 {TestRound(kGet, kServerChallenge, OK), TestRound(kGet, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3111783 {__LINE__,
11784 kProxy,
asankae2257db2016-10-11 22:03:1611785 AUTH_SYNC,
11786 ERR_FAILED,
11787 kServer,
11788 AUTH_NONE,
11789 OK,
11790 2,
11791 kNoSSL,
11792 {TestRound(kGetProxy, kProxyChallenge, OK),
11793 TestRound(kGetProxy, kFailure, ERR_FAILED)}},
asanka463ca4262016-11-16 02:34:3111794 {__LINE__,
11795 kProxy,
asankae2257db2016-10-11 22:03:1611796 AUTH_ASYNC,
11797 ERR_FAILED,
11798 kServer,
11799 AUTH_NONE,
11800 OK,
11801 2,
11802 kNoSSL,
11803 {TestRound(kGetProxy, kProxyChallenge, OK),
11804 TestRound(kGetProxy, kFailure, ERR_FAILED)}},
asanka463ca4262016-11-16 02:34:3111805 {__LINE__,
11806 nullptr,
asankae2257db2016-10-11 22:03:1611807 AUTH_NONE,
11808 OK,
11809 kServer,
11810 AUTH_SYNC,
11811 ERR_FAILED,
asankac93076192016-10-03 15:46:0211812 2,
11813 kNoSSL,
11814 {TestRound(kGet, kServerChallenge, OK),
asankae2257db2016-10-11 22:03:1611815 TestRound(kGet, kFailure, ERR_FAILED)}},
asanka463ca4262016-11-16 02:34:3111816 {__LINE__,
11817 nullptr,
asankae2257db2016-10-11 22:03:1611818 AUTH_NONE,
11819 OK,
11820 kServer,
11821 AUTH_ASYNC,
11822 ERR_FAILED,
11823 2,
11824 kNoSSL,
11825 {TestRound(kGet, kServerChallenge, OK),
11826 TestRound(kGet, kFailure, ERR_FAILED)}},
asanka463ca4262016-11-16 02:34:3111827 {__LINE__,
11828 nullptr,
asankac93076192016-10-03 15:46:0211829 AUTH_NONE,
11830 OK,
11831 kServer,
11832 AUTH_ASYNC,
11833 OK,
11834 2,
11835 kNoSSL,
11836 {TestRound(kGet, kServerChallenge, OK),
[email protected]044de0642010-06-17 10:42:1511837 TestRound(kGetAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3111838 {__LINE__,
11839 nullptr,
asankac93076192016-10-03 15:46:0211840 AUTH_NONE,
11841 OK,
11842 kServer,
11843 AUTH_ASYNC,
11844 ERR_INVALID_AUTH_CREDENTIALS,
asankae2257db2016-10-11 22:03:1611845 3,
asankac93076192016-10-03 15:46:0211846 kNoSSL,
11847 {TestRound(kGet, kServerChallenge, OK),
asankae2257db2016-10-11 22:03:1611848 // The second round uses a HttpAuthHandlerMock that always succeeds.
11849 TestRound(kGet, kServerChallenge, OK),
11850 TestRound(kGetAuth, kSuccess, OK)}},
asankac93076192016-10-03 15:46:0211851 // Non-authenticating HTTP server through a non-authenticating proxy.
asanka463ca4262016-11-16 02:34:3111852 {__LINE__,
11853 kProxy,
asankac93076192016-10-03 15:46:0211854 AUTH_NONE,
11855 OK,
11856 kServer,
11857 AUTH_NONE,
11858 OK,
11859 1,
11860 kNoSSL,
11861 {TestRound(kGetProxy, kSuccess, OK)}},
11862 // Authenticating HTTP server through a non-authenticating proxy.
asanka463ca4262016-11-16 02:34:3111863 {__LINE__,
11864 kProxy,
asankac93076192016-10-03 15:46:0211865 AUTH_NONE,
11866 OK,
11867 kServer,
11868 AUTH_SYNC,
11869 OK,
11870 2,
11871 kNoSSL,
11872 {TestRound(kGetProxy, kServerChallenge, OK),
[email protected]044de0642010-06-17 10:42:1511873 TestRound(kGetAuthThroughProxy, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3111874 {__LINE__,
11875 kProxy,
asankac93076192016-10-03 15:46:0211876 AUTH_NONE,
11877 OK,
11878 kServer,
11879 AUTH_SYNC,
11880 ERR_INVALID_AUTH_CREDENTIALS,
asankae2257db2016-10-11 22:03:1611881 3,
asankac93076192016-10-03 15:46:0211882 kNoSSL,
11883 {TestRound(kGetProxy, kServerChallenge, OK),
asankae2257db2016-10-11 22:03:1611884 TestRound(kGetProxy, kServerChallenge, OK),
11885 TestRound(kGetAuthThroughProxy, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3111886 {__LINE__,
11887 kProxy,
asankac93076192016-10-03 15:46:0211888 AUTH_NONE,
11889 OK,
11890 kServer,
11891 AUTH_ASYNC,
11892 OK,
11893 2,
11894 kNoSSL,
11895 {TestRound(kGetProxy, kServerChallenge, OK),
[email protected]044de0642010-06-17 10:42:1511896 TestRound(kGetAuthThroughProxy, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3111897 {__LINE__,
11898 kProxy,
asankac93076192016-10-03 15:46:0211899 AUTH_NONE,
11900 OK,
11901 kServer,
11902 AUTH_ASYNC,
11903 ERR_INVALID_AUTH_CREDENTIALS,
11904 2,
11905 kNoSSL,
11906 {TestRound(kGetProxy, kServerChallenge, OK),
asankae2257db2016-10-11 22:03:1611907 TestRound(kGetProxy, kSuccess, OK)}},
asankac93076192016-10-03 15:46:0211908 // Non-authenticating HTTP server through an authenticating proxy.
asanka463ca4262016-11-16 02:34:3111909 {__LINE__,
11910 kProxy,
asankac93076192016-10-03 15:46:0211911 AUTH_SYNC,
11912 OK,
11913 kServer,
11914 AUTH_NONE,
11915 OK,
11916 2,
11917 kNoSSL,
11918 {TestRound(kGetProxy, kProxyChallenge, OK),
[email protected]044de0642010-06-17 10:42:1511919 TestRound(kGetProxyAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3111920 {__LINE__,
11921 kProxy,
asankac93076192016-10-03 15:46:0211922 AUTH_SYNC,
11923 ERR_INVALID_AUTH_CREDENTIALS,
11924 kServer,
11925 AUTH_NONE,
11926 OK,
11927 2,
11928 kNoSSL,
11929 {TestRound(kGetProxy, kProxyChallenge, OK),
asankae2257db2016-10-11 22:03:1611930 TestRound(kGetProxy, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3111931 {__LINE__,
11932 kProxy,
asankac93076192016-10-03 15:46:0211933 AUTH_ASYNC,
11934 OK,
11935 kServer,
11936 AUTH_NONE,
11937 OK,
11938 2,
11939 kNoSSL,
11940 {TestRound(kGetProxy, kProxyChallenge, OK),
[email protected]044de0642010-06-17 10:42:1511941 TestRound(kGetProxyAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3111942 {__LINE__,
11943 kProxy,
asankac93076192016-10-03 15:46:0211944 AUTH_ASYNC,
11945 ERR_INVALID_AUTH_CREDENTIALS,
11946 kServer,
11947 AUTH_NONE,
11948 OK,
11949 2,
11950 kNoSSL,
11951 {TestRound(kGetProxy, kProxyChallenge, OK),
asankae2257db2016-10-11 22:03:1611952 TestRound(kGetProxy, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3111953 {__LINE__,
11954 kProxy,
11955 AUTH_ASYNC,
11956 ERR_INVALID_AUTH_CREDENTIALS,
11957 kServer,
11958 AUTH_NONE,
11959 OK,
11960 3,
11961 kNoSSL,
11962 {TestRound(kGetProxy, kProxyChallenge, OK),
11963 TestRound(kGetProxy, kProxyChallenge, OK),
11964 TestRound(kGetProxyAuth, kSuccess, OK)}},
asankac93076192016-10-03 15:46:0211965 // Authenticating HTTP server through an authenticating proxy.
asanka463ca4262016-11-16 02:34:3111966 {__LINE__,
11967 kProxy,
asankac93076192016-10-03 15:46:0211968 AUTH_SYNC,
11969 OK,
11970 kServer,
11971 AUTH_SYNC,
11972 OK,
11973 3,
11974 kNoSSL,
11975 {TestRound(kGetProxy, kProxyChallenge, OK),
[email protected]044de0642010-06-17 10:42:1511976 TestRound(kGetProxyAuth, kServerChallenge, OK),
11977 TestRound(kGetAuthWithProxyAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3111978 {__LINE__,
11979 kProxy,
asankac93076192016-10-03 15:46:0211980 AUTH_SYNC,
11981 OK,
11982 kServer,
11983 AUTH_SYNC,
11984 ERR_INVALID_AUTH_CREDENTIALS,
11985 3,
11986 kNoSSL,
11987 {TestRound(kGetProxy, kProxyChallenge, OK),
[email protected]044de0642010-06-17 10:42:1511988 TestRound(kGetProxyAuth, kServerChallenge, OK),
asankae2257db2016-10-11 22:03:1611989 TestRound(kGetProxyAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3111990 {__LINE__,
11991 kProxy,
asankac93076192016-10-03 15:46:0211992 AUTH_ASYNC,
11993 OK,
11994 kServer,
11995 AUTH_SYNC,
11996 OK,
11997 3,
11998 kNoSSL,
11999 {TestRound(kGetProxy, kProxyChallenge, OK),
[email protected]044de0642010-06-17 10:42:1512000 TestRound(kGetProxyAuth, kServerChallenge, OK),
12001 TestRound(kGetAuthWithProxyAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112002 {__LINE__,
12003 kProxy,
asankac93076192016-10-03 15:46:0212004 AUTH_ASYNC,
12005 OK,
12006 kServer,
12007 AUTH_SYNC,
12008 ERR_INVALID_AUTH_CREDENTIALS,
12009 3,
12010 kNoSSL,
12011 {TestRound(kGetProxy, kProxyChallenge, OK),
[email protected]044de0642010-06-17 10:42:1512012 TestRound(kGetProxyAuth, kServerChallenge, OK),
asankae2257db2016-10-11 22:03:1612013 TestRound(kGetProxyAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112014 {__LINE__,
12015 kProxy,
asankac93076192016-10-03 15:46:0212016 AUTH_SYNC,
12017 OK,
12018 kServer,
12019 AUTH_ASYNC,
12020 OK,
12021 3,
12022 kNoSSL,
12023 {TestRound(kGetProxy, kProxyChallenge, OK),
[email protected]044de0642010-06-17 10:42:1512024 TestRound(kGetProxyAuth, kServerChallenge, OK),
12025 TestRound(kGetAuthWithProxyAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112026 {__LINE__,
12027 kProxy,
12028 AUTH_SYNC,
12029 ERR_INVALID_AUTH_CREDENTIALS,
12030 kServer,
12031 AUTH_ASYNC,
12032 OK,
12033 4,
12034 kNoSSL,
12035 {TestRound(kGetProxy, kProxyChallenge, OK),
12036 TestRound(kGetProxy, kProxyChallenge, OK),
12037 TestRound(kGetProxyAuth, kServerChallenge, OK),
12038 TestRound(kGetAuthWithProxyAuth, kSuccess, OK)}},
12039 {__LINE__,
12040 kProxy,
asankac93076192016-10-03 15:46:0212041 AUTH_SYNC,
12042 OK,
12043 kServer,
12044 AUTH_ASYNC,
12045 ERR_INVALID_AUTH_CREDENTIALS,
12046 3,
12047 kNoSSL,
12048 {TestRound(kGetProxy, kProxyChallenge, OK),
[email protected]044de0642010-06-17 10:42:1512049 TestRound(kGetProxyAuth, kServerChallenge, OK),
asankae2257db2016-10-11 22:03:1612050 TestRound(kGetProxyAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112051 {__LINE__,
12052 kProxy,
asankac93076192016-10-03 15:46:0212053 AUTH_ASYNC,
12054 OK,
12055 kServer,
12056 AUTH_ASYNC,
12057 OK,
12058 3,
12059 kNoSSL,
12060 {TestRound(kGetProxy, kProxyChallenge, OK),
[email protected]044de0642010-06-17 10:42:1512061 TestRound(kGetProxyAuth, kServerChallenge, OK),
12062 TestRound(kGetAuthWithProxyAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112063 {__LINE__,
12064 kProxy,
asankac93076192016-10-03 15:46:0212065 AUTH_ASYNC,
12066 OK,
12067 kServer,
12068 AUTH_ASYNC,
12069 ERR_INVALID_AUTH_CREDENTIALS,
12070 3,
12071 kNoSSL,
12072 {TestRound(kGetProxy, kProxyChallenge, OK),
[email protected]044de0642010-06-17 10:42:1512073 TestRound(kGetProxyAuth, kServerChallenge, OK),
asankae2257db2016-10-11 22:03:1612074 TestRound(kGetProxyAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112075 {__LINE__,
12076 kProxy,
12077 AUTH_ASYNC,
12078 ERR_INVALID_AUTH_CREDENTIALS,
12079 kServer,
12080 AUTH_ASYNC,
12081 ERR_INVALID_AUTH_CREDENTIALS,
12082 4,
12083 kNoSSL,
12084 {TestRound(kGetProxy, kProxyChallenge, OK),
12085 TestRound(kGetProxy, kProxyChallenge, OK),
12086 TestRound(kGetProxyAuth, kServerChallenge, OK),
12087 TestRound(kGetProxyAuth, kSuccess, OK)}},
asankac93076192016-10-03 15:46:0212088 // Non-authenticating HTTPS server with a direct connection.
asanka463ca4262016-11-16 02:34:3112089 {__LINE__,
12090 nullptr,
asankac93076192016-10-03 15:46:0212091 AUTH_NONE,
12092 OK,
12093 kSecureServer,
12094 AUTH_NONE,
12095 OK,
12096 1,
12097 0,
12098 {TestRound(kGet, kSuccess, OK)}},
12099 // Authenticating HTTPS server with a direct connection.
asanka463ca4262016-11-16 02:34:3112100 {__LINE__,
12101 nullptr,
asankac93076192016-10-03 15:46:0212102 AUTH_NONE,
12103 OK,
12104 kSecureServer,
12105 AUTH_SYNC,
12106 OK,
12107 2,
12108 0,
12109 {TestRound(kGet, kServerChallenge, OK),
[email protected]044de0642010-06-17 10:42:1512110 TestRound(kGetAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112111 {__LINE__,
12112 nullptr,
asankac93076192016-10-03 15:46:0212113 AUTH_NONE,
12114 OK,
12115 kSecureServer,
12116 AUTH_SYNC,
12117 ERR_INVALID_AUTH_CREDENTIALS,
12118 2,
12119 0,
asankae2257db2016-10-11 22:03:1612120 {TestRound(kGet, kServerChallenge, OK), TestRound(kGet, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112121 {__LINE__,
12122 nullptr,
asankac93076192016-10-03 15:46:0212123 AUTH_NONE,
12124 OK,
12125 kSecureServer,
12126 AUTH_ASYNC,
12127 OK,
12128 2,
12129 0,
12130 {TestRound(kGet, kServerChallenge, OK),
[email protected]044de0642010-06-17 10:42:1512131 TestRound(kGetAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112132 {__LINE__,
12133 nullptr,
asankac93076192016-10-03 15:46:0212134 AUTH_NONE,
12135 OK,
12136 kSecureServer,
12137 AUTH_ASYNC,
12138 ERR_INVALID_AUTH_CREDENTIALS,
12139 2,
12140 0,
asankae2257db2016-10-11 22:03:1612141 {TestRound(kGet, kServerChallenge, OK), TestRound(kGet, kSuccess, OK)}},
asankac93076192016-10-03 15:46:0212142 // Non-authenticating HTTPS server with a non-authenticating proxy.
asanka463ca4262016-11-16 02:34:3112143 {__LINE__,
12144 kProxy,
asankac93076192016-10-03 15:46:0212145 AUTH_NONE,
12146 OK,
12147 kSecureServer,
12148 AUTH_NONE,
12149 OK,
12150 1,
12151 0,
12152 {TestRound(kConnect, kProxyConnected, OK, &kGet, &kSuccess)}},
12153 // Authenticating HTTPS server through a non-authenticating proxy.
asanka463ca4262016-11-16 02:34:3112154 {__LINE__,
12155 kProxy,
asankac93076192016-10-03 15:46:0212156 AUTH_NONE,
12157 OK,
12158 kSecureServer,
12159 AUTH_SYNC,
12160 OK,
12161 2,
12162 0,
12163 {TestRound(kConnect, kProxyConnected, OK, &kGet, &kServerChallenge),
[email protected]044de0642010-06-17 10:42:1512164 TestRound(kGetAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112165 {__LINE__,
12166 kProxy,
asankac93076192016-10-03 15:46:0212167 AUTH_NONE,
12168 OK,
12169 kSecureServer,
12170 AUTH_SYNC,
12171 ERR_INVALID_AUTH_CREDENTIALS,
12172 2,
12173 0,
12174 {TestRound(kConnect, kProxyConnected, OK, &kGet, &kServerChallenge),
asankae2257db2016-10-11 22:03:1612175 TestRound(kGet, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112176 {__LINE__,
12177 kProxy,
asankac93076192016-10-03 15:46:0212178 AUTH_NONE,
12179 OK,
12180 kSecureServer,
12181 AUTH_ASYNC,
12182 OK,
12183 2,
12184 0,
12185 {TestRound(kConnect, kProxyConnected, OK, &kGet, &kServerChallenge),
[email protected]044de0642010-06-17 10:42:1512186 TestRound(kGetAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112187 {__LINE__,
12188 kProxy,
asankac93076192016-10-03 15:46:0212189 AUTH_NONE,
12190 OK,
12191 kSecureServer,
12192 AUTH_ASYNC,
12193 ERR_INVALID_AUTH_CREDENTIALS,
12194 2,
12195 0,
12196 {TestRound(kConnect, kProxyConnected, OK, &kGet, &kServerChallenge),
asankae2257db2016-10-11 22:03:1612197 TestRound(kGet, kSuccess, OK)}},
asankac93076192016-10-03 15:46:0212198 // Non-Authenticating HTTPS server through an authenticating proxy.
asanka463ca4262016-11-16 02:34:3112199 {__LINE__,
12200 kProxy,
asankac93076192016-10-03 15:46:0212201 AUTH_SYNC,
12202 OK,
12203 kSecureServer,
12204 AUTH_NONE,
12205 OK,
12206 2,
12207 1,
12208 {TestRound(kConnect, kProxyChallenge, OK),
[email protected]044de0642010-06-17 10:42:1512209 TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet, &kSuccess)}},
asanka463ca4262016-11-16 02:34:3112210 {__LINE__,
12211 kProxy,
asankac93076192016-10-03 15:46:0212212 AUTH_SYNC,
12213 ERR_INVALID_AUTH_CREDENTIALS,
12214 kSecureServer,
12215 AUTH_NONE,
12216 OK,
12217 2,
12218 kNoSSL,
12219 {TestRound(kConnect, kProxyChallenge, OK),
asankae2257db2016-10-11 22:03:1612220 TestRound(kConnect, kProxyConnected, OK, &kGet, &kSuccess)}},
asanka463ca4262016-11-16 02:34:3112221 {__LINE__,
12222 kProxy,
asankae2257db2016-10-11 22:03:1612223 AUTH_SYNC,
12224 ERR_UNSUPPORTED_AUTH_SCHEME,
12225 kSecureServer,
12226 AUTH_NONE,
12227 OK,
12228 2,
12229 kNoSSL,
12230 {TestRound(kConnect, kProxyChallenge, OK),
12231 TestRound(kConnect, kProxyConnected, OK, &kGet, &kSuccess)}},
asanka463ca4262016-11-16 02:34:3112232 {__LINE__,
12233 kProxy,
asankae2257db2016-10-11 22:03:1612234 AUTH_SYNC,
12235 ERR_UNEXPECTED,
12236 kSecureServer,
12237 AUTH_NONE,
12238 OK,
12239 2,
12240 kNoSSL,
12241 {TestRound(kConnect, kProxyChallenge, OK),
12242 TestRound(kConnect, kProxyConnected, ERR_UNEXPECTED)}},
asanka463ca4262016-11-16 02:34:3112243 {__LINE__,
12244 kProxy,
asankac93076192016-10-03 15:46:0212245 AUTH_ASYNC,
12246 OK,
12247 kSecureServer,
12248 AUTH_NONE,
12249 OK,
12250 2,
12251 1,
12252 {TestRound(kConnect, kProxyChallenge, OK),
[email protected]044de0642010-06-17 10:42:1512253 TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet, &kSuccess)}},
asanka463ca4262016-11-16 02:34:3112254 {__LINE__,
12255 kProxy,
asankac93076192016-10-03 15:46:0212256 AUTH_ASYNC,
12257 ERR_INVALID_AUTH_CREDENTIALS,
12258 kSecureServer,
12259 AUTH_NONE,
12260 OK,
12261 2,
12262 kNoSSL,
12263 {TestRound(kConnect, kProxyChallenge, OK),
asankae2257db2016-10-11 22:03:1612264 TestRound(kConnect, kProxyConnected, OK, &kGet, &kSuccess)}},
asankac93076192016-10-03 15:46:0212265 // Authenticating HTTPS server through an authenticating proxy.
asanka463ca4262016-11-16 02:34:3112266 {__LINE__,
12267 kProxy,
asankac93076192016-10-03 15:46:0212268 AUTH_SYNC,
12269 OK,
12270 kSecureServer,
12271 AUTH_SYNC,
12272 OK,
12273 3,
12274 1,
12275 {TestRound(kConnect, kProxyChallenge, OK),
12276 TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet,
12277 &kServerChallenge),
[email protected]044de0642010-06-17 10:42:1512278 TestRound(kGetAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112279 {__LINE__,
12280 kProxy,
asankac93076192016-10-03 15:46:0212281 AUTH_SYNC,
12282 OK,
12283 kSecureServer,
12284 AUTH_SYNC,
12285 ERR_INVALID_AUTH_CREDENTIALS,
12286 3,
12287 1,
12288 {TestRound(kConnect, kProxyChallenge, OK),
12289 TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet,
12290 &kServerChallenge),
asankae2257db2016-10-11 22:03:1612291 TestRound(kGet, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112292 {__LINE__,
12293 kProxy,
asankac93076192016-10-03 15:46:0212294 AUTH_ASYNC,
12295 OK,
12296 kSecureServer,
12297 AUTH_SYNC,
12298 OK,
12299 3,
12300 1,
12301 {TestRound(kConnect, kProxyChallenge, OK),
12302 TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet,
12303 &kServerChallenge),
[email protected]044de0642010-06-17 10:42:1512304 TestRound(kGetAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112305 {__LINE__,
12306 kProxy,
asankac93076192016-10-03 15:46:0212307 AUTH_ASYNC,
12308 OK,
12309 kSecureServer,
12310 AUTH_SYNC,
12311 ERR_INVALID_AUTH_CREDENTIALS,
12312 3,
12313 1,
12314 {TestRound(kConnect, kProxyChallenge, OK),
12315 TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet,
12316 &kServerChallenge),
asankae2257db2016-10-11 22:03:1612317 TestRound(kGet, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112318 {__LINE__,
12319 kProxy,
asankac93076192016-10-03 15:46:0212320 AUTH_SYNC,
12321 OK,
12322 kSecureServer,
12323 AUTH_ASYNC,
12324 OK,
12325 3,
12326 1,
12327 {TestRound(kConnect, kProxyChallenge, OK),
12328 TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet,
12329 &kServerChallenge),
[email protected]044de0642010-06-17 10:42:1512330 TestRound(kGetAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112331 {__LINE__,
12332 kProxy,
asankac93076192016-10-03 15:46:0212333 AUTH_SYNC,
12334 OK,
12335 kSecureServer,
12336 AUTH_ASYNC,
12337 ERR_INVALID_AUTH_CREDENTIALS,
12338 3,
12339 1,
12340 {TestRound(kConnect, kProxyChallenge, OK),
12341 TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet,
12342 &kServerChallenge),
asankae2257db2016-10-11 22:03:1612343 TestRound(kGet, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112344 {__LINE__,
12345 kProxy,
asankac93076192016-10-03 15:46:0212346 AUTH_ASYNC,
12347 OK,
12348 kSecureServer,
12349 AUTH_ASYNC,
12350 OK,
12351 3,
12352 1,
12353 {TestRound(kConnect, kProxyChallenge, OK),
12354 TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet,
12355 &kServerChallenge),
[email protected]044de0642010-06-17 10:42:1512356 TestRound(kGetAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112357 {__LINE__,
12358 kProxy,
asankac93076192016-10-03 15:46:0212359 AUTH_ASYNC,
12360 OK,
12361 kSecureServer,
12362 AUTH_ASYNC,
12363 ERR_INVALID_AUTH_CREDENTIALS,
12364 3,
12365 1,
12366 {TestRound(kConnect, kProxyChallenge, OK),
12367 TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet,
12368 &kServerChallenge),
asankae2257db2016-10-11 22:03:1612369 TestRound(kGet, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112370 {__LINE__,
12371 kProxy,
12372 AUTH_ASYNC,
12373 ERR_INVALID_AUTH_CREDENTIALS,
12374 kSecureServer,
12375 AUTH_ASYNC,
12376 ERR_INVALID_AUTH_CREDENTIALS,
12377 4,
12378 2,
12379 {TestRound(kConnect, kProxyChallenge, OK),
12380 TestRound(kConnect, kProxyChallenge, OK),
12381 TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet,
12382 &kServerChallenge),
12383 TestRound(kGet, kSuccess, OK)}},
[email protected]044de0642010-06-17 10:42:1512384 };
12385
asanka463ca4262016-11-16 02:34:3112386 for (const auto& test_config : test_configs) {
12387 SCOPED_TRACE(::testing::Message() << "Test config at "
12388 << test_config.line_number);
[email protected]2d01c262011-08-11 23:07:0812389 HttpAuthHandlerMock::Factory* auth_factory(
12390 new HttpAuthHandlerMock::Factory());
[email protected]bb88e1d32013-05-03 23:11:0712391 session_deps_.http_auth_handler_factory.reset(auth_factory);
asanka5ffd5d72016-03-23 16:20:4912392 SSLInfo empty_ssl_info;
[email protected]65d34382010-07-01 18:12:2612393
12394 // Set up authentication handlers as necessary.
[email protected]044de0642010-06-17 10:42:1512395 if (test_config.proxy_auth_timing != AUTH_NONE) {
asanka463ca4262016-11-16 02:34:3112396 for (int n = 0; n < 3; n++) {
[email protected]2d01c262011-08-11 23:07:0812397 HttpAuthHandlerMock* auth_handler(new HttpAuthHandlerMock());
12398 std::string auth_challenge = "Mock realm=proxy";
12399 GURL origin(test_config.proxy_url);
[email protected]df41d0d82014-03-13 00:43:2412400 HttpAuthChallengeTokenizer tokenizer(auth_challenge.begin(),
12401 auth_challenge.end());
[email protected]2d01c262011-08-11 23:07:0812402 auth_handler->InitFromChallenge(&tokenizer, HttpAuth::AUTH_PROXY,
tfarina42834112016-09-22 13:38:2012403 empty_ssl_info, origin,
12404 NetLogWithSource());
[email protected]2d01c262011-08-11 23:07:0812405 auth_handler->SetGenerateExpectation(
12406 test_config.proxy_auth_timing == AUTH_ASYNC,
asanka463ca4262016-11-16 02:34:3112407 n == 0 ? test_config.first_generate_proxy_token_rv : OK);
[email protected]2d01c262011-08-11 23:07:0812408 auth_factory->AddMockHandler(auth_handler, HttpAuth::AUTH_PROXY);
12409 }
[email protected]044de0642010-06-17 10:42:1512410 }
12411 if (test_config.server_auth_timing != AUTH_NONE) {
[email protected]3fd9dae2010-06-21 11:39:0012412 HttpAuthHandlerMock* auth_handler(new HttpAuthHandlerMock());
[email protected]044de0642010-06-17 10:42:1512413 std::string auth_challenge = "Mock realm=server";
12414 GURL origin(test_config.server_url);
[email protected]df41d0d82014-03-13 00:43:2412415 HttpAuthChallengeTokenizer tokenizer(auth_challenge.begin(),
12416 auth_challenge.end());
[email protected]044de0642010-06-17 10:42:1512417 auth_handler->InitFromChallenge(&tokenizer, HttpAuth::AUTH_SERVER,
tfarina42834112016-09-22 13:38:2012418 empty_ssl_info, origin,
12419 NetLogWithSource());
[email protected]044de0642010-06-17 10:42:1512420 auth_handler->SetGenerateExpectation(
12421 test_config.server_auth_timing == AUTH_ASYNC,
asanka463ca4262016-11-16 02:34:3112422 test_config.first_generate_server_token_rv);
[email protected]2d01c262011-08-11 23:07:0812423 auth_factory->AddMockHandler(auth_handler, HttpAuth::AUTH_SERVER);
asankae2257db2016-10-11 22:03:1612424
12425 // The second handler always succeeds. It should only be used where there
12426 // are multiple auth sessions for server auth in the same network
12427 // transaction using the same auth scheme.
12428 std::unique_ptr<HttpAuthHandlerMock> second_handler =
Jeremy Roman0579ed62017-08-29 15:56:1912429 std::make_unique<HttpAuthHandlerMock>();
asankae2257db2016-10-11 22:03:1612430 second_handler->InitFromChallenge(&tokenizer, HttpAuth::AUTH_SERVER,
12431 empty_ssl_info, origin,
12432 NetLogWithSource());
12433 second_handler->SetGenerateExpectation(true, OK);
12434 auth_factory->AddMockHandler(second_handler.release(),
12435 HttpAuth::AUTH_SERVER);
[email protected]044de0642010-06-17 10:42:1512436 }
12437 if (test_config.proxy_url) {
rdsmith82957ad2015-09-16 19:42:0312438 session_deps_.proxy_service =
12439 ProxyService::CreateFixed(test_config.proxy_url);
[email protected]044de0642010-06-17 10:42:1512440 } else {
rdsmith82957ad2015-09-16 19:42:0312441 session_deps_.proxy_service = ProxyService::CreateDirect();
[email protected]044de0642010-06-17 10:42:1512442 }
12443
12444 HttpRequestInfo request;
12445 request.method = "GET";
12446 request.url = GURL(test_config.server_url);
[email protected]044de0642010-06-17 10:42:1512447
danakj1fd259a02016-04-16 03:17:0912448 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]044de0642010-06-17 10:42:1512449
rchcb68dc62015-05-21 04:45:3612450 SSLSocketDataProvider ssl_socket_data_provider(SYNCHRONOUS, OK);
12451
12452 std::vector<std::vector<MockRead>> mock_reads(1);
12453 std::vector<std::vector<MockWrite>> mock_writes(1);
[email protected]044de0642010-06-17 10:42:1512454 for (int round = 0; round < test_config.num_auth_rounds; ++round) {
davidben8c7089a2017-04-17 20:38:2212455 SCOPED_TRACE(round);
[email protected]044de0642010-06-17 10:42:1512456 const TestRound& read_write_round = test_config.rounds[round];
12457
12458 // Set up expected reads and writes.
rchcb68dc62015-05-21 04:45:3612459 mock_reads.back().push_back(read_write_round.read);
12460 mock_writes.back().push_back(read_write_round.write);
12461
12462 // kProxyChallenge uses Proxy-Connection: close which means that the
12463 // socket is closed and a new one will be created for the next request.
mmenkee71e15332015-10-07 16:39:5412464 if (read_write_round.read.data == kProxyChallenge.data) {
rchcb68dc62015-05-21 04:45:3612465 mock_reads.push_back(std::vector<MockRead>());
12466 mock_writes.push_back(std::vector<MockWrite>());
[email protected]044de0642010-06-17 10:42:1512467 }
12468
rchcb68dc62015-05-21 04:45:3612469 if (read_write_round.extra_read) {
12470 mock_reads.back().push_back(*read_write_round.extra_read);
[email protected]044de0642010-06-17 10:42:1512471 }
rchcb68dc62015-05-21 04:45:3612472 if (read_write_round.extra_write) {
12473 mock_writes.back().push_back(*read_write_round.extra_write);
12474 }
[email protected]044de0642010-06-17 10:42:1512475
12476 // Add an SSL sequence if necessary.
[email protected]044de0642010-06-17 10:42:1512477 if (round >= test_config.first_ssl_round)
[email protected]bb88e1d32013-05-03 23:11:0712478 session_deps_.socket_factory->AddSSLSocketDataProvider(
[email protected]044de0642010-06-17 10:42:1512479 &ssl_socket_data_provider);
rchcb68dc62015-05-21 04:45:3612480 }
[email protected]044de0642010-06-17 10:42:1512481
danakj1fd259a02016-04-16 03:17:0912482 std::vector<std::unique_ptr<StaticSocketDataProvider>> data_providers;
rchcb68dc62015-05-21 04:45:3612483 for (size_t i = 0; i < mock_reads.size(); ++i) {
Jeremy Roman0579ed62017-08-29 15:56:1912484 data_providers.push_back(std::make_unique<StaticSocketDataProvider>(
davidben5f8b6bc2015-11-25 03:19:5412485 mock_reads[i].data(), mock_reads[i].size(), mock_writes[i].data(),
bnc87dcefc2017-05-25 12:47:5812486 mock_writes[i].size()));
rchcb68dc62015-05-21 04:45:3612487 session_deps_.socket_factory->AddSocketDataProvider(
olli.raula525048c2015-12-10 07:38:3212488 data_providers.back().get());
rchcb68dc62015-05-21 04:45:3612489 }
12490
mmenkecc2298e2015-12-07 18:20:1812491 // Transaction must be created after DataProviders, so it's destroyed before
12492 // they are as well.
12493 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
12494
rchcb68dc62015-05-21 04:45:3612495 for (int round = 0; round < test_config.num_auth_rounds; ++round) {
davidben8c7089a2017-04-17 20:38:2212496 SCOPED_TRACE(round);
rchcb68dc62015-05-21 04:45:3612497 const TestRound& read_write_round = test_config.rounds[round];
[email protected]044de0642010-06-17 10:42:1512498 // Start or restart the transaction.
[email protected]49639fa2011-12-20 23:22:4112499 TestCompletionCallback callback;
[email protected]044de0642010-06-17 10:42:1512500 int rv;
12501 if (round == 0) {
tfarina42834112016-09-22 13:38:2012502 rv = trans.Start(&request, callback.callback(), NetLogWithSource());
[email protected]044de0642010-06-17 10:42:1512503 } else {
[email protected]49639fa2011-12-20 23:22:4112504 rv = trans.RestartWithAuth(
12505 AuthCredentials(kFoo, kBar), callback.callback());
[email protected]044de0642010-06-17 10:42:1512506 }
12507 if (rv == ERR_IO_PENDING)
12508 rv = callback.WaitForResult();
12509
12510 // Compare results with expected data.
asankae2257db2016-10-11 22:03:1612511 EXPECT_THAT(rv, IsError(read_write_round.expected_rv));
[email protected]0b0bf032010-09-21 18:08:5012512 const HttpResponseInfo* response = trans.GetResponseInfo();
ttuttlec0c828492015-05-15 01:25:5512513 if (read_write_round.expected_rv != OK) {
[email protected]044de0642010-06-17 10:42:1512514 EXPECT_EQ(round + 1, test_config.num_auth_rounds);
12515 continue;
12516 }
12517 if (round + 1 < test_config.num_auth_rounds) {
wezca1070932016-05-26 20:30:5212518 EXPECT_TRUE(response->auth_challenge);
[email protected]044de0642010-06-17 10:42:1512519 } else {
wezca1070932016-05-26 20:30:5212520 EXPECT_FALSE(response->auth_challenge);
asankae2257db2016-10-11 22:03:1612521 EXPECT_FALSE(trans.IsReadyToRestartForAuth());
[email protected]044de0642010-06-17 10:42:1512522 }
12523 }
[email protected]e5ae96a2010-04-14 20:12:4512524 }
12525}
12526
bncd16676a2016-07-20 16:23:0112527TEST_F(HttpNetworkTransactionTest, MultiRoundAuth) {
[email protected]c871bce92010-07-15 21:51:1412528 // Do multi-round authentication and make sure it works correctly.
[email protected]c871bce92010-07-15 21:51:1412529 HttpAuthHandlerMock::Factory* auth_factory(
12530 new HttpAuthHandlerMock::Factory());
[email protected]bb88e1d32013-05-03 23:11:0712531 session_deps_.http_auth_handler_factory.reset(auth_factory);
rdsmith82957ad2015-09-16 19:42:0312532 session_deps_.proxy_service = ProxyService::CreateDirect();
[email protected]bb88e1d32013-05-03 23:11:0712533 session_deps_.host_resolver->rules()->AddRule("www.example.com", "10.0.0.1");
12534 session_deps_.host_resolver->set_synchronous_mode(true);
[email protected]c871bce92010-07-15 21:51:1412535
12536 HttpAuthHandlerMock* auth_handler(new HttpAuthHandlerMock());
12537 auth_handler->set_connection_based(true);
12538 std::string auth_challenge = "Mock realm=server";
12539 GURL origin("http://www.example.com");
[email protected]df41d0d82014-03-13 00:43:2412540 HttpAuthChallengeTokenizer tokenizer(auth_challenge.begin(),
12541 auth_challenge.end());
asanka5ffd5d72016-03-23 16:20:4912542 SSLInfo empty_ssl_info;
[email protected]c871bce92010-07-15 21:51:1412543 auth_handler->InitFromChallenge(&tokenizer, HttpAuth::AUTH_SERVER,
tfarina42834112016-09-22 13:38:2012544 empty_ssl_info, origin, NetLogWithSource());
[email protected]2d01c262011-08-11 23:07:0812545 auth_factory->AddMockHandler(auth_handler, HttpAuth::AUTH_SERVER);
[email protected]c871bce92010-07-15 21:51:1412546
[email protected]c871bce92010-07-15 21:51:1412547 int rv = OK;
12548 const HttpResponseInfo* response = NULL;
12549 HttpRequestInfo request;
12550 request.method = "GET";
12551 request.url = origin;
[email protected]cb9bf6ca2011-01-28 13:15:2712552
danakj1fd259a02016-04-16 03:17:0912553 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]7ef4cbbb2011-02-06 11:19:1012554
12555 // Use a TCP Socket Pool with only one connection per group. This is used
12556 // to validate that the TCP socket is not released to the pool between
12557 // each round of multi-round authentication.
mmenkee65e7af2015-10-13 17:16:4212558 HttpNetworkSessionPeer session_peer(session.get());
[email protected]ab739042011-04-07 15:22:2812559 TransportClientSocketPool* transport_pool = new TransportClientSocketPool(
[email protected]7ef4cbbb2011-02-06 11:19:1012560 50, // Max sockets for pool
12561 1, // Max sockets per group
tbansal7b403bcc2016-04-13 22:33:2112562 session_deps_.host_resolver.get(), session_deps_.socket_factory.get(),
12563 NULL, session_deps_.net_log);
Jeremy Roman0579ed62017-08-29 15:56:1912564 auto mock_pool_manager = std::make_unique<MockClientSocketPoolManager>();
[email protected]a42dbd142011-11-17 16:42:0212565 mock_pool_manager->SetTransportSocketPool(transport_pool);
dchengc7eeda422015-12-26 03:56:4812566 session_peer.SetClientSocketPoolManager(std::move(mock_pool_manager));
[email protected]7ef4cbbb2011-02-06 11:19:1012567
bnc691fda62016-08-12 00:43:1612568 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]49639fa2011-12-20 23:22:4112569 TestCompletionCallback callback;
[email protected]c871bce92010-07-15 21:51:1412570
12571 const MockWrite kGet(
12572 "GET / HTTP/1.1\r\n"
12573 "Host: www.example.com\r\n"
12574 "Connection: keep-alive\r\n\r\n");
12575 const MockWrite kGetAuth(
12576 "GET / HTTP/1.1\r\n"
12577 "Host: www.example.com\r\n"
12578 "Connection: keep-alive\r\n"
12579 "Authorization: auth_token\r\n\r\n");
12580
12581 const MockRead kServerChallenge(
12582 "HTTP/1.1 401 Unauthorized\r\n"
12583 "WWW-Authenticate: Mock realm=server\r\n"
12584 "Content-Type: text/html; charset=iso-8859-1\r\n"
12585 "Content-Length: 14\r\n\r\n"
12586 "Unauthorized\r\n");
12587 const MockRead kSuccess(
12588 "HTTP/1.1 200 OK\r\n"
12589 "Content-Type: text/html; charset=iso-8859-1\r\n"
12590 "Content-Length: 3\r\n\r\n"
12591 "Yes");
12592
12593 MockWrite writes[] = {
12594 // First round
12595 kGet,
12596 // Second round
12597 kGetAuth,
12598 // Third round
12599 kGetAuth,
[email protected]eca50e122010-09-11 14:03:3012600 // Fourth round
[email protected]7ef4cbbb2011-02-06 11:19:1012601 kGetAuth,
12602 // Competing request
12603 kGet,
[email protected]c871bce92010-07-15 21:51:1412604 };
12605 MockRead reads[] = {
12606 // First round
12607 kServerChallenge,
12608 // Second round
12609 kServerChallenge,
12610 // Third round
[email protected]eca50e122010-09-11 14:03:3012611 kServerChallenge,
12612 // Fourth round
[email protected]c871bce92010-07-15 21:51:1412613 kSuccess,
[email protected]7ef4cbbb2011-02-06 11:19:1012614 // Competing response
12615 kSuccess,
[email protected]c871bce92010-07-15 21:51:1412616 };
12617 StaticSocketDataProvider data_provider(reads, arraysize(reads),
12618 writes, arraysize(writes));
[email protected]bb88e1d32013-05-03 23:11:0712619 session_deps_.socket_factory->AddSocketDataProvider(&data_provider);
[email protected]c871bce92010-07-15 21:51:1412620
thestig9d3bb0c2015-01-24 00:49:5112621 const char kSocketGroup[] = "www.example.com:80";
[email protected]7ef4cbbb2011-02-06 11:19:1012622
12623 // First round of authentication.
[email protected]c871bce92010-07-15 21:51:1412624 auth_handler->SetGenerateExpectation(false, OK);
tfarina42834112016-09-22 13:38:2012625 rv = trans.Start(&request, callback.callback(), NetLogWithSource());
[email protected]c871bce92010-07-15 21:51:1412626 if (rv == ERR_IO_PENDING)
12627 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0112628 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:1612629 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5212630 ASSERT_TRUE(response);
12631 EXPECT_TRUE(response->auth_challenge);
[email protected]ab739042011-04-07 15:22:2812632 EXPECT_EQ(0, transport_pool->IdleSocketCountInGroup(kSocketGroup));
asanka463ca4262016-11-16 02:34:3112633 EXPECT_EQ(HttpAuthHandlerMock::State::WAIT_FOR_GENERATE_AUTH_TOKEN,
12634 auth_handler->state());
[email protected]c871bce92010-07-15 21:51:1412635
[email protected]7ef4cbbb2011-02-06 11:19:1012636 // In between rounds, another request comes in for the same domain.
12637 // It should not be able to grab the TCP socket that trans has already
12638 // claimed.
bnc691fda62016-08-12 00:43:1612639 HttpNetworkTransaction trans_compete(DEFAULT_PRIORITY, session.get());
[email protected]49639fa2011-12-20 23:22:4112640 TestCompletionCallback callback_compete;
tfarina42834112016-09-22 13:38:2012641 rv = trans_compete.Start(&request, callback_compete.callback(),
12642 NetLogWithSource());
robpercival214763f2016-07-01 23:27:0112643 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]7ef4cbbb2011-02-06 11:19:1012644 // callback_compete.WaitForResult at this point would stall forever,
12645 // since the HttpNetworkTransaction does not release the request back to
12646 // the pool until after authentication completes.
12647
12648 // Second round of authentication.
[email protected]c871bce92010-07-15 21:51:1412649 auth_handler->SetGenerateExpectation(false, OK);
bnc691fda62016-08-12 00:43:1612650 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar), callback.callback());
[email protected]c871bce92010-07-15 21:51:1412651 if (rv == ERR_IO_PENDING)
12652 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0112653 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:1612654 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5212655 ASSERT_TRUE(response);
12656 EXPECT_FALSE(response->auth_challenge);
[email protected]ab739042011-04-07 15:22:2812657 EXPECT_EQ(0, transport_pool->IdleSocketCountInGroup(kSocketGroup));
asanka463ca4262016-11-16 02:34:3112658 EXPECT_EQ(HttpAuthHandlerMock::State::WAIT_FOR_GENERATE_AUTH_TOKEN,
12659 auth_handler->state());
[email protected]c871bce92010-07-15 21:51:1412660
[email protected]7ef4cbbb2011-02-06 11:19:1012661 // Third round of authentication.
[email protected]c871bce92010-07-15 21:51:1412662 auth_handler->SetGenerateExpectation(false, OK);
bnc691fda62016-08-12 00:43:1612663 rv = trans.RestartWithAuth(AuthCredentials(), callback.callback());
[email protected]c871bce92010-07-15 21:51:1412664 if (rv == ERR_IO_PENDING)
12665 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0112666 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:1612667 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5212668 ASSERT_TRUE(response);
12669 EXPECT_FALSE(response->auth_challenge);
[email protected]ab739042011-04-07 15:22:2812670 EXPECT_EQ(0, transport_pool->IdleSocketCountInGroup(kSocketGroup));
asanka463ca4262016-11-16 02:34:3112671 EXPECT_EQ(HttpAuthHandlerMock::State::WAIT_FOR_GENERATE_AUTH_TOKEN,
12672 auth_handler->state());
[email protected]eca50e122010-09-11 14:03:3012673
[email protected]7ef4cbbb2011-02-06 11:19:1012674 // Fourth round of authentication, which completes successfully.
[email protected]eca50e122010-09-11 14:03:3012675 auth_handler->SetGenerateExpectation(false, OK);
bnc691fda62016-08-12 00:43:1612676 rv = trans.RestartWithAuth(AuthCredentials(), callback.callback());
[email protected]eca50e122010-09-11 14:03:3012677 if (rv == ERR_IO_PENDING)
12678 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0112679 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:1612680 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5212681 ASSERT_TRUE(response);
12682 EXPECT_FALSE(response->auth_challenge);
[email protected]ab739042011-04-07 15:22:2812683 EXPECT_EQ(0, transport_pool->IdleSocketCountInGroup(kSocketGroup));
[email protected]7ef4cbbb2011-02-06 11:19:1012684
asanka463ca4262016-11-16 02:34:3112685 // In WAIT_FOR_CHALLENGE, although in reality the auth handler is done. A real
12686 // auth handler should transition to a DONE state in concert with the remote
12687 // server. But that's not something we can test here with a mock handler.
12688 EXPECT_EQ(HttpAuthHandlerMock::State::WAIT_FOR_CHALLENGE,
12689 auth_handler->state());
12690
[email protected]7ef4cbbb2011-02-06 11:19:1012691 // Read the body since the fourth round was successful. This will also
12692 // release the socket back to the pool.
12693 scoped_refptr<IOBufferWithSize> io_buf(new IOBufferWithSize(50));
bnc691fda62016-08-12 00:43:1612694 rv = trans.Read(io_buf.get(), io_buf->size(), callback.callback());
[email protected]7ef4cbbb2011-02-06 11:19:1012695 if (rv == ERR_IO_PENDING)
12696 rv = callback.WaitForResult();
12697 EXPECT_EQ(3, rv);
bnc691fda62016-08-12 00:43:1612698 rv = trans.Read(io_buf.get(), io_buf->size(), callback.callback());
[email protected]7ef4cbbb2011-02-06 11:19:1012699 EXPECT_EQ(0, rv);
12700 // There are still 0 idle sockets, since the trans_compete transaction
12701 // will be handed it immediately after trans releases it to the group.
[email protected]ab739042011-04-07 15:22:2812702 EXPECT_EQ(0, transport_pool->IdleSocketCountInGroup(kSocketGroup));
[email protected]7ef4cbbb2011-02-06 11:19:1012703
12704 // The competing request can now finish. Wait for the headers and then
12705 // read the body.
12706 rv = callback_compete.WaitForResult();
robpercival214763f2016-07-01 23:27:0112707 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:1612708 rv = trans_compete.Read(io_buf.get(), io_buf->size(), callback.callback());
[email protected]7ef4cbbb2011-02-06 11:19:1012709 if (rv == ERR_IO_PENDING)
12710 rv = callback.WaitForResult();
12711 EXPECT_EQ(3, rv);
bnc691fda62016-08-12 00:43:1612712 rv = trans_compete.Read(io_buf.get(), io_buf->size(), callback.callback());
[email protected]7ef4cbbb2011-02-06 11:19:1012713 EXPECT_EQ(0, rv);
12714
12715 // Finally, the socket is released to the group.
[email protected]ab739042011-04-07 15:22:2812716 EXPECT_EQ(1, transport_pool->IdleSocketCountInGroup(kSocketGroup));
[email protected]c871bce92010-07-15 21:51:1412717}
12718
[email protected]65041fa2010-05-21 06:56:5312719// This tests the case that a request is issued via http instead of spdy after
12720// npn is negotiated.
bncd16676a2016-07-20 16:23:0112721TEST_F(HttpNetworkTransactionTest, NpnWithHttpOverSSL) {
[email protected]65041fa2010-05-21 06:56:5312722 HttpRequestInfo request;
12723 request.method = "GET";
bncce36dca22015-04-21 22:11:2312724 request.url = GURL("https://www.example.org/");
[email protected]65041fa2010-05-21 06:56:5312725
12726 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:2312727 MockWrite(
12728 "GET / HTTP/1.1\r\n"
12729 "Host: www.example.org\r\n"
12730 "Connection: keep-alive\r\n\r\n"),
[email protected]65041fa2010-05-21 06:56:5312731 };
12732
12733 MockRead data_reads[] = {
bncc958faa2015-07-31 18:14:5212734 MockRead("HTTP/1.1 200 OK\r\n"),
bnc2df4b522016-07-08 18:17:4312735 MockRead(kAlternativeServiceHttpHeader),
bncc958faa2015-07-31 18:14:5212736 MockRead("\r\n"),
12737 MockRead("hello world"),
12738 MockRead(SYNCHRONOUS, OK),
[email protected]65041fa2010-05-21 06:56:5312739 };
12740
[email protected]8ddf8322012-02-23 18:08:0612741 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3612742 ssl.next_proto = kProtoHTTP11;
[email protected]65041fa2010-05-21 06:56:5312743
[email protected]bb88e1d32013-05-03 23:11:0712744 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]65041fa2010-05-21 06:56:5312745
12746 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
12747 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:0712748 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]65041fa2010-05-21 06:56:5312749
[email protected]49639fa2011-12-20 23:22:4112750 TestCompletionCallback callback;
[email protected]65041fa2010-05-21 06:56:5312751
danakj1fd259a02016-04-16 03:17:0912752 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1612753 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]65041fa2010-05-21 06:56:5312754
tfarina42834112016-09-22 13:38:2012755 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
[email protected]65041fa2010-05-21 06:56:5312756
robpercival214763f2016-07-01 23:27:0112757 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
12758 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]65041fa2010-05-21 06:56:5312759
bnc691fda62016-08-12 00:43:1612760 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5212761 ASSERT_TRUE(response);
12762 ASSERT_TRUE(response->headers);
[email protected]65041fa2010-05-21 06:56:5312763 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
12764
12765 std::string response_data;
bnc691fda62016-08-12 00:43:1612766 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
[email protected]65041fa2010-05-21 06:56:5312767 EXPECT_EQ("hello world", response_data);
12768
12769 EXPECT_FALSE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5212770 EXPECT_TRUE(response->was_alpn_negotiated);
[email protected]65041fa2010-05-21 06:56:5312771}
[email protected]26ef6582010-06-24 02:30:4712772
bnc55ff9da2015-08-19 18:42:3512773// Simulate the SSL handshake completing with an NPN negotiation followed by an
12774// immediate server closing of the socket.
12775// Regression test for https://crbug.com/46369.
bncd16676a2016-07-20 16:23:0112776TEST_F(HttpNetworkTransactionTest, SpdyPostNPNServerHangup) {
[email protected]26ef6582010-06-24 02:30:4712777 HttpRequestInfo request;
12778 request.method = "GET";
bncce36dca22015-04-21 22:11:2312779 request.url = GURL("https://www.example.org/");
[email protected]26ef6582010-06-24 02:30:4712780
[email protected]8ddf8322012-02-23 18:08:0612781 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3612782 ssl.next_proto = kProtoHTTP2;
[email protected]bb88e1d32013-05-03 23:11:0712783 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]26ef6582010-06-24 02:30:4712784
bncdf80d44fd2016-07-15 20:27:4112785 SpdySerializedFrame req(
bnc38dcd392016-02-09 23:19:4912786 spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST, true));
bncdf80d44fd2016-07-15 20:27:4112787 MockWrite spdy_writes[] = {CreateMockWrite(req, 1)};
[email protected]26ef6582010-06-24 02:30:4712788
12789 MockRead spdy_reads[] = {
[email protected]8ddf8322012-02-23 18:08:0612790 MockRead(SYNCHRONOUS, 0, 0) // Not async - return 0 immediately.
[email protected]26ef6582010-06-24 02:30:4712791 };
12792
rch8e6c6c42015-05-01 14:05:1312793 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
12794 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:0712795 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]26ef6582010-06-24 02:30:4712796
[email protected]49639fa2011-12-20 23:22:4112797 TestCompletionCallback callback;
[email protected]26ef6582010-06-24 02:30:4712798
danakj1fd259a02016-04-16 03:17:0912799 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1612800 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]26ef6582010-06-24 02:30:4712801
tfarina42834112016-09-22 13:38:2012802 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0112803 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
12804 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_CONNECTION_CLOSED));
[email protected]26ef6582010-06-24 02:30:4712805}
[email protected]65d34382010-07-01 18:12:2612806
[email protected]795cbf82013-07-22 09:37:2712807// A subclass of HttpAuthHandlerMock that records the request URL when
12808// it gets it. This is needed since the auth handler may get destroyed
12809// before we get a chance to query it.
12810class UrlRecordingHttpAuthHandlerMock : public HttpAuthHandlerMock {
12811 public:
12812 explicit UrlRecordingHttpAuthHandlerMock(GURL* url) : url_(url) {}
12813
dchengb03027d2014-10-21 12:00:2012814 ~UrlRecordingHttpAuthHandlerMock() override {}
[email protected]795cbf82013-07-22 09:37:2712815
12816 protected:
dchengb03027d2014-10-21 12:00:2012817 int GenerateAuthTokenImpl(const AuthCredentials* credentials,
12818 const HttpRequestInfo* request,
12819 const CompletionCallback& callback,
12820 std::string* auth_token) override {
[email protected]795cbf82013-07-22 09:37:2712821 *url_ = request->url;
12822 return HttpAuthHandlerMock::GenerateAuthTokenImpl(
12823 credentials, request, callback, auth_token);
12824 }
12825
12826 private:
12827 GURL* url_;
12828};
12829
[email protected]8e6441ca2010-08-19 05:56:3812830// Test that if we cancel the transaction as the connection is completing, that
12831// everything tears down correctly.
bncd16676a2016-07-20 16:23:0112832TEST_F(HttpNetworkTransactionTest, SimpleCancel) {
[email protected]8e6441ca2010-08-19 05:56:3812833 // Setup everything about the connection to complete synchronously, so that
12834 // after calling HttpNetworkTransaction::Start, the only thing we're waiting
12835 // for is the callback from the HttpStreamRequest.
12836 // Then cancel the transaction.
12837 // Verify that we don't crash.
[email protected]d973e99a2012-02-17 21:02:3612838 MockConnect mock_connect(SYNCHRONOUS, OK);
[email protected]8e6441ca2010-08-19 05:56:3812839 MockRead data_reads[] = {
[email protected]8ddf8322012-02-23 18:08:0612840 MockRead(SYNCHRONOUS, "HTTP/1.0 200 OK\r\n\r\n"),
12841 MockRead(SYNCHRONOUS, "hello world"),
12842 MockRead(SYNCHRONOUS, OK),
[email protected]8e6441ca2010-08-19 05:56:3812843 };
12844
[email protected]8e6441ca2010-08-19 05:56:3812845 HttpRequestInfo request;
12846 request.method = "GET";
bncce36dca22015-04-21 22:11:2312847 request.url = GURL("http://www.example.org/");
[email protected]8e6441ca2010-08-19 05:56:3812848
[email protected]bb88e1d32013-05-03 23:11:0712849 session_deps_.host_resolver->set_synchronous_mode(true);
danakj1fd259a02016-04-16 03:17:0912850 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc87dcefc2017-05-25 12:47:5812851 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:1912852 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:2712853
[email protected]8e6441ca2010-08-19 05:56:3812854 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
12855 data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:0712856 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]8e6441ca2010-08-19 05:56:3812857
[email protected]49639fa2011-12-20 23:22:4112858 TestCompletionCallback callback;
[email protected]8e6441ca2010-08-19 05:56:3812859
vishal.b62985ca92015-04-17 08:45:5112860 BoundTestNetLog log;
[email protected]49639fa2011-12-20 23:22:4112861 int rv = trans->Start(&request, callback.callback(), log.bound());
robpercival214763f2016-07-01 23:27:0112862 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]8e6441ca2010-08-19 05:56:3812863 trans.reset(); // Cancel the transaction here.
12864
fdoray92e35a72016-06-10 15:54:5512865 base::RunLoop().RunUntilIdle();
[email protected]f45c1ee2010-08-03 00:54:3012866}
12867
[email protected]ecab6e052014-05-16 14:58:1212868// Test that if a transaction is cancelled after receiving the headers, the
12869// stream is drained properly and added back to the socket pool. The main
12870// purpose of this test is to make sure that an HttpStreamParser can be read
12871// from after the HttpNetworkTransaction and the objects it owns have been
12872// deleted.
12873// See http://crbug.com/368418
bncd16676a2016-07-20 16:23:0112874TEST_F(HttpNetworkTransactionTest, CancelAfterHeaders) {
[email protected]ecab6e052014-05-16 14:58:1212875 MockRead data_reads[] = {
12876 MockRead(ASYNC, "HTTP/1.1 200 OK\r\n"),
12877 MockRead(ASYNC, "Content-Length: 2\r\n"),
12878 MockRead(ASYNC, "Connection: Keep-Alive\r\n\r\n"),
12879 MockRead(ASYNC, "1"),
12880 // 2 async reads are necessary to trigger a ReadResponseBody call after the
12881 // HttpNetworkTransaction has been deleted.
12882 MockRead(ASYNC, "2"),
12883 MockRead(SYNCHRONOUS, ERR_IO_PENDING), // Should never read this.
12884 };
12885 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
12886 session_deps_.socket_factory->AddSocketDataProvider(&data);
12887
danakj1fd259a02016-04-16 03:17:0912888 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]ecab6e052014-05-16 14:58:1212889
12890 {
12891 HttpRequestInfo request;
12892 request.method = "GET";
bncce36dca22015-04-21 22:11:2312893 request.url = GURL("http://www.example.org/");
[email protected]ecab6e052014-05-16 14:58:1212894
dcheng48459ac22014-08-26 00:46:4112895 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]ecab6e052014-05-16 14:58:1212896 TestCompletionCallback callback;
12897
tfarina42834112016-09-22 13:38:2012898 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0112899 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]ecab6e052014-05-16 14:58:1212900 callback.WaitForResult();
12901
12902 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5212903 ASSERT_TRUE(response);
12904 EXPECT_TRUE(response->headers);
[email protected]ecab6e052014-05-16 14:58:1212905 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
12906
12907 // The transaction and HttpRequestInfo are deleted.
12908 }
12909
12910 // Let the HttpResponseBodyDrainer drain the socket.
fdoray92e35a72016-06-10 15:54:5512911 base::RunLoop().RunUntilIdle();
[email protected]ecab6e052014-05-16 14:58:1212912
12913 // Socket should now be idle, waiting to be reused.
dcheng48459ac22014-08-26 00:46:4112914 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]ecab6e052014-05-16 14:58:1212915}
12916
[email protected]76a505b2010-08-25 06:23:0012917// Test a basic GET request through a proxy.
bncd16676a2016-07-20 16:23:0112918TEST_F(HttpNetworkTransactionTest, ProxyGet) {
rdsmith82957ad2015-09-16 19:42:0312919 session_deps_.proxy_service =
12920 ProxyService::CreateFixedFromPacResult("PROXY myproxy:70");
vishal.b62985ca92015-04-17 08:45:5112921 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:0712922 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:0912923 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]76a505b2010-08-25 06:23:0012924
[email protected]76a505b2010-08-25 06:23:0012925 HttpRequestInfo request;
12926 request.method = "GET";
bncce36dca22015-04-21 22:11:2312927 request.url = GURL("http://www.example.org/");
[email protected]76a505b2010-08-25 06:23:0012928
12929 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:2312930 MockWrite(
12931 "GET http://www.example.org/ HTTP/1.1\r\n"
12932 "Host: www.example.org\r\n"
12933 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]76a505b2010-08-25 06:23:0012934 };
12935
12936 MockRead data_reads1[] = {
12937 MockRead("HTTP/1.1 200 OK\r\n"),
12938 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
12939 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:0612940 MockRead(SYNCHRONOUS, OK),
[email protected]76a505b2010-08-25 06:23:0012941 };
12942
12943 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
12944 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:0712945 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]76a505b2010-08-25 06:23:0012946
[email protected]49639fa2011-12-20 23:22:4112947 TestCompletionCallback callback1;
[email protected]76a505b2010-08-25 06:23:0012948
bnc691fda62016-08-12 00:43:1612949 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
ryansturm49a8cb12016-06-15 16:51:0912950 BeforeHeadersSentHandler headers_handler;
bnc691fda62016-08-12 00:43:1612951 trans.SetBeforeHeadersSentCallback(
ryansturm49a8cb12016-06-15 16:51:0912952 base::Bind(&BeforeHeadersSentHandler::OnBeforeHeadersSent,
12953 base::Unretained(&headers_handler)));
[email protected]0b0bf032010-09-21 18:08:5012954
bnc691fda62016-08-12 00:43:1612955 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:0112956 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]76a505b2010-08-25 06:23:0012957
12958 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:0112959 EXPECT_THAT(rv, IsOk());
[email protected]76a505b2010-08-25 06:23:0012960
bnc691fda62016-08-12 00:43:1612961 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5212962 ASSERT_TRUE(response);
[email protected]76a505b2010-08-25 06:23:0012963
12964 EXPECT_TRUE(response->headers->IsKeepAlive());
12965 EXPECT_EQ(200, response->headers->response_code());
12966 EXPECT_EQ(100, response->headers->GetContentLength());
12967 EXPECT_TRUE(response->was_fetched_via_proxy);
tbansal2ecbbc72016-10-06 17:15:4712968 EXPECT_EQ(ProxyServer(ProxyServer::SCHEME_HTTP,
12969 HostPortPair::FromString("myproxy:70")),
12970 response->proxy_server);
ryansturm49a8cb12016-06-15 16:51:0912971 EXPECT_TRUE(headers_handler.observed_before_headers_sent());
12972 EXPECT_TRUE(headers_handler.observed_before_headers_sent_with_proxy());
12973 EXPECT_EQ("myproxy:70", headers_handler.observed_proxy_server_uri());
[email protected]76a505b2010-08-25 06:23:0012974 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
[email protected]029c83b62013-01-24 05:28:2012975
12976 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:1612977 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]029c83b62013-01-24 05:28:2012978 TestLoadTimingNotReusedWithPac(load_timing_info,
12979 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
[email protected]76a505b2010-08-25 06:23:0012980}
12981
12982// Test a basic HTTPS GET request through a proxy.
bncd16676a2016-07-20 16:23:0112983TEST_F(HttpNetworkTransactionTest, ProxyTunnelGet) {
rdsmith82957ad2015-09-16 19:42:0312984 session_deps_.proxy_service =
12985 ProxyService::CreateFixedFromPacResult("PROXY myproxy:70");
vishal.b62985ca92015-04-17 08:45:5112986 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:0712987 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:0912988 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]76a505b2010-08-25 06:23:0012989
[email protected]76a505b2010-08-25 06:23:0012990 HttpRequestInfo request;
12991 request.method = "GET";
bncce36dca22015-04-21 22:11:2312992 request.url = GURL("https://www.example.org/");
[email protected]76a505b2010-08-25 06:23:0012993
12994 // Since we have proxy, should try to establish tunnel.
12995 MockWrite data_writes1[] = {
rsleevidb16bb02015-11-12 23:47:1712996 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
12997 "Host: www.example.org:443\r\n"
12998 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]76a505b2010-08-25 06:23:0012999
rsleevidb16bb02015-11-12 23:47:1713000 MockWrite("GET / HTTP/1.1\r\n"
13001 "Host: www.example.org\r\n"
13002 "Connection: keep-alive\r\n\r\n"),
[email protected]76a505b2010-08-25 06:23:0013003 };
13004
13005 MockRead data_reads1[] = {
13006 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
13007
13008 MockRead("HTTP/1.1 200 OK\r\n"),
13009 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
13010 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:0613011 MockRead(SYNCHRONOUS, OK),
[email protected]76a505b2010-08-25 06:23:0013012 };
13013
13014 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
13015 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:0713016 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8ddf8322012-02-23 18:08:0613017 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:0713018 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]76a505b2010-08-25 06:23:0013019
[email protected]49639fa2011-12-20 23:22:4113020 TestCompletionCallback callback1;
[email protected]76a505b2010-08-25 06:23:0013021
bnc691fda62016-08-12 00:43:1613022 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
ryansturm49a8cb12016-06-15 16:51:0913023 BeforeHeadersSentHandler headers_handler;
bnc691fda62016-08-12 00:43:1613024 trans.SetBeforeHeadersSentCallback(
ryansturm49a8cb12016-06-15 16:51:0913025 base::Bind(&BeforeHeadersSentHandler::OnBeforeHeadersSent,
13026 base::Unretained(&headers_handler)));
[email protected]0b0bf032010-09-21 18:08:5013027
bnc691fda62016-08-12 00:43:1613028 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:0113029 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]76a505b2010-08-25 06:23:0013030
13031 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:0113032 EXPECT_THAT(rv, IsOk());
mmenke43758e62015-05-04 21:09:4613033 TestNetLogEntry::List entries;
[email protected]b2fcd0e2010-12-01 15:19:4013034 log.GetEntries(&entries);
[email protected]76a505b2010-08-25 06:23:0013035 size_t pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:0013036 entries, 0, NetLogEventType::HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
13037 NetLogEventPhase::NONE);
[email protected]76a505b2010-08-25 06:23:0013038 ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:4013039 entries, pos,
mikecirone8b85c432016-09-08 19:11:0013040 NetLogEventType::HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
13041 NetLogEventPhase::NONE);
[email protected]76a505b2010-08-25 06:23:0013042
bnc691fda62016-08-12 00:43:1613043 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5213044 ASSERT_TRUE(response);
[email protected]76a505b2010-08-25 06:23:0013045
13046 EXPECT_TRUE(response->headers->IsKeepAlive());
13047 EXPECT_EQ(200, response->headers->response_code());
13048 EXPECT_EQ(100, response->headers->GetContentLength());
13049 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
13050 EXPECT_TRUE(response->was_fetched_via_proxy);
tbansal2ecbbc72016-10-06 17:15:4713051 EXPECT_EQ(ProxyServer(ProxyServer::SCHEME_HTTP,
13052 HostPortPair::FromString("myproxy:70")),
13053 response->proxy_server);
ryansturm49a8cb12016-06-15 16:51:0913054 EXPECT_TRUE(headers_handler.observed_before_headers_sent());
13055 EXPECT_TRUE(headers_handler.observed_before_headers_sent_with_proxy());
13056 EXPECT_EQ("myproxy:70", headers_handler.observed_proxy_server_uri());
[email protected]029c83b62013-01-24 05:28:2013057
13058 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:1613059 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]029c83b62013-01-24 05:28:2013060 TestLoadTimingNotReusedWithPac(load_timing_info,
13061 CONNECT_TIMING_HAS_SSL_TIMES);
[email protected]76a505b2010-08-25 06:23:0013062}
13063
rsleevidb16bb02015-11-12 23:47:1713064// Test a basic HTTPS GET request through a proxy, connecting to an IPv6
13065// literal host.
bncd16676a2016-07-20 16:23:0113066TEST_F(HttpNetworkTransactionTest, ProxyTunnelGetIPv6) {
rsleevidb16bb02015-11-12 23:47:1713067 session_deps_.proxy_service =
13068 ProxyService::CreateFixedFromPacResult("PROXY myproxy:70");
13069 BoundTestNetLog log;
13070 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:0913071 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
rsleevidb16bb02015-11-12 23:47:1713072
13073 HttpRequestInfo request;
13074 request.method = "GET";
13075 request.url = GURL("https://[::1]:443/");
13076
13077 // Since we have proxy, should try to establish tunnel.
13078 MockWrite data_writes1[] = {
13079 MockWrite("CONNECT [::1]:443 HTTP/1.1\r\n"
13080 "Host: [::1]:443\r\n"
13081 "Proxy-Connection: keep-alive\r\n\r\n"),
13082
13083 MockWrite("GET / HTTP/1.1\r\n"
13084 "Host: [::1]\r\n"
13085 "Connection: keep-alive\r\n\r\n"),
13086 };
13087
13088 MockRead data_reads1[] = {
13089 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
13090
13091 MockRead("HTTP/1.1 200 OK\r\n"),
13092 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
13093 MockRead("Content-Length: 100\r\n\r\n"),
13094 MockRead(SYNCHRONOUS, OK),
13095 };
13096
13097 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
13098 data_writes1, arraysize(data_writes1));
13099 session_deps_.socket_factory->AddSocketDataProvider(&data1);
13100 SSLSocketDataProvider ssl(ASYNC, OK);
13101 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
13102
13103 TestCompletionCallback callback1;
13104
bnc691fda62016-08-12 00:43:1613105 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
rsleevidb16bb02015-11-12 23:47:1713106
bnc691fda62016-08-12 00:43:1613107 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:0113108 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
rsleevidb16bb02015-11-12 23:47:1713109
13110 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:0113111 EXPECT_THAT(rv, IsOk());
rsleevidb16bb02015-11-12 23:47:1713112 TestNetLogEntry::List entries;
13113 log.GetEntries(&entries);
13114 size_t pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:0013115 entries, 0, NetLogEventType::HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
13116 NetLogEventPhase::NONE);
rsleevidb16bb02015-11-12 23:47:1713117 ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:0013118 entries, pos,
13119 NetLogEventType::HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
13120 NetLogEventPhase::NONE);
rsleevidb16bb02015-11-12 23:47:1713121
bnc691fda62016-08-12 00:43:1613122 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5213123 ASSERT_TRUE(response);
rsleevidb16bb02015-11-12 23:47:1713124
13125 EXPECT_TRUE(response->headers->IsKeepAlive());
13126 EXPECT_EQ(200, response->headers->response_code());
13127 EXPECT_EQ(100, response->headers->GetContentLength());
13128 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
13129 EXPECT_TRUE(response->was_fetched_via_proxy);
tbansal2ecbbc72016-10-06 17:15:4713130 EXPECT_EQ(ProxyServer(ProxyServer::SCHEME_HTTP,
13131 HostPortPair::FromString("myproxy:70")),
13132 response->proxy_server);
rsleevidb16bb02015-11-12 23:47:1713133
13134 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:1613135 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
rsleevidb16bb02015-11-12 23:47:1713136 TestLoadTimingNotReusedWithPac(load_timing_info,
13137 CONNECT_TIMING_HAS_SSL_TIMES);
13138}
13139
[email protected]76a505b2010-08-25 06:23:0013140// Test a basic HTTPS GET request through a proxy, but the server hangs up
13141// while establishing the tunnel.
bncd16676a2016-07-20 16:23:0113142TEST_F(HttpNetworkTransactionTest, ProxyTunnelGetHangup) {
rdsmith82957ad2015-09-16 19:42:0313143 session_deps_.proxy_service = ProxyService::CreateFixed("myproxy:70");
vishal.b62985ca92015-04-17 08:45:5113144 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:0713145 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:0913146 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]76a505b2010-08-25 06:23:0013147
[email protected]76a505b2010-08-25 06:23:0013148 HttpRequestInfo request;
13149 request.method = "GET";
bncce36dca22015-04-21 22:11:2313150 request.url = GURL("https://www.example.org/");
[email protected]76a505b2010-08-25 06:23:0013151
13152 // Since we have proxy, should try to establish tunnel.
13153 MockWrite data_writes1[] = {
rsleevidb16bb02015-11-12 23:47:1713154 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
13155 "Host: www.example.org:443\r\n"
13156 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]76a505b2010-08-25 06:23:0013157
rsleevidb16bb02015-11-12 23:47:1713158 MockWrite("GET / HTTP/1.1\r\n"
13159 "Host: www.example.org\r\n"
13160 "Connection: keep-alive\r\n\r\n"),
[email protected]76a505b2010-08-25 06:23:0013161 };
13162
13163 MockRead data_reads1[] = {
[email protected]8ddf8322012-02-23 18:08:0613164 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
[email protected]76a505b2010-08-25 06:23:0013165 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:0613166 MockRead(ASYNC, 0, 0), // EOF
[email protected]76a505b2010-08-25 06:23:0013167 };
13168
13169 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
13170 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:0713171 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8ddf8322012-02-23 18:08:0613172 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:0713173 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]76a505b2010-08-25 06:23:0013174
[email protected]49639fa2011-12-20 23:22:4113175 TestCompletionCallback callback1;
[email protected]76a505b2010-08-25 06:23:0013176
bnc691fda62016-08-12 00:43:1613177 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]0b0bf032010-09-21 18:08:5013178
bnc691fda62016-08-12 00:43:1613179 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:0113180 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]76a505b2010-08-25 06:23:0013181
13182 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:0113183 EXPECT_THAT(rv, IsError(ERR_EMPTY_RESPONSE));
mmenke43758e62015-05-04 21:09:4613184 TestNetLogEntry::List entries;
[email protected]b2fcd0e2010-12-01 15:19:4013185 log.GetEntries(&entries);
[email protected]76a505b2010-08-25 06:23:0013186 size_t pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:0013187 entries, 0, NetLogEventType::HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
13188 NetLogEventPhase::NONE);
[email protected]76a505b2010-08-25 06:23:0013189 ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:4013190 entries, pos,
mikecirone8b85c432016-09-08 19:11:0013191 NetLogEventType::HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
13192 NetLogEventPhase::NONE);
[email protected]76a505b2010-08-25 06:23:0013193}
13194
[email protected]749eefa82010-09-13 22:14:0313195// Test for crbug.com/55424.
bncd16676a2016-07-20 16:23:0113196TEST_F(HttpNetworkTransactionTest, PreconnectWithExistingSpdySession) {
bncdf80d44fd2016-07-15 20:27:4113197 SpdySerializedFrame req(
bnc38dcd392016-02-09 23:19:4913198 spdy_util_.ConstructSpdyGet("https://www.example.org", 1, LOWEST));
bncdf80d44fd2016-07-15 20:27:4113199 MockWrite spdy_writes[] = {CreateMockWrite(req, 0)};
[email protected]749eefa82010-09-13 22:14:0313200
bnc42331402016-07-25 13:36:1513201 SpdySerializedFrame resp(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
bncdf80d44fd2016-07-15 20:27:4113202 SpdySerializedFrame data(spdy_util_.ConstructSpdyDataFrame(1, true));
[email protected]749eefa82010-09-13 22:14:0313203 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:4113204 CreateMockRead(resp, 1), CreateMockRead(data, 2), MockRead(ASYNC, 0, 3),
[email protected]749eefa82010-09-13 22:14:0313205 };
13206
rch8e6c6c42015-05-01 14:05:1313207 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
13208 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:0713209 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]749eefa82010-09-13 22:14:0313210
[email protected]8ddf8322012-02-23 18:08:0613211 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3613212 ssl.next_proto = kProtoHTTP2;
[email protected]bb88e1d32013-05-03 23:11:0713213 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]749eefa82010-09-13 22:14:0313214
danakj1fd259a02016-04-16 03:17:0913215 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]749eefa82010-09-13 22:14:0313216
13217 // Set up an initial SpdySession in the pool to reuse.
bncce36dca22015-04-21 22:11:2313218 HostPortPair host_port_pair("www.example.org", 443);
[email protected]e6d017652013-05-17 18:01:4013219 SpdySessionKey key(host_port_pair, ProxyServer::Direct(),
[email protected]314b03992014-04-01 01:28:5313220 PRIVACY_MODE_DISABLED);
[email protected]795cbf82013-07-22 09:37:2713221 base::WeakPtr<SpdySession> spdy_session =
Bence Béky0ef1556e2017-06-30 19:52:5213222 CreateSpdySession(session.get(), key, NetLogWithSource());
[email protected]749eefa82010-09-13 22:14:0313223
13224 HttpRequestInfo request;
13225 request.method = "GET";
bncce36dca22015-04-21 22:11:2313226 request.url = GURL("https://www.example.org/");
[email protected]749eefa82010-09-13 22:14:0313227
13228 // This is the important line that marks this as a preconnect.
13229 request.motivation = HttpRequestInfo::PRECONNECT_MOTIVATED;
13230
bnc691fda62016-08-12 00:43:1613231 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]749eefa82010-09-13 22:14:0313232
[email protected]41d64e82013-07-03 22:44:2613233 TestCompletionCallback callback;
tfarina42834112016-09-22 13:38:2013234 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0113235 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
13236 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]749eefa82010-09-13 22:14:0313237}
13238
[email protected]73b8dd222010-11-11 19:55:2413239// Given a net error, cause that error to be returned from the first Write()
bnc691fda62016-08-12 00:43:1613240// call and verify that the HttpNetworkTransaction fails with that error.
[email protected]23e482282013-06-14 16:08:0213241void HttpNetworkTransactionTest::CheckErrorIsPassedBack(
[email protected]bb88e1d32013-05-03 23:11:0713242 int error, IoMode mode) {
ttuttle859dc7a2015-04-23 19:42:2913243 HttpRequestInfo request_info;
[email protected]cb9bf6ca2011-01-28 13:15:2713244 request_info.url = GURL("https://www.example.com/");
13245 request_info.method = "GET";
ttuttle859dc7a2015-04-23 19:42:2913246 request_info.load_flags = LOAD_NORMAL;
[email protected]cb9bf6ca2011-01-28 13:15:2713247
[email protected]8ddf8322012-02-23 18:08:0613248 SSLSocketDataProvider ssl_data(mode, OK);
ttuttle859dc7a2015-04-23 19:42:2913249 MockWrite data_writes[] = {
13250 MockWrite(mode, error),
[email protected]73b8dd222010-11-11 19:55:2413251 };
ttuttle859dc7a2015-04-23 19:42:2913252 StaticSocketDataProvider data(NULL, 0, data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:0713253 session_deps_.socket_factory->AddSocketDataProvider(&data);
13254 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data);
[email protected]73b8dd222010-11-11 19:55:2413255
danakj1fd259a02016-04-16 03:17:0913256 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1613257 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]73b8dd222010-11-11 19:55:2413258
[email protected]49639fa2011-12-20 23:22:4113259 TestCompletionCallback callback;
tfarina42834112016-09-22 13:38:2013260 int rv = trans.Start(&request_info, callback.callback(), NetLogWithSource());
ttuttle859dc7a2015-04-23 19:42:2913261 if (rv == ERR_IO_PENDING)
[email protected]73b8dd222010-11-11 19:55:2413262 rv = callback.WaitForResult();
13263 ASSERT_EQ(error, rv);
13264}
13265
bncd16676a2016-07-20 16:23:0113266TEST_F(HttpNetworkTransactionTest, SSLWriteCertError) {
[email protected]73b8dd222010-11-11 19:55:2413267 // Just check a grab bag of cert errors.
13268 static const int kErrors[] = {
13269 ERR_CERT_COMMON_NAME_INVALID,
13270 ERR_CERT_AUTHORITY_INVALID,
13271 ERR_CERT_DATE_INVALID,
13272 };
13273 for (size_t i = 0; i < arraysize(kErrors); i++) {
[email protected]8ddf8322012-02-23 18:08:0613274 CheckErrorIsPassedBack(kErrors[i], ASYNC);
13275 CheckErrorIsPassedBack(kErrors[i], SYNCHRONOUS);
[email protected]73b8dd222010-11-11 19:55:2413276 }
13277}
13278
[email protected]bd0b6772011-01-11 19:59:3013279// Ensure that a client certificate is removed from the SSL client auth
13280// cache when:
13281// 1) No proxy is involved.
13282// 2) TLS False Start is disabled.
13283// 3) The initial TLS handshake requests a client certificate.
13284// 4) The client supplies an invalid/unacceptable certificate.
bncd16676a2016-07-20 16:23:0113285TEST_F(HttpNetworkTransactionTest, ClientAuthCertCache_Direct_NoFalseStart) {
ttuttle859dc7a2015-04-23 19:42:2913286 HttpRequestInfo request_info;
[email protected]cb9bf6ca2011-01-28 13:15:2713287 request_info.url = GURL("https://www.example.com/");
13288 request_info.method = "GET";
ttuttle859dc7a2015-04-23 19:42:2913289 request_info.load_flags = LOAD_NORMAL;
[email protected]cb9bf6ca2011-01-28 13:15:2713290
[email protected]bd0b6772011-01-11 19:59:3013291 scoped_refptr<SSLCertRequestInfo> cert_request(new SSLCertRequestInfo());
[email protected]791879c2013-12-17 07:22:4113292 cert_request->host_and_port = HostPortPair("www.example.com", 443);
[email protected]bd0b6772011-01-11 19:59:3013293
13294 // [ssl_]data1 contains the data for the first SSL handshake. When a
13295 // CertificateRequest is received for the first time, the handshake will
13296 // be aborted to allow the caller to provide a certificate.
ttuttle859dc7a2015-04-23 19:42:2913297 SSLSocketDataProvider ssl_data1(ASYNC, ERR_SSL_CLIENT_AUTH_CERT_NEEDED);
[email protected]bd0b6772011-01-11 19:59:3013298 ssl_data1.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0713299 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data1);
ttuttle859dc7a2015-04-23 19:42:2913300 StaticSocketDataProvider data1(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0713301 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]bd0b6772011-01-11 19:59:3013302
13303 // [ssl_]data2 contains the data for the second SSL handshake. When TLS
13304 // False Start is not being used, the result of the SSL handshake will be
13305 // returned as part of the SSLClientSocket::Connect() call. This test
13306 // matches the result of a server sending a handshake_failure alert,
13307 // rather than a Finished message, because it requires a client
13308 // certificate and none was supplied.
ttuttle859dc7a2015-04-23 19:42:2913309 SSLSocketDataProvider ssl_data2(ASYNC, ERR_SSL_PROTOCOL_ERROR);
[email protected]bd0b6772011-01-11 19:59:3013310 ssl_data2.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0713311 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data2);
ttuttle859dc7a2015-04-23 19:42:2913312 StaticSocketDataProvider data2(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0713313 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]bd0b6772011-01-11 19:59:3013314
13315 // [ssl_]data3 contains the data for the third SSL handshake. When a
13316 // connection to a server fails during an SSL handshake,
davidbenb937d6c2015-05-14 04:53:4213317 // HttpNetworkTransaction will attempt to fallback to TLSv1.1 if the previous
13318 // connection was attempted with TLSv1.2. This is transparent to the caller
[email protected]bd0b6772011-01-11 19:59:3013319 // of the HttpNetworkTransaction. Because this test failure is due to
13320 // requiring a client certificate, this fallback handshake should also
13321 // fail.
ttuttle859dc7a2015-04-23 19:42:2913322 SSLSocketDataProvider ssl_data3(ASYNC, ERR_SSL_PROTOCOL_ERROR);
[email protected]bd0b6772011-01-11 19:59:3013323 ssl_data3.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0713324 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data3);
ttuttle859dc7a2015-04-23 19:42:2913325 StaticSocketDataProvider data3(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0713326 session_deps_.socket_factory->AddSocketDataProvider(&data3);
[email protected]bd0b6772011-01-11 19:59:3013327
[email protected]80c75f682012-05-26 16:22:1713328 // [ssl_]data4 contains the data for the fourth SSL handshake. When a
13329 // connection to a server fails during an SSL handshake,
davidbenb937d6c2015-05-14 04:53:4213330 // HttpNetworkTransaction will attempt to fallback to TLSv1 if the previous
13331 // connection was attempted with TLSv1.1. This is transparent to the caller
[email protected]80c75f682012-05-26 16:22:1713332 // of the HttpNetworkTransaction. Because this test failure is due to
13333 // requiring a client certificate, this fallback handshake should also
13334 // fail.
ttuttle859dc7a2015-04-23 19:42:2913335 SSLSocketDataProvider ssl_data4(ASYNC, ERR_SSL_PROTOCOL_ERROR);
[email protected]80c75f682012-05-26 16:22:1713336 ssl_data4.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0713337 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data4);
ttuttle859dc7a2015-04-23 19:42:2913338 StaticSocketDataProvider data4(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0713339 session_deps_.socket_factory->AddSocketDataProvider(&data4);
[email protected]80c75f682012-05-26 16:22:1713340
danakj1fd259a02016-04-16 03:17:0913341 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1613342 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]bd0b6772011-01-11 19:59:3013343
[email protected]bd0b6772011-01-11 19:59:3013344 // Begin the SSL handshake with the peer. This consumes ssl_data1.
[email protected]49639fa2011-12-20 23:22:4113345 TestCompletionCallback callback;
tfarina42834112016-09-22 13:38:2013346 int rv = trans.Start(&request_info, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0113347 ASSERT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]bd0b6772011-01-11 19:59:3013348
13349 // Complete the SSL handshake, which should abort due to requiring a
13350 // client certificate.
13351 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0113352 ASSERT_THAT(rv, IsError(ERR_SSL_CLIENT_AUTH_CERT_NEEDED));
[email protected]bd0b6772011-01-11 19:59:3013353
13354 // Indicate that no certificate should be supplied. From the perspective
13355 // of SSLClientCertCache, NULL is just as meaningful as a real
13356 // certificate, so this is the same as supply a
13357 // legitimate-but-unacceptable certificate.
bnc691fda62016-08-12 00:43:1613358 rv = trans.RestartWithCertificate(NULL, NULL, callback.callback());
robpercival214763f2016-07-01 23:27:0113359 ASSERT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]bd0b6772011-01-11 19:59:3013360
13361 // Ensure the certificate was added to the client auth cache before
13362 // allowing the connection to continue restarting.
13363 scoped_refptr<X509Certificate> client_cert;
svaldez7872fd02015-11-19 21:10:5413364 scoped_refptr<SSLPrivateKey> client_private_key;
[email protected]791879c2013-12-17 07:22:4113365 ASSERT_TRUE(session->ssl_client_auth_cache()->Lookup(
svaldez7872fd02015-11-19 21:10:5413366 HostPortPair("www.example.com", 443), &client_cert, &client_private_key));
wezca1070932016-05-26 20:30:5213367 ASSERT_FALSE(client_cert);
[email protected]bd0b6772011-01-11 19:59:3013368
13369 // Restart the handshake. This will consume ssl_data2, which fails, and
[email protected]80c75f682012-05-26 16:22:1713370 // then consume ssl_data3 and ssl_data4, both of which should also fail.
13371 // The result code is checked against what ssl_data4 should return.
[email protected]bd0b6772011-01-11 19:59:3013372 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0113373 ASSERT_THAT(rv, IsError(ERR_SSL_PROTOCOL_ERROR));
[email protected]bd0b6772011-01-11 19:59:3013374
13375 // Ensure that the client certificate is removed from the cache on a
13376 // handshake failure.
[email protected]791879c2013-12-17 07:22:4113377 ASSERT_FALSE(session->ssl_client_auth_cache()->Lookup(
svaldez7872fd02015-11-19 21:10:5413378 HostPortPair("www.example.com", 443), &client_cert, &client_private_key));
[email protected]bd0b6772011-01-11 19:59:3013379}
13380
13381// Ensure that a client certificate is removed from the SSL client auth
13382// cache when:
13383// 1) No proxy is involved.
13384// 2) TLS False Start is enabled.
13385// 3) The initial TLS handshake requests a client certificate.
13386// 4) The client supplies an invalid/unacceptable certificate.
bncd16676a2016-07-20 16:23:0113387TEST_F(HttpNetworkTransactionTest, ClientAuthCertCache_Direct_FalseStart) {
ttuttle859dc7a2015-04-23 19:42:2913388 HttpRequestInfo request_info;
[email protected]cb9bf6ca2011-01-28 13:15:2713389 request_info.url = GURL("https://www.example.com/");
13390 request_info.method = "GET";
ttuttle859dc7a2015-04-23 19:42:2913391 request_info.load_flags = LOAD_NORMAL;
[email protected]cb9bf6ca2011-01-28 13:15:2713392
[email protected]bd0b6772011-01-11 19:59:3013393 scoped_refptr<SSLCertRequestInfo> cert_request(new SSLCertRequestInfo());
[email protected]791879c2013-12-17 07:22:4113394 cert_request->host_and_port = HostPortPair("www.example.com", 443);
[email protected]bd0b6772011-01-11 19:59:3013395
13396 // When TLS False Start is used, SSLClientSocket::Connect() calls will
13397 // return successfully after reading up to the peer's Certificate message.
13398 // This is to allow the caller to call SSLClientSocket::Write(), which can
13399 // enqueue application data to be sent in the same packet as the
13400 // ChangeCipherSpec and Finished messages.
13401 // The actual handshake will be finished when SSLClientSocket::Read() is
13402 // called, which expects to process the peer's ChangeCipherSpec and
13403 // Finished messages. If there was an error negotiating with the peer,
13404 // such as due to the peer requiring a client certificate when none was
13405 // supplied, the alert sent by the peer won't be processed until Read() is
13406 // called.
13407
13408 // Like the non-False Start case, when a client certificate is requested by
13409 // the peer, the handshake is aborted during the Connect() call.
13410 // [ssl_]data1 represents the initial SSL handshake with the peer.
ttuttle859dc7a2015-04-23 19:42:2913411 SSLSocketDataProvider ssl_data1(ASYNC, ERR_SSL_CLIENT_AUTH_CERT_NEEDED);
[email protected]bd0b6772011-01-11 19:59:3013412 ssl_data1.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0713413 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data1);
ttuttle859dc7a2015-04-23 19:42:2913414 StaticSocketDataProvider data1(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0713415 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]bd0b6772011-01-11 19:59:3013416
13417 // When a client certificate is supplied, Connect() will not be aborted
13418 // when the peer requests the certificate. Instead, the handshake will
13419 // artificially succeed, allowing the caller to write the HTTP request to
13420 // the socket. The handshake messages are not processed until Read() is
13421 // called, which then detects that the handshake was aborted, due to the
13422 // peer sending a handshake_failure because it requires a client
13423 // certificate.
ttuttle859dc7a2015-04-23 19:42:2913424 SSLSocketDataProvider ssl_data2(ASYNC, OK);
[email protected]bd0b6772011-01-11 19:59:3013425 ssl_data2.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0713426 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data2);
ttuttle859dc7a2015-04-23 19:42:2913427 MockRead data2_reads[] = {
13428 MockRead(ASYNC /* async */, ERR_SSL_PROTOCOL_ERROR),
[email protected]bd0b6772011-01-11 19:59:3013429 };
ttuttle859dc7a2015-04-23 19:42:2913430 StaticSocketDataProvider data2(data2_reads, arraysize(data2_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0713431 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]bd0b6772011-01-11 19:59:3013432
13433 // As described in ClientAuthCertCache_Direct_NoFalseStart, [ssl_]data3 is
[email protected]80c75f682012-05-26 16:22:1713434 // the data for the SSL handshake once the TLSv1.1 connection falls back to
13435 // TLSv1. It has the same behaviour as [ssl_]data2.
ttuttle859dc7a2015-04-23 19:42:2913436 SSLSocketDataProvider ssl_data3(ASYNC, OK);
[email protected]bd0b6772011-01-11 19:59:3013437 ssl_data3.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0713438 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data3);
ttuttle859dc7a2015-04-23 19:42:2913439 StaticSocketDataProvider data3(data2_reads, arraysize(data2_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0713440 session_deps_.socket_factory->AddSocketDataProvider(&data3);
[email protected]bd0b6772011-01-11 19:59:3013441
[email protected]80c75f682012-05-26 16:22:1713442 // [ssl_]data4 is the data for the SSL handshake once the TLSv1 connection
13443 // falls back to SSLv3. It has the same behaviour as [ssl_]data2.
ttuttle859dc7a2015-04-23 19:42:2913444 SSLSocketDataProvider ssl_data4(ASYNC, OK);
[email protected]80c75f682012-05-26 16:22:1713445 ssl_data4.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0713446 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data4);
ttuttle859dc7a2015-04-23 19:42:2913447 StaticSocketDataProvider data4(data2_reads, arraysize(data2_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0713448 session_deps_.socket_factory->AddSocketDataProvider(&data4);
[email protected]80c75f682012-05-26 16:22:1713449
[email protected]7799de12013-05-30 05:52:5113450 // Need one more if TLSv1.2 is enabled.
ttuttle859dc7a2015-04-23 19:42:2913451 SSLSocketDataProvider ssl_data5(ASYNC, OK);
[email protected]7799de12013-05-30 05:52:5113452 ssl_data5.cert_request_info = cert_request.get();
13453 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data5);
ttuttle859dc7a2015-04-23 19:42:2913454 StaticSocketDataProvider data5(data2_reads, arraysize(data2_reads), NULL, 0);
[email protected]7799de12013-05-30 05:52:5113455 session_deps_.socket_factory->AddSocketDataProvider(&data5);
13456
danakj1fd259a02016-04-16 03:17:0913457 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1613458 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]bd0b6772011-01-11 19:59:3013459
[email protected]bd0b6772011-01-11 19:59:3013460 // Begin the initial SSL handshake.
[email protected]49639fa2011-12-20 23:22:4113461 TestCompletionCallback callback;
tfarina42834112016-09-22 13:38:2013462 int rv = trans.Start(&request_info, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0113463 ASSERT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]bd0b6772011-01-11 19:59:3013464
13465 // Complete the SSL handshake, which should abort due to requiring a
13466 // client certificate.
13467 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0113468 ASSERT_THAT(rv, IsError(ERR_SSL_CLIENT_AUTH_CERT_NEEDED));
[email protected]bd0b6772011-01-11 19:59:3013469
13470 // Indicate that no certificate should be supplied. From the perspective
13471 // of SSLClientCertCache, NULL is just as meaningful as a real
13472 // certificate, so this is the same as supply a
13473 // legitimate-but-unacceptable certificate.
bnc691fda62016-08-12 00:43:1613474 rv = trans.RestartWithCertificate(NULL, NULL, callback.callback());
robpercival214763f2016-07-01 23:27:0113475 ASSERT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]bd0b6772011-01-11 19:59:3013476
13477 // Ensure the certificate was added to the client auth cache before
13478 // allowing the connection to continue restarting.
13479 scoped_refptr<X509Certificate> client_cert;
svaldez7872fd02015-11-19 21:10:5413480 scoped_refptr<SSLPrivateKey> client_private_key;
[email protected]791879c2013-12-17 07:22:4113481 ASSERT_TRUE(session->ssl_client_auth_cache()->Lookup(
svaldez7872fd02015-11-19 21:10:5413482 HostPortPair("www.example.com", 443), &client_cert, &client_private_key));
wezca1070932016-05-26 20:30:5213483 ASSERT_FALSE(client_cert);
[email protected]bd0b6772011-01-11 19:59:3013484
[email protected]bd0b6772011-01-11 19:59:3013485 // Restart the handshake. This will consume ssl_data2, which fails, and
[email protected]80c75f682012-05-26 16:22:1713486 // then consume ssl_data3 and ssl_data4, both of which should also fail.
13487 // The result code is checked against what ssl_data4 should return.
[email protected]bd0b6772011-01-11 19:59:3013488 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0113489 ASSERT_THAT(rv, IsError(ERR_SSL_PROTOCOL_ERROR));
[email protected]bd0b6772011-01-11 19:59:3013490
13491 // Ensure that the client certificate is removed from the cache on a
13492 // handshake failure.
[email protected]791879c2013-12-17 07:22:4113493 ASSERT_FALSE(session->ssl_client_auth_cache()->Lookup(
svaldez7872fd02015-11-19 21:10:5413494 HostPortPair("www.example.com", 443), &client_cert, &client_private_key));
[email protected]bd0b6772011-01-11 19:59:3013495}
13496
[email protected]8c405132011-01-11 22:03:1813497// Ensure that a client certificate is removed from the SSL client auth
13498// cache when:
13499// 1) An HTTPS proxy is involved.
13500// 3) The HTTPS proxy requests a client certificate.
13501// 4) The client supplies an invalid/unacceptable certificate for the
13502// proxy.
13503// The test is repeated twice, first for connecting to an HTTPS endpoint,
13504// then for connecting to an HTTP endpoint.
bncd16676a2016-07-20 16:23:0113505TEST_F(HttpNetworkTransactionTest, ClientAuthCertCache_Proxy_Fail) {
rdsmith82957ad2015-09-16 19:42:0313506 session_deps_.proxy_service = ProxyService::CreateFixed("https://proxy:70");
vishal.b62985ca92015-04-17 08:45:5113507 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:0713508 session_deps_.net_log = log.bound().net_log();
[email protected]8c405132011-01-11 22:03:1813509
13510 scoped_refptr<SSLCertRequestInfo> cert_request(new SSLCertRequestInfo());
[email protected]791879c2013-12-17 07:22:4113511 cert_request->host_and_port = HostPortPair("proxy", 70);
[email protected]8c405132011-01-11 22:03:1813512
13513 // See ClientAuthCertCache_Direct_NoFalseStart for the explanation of
13514 // [ssl_]data[1-3]. Rather than represending the endpoint
13515 // (www.example.com:443), they represent failures with the HTTPS proxy
13516 // (proxy:70).
ttuttle859dc7a2015-04-23 19:42:2913517 SSLSocketDataProvider ssl_data1(ASYNC, ERR_SSL_CLIENT_AUTH_CERT_NEEDED);
[email protected]8c405132011-01-11 22:03:1813518 ssl_data1.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0713519 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data1);
ttuttle859dc7a2015-04-23 19:42:2913520 StaticSocketDataProvider data1(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0713521 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8c405132011-01-11 22:03:1813522
ttuttle859dc7a2015-04-23 19:42:2913523 SSLSocketDataProvider ssl_data2(ASYNC, ERR_SSL_PROTOCOL_ERROR);
[email protected]8c405132011-01-11 22:03:1813524 ssl_data2.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0713525 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data2);
ttuttle859dc7a2015-04-23 19:42:2913526 StaticSocketDataProvider data2(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0713527 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]8c405132011-01-11 22:03:1813528
[email protected]80c75f682012-05-26 16:22:1713529 // TODO(wtc): find out why this unit test doesn't need [ssl_]data3.
13530#if 0
ttuttle859dc7a2015-04-23 19:42:2913531 SSLSocketDataProvider ssl_data3(ASYNC, ERR_SSL_PROTOCOL_ERROR);
[email protected]8c405132011-01-11 22:03:1813532 ssl_data3.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0713533 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data3);
ttuttle859dc7a2015-04-23 19:42:2913534 StaticSocketDataProvider data3(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0713535 session_deps_.socket_factory->AddSocketDataProvider(&data3);
[email protected]80c75f682012-05-26 16:22:1713536#endif
[email protected]8c405132011-01-11 22:03:1813537
ttuttle859dc7a2015-04-23 19:42:2913538 HttpRequestInfo requests[2];
[email protected]8c405132011-01-11 22:03:1813539 requests[0].url = GURL("https://www.example.com/");
13540 requests[0].method = "GET";
ttuttle859dc7a2015-04-23 19:42:2913541 requests[0].load_flags = LOAD_NORMAL;
[email protected]8c405132011-01-11 22:03:1813542
13543 requests[1].url = GURL("http://www.example.com/");
13544 requests[1].method = "GET";
ttuttle859dc7a2015-04-23 19:42:2913545 requests[1].load_flags = LOAD_NORMAL;
[email protected]8c405132011-01-11 22:03:1813546
13547 for (size_t i = 0; i < arraysize(requests); ++i) {
[email protected]bb88e1d32013-05-03 23:11:0713548 session_deps_.socket_factory->ResetNextMockIndexes();
danakj1fd259a02016-04-16 03:17:0913549 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1613550 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]8c405132011-01-11 22:03:1813551
13552 // Begin the SSL handshake with the proxy.
[email protected]49639fa2011-12-20 23:22:4113553 TestCompletionCallback callback;
tfarina42834112016-09-22 13:38:2013554 int rv = trans.Start(&requests[i], callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0113555 ASSERT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]8c405132011-01-11 22:03:1813556
13557 // Complete the SSL handshake, which should abort due to requiring a
13558 // client certificate.
13559 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0113560 ASSERT_THAT(rv, IsError(ERR_SSL_CLIENT_AUTH_CERT_NEEDED));
[email protected]8c405132011-01-11 22:03:1813561
13562 // Indicate that no certificate should be supplied. From the perspective
13563 // of SSLClientCertCache, NULL is just as meaningful as a real
13564 // certificate, so this is the same as supply a
13565 // legitimate-but-unacceptable certificate.
bnc691fda62016-08-12 00:43:1613566 rv = trans.RestartWithCertificate(NULL, NULL, callback.callback());
robpercival214763f2016-07-01 23:27:0113567 ASSERT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]8c405132011-01-11 22:03:1813568
13569 // Ensure the certificate was added to the client auth cache before
13570 // allowing the connection to continue restarting.
13571 scoped_refptr<X509Certificate> client_cert;
svaldez7872fd02015-11-19 21:10:5413572 scoped_refptr<SSLPrivateKey> client_private_key;
[email protected]791879c2013-12-17 07:22:4113573 ASSERT_TRUE(session->ssl_client_auth_cache()->Lookup(
svaldez7872fd02015-11-19 21:10:5413574 HostPortPair("proxy", 70), &client_cert, &client_private_key));
wezca1070932016-05-26 20:30:5213575 ASSERT_FALSE(client_cert);
[email protected]8c405132011-01-11 22:03:1813576 // Ensure the certificate was NOT cached for the endpoint. This only
13577 // applies to HTTPS requests, but is fine to check for HTTP requests.
[email protected]791879c2013-12-17 07:22:4113578 ASSERT_FALSE(session->ssl_client_auth_cache()->Lookup(
svaldez7872fd02015-11-19 21:10:5413579 HostPortPair("www.example.com", 443), &client_cert,
13580 &client_private_key));
[email protected]8c405132011-01-11 22:03:1813581
13582 // Restart the handshake. This will consume ssl_data2, which fails, and
13583 // then consume ssl_data3, which should also fail. The result code is
13584 // checked against what ssl_data3 should return.
13585 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0113586 ASSERT_THAT(rv, IsError(ERR_PROXY_CONNECTION_FAILED));
[email protected]8c405132011-01-11 22:03:1813587
13588 // Now that the new handshake has failed, ensure that the client
13589 // certificate was removed from the client auth cache.
[email protected]791879c2013-12-17 07:22:4113590 ASSERT_FALSE(session->ssl_client_auth_cache()->Lookup(
svaldez7872fd02015-11-19 21:10:5413591 HostPortPair("proxy", 70), &client_cert, &client_private_key));
[email protected]791879c2013-12-17 07:22:4113592 ASSERT_FALSE(session->ssl_client_auth_cache()->Lookup(
svaldez7872fd02015-11-19 21:10:5413593 HostPortPair("www.example.com", 443), &client_cert,
13594 &client_private_key));
[email protected]8c405132011-01-11 22:03:1813595 }
13596}
13597
bncd16676a2016-07-20 16:23:0113598TEST_F(HttpNetworkTransactionTest, UseIPConnectionPooling) {
[email protected]e3ceb682011-06-28 23:55:4613599 // Set up a special HttpNetworkSession with a MockCachingHostResolver.
Jeremy Roman0579ed62017-08-29 15:56:1913600 session_deps_.host_resolver = std::make_unique<MockCachingHostResolver>();
danakj1fd259a02016-04-16 03:17:0913601 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]e3ceb682011-06-28 23:55:4613602
bnc032658ba2016-09-26 18:17:1513603 AddSSLSocketData();
[email protected]e3ceb682011-06-28 23:55:4613604
bncdf80d44fd2016-07-15 20:27:4113605 SpdySerializedFrame host1_req(
bnc38dcd392016-02-09 23:19:4913606 spdy_util_.ConstructSpdyGet("https://www.example.org", 1, LOWEST));
rdsmithebb50aa2015-11-12 03:44:3813607 spdy_util_.UpdateWithStreamDestruction(1);
bncdf80d44fd2016-07-15 20:27:4113608 SpdySerializedFrame host2_req(
bnca4d611d2016-09-22 19:55:3713609 spdy_util_.ConstructSpdyGet("https://mail.example.com", 3, LOWEST));
[email protected]e3ceb682011-06-28 23:55:4613610 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:4113611 CreateMockWrite(host1_req, 0), CreateMockWrite(host2_req, 3),
[email protected]e3ceb682011-06-28 23:55:4613612 };
bnc42331402016-07-25 13:36:1513613 SpdySerializedFrame host1_resp(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
bncdf80d44fd2016-07-15 20:27:4113614 SpdySerializedFrame host1_resp_body(
13615 spdy_util_.ConstructSpdyDataFrame(1, true));
bnc42331402016-07-25 13:36:1513616 SpdySerializedFrame host2_resp(spdy_util_.ConstructSpdyGetReply(NULL, 0, 3));
bncdf80d44fd2016-07-15 20:27:4113617 SpdySerializedFrame host2_resp_body(
13618 spdy_util_.ConstructSpdyDataFrame(3, true));
[email protected]e3ceb682011-06-28 23:55:4613619 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:4113620 CreateMockRead(host1_resp, 1), CreateMockRead(host1_resp_body, 2),
13621 CreateMockRead(host2_resp, 4), CreateMockRead(host2_resp_body, 5),
rch8e6c6c42015-05-01 14:05:1313622 MockRead(ASYNC, 0, 6),
[email protected]e3ceb682011-06-28 23:55:4613623 };
13624
eroman36d84e54432016-03-17 03:23:0213625 IPEndPoint peer_addr(IPAddress::IPv4Localhost(), 443);
[email protected]d2b5f092012-06-08 23:55:0213626 MockConnect connect(ASYNC, OK, peer_addr);
rch8e6c6c42015-05-01 14:05:1313627 SequencedSocketData spdy_data(connect, spdy_reads, arraysize(spdy_reads),
13628 spdy_writes, arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:0713629 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]e3ceb682011-06-28 23:55:4613630
[email protected]aa22b242011-11-16 18:58:2913631 TestCompletionCallback callback;
[email protected]e3ceb682011-06-28 23:55:4613632 HttpRequestInfo request1;
13633 request1.method = "GET";
bncce36dca22015-04-21 22:11:2313634 request1.url = GURL("https://www.example.org/");
[email protected]e3ceb682011-06-28 23:55:4613635 request1.load_flags = 0;
[email protected]90499482013-06-01 00:39:5013636 HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
[email protected]e3ceb682011-06-28 23:55:4613637
tfarina42834112016-09-22 13:38:2013638 int rv = trans1.Start(&request1, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0113639 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
13640 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]e3ceb682011-06-28 23:55:4613641
13642 const HttpResponseInfo* response = trans1.GetResponseInfo();
wezca1070932016-05-26 20:30:5213643 ASSERT_TRUE(response);
13644 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0213645 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]e3ceb682011-06-28 23:55:4613646
13647 std::string response_data;
robpercival214763f2016-07-01 23:27:0113648 ASSERT_THAT(ReadTransaction(&trans1, &response_data), IsOk());
[email protected]e3ceb682011-06-28 23:55:4613649 EXPECT_EQ("hello!", response_data);
13650
bnca4d611d2016-09-22 19:55:3713651 // Preload mail.example.com into HostCache.
13652 HostPortPair host_port("mail.example.com", 443);
[email protected]5109c1952013-08-20 18:44:1013653 HostResolver::RequestInfo resolve_info(host_port);
[email protected]e3ceb682011-06-28 23:55:4613654 AddressList ignored;
maksim.sisov31452af2016-07-27 06:38:1013655 std::unique_ptr<HostResolver::Request> request;
13656 rv = session_deps_.host_resolver->Resolve(resolve_info, DEFAULT_PRIORITY,
13657 &ignored, callback.callback(),
tfarina42834112016-09-22 13:38:2013658 &request, NetLogWithSource());
robpercival214763f2016-07-01 23:27:0113659 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]6e78dfb2011-07-28 21:34:4713660 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0113661 EXPECT_THAT(rv, IsOk());
[email protected]e3ceb682011-06-28 23:55:4613662
13663 HttpRequestInfo request2;
13664 request2.method = "GET";
bnca4d611d2016-09-22 19:55:3713665 request2.url = GURL("https://mail.example.com/");
[email protected]e3ceb682011-06-28 23:55:4613666 request2.load_flags = 0;
[email protected]90499482013-06-01 00:39:5013667 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
[email protected]e3ceb682011-06-28 23:55:4613668
tfarina42834112016-09-22 13:38:2013669 rv = trans2.Start(&request2, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0113670 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
13671 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]e3ceb682011-06-28 23:55:4613672
13673 response = trans2.GetResponseInfo();
wezca1070932016-05-26 20:30:5213674 ASSERT_TRUE(response);
13675 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0213676 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]e3ceb682011-06-28 23:55:4613677 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5213678 EXPECT_TRUE(response->was_alpn_negotiated);
robpercival214763f2016-07-01 23:27:0113679 ASSERT_THAT(ReadTransaction(&trans2, &response_data), IsOk());
[email protected]e3ceb682011-06-28 23:55:4613680 EXPECT_EQ("hello!", response_data);
[email protected]e3ceb682011-06-28 23:55:4613681}
13682
bncd16676a2016-07-20 16:23:0113683TEST_F(HttpNetworkTransactionTest, UseIPConnectionPoolingAfterResolution) {
[email protected]d2b5f092012-06-08 23:55:0213684 // Set up a special HttpNetworkSession with a MockCachingHostResolver.
Jeremy Roman0579ed62017-08-29 15:56:1913685 session_deps_.host_resolver = std::make_unique<MockCachingHostResolver>();
danakj1fd259a02016-04-16 03:17:0913686 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]d2b5f092012-06-08 23:55:0213687
bnc032658ba2016-09-26 18:17:1513688 AddSSLSocketData();
[email protected]d2b5f092012-06-08 23:55:0213689
bncdf80d44fd2016-07-15 20:27:4113690 SpdySerializedFrame host1_req(
bnc38dcd392016-02-09 23:19:4913691 spdy_util_.ConstructSpdyGet("https://www.example.org", 1, LOWEST));
rdsmithebb50aa2015-11-12 03:44:3813692 spdy_util_.UpdateWithStreamDestruction(1);
bncdf80d44fd2016-07-15 20:27:4113693 SpdySerializedFrame host2_req(
bnca4d611d2016-09-22 19:55:3713694 spdy_util_.ConstructSpdyGet("https://mail.example.com", 3, LOWEST));
[email protected]d2b5f092012-06-08 23:55:0213695 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:4113696 CreateMockWrite(host1_req, 0), CreateMockWrite(host2_req, 3),
[email protected]d2b5f092012-06-08 23:55:0213697 };
bnc42331402016-07-25 13:36:1513698 SpdySerializedFrame host1_resp(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
bncdf80d44fd2016-07-15 20:27:4113699 SpdySerializedFrame host1_resp_body(
13700 spdy_util_.ConstructSpdyDataFrame(1, true));
bnc42331402016-07-25 13:36:1513701 SpdySerializedFrame host2_resp(spdy_util_.ConstructSpdyGetReply(NULL, 0, 3));
bncdf80d44fd2016-07-15 20:27:4113702 SpdySerializedFrame host2_resp_body(
13703 spdy_util_.ConstructSpdyDataFrame(3, true));
[email protected]d2b5f092012-06-08 23:55:0213704 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:4113705 CreateMockRead(host1_resp, 1), CreateMockRead(host1_resp_body, 2),
13706 CreateMockRead(host2_resp, 4), CreateMockRead(host2_resp_body, 5),
rch8e6c6c42015-05-01 14:05:1313707 MockRead(ASYNC, 0, 6),
[email protected]d2b5f092012-06-08 23:55:0213708 };
13709
eroman36d84e54432016-03-17 03:23:0213710 IPEndPoint peer_addr(IPAddress::IPv4Localhost(), 443);
[email protected]d2b5f092012-06-08 23:55:0213711 MockConnect connect(ASYNC, OK, peer_addr);
rch8e6c6c42015-05-01 14:05:1313712 SequencedSocketData spdy_data(connect, spdy_reads, arraysize(spdy_reads),
13713 spdy_writes, arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:0713714 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]d2b5f092012-06-08 23:55:0213715
13716 TestCompletionCallback callback;
13717 HttpRequestInfo request1;
13718 request1.method = "GET";
bncce36dca22015-04-21 22:11:2313719 request1.url = GURL("https://www.example.org/");
[email protected]d2b5f092012-06-08 23:55:0213720 request1.load_flags = 0;
[email protected]90499482013-06-01 00:39:5013721 HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
[email protected]d2b5f092012-06-08 23:55:0213722
tfarina42834112016-09-22 13:38:2013723 int rv = trans1.Start(&request1, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0113724 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
13725 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]d2b5f092012-06-08 23:55:0213726
13727 const HttpResponseInfo* response = trans1.GetResponseInfo();
wezca1070932016-05-26 20:30:5213728 ASSERT_TRUE(response);
13729 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0213730 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]d2b5f092012-06-08 23:55:0213731
13732 std::string response_data;
robpercival214763f2016-07-01 23:27:0113733 ASSERT_THAT(ReadTransaction(&trans1, &response_data), IsOk());
[email protected]d2b5f092012-06-08 23:55:0213734 EXPECT_EQ("hello!", response_data);
13735
13736 HttpRequestInfo request2;
13737 request2.method = "GET";
bnca4d611d2016-09-22 19:55:3713738 request2.url = GURL("https://mail.example.com/");
[email protected]d2b5f092012-06-08 23:55:0213739 request2.load_flags = 0;
[email protected]90499482013-06-01 00:39:5013740 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
[email protected]d2b5f092012-06-08 23:55:0213741
tfarina42834112016-09-22 13:38:2013742 rv = trans2.Start(&request2, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0113743 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
13744 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]d2b5f092012-06-08 23:55:0213745
13746 response = trans2.GetResponseInfo();
wezca1070932016-05-26 20:30:5213747 ASSERT_TRUE(response);
13748 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0213749 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]d2b5f092012-06-08 23:55:0213750 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5213751 EXPECT_TRUE(response->was_alpn_negotiated);
robpercival214763f2016-07-01 23:27:0113752 ASSERT_THAT(ReadTransaction(&trans2, &response_data), IsOk());
[email protected]d2b5f092012-06-08 23:55:0213753 EXPECT_EQ("hello!", response_data);
[email protected]d2b5f092012-06-08 23:55:0213754}
13755
bnc8016c1f2017-03-31 02:11:2913756// Regression test for https://crbug.com/546991.
13757// The server might not be able to serve an IP pooled request, and might send a
13758// 421 Misdirected Request response status to indicate this.
13759// HttpNetworkTransaction should reset the request and retry without IP pooling.
13760TEST_F(HttpNetworkTransactionTest, RetryWithoutConnectionPooling) {
13761 // Two hosts resolve to the same IP address.
13762 const std::string ip_addr = "1.2.3.4";
13763 IPAddress ip;
13764 ASSERT_TRUE(ip.AssignFromIPLiteral(ip_addr));
13765 IPEndPoint peer_addr = IPEndPoint(ip, 443);
13766
Jeremy Roman0579ed62017-08-29 15:56:1913767 session_deps_.host_resolver = std::make_unique<MockCachingHostResolver>();
bnc8016c1f2017-03-31 02:11:2913768 session_deps_.host_resolver->rules()->AddRule("www.example.org", ip_addr);
13769 session_deps_.host_resolver->rules()->AddRule("mail.example.org", ip_addr);
13770
13771 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
13772
13773 // Two requests on the first connection.
13774 SpdySerializedFrame req1(
13775 spdy_util_.ConstructSpdyGet("https://www.example.org", 1, LOWEST));
13776 spdy_util_.UpdateWithStreamDestruction(1);
13777 SpdySerializedFrame req2(
13778 spdy_util_.ConstructSpdyGet("https://mail.example.org", 3, LOWEST));
13779 SpdySerializedFrame rst(
13780 spdy_util_.ConstructSpdyRstStream(3, ERROR_CODE_CANCEL));
13781 MockWrite writes1[] = {
13782 CreateMockWrite(req1, 0), CreateMockWrite(req2, 3),
13783 CreateMockWrite(rst, 6),
13784 };
13785
13786 // The first one succeeds, the second gets error 421 Misdirected Request.
13787 SpdySerializedFrame resp1(spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
13788 SpdySerializedFrame body1(spdy_util_.ConstructSpdyDataFrame(1, true));
13789 SpdyHeaderBlock response_headers;
13790 response_headers[SpdyTestUtil::GetStatusKey()] = "421";
13791 SpdySerializedFrame resp2(
13792 spdy_util_.ConstructSpdyReply(3, std::move(response_headers)));
13793 MockRead reads1[] = {CreateMockRead(resp1, 1), CreateMockRead(body1, 2),
13794 CreateMockRead(resp2, 4), MockRead(ASYNC, 0, 5)};
13795
13796 MockConnect connect1(ASYNC, OK, peer_addr);
13797 SequencedSocketData data1(connect1, reads1, arraysize(reads1), writes1,
13798 arraysize(writes1));
13799 session_deps_.socket_factory->AddSocketDataProvider(&data1);
13800
13801 AddSSLSocketData();
13802
13803 // Retry the second request on a second connection.
13804 SpdyTestUtil spdy_util2;
13805 SpdySerializedFrame req3(
13806 spdy_util2.ConstructSpdyGet("https://mail.example.org", 1, LOWEST));
13807 MockWrite writes2[] = {
13808 CreateMockWrite(req3, 0),
13809 };
13810
13811 SpdySerializedFrame resp3(spdy_util2.ConstructSpdyGetReply(nullptr, 0, 1));
13812 SpdySerializedFrame body3(spdy_util2.ConstructSpdyDataFrame(1, true));
13813 MockRead reads2[] = {CreateMockRead(resp3, 1), CreateMockRead(body3, 2),
13814 MockRead(ASYNC, 0, 3)};
13815
13816 MockConnect connect2(ASYNC, OK, peer_addr);
13817 SequencedSocketData data2(connect2, reads2, arraysize(reads2), writes2,
13818 arraysize(writes2));
13819 session_deps_.socket_factory->AddSocketDataProvider(&data2);
13820
13821 AddSSLSocketData();
13822
13823 // Preload mail.example.org into HostCache.
13824 HostPortPair host_port("mail.example.org", 443);
13825 HostResolver::RequestInfo resolve_info(host_port);
13826 AddressList ignored;
13827 std::unique_ptr<HostResolver::Request> request;
13828 TestCompletionCallback callback;
13829 int rv = session_deps_.host_resolver->Resolve(resolve_info, DEFAULT_PRIORITY,
13830 &ignored, callback.callback(),
13831 &request, NetLogWithSource());
13832 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
13833 rv = callback.WaitForResult();
13834 EXPECT_THAT(rv, IsOk());
13835
13836 HttpRequestInfo request1;
13837 request1.method = "GET";
13838 request1.url = GURL("https://www.example.org/");
13839 request1.load_flags = 0;
13840 HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
13841
13842 rv = trans1.Start(&request1, callback.callback(), NetLogWithSource());
13843 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
13844 rv = callback.WaitForResult();
13845 EXPECT_THAT(rv, IsOk());
13846
13847 const HttpResponseInfo* response = trans1.GetResponseInfo();
13848 ASSERT_TRUE(response);
13849 ASSERT_TRUE(response->headers);
13850 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
13851 EXPECT_TRUE(response->was_fetched_via_spdy);
13852 EXPECT_TRUE(response->was_alpn_negotiated);
13853 std::string response_data;
13854 ASSERT_THAT(ReadTransaction(&trans1, &response_data), IsOk());
13855 EXPECT_EQ("hello!", response_data);
13856
13857 HttpRequestInfo request2;
13858 request2.method = "GET";
13859 request2.url = GURL("https://mail.example.org/");
13860 request2.load_flags = 0;
13861 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
13862
13863 BoundTestNetLog log;
13864 rv = trans2.Start(&request2, callback.callback(), log.bound());
13865 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
13866 rv = callback.WaitForResult();
13867 EXPECT_THAT(rv, IsOk());
13868
13869 response = trans2.GetResponseInfo();
13870 ASSERT_TRUE(response);
13871 ASSERT_TRUE(response->headers);
13872 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
13873 EXPECT_TRUE(response->was_fetched_via_spdy);
13874 EXPECT_TRUE(response->was_alpn_negotiated);
13875 ASSERT_THAT(ReadTransaction(&trans2, &response_data), IsOk());
13876 EXPECT_EQ("hello!", response_data);
13877
13878 TestNetLogEntry::List entries;
13879 log.GetEntries(&entries);
davidbence688ae2017-05-04 15:12:5913880 ExpectLogContainsSomewhere(
13881 entries, 0, NetLogEventType::HTTP_TRANSACTION_RESTART_MISDIRECTED_REQUEST,
bnc8016c1f2017-03-31 02:11:2913882 NetLogEventPhase::NONE);
davidbence688ae2017-05-04 15:12:5913883}
13884
13885// Test that HTTP 421 responses are properly returned to the caller if received
13886// on the retry as well. HttpNetworkTransaction should not infinite loop or lose
13887// portions of the response.
13888TEST_F(HttpNetworkTransactionTest, ReturnHTTP421OnRetry) {
13889 // Two hosts resolve to the same IP address.
13890 const std::string ip_addr = "1.2.3.4";
13891 IPAddress ip;
13892 ASSERT_TRUE(ip.AssignFromIPLiteral(ip_addr));
13893 IPEndPoint peer_addr = IPEndPoint(ip, 443);
13894
Jeremy Roman0579ed62017-08-29 15:56:1913895 session_deps_.host_resolver = std::make_unique<MockCachingHostResolver>();
davidbence688ae2017-05-04 15:12:5913896 session_deps_.host_resolver->rules()->AddRule("www.example.org", ip_addr);
13897 session_deps_.host_resolver->rules()->AddRule("mail.example.org", ip_addr);
13898
13899 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
13900
13901 // Two requests on the first connection.
13902 SpdySerializedFrame req1(
13903 spdy_util_.ConstructSpdyGet("https://www.example.org", 1, LOWEST));
13904 spdy_util_.UpdateWithStreamDestruction(1);
13905 SpdySerializedFrame req2(
13906 spdy_util_.ConstructSpdyGet("https://mail.example.org", 3, LOWEST));
13907 SpdySerializedFrame rst(
13908 spdy_util_.ConstructSpdyRstStream(3, ERROR_CODE_CANCEL));
13909 MockWrite writes1[] = {
13910 CreateMockWrite(req1, 0), CreateMockWrite(req2, 3),
13911 CreateMockWrite(rst, 6),
13912 };
13913
13914 // The first one succeeds, the second gets error 421 Misdirected Request.
13915 SpdySerializedFrame resp1(spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
13916 SpdySerializedFrame body1(spdy_util_.ConstructSpdyDataFrame(1, true));
13917 SpdyHeaderBlock response_headers;
13918 response_headers[SpdyTestUtil::GetStatusKey()] = "421";
13919 SpdySerializedFrame resp2(
13920 spdy_util_.ConstructSpdyReply(3, response_headers.Clone()));
13921 MockRead reads1[] = {CreateMockRead(resp1, 1), CreateMockRead(body1, 2),
13922 CreateMockRead(resp2, 4), MockRead(ASYNC, 0, 5)};
13923
13924 MockConnect connect1(ASYNC, OK, peer_addr);
13925 SequencedSocketData data1(connect1, reads1, arraysize(reads1), writes1,
13926 arraysize(writes1));
13927 session_deps_.socket_factory->AddSocketDataProvider(&data1);
13928
13929 AddSSLSocketData();
13930
13931 // Retry the second request on a second connection. It returns 421 Misdirected
13932 // Retry again.
13933 SpdyTestUtil spdy_util2;
13934 SpdySerializedFrame req3(
13935 spdy_util2.ConstructSpdyGet("https://mail.example.org", 1, LOWEST));
13936 MockWrite writes2[] = {
13937 CreateMockWrite(req3, 0),
13938 };
13939
13940 SpdySerializedFrame resp3(
13941 spdy_util2.ConstructSpdyReply(1, std::move(response_headers)));
13942 SpdySerializedFrame body3(spdy_util2.ConstructSpdyDataFrame(1, true));
13943 MockRead reads2[] = {CreateMockRead(resp3, 1), CreateMockRead(body3, 2),
13944 MockRead(ASYNC, 0, 3)};
13945
13946 MockConnect connect2(ASYNC, OK, peer_addr);
13947 SequencedSocketData data2(connect2, reads2, arraysize(reads2), writes2,
13948 arraysize(writes2));
13949 session_deps_.socket_factory->AddSocketDataProvider(&data2);
13950
13951 AddSSLSocketData();
13952
13953 // Preload mail.example.org into HostCache.
13954 HostPortPair host_port("mail.example.org", 443);
13955 HostResolver::RequestInfo resolve_info(host_port);
13956 AddressList ignored;
13957 std::unique_ptr<HostResolver::Request> request;
13958 TestCompletionCallback callback;
13959 int rv = session_deps_.host_resolver->Resolve(resolve_info, DEFAULT_PRIORITY,
13960 &ignored, callback.callback(),
13961 &request, NetLogWithSource());
13962 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
13963 rv = callback.WaitForResult();
13964 EXPECT_THAT(rv, IsOk());
13965
13966 HttpRequestInfo request1;
13967 request1.method = "GET";
13968 request1.url = GURL("https://www.example.org/");
13969 request1.load_flags = 0;
13970 HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
13971
13972 rv = trans1.Start(&request1, callback.callback(), NetLogWithSource());
13973 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
13974 rv = callback.WaitForResult();
13975 EXPECT_THAT(rv, IsOk());
13976
13977 const HttpResponseInfo* response = trans1.GetResponseInfo();
13978 ASSERT_TRUE(response);
13979 ASSERT_TRUE(response->headers);
13980 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
13981 EXPECT_TRUE(response->was_fetched_via_spdy);
13982 EXPECT_TRUE(response->was_alpn_negotiated);
13983 std::string response_data;
13984 ASSERT_THAT(ReadTransaction(&trans1, &response_data), IsOk());
13985 EXPECT_EQ("hello!", response_data);
13986
13987 HttpRequestInfo request2;
13988 request2.method = "GET";
13989 request2.url = GURL("https://mail.example.org/");
13990 request2.load_flags = 0;
13991 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
13992
13993 BoundTestNetLog log;
13994 rv = trans2.Start(&request2, callback.callback(), log.bound());
13995 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
13996 rv = callback.WaitForResult();
13997 EXPECT_THAT(rv, IsOk());
13998
13999 // After a retry, the 421 Misdirected Request is reported back up to the
14000 // caller.
14001 response = trans2.GetResponseInfo();
14002 ASSERT_TRUE(response);
14003 ASSERT_TRUE(response->headers);
14004 EXPECT_EQ("HTTP/1.1 421", response->headers->GetStatusLine());
14005 EXPECT_TRUE(response->was_fetched_via_spdy);
14006 EXPECT_TRUE(response->was_alpn_negotiated);
14007 EXPECT_TRUE(response->ssl_info.cert);
14008 ASSERT_THAT(ReadTransaction(&trans2, &response_data), IsOk());
14009 EXPECT_EQ("hello!", response_data);
bnc8016c1f2017-03-31 02:11:2914010}
14011
bnc6dcd8192017-05-25 20:11:5014012class OneTimeCachingHostResolver : public MockHostResolverBase {
[email protected]e3ceb682011-06-28 23:55:4614013 public:
14014 explicit OneTimeCachingHostResolver(const HostPortPair& host_port)
bnc6dcd8192017-05-25 20:11:5014015 : MockHostResolverBase(/* use_caching = */ true), host_port_(host_port) {}
dchengb03027d2014-10-21 12:00:2014016 ~OneTimeCachingHostResolver() override {}
[email protected]e3ceb682011-06-28 23:55:4614017
dchengb03027d2014-10-21 12:00:2014018 int ResolveFromCache(const RequestInfo& info,
14019 AddressList* addresses,
tfarina42834112016-09-22 13:38:2014020 const NetLogWithSource& net_log) override {
bnc6dcd8192017-05-25 20:11:5014021 int rv = MockHostResolverBase::ResolveFromCache(info, addresses, net_log);
[email protected]95a214c2011-08-04 21:50:4014022 if (rv == OK && info.host_port_pair().Equals(host_port_))
bnc6dcd8192017-05-25 20:11:5014023 GetHostCache()->clear();
[email protected]e3ceb682011-06-28 23:55:4614024 return rv;
14025 }
14026
[email protected]e3ceb682011-06-28 23:55:4614027 private:
[email protected]e3ceb682011-06-28 23:55:4614028 const HostPortPair host_port_;
14029};
14030
bncd16676a2016-07-20 16:23:0114031TEST_F(HttpNetworkTransactionTest,
mmenke5c642132015-06-02 16:05:1314032 UseIPConnectionPoolingWithHostCacheExpiration) {
[email protected]e3ceb682011-06-28 23:55:4614033 // Set up a special HttpNetworkSession with a OneTimeCachingHostResolver.
Jeremy Roman0579ed62017-08-29 15:56:1914034 session_deps_.host_resolver = std::make_unique<OneTimeCachingHostResolver>(
bnca4d611d2016-09-22 19:55:3714035 HostPortPair("mail.example.com", 443));
danakj1fd259a02016-04-16 03:17:0914036 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]e3ceb682011-06-28 23:55:4614037
bnc032658ba2016-09-26 18:17:1514038 AddSSLSocketData();
[email protected]e3ceb682011-06-28 23:55:4614039
bncdf80d44fd2016-07-15 20:27:4114040 SpdySerializedFrame host1_req(
bnc38dcd392016-02-09 23:19:4914041 spdy_util_.ConstructSpdyGet("https://www.example.org", 1, LOWEST));
rdsmithebb50aa2015-11-12 03:44:3814042 spdy_util_.UpdateWithStreamDestruction(1);
bncdf80d44fd2016-07-15 20:27:4114043 SpdySerializedFrame host2_req(
bnca4d611d2016-09-22 19:55:3714044 spdy_util_.ConstructSpdyGet("https://mail.example.com", 3, LOWEST));
[email protected]e3ceb682011-06-28 23:55:4614045 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:4114046 CreateMockWrite(host1_req, 0), CreateMockWrite(host2_req, 3),
[email protected]e3ceb682011-06-28 23:55:4614047 };
bnc42331402016-07-25 13:36:1514048 SpdySerializedFrame host1_resp(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
bncdf80d44fd2016-07-15 20:27:4114049 SpdySerializedFrame host1_resp_body(
14050 spdy_util_.ConstructSpdyDataFrame(1, true));
bnc42331402016-07-25 13:36:1514051 SpdySerializedFrame host2_resp(spdy_util_.ConstructSpdyGetReply(NULL, 0, 3));
bncdf80d44fd2016-07-15 20:27:4114052 SpdySerializedFrame host2_resp_body(
14053 spdy_util_.ConstructSpdyDataFrame(3, true));
[email protected]e3ceb682011-06-28 23:55:4614054 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:4114055 CreateMockRead(host1_resp, 1), CreateMockRead(host1_resp_body, 2),
14056 CreateMockRead(host2_resp, 4), CreateMockRead(host2_resp_body, 5),
rch8e6c6c42015-05-01 14:05:1314057 MockRead(ASYNC, 0, 6),
[email protected]e3ceb682011-06-28 23:55:4614058 };
14059
eroman36d84e54432016-03-17 03:23:0214060 IPEndPoint peer_addr(IPAddress::IPv4Localhost(), 443);
[email protected]d2b5f092012-06-08 23:55:0214061 MockConnect connect(ASYNC, OK, peer_addr);
rch8e6c6c42015-05-01 14:05:1314062 SequencedSocketData spdy_data(connect, spdy_reads, arraysize(spdy_reads),
14063 spdy_writes, arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:0714064 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]e3ceb682011-06-28 23:55:4614065
[email protected]aa22b242011-11-16 18:58:2914066 TestCompletionCallback callback;
[email protected]e3ceb682011-06-28 23:55:4614067 HttpRequestInfo request1;
14068 request1.method = "GET";
bncce36dca22015-04-21 22:11:2314069 request1.url = GURL("https://www.example.org/");
[email protected]e3ceb682011-06-28 23:55:4614070 request1.load_flags = 0;
[email protected]90499482013-06-01 00:39:5014071 HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
[email protected]e3ceb682011-06-28 23:55:4614072
tfarina42834112016-09-22 13:38:2014073 int rv = trans1.Start(&request1, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0114074 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
14075 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]e3ceb682011-06-28 23:55:4614076
14077 const HttpResponseInfo* response = trans1.GetResponseInfo();
wezca1070932016-05-26 20:30:5214078 ASSERT_TRUE(response);
14079 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0214080 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]e3ceb682011-06-28 23:55:4614081
14082 std::string response_data;
robpercival214763f2016-07-01 23:27:0114083 ASSERT_THAT(ReadTransaction(&trans1, &response_data), IsOk());
[email protected]e3ceb682011-06-28 23:55:4614084 EXPECT_EQ("hello!", response_data);
14085
14086 // Preload cache entries into HostCache.
bnca4d611d2016-09-22 19:55:3714087 HostResolver::RequestInfo resolve_info(HostPortPair("mail.example.com", 443));
[email protected]e3ceb682011-06-28 23:55:4614088 AddressList ignored;
maksim.sisov31452af2016-07-27 06:38:1014089 std::unique_ptr<HostResolver::Request> request;
bnc6dcd8192017-05-25 20:11:5014090 rv = session_deps_.host_resolver->Resolve(resolve_info, DEFAULT_PRIORITY,
14091 &ignored, callback.callback(),
14092 &request, NetLogWithSource());
robpercival214763f2016-07-01 23:27:0114093 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]6e78dfb2011-07-28 21:34:4714094 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0114095 EXPECT_THAT(rv, IsOk());
[email protected]e3ceb682011-06-28 23:55:4614096
14097 HttpRequestInfo request2;
14098 request2.method = "GET";
bnca4d611d2016-09-22 19:55:3714099 request2.url = GURL("https://mail.example.com/");
[email protected]e3ceb682011-06-28 23:55:4614100 request2.load_flags = 0;
[email protected]90499482013-06-01 00:39:5014101 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
[email protected]e3ceb682011-06-28 23:55:4614102
tfarina42834112016-09-22 13:38:2014103 rv = trans2.Start(&request2, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0114104 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
14105 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]e3ceb682011-06-28 23:55:4614106
14107 response = trans2.GetResponseInfo();
wezca1070932016-05-26 20:30:5214108 ASSERT_TRUE(response);
14109 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0214110 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]e3ceb682011-06-28 23:55:4614111 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5214112 EXPECT_TRUE(response->was_alpn_negotiated);
robpercival214763f2016-07-01 23:27:0114113 ASSERT_THAT(ReadTransaction(&trans2, &response_data), IsOk());
[email protected]e3ceb682011-06-28 23:55:4614114 EXPECT_EQ("hello!", response_data);
[email protected]e3ceb682011-06-28 23:55:4614115}
14116
bncd16676a2016-07-20 16:23:0114117TEST_F(HttpNetworkTransactionTest, DoNotUseSpdySessionForHttp) {
bncce36dca22015-04-21 22:11:2314118 const std::string https_url = "https://www.example.org:8080/";
14119 const std::string http_url = "http://www.example.org:8080/";
[email protected]8450d722012-07-02 19:14:0414120
14121 // SPDY GET for HTTPS URL
bncdf80d44fd2016-07-15 20:27:4114122 SpdySerializedFrame req1(
bnc38dcd392016-02-09 23:19:4914123 spdy_util_.ConstructSpdyGet(https_url.c_str(), 1, LOWEST));
[email protected]8450d722012-07-02 19:14:0414124
14125 MockWrite writes1[] = {
bncdf80d44fd2016-07-15 20:27:4114126 CreateMockWrite(req1, 0),
[email protected]8450d722012-07-02 19:14:0414127 };
14128
bnc42331402016-07-25 13:36:1514129 SpdySerializedFrame resp1(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
bncdf80d44fd2016-07-15 20:27:4114130 SpdySerializedFrame body1(spdy_util_.ConstructSpdyDataFrame(1, true));
14131 MockRead reads1[] = {CreateMockRead(resp1, 1), CreateMockRead(body1, 2),
mmenkee24011922015-12-17 22:12:5914132 MockRead(SYNCHRONOUS, ERR_IO_PENDING, 3)};
[email protected]8450d722012-07-02 19:14:0414133
rch8e6c6c42015-05-01 14:05:1314134 SequencedSocketData data1(reads1, arraysize(reads1), writes1,
14135 arraysize(writes1));
[email protected]8450d722012-07-02 19:14:0414136 MockConnect connect_data1(ASYNC, OK);
[email protected]dd54bd82012-07-19 23:44:5714137 data1.set_connect_data(connect_data1);
[email protected]8450d722012-07-02 19:14:0414138
14139 // HTTP GET for the HTTP URL
14140 MockWrite writes2[] = {
rch8e6c6c42015-05-01 14:05:1314141 MockWrite(ASYNC, 0,
lgarrona91df87f2014-12-05 00:51:3414142 "GET / HTTP/1.1\r\n"
bncce36dca22015-04-21 22:11:2314143 "Host: www.example.org:8080\r\n"
lgarrona91df87f2014-12-05 00:51:3414144 "Connection: keep-alive\r\n\r\n"),
[email protected]8450d722012-07-02 19:14:0414145 };
14146
14147 MockRead reads2[] = {
rch8e6c6c42015-05-01 14:05:1314148 MockRead(ASYNC, 1, "HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
14149 MockRead(ASYNC, 2, "hello"),
14150 MockRead(ASYNC, OK, 3),
[email protected]8450d722012-07-02 19:14:0414151 };
14152
rch8e6c6c42015-05-01 14:05:1314153 SequencedSocketData data2(reads2, arraysize(reads2), writes2,
14154 arraysize(writes2));
[email protected]8450d722012-07-02 19:14:0414155
[email protected]8450d722012-07-02 19:14:0414156 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3614157 ssl.next_proto = kProtoHTTP2;
[email protected]bb88e1d32013-05-03 23:11:0714158 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
14159 session_deps_.socket_factory->AddSocketDataProvider(&data1);
14160 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]8450d722012-07-02 19:14:0414161
danakj1fd259a02016-04-16 03:17:0914162 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]8450d722012-07-02 19:14:0414163
14164 // Start the first transaction to set up the SpdySession
14165 HttpRequestInfo request1;
14166 request1.method = "GET";
14167 request1.url = GURL(https_url);
[email protected]8450d722012-07-02 19:14:0414168 request1.load_flags = 0;
[email protected]90499482013-06-01 00:39:5014169 HttpNetworkTransaction trans1(LOWEST, session.get());
[email protected]8450d722012-07-02 19:14:0414170 TestCompletionCallback callback1;
14171 EXPECT_EQ(ERR_IO_PENDING,
tfarina42834112016-09-22 13:38:2014172 trans1.Start(&request1, callback1.callback(), NetLogWithSource()));
fdoray92e35a72016-06-10 15:54:5514173 base::RunLoop().RunUntilIdle();
[email protected]8450d722012-07-02 19:14:0414174
robpercival214763f2016-07-01 23:27:0114175 EXPECT_THAT(callback1.WaitForResult(), IsOk());
[email protected]8450d722012-07-02 19:14:0414176 EXPECT_TRUE(trans1.GetResponseInfo()->was_fetched_via_spdy);
14177
14178 // Now, start the HTTP request
14179 HttpRequestInfo request2;
14180 request2.method = "GET";
14181 request2.url = GURL(http_url);
[email protected]8450d722012-07-02 19:14:0414182 request2.load_flags = 0;
[email protected]90499482013-06-01 00:39:5014183 HttpNetworkTransaction trans2(MEDIUM, session.get());
[email protected]8450d722012-07-02 19:14:0414184 TestCompletionCallback callback2;
14185 EXPECT_EQ(ERR_IO_PENDING,
tfarina42834112016-09-22 13:38:2014186 trans2.Start(&request2, callback2.callback(), NetLogWithSource()));
fdoray92e35a72016-06-10 15:54:5514187 base::RunLoop().RunUntilIdle();
[email protected]8450d722012-07-02 19:14:0414188
robpercival214763f2016-07-01 23:27:0114189 EXPECT_THAT(callback2.WaitForResult(), IsOk());
[email protected]8450d722012-07-02 19:14:0414190 EXPECT_FALSE(trans2.GetResponseInfo()->was_fetched_via_spdy);
14191}
14192
bnc5452e2a2015-05-08 16:27:4214193// Alternative service requires HTTP/2 (or SPDY), but HTTP/1.1 is negotiated
14194// with the alternative server. That connection should not be used.
bncd16676a2016-07-20 16:23:0114195TEST_F(HttpNetworkTransactionTest, AlternativeServiceNotOnHttp11) {
bnc8bef8da22016-05-30 01:28:2514196 url::SchemeHostPort server("https", "www.example.org", 443);
14197 HostPortPair alternative("www.example.org", 444);
bnc5452e2a2015-05-08 16:27:4214198
bnc8bef8da22016-05-30 01:28:2514199 // Negotiate HTTP/1.1 with alternative.
bnc5452e2a2015-05-08 16:27:4214200 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3614201 ssl.next_proto = kProtoHTTP11;
bnc5452e2a2015-05-08 16:27:4214202 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
14203
14204 // No data should be read from the alternative, because HTTP/1.1 is
14205 // negotiated.
14206 StaticSocketDataProvider data;
14207 session_deps_.socket_factory->AddSocketDataProvider(&data);
14208
14209 // This test documents that an alternate Job should not be used if HTTP/1.1 is
zhongyi3d4a55e72016-04-22 20:36:4614210 // negotiated. In order to test this, a failed connection to the server is
bnc5452e2a2015-05-08 16:27:4214211 // mocked. This way the request relies on the alternate Job.
14212 StaticSocketDataProvider data_refused;
14213 data_refused.set_connect_data(MockConnect(ASYNC, ERR_CONNECTION_REFUSED));
14214 session_deps_.socket_factory->AddSocketDataProvider(&data_refused);
14215
zhongyi3d4a55e72016-04-22 20:36:4614216 // Set up alternative service for server.
danakj1fd259a02016-04-16 03:17:0914217 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc525e175a2016-06-20 12:36:4014218 HttpServerProperties* http_server_properties =
bnc5452e2a2015-05-08 16:27:4214219 session->http_server_properties();
bnc3472afd2016-11-17 15:27:2114220 AlternativeService alternative_service(kProtoHTTP2, alternative);
bnc7dc7e1b42015-07-28 14:43:1214221 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:2114222 http_server_properties->SetHttp2AlternativeService(
14223 server, alternative_service, expiration);
bnc5452e2a2015-05-08 16:27:4214224
bnc5452e2a2015-05-08 16:27:4214225 HttpRequestInfo request;
krasinc06a72a2016-12-21 03:42:4614226 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
bnc5452e2a2015-05-08 16:27:4214227 request.method = "GET";
bnc8bef8da22016-05-30 01:28:2514228 request.url = GURL("https://www.example.org:443");
bnc5452e2a2015-05-08 16:27:4214229 TestCompletionCallback callback;
14230
14231 // HTTP/2 (or SPDY) is required for alternative service, if HTTP/1.1 is
bnc94c92842016-09-21 15:22:5214232 // negotiated, the alternate Job should fail with ERR_ALPN_NEGOTIATION_FAILED.
tfarina42834112016-09-22 13:38:2014233 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
bnc94c92842016-09-21 15:22:5214234 EXPECT_THAT(callback.GetResult(rv), IsError(ERR_ALPN_NEGOTIATION_FAILED));
bnc5452e2a2015-05-08 16:27:4214235}
14236
bnc40448a532015-05-11 19:13:1414237// A request to a server with an alternative service fires two Jobs: one to the
zhongyi3d4a55e72016-04-22 20:36:4614238// server, and an alternate one to the alternative server. If the former
bnc40448a532015-05-11 19:13:1414239// succeeds, the request should succeed, even if the latter fails because
14240// HTTP/1.1 is negotiated which is insufficient for alternative service.
bncd16676a2016-07-20 16:23:0114241TEST_F(HttpNetworkTransactionTest, FailedAlternativeServiceIsNotUserVisible) {
bnc8bef8da22016-05-30 01:28:2514242 url::SchemeHostPort server("https", "www.example.org", 443);
14243 HostPortPair alternative("www.example.org", 444);
bnc40448a532015-05-11 19:13:1414244
14245 // Negotiate HTTP/1.1 with alternative.
14246 SSLSocketDataProvider alternative_ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3614247 alternative_ssl.next_proto = kProtoHTTP11;
bnc40448a532015-05-11 19:13:1414248 session_deps_.socket_factory->AddSSLSocketDataProvider(&alternative_ssl);
14249
14250 // No data should be read from the alternative, because HTTP/1.1 is
14251 // negotiated.
14252 StaticSocketDataProvider data;
14253 session_deps_.socket_factory->AddSocketDataProvider(&data);
14254
zhongyi3d4a55e72016-04-22 20:36:4614255 // Negotiate HTTP/1.1 with server.
bnc40448a532015-05-11 19:13:1414256 SSLSocketDataProvider origin_ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3614257 origin_ssl.next_proto = kProtoHTTP11;
bnc40448a532015-05-11 19:13:1414258 session_deps_.socket_factory->AddSSLSocketDataProvider(&origin_ssl);
14259
14260 MockWrite http_writes[] = {
bnc8bef8da22016-05-30 01:28:2514261 MockWrite("GET / HTTP/1.1\r\n"
14262 "Host: www.example.org\r\n"
14263 "Connection: keep-alive\r\n\r\n"),
14264 MockWrite("GET /second HTTP/1.1\r\n"
14265 "Host: www.example.org\r\n"
14266 "Connection: keep-alive\r\n\r\n"),
bnc40448a532015-05-11 19:13:1414267 };
14268
14269 MockRead http_reads[] = {
14270 MockRead("HTTP/1.1 200 OK\r\n"),
14271 MockRead("Content-Type: text/html\r\n"),
14272 MockRead("Content-Length: 6\r\n\r\n"),
14273 MockRead("foobar"),
14274 MockRead("HTTP/1.1 200 OK\r\n"),
14275 MockRead("Content-Type: text/html\r\n"),
14276 MockRead("Content-Length: 7\r\n\r\n"),
14277 MockRead("another"),
14278 };
14279 StaticSocketDataProvider http_data(http_reads, arraysize(http_reads),
14280 http_writes, arraysize(http_writes));
14281 session_deps_.socket_factory->AddSocketDataProvider(&http_data);
14282
zhongyi3d4a55e72016-04-22 20:36:4614283 // Set up alternative service for server.
danakj1fd259a02016-04-16 03:17:0914284 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc525e175a2016-06-20 12:36:4014285 HttpServerProperties* http_server_properties =
bnc40448a532015-05-11 19:13:1414286 session->http_server_properties();
bnc3472afd2016-11-17 15:27:2114287 AlternativeService alternative_service(kProtoHTTP2, alternative);
bnc7dc7e1b42015-07-28 14:43:1214288 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:2114289 http_server_properties->SetHttp2AlternativeService(
14290 server, alternative_service, expiration);
bnc40448a532015-05-11 19:13:1414291
14292 HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
14293 HttpRequestInfo request1;
14294 request1.method = "GET";
bnc8bef8da22016-05-30 01:28:2514295 request1.url = GURL("https://www.example.org:443");
bnc40448a532015-05-11 19:13:1414296 request1.load_flags = 0;
14297 TestCompletionCallback callback1;
14298
tfarina42834112016-09-22 13:38:2014299 int rv = trans1.Start(&request1, callback1.callback(), NetLogWithSource());
bnc40448a532015-05-11 19:13:1414300 rv = callback1.GetResult(rv);
robpercival214763f2016-07-01 23:27:0114301 EXPECT_THAT(rv, IsOk());
bnc40448a532015-05-11 19:13:1414302
14303 const HttpResponseInfo* response1 = trans1.GetResponseInfo();
wezca1070932016-05-26 20:30:5214304 ASSERT_TRUE(response1);
14305 ASSERT_TRUE(response1->headers);
bnc40448a532015-05-11 19:13:1414306 EXPECT_EQ("HTTP/1.1 200 OK", response1->headers->GetStatusLine());
14307
14308 std::string response_data1;
robpercival214763f2016-07-01 23:27:0114309 ASSERT_THAT(ReadTransaction(&trans1, &response_data1), IsOk());
bnc40448a532015-05-11 19:13:1414310 EXPECT_EQ("foobar", response_data1);
14311
14312 // Alternative should be marked as broken, because HTTP/1.1 is not sufficient
14313 // for alternative service.
14314 EXPECT_TRUE(
14315 http_server_properties->IsAlternativeServiceBroken(alternative_service));
14316
zhongyi3d4a55e72016-04-22 20:36:4614317 // Since |alternative_service| is broken, a second transaction to server
bnc40448a532015-05-11 19:13:1414318 // should not start an alternate Job. It should pool to existing connection
zhongyi3d4a55e72016-04-22 20:36:4614319 // to server.
bnc40448a532015-05-11 19:13:1414320 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
14321 HttpRequestInfo request2;
14322 request2.method = "GET";
bnc8bef8da22016-05-30 01:28:2514323 request2.url = GURL("https://www.example.org:443/second");
bnc40448a532015-05-11 19:13:1414324 request2.load_flags = 0;
14325 TestCompletionCallback callback2;
14326
tfarina42834112016-09-22 13:38:2014327 rv = trans2.Start(&request2, callback2.callback(), NetLogWithSource());
bnc40448a532015-05-11 19:13:1414328 rv = callback2.GetResult(rv);
robpercival214763f2016-07-01 23:27:0114329 EXPECT_THAT(rv, IsOk());
bnc40448a532015-05-11 19:13:1414330
14331 const HttpResponseInfo* response2 = trans2.GetResponseInfo();
wezca1070932016-05-26 20:30:5214332 ASSERT_TRUE(response2);
14333 ASSERT_TRUE(response2->headers);
bnc40448a532015-05-11 19:13:1414334 EXPECT_EQ("HTTP/1.1 200 OK", response2->headers->GetStatusLine());
14335
14336 std::string response_data2;
robpercival214763f2016-07-01 23:27:0114337 ASSERT_THAT(ReadTransaction(&trans2, &response_data2), IsOk());
bnc40448a532015-05-11 19:13:1414338 EXPECT_EQ("another", response_data2);
14339}
14340
bnc5452e2a2015-05-08 16:27:4214341// Alternative service requires HTTP/2 (or SPDY), but there is already a
14342// HTTP/1.1 socket open to the alternative server. That socket should not be
14343// used.
bncd16676a2016-07-20 16:23:0114344TEST_F(HttpNetworkTransactionTest, AlternativeServiceShouldNotPoolToHttp11) {
zhongyi3d4a55e72016-04-22 20:36:4614345 url::SchemeHostPort server("https", "origin.example.org", 443);
bnc5452e2a2015-05-08 16:27:4214346 HostPortPair alternative("alternative.example.org", 443);
14347 std::string origin_url = "https://origin.example.org:443";
14348 std::string alternative_url = "https://alternative.example.org:443";
14349
14350 // Negotiate HTTP/1.1 with alternative.example.org.
14351 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3614352 ssl.next_proto = kProtoHTTP11;
bnc5452e2a2015-05-08 16:27:4214353 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
14354
14355 // HTTP/1.1 data for |request1| and |request2|.
14356 MockWrite http_writes[] = {
14357 MockWrite(
14358 "GET / HTTP/1.1\r\n"
14359 "Host: alternative.example.org\r\n"
14360 "Connection: keep-alive\r\n\r\n"),
14361 MockWrite(
14362 "GET / HTTP/1.1\r\n"
14363 "Host: alternative.example.org\r\n"
14364 "Connection: keep-alive\r\n\r\n"),
14365 };
14366
14367 MockRead http_reads[] = {
14368 MockRead(
14369 "HTTP/1.1 200 OK\r\n"
14370 "Content-Type: text/html; charset=iso-8859-1\r\n"
14371 "Content-Length: 40\r\n\r\n"
14372 "first HTTP/1.1 response from alternative"),
14373 MockRead(
14374 "HTTP/1.1 200 OK\r\n"
14375 "Content-Type: text/html; charset=iso-8859-1\r\n"
14376 "Content-Length: 41\r\n\r\n"
14377 "second HTTP/1.1 response from alternative"),
14378 };
14379 StaticSocketDataProvider http_data(http_reads, arraysize(http_reads),
14380 http_writes, arraysize(http_writes));
14381 session_deps_.socket_factory->AddSocketDataProvider(&http_data);
14382
14383 // This test documents that an alternate Job should not pool to an already
14384 // existing HTTP/1.1 connection. In order to test this, a failed connection
zhongyi3d4a55e72016-04-22 20:36:4614385 // to the server is mocked. This way |request2| relies on the alternate Job.
bnc5452e2a2015-05-08 16:27:4214386 StaticSocketDataProvider data_refused;
14387 data_refused.set_connect_data(MockConnect(ASYNC, ERR_CONNECTION_REFUSED));
14388 session_deps_.socket_factory->AddSocketDataProvider(&data_refused);
14389
zhongyi3d4a55e72016-04-22 20:36:4614390 // Set up alternative service for server.
danakj1fd259a02016-04-16 03:17:0914391 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc525e175a2016-06-20 12:36:4014392 HttpServerProperties* http_server_properties =
bnc5452e2a2015-05-08 16:27:4214393 session->http_server_properties();
bnc3472afd2016-11-17 15:27:2114394 AlternativeService alternative_service(kProtoHTTP2, alternative);
bnc7dc7e1b42015-07-28 14:43:1214395 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:2114396 http_server_properties->SetHttp2AlternativeService(
14397 server, alternative_service, expiration);
bnc5452e2a2015-05-08 16:27:4214398
14399 // First transaction to alternative to open an HTTP/1.1 socket.
bnc5452e2a2015-05-08 16:27:4214400 HttpRequestInfo request1;
krasinc06a72a2016-12-21 03:42:4614401 HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
bnc5452e2a2015-05-08 16:27:4214402 request1.method = "GET";
14403 request1.url = GURL(alternative_url);
14404 request1.load_flags = 0;
14405 TestCompletionCallback callback1;
14406
tfarina42834112016-09-22 13:38:2014407 int rv = trans1.Start(&request1, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0114408 EXPECT_THAT(callback1.GetResult(rv), IsOk());
bnc691fda62016-08-12 00:43:1614409 const HttpResponseInfo* response1 = trans1.GetResponseInfo();
bnc5452e2a2015-05-08 16:27:4214410 ASSERT_TRUE(response1);
wezca1070932016-05-26 20:30:5214411 ASSERT_TRUE(response1->headers);
bnc5452e2a2015-05-08 16:27:4214412 EXPECT_EQ("HTTP/1.1 200 OK", response1->headers->GetStatusLine());
bnc94c92842016-09-21 15:22:5214413 EXPECT_TRUE(response1->was_alpn_negotiated);
bnc5452e2a2015-05-08 16:27:4214414 EXPECT_FALSE(response1->was_fetched_via_spdy);
14415 std::string response_data1;
bnc691fda62016-08-12 00:43:1614416 ASSERT_THAT(ReadTransaction(&trans1, &response_data1), IsOk());
bnc5452e2a2015-05-08 16:27:4214417 EXPECT_EQ("first HTTP/1.1 response from alternative", response_data1);
14418
14419 // Request for origin.example.org, which has an alternative service. This
14420 // will start two Jobs: the alternative looks for connections to pool to,
14421 // finds one which is HTTP/1.1, and should ignore it, and should not try to
zhongyi3d4a55e72016-04-22 20:36:4614422 // open other connections to alternative server. The Job to server fails, so
bnc5452e2a2015-05-08 16:27:4214423 // this request fails.
bnc5452e2a2015-05-08 16:27:4214424 HttpRequestInfo request2;
krasinc06a72a2016-12-21 03:42:4614425 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
bnc5452e2a2015-05-08 16:27:4214426 request2.method = "GET";
14427 request2.url = GURL(origin_url);
14428 request2.load_flags = 0;
14429 TestCompletionCallback callback2;
14430
tfarina42834112016-09-22 13:38:2014431 rv = trans2.Start(&request2, callback2.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0114432 EXPECT_THAT(callback2.GetResult(rv), IsError(ERR_CONNECTION_REFUSED));
bnc5452e2a2015-05-08 16:27:4214433
14434 // Another transaction to alternative. This is to test that the HTTP/1.1
14435 // socket is still open and in the pool.
bnc5452e2a2015-05-08 16:27:4214436 HttpRequestInfo request3;
krasinc06a72a2016-12-21 03:42:4614437 HttpNetworkTransaction trans3(DEFAULT_PRIORITY, session.get());
bnc5452e2a2015-05-08 16:27:4214438 request3.method = "GET";
14439 request3.url = GURL(alternative_url);
14440 request3.load_flags = 0;
14441 TestCompletionCallback callback3;
14442
tfarina42834112016-09-22 13:38:2014443 rv = trans3.Start(&request3, callback3.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0114444 EXPECT_THAT(callback3.GetResult(rv), IsOk());
bnc691fda62016-08-12 00:43:1614445 const HttpResponseInfo* response3 = trans3.GetResponseInfo();
bnc5452e2a2015-05-08 16:27:4214446 ASSERT_TRUE(response3);
wezca1070932016-05-26 20:30:5214447 ASSERT_TRUE(response3->headers);
bnc5452e2a2015-05-08 16:27:4214448 EXPECT_EQ("HTTP/1.1 200 OK", response3->headers->GetStatusLine());
bnc94c92842016-09-21 15:22:5214449 EXPECT_TRUE(response3->was_alpn_negotiated);
bnc5452e2a2015-05-08 16:27:4214450 EXPECT_FALSE(response3->was_fetched_via_spdy);
14451 std::string response_data3;
bnc691fda62016-08-12 00:43:1614452 ASSERT_THAT(ReadTransaction(&trans3, &response_data3), IsOk());
bnc5452e2a2015-05-08 16:27:4214453 EXPECT_EQ("second HTTP/1.1 response from alternative", response_data3);
14454}
14455
bncd16676a2016-07-20 16:23:0114456TEST_F(HttpNetworkTransactionTest, DoNotUseSpdySessionForHttpOverTunnel) {
bncce36dca22015-04-21 22:11:2314457 const std::string https_url = "https://www.example.org:8080/";
14458 const std::string http_url = "http://www.example.org:8080/";
[email protected]8450d722012-07-02 19:14:0414459
rdsmithebb50aa2015-11-12 03:44:3814460 // Separate SPDY util instance for naked and wrapped requests.
bncd16676a2016-07-20 16:23:0114461 SpdyTestUtil spdy_util_wrapped;
rdsmithebb50aa2015-11-12 03:44:3814462
[email protected]8450d722012-07-02 19:14:0414463 // SPDY GET for HTTPS URL (through CONNECT tunnel)
bncce36dca22015-04-21 22:11:2314464 const HostPortPair host_port_pair("www.example.org", 8080);
bncdf80d44fd2016-07-15 20:27:4114465 SpdySerializedFrame connect(
lgarrona91df87f2014-12-05 00:51:3414466 spdy_util_.ConstructSpdyConnect(NULL, 0, 1, LOWEST, host_port_pair));
bncdf80d44fd2016-07-15 20:27:4114467 SpdySerializedFrame req1(
bnc38dcd392016-02-09 23:19:4914468 spdy_util_wrapped.ConstructSpdyGet(https_url.c_str(), 1, LOWEST));
bncdf80d44fd2016-07-15 20:27:4114469 SpdySerializedFrame wrapped_req1(
[email protected]23e482282013-06-14 16:08:0214470 spdy_util_.ConstructWrappedSpdyFrame(req1, 1));
[email protected]601e03f12014-04-06 16:26:3914471
14472 // SPDY GET for HTTP URL (through the proxy, but not the tunnel).
[email protected]745aa9c2014-06-27 02:21:2914473 SpdyHeaderBlock req2_block;
14474 req2_block[spdy_util_.GetMethodKey()] = "GET";
bncce36dca22015-04-21 22:11:2314475 req2_block[spdy_util_.GetHostKey()] = "www.example.org:8080";
[email protected]745aa9c2014-06-27 02:21:2914476 req2_block[spdy_util_.GetSchemeKey()] = "http";
bnc7ecc1122015-09-28 13:22:4914477 req2_block[spdy_util_.GetPathKey()] = "/";
bncdf80d44fd2016-07-15 20:27:4114478 SpdySerializedFrame req2(
bnc42331402016-07-25 13:36:1514479 spdy_util_.ConstructSpdyHeaders(3, std::move(req2_block), MEDIUM, true));
[email protected]8450d722012-07-02 19:14:0414480
14481 MockWrite writes1[] = {
bncdf80d44fd2016-07-15 20:27:4114482 CreateMockWrite(connect, 0), CreateMockWrite(wrapped_req1, 2),
14483 CreateMockWrite(req2, 6),
[email protected]8450d722012-07-02 19:14:0414484 };
14485
bncdf80d44fd2016-07-15 20:27:4114486 SpdySerializedFrame conn_resp(
bnc42331402016-07-25 13:36:1514487 spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
bncdf80d44fd2016-07-15 20:27:4114488 SpdySerializedFrame resp1(
bnc42331402016-07-25 13:36:1514489 spdy_util_wrapped.ConstructSpdyGetReply(nullptr, 0, 1));
bncdf80d44fd2016-07-15 20:27:4114490 SpdySerializedFrame body1(spdy_util_wrapped.ConstructSpdyDataFrame(1, true));
14491 SpdySerializedFrame wrapped_resp1(
rdsmithebb50aa2015-11-12 03:44:3814492 spdy_util_wrapped.ConstructWrappedSpdyFrame(resp1, 1));
bncdf80d44fd2016-07-15 20:27:4114493 SpdySerializedFrame wrapped_body1(
rdsmithebb50aa2015-11-12 03:44:3814494 spdy_util_wrapped.ConstructWrappedSpdyFrame(body1, 1));
bnc42331402016-07-25 13:36:1514495 SpdySerializedFrame resp2(spdy_util_.ConstructSpdyGetReply(NULL, 0, 3));
bncdf80d44fd2016-07-15 20:27:4114496 SpdySerializedFrame body2(spdy_util_.ConstructSpdyDataFrame(3, true));
mmenke666a6fea2015-12-19 04:16:3314497 MockRead reads1[] = {
bncdf80d44fd2016-07-15 20:27:4114498 CreateMockRead(conn_resp, 1),
mmenke666a6fea2015-12-19 04:16:3314499 MockRead(ASYNC, ERR_IO_PENDING, 3),
bncdf80d44fd2016-07-15 20:27:4114500 CreateMockRead(wrapped_resp1, 4),
14501 CreateMockRead(wrapped_body1, 5),
mmenke666a6fea2015-12-19 04:16:3314502 MockRead(ASYNC, ERR_IO_PENDING, 7),
bncdf80d44fd2016-07-15 20:27:4114503 CreateMockRead(resp2, 8),
14504 CreateMockRead(body2, 9),
mmenke666a6fea2015-12-19 04:16:3314505 MockRead(SYNCHRONOUS, ERR_IO_PENDING, 10),
14506 };
[email protected]8450d722012-07-02 19:14:0414507
mmenke666a6fea2015-12-19 04:16:3314508 SequencedSocketData data1(reads1, arraysize(reads1), writes1,
14509 arraysize(writes1));
[email protected]8450d722012-07-02 19:14:0414510 MockConnect connect_data1(ASYNC, OK);
[email protected]dd54bd82012-07-19 23:44:5714511 data1.set_connect_data(connect_data1);
[email protected]8450d722012-07-02 19:14:0414512
rdsmith82957ad2015-09-16 19:42:0314513 session_deps_.proxy_service =
14514 ProxyService::CreateFixedFromPacResult("HTTPS proxy:70");
vishal.b62985ca92015-04-17 08:45:5114515 TestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:0714516 session_deps_.net_log = &log;
[email protected]8450d722012-07-02 19:14:0414517 SSLSocketDataProvider ssl1(ASYNC, OK); // to the proxy
bnc3cf2a592016-08-11 14:48:3614518 ssl1.next_proto = kProtoHTTP2;
mmenke666a6fea2015-12-19 04:16:3314519 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl1);
[email protected]8450d722012-07-02 19:14:0414520 SSLSocketDataProvider ssl2(ASYNC, OK); // to the server
bnc3cf2a592016-08-11 14:48:3614521 ssl2.next_proto = kProtoHTTP2;
mmenke666a6fea2015-12-19 04:16:3314522 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
14523 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8450d722012-07-02 19:14:0414524
danakj1fd259a02016-04-16 03:17:0914525 std::unique_ptr<HttpNetworkSession> session = CreateSession(&session_deps_);
[email protected]8450d722012-07-02 19:14:0414526
14527 // Start the first transaction to set up the SpdySession
14528 HttpRequestInfo request1;
14529 request1.method = "GET";
14530 request1.url = GURL(https_url);
[email protected]8450d722012-07-02 19:14:0414531 request1.load_flags = 0;
[email protected]90499482013-06-01 00:39:5014532 HttpNetworkTransaction trans1(LOWEST, session.get());
[email protected]8450d722012-07-02 19:14:0414533 TestCompletionCallback callback1;
tfarina42834112016-09-22 13:38:2014534 int rv = trans1.Start(&request1, callback1.callback(), NetLogWithSource());
[email protected]8450d722012-07-02 19:14:0414535
mmenke666a6fea2015-12-19 04:16:3314536 // This pause is a hack to avoid running into https://crbug.com/497228.
14537 data1.RunUntilPaused();
14538 base::RunLoop().RunUntilIdle();
14539 data1.Resume();
robpercival214763f2016-07-01 23:27:0114540 EXPECT_THAT(callback1.GetResult(rv), IsOk());
[email protected]8450d722012-07-02 19:14:0414541 EXPECT_TRUE(trans1.GetResponseInfo()->was_fetched_via_spdy);
14542
[email protected]f6c63db52013-02-02 00:35:2214543 LoadTimingInfo load_timing_info1;
14544 EXPECT_TRUE(trans1.GetLoadTimingInfo(&load_timing_info1));
14545 TestLoadTimingNotReusedWithPac(load_timing_info1,
14546 CONNECT_TIMING_HAS_SSL_TIMES);
14547
mmenke666a6fea2015-12-19 04:16:3314548 // Now, start the HTTP request.
[email protected]8450d722012-07-02 19:14:0414549 HttpRequestInfo request2;
14550 request2.method = "GET";
14551 request2.url = GURL(http_url);
[email protected]8450d722012-07-02 19:14:0414552 request2.load_flags = 0;
[email protected]90499482013-06-01 00:39:5014553 HttpNetworkTransaction trans2(MEDIUM, session.get());
[email protected]8450d722012-07-02 19:14:0414554 TestCompletionCallback callback2;
tfarina42834112016-09-22 13:38:2014555 rv = trans2.Start(&request2, callback2.callback(), NetLogWithSource());
[email protected]8450d722012-07-02 19:14:0414556
mmenke666a6fea2015-12-19 04:16:3314557 // This pause is a hack to avoid running into https://crbug.com/497228.
14558 data1.RunUntilPaused();
14559 base::RunLoop().RunUntilIdle();
14560 data1.Resume();
robpercival214763f2016-07-01 23:27:0114561 EXPECT_THAT(callback2.GetResult(rv), IsOk());
mmenke666a6fea2015-12-19 04:16:3314562
[email protected]8450d722012-07-02 19:14:0414563 EXPECT_TRUE(trans2.GetResponseInfo()->was_fetched_via_spdy);
[email protected]f6c63db52013-02-02 00:35:2214564
14565 LoadTimingInfo load_timing_info2;
14566 EXPECT_TRUE(trans2.GetLoadTimingInfo(&load_timing_info2));
14567 // The established SPDY sessions is considered reused by the HTTP request.
14568 TestLoadTimingReusedWithPac(load_timing_info2);
14569 // HTTP requests over a SPDY session should have a different connection
14570 // socket_log_id than requests over a tunnel.
14571 EXPECT_NE(load_timing_info1.socket_log_id, load_timing_info2.socket_log_id);
[email protected]8450d722012-07-02 19:14:0414572}
14573
[email protected]2d88e7d2012-07-19 17:55:1714574// Test that in the case where we have a SPDY session to a SPDY proxy
14575// that we do not pool other origins that resolve to the same IP when
14576// the certificate does not match the new origin.
14577// http://crbug.com/134690
bncd16676a2016-07-20 16:23:0114578TEST_F(HttpNetworkTransactionTest, DoNotUseSpdySessionIfCertDoesNotMatch) {
bncce36dca22015-04-21 22:11:2314579 const std::string url1 = "http://www.example.org/";
14580 const std::string url2 = "https://news.example.org/";
[email protected]2d88e7d2012-07-19 17:55:1714581 const std::string ip_addr = "1.2.3.4";
14582
rdsmithebb50aa2015-11-12 03:44:3814583 // Second SpdyTestUtil instance for the second socket.
bncd16676a2016-07-20 16:23:0114584 SpdyTestUtil spdy_util_secure;
rdsmithebb50aa2015-11-12 03:44:3814585
[email protected]2d88e7d2012-07-19 17:55:1714586 // SPDY GET for HTTP URL (through SPDY proxy)
bnc086b39e12016-06-24 13:05:2614587 SpdyHeaderBlock headers(
bncce36dca22015-04-21 22:11:2314588 spdy_util_.ConstructGetHeaderBlockForProxy("http://www.example.org/"));
bncdf80d44fd2016-07-15 20:27:4114589 SpdySerializedFrame req1(
bnc42331402016-07-25 13:36:1514590 spdy_util_.ConstructSpdyHeaders(1, std::move(headers), LOWEST, true));
[email protected]2d88e7d2012-07-19 17:55:1714591
14592 MockWrite writes1[] = {
bncdf80d44fd2016-07-15 20:27:4114593 CreateMockWrite(req1, 0),
[email protected]2d88e7d2012-07-19 17:55:1714594 };
14595
bnc42331402016-07-25 13:36:1514596 SpdySerializedFrame resp1(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
bncdf80d44fd2016-07-15 20:27:4114597 SpdySerializedFrame body1(spdy_util_.ConstructSpdyDataFrame(1, true));
[email protected]2d88e7d2012-07-19 17:55:1714598 MockRead reads1[] = {
bncdf80d44fd2016-07-15 20:27:4114599 MockRead(ASYNC, ERR_IO_PENDING, 1), CreateMockRead(resp1, 2),
14600 CreateMockRead(body1, 3), MockRead(ASYNC, OK, 4), // EOF
[email protected]2d88e7d2012-07-19 17:55:1714601 };
14602
mmenke666a6fea2015-12-19 04:16:3314603 SequencedSocketData data1(reads1, arraysize(reads1), writes1,
14604 arraysize(writes1));
martijnfe9636e2016-02-06 14:33:3214605 IPAddress ip;
martijn654c8c42016-02-10 22:10:5914606 ASSERT_TRUE(ip.AssignFromIPLiteral(ip_addr));
[email protected]2d88e7d2012-07-19 17:55:1714607 IPEndPoint peer_addr = IPEndPoint(ip, 443);
14608 MockConnect connect_data1(ASYNC, OK, peer_addr);
mmenke666a6fea2015-12-19 04:16:3314609 data1.set_connect_data(connect_data1);
[email protected]2d88e7d2012-07-19 17:55:1714610
14611 // SPDY GET for HTTPS URL (direct)
bncdf80d44fd2016-07-15 20:27:4114612 SpdySerializedFrame req2(
bnc38dcd392016-02-09 23:19:4914613 spdy_util_secure.ConstructSpdyGet(url2.c_str(), 1, MEDIUM));
[email protected]2d88e7d2012-07-19 17:55:1714614
14615 MockWrite writes2[] = {
bncdf80d44fd2016-07-15 20:27:4114616 CreateMockWrite(req2, 0),
[email protected]2d88e7d2012-07-19 17:55:1714617 };
14618
bnc42331402016-07-25 13:36:1514619 SpdySerializedFrame resp2(spdy_util_secure.ConstructSpdyGetReply(NULL, 0, 1));
bncdf80d44fd2016-07-15 20:27:4114620 SpdySerializedFrame body2(spdy_util_secure.ConstructSpdyDataFrame(1, true));
14621 MockRead reads2[] = {CreateMockRead(resp2, 1), CreateMockRead(body2, 2),
mmenke666a6fea2015-12-19 04:16:3314622 MockRead(ASYNC, OK, 3)};
[email protected]2d88e7d2012-07-19 17:55:1714623
mmenke666a6fea2015-12-19 04:16:3314624 SequencedSocketData data2(reads2, arraysize(reads2), writes2,
14625 arraysize(writes2));
[email protected]2d88e7d2012-07-19 17:55:1714626 MockConnect connect_data2(ASYNC, OK);
mmenke666a6fea2015-12-19 04:16:3314627 data2.set_connect_data(connect_data2);
[email protected]2d88e7d2012-07-19 17:55:1714628
14629 // Set up a proxy config that sends HTTP requests to a proxy, and
14630 // all others direct.
14631 ProxyConfig proxy_config;
14632 proxy_config.proxy_rules().ParseFromString("http=https://proxy:443");
Jeremy Roman0579ed62017-08-29 15:56:1914633 session_deps_.proxy_service = std::make_unique<ProxyService>(
14634 std::make_unique<ProxyConfigServiceFixed>(proxy_config), nullptr,
bnc87dcefc2017-05-25 12:47:5814635 nullptr);
[email protected]2d88e7d2012-07-19 17:55:1714636
bncce36dca22015-04-21 22:11:2314637 SSLSocketDataProvider ssl1(ASYNC, OK); // to the proxy
bnc3cf2a592016-08-11 14:48:3614638 ssl1.next_proto = kProtoHTTP2;
[email protected]2d88e7d2012-07-19 17:55:1714639 // Load a valid cert. Note, that this does not need to
14640 // be valid for proxy because the MockSSLClientSocket does
14641 // not actually verify it. But SpdySession will use this
14642 // to see if it is valid for the new origin
bncce36dca22015-04-21 22:11:2314643 ssl1.cert = ImportCertFromFile(GetTestCertsDirectory(), "ok_cert.pem");
wezca1070932016-05-26 20:30:5214644 ASSERT_TRUE(ssl1.cert);
mmenke666a6fea2015-12-19 04:16:3314645 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl1);
14646 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]2d88e7d2012-07-19 17:55:1714647
14648 SSLSocketDataProvider ssl2(ASYNC, OK); // to the server
bnc3cf2a592016-08-11 14:48:3614649 ssl2.next_proto = kProtoHTTP2;
mmenke666a6fea2015-12-19 04:16:3314650 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
14651 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]2d88e7d2012-07-19 17:55:1714652
Jeremy Roman0579ed62017-08-29 15:56:1914653 session_deps_.host_resolver = std::make_unique<MockCachingHostResolver>();
bncce36dca22015-04-21 22:11:2314654 session_deps_.host_resolver->rules()->AddRule("news.example.org", ip_addr);
[email protected]bb88e1d32013-05-03 23:11:0714655 session_deps_.host_resolver->rules()->AddRule("proxy", ip_addr);
[email protected]2d88e7d2012-07-19 17:55:1714656
danakj1fd259a02016-04-16 03:17:0914657 std::unique_ptr<HttpNetworkSession> session = CreateSession(&session_deps_);
[email protected]2d88e7d2012-07-19 17:55:1714658
14659 // Start the first transaction to set up the SpdySession
14660 HttpRequestInfo request1;
14661 request1.method = "GET";
14662 request1.url = GURL(url1);
[email protected]2d88e7d2012-07-19 17:55:1714663 request1.load_flags = 0;
[email protected]90499482013-06-01 00:39:5014664 HttpNetworkTransaction trans1(LOWEST, session.get());
[email protected]2d88e7d2012-07-19 17:55:1714665 TestCompletionCallback callback1;
14666 ASSERT_EQ(ERR_IO_PENDING,
tfarina42834112016-09-22 13:38:2014667 trans1.Start(&request1, callback1.callback(), NetLogWithSource()));
mmenke666a6fea2015-12-19 04:16:3314668 // This pause is a hack to avoid running into https://crbug.com/497228.
14669 data1.RunUntilPaused();
14670 base::RunLoop().RunUntilIdle();
14671 data1.Resume();
[email protected]2d88e7d2012-07-19 17:55:1714672
robpercival214763f2016-07-01 23:27:0114673 EXPECT_THAT(callback1.WaitForResult(), IsOk());
[email protected]2d88e7d2012-07-19 17:55:1714674 EXPECT_TRUE(trans1.GetResponseInfo()->was_fetched_via_spdy);
14675
14676 // Now, start the HTTP request
14677 HttpRequestInfo request2;
14678 request2.method = "GET";
14679 request2.url = GURL(url2);
[email protected]2d88e7d2012-07-19 17:55:1714680 request2.load_flags = 0;
[email protected]90499482013-06-01 00:39:5014681 HttpNetworkTransaction trans2(MEDIUM, session.get());
[email protected]2d88e7d2012-07-19 17:55:1714682 TestCompletionCallback callback2;
14683 EXPECT_EQ(ERR_IO_PENDING,
tfarina42834112016-09-22 13:38:2014684 trans2.Start(&request2, callback2.callback(), NetLogWithSource()));
fdoray92e35a72016-06-10 15:54:5514685 base::RunLoop().RunUntilIdle();
[email protected]2d88e7d2012-07-19 17:55:1714686
14687 ASSERT_TRUE(callback2.have_result());
robpercival214763f2016-07-01 23:27:0114688 EXPECT_THAT(callback2.WaitForResult(), IsOk());
[email protected]2d88e7d2012-07-19 17:55:1714689 EXPECT_TRUE(trans2.GetResponseInfo()->was_fetched_via_spdy);
14690}
14691
[email protected]85f97342013-04-17 06:12:2414692// Test to verify that a failed socket read (due to an ERR_CONNECTION_CLOSED
14693// error) in SPDY session, removes the socket from pool and closes the SPDY
14694// session. Verify that new url's from the same HttpNetworkSession (and a new
14695// SpdySession) do work. http://crbug.com/224701
bncd16676a2016-07-20 16:23:0114696TEST_F(HttpNetworkTransactionTest, ErrorSocketNotConnected) {
bncce36dca22015-04-21 22:11:2314697 const std::string https_url = "https://www.example.org/";
[email protected]85f97342013-04-17 06:12:2414698
14699 MockRead reads1[] = {
14700 MockRead(SYNCHRONOUS, ERR_CONNECTION_CLOSED, 0)
14701 };
14702
mmenke11eb5152015-06-09 14:50:5014703 SequencedSocketData data1(reads1, arraysize(reads1), NULL, 0);
[email protected]85f97342013-04-17 06:12:2414704
bncdf80d44fd2016-07-15 20:27:4114705 SpdySerializedFrame req2(
bnc38dcd392016-02-09 23:19:4914706 spdy_util_.ConstructSpdyGet(https_url.c_str(), 1, MEDIUM));
[email protected]85f97342013-04-17 06:12:2414707 MockWrite writes2[] = {
bncdf80d44fd2016-07-15 20:27:4114708 CreateMockWrite(req2, 0),
[email protected]85f97342013-04-17 06:12:2414709 };
14710
bnc42331402016-07-25 13:36:1514711 SpdySerializedFrame resp2(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
bncdf80d44fd2016-07-15 20:27:4114712 SpdySerializedFrame body2(spdy_util_.ConstructSpdyDataFrame(1, true));
[email protected]85f97342013-04-17 06:12:2414713 MockRead reads2[] = {
bncdf80d44fd2016-07-15 20:27:4114714 CreateMockRead(resp2, 1), CreateMockRead(body2, 2),
14715 MockRead(ASYNC, OK, 3) // EOF
[email protected]85f97342013-04-17 06:12:2414716 };
14717
mmenke11eb5152015-06-09 14:50:5014718 SequencedSocketData data2(reads2, arraysize(reads2), writes2,
14719 arraysize(writes2));
[email protected]85f97342013-04-17 06:12:2414720
[email protected]85f97342013-04-17 06:12:2414721 SSLSocketDataProvider ssl1(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3614722 ssl1.next_proto = kProtoHTTP2;
mmenke11eb5152015-06-09 14:50:5014723 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl1);
14724 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]85f97342013-04-17 06:12:2414725
14726 SSLSocketDataProvider ssl2(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3614727 ssl2.next_proto = kProtoHTTP2;
mmenke11eb5152015-06-09 14:50:5014728 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
14729 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]85f97342013-04-17 06:12:2414730
danakj1fd259a02016-04-16 03:17:0914731 std::unique_ptr<HttpNetworkSession> session(
mmenke11eb5152015-06-09 14:50:5014732 SpdySessionDependencies::SpdyCreateSession(&session_deps_));
[email protected]85f97342013-04-17 06:12:2414733
14734 // Start the first transaction to set up the SpdySession and verify that
14735 // connection was closed.
14736 HttpRequestInfo request1;
14737 request1.method = "GET";
14738 request1.url = GURL(https_url);
14739 request1.load_flags = 0;
[email protected]90499482013-06-01 00:39:5014740 HttpNetworkTransaction trans1(MEDIUM, session.get());
[email protected]85f97342013-04-17 06:12:2414741 TestCompletionCallback callback1;
14742 EXPECT_EQ(ERR_IO_PENDING,
tfarina42834112016-09-22 13:38:2014743 trans1.Start(&request1, callback1.callback(), NetLogWithSource()));
robpercival214763f2016-07-01 23:27:0114744 EXPECT_THAT(callback1.WaitForResult(), IsError(ERR_CONNECTION_CLOSED));
[email protected]85f97342013-04-17 06:12:2414745
14746 // Now, start the second request and make sure it succeeds.
14747 HttpRequestInfo request2;
14748 request2.method = "GET";
14749 request2.url = GURL(https_url);
14750 request2.load_flags = 0;
[email protected]90499482013-06-01 00:39:5014751 HttpNetworkTransaction trans2(MEDIUM, session.get());
[email protected]85f97342013-04-17 06:12:2414752 TestCompletionCallback callback2;
14753 EXPECT_EQ(ERR_IO_PENDING,
tfarina42834112016-09-22 13:38:2014754 trans2.Start(&request2, callback2.callback(), NetLogWithSource()));
[email protected]85f97342013-04-17 06:12:2414755
robpercival214763f2016-07-01 23:27:0114756 ASSERT_THAT(callback2.WaitForResult(), IsOk());
[email protected]85f97342013-04-17 06:12:2414757 EXPECT_TRUE(trans2.GetResponseInfo()->was_fetched_via_spdy);
14758}
14759
bncd16676a2016-07-20 16:23:0114760TEST_F(HttpNetworkTransactionTest, CloseIdleSpdySessionToOpenNewOne) {
[email protected]483fa202013-05-14 01:07:0314761 ClientSocketPoolManager::set_max_sockets_per_group(
14762 HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
14763 ClientSocketPoolManager::set_max_sockets_per_pool(
14764 HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
14765
14766 // Use two different hosts with different IPs so they don't get pooled.
14767 session_deps_.host_resolver->rules()->AddRule("www.a.com", "10.0.0.1");
14768 session_deps_.host_resolver->rules()->AddRule("www.b.com", "10.0.0.2");
danakj1fd259a02016-04-16 03:17:0914769 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]483fa202013-05-14 01:07:0314770
14771 SSLSocketDataProvider ssl1(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3614772 ssl1.next_proto = kProtoHTTP2;
[email protected]483fa202013-05-14 01:07:0314773 SSLSocketDataProvider ssl2(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3614774 ssl2.next_proto = kProtoHTTP2;
[email protected]483fa202013-05-14 01:07:0314775 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl1);
14776 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
14777
bncdf80d44fd2016-07-15 20:27:4114778 SpdySerializedFrame host1_req(
bnc38dcd392016-02-09 23:19:4914779 spdy_util_.ConstructSpdyGet("https://www.a.com", 1, DEFAULT_PRIORITY));
[email protected]483fa202013-05-14 01:07:0314780 MockWrite spdy1_writes[] = {
bncdf80d44fd2016-07-15 20:27:4114781 CreateMockWrite(host1_req, 0),
[email protected]483fa202013-05-14 01:07:0314782 };
bnc42331402016-07-25 13:36:1514783 SpdySerializedFrame host1_resp(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
bncdf80d44fd2016-07-15 20:27:4114784 SpdySerializedFrame host1_resp_body(
14785 spdy_util_.ConstructSpdyDataFrame(1, true));
[email protected]483fa202013-05-14 01:07:0314786 MockRead spdy1_reads[] = {
bncdf80d44fd2016-07-15 20:27:4114787 CreateMockRead(host1_resp, 1), CreateMockRead(host1_resp_body, 2),
mmenkee24011922015-12-17 22:12:5914788 MockRead(SYNCHRONOUS, ERR_IO_PENDING, 3),
[email protected]483fa202013-05-14 01:07:0314789 };
14790
rdsmithebb50aa2015-11-12 03:44:3814791 // Use a separate test instance for the separate SpdySession that will be
14792 // created.
bncd16676a2016-07-20 16:23:0114793 SpdyTestUtil spdy_util_2;
Jeremy Roman0579ed62017-08-29 15:56:1914794 auto spdy1_data = std::make_unique<SequencedSocketData>(
bnc87dcefc2017-05-25 12:47:5814795 spdy1_reads, arraysize(spdy1_reads), spdy1_writes,
14796 arraysize(spdy1_writes));
[email protected]483fa202013-05-14 01:07:0314797 session_deps_.socket_factory->AddSocketDataProvider(spdy1_data.get());
14798
bncdf80d44fd2016-07-15 20:27:4114799 SpdySerializedFrame host2_req(
bnc38dcd392016-02-09 23:19:4914800 spdy_util_2.ConstructSpdyGet("https://www.b.com", 1, DEFAULT_PRIORITY));
[email protected]483fa202013-05-14 01:07:0314801 MockWrite spdy2_writes[] = {
bncdf80d44fd2016-07-15 20:27:4114802 CreateMockWrite(host2_req, 0),
[email protected]483fa202013-05-14 01:07:0314803 };
bnc42331402016-07-25 13:36:1514804 SpdySerializedFrame host2_resp(spdy_util_2.ConstructSpdyGetReply(NULL, 0, 1));
bncdf80d44fd2016-07-15 20:27:4114805 SpdySerializedFrame host2_resp_body(
14806 spdy_util_2.ConstructSpdyDataFrame(1, true));
[email protected]483fa202013-05-14 01:07:0314807 MockRead spdy2_reads[] = {
bncdf80d44fd2016-07-15 20:27:4114808 CreateMockRead(host2_resp, 1), CreateMockRead(host2_resp_body, 2),
mmenkee24011922015-12-17 22:12:5914809 MockRead(SYNCHRONOUS, ERR_IO_PENDING, 3),
[email protected]483fa202013-05-14 01:07:0314810 };
14811
Jeremy Roman0579ed62017-08-29 15:56:1914812 auto spdy2_data = std::make_unique<SequencedSocketData>(
bnc87dcefc2017-05-25 12:47:5814813 spdy2_reads, arraysize(spdy2_reads), spdy2_writes,
14814 arraysize(spdy2_writes));
[email protected]483fa202013-05-14 01:07:0314815 session_deps_.socket_factory->AddSocketDataProvider(spdy2_data.get());
14816
14817 MockWrite http_write[] = {
14818 MockWrite("GET / HTTP/1.1\r\n"
14819 "Host: www.a.com\r\n"
14820 "Connection: keep-alive\r\n\r\n"),
14821 };
14822
14823 MockRead http_read[] = {
14824 MockRead("HTTP/1.1 200 OK\r\n"),
14825 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
14826 MockRead("Content-Length: 6\r\n\r\n"),
14827 MockRead("hello!"),
14828 };
14829 StaticSocketDataProvider http_data(http_read, arraysize(http_read),
14830 http_write, arraysize(http_write));
14831 session_deps_.socket_factory->AddSocketDataProvider(&http_data);
14832
14833 HostPortPair host_port_pair_a("www.a.com", 443);
[email protected]e6d017652013-05-17 18:01:4014834 SpdySessionKey spdy_session_key_a(
[email protected]314b03992014-04-01 01:28:5314835 host_port_pair_a, ProxyServer::Direct(), PRIVACY_MODE_DISABLED);
[email protected]483fa202013-05-14 01:07:0314836 EXPECT_FALSE(
[email protected]41d64e82013-07-03 22:44:2614837 HasSpdySession(session->spdy_session_pool(), spdy_session_key_a));
[email protected]483fa202013-05-14 01:07:0314838
14839 TestCompletionCallback callback;
14840 HttpRequestInfo request1;
14841 request1.method = "GET";
14842 request1.url = GURL("https://www.a.com/");
14843 request1.load_flags = 0;
bnc87dcefc2017-05-25 12:47:5814844 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:1914845 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]483fa202013-05-14 01:07:0314846
tfarina42834112016-09-22 13:38:2014847 int rv = trans->Start(&request1, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0114848 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
14849 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]483fa202013-05-14 01:07:0314850
14851 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5214852 ASSERT_TRUE(response);
14853 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0214854 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]483fa202013-05-14 01:07:0314855 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5214856 EXPECT_TRUE(response->was_alpn_negotiated);
[email protected]483fa202013-05-14 01:07:0314857
14858 std::string response_data;
robpercival214763f2016-07-01 23:27:0114859 ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
[email protected]483fa202013-05-14 01:07:0314860 EXPECT_EQ("hello!", response_data);
14861 trans.reset();
14862 EXPECT_TRUE(
[email protected]41d64e82013-07-03 22:44:2614863 HasSpdySession(session->spdy_session_pool(), spdy_session_key_a));
[email protected]483fa202013-05-14 01:07:0314864
14865 HostPortPair host_port_pair_b("www.b.com", 443);
[email protected]e6d017652013-05-17 18:01:4014866 SpdySessionKey spdy_session_key_b(
[email protected]314b03992014-04-01 01:28:5314867 host_port_pair_b, ProxyServer::Direct(), PRIVACY_MODE_DISABLED);
[email protected]483fa202013-05-14 01:07:0314868 EXPECT_FALSE(
[email protected]41d64e82013-07-03 22:44:2614869 HasSpdySession(session->spdy_session_pool(), spdy_session_key_b));
[email protected]483fa202013-05-14 01:07:0314870 HttpRequestInfo request2;
14871 request2.method = "GET";
14872 request2.url = GURL("https://www.b.com/");
14873 request2.load_flags = 0;
bnc87dcefc2017-05-25 12:47:5814874 trans =
Jeremy Roman0579ed62017-08-29 15:56:1914875 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]483fa202013-05-14 01:07:0314876
tfarina42834112016-09-22 13:38:2014877 rv = trans->Start(&request2, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0114878 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
14879 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]483fa202013-05-14 01:07:0314880
14881 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5214882 ASSERT_TRUE(response);
14883 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0214884 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]483fa202013-05-14 01:07:0314885 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5214886 EXPECT_TRUE(response->was_alpn_negotiated);
robpercival214763f2016-07-01 23:27:0114887 ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
[email protected]483fa202013-05-14 01:07:0314888 EXPECT_EQ("hello!", response_data);
14889 EXPECT_FALSE(
[email protected]41d64e82013-07-03 22:44:2614890 HasSpdySession(session->spdy_session_pool(), spdy_session_key_a));
[email protected]483fa202013-05-14 01:07:0314891 EXPECT_TRUE(
[email protected]41d64e82013-07-03 22:44:2614892 HasSpdySession(session->spdy_session_pool(), spdy_session_key_b));
[email protected]483fa202013-05-14 01:07:0314893
14894 HostPortPair host_port_pair_a1("www.a.com", 80);
[email protected]e6d017652013-05-17 18:01:4014895 SpdySessionKey spdy_session_key_a1(
[email protected]314b03992014-04-01 01:28:5314896 host_port_pair_a1, ProxyServer::Direct(), PRIVACY_MODE_DISABLED);
[email protected]483fa202013-05-14 01:07:0314897 EXPECT_FALSE(
[email protected]41d64e82013-07-03 22:44:2614898 HasSpdySession(session->spdy_session_pool(), spdy_session_key_a1));
[email protected]483fa202013-05-14 01:07:0314899 HttpRequestInfo request3;
14900 request3.method = "GET";
14901 request3.url = GURL("http://www.a.com/");
14902 request3.load_flags = 0;
bnc87dcefc2017-05-25 12:47:5814903 trans =
Jeremy Roman0579ed62017-08-29 15:56:1914904 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]483fa202013-05-14 01:07:0314905
tfarina42834112016-09-22 13:38:2014906 rv = trans->Start(&request3, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0114907 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
14908 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]483fa202013-05-14 01:07:0314909
14910 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5214911 ASSERT_TRUE(response);
14912 ASSERT_TRUE(response->headers);
[email protected]483fa202013-05-14 01:07:0314913 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
14914 EXPECT_FALSE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5214915 EXPECT_FALSE(response->was_alpn_negotiated);
robpercival214763f2016-07-01 23:27:0114916 ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
[email protected]483fa202013-05-14 01:07:0314917 EXPECT_EQ("hello!", response_data);
14918 EXPECT_FALSE(
[email protected]41d64e82013-07-03 22:44:2614919 HasSpdySession(session->spdy_session_pool(), spdy_session_key_a));
[email protected]483fa202013-05-14 01:07:0314920 EXPECT_FALSE(
[email protected]41d64e82013-07-03 22:44:2614921 HasSpdySession(session->spdy_session_pool(), spdy_session_key_b));
[email protected]483fa202013-05-14 01:07:0314922}
14923
bncd16676a2016-07-20 16:23:0114924TEST_F(HttpNetworkTransactionTest, HttpSyncConnectError) {
[email protected]79e1fd62013-06-20 06:50:0414925 HttpRequestInfo request;
14926 request.method = "GET";
bncce36dca22015-04-21 22:11:2314927 request.url = GURL("http://www.example.org/");
[email protected]79e1fd62013-06-20 06:50:0414928
danakj1fd259a02016-04-16 03:17:0914929 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1614930 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]79e1fd62013-06-20 06:50:0414931
ttuttled9dbc652015-09-29 20:00:5914932 MockConnect mock_connect(SYNCHRONOUS, ERR_NAME_NOT_RESOLVED);
[email protected]79e1fd62013-06-20 06:50:0414933 StaticSocketDataProvider data;
14934 data.set_connect_data(mock_connect);
14935 session_deps_.socket_factory->AddSocketDataProvider(&data);
14936
14937 TestCompletionCallback callback;
14938
tfarina42834112016-09-22 13:38:2014939 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0114940 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]79e1fd62013-06-20 06:50:0414941
14942 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0114943 EXPECT_THAT(rv, IsError(ERR_NAME_NOT_RESOLVED));
[email protected]79e1fd62013-06-20 06:50:0414944
[email protected]79e1fd62013-06-20 06:50:0414945 // We don't care whether this succeeds or fails, but it shouldn't crash.
14946 HttpRequestHeaders request_headers;
bnc691fda62016-08-12 00:43:1614947 trans.GetFullRequestHeaders(&request_headers);
ttuttle1f2d7e92015-04-28 16:17:4714948
14949 ConnectionAttempts attempts;
bnc691fda62016-08-12 00:43:1614950 trans.GetConnectionAttempts(&attempts);
ttuttle1f2d7e92015-04-28 16:17:4714951 ASSERT_EQ(1u, attempts.size());
robpercival214763f2016-07-01 23:27:0114952 EXPECT_THAT(attempts[0].result, IsError(ERR_NAME_NOT_RESOLVED));
ttuttled9dbc652015-09-29 20:00:5914953
14954 IPEndPoint endpoint;
bnc691fda62016-08-12 00:43:1614955 EXPECT_FALSE(trans.GetRemoteEndpoint(&endpoint));
ttuttled9dbc652015-09-29 20:00:5914956 EXPECT_TRUE(endpoint.address().empty());
[email protected]79e1fd62013-06-20 06:50:0414957}
14958
bncd16676a2016-07-20 16:23:0114959TEST_F(HttpNetworkTransactionTest, HttpAsyncConnectError) {
[email protected]79e1fd62013-06-20 06:50:0414960 HttpRequestInfo request;
14961 request.method = "GET";
bncce36dca22015-04-21 22:11:2314962 request.url = GURL("http://www.example.org/");
[email protected]79e1fd62013-06-20 06:50:0414963
danakj1fd259a02016-04-16 03:17:0914964 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1614965 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]79e1fd62013-06-20 06:50:0414966
ttuttled9dbc652015-09-29 20:00:5914967 MockConnect mock_connect(ASYNC, ERR_NAME_NOT_RESOLVED);
[email protected]79e1fd62013-06-20 06:50:0414968 StaticSocketDataProvider data;
14969 data.set_connect_data(mock_connect);
14970 session_deps_.socket_factory->AddSocketDataProvider(&data);
14971
14972 TestCompletionCallback callback;
14973
tfarina42834112016-09-22 13:38:2014974 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0114975 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]79e1fd62013-06-20 06:50:0414976
14977 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0114978 EXPECT_THAT(rv, IsError(ERR_NAME_NOT_RESOLVED));
[email protected]79e1fd62013-06-20 06:50:0414979
[email protected]79e1fd62013-06-20 06:50:0414980 // We don't care whether this succeeds or fails, but it shouldn't crash.
14981 HttpRequestHeaders request_headers;
bnc691fda62016-08-12 00:43:1614982 trans.GetFullRequestHeaders(&request_headers);
ttuttle1f2d7e92015-04-28 16:17:4714983
14984 ConnectionAttempts attempts;
bnc691fda62016-08-12 00:43:1614985 trans.GetConnectionAttempts(&attempts);
ttuttle1f2d7e92015-04-28 16:17:4714986 ASSERT_EQ(1u, attempts.size());
robpercival214763f2016-07-01 23:27:0114987 EXPECT_THAT(attempts[0].result, IsError(ERR_NAME_NOT_RESOLVED));
ttuttled9dbc652015-09-29 20:00:5914988
14989 IPEndPoint endpoint;
bnc691fda62016-08-12 00:43:1614990 EXPECT_FALSE(trans.GetRemoteEndpoint(&endpoint));
ttuttled9dbc652015-09-29 20:00:5914991 EXPECT_TRUE(endpoint.address().empty());
[email protected]79e1fd62013-06-20 06:50:0414992}
14993
bncd16676a2016-07-20 16:23:0114994TEST_F(HttpNetworkTransactionTest, HttpSyncWriteError) {
[email protected]79e1fd62013-06-20 06:50:0414995 HttpRequestInfo request;
14996 request.method = "GET";
bncce36dca22015-04-21 22:11:2314997 request.url = GURL("http://www.example.org/");
[email protected]79e1fd62013-06-20 06:50:0414998
danakj1fd259a02016-04-16 03:17:0914999 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1615000 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]79e1fd62013-06-20 06:50:0415001
15002 MockWrite data_writes[] = {
15003 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
15004 };
15005 MockRead data_reads[] = {
15006 MockRead(SYNCHRONOUS, ERR_UNEXPECTED), // Should not be reached.
15007 };
15008
15009 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
15010 data_writes, arraysize(data_writes));
15011 session_deps_.socket_factory->AddSocketDataProvider(&data);
15012
15013 TestCompletionCallback callback;
15014
tfarina42834112016-09-22 13:38:2015015 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0115016 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]79e1fd62013-06-20 06:50:0415017
15018 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0115019 EXPECT_THAT(rv, IsError(ERR_CONNECTION_RESET));
[email protected]79e1fd62013-06-20 06:50:0415020
[email protected]79e1fd62013-06-20 06:50:0415021 HttpRequestHeaders request_headers;
bnc691fda62016-08-12 00:43:1615022 EXPECT_TRUE(trans.GetFullRequestHeaders(&request_headers));
[email protected]79e1fd62013-06-20 06:50:0415023 EXPECT_TRUE(request_headers.HasHeader("Host"));
15024}
15025
bncd16676a2016-07-20 16:23:0115026TEST_F(HttpNetworkTransactionTest, HttpAsyncWriteError) {
[email protected]79e1fd62013-06-20 06:50:0415027 HttpRequestInfo request;
15028 request.method = "GET";
bncce36dca22015-04-21 22:11:2315029 request.url = GURL("http://www.example.org/");
[email protected]79e1fd62013-06-20 06:50:0415030
danakj1fd259a02016-04-16 03:17:0915031 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1615032 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]79e1fd62013-06-20 06:50:0415033
15034 MockWrite data_writes[] = {
15035 MockWrite(ASYNC, ERR_CONNECTION_RESET),
15036 };
15037 MockRead data_reads[] = {
15038 MockRead(SYNCHRONOUS, ERR_UNEXPECTED), // Should not be reached.
15039 };
15040
15041 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
15042 data_writes, arraysize(data_writes));
15043 session_deps_.socket_factory->AddSocketDataProvider(&data);
15044
15045 TestCompletionCallback callback;
15046
tfarina42834112016-09-22 13:38:2015047 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0115048 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]79e1fd62013-06-20 06:50:0415049
15050 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0115051 EXPECT_THAT(rv, IsError(ERR_CONNECTION_RESET));
[email protected]79e1fd62013-06-20 06:50:0415052
[email protected]79e1fd62013-06-20 06:50:0415053 HttpRequestHeaders request_headers;
bnc691fda62016-08-12 00:43:1615054 EXPECT_TRUE(trans.GetFullRequestHeaders(&request_headers));
[email protected]79e1fd62013-06-20 06:50:0415055 EXPECT_TRUE(request_headers.HasHeader("Host"));
15056}
15057
bncd16676a2016-07-20 16:23:0115058TEST_F(HttpNetworkTransactionTest, HttpSyncReadError) {
[email protected]79e1fd62013-06-20 06:50:0415059 HttpRequestInfo request;
15060 request.method = "GET";
bncce36dca22015-04-21 22:11:2315061 request.url = GURL("http://www.example.org/");
[email protected]79e1fd62013-06-20 06:50:0415062
danakj1fd259a02016-04-16 03:17:0915063 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1615064 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]79e1fd62013-06-20 06:50:0415065
15066 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:2315067 MockWrite(
15068 "GET / HTTP/1.1\r\n"
15069 "Host: www.example.org\r\n"
15070 "Connection: keep-alive\r\n\r\n"),
[email protected]79e1fd62013-06-20 06:50:0415071 };
15072 MockRead data_reads[] = {
15073 MockRead(SYNCHRONOUS, ERR_CONNECTION_RESET),
15074 };
15075
15076 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
15077 data_writes, arraysize(data_writes));
15078 session_deps_.socket_factory->AddSocketDataProvider(&data);
15079
15080 TestCompletionCallback callback;
15081
tfarina42834112016-09-22 13:38:2015082 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0115083 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]79e1fd62013-06-20 06:50:0415084
15085 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0115086 EXPECT_THAT(rv, IsError(ERR_CONNECTION_RESET));
[email protected]79e1fd62013-06-20 06:50:0415087
[email protected]79e1fd62013-06-20 06:50:0415088 HttpRequestHeaders request_headers;
bnc691fda62016-08-12 00:43:1615089 EXPECT_TRUE(trans.GetFullRequestHeaders(&request_headers));
[email protected]79e1fd62013-06-20 06:50:0415090 EXPECT_TRUE(request_headers.HasHeader("Host"));
15091}
15092
bncd16676a2016-07-20 16:23:0115093TEST_F(HttpNetworkTransactionTest, HttpAsyncReadError) {
[email protected]79e1fd62013-06-20 06:50:0415094 HttpRequestInfo request;
15095 request.method = "GET";
bncce36dca22015-04-21 22:11:2315096 request.url = GURL("http://www.example.org/");
[email protected]79e1fd62013-06-20 06:50:0415097
danakj1fd259a02016-04-16 03:17:0915098 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1615099 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]79e1fd62013-06-20 06:50:0415100
15101 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:2315102 MockWrite(
15103 "GET / HTTP/1.1\r\n"
15104 "Host: www.example.org\r\n"
15105 "Connection: keep-alive\r\n\r\n"),
[email protected]79e1fd62013-06-20 06:50:0415106 };
15107 MockRead data_reads[] = {
15108 MockRead(ASYNC, ERR_CONNECTION_RESET),
15109 };
15110
15111 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
15112 data_writes, arraysize(data_writes));
15113 session_deps_.socket_factory->AddSocketDataProvider(&data);
15114
15115 TestCompletionCallback callback;
15116
tfarina42834112016-09-22 13:38:2015117 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0115118 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]79e1fd62013-06-20 06:50:0415119
15120 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0115121 EXPECT_THAT(rv, IsError(ERR_CONNECTION_RESET));
[email protected]79e1fd62013-06-20 06:50:0415122
[email protected]79e1fd62013-06-20 06:50:0415123 HttpRequestHeaders request_headers;
bnc691fda62016-08-12 00:43:1615124 EXPECT_TRUE(trans.GetFullRequestHeaders(&request_headers));
[email protected]79e1fd62013-06-20 06:50:0415125 EXPECT_TRUE(request_headers.HasHeader("Host"));
15126}
15127
bncd16676a2016-07-20 16:23:0115128TEST_F(HttpNetworkTransactionTest, GetFullRequestHeadersIncludesExtraHeader) {
[email protected]79e1fd62013-06-20 06:50:0415129 HttpRequestInfo request;
15130 request.method = "GET";
bncce36dca22015-04-21 22:11:2315131 request.url = GURL("http://www.example.org/");
[email protected]79e1fd62013-06-20 06:50:0415132 request.extra_headers.SetHeader("X-Foo", "bar");
15133
danakj1fd259a02016-04-16 03:17:0915134 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1615135 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]79e1fd62013-06-20 06:50:0415136
15137 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:2315138 MockWrite(
15139 "GET / HTTP/1.1\r\n"
15140 "Host: www.example.org\r\n"
15141 "Connection: keep-alive\r\n"
15142 "X-Foo: bar\r\n\r\n"),
[email protected]79e1fd62013-06-20 06:50:0415143 };
15144 MockRead data_reads[] = {
15145 MockRead("HTTP/1.1 200 OK\r\n"
15146 "Content-Length: 5\r\n\r\n"
15147 "hello"),
15148 MockRead(ASYNC, ERR_UNEXPECTED),
15149 };
15150
15151 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
15152 data_writes, arraysize(data_writes));
15153 session_deps_.socket_factory->AddSocketDataProvider(&data);
15154
15155 TestCompletionCallback callback;
15156
tfarina42834112016-09-22 13:38:2015157 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0115158 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]79e1fd62013-06-20 06:50:0415159
15160 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0115161 EXPECT_THAT(rv, IsOk());
[email protected]79e1fd62013-06-20 06:50:0415162
15163 HttpRequestHeaders request_headers;
bnc691fda62016-08-12 00:43:1615164 EXPECT_TRUE(trans.GetFullRequestHeaders(&request_headers));
[email protected]79e1fd62013-06-20 06:50:0415165 std::string foo;
15166 EXPECT_TRUE(request_headers.GetHeader("X-Foo", &foo));
15167 EXPECT_EQ("bar", foo);
15168}
15169
[email protected]bf828982013-08-14 18:01:4715170namespace {
15171
yhiranoa7e05bb2014-11-06 05:40:3915172// Fake HttpStream that simply records calls to SetPriority().
15173class FakeStream : public HttpStream,
[email protected]e86839fd2013-08-14 18:29:0315174 public base::SupportsWeakPtr<FakeStream> {
15175 public:
15176 explicit FakeStream(RequestPriority priority) : priority_(priority) {}
dchengb03027d2014-10-21 12:00:2015177 ~FakeStream() override {}
[email protected]e86839fd2013-08-14 18:29:0315178
15179 RequestPriority priority() const { return priority_; }
15180
dchengb03027d2014-10-21 12:00:2015181 int InitializeStream(const HttpRequestInfo* request_info,
15182 RequestPriority priority,
tfarina42834112016-09-22 13:38:2015183 const NetLogWithSource& net_log,
dchengb03027d2014-10-21 12:00:2015184 const CompletionCallback& callback) override {
[email protected]e86839fd2013-08-14 18:29:0315185 return ERR_IO_PENDING;
15186 }
15187
dchengb03027d2014-10-21 12:00:2015188 int SendRequest(const HttpRequestHeaders& request_headers,
15189 HttpResponseInfo* response,
15190 const CompletionCallback& callback) override {
[email protected]e86839fd2013-08-14 18:29:0315191 ADD_FAILURE();
15192 return ERR_UNEXPECTED;
15193 }
15194
dchengb03027d2014-10-21 12:00:2015195 int ReadResponseHeaders(const CompletionCallback& callback) override {
[email protected]e86839fd2013-08-14 18:29:0315196 ADD_FAILURE();
15197 return ERR_UNEXPECTED;
15198 }
15199
dchengb03027d2014-10-21 12:00:2015200 int ReadResponseBody(IOBuffer* buf,
15201 int buf_len,
15202 const CompletionCallback& callback) override {
[email protected]e86839fd2013-08-14 18:29:0315203 ADD_FAILURE();
15204 return ERR_UNEXPECTED;
15205 }
15206
dchengb03027d2014-10-21 12:00:2015207 void Close(bool not_reusable) override {}
[email protected]e86839fd2013-08-14 18:29:0315208
dchengb03027d2014-10-21 12:00:2015209 bool IsResponseBodyComplete() const override {
[email protected]e86839fd2013-08-14 18:29:0315210 ADD_FAILURE();
15211 return false;
15212 }
15213
dchengb03027d2014-10-21 12:00:2015214 bool IsConnectionReused() const override {
[email protected]e86839fd2013-08-14 18:29:0315215 ADD_FAILURE();
15216 return false;
15217 }
15218
dchengb03027d2014-10-21 12:00:2015219 void SetConnectionReused() override { ADD_FAILURE(); }
[email protected]e86839fd2013-08-14 18:29:0315220
mmenkebd84c392015-09-02 14:12:3415221 bool CanReuseConnection() const override { return false; }
[email protected]e86839fd2013-08-14 18:29:0315222
sclittle4de1bab92015-09-22 21:28:2415223 int64_t GetTotalReceivedBytes() const override {
[email protected]bc92bc972013-12-13 08:32:5915224 ADD_FAILURE();
15225 return 0;
15226 }
15227
sclittlebe1ccf62015-09-02 19:40:3615228 int64_t GetTotalSentBytes() const override {
15229 ADD_FAILURE();
15230 return 0;
15231 }
15232
dchengb03027d2014-10-21 12:00:2015233 bool GetLoadTimingInfo(LoadTimingInfo* load_timing_info) const override {
[email protected]e86839fd2013-08-14 18:29:0315234 ADD_FAILURE();
15235 return false;
15236 }
15237
rchcd379012017-04-12 21:53:3215238 bool GetAlternativeService(
15239 AlternativeService* alternative_service) const override {
15240 ADD_FAILURE();
15241 return false;
15242 }
15243
dchengb03027d2014-10-21 12:00:2015244 void GetSSLInfo(SSLInfo* ssl_info) override { ADD_FAILURE(); }
15245
15246 void GetSSLCertRequestInfo(SSLCertRequestInfo* cert_request_info) override {
[email protected]e86839fd2013-08-14 18:29:0315247 ADD_FAILURE();
15248 }
15249
ttuttled9dbc652015-09-29 20:00:5915250 bool GetRemoteEndpoint(IPEndPoint* endpoint) override { return false; }
15251
nharper78e6d2b2016-09-21 05:42:3515252 Error GetTokenBindingSignature(crypto::ECPrivateKey* key,
15253 TokenBindingType tb_type,
15254 std::vector<uint8_t>* out) override {
nharperb7441ef2016-01-25 23:54:1415255 ADD_FAILURE();
15256 return ERR_NOT_IMPLEMENTED;
15257 }
15258
dchengb03027d2014-10-21 12:00:2015259 void Drain(HttpNetworkSession* session) override { ADD_FAILURE(); }
[email protected]e86839fd2013-08-14 18:29:0315260
zhongyica364fbb2015-12-12 03:39:1215261 void PopulateNetErrorDetails(NetErrorDetails* details) override { return; }
15262
dchengb03027d2014-10-21 12:00:2015263 void SetPriority(RequestPriority priority) override { priority_ = priority; }
[email protected]e86839fd2013-08-14 18:29:0315264
yhiranoa7e05bb2014-11-06 05:40:3915265 HttpStream* RenewStreamForAuth() override { return NULL; }
15266
Andrey Kosyakov83a6eee2017-08-14 19:20:0415267 void SetRequestHeadersCallback(RequestHeadersCallback callback) override {}
15268
[email protected]e86839fd2013-08-14 18:29:0315269 private:
15270 RequestPriority priority_;
15271
15272 DISALLOW_COPY_AND_ASSIGN(FakeStream);
15273};
15274
15275// Fake HttpStreamRequest that simply records calls to SetPriority()
15276// and vends FakeStreams with its current priority.
[email protected]bf828982013-08-14 18:01:4715277class FakeStreamRequest : public HttpStreamRequest,
15278 public base::SupportsWeakPtr<FakeStreamRequest> {
15279 public:
[email protected]e86839fd2013-08-14 18:29:0315280 FakeStreamRequest(RequestPriority priority,
15281 HttpStreamRequest::Delegate* delegate)
15282 : priority_(priority),
[email protected]831e4a32013-11-14 02:14:4415283 delegate_(delegate),
15284 websocket_stream_create_helper_(NULL) {}
15285
15286 FakeStreamRequest(RequestPriority priority,
15287 HttpStreamRequest::Delegate* delegate,
15288 WebSocketHandshakeStreamBase::CreateHelper* create_helper)
15289 : priority_(priority),
15290 delegate_(delegate),
15291 websocket_stream_create_helper_(create_helper) {}
[email protected]e86839fd2013-08-14 18:29:0315292
dchengb03027d2014-10-21 12:00:2015293 ~FakeStreamRequest() override {}
[email protected]bf828982013-08-14 18:01:4715294
15295 RequestPriority priority() const { return priority_; }
15296
[email protected]831e4a32013-11-14 02:14:4415297 const WebSocketHandshakeStreamBase::CreateHelper*
15298 websocket_stream_create_helper() const {
15299 return websocket_stream_create_helper_;
15300 }
15301
[email protected]e86839fd2013-08-14 18:29:0315302 // Create a new FakeStream and pass it to the request's
15303 // delegate. Returns a weak pointer to the FakeStream.
15304 base::WeakPtr<FakeStream> FinishStreamRequest() {
Jeremy Roman0579ed62017-08-29 15:56:1915305 auto fake_stream = std::make_unique<FakeStream>(priority_);
[email protected]e86839fd2013-08-14 18:29:0315306 // Do this before calling OnStreamReady() as OnStreamReady() may
15307 // immediately delete |fake_stream|.
15308 base::WeakPtr<FakeStream> weak_stream = fake_stream->AsWeakPtr();
bnc5029f4632017-06-08 16:19:0015309 delegate_->OnStreamReady(SSLConfig(), ProxyInfo(), std::move(fake_stream));
[email protected]e86839fd2013-08-14 18:29:0315310 return weak_stream;
15311 }
15312
asanka681f02d2017-02-22 17:06:3915313 int RestartTunnelWithProxyAuth() override {
[email protected]bf828982013-08-14 18:01:4715314 ADD_FAILURE();
15315 return ERR_UNEXPECTED;
15316 }
15317
dchengb03027d2014-10-21 12:00:2015318 LoadState GetLoadState() const override {
[email protected]bf828982013-08-14 18:01:4715319 ADD_FAILURE();
15320 return LoadState();
15321 }
15322
dchengb03027d2014-10-21 12:00:2015323 void SetPriority(RequestPriority priority) override { priority_ = priority; }
[email protected]bf828982013-08-14 18:01:4715324
bnc94c92842016-09-21 15:22:5215325 bool was_alpn_negotiated() const override { return false; }
[email protected]bf828982013-08-14 18:01:4715326
bnc6227b26e2016-08-12 02:00:4315327 NextProto negotiated_protocol() const override { return kProtoUnknown; }
[email protected]bf828982013-08-14 18:01:4715328
dchengb03027d2014-10-21 12:00:2015329 bool using_spdy() const override { return false; }
[email protected]bf828982013-08-14 18:01:4715330
ttuttle1f2d7e92015-04-28 16:17:4715331 const ConnectionAttempts& connection_attempts() const override {
15332 static ConnectionAttempts no_attempts;
15333 return no_attempts;
15334 }
15335
[email protected]bf828982013-08-14 18:01:4715336 private:
15337 RequestPriority priority_;
[email protected]e86839fd2013-08-14 18:29:0315338 HttpStreamRequest::Delegate* const delegate_;
[email protected]831e4a32013-11-14 02:14:4415339 WebSocketHandshakeStreamBase::CreateHelper* websocket_stream_create_helper_;
[email protected]bf828982013-08-14 18:01:4715340
15341 DISALLOW_COPY_AND_ASSIGN(FakeStreamRequest);
15342};
15343
15344// Fake HttpStreamFactory that vends FakeStreamRequests.
15345class FakeStreamFactory : public HttpStreamFactory {
15346 public:
15347 FakeStreamFactory() {}
dchengb03027d2014-10-21 12:00:2015348 ~FakeStreamFactory() override {}
[email protected]bf828982013-08-14 18:01:4715349
15350 // Returns a WeakPtr<> to the last HttpStreamRequest returned by
15351 // RequestStream() (which may be NULL if it was destroyed already).
15352 base::WeakPtr<FakeStreamRequest> last_stream_request() {
15353 return last_stream_request_;
15354 }
15355
xunjieli96f2a402017-06-05 17:24:2715356 std::unique_ptr<HttpStreamRequest> RequestStream(
15357 const HttpRequestInfo& info,
15358 RequestPriority priority,
15359 const SSLConfig& server_ssl_config,
15360 const SSLConfig& proxy_ssl_config,
15361 HttpStreamRequest::Delegate* delegate,
15362 bool enable_ip_based_pooling,
15363 bool enable_alternative_services,
15364 const NetLogWithSource& net_log) override {
Jeremy Roman0579ed62017-08-29 15:56:1915365 auto fake_request = std::make_unique<FakeStreamRequest>(priority, delegate);
[email protected]bf828982013-08-14 18:01:4715366 last_stream_request_ = fake_request->AsWeakPtr();
xunjieli96f2a402017-06-05 17:24:2715367 return std::move(fake_request);
[email protected]bf828982013-08-14 18:01:4715368 }
15369
xunjieli96f2a402017-06-05 17:24:2715370 std::unique_ptr<HttpStreamRequest> RequestBidirectionalStreamImpl(
xunjieli11834f02015-12-22 04:27:0815371 const HttpRequestInfo& info,
15372 RequestPriority priority,
15373 const SSLConfig& server_ssl_config,
15374 const SSLConfig& proxy_ssl_config,
15375 HttpStreamRequest::Delegate* delegate,
bnc8016c1f2017-03-31 02:11:2915376 bool enable_ip_based_pooling,
bncaccd4962017-04-06 21:00:2615377 bool enable_alternative_services,
tfarina42834112016-09-22 13:38:2015378 const NetLogWithSource& net_log) override {
xunjieli11834f02015-12-22 04:27:0815379 NOTREACHED();
15380 return nullptr;
15381 }
15382
xunjieli96f2a402017-06-05 17:24:2715383 std::unique_ptr<HttpStreamRequest> RequestWebSocketHandshakeStream(
[email protected]bf828982013-08-14 18:01:4715384 const HttpRequestInfo& info,
15385 RequestPriority priority,
15386 const SSLConfig& server_ssl_config,
15387 const SSLConfig& proxy_ssl_config,
15388 HttpStreamRequest::Delegate* delegate,
[email protected]467086b2013-11-12 08:19:4615389 WebSocketHandshakeStreamBase::CreateHelper* create_helper,
bnc8016c1f2017-03-31 02:11:2915390 bool enable_ip_based_pooling,
bncaccd4962017-04-06 21:00:2615391 bool enable_alternative_services,
tfarina42834112016-09-22 13:38:2015392 const NetLogWithSource& net_log) override {
xunjieli96f2a402017-06-05 17:24:2715393 auto fake_request =
Jeremy Roman0579ed62017-08-29 15:56:1915394 std::make_unique<FakeStreamRequest>(priority, delegate, create_helper);
[email protected]831e4a32013-11-14 02:14:4415395 last_stream_request_ = fake_request->AsWeakPtr();
xunjieli96f2a402017-06-05 17:24:2715396 return std::move(fake_request);
[email protected]bf828982013-08-14 18:01:4715397 }
15398
dchengb03027d2014-10-21 12:00:2015399 void PreconnectStreams(int num_streams,
nharper8cdb0fb2016-04-22 21:34:5915400 const HttpRequestInfo& info) override {
[email protected]bf828982013-08-14 18:01:4715401 ADD_FAILURE();
15402 }
15403
dchengb03027d2014-10-21 12:00:2015404 const HostMappingRules* GetHostMappingRules() const override {
[email protected]bf828982013-08-14 18:01:4715405 ADD_FAILURE();
15406 return NULL;
15407 }
15408
xunjielif5267de2017-01-20 21:18:5715409 void DumpMemoryStats(base::trace_event::ProcessMemoryDump* pmd,
15410 const std::string& parent_absolute_name) const override {
15411 ADD_FAILURE();
15412 }
15413
[email protected]bf828982013-08-14 18:01:4715414 private:
15415 base::WeakPtr<FakeStreamRequest> last_stream_request_;
15416
15417 DISALLOW_COPY_AND_ASSIGN(FakeStreamFactory);
15418};
15419
Adam Rice425cf122015-01-19 06:18:2415420// TODO(ricea): Maybe unify this with the one in
15421// url_request_http_job_unittest.cc ?
15422class FakeWebSocketBasicHandshakeStream : public WebSocketHandshakeStreamBase {
15423 public:
danakj1fd259a02016-04-16 03:17:0915424 FakeWebSocketBasicHandshakeStream(
15425 std::unique_ptr<ClientSocketHandle> connection,
15426 bool using_proxy)
mmenkea7da6da2016-09-01 21:56:5215427 : state_(std::move(connection), using_proxy, false) {}
Adam Rice425cf122015-01-19 06:18:2415428
15429 // Fake implementation of HttpStreamBase methods.
15430 // This ends up being quite "real" because this object has to really send data
15431 // on the mock socket. It might be easier to use the real implementation, but
15432 // the fact that the WebSocket code is not compiled on iOS makes that
15433 // difficult.
15434 int InitializeStream(const HttpRequestInfo* request_info,
15435 RequestPriority priority,
tfarina42834112016-09-22 13:38:2015436 const NetLogWithSource& net_log,
Adam Rice425cf122015-01-19 06:18:2415437 const CompletionCallback& callback) override {
15438 state_.Initialize(request_info, priority, net_log, callback);
15439 return OK;
15440 }
15441
15442 int SendRequest(const HttpRequestHeaders& request_headers,
15443 HttpResponseInfo* response,
15444 const CompletionCallback& callback) override {
15445 return parser()->SendRequest(state_.GenerateRequestLine(), request_headers,
15446 response, callback);
15447 }
15448
15449 int ReadResponseHeaders(const CompletionCallback& callback) override {
15450 return parser()->ReadResponseHeaders(callback);
15451 }
15452
15453 int ReadResponseBody(IOBuffer* buf,
15454 int buf_len,
15455 const CompletionCallback& callback) override {
15456 NOTREACHED();
15457 return ERR_IO_PENDING;
15458 }
15459
15460 void Close(bool not_reusable) override {
15461 if (parser())
15462 parser()->Close(true);
15463 }
15464
15465 bool IsResponseBodyComplete() const override {
15466 NOTREACHED();
15467 return false;
15468 }
15469
Adam Rice425cf122015-01-19 06:18:2415470 bool IsConnectionReused() const override {
15471 NOTREACHED();
15472 return false;
15473 }
15474 void SetConnectionReused() override { NOTREACHED(); }
15475
mmenkebd84c392015-09-02 14:12:3415476 bool CanReuseConnection() const override { return false; }
Adam Rice425cf122015-01-19 06:18:2415477
sclittle4de1bab92015-09-22 21:28:2415478 int64_t GetTotalReceivedBytes() const override {
Adam Rice425cf122015-01-19 06:18:2415479 NOTREACHED();
15480 return 0;
15481 }
15482
sclittlebe1ccf62015-09-02 19:40:3615483 int64_t GetTotalSentBytes() const override {
15484 NOTREACHED();
15485 return 0;
15486 }
15487
Adam Rice425cf122015-01-19 06:18:2415488 bool GetLoadTimingInfo(LoadTimingInfo* load_timing_info) const override {
15489 NOTREACHED();
15490 return false;
15491 }
15492
rchcd379012017-04-12 21:53:3215493 bool GetAlternativeService(
15494 AlternativeService* alternative_service) const override {
15495 ADD_FAILURE();
15496 return false;
15497 }
15498
Adam Ricecb76ac62015-02-20 05:33:2515499 void GetSSLInfo(SSLInfo* ssl_info) override {}
Adam Rice425cf122015-01-19 06:18:2415500
15501 void GetSSLCertRequestInfo(SSLCertRequestInfo* cert_request_info) override {
15502 NOTREACHED();
15503 }
15504
ttuttled9dbc652015-09-29 20:00:5915505 bool GetRemoteEndpoint(IPEndPoint* endpoint) override { return false; }
15506
nharper78e6d2b2016-09-21 05:42:3515507 Error GetTokenBindingSignature(crypto::ECPrivateKey* key,
15508 TokenBindingType tb_type,
15509 std::vector<uint8_t>* out) override {
nharperb7441ef2016-01-25 23:54:1415510 ADD_FAILURE();
15511 return ERR_NOT_IMPLEMENTED;
15512 }
15513
Adam Rice425cf122015-01-19 06:18:2415514 void Drain(HttpNetworkSession* session) override { NOTREACHED(); }
15515
zhongyica364fbb2015-12-12 03:39:1215516 void PopulateNetErrorDetails(NetErrorDetails* details) override { return; }
15517
Adam Rice425cf122015-01-19 06:18:2415518 void SetPriority(RequestPriority priority) override { NOTREACHED(); }
15519
Adam Rice425cf122015-01-19 06:18:2415520 HttpStream* RenewStreamForAuth() override {
15521 NOTREACHED();
15522 return nullptr;
15523 }
15524
15525 // Fake implementation of WebSocketHandshakeStreamBase method(s)
danakj1fd259a02016-04-16 03:17:0915526 std::unique_ptr<WebSocketStream> Upgrade() override {
Adam Rice425cf122015-01-19 06:18:2415527 NOTREACHED();
danakj1fd259a02016-04-16 03:17:0915528 return std::unique_ptr<WebSocketStream>();
Adam Rice425cf122015-01-19 06:18:2415529 }
15530
15531 private:
15532 HttpStreamParser* parser() const { return state_.parser(); }
15533 HttpBasicState state_;
15534
15535 DISALLOW_COPY_AND_ASSIGN(FakeWebSocketBasicHandshakeStream);
15536};
15537
[email protected]831e4a32013-11-14 02:14:4415538// TODO(yhirano): Split this class out into a net/websockets file, if it is
15539// worth doing.
15540class FakeWebSocketStreamCreateHelper :
15541 public WebSocketHandshakeStreamBase::CreateHelper {
15542 public:
bnc615cf2f2017-05-19 18:53:2615543 std::unique_ptr<WebSocketHandshakeStreamBase> CreateBasicStream(
danakj1fd259a02016-04-16 03:17:0915544 std::unique_ptr<ClientSocketHandle> connection,
mostynbba063d6032014-10-09 11:01:1315545 bool using_proxy) override {
Jeremy Roman0579ed62017-08-29 15:56:1915546 return std::make_unique<FakeWebSocketBasicHandshakeStream>(
bnc615cf2f2017-05-19 18:53:2615547 std::move(connection), using_proxy);
[email protected]831e4a32013-11-14 02:14:4415548 }
15549
dchengb03027d2014-10-21 12:00:2015550 ~FakeWebSocketStreamCreateHelper() override {}
[email protected]831e4a32013-11-14 02:14:4415551
danakj1fd259a02016-04-16 03:17:0915552 virtual std::unique_ptr<WebSocketStream> Upgrade() {
[email protected]831e4a32013-11-14 02:14:4415553 NOTREACHED();
danakj1fd259a02016-04-16 03:17:0915554 return std::unique_ptr<WebSocketStream>();
[email protected]831e4a32013-11-14 02:14:4415555 }
15556};
15557
[email protected]bf828982013-08-14 18:01:4715558} // namespace
15559
15560// Make sure that HttpNetworkTransaction passes on its priority to its
15561// stream request on start.
bncd16676a2016-07-20 16:23:0115562TEST_F(HttpNetworkTransactionTest, SetStreamRequestPriorityOnStart) {
danakj1fd259a02016-04-16 03:17:0915563 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
mmenkee65e7af2015-10-13 17:16:4215564 HttpNetworkSessionPeer peer(session.get());
[email protected]bf828982013-08-14 18:01:4715565 FakeStreamFactory* fake_factory = new FakeStreamFactory();
danakj1fd259a02016-04-16 03:17:0915566 peer.SetHttpStreamFactory(std::unique_ptr<HttpStreamFactory>(fake_factory));
[email protected]bf828982013-08-14 18:01:4715567
krasinc06a72a2016-12-21 03:42:4615568 HttpRequestInfo request;
dcheng48459ac22014-08-26 00:46:4115569 HttpNetworkTransaction trans(LOW, session.get());
[email protected]bf828982013-08-14 18:01:4715570
wezca1070932016-05-26 20:30:5215571 ASSERT_FALSE(fake_factory->last_stream_request());
[email protected]bf828982013-08-14 18:01:4715572
[email protected]bf828982013-08-14 18:01:4715573 TestCompletionCallback callback;
15574 EXPECT_EQ(ERR_IO_PENDING,
tfarina42834112016-09-22 13:38:2015575 trans.Start(&request, callback.callback(), NetLogWithSource()));
[email protected]bf828982013-08-14 18:01:4715576
15577 base::WeakPtr<FakeStreamRequest> fake_request =
15578 fake_factory->last_stream_request();
wezca1070932016-05-26 20:30:5215579 ASSERT_TRUE(fake_request);
[email protected]bf828982013-08-14 18:01:4715580 EXPECT_EQ(LOW, fake_request->priority());
15581}
15582
15583// Make sure that HttpNetworkTransaction passes on its priority
15584// updates to its stream request.
bncd16676a2016-07-20 16:23:0115585TEST_F(HttpNetworkTransactionTest, SetStreamRequestPriority) {
danakj1fd259a02016-04-16 03:17:0915586 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
mmenkee65e7af2015-10-13 17:16:4215587 HttpNetworkSessionPeer peer(session.get());
[email protected]bf828982013-08-14 18:01:4715588 FakeStreamFactory* fake_factory = new FakeStreamFactory();
danakj1fd259a02016-04-16 03:17:0915589 peer.SetHttpStreamFactory(std::unique_ptr<HttpStreamFactory>(fake_factory));
[email protected]bf828982013-08-14 18:01:4715590
krasinc06a72a2016-12-21 03:42:4615591 HttpRequestInfo request;
dcheng48459ac22014-08-26 00:46:4115592 HttpNetworkTransaction trans(LOW, session.get());
[email protected]bf828982013-08-14 18:01:4715593
[email protected]bf828982013-08-14 18:01:4715594 TestCompletionCallback callback;
15595 EXPECT_EQ(ERR_IO_PENDING,
tfarina42834112016-09-22 13:38:2015596 trans.Start(&request, callback.callback(), NetLogWithSource()));
[email protected]bf828982013-08-14 18:01:4715597
15598 base::WeakPtr<FakeStreamRequest> fake_request =
15599 fake_factory->last_stream_request();
wezca1070932016-05-26 20:30:5215600 ASSERT_TRUE(fake_request);
[email protected]bf828982013-08-14 18:01:4715601 EXPECT_EQ(LOW, fake_request->priority());
15602
15603 trans.SetPriority(LOWEST);
wezca1070932016-05-26 20:30:5215604 ASSERT_TRUE(fake_request);
[email protected]bf828982013-08-14 18:01:4715605 EXPECT_EQ(LOWEST, fake_request->priority());
15606}
15607
[email protected]e86839fd2013-08-14 18:29:0315608// Make sure that HttpNetworkTransaction passes on its priority
15609// updates to its stream.
bncd16676a2016-07-20 16:23:0115610TEST_F(HttpNetworkTransactionTest, SetStreamPriority) {
danakj1fd259a02016-04-16 03:17:0915611 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
mmenkee65e7af2015-10-13 17:16:4215612 HttpNetworkSessionPeer peer(session.get());
[email protected]e86839fd2013-08-14 18:29:0315613 FakeStreamFactory* fake_factory = new FakeStreamFactory();
danakj1fd259a02016-04-16 03:17:0915614 peer.SetHttpStreamFactory(std::unique_ptr<HttpStreamFactory>(fake_factory));
[email protected]e86839fd2013-08-14 18:29:0315615
krasinc06a72a2016-12-21 03:42:4615616 HttpRequestInfo request;
dcheng48459ac22014-08-26 00:46:4115617 HttpNetworkTransaction trans(LOW, session.get());
[email protected]e86839fd2013-08-14 18:29:0315618
[email protected]e86839fd2013-08-14 18:29:0315619 TestCompletionCallback callback;
15620 EXPECT_EQ(ERR_IO_PENDING,
tfarina42834112016-09-22 13:38:2015621 trans.Start(&request, callback.callback(), NetLogWithSource()));
[email protected]e86839fd2013-08-14 18:29:0315622
15623 base::WeakPtr<FakeStreamRequest> fake_request =
15624 fake_factory->last_stream_request();
wezca1070932016-05-26 20:30:5215625 ASSERT_TRUE(fake_request);
[email protected]e86839fd2013-08-14 18:29:0315626 base::WeakPtr<FakeStream> fake_stream = fake_request->FinishStreamRequest();
wezca1070932016-05-26 20:30:5215627 ASSERT_TRUE(fake_stream);
[email protected]e86839fd2013-08-14 18:29:0315628 EXPECT_EQ(LOW, fake_stream->priority());
15629
15630 trans.SetPriority(LOWEST);
15631 EXPECT_EQ(LOWEST, fake_stream->priority());
15632}
15633
bncd16676a2016-07-20 16:23:0115634TEST_F(HttpNetworkTransactionTest, CreateWebSocketHandshakeStream) {
[email protected]831e4a32013-11-14 02:14:4415635 // The same logic needs to be tested for both ws: and wss: schemes, but this
15636 // test is already parameterised on NextProto, so it uses a loop to verify
15637 // that the different schemes work.
bncce36dca22015-04-21 22:11:2315638 std::string test_cases[] = {"ws://www.example.org/",
15639 "wss://www.example.org/"};
[email protected]831e4a32013-11-14 02:14:4415640 for (size_t i = 0; i < arraysize(test_cases); ++i) {
danakj1fd259a02016-04-16 03:17:0915641 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
mmenkee65e7af2015-10-13 17:16:4215642 HttpNetworkSessionPeer peer(session.get());
[email protected]831e4a32013-11-14 02:14:4415643 FakeStreamFactory* fake_factory = new FakeStreamFactory();
15644 FakeWebSocketStreamCreateHelper websocket_stream_create_helper;
[email protected]0191b51c2013-11-18 10:55:2315645 peer.SetHttpStreamFactoryForWebSocket(
danakj1fd259a02016-04-16 03:17:0915646 std::unique_ptr<HttpStreamFactory>(fake_factory));
[email protected]831e4a32013-11-14 02:14:4415647
krasinc06a72a2016-12-21 03:42:4615648 HttpRequestInfo request;
dcheng48459ac22014-08-26 00:46:4115649 HttpNetworkTransaction trans(LOW, session.get());
[email protected]831e4a32013-11-14 02:14:4415650 trans.SetWebSocketHandshakeStreamCreateHelper(
15651 &websocket_stream_create_helper);
15652
[email protected]831e4a32013-11-14 02:14:4415653 TestCompletionCallback callback;
15654 request.method = "GET";
15655 request.url = GURL(test_cases[i]);
15656
15657 EXPECT_EQ(ERR_IO_PENDING,
tfarina42834112016-09-22 13:38:2015658 trans.Start(&request, callback.callback(), NetLogWithSource()));
[email protected]831e4a32013-11-14 02:14:4415659
15660 base::WeakPtr<FakeStreamRequest> fake_request =
15661 fake_factory->last_stream_request();
wezca1070932016-05-26 20:30:5215662 ASSERT_TRUE(fake_request);
[email protected]831e4a32013-11-14 02:14:4415663 EXPECT_EQ(&websocket_stream_create_helper,
15664 fake_request->websocket_stream_create_helper());
15665 }
15666}
15667
[email protected]043b68c82013-08-22 23:41:5215668// Tests that when a used socket is returned to the SSL socket pool, it's closed
15669// if the transport socket pool is stalled on the global socket limit.
bncd16676a2016-07-20 16:23:0115670TEST_F(HttpNetworkTransactionTest, CloseSSLSocketOnIdleForHttpRequest) {
[email protected]043b68c82013-08-22 23:41:5215671 ClientSocketPoolManager::set_max_sockets_per_group(
15672 HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
15673 ClientSocketPoolManager::set_max_sockets_per_pool(
15674 HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
15675
15676 // Set up SSL request.
15677
15678 HttpRequestInfo ssl_request;
15679 ssl_request.method = "GET";
bncce36dca22015-04-21 22:11:2315680 ssl_request.url = GURL("https://www.example.org/");
[email protected]043b68c82013-08-22 23:41:5215681
15682 MockWrite ssl_writes[] = {
bncce36dca22015-04-21 22:11:2315683 MockWrite(
15684 "GET / HTTP/1.1\r\n"
15685 "Host: www.example.org\r\n"
15686 "Connection: keep-alive\r\n\r\n"),
[email protected]043b68c82013-08-22 23:41:5215687 };
15688 MockRead ssl_reads[] = {
15689 MockRead("HTTP/1.1 200 OK\r\n"),
15690 MockRead("Content-Length: 11\r\n\r\n"),
15691 MockRead("hello world"),
15692 MockRead(SYNCHRONOUS, OK),
15693 };
15694 StaticSocketDataProvider ssl_data(ssl_reads, arraysize(ssl_reads),
15695 ssl_writes, arraysize(ssl_writes));
15696 session_deps_.socket_factory->AddSocketDataProvider(&ssl_data);
15697
15698 SSLSocketDataProvider ssl(ASYNC, OK);
15699 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
15700
15701 // Set up HTTP request.
15702
15703 HttpRequestInfo http_request;
15704 http_request.method = "GET";
bncce36dca22015-04-21 22:11:2315705 http_request.url = GURL("http://www.example.org/");
[email protected]043b68c82013-08-22 23:41:5215706
15707 MockWrite http_writes[] = {
bncce36dca22015-04-21 22:11:2315708 MockWrite(
15709 "GET / HTTP/1.1\r\n"
15710 "Host: www.example.org\r\n"
15711 "Connection: keep-alive\r\n\r\n"),
[email protected]043b68c82013-08-22 23:41:5215712 };
15713 MockRead http_reads[] = {
15714 MockRead("HTTP/1.1 200 OK\r\n"),
15715 MockRead("Content-Length: 7\r\n\r\n"),
15716 MockRead("falafel"),
15717 MockRead(SYNCHRONOUS, OK),
15718 };
15719 StaticSocketDataProvider http_data(http_reads, arraysize(http_reads),
15720 http_writes, arraysize(http_writes));
15721 session_deps_.socket_factory->AddSocketDataProvider(&http_data);
15722
danakj1fd259a02016-04-16 03:17:0915723 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]043b68c82013-08-22 23:41:5215724
15725 // Start the SSL request.
15726 TestCompletionCallback ssl_callback;
bnc691fda62016-08-12 00:43:1615727 HttpNetworkTransaction ssl_trans(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:2015728 ASSERT_EQ(ERR_IO_PENDING,
15729 ssl_trans.Start(&ssl_request, ssl_callback.callback(),
15730 NetLogWithSource()));
[email protected]043b68c82013-08-22 23:41:5215731
15732 // Start the HTTP request. Pool should stall.
15733 TestCompletionCallback http_callback;
bnc691fda62016-08-12 00:43:1615734 HttpNetworkTransaction http_trans(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:2015735 ASSERT_EQ(ERR_IO_PENDING,
15736 http_trans.Start(&http_request, http_callback.callback(),
15737 NetLogWithSource()));
dcheng48459ac22014-08-26 00:46:4115738 EXPECT_TRUE(IsTransportSocketPoolStalled(session.get()));
[email protected]043b68c82013-08-22 23:41:5215739
15740 // Wait for response from SSL request.
robpercival214763f2016-07-01 23:27:0115741 ASSERT_THAT(ssl_callback.WaitForResult(), IsOk());
[email protected]043b68c82013-08-22 23:41:5215742 std::string response_data;
bnc691fda62016-08-12 00:43:1615743 ASSERT_THAT(ReadTransaction(&ssl_trans, &response_data), IsOk());
[email protected]043b68c82013-08-22 23:41:5215744 EXPECT_EQ("hello world", response_data);
15745
15746 // The SSL socket should automatically be closed, so the HTTP request can
15747 // start.
dcheng48459ac22014-08-26 00:46:4115748 EXPECT_EQ(0, GetIdleSocketCountInSSLSocketPool(session.get()));
15749 ASSERT_FALSE(IsTransportSocketPoolStalled(session.get()));
[email protected]043b68c82013-08-22 23:41:5215750
15751 // The HTTP request can now complete.
robpercival214763f2016-07-01 23:27:0115752 ASSERT_THAT(http_callback.WaitForResult(), IsOk());
bnc691fda62016-08-12 00:43:1615753 ASSERT_THAT(ReadTransaction(&http_trans, &response_data), IsOk());
[email protected]043b68c82013-08-22 23:41:5215754 EXPECT_EQ("falafel", response_data);
15755
dcheng48459ac22014-08-26 00:46:4115756 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]043b68c82013-08-22 23:41:5215757}
15758
15759// Tests that when a SSL connection is established but there's no corresponding
15760// request that needs it, the new socket is closed if the transport socket pool
15761// is stalled on the global socket limit.
bncd16676a2016-07-20 16:23:0115762TEST_F(HttpNetworkTransactionTest, CloseSSLSocketOnIdleForHttpRequest2) {
[email protected]043b68c82013-08-22 23:41:5215763 ClientSocketPoolManager::set_max_sockets_per_group(
15764 HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
15765 ClientSocketPoolManager::set_max_sockets_per_pool(
15766 HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
15767
15768 // Set up an ssl request.
15769
15770 HttpRequestInfo ssl_request;
15771 ssl_request.method = "GET";
15772 ssl_request.url = GURL("https://www.foopy.com/");
15773
15774 // No data will be sent on the SSL socket.
15775 StaticSocketDataProvider ssl_data;
15776 session_deps_.socket_factory->AddSocketDataProvider(&ssl_data);
15777
15778 SSLSocketDataProvider ssl(ASYNC, OK);
15779 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
15780
15781 // Set up HTTP request.
15782
15783 HttpRequestInfo http_request;
15784 http_request.method = "GET";
bncce36dca22015-04-21 22:11:2315785 http_request.url = GURL("http://www.example.org/");
[email protected]043b68c82013-08-22 23:41:5215786
15787 MockWrite http_writes[] = {
bncce36dca22015-04-21 22:11:2315788 MockWrite(
15789 "GET / HTTP/1.1\r\n"
15790 "Host: www.example.org\r\n"
15791 "Connection: keep-alive\r\n\r\n"),
[email protected]043b68c82013-08-22 23:41:5215792 };
15793 MockRead http_reads[] = {
15794 MockRead("HTTP/1.1 200 OK\r\n"),
15795 MockRead("Content-Length: 7\r\n\r\n"),
15796 MockRead("falafel"),
15797 MockRead(SYNCHRONOUS, OK),
15798 };
15799 StaticSocketDataProvider http_data(http_reads, arraysize(http_reads),
15800 http_writes, arraysize(http_writes));
15801 session_deps_.socket_factory->AddSocketDataProvider(&http_data);
15802
danakj1fd259a02016-04-16 03:17:0915803 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]043b68c82013-08-22 23:41:5215804
15805 // Preconnect an SSL socket. A preconnect is needed because connect jobs are
15806 // cancelled when a normal transaction is cancelled.
ttuttle859dc7a2015-04-23 19:42:2915807 HttpStreamFactory* http_stream_factory = session->http_stream_factory();
nharper8cdb0fb2016-04-22 21:34:5915808 http_stream_factory->PreconnectStreams(1, ssl_request);
dcheng48459ac22014-08-26 00:46:4115809 EXPECT_EQ(0, GetIdleSocketCountInSSLSocketPool(session.get()));
[email protected]043b68c82013-08-22 23:41:5215810
15811 // Start the HTTP request. Pool should stall.
15812 TestCompletionCallback http_callback;
bnc691fda62016-08-12 00:43:1615813 HttpNetworkTransaction http_trans(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:2015814 ASSERT_EQ(ERR_IO_PENDING,
15815 http_trans.Start(&http_request, http_callback.callback(),
15816 NetLogWithSource()));
dcheng48459ac22014-08-26 00:46:4115817 EXPECT_TRUE(IsTransportSocketPoolStalled(session.get()));
[email protected]043b68c82013-08-22 23:41:5215818
15819 // The SSL connection will automatically be closed once the connection is
15820 // established, to let the HTTP request start.
robpercival214763f2016-07-01 23:27:0115821 ASSERT_THAT(http_callback.WaitForResult(), IsOk());
[email protected]043b68c82013-08-22 23:41:5215822 std::string response_data;
bnc691fda62016-08-12 00:43:1615823 ASSERT_THAT(ReadTransaction(&http_trans, &response_data), IsOk());
[email protected]043b68c82013-08-22 23:41:5215824 EXPECT_EQ("falafel", response_data);
15825
dcheng48459ac22014-08-26 00:46:4115826 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]043b68c82013-08-22 23:41:5215827}
15828
bncd16676a2016-07-20 16:23:0115829TEST_F(HttpNetworkTransactionTest, PostReadsErrorResponseAfterReset) {
danakj1fd259a02016-04-16 03:17:0915830 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:2215831 element_readers.push_back(
Jeremy Roman0579ed62017-08-29 15:56:1915832 std::make_unique<UploadBytesElementReader>("foo", 3));
olli.raula6df48b2a2015-11-26 07:40:2215833 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]02d74a02014-04-23 18:10:5415834
15835 HttpRequestInfo request;
15836 request.method = "POST";
15837 request.url = GURL("http://www.foo.com/");
15838 request.upload_data_stream = &upload_data_stream;
[email protected]02d74a02014-04-23 18:10:5415839
danakj1fd259a02016-04-16 03:17:0915840 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1615841 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]02d74a02014-04-23 18:10:5415842 // Send headers successfully, but get an error while sending the body.
15843 MockWrite data_writes[] = {
15844 MockWrite("POST / HTTP/1.1\r\n"
15845 "Host: www.foo.com\r\n"
15846 "Connection: keep-alive\r\n"
15847 "Content-Length: 3\r\n\r\n"),
15848 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
15849 };
15850
15851 MockRead data_reads[] = {
15852 MockRead("HTTP/1.0 400 Not OK\r\n\r\n"),
15853 MockRead("hello world"),
15854 MockRead(SYNCHRONOUS, OK),
15855 };
15856 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
15857 arraysize(data_writes));
15858 session_deps_.socket_factory->AddSocketDataProvider(&data);
15859
15860 TestCompletionCallback callback;
15861
tfarina42834112016-09-22 13:38:2015862 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0115863 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]02d74a02014-04-23 18:10:5415864
15865 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0115866 EXPECT_THAT(rv, IsOk());
[email protected]02d74a02014-04-23 18:10:5415867
bnc691fda62016-08-12 00:43:1615868 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5215869 ASSERT_TRUE(response);
[email protected]02d74a02014-04-23 18:10:5415870
wezca1070932016-05-26 20:30:5215871 EXPECT_TRUE(response->headers);
[email protected]02d74a02014-04-23 18:10:5415872 EXPECT_EQ("HTTP/1.0 400 Not OK", response->headers->GetStatusLine());
15873
15874 std::string response_data;
bnc691fda62016-08-12 00:43:1615875 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:0115876 EXPECT_THAT(rv, IsOk());
[email protected]02d74a02014-04-23 18:10:5415877 EXPECT_EQ("hello world", response_data);
15878}
15879
15880// This test makes sure the retry logic doesn't trigger when reading an error
15881// response from a server that rejected a POST with a CONNECTION_RESET.
bncd16676a2016-07-20 16:23:0115882TEST_F(HttpNetworkTransactionTest,
[email protected]02d74a02014-04-23 18:10:5415883 PostReadsErrorResponseAfterResetOnReusedSocket) {
danakj1fd259a02016-04-16 03:17:0915884 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]02d74a02014-04-23 18:10:5415885 MockWrite data_writes[] = {
15886 MockWrite("GET / HTTP/1.1\r\n"
15887 "Host: www.foo.com\r\n"
15888 "Connection: keep-alive\r\n\r\n"),
15889 MockWrite("POST / HTTP/1.1\r\n"
15890 "Host: www.foo.com\r\n"
15891 "Connection: keep-alive\r\n"
15892 "Content-Length: 3\r\n\r\n"),
15893 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
15894 };
15895
15896 MockRead data_reads[] = {
15897 MockRead("HTTP/1.1 200 Peachy\r\n"
15898 "Content-Length: 14\r\n\r\n"),
15899 MockRead("first response"),
15900 MockRead("HTTP/1.1 400 Not OK\r\n"
15901 "Content-Length: 15\r\n\r\n"),
15902 MockRead("second response"),
15903 MockRead(SYNCHRONOUS, OK),
15904 };
15905 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
15906 arraysize(data_writes));
15907 session_deps_.socket_factory->AddSocketDataProvider(&data);
15908
15909 TestCompletionCallback callback;
15910 HttpRequestInfo request1;
15911 request1.method = "GET";
15912 request1.url = GURL("http://www.foo.com/");
15913 request1.load_flags = 0;
15914
bnc87dcefc2017-05-25 12:47:5815915 auto trans1 =
Jeremy Roman0579ed62017-08-29 15:56:1915916 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:2015917 int rv = trans1->Start(&request1, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0115918 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]02d74a02014-04-23 18:10:5415919
15920 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0115921 EXPECT_THAT(rv, IsOk());
[email protected]02d74a02014-04-23 18:10:5415922
15923 const HttpResponseInfo* response1 = trans1->GetResponseInfo();
wezca1070932016-05-26 20:30:5215924 ASSERT_TRUE(response1);
[email protected]02d74a02014-04-23 18:10:5415925
wezca1070932016-05-26 20:30:5215926 EXPECT_TRUE(response1->headers);
[email protected]02d74a02014-04-23 18:10:5415927 EXPECT_EQ("HTTP/1.1 200 Peachy", response1->headers->GetStatusLine());
15928
15929 std::string response_data1;
15930 rv = ReadTransaction(trans1.get(), &response_data1);
robpercival214763f2016-07-01 23:27:0115931 EXPECT_THAT(rv, IsOk());
[email protected]02d74a02014-04-23 18:10:5415932 EXPECT_EQ("first response", response_data1);
15933 // Delete the transaction to release the socket back into the socket pool.
15934 trans1.reset();
15935
danakj1fd259a02016-04-16 03:17:0915936 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:2215937 element_readers.push_back(
Jeremy Roman0579ed62017-08-29 15:56:1915938 std::make_unique<UploadBytesElementReader>("foo", 3));
olli.raula6df48b2a2015-11-26 07:40:2215939 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]02d74a02014-04-23 18:10:5415940
15941 HttpRequestInfo request2;
15942 request2.method = "POST";
15943 request2.url = GURL("http://www.foo.com/");
15944 request2.upload_data_stream = &upload_data_stream;
15945 request2.load_flags = 0;
15946
bnc691fda62016-08-12 00:43:1615947 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:2015948 rv = trans2.Start(&request2, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0115949 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]02d74a02014-04-23 18:10:5415950
15951 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0115952 EXPECT_THAT(rv, IsOk());
[email protected]02d74a02014-04-23 18:10:5415953
bnc691fda62016-08-12 00:43:1615954 const HttpResponseInfo* response2 = trans2.GetResponseInfo();
wezca1070932016-05-26 20:30:5215955 ASSERT_TRUE(response2);
[email protected]02d74a02014-04-23 18:10:5415956
wezca1070932016-05-26 20:30:5215957 EXPECT_TRUE(response2->headers);
[email protected]02d74a02014-04-23 18:10:5415958 EXPECT_EQ("HTTP/1.1 400 Not OK", response2->headers->GetStatusLine());
15959
15960 std::string response_data2;
bnc691fda62016-08-12 00:43:1615961 rv = ReadTransaction(&trans2, &response_data2);
robpercival214763f2016-07-01 23:27:0115962 EXPECT_THAT(rv, IsOk());
[email protected]02d74a02014-04-23 18:10:5415963 EXPECT_EQ("second response", response_data2);
15964}
15965
bncd16676a2016-07-20 16:23:0115966TEST_F(HttpNetworkTransactionTest,
[email protected]02d74a02014-04-23 18:10:5415967 PostReadsErrorResponseAfterResetPartialBodySent) {
danakj1fd259a02016-04-16 03:17:0915968 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:2215969 element_readers.push_back(
Jeremy Roman0579ed62017-08-29 15:56:1915970 std::make_unique<UploadBytesElementReader>("foo", 3));
olli.raula6df48b2a2015-11-26 07:40:2215971 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]02d74a02014-04-23 18:10:5415972
15973 HttpRequestInfo request;
15974 request.method = "POST";
15975 request.url = GURL("http://www.foo.com/");
15976 request.upload_data_stream = &upload_data_stream;
[email protected]02d74a02014-04-23 18:10:5415977
danakj1fd259a02016-04-16 03:17:0915978 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1615979 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]02d74a02014-04-23 18:10:5415980 // Send headers successfully, but get an error while sending the body.
15981 MockWrite data_writes[] = {
15982 MockWrite("POST / HTTP/1.1\r\n"
15983 "Host: www.foo.com\r\n"
15984 "Connection: keep-alive\r\n"
15985 "Content-Length: 3\r\n\r\n"
15986 "fo"),
15987 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
15988 };
15989
15990 MockRead data_reads[] = {
15991 MockRead("HTTP/1.0 400 Not OK\r\n\r\n"),
15992 MockRead("hello world"),
15993 MockRead(SYNCHRONOUS, OK),
15994 };
15995 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
15996 arraysize(data_writes));
15997 session_deps_.socket_factory->AddSocketDataProvider(&data);
15998
15999 TestCompletionCallback callback;
16000
tfarina42834112016-09-22 13:38:2016001 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0116002 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]02d74a02014-04-23 18:10:5416003
16004 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0116005 EXPECT_THAT(rv, IsOk());
[email protected]02d74a02014-04-23 18:10:5416006
bnc691fda62016-08-12 00:43:1616007 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5216008 ASSERT_TRUE(response);
[email protected]02d74a02014-04-23 18:10:5416009
wezca1070932016-05-26 20:30:5216010 EXPECT_TRUE(response->headers);
[email protected]02d74a02014-04-23 18:10:5416011 EXPECT_EQ("HTTP/1.0 400 Not OK", response->headers->GetStatusLine());
16012
16013 std::string response_data;
bnc691fda62016-08-12 00:43:1616014 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:0116015 EXPECT_THAT(rv, IsOk());
[email protected]02d74a02014-04-23 18:10:5416016 EXPECT_EQ("hello world", response_data);
16017}
16018
16019// This tests the more common case than the previous test, where headers and
16020// body are not merged into a single request.
bncd16676a2016-07-20 16:23:0116021TEST_F(HttpNetworkTransactionTest, ChunkedPostReadsErrorResponseAfterReset) {
mmenkecbc2b712014-10-09 20:29:0716022 ChunkedUploadDataStream upload_data_stream(0);
[email protected]02d74a02014-04-23 18:10:5416023
16024 HttpRequestInfo request;
16025 request.method = "POST";
16026 request.url = GURL("http://www.foo.com/");
16027 request.upload_data_stream = &upload_data_stream;
[email protected]02d74a02014-04-23 18:10:5416028
danakj1fd259a02016-04-16 03:17:0916029 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1616030 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]02d74a02014-04-23 18:10:5416031 // Send headers successfully, but get an error while sending the body.
16032 MockWrite data_writes[] = {
16033 MockWrite("POST / HTTP/1.1\r\n"
16034 "Host: www.foo.com\r\n"
16035 "Connection: keep-alive\r\n"
16036 "Transfer-Encoding: chunked\r\n\r\n"),
16037 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
16038 };
16039
16040 MockRead data_reads[] = {
16041 MockRead("HTTP/1.0 400 Not OK\r\n\r\n"),
16042 MockRead("hello world"),
16043 MockRead(SYNCHRONOUS, OK),
16044 };
16045 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
16046 arraysize(data_writes));
16047 session_deps_.socket_factory->AddSocketDataProvider(&data);
16048
16049 TestCompletionCallback callback;
16050
tfarina42834112016-09-22 13:38:2016051 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0116052 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]02d74a02014-04-23 18:10:5416053 // Make sure the headers are sent before adding a chunk. This ensures that
16054 // they can't be merged with the body in a single send. Not currently
16055 // necessary since a chunked body is never merged with headers, but this makes
16056 // the test more future proof.
16057 base::RunLoop().RunUntilIdle();
16058
mmenkecbc2b712014-10-09 20:29:0716059 upload_data_stream.AppendData("last chunk", 10, true);
[email protected]02d74a02014-04-23 18:10:5416060
16061 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0116062 EXPECT_THAT(rv, IsOk());
[email protected]02d74a02014-04-23 18:10:5416063
bnc691fda62016-08-12 00:43:1616064 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5216065 ASSERT_TRUE(response);
[email protected]02d74a02014-04-23 18:10:5416066
wezca1070932016-05-26 20:30:5216067 EXPECT_TRUE(response->headers);
[email protected]02d74a02014-04-23 18:10:5416068 EXPECT_EQ("HTTP/1.0 400 Not OK", response->headers->GetStatusLine());
16069
16070 std::string response_data;
bnc691fda62016-08-12 00:43:1616071 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:0116072 EXPECT_THAT(rv, IsOk());
[email protected]02d74a02014-04-23 18:10:5416073 EXPECT_EQ("hello world", response_data);
16074}
16075
bncd16676a2016-07-20 16:23:0116076TEST_F(HttpNetworkTransactionTest, PostReadsErrorResponseAfterResetAnd100) {
danakj1fd259a02016-04-16 03:17:0916077 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:2216078 element_readers.push_back(
Jeremy Roman0579ed62017-08-29 15:56:1916079 std::make_unique<UploadBytesElementReader>("foo", 3));
olli.raula6df48b2a2015-11-26 07:40:2216080 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]02d74a02014-04-23 18:10:5416081
16082 HttpRequestInfo request;
16083 request.method = "POST";
16084 request.url = GURL("http://www.foo.com/");
16085 request.upload_data_stream = &upload_data_stream;
[email protected]02d74a02014-04-23 18:10:5416086
danakj1fd259a02016-04-16 03:17:0916087 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1616088 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]02d74a02014-04-23 18:10:5416089
16090 MockWrite data_writes[] = {
16091 MockWrite("POST / HTTP/1.1\r\n"
16092 "Host: www.foo.com\r\n"
16093 "Connection: keep-alive\r\n"
16094 "Content-Length: 3\r\n\r\n"),
16095 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
16096 };
16097
16098 MockRead data_reads[] = {
16099 MockRead("HTTP/1.0 100 Continue\r\n\r\n"),
16100 MockRead("HTTP/1.0 400 Not OK\r\n\r\n"),
16101 MockRead("hello world"),
16102 MockRead(SYNCHRONOUS, OK),
16103 };
16104 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
16105 arraysize(data_writes));
16106 session_deps_.socket_factory->AddSocketDataProvider(&data);
16107
16108 TestCompletionCallback callback;
16109
tfarina42834112016-09-22 13:38:2016110 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0116111 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]02d74a02014-04-23 18:10:5416112
16113 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0116114 EXPECT_THAT(rv, IsOk());
[email protected]02d74a02014-04-23 18:10:5416115
bnc691fda62016-08-12 00:43:1616116 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5216117 ASSERT_TRUE(response);
[email protected]02d74a02014-04-23 18:10:5416118
wezca1070932016-05-26 20:30:5216119 EXPECT_TRUE(response->headers);
[email protected]02d74a02014-04-23 18:10:5416120 EXPECT_EQ("HTTP/1.0 400 Not OK", response->headers->GetStatusLine());
16121
16122 std::string response_data;
bnc691fda62016-08-12 00:43:1616123 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:0116124 EXPECT_THAT(rv, IsOk());
[email protected]02d74a02014-04-23 18:10:5416125 EXPECT_EQ("hello world", response_data);
16126}
16127
bncd16676a2016-07-20 16:23:0116128TEST_F(HttpNetworkTransactionTest, PostIgnoresNonErrorResponseAfterReset) {
danakj1fd259a02016-04-16 03:17:0916129 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:2216130 element_readers.push_back(
Jeremy Roman0579ed62017-08-29 15:56:1916131 std::make_unique<UploadBytesElementReader>("foo", 3));
olli.raula6df48b2a2015-11-26 07:40:2216132 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]02d74a02014-04-23 18:10:5416133
16134 HttpRequestInfo request;
16135 request.method = "POST";
16136 request.url = GURL("http://www.foo.com/");
16137 request.upload_data_stream = &upload_data_stream;
[email protected]02d74a02014-04-23 18:10:5416138
danakj1fd259a02016-04-16 03:17:0916139 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1616140 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]02d74a02014-04-23 18:10:5416141 // Send headers successfully, but get an error while sending the body.
16142 MockWrite data_writes[] = {
16143 MockWrite("POST / HTTP/1.1\r\n"
16144 "Host: www.foo.com\r\n"
16145 "Connection: keep-alive\r\n"
16146 "Content-Length: 3\r\n\r\n"),
16147 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
16148 };
16149
16150 MockRead data_reads[] = {
16151 MockRead("HTTP/1.0 200 Just Dandy\r\n\r\n"),
16152 MockRead("hello world"),
16153 MockRead(SYNCHRONOUS, OK),
16154 };
16155 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
16156 arraysize(data_writes));
16157 session_deps_.socket_factory->AddSocketDataProvider(&data);
16158
16159 TestCompletionCallback callback;
16160
tfarina42834112016-09-22 13:38:2016161 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0116162 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]02d74a02014-04-23 18:10:5416163
16164 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0116165 EXPECT_THAT(rv, IsError(ERR_CONNECTION_RESET));
[email protected]02d74a02014-04-23 18:10:5416166}
16167
bncd16676a2016-07-20 16:23:0116168TEST_F(HttpNetworkTransactionTest,
[email protected]02d74a02014-04-23 18:10:5416169 PostIgnoresNonErrorResponseAfterResetAnd100) {
danakj1fd259a02016-04-16 03:17:0916170 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:2216171 element_readers.push_back(
Jeremy Roman0579ed62017-08-29 15:56:1916172 std::make_unique<UploadBytesElementReader>("foo", 3));
olli.raula6df48b2a2015-11-26 07:40:2216173 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]02d74a02014-04-23 18:10:5416174
16175 HttpRequestInfo request;
16176 request.method = "POST";
16177 request.url = GURL("http://www.foo.com/");
16178 request.upload_data_stream = &upload_data_stream;
[email protected]02d74a02014-04-23 18:10:5416179
danakj1fd259a02016-04-16 03:17:0916180 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1616181 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]02d74a02014-04-23 18:10:5416182 // Send headers successfully, but get an error while sending the body.
16183 MockWrite data_writes[] = {
16184 MockWrite("POST / HTTP/1.1\r\n"
16185 "Host: www.foo.com\r\n"
16186 "Connection: keep-alive\r\n"
16187 "Content-Length: 3\r\n\r\n"),
16188 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
16189 };
16190
16191 MockRead data_reads[] = {
16192 MockRead("HTTP/1.0 100 Continue\r\n\r\n"),
16193 MockRead("HTTP/1.0 302 Redirect\r\n"),
16194 MockRead("Location: http://somewhere-else.com/\r\n"),
16195 MockRead("Content-Length: 0\r\n\r\n"),
16196 MockRead(SYNCHRONOUS, OK),
16197 };
16198 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
16199 arraysize(data_writes));
16200 session_deps_.socket_factory->AddSocketDataProvider(&data);
16201
16202 TestCompletionCallback callback;
16203
tfarina42834112016-09-22 13:38:2016204 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0116205 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]02d74a02014-04-23 18:10:5416206
16207 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0116208 EXPECT_THAT(rv, IsError(ERR_CONNECTION_RESET));
[email protected]02d74a02014-04-23 18:10:5416209}
16210
bncd16676a2016-07-20 16:23:0116211TEST_F(HttpNetworkTransactionTest, PostIgnoresHttp09ResponseAfterReset) {
danakj1fd259a02016-04-16 03:17:0916212 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:2216213 element_readers.push_back(
Jeremy Roman0579ed62017-08-29 15:56:1916214 std::make_unique<UploadBytesElementReader>("foo", 3));
olli.raula6df48b2a2015-11-26 07:40:2216215 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]02d74a02014-04-23 18:10:5416216
16217 HttpRequestInfo request;
16218 request.method = "POST";
16219 request.url = GURL("http://www.foo.com/");
16220 request.upload_data_stream = &upload_data_stream;
[email protected]02d74a02014-04-23 18:10:5416221
danakj1fd259a02016-04-16 03:17:0916222 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1616223 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]02d74a02014-04-23 18:10:5416224 // Send headers successfully, but get an error while sending the body.
16225 MockWrite data_writes[] = {
16226 MockWrite("POST / HTTP/1.1\r\n"
16227 "Host: www.foo.com\r\n"
16228 "Connection: keep-alive\r\n"
16229 "Content-Length: 3\r\n\r\n"),
16230 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
16231 };
16232
16233 MockRead data_reads[] = {
16234 MockRead("HTTP 0.9 rocks!"),
16235 MockRead(SYNCHRONOUS, OK),
16236 };
16237 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
16238 arraysize(data_writes));
16239 session_deps_.socket_factory->AddSocketDataProvider(&data);
16240
16241 TestCompletionCallback callback;
16242
tfarina42834112016-09-22 13:38:2016243 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0116244 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]02d74a02014-04-23 18:10:5416245
16246 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0116247 EXPECT_THAT(rv, IsError(ERR_CONNECTION_RESET));
[email protected]02d74a02014-04-23 18:10:5416248}
16249
bncd16676a2016-07-20 16:23:0116250TEST_F(HttpNetworkTransactionTest, PostIgnoresPartial400HeadersAfterReset) {
danakj1fd259a02016-04-16 03:17:0916251 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:2216252 element_readers.push_back(
Jeremy Roman0579ed62017-08-29 15:56:1916253 std::make_unique<UploadBytesElementReader>("foo", 3));
olli.raula6df48b2a2015-11-26 07:40:2216254 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]02d74a02014-04-23 18:10:5416255
16256 HttpRequestInfo request;
16257 request.method = "POST";
16258 request.url = GURL("http://www.foo.com/");
16259 request.upload_data_stream = &upload_data_stream;
[email protected]02d74a02014-04-23 18:10:5416260
danakj1fd259a02016-04-16 03:17:0916261 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1616262 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]02d74a02014-04-23 18:10:5416263 // Send headers successfully, but get an error while sending the body.
16264 MockWrite data_writes[] = {
16265 MockWrite("POST / HTTP/1.1\r\n"
16266 "Host: www.foo.com\r\n"
16267 "Connection: keep-alive\r\n"
16268 "Content-Length: 3\r\n\r\n"),
16269 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
16270 };
16271
16272 MockRead data_reads[] = {
16273 MockRead("HTTP/1.0 400 Not a Full Response\r\n"),
16274 MockRead(SYNCHRONOUS, OK),
16275 };
16276 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
16277 arraysize(data_writes));
16278 session_deps_.socket_factory->AddSocketDataProvider(&data);
16279
16280 TestCompletionCallback callback;
16281
tfarina42834112016-09-22 13:38:2016282 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0116283 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]02d74a02014-04-23 18:10:5416284
16285 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0116286 EXPECT_THAT(rv, IsError(ERR_CONNECTION_RESET));
[email protected]02d74a02014-04-23 18:10:5416287}
16288
Adam Rice425cf122015-01-19 06:18:2416289// Verify that proxy headers are not sent to the destination server when
16290// establishing a tunnel for a secure WebSocket connection.
bncd16676a2016-07-20 16:23:0116291TEST_F(HttpNetworkTransactionTest, ProxyHeadersNotSentOverWssTunnel) {
Adam Rice425cf122015-01-19 06:18:2416292 HttpRequestInfo request;
16293 request.method = "GET";
bncce36dca22015-04-21 22:11:2316294 request.url = GURL("wss://www.example.org/");
Adam Rice425cf122015-01-19 06:18:2416295 AddWebSocketHeaders(&request.extra_headers);
16296
16297 // Configure against proxy server "myproxy:70".
rdsmith82957ad2015-09-16 19:42:0316298 session_deps_.proxy_service =
16299 ProxyService::CreateFixedFromPacResult("PROXY myproxy:70");
Adam Rice425cf122015-01-19 06:18:2416300
danakj1fd259a02016-04-16 03:17:0916301 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
Adam Rice425cf122015-01-19 06:18:2416302
16303 // Since a proxy is configured, try to establish a tunnel.
16304 MockWrite data_writes[] = {
rsleevidb16bb02015-11-12 23:47:1716305 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
16306 "Host: www.example.org:443\r\n"
16307 "Proxy-Connection: keep-alive\r\n\r\n"),
Adam Rice425cf122015-01-19 06:18:2416308
16309 // After calling trans->RestartWithAuth(), this is the request we should
16310 // be issuing -- the final header line contains the credentials.
rsleevidb16bb02015-11-12 23:47:1716311 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
16312 "Host: www.example.org:443\r\n"
16313 "Proxy-Connection: keep-alive\r\n"
16314 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
Adam Rice425cf122015-01-19 06:18:2416315
rsleevidb16bb02015-11-12 23:47:1716316 MockWrite("GET / HTTP/1.1\r\n"
16317 "Host: www.example.org\r\n"
16318 "Connection: Upgrade\r\n"
16319 "Upgrade: websocket\r\n"
16320 "Origin: http://www.example.org\r\n"
16321 "Sec-WebSocket-Version: 13\r\n"
16322 "Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==\r\n\r\n"),
Adam Rice425cf122015-01-19 06:18:2416323 };
16324
16325 // The proxy responds to the connect with a 407, using a persistent
16326 // connection.
16327 MockRead data_reads[] = {
16328 // No credentials.
16329 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
16330 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
mmenkee71e15332015-10-07 16:39:5416331 MockRead("Content-Length: 0\r\n"),
16332 MockRead("Proxy-Connection: keep-alive\r\n\r\n"),
Adam Rice425cf122015-01-19 06:18:2416333
16334 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
16335
16336 MockRead("HTTP/1.1 101 Switching Protocols\r\n"),
16337 MockRead("Upgrade: websocket\r\n"),
16338 MockRead("Connection: Upgrade\r\n"),
16339 MockRead("Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=\r\n\r\n"),
16340 };
16341
16342 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
16343 arraysize(data_writes));
16344 session_deps_.socket_factory->AddSocketDataProvider(&data);
16345 SSLSocketDataProvider ssl(ASYNC, OK);
16346 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
16347
bnc87dcefc2017-05-25 12:47:5816348 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:1916349 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
Adam Rice425cf122015-01-19 06:18:2416350 FakeWebSocketStreamCreateHelper websocket_stream_create_helper;
16351 trans->SetWebSocketHandshakeStreamCreateHelper(
16352 &websocket_stream_create_helper);
16353
16354 {
16355 TestCompletionCallback callback;
16356
tfarina42834112016-09-22 13:38:2016357 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0116358 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
Adam Rice425cf122015-01-19 06:18:2416359
16360 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0116361 EXPECT_THAT(rv, IsOk());
Adam Rice425cf122015-01-19 06:18:2416362 }
16363
16364 const HttpResponseInfo* response = trans->GetResponseInfo();
16365 ASSERT_TRUE(response);
wezca1070932016-05-26 20:30:5216366 ASSERT_TRUE(response->headers);
Adam Rice425cf122015-01-19 06:18:2416367 EXPECT_EQ(407, response->headers->response_code());
16368
16369 {
16370 TestCompletionCallback callback;
16371
16372 int rv = trans->RestartWithAuth(AuthCredentials(kFoo, kBar),
16373 callback.callback());
robpercival214763f2016-07-01 23:27:0116374 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
Adam Rice425cf122015-01-19 06:18:2416375
16376 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0116377 EXPECT_THAT(rv, IsOk());
Adam Rice425cf122015-01-19 06:18:2416378 }
16379
16380 response = trans->GetResponseInfo();
16381 ASSERT_TRUE(response);
wezca1070932016-05-26 20:30:5216382 ASSERT_TRUE(response->headers);
Adam Rice425cf122015-01-19 06:18:2416383
16384 EXPECT_EQ(101, response->headers->response_code());
16385
16386 trans.reset();
16387 session->CloseAllConnections();
16388}
16389
16390// Verify that proxy headers are not sent to the destination server when
16391// establishing a tunnel for an insecure WebSocket connection.
16392// This requires the authentication info to be injected into the auth cache
16393// due to crbug.com/395064
16394// TODO(ricea): Change to use a 407 response once issue 395064 is fixed.
bncd16676a2016-07-20 16:23:0116395TEST_F(HttpNetworkTransactionTest, ProxyHeadersNotSentOverWsTunnel) {
Adam Rice425cf122015-01-19 06:18:2416396 HttpRequestInfo request;
16397 request.method = "GET";
bncce36dca22015-04-21 22:11:2316398 request.url = GURL("ws://www.example.org/");
Adam Rice425cf122015-01-19 06:18:2416399 AddWebSocketHeaders(&request.extra_headers);
16400
16401 // Configure against proxy server "myproxy:70".
rdsmith82957ad2015-09-16 19:42:0316402 session_deps_.proxy_service =
16403 ProxyService::CreateFixedFromPacResult("PROXY myproxy:70");
Adam Rice425cf122015-01-19 06:18:2416404
danakj1fd259a02016-04-16 03:17:0916405 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
Adam Rice425cf122015-01-19 06:18:2416406
16407 MockWrite data_writes[] = {
16408 // Try to establish a tunnel for the WebSocket connection, with
16409 // credentials. Because WebSockets have a separate set of socket pools,
16410 // they cannot and will not use the same TCP/IP connection as the
16411 // preflight HTTP request.
16412 MockWrite(
bncce36dca22015-04-21 22:11:2316413 "CONNECT www.example.org:80 HTTP/1.1\r\n"
16414 "Host: www.example.org:80\r\n"
Adam Rice425cf122015-01-19 06:18:2416415 "Proxy-Connection: keep-alive\r\n"
16416 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
16417
16418 MockWrite(
16419 "GET / HTTP/1.1\r\n"
bncce36dca22015-04-21 22:11:2316420 "Host: www.example.org\r\n"
Adam Rice425cf122015-01-19 06:18:2416421 "Connection: Upgrade\r\n"
16422 "Upgrade: websocket\r\n"
bncce36dca22015-04-21 22:11:2316423 "Origin: http://www.example.org\r\n"
Adam Rice425cf122015-01-19 06:18:2416424 "Sec-WebSocket-Version: 13\r\n"
16425 "Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==\r\n\r\n"),
16426 };
16427
16428 MockRead data_reads[] = {
16429 // HTTP CONNECT with credentials.
16430 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
16431
16432 // WebSocket connection established inside tunnel.
16433 MockRead("HTTP/1.1 101 Switching Protocols\r\n"),
16434 MockRead("Upgrade: websocket\r\n"),
16435 MockRead("Connection: Upgrade\r\n"),
16436 MockRead("Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=\r\n\r\n"),
16437 };
16438
16439 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
16440 arraysize(data_writes));
16441 session_deps_.socket_factory->AddSocketDataProvider(&data);
16442
16443 session->http_auth_cache()->Add(
16444 GURL("http://myproxy:70/"), "MyRealm1", HttpAuth::AUTH_SCHEME_BASIC,
16445 "Basic realm=MyRealm1", AuthCredentials(kFoo, kBar), "/");
16446
bnc87dcefc2017-05-25 12:47:5816447 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:1916448 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
Adam Rice425cf122015-01-19 06:18:2416449 FakeWebSocketStreamCreateHelper websocket_stream_create_helper;
16450 trans->SetWebSocketHandshakeStreamCreateHelper(
16451 &websocket_stream_create_helper);
16452
16453 TestCompletionCallback callback;
16454
tfarina42834112016-09-22 13:38:2016455 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0116456 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
Adam Rice425cf122015-01-19 06:18:2416457
16458 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0116459 EXPECT_THAT(rv, IsOk());
Adam Rice425cf122015-01-19 06:18:2416460
16461 const HttpResponseInfo* response = trans->GetResponseInfo();
16462 ASSERT_TRUE(response);
wezca1070932016-05-26 20:30:5216463 ASSERT_TRUE(response->headers);
Adam Rice425cf122015-01-19 06:18:2416464
16465 EXPECT_EQ(101, response->headers->response_code());
16466
16467 trans.reset();
16468 session->CloseAllConnections();
16469}
16470
bncd16676a2016-07-20 16:23:0116471TEST_F(HttpNetworkTransactionTest, TotalNetworkBytesPost) {
danakj1fd259a02016-04-16 03:17:0916472 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:2216473 element_readers.push_back(
Jeremy Roman0579ed62017-08-29 15:56:1916474 std::make_unique<UploadBytesElementReader>("foo", 3));
olli.raula6df48b2a2015-11-26 07:40:2216475 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
sclittlefb249892015-09-10 21:33:2216476
16477 HttpRequestInfo request;
16478 request.method = "POST";
16479 request.url = GURL("http://www.foo.com/");
16480 request.upload_data_stream = &upload_data_stream;
16481
danakj1fd259a02016-04-16 03:17:0916482 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1616483 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
sclittlefb249892015-09-10 21:33:2216484 MockWrite data_writes[] = {
16485 MockWrite("POST / HTTP/1.1\r\n"
16486 "Host: www.foo.com\r\n"
16487 "Connection: keep-alive\r\n"
16488 "Content-Length: 3\r\n\r\n"),
16489 MockWrite("foo"),
16490 };
16491
16492 MockRead data_reads[] = {
16493 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello world"),
16494 MockRead(SYNCHRONOUS, OK),
16495 };
16496 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
16497 arraysize(data_writes));
16498 session_deps_.socket_factory->AddSocketDataProvider(&data);
16499
16500 TestCompletionCallback callback;
16501
16502 EXPECT_EQ(ERR_IO_PENDING,
tfarina42834112016-09-22 13:38:2016503 trans.Start(&request, callback.callback(), NetLogWithSource()));
robpercival214763f2016-07-01 23:27:0116504 EXPECT_THAT(callback.WaitForResult(), IsOk());
sclittlefb249892015-09-10 21:33:2216505
16506 std::string response_data;
bnc691fda62016-08-12 00:43:1616507 EXPECT_THAT(ReadTransaction(&trans, &response_data), IsOk());
sclittlefb249892015-09-10 21:33:2216508
16509 EXPECT_EQ(CountWriteBytes(data_writes, arraysize(data_writes)),
bnc691fda62016-08-12 00:43:1616510 trans.GetTotalSentBytes());
sclittlefb249892015-09-10 21:33:2216511 EXPECT_EQ(CountReadBytes(data_reads, arraysize(data_reads)),
bnc691fda62016-08-12 00:43:1616512 trans.GetTotalReceivedBytes());
sclittlefb249892015-09-10 21:33:2216513}
16514
bncd16676a2016-07-20 16:23:0116515TEST_F(HttpNetworkTransactionTest, TotalNetworkBytesPost100Continue) {
danakj1fd259a02016-04-16 03:17:0916516 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:2216517 element_readers.push_back(
Jeremy Roman0579ed62017-08-29 15:56:1916518 std::make_unique<UploadBytesElementReader>("foo", 3));
olli.raula6df48b2a2015-11-26 07:40:2216519 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
sclittlefb249892015-09-10 21:33:2216520
16521 HttpRequestInfo request;
16522 request.method = "POST";
16523 request.url = GURL("http://www.foo.com/");
16524 request.upload_data_stream = &upload_data_stream;
16525
danakj1fd259a02016-04-16 03:17:0916526 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1616527 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
sclittlefb249892015-09-10 21:33:2216528 MockWrite data_writes[] = {
16529 MockWrite("POST / HTTP/1.1\r\n"
16530 "Host: www.foo.com\r\n"
16531 "Connection: keep-alive\r\n"
16532 "Content-Length: 3\r\n\r\n"),
16533 MockWrite("foo"),
16534 };
16535
16536 MockRead data_reads[] = {
16537 MockRead("HTTP/1.1 100 Continue\r\n\r\n"),
16538 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello world"),
16539 MockRead(SYNCHRONOUS, OK),
16540 };
16541 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
16542 arraysize(data_writes));
16543 session_deps_.socket_factory->AddSocketDataProvider(&data);
16544
16545 TestCompletionCallback callback;
16546
16547 EXPECT_EQ(ERR_IO_PENDING,
tfarina42834112016-09-22 13:38:2016548 trans.Start(&request, callback.callback(), NetLogWithSource()));
robpercival214763f2016-07-01 23:27:0116549 EXPECT_THAT(callback.WaitForResult(), IsOk());
sclittlefb249892015-09-10 21:33:2216550
16551 std::string response_data;
bnc691fda62016-08-12 00:43:1616552 EXPECT_THAT(ReadTransaction(&trans, &response_data), IsOk());
sclittlefb249892015-09-10 21:33:2216553
16554 EXPECT_EQ(CountWriteBytes(data_writes, arraysize(data_writes)),
bnc691fda62016-08-12 00:43:1616555 trans.GetTotalSentBytes());
sclittlefb249892015-09-10 21:33:2216556 EXPECT_EQ(CountReadBytes(data_reads, arraysize(data_reads)),
bnc691fda62016-08-12 00:43:1616557 trans.GetTotalReceivedBytes());
sclittlefb249892015-09-10 21:33:2216558}
16559
bncd16676a2016-07-20 16:23:0116560TEST_F(HttpNetworkTransactionTest, TotalNetworkBytesChunkedPost) {
sclittlefb249892015-09-10 21:33:2216561 ChunkedUploadDataStream upload_data_stream(0);
16562
16563 HttpRequestInfo request;
16564 request.method = "POST";
16565 request.url = GURL("http://www.foo.com/");
16566 request.upload_data_stream = &upload_data_stream;
16567
danakj1fd259a02016-04-16 03:17:0916568 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1616569 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
sclittlefb249892015-09-10 21:33:2216570 // Send headers successfully, but get an error while sending the body.
16571 MockWrite data_writes[] = {
16572 MockWrite("POST / HTTP/1.1\r\n"
16573 "Host: www.foo.com\r\n"
16574 "Connection: keep-alive\r\n"
16575 "Transfer-Encoding: chunked\r\n\r\n"),
16576 MockWrite("1\r\nf\r\n"), MockWrite("2\r\noo\r\n"), MockWrite("0\r\n\r\n"),
16577 };
16578
16579 MockRead data_reads[] = {
16580 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello world"),
16581 MockRead(SYNCHRONOUS, OK),
16582 };
16583 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
16584 arraysize(data_writes));
16585 session_deps_.socket_factory->AddSocketDataProvider(&data);
16586
16587 TestCompletionCallback callback;
16588
16589 EXPECT_EQ(ERR_IO_PENDING,
tfarina42834112016-09-22 13:38:2016590 trans.Start(&request, callback.callback(), NetLogWithSource()));
sclittlefb249892015-09-10 21:33:2216591
16592 base::RunLoop().RunUntilIdle();
16593 upload_data_stream.AppendData("f", 1, false);
16594
16595 base::RunLoop().RunUntilIdle();
16596 upload_data_stream.AppendData("oo", 2, true);
16597
robpercival214763f2016-07-01 23:27:0116598 EXPECT_THAT(callback.WaitForResult(), IsOk());
sclittlefb249892015-09-10 21:33:2216599
16600 std::string response_data;
bnc691fda62016-08-12 00:43:1616601 EXPECT_THAT(ReadTransaction(&trans, &response_data), IsOk());
sclittlefb249892015-09-10 21:33:2216602
16603 EXPECT_EQ(CountWriteBytes(data_writes, arraysize(data_writes)),
bnc691fda62016-08-12 00:43:1616604 trans.GetTotalSentBytes());
sclittlefb249892015-09-10 21:33:2216605 EXPECT_EQ(CountReadBytes(data_reads, arraysize(data_reads)),
bnc691fda62016-08-12 00:43:1616606 trans.GetTotalReceivedBytes());
sclittlefb249892015-09-10 21:33:2216607}
16608
rdsmith1d343be52016-10-21 20:37:5016609// Confirm that transactions whose throttle is created in (and stays in)
16610// the unthrottled state are not blocked.
16611TEST_F(HttpNetworkTransactionTest, ThrottlingUnthrottled) {
16612 TestNetworkStreamThrottler* throttler(nullptr);
16613 std::unique_ptr<HttpNetworkSession> session(
16614 CreateSessionWithThrottler(&session_deps_, &throttler));
16615
16616 // Send a simple request and make sure it goes through.
16617 HttpRequestInfo request;
16618 request.method = "GET";
16619 request.url = GURL("http://www.example.org/");
16620
bnc87dcefc2017-05-25 12:47:5816621 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:1916622 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
rdsmith1d343be52016-10-21 20:37:5016623
16624 MockWrite data_writes[] = {
16625 MockWrite("GET / HTTP/1.1\r\n"
16626 "Host: www.example.org\r\n"
16627 "Connection: keep-alive\r\n\r\n"),
16628 };
16629 MockRead data_reads[] = {
16630 MockRead("HTTP/1.0 200 OK\r\n\r\n"), MockRead("hello world"),
16631 MockRead(SYNCHRONOUS, OK),
16632 };
16633 StaticSocketDataProvider reads(data_reads, arraysize(data_reads), data_writes,
16634 arraysize(data_writes));
16635 session_deps_.socket_factory->AddSocketDataProvider(&reads);
16636
16637 TestCompletionCallback callback;
16638 trans->Start(&request, callback.callback(), NetLogWithSource());
16639 EXPECT_EQ(OK, callback.WaitForResult());
16640}
16641
16642// Confirm requests can be blocked by a throttler, and are resumed
16643// when the throttle is unblocked.
16644TEST_F(HttpNetworkTransactionTest, ThrottlingBasic) {
16645 TestNetworkStreamThrottler* throttler(nullptr);
16646 std::unique_ptr<HttpNetworkSession> session(
16647 CreateSessionWithThrottler(&session_deps_, &throttler));
16648
16649 // Send a simple request and make sure it goes through.
16650 HttpRequestInfo request;
16651 request.method = "GET";
16652 request.url = GURL("http://www.example.org/");
16653
16654 MockWrite data_writes[] = {
16655 MockWrite("GET / HTTP/1.1\r\n"
16656 "Host: www.example.org\r\n"
16657 "Connection: keep-alive\r\n\r\n"),
16658 };
16659 MockRead data_reads[] = {
16660 MockRead("HTTP/1.0 200 OK\r\n\r\n"), MockRead("hello world"),
16661 MockRead(SYNCHRONOUS, OK),
16662 };
16663 StaticSocketDataProvider reads(data_reads, arraysize(data_reads), data_writes,
16664 arraysize(data_writes));
16665 session_deps_.socket_factory->AddSocketDataProvider(&reads);
16666
16667 // Start a request that will be throttled at start; confirm it
16668 // doesn't complete.
16669 throttler->set_throttle_new_requests(true);
bnc87dcefc2017-05-25 12:47:5816670 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:1916671 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
rdsmith1d343be52016-10-21 20:37:5016672
16673 TestCompletionCallback callback;
16674 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
16675 EXPECT_EQ(ERR_IO_PENDING, rv);
16676
16677 base::RunLoop().RunUntilIdle();
16678 EXPECT_EQ(LOAD_STATE_THROTTLED, trans->GetLoadState());
16679 EXPECT_FALSE(callback.have_result());
16680
16681 // Confirm the request goes on to complete when unthrottled.
16682 throttler->UnthrottleAllRequests();
16683 base::RunLoop().RunUntilIdle();
16684 ASSERT_TRUE(callback.have_result());
16685 EXPECT_EQ(OK, callback.WaitForResult());
16686}
16687
16688// Destroy a request while it's throttled.
16689TEST_F(HttpNetworkTransactionTest, ThrottlingDestruction) {
16690 TestNetworkStreamThrottler* throttler(nullptr);
16691 std::unique_ptr<HttpNetworkSession> session(
16692 CreateSessionWithThrottler(&session_deps_, &throttler));
16693
16694 // Send a simple request and make sure it goes through.
16695 HttpRequestInfo request;
16696 request.method = "GET";
16697 request.url = GURL("http://www.example.org/");
16698
16699 MockWrite data_writes[] = {
16700 MockWrite("GET / HTTP/1.1\r\n"
16701 "Host: www.example.org\r\n"
16702 "Connection: keep-alive\r\n\r\n"),
16703 };
16704 MockRead data_reads[] = {
16705 MockRead("HTTP/1.0 200 OK\r\n\r\n"), MockRead("hello world"),
16706 MockRead(SYNCHRONOUS, OK),
16707 };
16708 StaticSocketDataProvider reads(data_reads, arraysize(data_reads), data_writes,
16709 arraysize(data_writes));
16710 session_deps_.socket_factory->AddSocketDataProvider(&reads);
16711
16712 // Start a request that will be throttled at start; confirm it
16713 // doesn't complete.
16714 throttler->set_throttle_new_requests(true);
bnc87dcefc2017-05-25 12:47:5816715 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:1916716 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
rdsmith1d343be52016-10-21 20:37:5016717
16718 TestCompletionCallback callback;
16719 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
16720 EXPECT_EQ(ERR_IO_PENDING, rv);
16721
16722 base::RunLoop().RunUntilIdle();
16723 EXPECT_EQ(LOAD_STATE_THROTTLED, trans->GetLoadState());
16724 EXPECT_FALSE(callback.have_result());
16725
16726 EXPECT_EQ(1u, throttler->num_outstanding_requests());
16727 trans.reset();
16728 EXPECT_EQ(0u, throttler->num_outstanding_requests());
16729}
16730
16731// Confirm the throttler receives SetPriority calls.
16732TEST_F(HttpNetworkTransactionTest, ThrottlingPrioritySet) {
16733 TestNetworkStreamThrottler* throttler(nullptr);
16734 std::unique_ptr<HttpNetworkSession> session(
16735 CreateSessionWithThrottler(&session_deps_, &throttler));
16736
16737 // Send a simple request and make sure it goes through.
16738 HttpRequestInfo request;
16739 request.method = "GET";
16740 request.url = GURL("http://www.example.org/");
16741
16742 MockWrite data_writes[] = {
16743 MockWrite("GET / HTTP/1.1\r\n"
16744 "Host: www.example.org\r\n"
16745 "Connection: keep-alive\r\n\r\n"),
16746 };
16747 MockRead data_reads[] = {
16748 MockRead("HTTP/1.0 200 OK\r\n\r\n"), MockRead("hello world"),
16749 MockRead(SYNCHRONOUS, OK),
16750 };
16751 StaticSocketDataProvider reads(data_reads, arraysize(data_reads), data_writes,
16752 arraysize(data_writes));
16753 session_deps_.socket_factory->AddSocketDataProvider(&reads);
16754
16755 throttler->set_throttle_new_requests(true);
Jeremy Roman0579ed62017-08-29 15:56:1916756 auto trans = std::make_unique<HttpNetworkTransaction>(IDLE, session.get());
rdsmith1d343be52016-10-21 20:37:5016757 // Start the transaction to associate a throttle with it.
16758 TestCompletionCallback callback;
16759 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
16760 EXPECT_EQ(ERR_IO_PENDING, rv);
16761
16762 EXPECT_EQ(0, throttler->num_set_priority_calls());
16763 trans->SetPriority(LOW);
16764 EXPECT_EQ(1, throttler->num_set_priority_calls());
16765 EXPECT_EQ(LOW, throttler->last_priority_set());
16766
16767 throttler->UnthrottleAllRequests();
16768 base::RunLoop().RunUntilIdle();
16769 ASSERT_TRUE(callback.have_result());
16770 EXPECT_EQ(OK, callback.WaitForResult());
16771}
16772
16773// Confirm that unthrottling from a SetPriority call by the
16774// throttler works properly.
16775TEST_F(HttpNetworkTransactionTest, ThrottlingPrioritySetUnthrottle) {
16776 TestNetworkStreamThrottler* throttler(nullptr);
16777 std::unique_ptr<HttpNetworkSession> session(
16778 CreateSessionWithThrottler(&session_deps_, &throttler));
16779
16780 // Send a simple request and make sure it goes through.
16781 HttpRequestInfo request;
16782 request.method = "GET";
16783 request.url = GURL("http://www.example.org/");
16784
16785 MockWrite data_writes[] = {
16786 MockWrite("GET / HTTP/1.1\r\n"
16787 "Host: www.example.org\r\n"
16788 "Connection: keep-alive\r\n\r\n"),
16789 };
16790 MockRead data_reads[] = {
16791 MockRead("HTTP/1.0 200 OK\r\n\r\n"), MockRead("hello world"),
16792 MockRead(SYNCHRONOUS, OK),
16793 };
16794 StaticSocketDataProvider reads(data_reads, arraysize(data_reads), data_writes,
16795 arraysize(data_writes));
16796 session_deps_.socket_factory->AddSocketDataProvider(&reads);
16797
16798 StaticSocketDataProvider reads1(data_reads, arraysize(data_reads),
16799 data_writes, arraysize(data_writes));
16800 session_deps_.socket_factory->AddSocketDataProvider(&reads1);
16801
16802 // Start a request that will be throttled at start; confirm it
16803 // doesn't complete.
16804 throttler->set_throttle_new_requests(true);
bnc87dcefc2017-05-25 12:47:5816805 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:1916806 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
rdsmith1d343be52016-10-21 20:37:5016807
16808 TestCompletionCallback callback;
16809 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
16810 EXPECT_EQ(ERR_IO_PENDING, rv);
16811
16812 base::RunLoop().RunUntilIdle();
16813 EXPECT_EQ(LOAD_STATE_THROTTLED, trans->GetLoadState());
16814 EXPECT_FALSE(callback.have_result());
16815
16816 // Create a new request, call SetPriority on it to unthrottle,
16817 // and make sure that allows the original request to complete.
Jeremy Roman0579ed62017-08-29 15:56:1916818 auto trans1 = std::make_unique<HttpNetworkTransaction>(LOW, session.get());
rdsmith1d343be52016-10-21 20:37:5016819 throttler->set_priority_change_closure(
16820 base::Bind(&TestNetworkStreamThrottler::UnthrottleAllRequests,
16821 base::Unretained(throttler)));
16822
16823 // Start the transaction to associate a throttle with it.
16824 TestCompletionCallback callback1;
16825 rv = trans1->Start(&request, callback1.callback(), NetLogWithSource());
16826 EXPECT_EQ(ERR_IO_PENDING, rv);
16827
16828 trans1->SetPriority(IDLE);
16829
16830 base::RunLoop().RunUntilIdle();
16831 ASSERT_TRUE(callback.have_result());
16832 EXPECT_EQ(OK, callback.WaitForResult());
16833 ASSERT_TRUE(callback1.have_result());
16834 EXPECT_EQ(OK, callback1.WaitForResult());
16835}
16836
16837// Transaction will be destroyed when the unique_ptr goes out of scope.
bnc87dcefc2017-05-25 12:47:5816838void DestroyTransaction(std::unique_ptr<HttpNetworkTransaction> transaction) {}
rdsmith1d343be52016-10-21 20:37:5016839
16840// Confirm that destroying a transaction from a SetPriority call by the
16841// throttler works properly.
16842TEST_F(HttpNetworkTransactionTest, ThrottlingPrioritySetDestroy) {
16843 TestNetworkStreamThrottler* throttler(nullptr);
16844 std::unique_ptr<HttpNetworkSession> session(
16845 CreateSessionWithThrottler(&session_deps_, &throttler));
16846
16847 // Send a simple request and make sure it goes through.
16848 HttpRequestInfo request;
16849 request.method = "GET";
16850 request.url = GURL("http://www.example.org/");
16851
16852 MockWrite data_writes[] = {
16853 MockWrite("GET / HTTP/1.1\r\n"
16854 "Host: www.example.org\r\n"
16855 "Connection: keep-alive\r\n\r\n"),
16856 };
16857 MockRead data_reads[] = {
16858 MockRead("HTTP/1.0 200 OK\r\n\r\n"), MockRead("hello world"),
16859 MockRead(SYNCHRONOUS, OK),
16860 };
16861 StaticSocketDataProvider reads(data_reads, arraysize(data_reads), data_writes,
16862 arraysize(data_writes));
16863 session_deps_.socket_factory->AddSocketDataProvider(&reads);
16864
16865 StaticSocketDataProvider reads1(data_reads, arraysize(data_reads),
16866 data_writes, arraysize(data_writes));
16867 session_deps_.socket_factory->AddSocketDataProvider(&reads1);
16868
16869 // Start a request that will be throttled at start; confirm it
16870 // doesn't complete.
16871 throttler->set_throttle_new_requests(true);
bnc87dcefc2017-05-25 12:47:5816872 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:1916873 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
rdsmith1d343be52016-10-21 20:37:5016874
16875 TestCompletionCallback callback;
16876 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
16877 EXPECT_EQ(ERR_IO_PENDING, rv);
16878
16879 base::RunLoop().RunUntilIdle();
16880 EXPECT_EQ(LOAD_STATE_THROTTLED, trans->GetLoadState());
16881 EXPECT_FALSE(callback.have_result());
16882
16883 // Arrange for the set priority call on the above transaction to delete
16884 // the transaction.
bnc87dcefc2017-05-25 12:47:5816885 HttpNetworkTransaction* trans_ptr(trans.get());
rdsmith1d343be52016-10-21 20:37:5016886 throttler->set_priority_change_closure(
16887 base::Bind(&DestroyTransaction, base::Passed(&trans)));
16888
16889 // Call it and check results (partially a "doesn't crash" test).
16890 trans_ptr->SetPriority(IDLE);
16891 trans_ptr = nullptr; // No longer a valid pointer.
16892
16893 base::RunLoop().RunUntilIdle();
16894 ASSERT_FALSE(callback.have_result());
16895}
16896
nharperb7441ef2016-01-25 23:54:1416897#if !defined(OS_IOS)
bncd16676a2016-07-20 16:23:0116898TEST_F(HttpNetworkTransactionTest, TokenBindingSpdy) {
nharperb7441ef2016-01-25 23:54:1416899 const std::string https_url = "https://www.example.com";
16900 HttpRequestInfo request;
16901 request.url = GURL(https_url);
16902 request.method = "GET";
16903
16904 SSLSocketDataProvider ssl(ASYNC, OK);
16905 ssl.token_binding_negotiated = true;
16906 ssl.token_binding_key_param = TB_PARAM_ECDSAP256;
bnc3cf2a592016-08-11 14:48:3616907 ssl.next_proto = kProtoHTTP2;
nharperb7441ef2016-01-25 23:54:1416908 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
16909
bnc42331402016-07-25 13:36:1516910 SpdySerializedFrame resp(spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
bncdf80d44fd2016-07-15 20:27:4116911 SpdySerializedFrame body(spdy_util_.ConstructSpdyDataFrame(1, true));
16912 MockRead reads[] = {CreateMockRead(resp), CreateMockRead(body),
nharperb7441ef2016-01-25 23:54:1416913 MockRead(ASYNC, ERR_IO_PENDING)};
16914 StaticSocketDataProvider data(reads, arraysize(reads), nullptr, 0);
16915 session_deps_.socket_factory->AddSocketDataProvider(&data);
bnc87dcefc2017-05-25 12:47:5816916 session_deps_.channel_id_service =
Jeremy Roman0579ed62017-08-29 15:56:1916917 std::make_unique<ChannelIDService>(new DefaultChannelIDStore(nullptr));
danakj1fd259a02016-04-16 03:17:0916918 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
nharperb7441ef2016-01-25 23:54:1416919
16920 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
16921 TestCompletionCallback callback;
16922 EXPECT_EQ(ERR_IO_PENDING,
tfarina42834112016-09-22 13:38:2016923 trans.Start(&request, callback.callback(), NetLogWithSource()));
fdorayf33fede2017-05-11 21:18:1016924
16925 NetTestSuite::GetScopedTaskEnvironment()->RunUntilIdle();
nharperb7441ef2016-01-25 23:54:1416926
16927 EXPECT_TRUE(trans.GetResponseInfo()->was_fetched_via_spdy);
16928 HttpRequestHeaders headers;
16929 ASSERT_TRUE(trans.GetFullRequestHeaders(&headers));
16930 EXPECT_TRUE(headers.HasHeader(HttpRequestHeaders::kTokenBinding));
16931}
16932#endif // !defined(OS_IOS)
16933
eustasc7d27da2017-04-06 10:33:2016934void CheckContentEncodingMatching(SpdySessionDependencies* session_deps,
16935 const std::string& accept_encoding,
16936 const std::string& content_encoding,
sky50576f32017-05-01 19:28:0316937 const std::string& location,
eustasc7d27da2017-04-06 10:33:2016938 bool should_match) {
16939 HttpRequestInfo request;
16940 request.method = "GET";
16941 request.url = GURL("http://www.foo.com/");
16942 request.extra_headers.SetHeader(HttpRequestHeaders::kAcceptEncoding,
16943 accept_encoding);
16944
16945 std::unique_ptr<HttpNetworkSession> session(CreateSession(session_deps));
16946 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
16947 // Send headers successfully, but get an error while sending the body.
16948 MockWrite data_writes[] = {
16949 MockWrite("GET / HTTP/1.1\r\n"
16950 "Host: www.foo.com\r\n"
16951 "Connection: keep-alive\r\n"
16952 "Accept-Encoding: "),
16953 MockWrite(accept_encoding.data()), MockWrite("\r\n\r\n"),
16954 };
16955
sky50576f32017-05-01 19:28:0316956 std::string response_code = "200 OK";
16957 std::string extra;
16958 if (!location.empty()) {
16959 response_code = "301 Redirect\r\nLocation: ";
16960 response_code.append(location);
16961 }
16962
eustasc7d27da2017-04-06 10:33:2016963 MockRead data_reads[] = {
sky50576f32017-05-01 19:28:0316964 MockRead("HTTP/1.0 "),
16965 MockRead(response_code.data()),
16966 MockRead("\r\nContent-Encoding: "),
16967 MockRead(content_encoding.data()),
16968 MockRead("\r\n\r\n"),
eustasc7d27da2017-04-06 10:33:2016969 MockRead(SYNCHRONOUS, OK),
16970 };
16971 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
16972 arraysize(data_writes));
16973 session_deps->socket_factory->AddSocketDataProvider(&data);
16974
16975 TestCompletionCallback callback;
16976
16977 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
16978 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
16979
16980 rv = callback.WaitForResult();
16981 if (should_match) {
16982 EXPECT_THAT(rv, IsOk());
16983 } else {
16984 EXPECT_THAT(rv, IsError(ERR_CONTENT_DECODING_FAILED));
16985 }
16986}
16987
16988TEST_F(HttpNetworkTransactionTest, MatchContentEncoding1) {
sky50576f32017-05-01 19:28:0316989 CheckContentEncodingMatching(&session_deps_, "gzip,sdch", "br", "", false);
eustasc7d27da2017-04-06 10:33:2016990}
16991
16992TEST_F(HttpNetworkTransactionTest, MatchContentEncoding2) {
sky50576f32017-05-01 19:28:0316993 CheckContentEncodingMatching(&session_deps_, "identity;q=1, *;q=0", "", "",
16994 true);
eustasc7d27da2017-04-06 10:33:2016995}
16996
16997TEST_F(HttpNetworkTransactionTest, MatchContentEncoding3) {
16998 CheckContentEncodingMatching(&session_deps_, "identity;q=1, *;q=0", "gzip",
sky50576f32017-05-01 19:28:0316999 "", false);
17000}
17001
17002TEST_F(HttpNetworkTransactionTest, MatchContentEncoding4) {
17003 CheckContentEncodingMatching(&session_deps_, "identity;q=1, *;q=0", "gzip",
17004 "www.foo.com/other", true);
eustasc7d27da2017-04-06 10:33:2017005}
17006
xunjieli96f2a402017-06-05 17:24:2717007TEST_F(HttpNetworkTransactionTest, ProxyResolutionFailsSync) {
17008 ProxyConfig proxy_config;
17009 proxy_config.set_pac_url(GURL("http://fooproxyurl"));
17010 proxy_config.set_pac_mandatory(true);
17011 MockAsyncProxyResolver resolver;
17012 session_deps_.proxy_service.reset(new ProxyService(
Jeremy Roman0579ed62017-08-29 15:56:1917013 std::make_unique<ProxyConfigServiceFixed>(proxy_config),
xunjieli96f2a402017-06-05 17:24:2717014 base::WrapUnique(new FailingProxyResolverFactory), nullptr));
17015
17016 HttpRequestInfo request;
17017 request.method = "GET";
17018 request.url = GURL("http://www.example.org/");
17019
17020 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
17021 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
17022
17023 TestCompletionCallback callback;
17024
17025 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
17026 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
17027 EXPECT_THAT(callback.WaitForResult(),
17028 IsError(ERR_MANDATORY_PROXY_CONFIGURATION_FAILED));
17029}
17030
17031TEST_F(HttpNetworkTransactionTest, ProxyResolutionFailsAsync) {
17032 ProxyConfig proxy_config;
17033 proxy_config.set_pac_url(GURL("http://fooproxyurl"));
17034 proxy_config.set_pac_mandatory(true);
17035 MockAsyncProxyResolverFactory* proxy_resolver_factory =
17036 new MockAsyncProxyResolverFactory(false);
17037 MockAsyncProxyResolver resolver;
17038 session_deps_.proxy_service.reset(
Jeremy Roman0579ed62017-08-29 15:56:1917039 new ProxyService(std::make_unique<ProxyConfigServiceFixed>(proxy_config),
xunjieli96f2a402017-06-05 17:24:2717040 base::WrapUnique(proxy_resolver_factory), nullptr));
17041 HttpRequestInfo request;
17042 request.method = "GET";
17043 request.url = GURL("http://www.example.org/");
17044
17045 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
17046 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
17047
17048 TestCompletionCallback callback;
17049 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
17050 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
17051
17052 proxy_resolver_factory->pending_requests()[0]->CompleteNowWithForwarder(
17053 ERR_FAILED, &resolver);
17054 EXPECT_THAT(callback.WaitForResult(),
17055 IsError(ERR_MANDATORY_PROXY_CONFIGURATION_FAILED));
17056}
17057
17058TEST_F(HttpNetworkTransactionTest, NoSupportedProxies) {
17059 session_deps_.proxy_service =
17060 ProxyService::CreateFixedFromPacResult("QUIC myproxy.org:443");
17061 session_deps_.enable_quic = false;
17062 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
17063
17064 HttpRequestInfo request;
17065 request.method = "GET";
17066 request.url = GURL("http://www.example.org/");
17067
17068 TestCompletionCallback callback;
17069 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
17070 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
17071 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
17072
17073 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_NO_SUPPORTED_PROXIES));
17074}
17075
[email protected]89ceba9a2009-03-21 03:46:0617076} // namespace net